Skip to content

Commit ea15bbf

Browse files
fix(orch): observe mapped handoffs during archive-plan re-entry (#27)
archive-plan discarded valid mapped-invariant executor results because _try_validate_task_handoff re-validated without observe=True or execution binding arguments. Forward those inputs so declared plan-level acceptance is no longer reported as missing. Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Ldsystem <Ldsystem@users.noreply.github.com>
1 parent 1126d01 commit ea15bbf

2 files changed

Lines changed: 108 additions & 1 deletion

File tree

scripts/orchestration/plans.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
unique_explicit_handoff_plan_id,
1010
validate_executor_result_for_task,
1111
_compile_task_brief,
12+
_observation_kwargs,
1213
_parse_scalar,
1314
)
1415
from handoffs import _read_compact_yaml_metadata
@@ -104,11 +105,18 @@ def _try_validate_task_handoff(
104105
handoff=None,
105106
base=None,
106107
head=None,
108+
**_observation_kwargs(args),
107109
)
108110
try:
109111
_, brief_document = _compile_task_brief(compile_args)
110112
brief = brief_document["task_brief"]
111-
validate_executor_result_for_task(handoff, brief)
113+
capability = brief.get("evidence_capability") if isinstance(brief.get("evidence_capability"), dict) else {}
114+
validate_executor_result_for_task(
115+
handoff,
116+
brief,
117+
observe=capability.get("result") == "mapped",
118+
**_observation_kwargs(args),
119+
)
112120
except SystemExit:
113121
return None
114122
return handoff, brief
@@ -524,6 +532,7 @@ def _assert_completed_task_handoff(args: argparse.Namespace, task_path: Path) ->
524532
handoff=str(handoff),
525533
base=None,
526534
head=None,
535+
**_observation_kwargs(args),
527536
)
528537
)
529538

tests/test_orchestration_workflow_contracts.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,104 @@ def test_failing_declared_plan_acceptance_blocks_archive_without_second_reviewer
10831083
assert (tmp_path / ".work-bundle/orchestration/plan/active/plan-B.md").is_file()
10841084

10851085

1086+
def _mapped_archive_workspace(tmp_path: Path):
1087+
from test_orchestration_execution_context import (
1088+
PASSING_PROCESS,
1089+
_bind_task_execution,
1090+
_compiled_brief,
1091+
_handoff_for_command,
1092+
_set_task_validation,
1093+
git,
1094+
workspace,
1095+
)
1096+
1097+
command = ARCHIVE_NEUTRAL_COMMAND
1098+
root, _, task = workspace(tmp_path)
1099+
task.write_text(
1100+
task.read_text(encoding="utf-8").replace(
1101+
"evidence_capability:\n"
1102+
" result: no_validation_bearing_obligation\n"
1103+
" reason: This shared fixture leaves capability semantics to scenario-specific tests.\n"
1104+
" invariants: []\n",
1105+
"evidence_capability:\n"
1106+
" result: mapped\n"
1107+
" reason: Archive re-entry must observe mapped invariants.\n"
1108+
" invariants:\n"
1109+
" - {id: INV-001, source_ids: [REQ-003], invariant: Observable behavior, boundary: integration, oracle: VAL-001, capability_reason: Process oracle distinguishes violation., freshness: current_task_batch, task_id: task-004, evidence_ids: [VAL-001], closure_result: pending}\n",
1110+
),
1111+
encoding="utf-8",
1112+
)
1113+
_set_task_validation(
1114+
task,
1115+
"validation:\n"
1116+
f" - {{kind: process, command: {json.dumps(PASSING_PROCESS)}, proves: TEST-004, expected: passed, id: VAL-001, invariant_ids: [INV-001], capability_reason: Process oracle distinguishes violation.}}\n",
1117+
)
1118+
_append_plan_knowledge(root, closure_return="missing")
1119+
_append_plan_integration_command(root, command)
1120+
git(root, "add", ".")
1121+
git(root, "commit", "-qm", "mapped archive workspace")
1122+
brief = _compiled_brief(root, task)
1123+
binding = _bind_task_execution(root, brief)
1124+
handoff = _handoff_for_command(root, PASSING_PROCESS)
1125+
handoff.write_text(
1126+
handoff.read_text(encoding="utf-8").replace(
1127+
f"- {{command: {json.dumps(PASSING_PROCESS)}, result: passed}}\n",
1128+
f"- {{command: {json.dumps(PASSING_PROCESS)}, result: passed, id: VAL-001, invariant_ids: [INV-001]}}\n"
1129+
f" - {{command: {command}, result: passed}}\n",
1130+
)
1131+
+ "evidence_closure:\n"
1132+
+ " result: passed\n"
1133+
+ " invariants:\n"
1134+
+ " - {id: INV-001, boundary: integration, freshness: current_task_batch, evidence_ids: [VAL-001], closure_result: passed}\n",
1135+
encoding="utf-8",
1136+
)
1137+
return root, binding, command
1138+
1139+
1140+
def test_archive_plan_accepts_mapped_invariant_handoff_with_harness_observation(tmp_path: Path) -> None:
1141+
from plans import cmd_archive_plan
1142+
1143+
root, _binding, _command = _mapped_archive_workspace(tmp_path)
1144+
1145+
cmd_archive_plan(argparse.Namespace(project_root=str(root), id="plan-001"))
1146+
1147+
assert (root / ".work-bundle/orchestration/plan/archived/compiler-plan.md").is_file()
1148+
1149+
1150+
def test_archive_plan_forwards_execution_binding_into_task_revalidation(tmp_path: Path) -> None:
1151+
from plans import cmd_archive_plan
1152+
1153+
root, binding, command = _mapped_archive_workspace(tmp_path)
1154+
1155+
cmd_archive_plan(
1156+
argparse.Namespace(
1157+
project_root=str(root),
1158+
id="plan-001",
1159+
workspace_id=binding["workspace_id"],
1160+
execution_id=binding["execution_id"],
1161+
repository_id=binding["repository_id"],
1162+
execution_runtime_root=binding["runtime_root"],
1163+
)
1164+
)
1165+
assert (root / ".work-bundle/orchestration/plan/archived/compiler-plan.md").is_file()
1166+
1167+
restored = tmp_path / "restored-mapped"
1168+
restored.mkdir()
1169+
restored_root, restored_binding, _command = _mapped_archive_workspace(restored)
1170+
with pytest.raises(SystemExit, match=rf"acceptance-blocked: declared plan-level acceptance {command} is missing"):
1171+
cmd_archive_plan(
1172+
argparse.Namespace(
1173+
project_root=str(restored_root),
1174+
id="plan-001",
1175+
workspace_id="wrong-workspace",
1176+
execution_id=restored_binding["execution_id"],
1177+
repository_id=restored_binding["repository_id"],
1178+
execution_runtime_root=restored_binding["runtime_root"],
1179+
)
1180+
)
1181+
assert (restored_root / ".work-bundle/orchestration/plan/active/compiler-plan.md").is_file()
1182+
1183+
10861184
def test_passing_declared_plan_acceptance_allows_archive_without_second_reviewer(tmp_path: Path) -> None:
10871185
from plans import cmd_archive_plan
10881186
from test_orchestration_execution_context import (

0 commit comments

Comments
 (0)