Skip to content

Commit 4fde92f

Browse files
committed
docs: preserve consensus validation intent before deletion
Record the feature intent, symbol-level inventory, wire-blockers, and git recovery path for teaagent/consensus/consensus_validation.py before any runtime deletion. This keeps Option D reversible as archaeology while making clear that restore-from-history is not authority to rewire the module. Action: G-P2-8 Roadmap-Status: unchanged Constraint: documentation and guard test only; no consensus code deletion or behavior change in this commit; unrelated .omo work orders left untracked Tested: ruff format --check tests/test_docs_consistency.py; ruff check tests/test_docs_consistency.py; scripts/validate_docs_consistency.py (29/29 risk, 21/21 ticket); pytest tests/test_docs_consistency.py -q (45 passed); docs-inventory and OKF catalog --check clean Not-tested: consensus module deletion, full acceptance/nightly suite, live providers, real dogfood Confidence: high
1 parent 7a7799d commit 4fde92f

4 files changed

Lines changed: 99 additions & 2 deletions

File tree

docs/adr/0029-consensus-validation-deferred.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ deletion checklist — import-graph guard, remove the module and its
4646
roadmap/backlog — and may land at or before the 2026-12-10 review. Until
4747
executed, the module stays `experimental — unwired`.
4848

49+
Preservation requirement before deletion: keep the feature intent, symbol-level
50+
inventory, wire-blockers, and git recovery commands in
51+
`../specs/consensus-validation-disposition-spec-2026-07-11.md` §2. Deletion may
52+
remove runtime files and tests, but it must not remove the historical record
53+
needed to recover or evaluate the design from git history.
54+
4955
## References
5056

5157
- [Work Direction Decomposition (WDA-006)](../plans/work-direction-decomposition-2026-06-10.md)

docs/generated/docs-inventory.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Do not edit this file manually — regenerate instead.
3939
| `adr/0026-cli-execution-abstraction-layer.md` | working | 560 | `2498fb2f04a4` |
4040
| `adr/0027-context-bus-architecture.md` | working | 543 | `6fa1d2ced665` |
4141
| `adr/0028-tournament-swarm-architecture.md` | working | 594 | `ee8dec0fdb60` |
42-
| `adr/0029-consensus-validation-deferred.md` | working | 2288 | `f3aeee58e959` |
42+
| `adr/0029-consensus-validation-deferred.md` | working | 2641 | `cf627c48c05f` |
4343
| `adr/0030-root-module-freeze.md` | working | 1297 | `bee25422e85f` |
4444
| `adr/0031-shadow-mode-exit-criteria.md` | working | 3598 | `46a9a0d5eaac` |
4545
| `adr/0032-run-event-taxonomy.md` | working | 16065 | `b9f0c0d7c30a` |
@@ -564,7 +564,7 @@ Do not edit this file manually — regenerate instead.
564564
| `specs/architecture-spec.md` | working | 5496 | `1bc7809ba2a7` |
565565
| `specs/automation-lifecycle-spec-2026-06-01.md` | archive | 5311 | `e27fe2b64798` |
566566
| `specs/background-lifecycle-acceptance-spec-2026-07-11.md` | archive | 9352 | `d064d1f8c46b` |
567-
| `specs/consensus-validation-disposition-spec-2026-07-11.md` | archive | 9509 | `ebc1215f76a8` |
567+
| `specs/consensus-validation-disposition-spec-2026-07-11.md` | archive | 13873 | `41deb85d9e3b` |
568568
| `specs/daily-driver-persona-journey-maps-2026-06-01.md` | archive | 7676 | `a63800c54c69` |
569569
| `specs/daily-driver-tui-controller-migration-spec-2026-06-01.md` | archive | 6486 | `b10ee8d93a62` |
570570
| `specs/daily-driver/approval-scope-contract-2026-06-02.md` | archive | 869 | `6e8964afe6e6` |

docs/specs/consensus-validation-disposition-spec-2026-07-11.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,77 @@ third parallel consensus surface. Destructive actions flow through the
5959
approval queue + JIT approval coordinator only. Nothing here changes that;
6060
this spec exists so the expiry review is a decision, not an investigation.
6161

62+
### 2.1 Pre-deletion preservation record (2026-07-22)
63+
64+
This section exists so `consensus_validation` remains recoverable after Option D
65+
deletes the code. Deletion must remove the runtime surface, not the historical
66+
intent, feature inventory, or revival path.
67+
68+
#### 2.1.1 Original intent
69+
70+
`consensus_validation` was intended as a **post-approval multi-agent consensus
71+
validator** for collaborative or destructive actions that had already passed the
72+
normal approval queue. It was never supposed to replace ADR-0022's centralized
73+
approval queue; the safe wiring shape was a second key behind the queue for a
74+
narrow action class.
75+
76+
The surviving design question, if revived, is: "Do we need a separate N-of-M /
77+
role-based sign-off gate after the existing queue has approved a destructive
78+
action?" Absent that owner friction or governance-gap evidence, DR-006 favors
79+
deletion over preserving dormant code.
80+
81+
#### 2.1.2 Feature inventory to preserve in history
82+
83+
The module at `teaagent/consensus/consensus_validation.py` contained:
84+
85+
| Area | Symbols / behavior | Revival note |
86+
| --- | --- | --- |
87+
| Status model | `ConsensusStatus`: `pending`, `approved`, `rejected`, `expired`, `cancelled` | Keep terminal-state semantics explicit if rebuilt. |
88+
| Rule model | `ConsensusRuleType`: `N_OF_M`, `UNANIMOUS`, `MAJORITY`, `SUPERMAJORITY`, `ROLE_BASED`; `ConsensusRule.check_consensus()` | Rebuild only the rule types needed by real policy; do not automatically restore `SUPERMAJORITY`. |
89+
| Role-based voting | `ROLE_BASED` rules consult `voter_roles`; absent a mapping, `voter_id` is treated as the role | This was the 2026-06-30 A-P2-7 fix; keep it if role-based consensus returns. |
90+
| Request model | `ConsensusRequest`: action, context, requester, votes, voter roles, timestamps, expiry, metadata | Revote currently overwrote silently; audited revote events are required before destructive-action wiring. |
91+
| Storage | `ConsensusStore`: tenant-scoped JSON under `.teaagent/consensus-rules` and `.teaagent/consensus-requests` using `atomic_write_text` | Reuse only if file-backed request state is still desired; otherwise prefer the approval queue's store. |
92+
| Validator facade | `ConsensusValidator`: `create_rule`, `request_consensus`, `cast_vote`, `get_consensus_status`, `create_default_rules` | Facade was not imported by production paths. A revived version must integrate through the approval queue. |
93+
| Policy bridge | `create_rule()` created `PolicyType.CONSENSUS` allow policies with `rule_id` metadata | Bridge was inert without a queue hook; rebuild with a real policy condition contract or delete it. |
94+
| Default rules | 2-of-3 production deploy, unanimous destructive action, majority operational decision | Treat as examples, not product requirements. |
95+
96+
Known wire-blockers that history must not hide:
97+
98+
- `SUPERMAJORITY` counted only votes cast, not `total_voters`; a single YES vote
99+
could approve. Destructive-action revival must use quorum semantics or remove
100+
this rule type from wireable policy.
101+
- `ConsensusRequest.add_vote()` overwrote prior votes silently. Revival needs an
102+
audited revote or immutable-vote contract.
103+
- The module emitted no ADR-0032 audit events and had no approval-queue hold
104+
hook. Any revival starts with the event/queue integration, not the old facade.
105+
- The CLI `consensus *` commands used the separate ADR-0019 federated engine;
106+
they were not proof that this validation module was live.
107+
108+
#### 2.1.3 Git recovery path
109+
110+
Known-good code anchor when this preservation record was written:
111+
`7a7799d` (`docs: record owner-ratified intent decisions and intent-roadmap survey`).
112+
The deletion commit's parent should also contain the final pre-deletion code.
113+
114+
To find the deleted module later:
115+
116+
```bash
117+
git log --all --follow -- teaagent/consensus/consensus_validation.py
118+
git show 7a7799d:teaagent/consensus/consensus_validation.py
119+
git show <deletion_commit>^:teaagent/consensus/consensus_validation.py
120+
```
121+
122+
To restore the last pre-deletion implementation for investigation, not automatic
123+
re-adoption:
124+
125+
```bash
126+
git restore --source=<deletion_commit>^ -- teaagent/consensus/consensus_validation.py
127+
git restore --source=<deletion_commit>^ -- tests/test_consensus.py tests/test_consensus_disposition_spec.py
128+
```
129+
130+
Then re-run the decision matrix in §3.3. Restoring from history is evidence
131+
recovery, not authority to wire the module.
132+
62133
## 3. Future contract — both options
63134

64135
### 3.1 Option W: wire behind the approval queue

tests/test_docs_consistency.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,26 @@ def test_intent_review_candidate_adoption_state() -> None:
354354
assert 'a new strategy doc, separate execution-plan doc' in review
355355

356356

357+
def test_consensus_validation_deletion_preserves_recovery_record() -> None:
358+
root = Path(__file__).resolve().parents[1]
359+
spec = (
360+
root / 'docs' / 'specs' / 'consensus-validation-disposition-spec-2026-07-11.md'
361+
).read_text(encoding='utf-8')
362+
adr = (root / 'docs' / 'adr' / '0029-consensus-validation-deferred.md').read_text(
363+
encoding='utf-8'
364+
)
365+
assert '### 2.1 Pre-deletion preservation record (2026-07-22)' in spec
366+
assert '`ConsensusRuleType`: `N_OF_M`, `UNANIMOUS`, `MAJORITY`' in spec
367+
assert '`ConsensusValidator`: `create_rule`, `request_consensus`' in spec
368+
assert '`SUPERMAJORITY` counted only votes cast' in spec
369+
assert 'Revival needs an\n audited revote' in spec
370+
assert 'git show 7a7799d:teaagent/consensus/consensus_validation.py' in spec
371+
assert 'git restore --source=<deletion_commit>^' in spec
372+
assert 'Restoring from history is evidence\nrecovery, not authority' in spec
373+
assert 'Preservation requirement before deletion' in adr
374+
assert 'symbol-level\ninventory, wire-blockers, and git recovery commands' in adr
375+
376+
357377
def test_doc_cross_references_fail_for_non_historical_docs(tmp_path: Path) -> None:
358378
docs = tmp_path / 'docs'
359379
docs.mkdir()

0 commit comments

Comments
 (0)