diff --git a/docs/reference/protocols/turn-envelope-v0.md b/docs/reference/protocols/turn-envelope-v0.md index 7d185eb049..65a3485e0d 100644 --- a/docs/reference/protocols/turn-envelope-v0.md +++ b/docs/reference/protocols/turn-envelope-v0.md @@ -134,12 +134,19 @@ interpreter's `-m loopx.entrypoint` route rather than an unrelated PATH executab Native reads propagate that route through review, acceptance and writeback; the complete original observation is not rewritten to carry a new command. The review stage provides structured facts without a prescribed diagnostic -method. Writeback omits filled-in Vision/stride examples while retaining field -limits, legal options, source bindings and settlement rules. Stride exposes its -required field names and basis options independently of examples. The unchanged -full capture remains available for optional examples and source inspection. -This intentionally reduces advisory prompting; it does not remove acceptance, -authority or stop obligations, nor demonstrate better autonomous decisions. +method. Writeback omits the generic filled-in Vision example while retaining +field limits, legal options, source bindings and settlement rules. Enabled +Stride retains its owner's current `minimal_example`, including the nested +previous-decision and Explore review fields when applicable. Top-level required +field names alone do not describe that authoring shape. The example supplies +syntax, not a recommended decision or evidence of adoption; replace its claims +with the reviewed facts. Decision evidence remains in review/Explore and the +unchanged full capture. This changes no acceptance, authority, stop rule or +validation budget, and does not establish fewer model retries or better results. + +中文:写回保留 Stride owner 的当前格式示例,包含适用的上次决策与 Explore 复盘 +嵌套字段。示例只说明语法,判断与证据仍来自本次复盘;验收、权限、停止条件和校验 +预算不变。字段完整性不代表模型已采用,也不证明重试减少或结果改善。 Cumulative outcome requirements are indexed by exact content hash. Every objective, revision and requirement count remains visible; the acceptance read @@ -303,9 +310,10 @@ TurnEnvelope 先给出 `review` 状态读取,再给出 `writeback` 格式读 捕获后的读取沿用调用方显式选择的 `--cli-bin`,后续验收和 Explore 读取也不会 悄悄切换到环境中的其他版本。复盘视图提供结构化事实,不预设诊断方法;写回视图 -移除预填的 Vision/stride 答案示例,保留字段限制、合法选项、来源绑定和结算规则。 -stride 的必需字段与 basis 选项独立展示,完整快照仍可用于按需查看示例与源材料。 -这是有意减少建议性提示,不删除验收、权限或停止义务,也不证明自主决策质量提升。 +只移除通用 Vision 的预填示例,保留字段限制、合法选项、来源绑定和结算规则。 +启用 Stride 时保留当前 owner 的嵌套语法示例,必需字段与 basis 选项也独立展示; +判断和证据仍须来自实际复盘,完整快照仍可按需读取。示例不代表推荐决定或已采用 +证据,不删除验收、权限或停止义务,也不证明自主决策质量提升。 新决定用精简的目标、证据和权限边界替换原方法清单及重复的 stride 规划建议:复盘 一次交付这些边界与事实,写回提供既有格式。可执行 Todo 的次序和 agent 自拟候选 diff --git a/loopx/control_plane/quota/turn_envelope.ts b/loopx/control_plane/quota/turn_envelope.ts index b3df259152..444aafca16 100644 --- a/loopx/control_plane/quota/turn_envelope.ts +++ b/loopx/control_plane/quota/turn_envelope.ts @@ -506,7 +506,9 @@ function replanView(request: JsonObject): JsonObject { // Preserve executable shape and all settlement rules; decision advice and // duplicate context are available in the unchanged full captured source. const stride = {...object(packet.stride_control)}; - for (const key of ["decision_followthrough", "explore_basis", "decision_value_review", "minimal_example"]) delete stride[key]; + // The current nested review syntax belongs to authoring, not duplicate + // decision evidence. Top-level required_fields cannot describe that shape. + for (const key of ["decision_followthrough", "explore_basis", "decision_value_review"]) delete stride[key]; const contract = {...object(packet.writeback_contract)}; if (contract.vision_authoring) { const authoring = {...object(contract.vision_authoring)}; diff --git a/tests/control_plane/test_replan_staged_read.py b/tests/control_plane/test_replan_staged_read.py index 97e12fb036..f8cee18e4d 100644 --- a/tests/control_plane/test_replan_staged_read.py +++ b/tests/control_plane/test_replan_staged_read.py @@ -78,7 +78,7 @@ def test_staged_packet_budget_and_lossless_authority(stride): control = writer["stride_control"] assert control["previous_decision_ref"] == source["replan_action_packet"]["stride_control"]["previous_decision_ref"] assert "decision_followthrough" not in control and "decision_value_review" not in control - assert "minimal_example" not in control + assert control["minimal_example"] == source["replan_action_packet"]["stride_control"]["minimal_example"] assert control["basis_options"] == ["supported_progress", "unexplained_gap", "uncertain_evidence", "useful_new_route", "decision_failure"] assert {"basis", "action", "axes", "next_probe"} <= set(control["required_fields"]) assert source == original @@ -672,7 +672,18 @@ def test_explore_uses_its_own_incremental_budget_and_real_result_log(tmp_path): cli_detail = call_progress_cli(reader_fixture, *command[3:]) assert cli_detail["explore_basis"] == basis assert {row["status"] for row in basis["finding_refs"]} >= {"confirmed", "refuted"} - _, _, params = _views(enabled) - writer = _turn_envelope_result("replan_view", **params, stage="writeback") + writer_command = shlex.split(cli_review["next"]["writeback"]) + writer = call_progress_cli(reader_fixture, *writer_command[3:]) assert writer["stride_control"]["reference_context_id"] == review["context_id"] + control = writer["stride_control"] + example = control["minimal_example"] + assert set(control["required_fields"]) <= example.keys() + assert set(example["previous_review"]) == { + "reference_decision_ref", "adoption", "information_gain", "goal_gain", "evidence_refs", "lesson", + } + assert example["previous_review"]["reference_decision_ref"] == control["previous_decision_ref"] + assert {example["previous_review"][key] for key in ("adoption", "information_gain", "goal_gain")} == {"unknown"} + assert set(example["explore_review"]) >= {"revision", "disposition", "considered_refs", "reason"} + assert example["explore_review"]["revision"] == basis["revision"] + assert example["explore_review"]["considered_refs"] == [] assert json_bytes(writer) <= 16 * 1024