Bind approvals and feedback to the revision they were about
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m16s
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m16s
Fixes counterexamples 1-4 from specs/orchestrator.qnt: a repeated 'approve', 'approve rev-1' meant for the architecture, approving on both channels, and 'approve' plus an afterthought all landed on the next plan, one the operator had not seen. - Revisions are numbered across the work item (A4 already required monotonic tags; the code numbered per gate), so rev-N names one plan. - Each reply is stamped on arrival with the revision that was up: in Matrix the one whose approval request had been sent (a plain value the transport thread reads, restored on boot), in Gitea the latest plan comment older than the reply (board.posts). - Gate.evaluate applies a reply that names no revision only if its stamp is the current revision. Otherwise an approval is not applied and feedback rejects nothing (it is still in the transcript), and the agent says which revision is up. 'approve rev-N' binds by its number. - Spec A4 states both rules. The model applies them; scenarios 1-4 now expect the properties to hold, and both held over 200,000 random traces and Apalache's exhaustive check to depth 8. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
1 parent
6c83839f4d
commit
97863c1939
10 files changed
+324
-44
No files matched your search
@@ -229,8 +229,12 @@ def test_stop_reaches_work_running_on_the_worker(tmp_path: Path, word: str) -> N
|
||||
cancel=cancel,
|
||||
)
|
||||
worker.call(orch.start)
|
||||
for text in ("use demo", "approve", "approve", "start milestone 1"):
|
||||
for text in ("use demo", "approve", "approve"):
|
||||
transport.receive("don", text)
|
||||
# Reply only once the plan is up: a reply stamped with an earlier
|
||||
# revision is not applied to a later one.
|
||||
worker.call(lambda: None)
|
||||
transport.receive("don", "start milestone 1")
|
||||
assert executor.running.wait(5)
|
||||
|
||||
transport.receive("don", "status") # delivered while the milestone runs
|
||||
|
||||
Reference in new issue
Block a user