Reward Memory Architecture v0¶
LoopX separates feedback evidence, policy content, and action authority so a useful judgment does not silently become a universal personal profile or create permissions that the actor never held. Feedback from a verified repository owner or core contributor may still derive durable policy content inside that actor's independently verified repository scope. The distinction is between inferring what the contributor wants and inventing what the contributor is authorized to permit.
This contract defines five memory classes, guarded precedence, and the pilot/meta delegation boundary. Stage 1 adds the corpus registry and health read model. Stage 2 adds the stateless candidate/review seam. Stage 3 adds explicit recall/application. The minimal ingest loop only composes those seams into one corpus-owner-authorized provider write and exact readback. It adds no second memory store, candidate scheduler, semantic router, evaluation harness, or rollout. The opt-in runtime hooks reuse these seams at module-owned boundaries; they do not create a background learner.
The machine-readable contract is available through:
loopx reward-memory architecture --format json
loopx reward-memory candidate-review --case issue-fix-verified-contributor --decision accept --format json
loopx reward-memory ingest-event --input full-public-fixture.json --format json
Experimental activation¶
Reward Memory is a provider-neutral, default-off experimental capability. It is enabled for a named Agent inside one Goal, not for a whole Goal or LoopX install:
# Preview first; add --execute only after checking the boundary change.
loopx configure-goal --goal-id <goal> \
--reward-memory-config .loopx/config/reward-memory/experiment.json \
--reward-memory-agent <registered-agent>
loopx reward-memory experiment-status \
--goal-id <goal> --agent-id <registered-agent> --format json
The registry retains enabled, experimental, an ignored repo-relative config
pointer and digest, the explicit Agent allowlist, and a public-safe per-Agent
enablement receipt. Provider-specific choices stay local and private. A
verified receipt proves that the exact route accepted a fresh non-recallable
canary write and returned the same bytes. A missing receipt or config digest
drift makes automatic use unavailable without blocking ordinary Goal work.
OpenViking is the first provider used by the Issue Fix pilot, but it is not a
global LoopX feature flag or mandatory dependency; another provider can
satisfy the same binding contract.
OpenViking v0.4.19 identity boundary¶
LoopX currently assumes one Agent belongs to exactly one Goal, while a Goal may
contain several Agents. Agent names are only Goal-local. The durable runtime
identity is therefore (goal_id, agent_id), and LoopX derives a deterministic,
OpenViking-safe peer token from that pair. Reusing explorer in another Goal
produces another peer token, even when both routes use the same authenticated
OpenViking user.
New private writes must use
viking://user/{user_id}/peers/{canonical_peer}/memories/...; the request's
actor_peer_id must equal the URI peer before any provider call. LoopX rejects
viking://agent/... as a Reward Memory write target because OpenViking v0.4.19
keeps durable memories in the current User or actor-bound Peer namespace; the
Agent scope is not the durable per-peer memory root. LoopX also rejects
user-private paths without an actor-bound peer for an Agent-private corpus. Private peer
reads/writes require CLI >=0.4.18 and server >=0.4.19. See OpenViking's
multi-tenant model
and context types.
Config v1 can bind one private Goal-scoped Agent only. Supplying several Agents
with one private provider binding is rejected instead of silently sharing a
peer. Account/public resources remain an explicit shared mode. A future
same-Goal goal_shared memory must be a separate corpus with its own owner,
reader allowlist, write/promotion policy, and receipt; runtime recall may then
federate the Agent-private and Goal-shared corpora explicitly. Private memory is
never promoted or made visible to a sibling Agent merely because both Agents
belong to the same Goal.
Lifecycle completion boundary¶
Provider readiness and lifecycle automation are separate status dimensions. A verified storage receipt does not by itself prove that automatic recall and writeback are connected to every host. Complete lifecycle enablement means the supported planning/decision entry points perform bounded recall, and real evidence-backed outcome reviews perform idempotent writeback without another hidden opt-in. No new evidence means no new memory. A missing identity never falls back to a shared corpus; provider degradation stays visible while base Goal work continues. Each host must report its actual coverage rather than generalizing from a direct CLI or helper test.
Config v1 declares one project_provider_binding, its exact per-corpus scope
references, the project corpus set, module-owned surfaces, and an automation
policy. A surface explicitly lists its compatible corpus_ids, selects one
ingest_corpus_id, and owns its recall_profile. LoopX never discovers routes
by scanning all corpora. Corpora assigned to one surface must have the same
memory class, authority, privacy, freshness, and lifecycle. Scope digests and
provider/corpus identity are still checked independently for every corpus.
{
"schema_version": "reward_memory_experiment_config_v1",
"project_provider_binding": {
"provider_id": "openviking",
"namespace": "reward_memory",
"corpus_scopes": [
{"corpus_id": "review_policy", "scope_ref": "viking://.../review-policy"}
]
},
"corpora": [
{"corpus": {"corpus_id": "review_policy"}, "standing_policy": {}}
],
"surfaces": [
{
"surface_id": "reviewer_artifact.summary",
"adapter": "scoped_feedback",
"corpus_ids": ["review_policy"],
"ingest_corpus_id": "review_policy",
"recall_profile": {
"profile_id": "review_summary_v1",
"mode": "function_boundary",
"max_queries": 1,
"limit": 4
}
}
],
"automation": {
"automatic_recall": true,
"automatic_ingest": true,
"fail_open": true
}
}
The abbreviated corpus and standing-policy objects above represent the full
existing record contracts. These true values show the new-enable default;
an explicit false remains the supported per-hook opt-out. configure-goal
preview now calls the provider
preflight and reports preflight_ready, preflight_incomplete, or
unavailable; it never reports a provider write as merely planned. Preview
does not prove writability. Apply must complete the fresh canary write and
exact readback before it commits the registry binding. experiment-status
reports the v1 config schema,
corpus/surface counts, recall-profile ids, and the effective automatic policy
without exposing scope refs. Agent-scoped quota should-run and status
--agent-id resolve that policy through the same invoked registry and config
reader; they do not copy automation flags into registry summaries. Their compact
config_runtime_route names the registry role and project/shared runtime scope,
and marks exact config readback without exposing either local path. The runtime accepts only
reward_memory_experiment_config_v1; local ignored configs must be migrated
explicitly before rollout. Setting a flag only authorizes a compatible runtime
hook; it does not create a scheduler, infer a query, widen authority, or bypass
the exact surface/corpus guards.
automatic_recall=true lets a predeclared module boundary call the shared
runtime hook. The module still supplies its surface query, current-artifact
checks, and reasoning callback. The hook follows the configured corpus order,
stops at the first exact readback hit, allows exactly one query at a
function_boundary or at most three at a bounded-agentic boundary, and emits
provider-call telemetry plus an application receipt. A provider or application
failure preserves the module's base output and is never a user gate.
automatic_ingest=true lets a module pass one already-distilled compact event
to the configured adapter and ingest corpus. The adapter and standing policy
remain responsible for exact actor/project/surface/action scope. The shared
hook reuses deterministic candidate identity, activation, provider sync, exact
readback, and an ingest receipt. It does not collect chats, parse tool logs,
store raw content, or infer new authority. Repeated events remain idempotent.
When either automation field is omitted from a newly enabled v1 config it
defaults to true; an explicit false remains disabled and is projected with
explicit intent provenance. Existing false values are never silently
reinterpreted. The explicit ingest-event command remains an operator/caller
path rather than a compatibility fallback.
The production Codex CLI Turn performs recall after quota/Todo admission and
accepts outcome ingestion only after independent validation, durable writeback,
and quota settlement. A reflection must use turn_reward_memory_reflection_v0
and include an exact configured surface, a distinct research/simulation/real/
engineering source kind, and opaque evidence refs; an ordinary Turn summary is
not evidence. Ambiguous provider commits and unverified readbacks remain in a
mode-0600 Goal+Agent+event sidecar. The next executing Turn retries the same
deterministic event before recall, so the provider can deduplicate it and LoopX
can require exact readback. Explicit disable suppresses reconciliation and all
provider calls.
The Codex App uses the same settlement boundary without copying the raw
reflection into run indexes, rollout events, or public projections. For a
Todo-bound accountable refresh, the caller may add
--reward-memory-reflection-json <turn_reward_memory_reflection_v0 JSON>.
LoopX stores that candidate only in a mode-0600 Goal+Agent+candidate sidecar and
runs the exact completion-validation command already declared by that Todo. The
validator must return reward_memory_reflection_validation_v0 with the exact
reflection digest and evidence references; an ordinary successful validation
exit is insufficient. The later matching quota spend-slot --execute finalizes
ingestion only after exact refresh/writeback and spend readback. A missing,
failed, or non-attesting validation remains awaiting_evidence_validation and
makes zero provider calls. The App does not need a separate manual
reward-memory ingest-event command for this lifecycle. DSH currently carries
recall context but does not claim this post-settlement ingest boundary.
Dashboard, CLI/status, and Lark projections reuse the same capability owner and public receipt. Dashboard writes only an ignored config pointer and registered Goal-local Agent allowlist through the existing preview/apply/readback transaction. It returns an opaque binding revision, effective automation and intent provenance, never the local-private path or provider scope.
An allowlisted agent supplies only the compact event at runtime:
loopx reward-memory ingest-event \
--goal-id <goal> --agent-id <registered-agent> \
--input compact-event.json --execute --format json
Real provider writes require this configured goal-and-agent route. The legacy
full-packet form remains available only as a no-write evaluation fixture.
Config loading alone does not capture feedback or authenticate a provider.
Automatic hooks run only when both the flag and a real module-owned callsite
are present. Issue Fix currently has two independently configured recall
callsites: reviewer_artifact.summary applies a concise reviewer-facing
summary, while reviewer_notification.before_send may apply one verified
structured hard-policy delivery window immediately before the existing
secondary sink. The latter reuses the sink's queue/dedupe/readback path and is
unrestricted when neither recalled nor explicit sink policy exists; it is not
a generic router. Other surfaces remain explicit until separately wired and
verified. Issue Fix continues normally when the experiment is disabled,
unavailable, rejected by guards, or fails exact readback. Invalid or non-v1
configuration resolves unavailable with both automatic flags false.
Inbox feedback review (explicit ingestion)¶
When a registry-routed loopx lark-inbox drain --goal-id <goal> --agent-id
<agent> returns messages, it also emits reward_memory_feedback_review if
Reward Memory is enabled for that agent and has an active, writable
scoped_feedback route with an enabled standing policy and exact
peer_ref=agent:<agent>. The hint lists configured destinations and a preview
command bound to the same registry, Goal and Agent. It is advisory: there is no
provider call, automatic candidate creation, new permission, or ACK gate.
Both JSON and Markdown drains expose it. Empty/disabled inboxes, disabled or
invalid memory configurations, unconfigured agents, incompatible routes, and
explicit --config/--project overrides retain their previous output.
The agent reviews the conversation before choosing what, if anything, to learn:
- Verify the source actor and existing authority, current evidence, conflicts and applicability. A policy's allowed roles are not proof of a sender's role. A disagreement is not a universal ban, and one-off task state belongs in Todo/vision rather than durable preference memory.
- Distill only confirmed reusable feedback into an applicable configured
soft_preference,procedural_experience, or independently authorizedhard_policyroute. Never widen the route or enable automation to make an event pass. Keep raw chat and credentials out of the event. - Prepare
{adapter, event, observed_at}using the scoped feedback fixture for field shape only. The event usesschema_version=scoped_feedback_reward_memory_event_v0, a stablefeedback_ref, actualsource,reasoning,guard_context, compactcontent_summary,target_class, and exact identity/surface/revision/action scope. Advisory classes require emptyrequested_action_scopes; allowed policy scopes do not grant advisory memory action authority. Do not copy the fixture's actor or verified-guard assertions. - Replace the hint's input placeholder and preview
ingest-eventwithout--execute. Inspect its guards. Only then execute within the standing policy and verifyexact_readback_verifiedandmemory_available_for_recall; a preview is not a learned memory. - Finish normal reply/material-review/ACK. No reusable feedback or unavailable memory is an honest no-memory outcome, not a reason to block the inbox or repeatedly ask the user for permission. Actual write failures remain visible in the existing ingestion receipt.
automatic_ingest=false does not prohibit this explicit workflow. Enabling
it also does not wire raw inbox messages into ingestion. Issue Fix's compact
feedback adapter and recall hooks share the same core but are not a general
inbox-to-memory feedback loop. Disable the hint by disabling Reward Memory for
the agent (or its applicable route); no extra store, queue or scheduler exists.
Five first-class classes¶
| Class | Source and scope | Authority and use | Lifecycle |
|---|---|---|---|
run_bound_reward |
Explicit human judgment attached to one exact goal/run. | Evidence about that outcome only. Future influence requires compact candidate derivation and an activation policy; the overlay itself is not a standing instruction. | Append-only overlay; corrections and revocations append references instead of rewriting the judged run. |
hard_policy |
Explicit user/repository/operator authority, or policy content inferred from verified owner/core-contributor evidence and bound to an existing project/action authority scope. | Constraint or veto inside the verified scope. Reasoning may infer policy meaning from rewards, preferences, current-artifact-verified experience, selected options, accepted/rejected outcomes, and maintainer corrections; it may not infer credentials, new publish/production scope, or cross-user/repository authority. | Active records retain actor, evidence, scope, and derivation provenance until superseded, revoked, or expired; temporary or weakly reinforced inference should expire or return to review. |
soft_preference |
Explicit feedback, selected options, or later reviewed candidates scoped to a workspace/project and module-owned surface. | Advisory ranking or rewrite only. It cannot grant publish, merge, write, credential, or production authority. | Durable only after explicit review; editable, rejectable, supersedable, revocable, and retireable. |
procedural_experience |
Revision-stamped trajectories, distilled experiences, maintainer corrections, accepted/rejected changes, and reviewed architectural learning, with repository/module/revision/applicability scope. | Advisory diagnosis, scope, routing, or validation guidance only after current-artifact verification. A training/evaluation case is evidence, not an executable instruction. Retrieval alone has zero patch authority. | Trajectories may be add-only; distilled or architectural experiences are supersedable. New source truth can stale, quarantine, refute, or retire them. |
working_context |
Either fresh execution state (fresh_execution_context) or a revisioned session-continuation summary (session_working_memory). |
Supports only the current execution/session continuation. Neither subtype becomes reusable policy or grants action authority. Fresh source-of-truth reads outrank recalled material. | fresh_execution_context already exists in LoopX registry/state/todo/quota/checkout observations and is reused, not rebuilt. Session context remains bound to its session/archive revision. |
Every durable record must name source, scope, authority, confidence,
lifecycle_state, supersession, revocation, expiry, and privacy in
addition to the class. Confidence describes evidence quality; it never
increases authority. Confidence is low, medium, or high with a required
basis; source names kind/ref/actor/time, scope names user/workspace,
project/repository, module/surface, and revision/time boundaries. Lifecycle
records state plus supersession, revocation, expiry, and retirement references.
Privacy names visibility, retention class, and whether raw content was captured.
Policy content versus authority¶
Hard policy has two independent questions:
- What is the policy? LoopX may infer compact policy content from explicit feedback, reviewed preferences, current-artifact-verified experience, selected options, repeated accepted or rejected outcomes, and maintainer corrections.
- Where does that policy have force? Actor identity and repository/action authority must come from an independently verified source. Memory confidence cannot create or widen that scope.
For a verified repository owner or core contributor, an unambiguous inferred policy may become active without asking the same question after every run when all of these hold: actor and authority scope are verified, provenance is compact and inspectable, no higher-authority source conflicts, and the record is reversible through edit, supersede, revoke, retire, or expiry. Ambiguous meaning, unclear scope, identity uncertainty, or a conflict returns the item to review. Inference never creates credentials, external-write capability, production permission, cross-agent authority, or authority in another repository.
Inference may derive a reusable boundary or gate policy, but it cannot fabricate the current state transition of a concrete operator gate or authority checkpoint. A current approve/reject/consume receipt still comes from that gate's source of truth.
Guarded precedence and model reasoning¶
The following order is a safety and attention envelope, not an exhaustive decision table:
- explicit action authority and privacy boundaries;
- active in-scope hard policy;
- fresh working context and current source of truth;
- current-artifact-verified procedural experience;
- active in-scope soft preference;
- run-bound reward as evidence only.
Deterministic code should reject illegal states: unverified authority, wrong project or surface, revoked/expired material, privacy violations, unresolved same-authority conflicts, and missing current-artifact verification. Within the remaining allowed action set, the model keeps responsibility for interpreting feedback, judging relevance and evidence sufficiency, balancing trade-offs, and deciding to apply, ignore, or seek more evidence. Its compact receipt names the reasoning summary, memory references, artifact verification, and authority/scope check.
Prefer explicit provenance when evidence is otherwise equal, but do not turn that preference into a hard-coded router that suppresses useful inference. Raw chat, transcripts, tool logs, credentials, and local paths are not reward-memory records.
loopx reward-memory route-check is a deterministic regression fixture for
obvious safety/escalation conditions such as PR #3237. It is not the live Issue
Fix decision engine and does not replace model reasoning.
Architecture layers and reuse¶
flowchart TD
OV["OpenViking memory substrate<br/>AGFS source truth, index, scoped retrieval,<br/>preferences, trajectories, experiences, session memory"]
CTX["Existing LoopX fresh execution context<br/>registry, active state, todo/quota, checkout, bounded observations"]
CORE["LoopX reward-memory core<br/>classes, scope/authority, corpus health,<br/>candidate and activation decisions"]
IF["Issue Fix adapter<br/>run outcome and maintainer feedback in;<br/>routing/validation influence receipt out"]
OTHER["Later module adapters<br/>same core contract, module-owned surfaces"]
OV --> CORE
CTX --> CORE
CORE --> IF
CORE --> OTHER
OpenViking owns memory storage, indexing, scoped retrieval, and session-memory building blocks. LoopX owns action semantics: class, scope, authority, lifecycle, candidate derivation, activation, and application receipts. The Issue Fix adapter maps issue/PR evidence into the shared core and consumes its decisions; it must not grow a parallel memory store, policy schema, or ranking pipeline. Other modules join only after this reuse seam is proven.
Issue Fix as the first adapter¶
Issue Fix contributes only domain mapping:
- exact run reward, maintainer correction, selected fix direction, and durable issue/PR outcome become compact inputs to the shared candidate contract;
- repository identity, contributor role, current checkout, issue/PR state, and active LoopX gates supply current authority and execution context;
- OpenViking supplies scoped preference or experience retrieval when the module asks for it;
- the shared core returns apply, ignore, seek-evidence, or review, together with a compact influence receipt;
- Issue Fix still verifies any recalled technical claim against current code and tests before it can affect a patch.
The adapter does not own candidate lifecycle, contributor-policy semantics, retrieval health, or provider persistence. Those stay reusable core concerns. This keeps the issue-fix scenario valuable without letting it define the whole memory product.
Implemented Stage-2 seam¶
Stage 2 accepts a model-proposed compact candidate: target class, content summary, source actor and evidence reference, workspace/project/surface scope, reasoning summary, confidence, and any requested action scopes. The model owns interpretation and the proposed policy meaning. Deterministic code only checks the public-safe shape, scope binding, raw-content boundary, source freshness, unresolved conflicts, current-artifact proof where required, and authority checkpoint.
For hard_policy, the checkpoint must independently bind the same actor, role,
project, and action scopes. A verified core-contributor correction can
therefore produce an activation-ready policy candidate directly, but only for
the subset of action scopes already present in that checkpoint. An unverified,
mismatched, or wider request remains inspectable as guard_blocked; an
attempted accept or edit becomes no_write instead of gaining authority.
Advisory preference and experience candidates cannot request action authority.
The review contract exposes five decisions:
acceptemits an active record;editemits a revised candidate linked to the prior candidate;rejectcloses the candidate as rejected;retirecloses an already active reviewed record;no_writerecords that no provider write should occur.
These are decision records, not persistence operations. accept and retire
only return a next-step instruction for the caller to use the declared corpus
write authority and verify readback. The seam itself writes no LoopX state,
OpenViking corpus, index, receipt, or external system. It also does not ingest
raw chat or tool transcripts.
issue_fix_reward_memory_candidate_adapter_v0 is deliberately a field-mapping
adapter. It maps a compact issue reference, repository revision, module-owned
surface, contributor evidence, and model reasoning into
reward_memory_candidate_v0; all guards and lifecycle decisions remain in the
shared core. This is the first reuse proof, not an Issue Fix-specific memory
implementation.
Minimal ingest loop¶
loopx reward-memory ingest-event is a thin atomic orchestration, not another
memory product layer. The configured experiment explicitly selects an adapter.
issue_fix_maintainer_feedback remains the Issue Fix compatibility adapter;
scoped_feedback accepts a generic scoped_feedback_reward_memory_event_v0
for any module-qualified surface. Both adapters only map strict compact fields
into the same reward_memory_candidate_v0; neither owns a second lifecycle,
store, scheduler, recall path, or semantic router. LoopX neither retains raw
feedback bodies nor uses keywords to decide which feedback deserves memory.
The model or calling module first distils an event containing only a source
reference, verified actor/role, exact workspace/project/surface/revision,
compact summary, reasoning, and current-artifact evidence.
A reward_memory_standing_policy_v0 predeclares the corpus owner, reviewer,
authority source, exact project/surfaces, one memory class, source kinds,
verified actor roles, and action scopes. This replaces per-comment approval
with one approval of an exact boundary. It cannot create credentials,
repository write authority, publish/production scope, or cross-project
authority. Out-of-scope, conflicted, stale, raw, or unmodelled input is
guard_blocked before any provider call.
The command then composes deterministic candidate_ref deduplication, standing
policy acceptance, active-envelope construction, declared-provider sync, and
one exact-corpus/surface function-boundary recall. A
reward_memory_ingest_receipt_v0 reports activated and
memory_available_for_recall=true only when resource ref, candidate ref, and
canonical content digest all match. Provider unavailability, pending commit,
or readback mismatch fails open and does not block the caller's normal work.
observed_at is the immutable first-observed event timestamp and must be reused
on retries. The provider target binds both standing-policy and candidate
digests so a policy revision cannot silently reuse an older activation.
--execute is off by default; dry-run returns only planned. Execute also
requires the goal id and allowlisted agent id, so a caller cannot bypass the
default-off experiment policy by supplying a provider binding directly.
The caller still explicitly invokes its existing Stage-3 function-boundary
recall hook. Issue Fix keeps run_issue_fix_patch_planning_reward_memory; other
modules use their own surface-owned hook. The model decides apply, ignore, or
refute and reuses the shared application receipt. The ingest seam adds no
deterministic semantic routing or background scheduler.
OpenViking alignment¶
The five classes are provider-neutral, but the Stage-0 boundary was checked against OpenViking's current public architecture and code:
- OpenViking is a context database, not an action-authority system. AGFS content is its source of truth; the vector index stores retrieval references.
- OpenViking
preferencescan supply reviewedsoft_preferencecandidates. They never become permission. - OpenViking
trajectoriesare add-only operation contracts distilled from one execution. OpenVikingexperiencesare upserted, executable-looking generalizations that may explicitlysupersedean older experience. Both map to advisoryprocedural_experience, subject to current-revision verification. - OpenViking
casesexplicitly define a task and rubric for training or evaluation; they are not experience instructions and cannot be injected as policy. - OpenViking Working Memory is a seven-section archive overview used for
session continuation. It maps to
working_context/session_working_memory, not long-term policy. LoopX's fresh registry/todo/checkout observations map to the separatefresh_execution_contextsubtype. - OpenViking
soul.mdor another provider record may contain policy evidence, but it becomes LoopXhard_policyonly when the actor and repository/action authority scope are independently verified. The content may be inferred; the authority may not. - Account, user, peer, session, and repository-revision boundaries remain part of scope and privacy. A peer label does not grant cross-user or cross-agent authority.
Provider health is intentionally decomposed into corpus_present,
index_present, retrieval_query_succeeded, result_readback_verified, and
memory_applied_with_receipt. These states must not be collapsed. In
particular, the current OpenViking Codex auto-recall path configures the
experiences quota to zero, so an experience corpus can exist without being
automatically recalled. Stage 1 owns that inventory and health proof; Stage 0
does not claim it.
Grounding references: OpenViking
architecture,
session management,
multi-tenant and peer isolation,
and source revision
ba46491.
Pilot/meta delegation¶
The pilot may take a fix only when behavior is a confirmed bug, scope is one bounded surface, the change does not alter a semantic contract or place product-specific policy in a generic boundary, reproduction and validation are named, edge-case complexity is low or medium, and all relevant evidence is present. Meta design review is required for by-design or uncertain semantics, a semantic-contract change, cross-surface change, generic-boundary leakage, or high edge-case complexity.
Evidence requirements are relevance-gated instead of using a blanket
"core-component" rule: effect evidence is always required; UX evidence is
required for a user-visible behavior change; performance evidence is required
for a hot-path or storage-behavior change; benchmark evidence is required only
when retrieval or memory quality is claimed. Missing required evidence without
a meta trigger produces hold_for_evidence. This allows a bounded bug inside a
core module to remain pilot-sized while still escalating a deceptively small
change that alters a public or storage contract.
This is guarded routing, not cross-agent authority. The live agent still reasons about semantics and evidence inside the guards. The meta lane does not edit or claim the pilot's todos, and the pilot cannot bypass the design gate with a memory hit.
PR #3237 regression¶
OpenViking PR #3237 is the negative regression. It tried to make generic directory listing reflect session-specific activity across backend and Web Studio surfaces even though the maintained directory-mtime behavior was by design. The resulting patch changed a generic filesystem/session contract for one product-specific edge case, crossed backend and Web Studio surfaces, and added metadata reads on a listing/storage path. It lacked product-effect, UX, and performance evidence. Benchmark evidence is not required by this regression because it made no retrieval or memory-quality claim.
The stable expectation is meta_design_gate, not pilot_fix. Meta may narrow
the product behavior to a session-specific presentation boundary or close the
change; a prior memory result cannot authorize the generic-layer patch.
Staged ownership¶
- Stage 0: this classification, precedence, and delegation contract.
- Stage 1: the implemented provider-neutral
corpus registry and health contract,
including ownership, authority, freshness, retirement, scope isolation, and
retrieval-health distinctions. Its
fresh_execution_contextentry describes an existing LoopX capability; it is not a request for another context system. - Stage 2: the implemented stateless candidate and activation-decision seam over existing LoopX/OpenViking evidence. It adds no second store, scheduler, automatic recall, or raw-content retention. Issue Fix is the first adapter and reuses the generic record/decision shape.
- Stage 3: the implemented opt-in cross-module recall/application seam. Model reasoning stays inside deterministic scope, authority, privacy, freshness, and conflict guards; Issue Fix patch planning and the non-Issue-Fix semantic preference module share the same core and compact application receipt. The minimal ingest seam reuses Stages 2/3 and the declared provider to atomically write and exactly read back compact events inside a standing-policy boundary; it does not choose the event, corpus, or consumer module.
- Stage 4: evaluation harness and release gate.
- Stage 5: bounded cross-module dogfood, optional post-outcome utility attribution, and operator edit/retire controls.
Later stages must extend this contract rather than collapsing these classes, duplicating existing context/provider capabilities, or turning provider availability into a user gate. Stage 1 remains a stateless read model and performs no provider or external write.
Stage 3 recall and application seam¶
Stage 3 accepts only an explicit reward_memory_recall_request_v0 naming one
registered corpus and one module-owned surface. The request carries a matching
read-authority checkpoint and current freshness/conflict observations. A
project, surface, authority, revision, lifecycle, or provider-binding mismatch
stops before the provider is called. This is deterministic safety validation,
not a semantic router.
The caller/model owns the query and interpretation. function_boundary allows
one query at a named function boundary. bounded_agentic_search allows at most
three caller/model-authored queries. LoopX does not choose a module, infer a
corpus from similarity, scan every corpus, schedule a later recall, or grant
action authority from a hit.
An accepted reward_memory_candidate_review_v0 may be wrapped as a
reward_memory_active_record_v0; only the declared corpus owner may persist
that envelope. Recall accepts only active envelopes from the exact selected
corpus and surface. Private summaries remain transient in-process. Public
packets expose opaque provider references and compact lineage; application
receipts contain hashed memory references, the model-owned reasoning summary,
and current-artifact verification, never raw provider content.
Provider unavailability returns setup guidance and preserves the base output.
It is an agent/runtime condition, not a user gate. Invalid or failed model
application also preserves the base output. An applied receipt requires both
attribution to an item returned by this recall and current-artifact
verification. Issue Fix uses the fixed issue_fix.patch_planning surface;
semantic_preference is the second, non-Issue-Fix module consumer.
An OpenViking binding whose scope is under /peers/<peer>/ must carry that
exact actor_peer_id. LoopX forwards it only to scoped provider operations and
never infers an actor identity from an arbitrary target URI.
Stage 4 evaluation and release gate¶
Stage 4 is one bounded contract suite over the existing shared core. It does not add another evaluator, store, provider, scheduler, or semantic router:
The runner executes the real candidate, recall, application, Issue Fix adapter, and route-guard code for eight cases: compact/restart survival; project and module isolation; supersede/revoke rejection; stale-source rejection; multi-person authority matching; gate non-override; verified candidate-ranking influence; and protection against a large patch for the PR #3237 edge case.
evaluation.py owns case orchestration, assertions, metrics, and the release
gate. Reusable setup and provider doubles live in evaluation_fixtures.py with
neutral fixture identities; OpenViking appears there only through the explicitly
named PR #3237 Issue Fix regression fixture. Project identity is fixture data,
not evaluator policy.
reward_memory_evaluation_v0 reports task outcome plus exact local runner
latency, public evidence bytes, model-token count, provider/storage writes,
false applications, maintainer interruptions, and user gates. Zero model tokens
means this deterministic contract suite did not invoke a model; it is not a
token-cost estimate for later dogfood. The release gate passes only when every
case passes and all write, false-application, interruption, and user-gate counts
remain zero.
A pass yields ready_for_bounded_dogfood, not production release. It proves
core contract invariants only, does not claim semantic uplift, and does not
authorize production rollout. Stage 5 must use a corpus-owner-approved record,
exact provider readback, and real module outcomes before making an uplift claim.
Stage 5 dogfood receipts, utility attribution, and operator controls¶
Stage 5 adds one thin evidence layer over the Stage 3 application receipt. It does not add a store, scheduler, semantic router, automatic recall path, or ranking behavior. A caller supplies a compact real-module observation whose artifact reference matches the application receipt:
reward_memory_dogfood_receipt_v1 records application_disposition as
applied, not_applied, or refuted. This is application coverage, not a
causal utility judgment. An applied or refuted disposition is invalid unless
the selected provider result was read back exactly and the current artifact
was verified. The receipt retains the opaque digest application_receipt_id
for the exact Stage 3 application receipt, plus only opaque or hashed memory
references, a compact verified outcome reference and summary, latency,
model-token and provider-call counts, intervention count, and optional compact
bot feedback.
It retains no raw provider content and grants no new action authority.
The former reward_memory_dogfood_receipt_v0 used hit, miss, and refute
for this same application-coverage distinction. In particular, its hit
never established that a memory was helpful. The v1 receipt supersedes that
ambiguous naming instead of silently changing the v0 contract.
Post-outcome utility is a separate memory_utility_observation_v0 with one of
helpful, harmful, neutral, or unknown. The optional evaluator is
default-off and proposal-only. LoopX validates its proposal against separately
trusted agent, project, corpus, and surface scope; the verified outcome ref;
and the retrieval and policy snapshot refs supplied by the execution boundary.
Snapshot freshness is owned by the execution or provider adapter that supplies
the trusted attribution context. When a compatible application receipt also
carries snapshot refs, the validator cross-checks them exactly. A stale or
mismatched evaluator echo is rejected. applied plus a successful outcome
remains unknown without independent attribution evidence. When several
memories are involved, attribution defaults to set; set-level credit is never
copied to individual items.
Evidence basis is typed rather than inferred from prose. owner_correction,
controlled_replay, and deterministic_effect are stronger bases and require
at least one opaque evidence_ref in the evaluator proposal, even when the
label remains unknown. evaluator_inference is weaker and insufficient is
lineage-only. Stage 1 preserves that typed distinction; the Stage 2 reducer
owns precedence between weak and strong observations.
The public observation contains only opaque references, canonical memory
digests, typed reason codes, evaluator/version identity, and compact public-safe
evidence. URLs, local paths, raw-content fields, and any proposal to grant
action authority or perform a write are rejected. Provider adapters must digest
exact private provider references before constructing this public contract. An
absent, timed-out, or malformed evaluator fails open: the main result,
application settlement, and dogfood readiness remain unchanged. The attribution
subject, evidence, evaluator identity, and evaluation version produce a stable
observation id for replay identity. A different judgment under the same key is
a conflicting delivery, not additional support; a correction must cite new
evidence or advance the evaluation version. Utility-attribution Stage 1 does not
persist or reduce observations and therefore does not yet claim
duplicate-delivery no-op behavior. The Stage 5 batch rejects duplicate
application_receipt_id values and counts each application settlement once.
The settlement receipt_id deliberately excludes evaluator status and
observation_id; utility retries and new evidence use the observation identity
instead. A new utility observation for the same settlement belongs in the later
append-only utility ledger and must not duplicate disposition or cost metrics.
reward_memory_dogfood_batch_v1 becomes
ready_for_bounded_issue_fix_pilot only when the Stage 4 gate still passes and
the bounded batch contains at least one Issue Fix result, two distinct LoopX
domain results, all three applied/not_applied/refuted application
dispositions, and both operator controls. Utility observations do not affect
this readiness decision. This is a trial-readiness statement; semantic uplift
and production rollout remain false. The Stage 2 reducer and projection,
ranking influence, and OpenViking writeback are outside this implementation.
The edit/retire control is similarly narrow:
loopx reward-memory operator-control \
--input reviewed-record.json --action retire \
--control-ref control:example:retire \
--reasoning-summary 'Current source truth supersedes this record.' \
--format json
An edit checkpoint must match the corpus owner; a retirement checkpoint must
match maintenance.retirement_authority. Both checkpoints are also bound to
the exact corpus, project, and action. Edit produces a replacement
candidate linked to the active record. Retire produces a retired decision.
Neither command writes provider state. The declared corpus owner still performs
the write and exact readback, so operator control cannot silently become a
publish, production, or cross-project authority expansion.
Outbound communication¶
The opt-in outbound guidance integration (中文) recalls reviewed preferences at the actual goal/agent-bound Lark inbox send and reply boundary. It returns guidance for agent review without granting send authority.