-
Notifications
You must be signed in to change notification settings - Fork 7
fix(agent-loop): reconcile exact root recovery evidence #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
77f0e28
74b6fa1
d011c47
2b32ffb
5317fcc
9bb2b98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| # Chunk Contract: WS-ENG-ROOT-001-02 — Exact Root Reconciliation Recovery | ||
|
|
||
| ## Goal | ||
|
|
||
| Preserve the reviewed schema-v7 recovery policy while shared reconciliation | ||
| collects PR #205, then consume PR #205 and this repair as one exact sequence. | ||
|
|
||
| ## Risk class | ||
|
|
||
| L0 | ||
|
|
||
| ## Start phase | ||
|
|
||
| `implementation` | ||
|
|
||
| ## Machine-checkable scope | ||
|
|
||
| ```chunk-scope-json | ||
| { | ||
| "schema_version": 1, | ||
| "chunk_id": "WS-ENG-ROOT-001-02", | ||
| "phase": "implementation", | ||
| "risk_class": "L0", | ||
| "allowed_paths": [ | ||
| ".agent-loop/policies/loop-memory-recovery.json", | ||
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/**", | ||
| ".agent-loop/merge-intents/WS-ENG-ROOT-001-02.json", | ||
| ".agent-loop/merge-intents/WS-ENG-ROOT-001-01.json", | ||
| "scripts/check_loop_memory_state.py", | ||
| "scripts/check_chunk_contract.py", | ||
| "scripts/update_post_merge_memory.py", | ||
| "scripts/test_agent_gates.py", | ||
| "scripts/test_check_chunk_contract.py", | ||
| "scripts/test_check_loop_memory_state.py", | ||
| "scripts/test_update_post_merge_memory.py" | ||
| ], | ||
| "forbidden_paths": ["backend/**", "frontend/**", ".github/**"], | ||
| "required_reviewers": ["senior engineering", "qa/test", "security/auth", "product/ops", "architecture", "ci integrity", "docs", "reuse/dedup", "test delta"], | ||
| "verification_commands": ["agent-gate-tests", "loop-memory-state", "loop-memory-recovery-tests", "chunk-scope-tests", "internal-review-evidence", "markdown-links", "stale-wording", "git-diff-check"] | ||
| } | ||
| ``` | ||
|
|
||
| ## Allowed files | ||
|
|
||
| ```text | ||
| .agent-loop/policies/loop-memory-recovery.json | ||
| .agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/** | ||
| .agent-loop/merge-intents/WS-ENG-ROOT-001-02.json | ||
| .agent-loop/merge-intents/WS-ENG-ROOT-001-01.json | ||
| scripts/check_loop_memory_state.py | ||
| scripts/check_chunk_contract.py | ||
| scripts/update_post_merge_memory.py | ||
| scripts/test_agent_gates.py | ||
| scripts/test_check_chunk_contract.py | ||
| scripts/test_check_loop_memory_state.py | ||
| scripts/test_update_post_merge_memory.py | ||
| ``` | ||
|
|
||
| ## Not allowed | ||
|
|
||
| ```text | ||
| backend/** | ||
| frontend/** | ||
| .github/** | ||
| product behavior, workflow changes, dependencies, reusable recovery authority | ||
| ``` | ||
|
|
||
| ## Acceptance criteria | ||
|
|
||
| - [ ] `reconcile_to_main` recollects schema-v7/v8 recovery merges with the exact | ||
| immutable policy used during preparation. | ||
| - [ ] Schema v8 binds signed basis `339248c4`, PR #205 merge `ce512bdb`, this | ||
| activation identity, adjacency, exact paths, null successor, and fixed | ||
| recovery-only evidence. | ||
| - [ ] Both exemptions are consumed and neither persists in signed history. | ||
| - [ ] Mutation, replay, wrong-order, wrong-parent, and foreign-identity cases fail. | ||
| - [ ] No product, workflow, dependency, coverage, start, or authorization behavior changes. | ||
|
|
||
| ## Verification commands | ||
|
|
||
| ```bash | ||
| python3 scripts/test_agent_gates.py | ||
| PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_update_post_merge_memory.py scripts/test_check_loop_memory_state.py | ||
| python3 scripts/check_loop_memory_state.py | ||
| python3 scripts/test_check_chunk_contract.py | ||
| python3 scripts/check_internal_review_evidence.py | ||
| python3 scripts/check_markdown_links.py | ||
| python3 scripts/check_stale_workstream_wording.py | ||
| git diff --check origin/main...HEAD | ||
| ``` | ||
|
|
||
| ## Required reviewers | ||
|
|
||
| - [ ] senior engineering | ||
| - [ ] qa/test | ||
| - [ ] security/auth | ||
| - [ ] product/ops | ||
| - [ ] architecture | ||
| - [ ] ci integrity | ||
| - [ ] docs | ||
| - [ ] reuse/dedup | ||
| - [ ] test delta | ||
|
|
||
| ## Human review focus | ||
|
|
||
| Confirm the authority is exact, adjacent, one-use, and cannot admit a third merge. | ||
|
|
||
| ## Stop conditions | ||
|
|
||
| Stop if the policy becomes reusable, paths widen, checks weaken, or product code changes. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # WS-ENG-ROOT-001-02 Internal Review Evidence | ||
|
|
||
| Reviewed code SHA: `2b32ffb446d3ad4bc4a97b926d880b8ef98b8fe0` | ||
|
|
||
| Reviewed at: `2026-07-26T18:00:00Z` | ||
|
|
||
| Reviewer run IDs: `r2f_senior`, `r2f_qa`, `r2f_security`, `r2f_product`, | ||
| `r2f_arch`, `r2f_ci`, `r2f_docs`, `r2f_reuse`, `r2f_testdelta` | ||
|
|
||
| ## Commands Run | ||
|
|
||
| ```bash | ||
| python3 scripts/test_agent_gates.py | ||
| python3 scripts/test_check_chunk_contract.py | ||
| python3 scripts/check_loop_memory_state.py | ||
| PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest -q scripts/test_update_post_merge_memory.py scripts/test_check_loop_memory_state.py | ||
| python3 scripts/check_internal_review_evidence.py | ||
| python3 scripts/check_markdown_links.py | ||
| python3 scripts/check_stale_workstream_wording.py | ||
| git diff --check origin/main...HEAD | ||
| ``` | ||
|
|
||
| ## Reviewer Results | ||
|
|
||
| | Reviewer | Result | Blocking findings | Notes | | ||
| |---|---|---|---| | ||
| | senior engineering | PASS AFTER FIXES | none | The final evidence file completes the exact certificate reserved in the reviewed implementation. | | ||
| | QA/test | PASS WITH LOW RISKS | none | Adversarial schema-v8 recovery, order, parent, identity, evidence, and policy cases pass. | | ||
| | security/auth | PASS | none | Recovery authority is exact, adjacent, identity-bound, and one-use. | | ||
| | product/ops | PASS | none | AUTH remains stopped until canonical reconciliation succeeds. | | ||
| | architecture | PASS | none | Independent validators preserve the closed schema-v8 boundary. | | ||
| | CI integrity | PASS | none | Existing coverage gates pass at 90.23 and 90.65 percent without weakening. | | ||
| | docs | PASS | none | Contract, status, trust bundle, policy, and intent are aligned. | | ||
| | reuse/dedup | PASS | none | Exact duplication is deliberate independent validation. | | ||
| | test delta | PASS | none | No test, assertion, threshold, or command was removed or weakened. | | ||
|
|
||
| ## Findings Resolved | ||
|
|
||
| Valid findings addressed: yes | ||
|
|
||
| Open sub-agent sessions: none | ||
|
|
||
| The first candidate omitted self-admission, then fell below the unchanged | ||
| coverage floors. The reviewed implementation added exact schema-v8 admission, | ||
| adversarial recovery proof, independent PR #205 pinning, and sufficient branch | ||
| coverage. This evidence-only file completes the pre-reviewed exact path | ||
| certificate without changing implementation. | ||
|
|
||
| ## Remaining Gate | ||
|
|
||
| GitHub checks, external review, and the explicit human recovery merge | ||
| checkpoint remain. AUTH must stay stopped until generated signed state reaches | ||
| the reconciliation merge and consumes both exemptions. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # PR Trust Bundle: WS-ENG-ROOT-001-02 | ||
|
|
||
| ## Intent and scope | ||
|
|
||
| Fix only the post-merge recollection loss that prevented PR #205 reconciliation. | ||
| The closed schema-v8 policy names PR #205 as the sole recovered merge and this | ||
| chunk as the sole activation, with a null successor. | ||
|
|
||
| ## Design | ||
|
|
||
| Recovery preparation and reconciliation use the same immutable target policy. | ||
| Both adjacent records receive recovery-only evidence, are admitted through the | ||
| ephemeral exemption inventory, and must be fully consumed. | ||
|
|
||
| ## Evidence | ||
|
|
||
| Pending deterministic checks and required internal review evidence. | ||
|
|
||
| ## Risks and human focus | ||
|
|
||
| Review the exact SHA/PR/chunk bindings, first-parent adjacency, independent | ||
| validator parity, mutation coverage, and absence of reusable authority. | ||
|
|
||
| ## Stop | ||
|
|
||
| Human approval is required before push, PR, or merge action. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| { | ||
| "schema_version": 2, | ||
| "initiative_id": "WS-ENG-ROOT-001", | ||
| "chunk_id": "WS-ENG-ROOT-001-02", | ||
| "chunk_title": "Exact Root Reconciliation Recovery", | ||
| "next_chunk_id": null, | ||
| "next_chunk_title": null, | ||
| "next_requires_explicit_start": true | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,16 @@ | ||
| { | ||
| "activation": { | ||
| "chunk_id": "WS-ENG-ROOT-001-01", | ||
| "chunk_id": "WS-ENG-ROOT-001-02", | ||
| "initiative_id": "WS-ENG-ROOT-001" | ||
| }, | ||
| "signed_basis": "339248c40020658583bf7bd1e4a58daf85f5ffb8", | ||
| "recovered_merges": [], | ||
| "schema_version": 7 | ||
| "recovered_merges": [ | ||
| { | ||
| "initiative_id": "WS-ENG-ROOT-001", | ||
| "chunk_id": "WS-ENG-ROOT-001-01", | ||
| "pr_number": 205, | ||
| "merge_sha": "ce512bdb6ae47e94ae8067845531cacfc3378a85" | ||
| } | ||
| ], | ||
| "schema_version": 8 | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -90,6 +90,41 @@ | |
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/reviews/WS-ENG-ROOT-001-01-pr-trust-bundle.md", | ||
| *ROOT_RECOVERY_ALLOWED[3:], | ||
| }) | ||
| ROOT_RECONCILE_BASE = "ce512bdb6ae47e94ae8067845531cacfc3378a85" | ||
| ROOT_RECONCILE_CHUNK = "WS-ENG-ROOT-001-02" | ||
| ROOT_RECONCILE_CONTRACT = ( | ||
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/" | ||
| "chunks/WS-ENG-ROOT-001-02-exact-root-reconciliation-recovery.md" | ||
| ) | ||
| ROOT_RECONCILE_ALLOWED = ( | ||
| ".agent-loop/policies/loop-memory-recovery.json", | ||
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/**", | ||
| ".agent-loop/merge-intents/WS-ENG-ROOT-001-02.json", | ||
| ".agent-loop/merge-intents/WS-ENG-ROOT-001-01.json", | ||
| "scripts/check_loop_memory_state.py", | ||
| "scripts/check_chunk_contract.py", | ||
| "scripts/update_post_merge_memory.py", | ||
| "scripts/test_agent_gates.py", | ||
| "scripts/test_check_chunk_contract.py", | ||
| "scripts/test_check_loop_memory_state.py", | ||
| "scripts/test_update_post_merge_memory.py", | ||
| ) | ||
| ROOT_RECONCILE_PATHS = frozenset({ | ||
| ".agent-loop/policies/loop-memory-recovery.json", | ||
| ".agent-loop/merge-intents/WS-ENG-ROOT-001-02.json", | ||
| ".agent-loop/merge-intents/WS-ENG-ROOT-001-01.json", | ||
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/STATUS.md", | ||
| ROOT_RECONCILE_CONTRACT, | ||
| ROOT_RECOVERY_CONTRACT, | ||
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/reviews/WS-ENG-ROOT-001-02-internal-review-evidence.md", | ||
| ".agent-loop/initiatives/WS-ENG-ROOT-001-planning-intake-gate-recovery/reviews/WS-ENG-ROOT-001-02-pr-trust-bundle.md", | ||
| "scripts/check_chunk_contract.py", | ||
| "scripts/check_loop_memory_state.py", | ||
| "scripts/update_post_merge_memory.py", | ||
| "scripts/test_agent_gates.py", | ||
| "scripts/test_check_chunk_contract.py", | ||
| "scripts/test_update_post_merge_memory.py", | ||
| }) | ||
|
Comment on lines
+93
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔴 Critical | 🏗️ Heavy lift Move reconciliation authorization to immutable pre-PR state. The reconciliation exception currently validates PR-controlled constants, policy, contract, and tests against one another, rather than against an independently trusted certificate.
📍 Affects 2 files
🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| class ContractError(ValueError): | ||
|
|
@@ -613,6 +648,71 @@ def root_recovery_scope( | |
| ) | ||
|
|
||
|
|
||
| def root_reconcile_scope( | ||
| repo: Path, base: str, head: str, intent: dict[str, Any] | ||
| ) -> ScopeContract | None: | ||
| """Admit only the exact schema-v8 repair that consumes PR #205.""" | ||
| if intent["chunk_id"] != ROOT_RECONCILE_CHUNK: | ||
| return None | ||
| if intent["initiative_id"] != ROOT_RECOVERY_INITIATIVE: | ||
| raise ContractError("root reconciliation merge intent identity is invalid") | ||
| resolved_base = _decode_utf8( | ||
| _git(repo, "rev-parse", f"{base}^{{commit}}"), "root reconciliation base" | ||
| ).strip() | ||
| if resolved_base != ROOT_RECONCILE_BASE: | ||
| raise ContractError("root reconciliation is not based on exact PR 205 merge") | ||
| expected_policy = { | ||
| "activation": {"chunk_id": ROOT_RECONCILE_CHUNK, "initiative_id": ROOT_RECOVERY_INITIATIVE}, | ||
| "signed_basis": ROOT_RECOVERY_SIGNED_BASIS, | ||
| "recovered_merges": [{ | ||
| "initiative_id": ROOT_RECOVERY_INITIATIVE, | ||
| "chunk_id": ROOT_RECOVERY_CHUNK, | ||
| "pr_number": 205, | ||
| "merge_sha": ROOT_RECONCILE_BASE, | ||
| }], | ||
| "schema_version": 8, | ||
| } | ||
| if _git_json(repo, f"{head}:.agent-loop/policies/loop-memory-recovery.json") != expected_policy: | ||
| raise ContractError("root reconciliation certificate is invalid or reusable") | ||
| statuses = parse_name_status_z(_git( | ||
| repo, "diff", "--name-status", "-z", "--find-renames", | ||
| "--find-copies-harder", f"{base}...{head}" | ||
| )) | ||
| if any(status not in {"A", "M"} and not status.startswith("C") for status, _names in statuses): | ||
| raise ContractError("root reconciliation permits only exact added or modified files") | ||
| paths = validate_path_bytes(name for _status, names in statuses for name in names) | ||
| if frozenset(paths) != ROOT_RECONCILE_PATHS: | ||
| raise ContractError("root reconciliation delta does not match exact path certificate") | ||
| contract_raw = _git(repo, "show", f"{head}:{ROOT_RECONCILE_CONTRACT}") | ||
| heading = HEADING_RE.match(_decode_utf8(contract_raw)) | ||
| try: | ||
| scope_data = json.loads(machine_block(contract_raw), object_pairs_hook=_object) | ||
| except (json.JSONDecodeError, ContractError) as exc: | ||
| raise ContractError(f"root reconciliation contract scope is malformed: {exc}") from exc | ||
| expected_scope = { | ||
| "schema_version": 1, "chunk_id": ROOT_RECONCILE_CHUNK, | ||
| "phase": "implementation", "risk_class": "L0", | ||
| "allowed_paths": list(ROOT_RECONCILE_ALLOWED), | ||
| "forbidden_paths": ["backend/**", "frontend/**", ".github/**"], | ||
| "required_reviewers": [ | ||
| "senior engineering", "qa/test", "security/auth", "product/ops", | ||
| "architecture", "ci integrity", "docs", "reuse/dedup", "test delta", | ||
| ], | ||
| "verification_commands": [ | ||
| "agent-gate-tests", "loop-memory-state", "loop-memory-recovery-tests", | ||
| "chunk-scope-tests", "internal-review-evidence", "markdown-links", | ||
| "stale-wording", "git-diff-check", | ||
| ], | ||
| } | ||
| if heading is None or heading.group("id") != ROOT_RECONCILE_CHUNK or scope_data != expected_scope: | ||
| raise ContractError("root reconciliation contract scope is not exact") | ||
| return ScopeContract( | ||
| ROOT_RECONCILE_CHUNK, "implementation", "L0", ROOT_RECONCILE_ALLOWED, | ||
| ("backend/**", "frontend/**", ".github/**"), | ||
| tuple(expected_scope["required_reviewers"]), tuple(expected_scope["verification_commands"]), | ||
| ) | ||
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class SignedStart: | ||
| ledger_index: int | ||
|
|
@@ -829,6 +929,9 @@ def select_contract( | |
| recovery = root_recovery_scope(repo, base, head, intent) | ||
| if recovery is not None: | ||
| return recovery, None | ||
| reconciliation = root_reconcile_scope(repo, base, head, intent) | ||
| if reconciliation is not None: | ||
| return reconciliation, None | ||
| start = latest_signed_start(records, intent["chunk_id"]) | ||
| if start.initiative_id != intent["initiative_id"]: | ||
| raise ContractError("signed start initiative disagrees with merge intent") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Update the trust-bundle evidence state.
Line 17 conflicts with the completed checks and review evidence recorded in
WS-ENG-ROOT-001-02-internal-review-evidence.md. State only the remaining external/human gates.🤖 Prompt for AI Agents