Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions loopx/capabilities/reward_memory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,17 @@ engineering source kind, and opaque evidence refs; an ordinary Turn summary is
not evidence. It also carries `procedural_experience_contract_v0` with
applicability, observed outcome, attribution, complete future behavior,
limitations, and the same evidence refs. Legacy v0 reflections remain
audit-only and cannot become durable memory. Ambiguous provider commits and
unverified readbacks remain in a
audit-only and cannot become durable memory. When the same Turn delivers recall
guidance and enables ingest, reflection compares new independent evidence with
comparable procedural experience guidance. Without a comparable experience, the
ordinary eligibility rule remains in force. Mere confirmation leaves the
reflection empty; a candidate is
produced only for distinct reusable applicability or a material change to its
trigger, action, validation, stop condition, or limitations. Distinct
applicability remains separate rather than being blended. Reflection never
merges, updates, retires, or supersedes a provider record; configured lifecycle
owners retain those decisions. 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
Expand Down
8 changes: 7 additions & 1 deletion loopx/capabilities/reward_memory/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,13 @@ quota settlement 均完成后,才接受 outcome ingest。Reflection 必须使
research/simulation/real/engineering 来源类型和 opaque evidence refs;还必须携带
`procedural_experience_contract_v0`,分别写出适用情境、已观察结果、归因、未来行为(触发、动作、
验证、停止条件)、失效边界,并绑定相同 evidence refs。只有事实复述、没有未来行为改变的普通
Turn summary 不算经验。旧的 v0 reflection 只保留审计兼容,不会写成可持久召回的记忆。
Turn summary 不算经验。旧的 v0 reflection 只保留审计兼容,不会写成可持久召回的记忆。同一
Turn 同时交付 recall guidance 并启用 ingest 时,reflection 会把新的独立证据与其中可比较的
procedural experience 对照;没有可比较经验时,仍使用普通资格规则。若只是确认相同的未来行为
与失效边界,就保持为空。只有触发、动作、验证、停止条件或
失效边界发生实质变化,或者形成可复用的独立适用情境时才生成候选;适用情境不同的经验保持
分开,不混成更宽泛的规则。
Reflection 不合并、更新、退役或取代 Provider 记录,这些决定仍属于已配置的生命周期 owner。
Provider commit 含糊或精确读回失败时,会保留一份权限为 0600、按 Goal+Agent+事件隔离的
sidecar。下一个执行 Turn 会在 recall 前以同一 deterministic event 重试,使 Provider 可以去重,
LoopX 再要求精确读回。显式关闭会停止 reconciliation,并保持零 Provider 调用。
Expand Down
4 changes: 4 additions & 0 deletions loopx/capabilities/reward_memory/turn_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def _reward_memory_prompt_instructions(*, has_guidance: bool, ingest_enabled: bo
instructions.append(
"Set reward_memory_reflection_json to an empty string unless independent task evidence established a reusable experience. For eligible evidence, return one compact JSON object using schema_version=turn_reward_memory_reflection_v1, status=eligible, a configured surface_id, outcome_kind in research|simulation|real|engineering, content_summary, reasoning_summary, confidence in low|medium|high, and 1-5 opaque evidence_refs. Also include experience using schema_version=procedural_experience_contract_v0 with non-empty applicability and limitations lists, observed_outcome, attribution, the same evidence_refs, and future_behavior containing trigger, action, validation, and stop_condition. A fact recap without a future behavior change and non-generalization boundary is not eligible memory. Legacy v0 reflections are audit-only and cannot become durable memory. Never use your own summary as evidence. Settlement may ingest it only when the caller-declared Todo validator attests the exact reflection digest and evidence; ordinary validator success remains awaiting and makes no provider write."
)
if has_guidance and ingest_enabled:
instructions.append(
"Before proposing a reflection, compare current independent task evidence with any comparable procedural_experience in the delivered reward_memory_recall guidance. If no comparable procedural experience was delivered, apply the ordinary eligibility rule above. Leave reward_memory_reflection_json empty when the evidence only confirms the same future behavior and limitations; emit a candidate only when it establishes distinct reusable applicability or materially changes the trigger, action, validation, stop condition, or limitations. Keep distinct applicability conditions separate rather than blending them. Do not claim to merge, update, retire, or supersede provider records; those lifecycle decisions remain with their configured owners."

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 新增反思提示挤掉原可交付的召回。 同一组 8 条通过 scope、lifecycle 和经验质量校验的记录,主干以 65,190 字节交付全部经验。候选加上 747 字节的提示后需要 65,937 字节,超过 65,536 字节;App guard 省略 8 条经验和比较提示。召回状态仍为 applied,反思字段仍启用。 保留现有 64 KiB 上限,用原有有界指令渠道或经证实无损的预算调整保存原先可交付的召回。加近上限的真实 guard 回归,断言这 8 条经验和比较提示均交付,同时保留真正超限的降级对照。

)
return instructions


Expand Down
8 changes: 8 additions & 0 deletions tests/control_plane/test_quota_memory_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ def test_real_app_guard_delivers_scoped_memory_once(
assert project_turn_context(first)["reward_memory_recall"]["context"]["guidance"] == guidance
assert contribution["result_fields"]["reward_memory_reflection_json"]["maxLength"] == 2400
assert "private, non-authoritative" in contribution["instructions"][0]
assert any(
"compare current independent task evidence" in item
for item in contribution["instructions"]
)
repeated = run_cli(args)
assert repeated["ok"] and memory.calls == 1
assert not repeated.get("reward_memory_recall", {}).get("external_writes_performed")
Expand Down Expand Up @@ -206,6 +210,10 @@ def test_quota_recall_size_limit_preserves_independently_enabled_ingest(size: in
delivered = result["context_fields"]["reward_memory_recall"]
assert (delivered["context"] is not None) is (size == 40_000)
assert result["result_fields"]["reward_memory_reflection_json"]["maxLength"] == 2400
assert any(
"compare current independent task evidence" in item
for item in result["instructions"]
) is (size == 40_000)
assert len(json.dumps(result, separators=(",", ":")).encode()) <= 65536


Expand Down
10 changes: 10 additions & 0 deletions tests/control_plane/test_reward_memory_host_isolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ def test_recall_and_reflection_are_independently_opted_in(recall: bool, ingest:
prompt = _prompt(request)
assert ("When reward_memory_recall contains guidance" in prompt) is recall
assert ("Set reward_memory_reflection_json" in prompt) is ingest
assert ("compare current independent task evidence" in prompt) is (recall and ingest)
for consolidation_rule in (
"any comparable procedural_experience",
"If no comparable procedural experience was delivered",
"only confirms the same future behavior and limitations",
"establishes distinct reusable applicability or materially changes",
"Keep distinct applicability conditions separate",
"Do not claim to merge, update, retire, or supersede provider records",
):
assert (consolidation_rule in prompt) is (recall and ingest)
assert ("reward_memory_reflection_json" in codex_cli_result_schema(request)["properties"]) is ingest
assert bool(request["reward_memory_recall"].get("context")) is recall
if ingest:
Expand Down
Loading