[issue-3200][slice-3/10] Derive - #3238
Conversation
…lice-3, task-3-1) Add a purely mechanical derivation of the four #3189 deterministic anchor fields from the BRC message record (the same list-of-dicts read_peer_artifact / _write_brc_history serialize): (i) last-reviewed SHA per producer, (ii) latest verdict per reviewer->producer edge, (iii) open NACK reasons (current-version NACKs not yet superseded), (iv) conditional-ACK obligations (pre_merge_condition, resolved/unresolved). The derivation reads only structured message fields (never agent-authored prose) and mirrors orchestrator.peer_consensus replay semantics — proposal versions advance on re-propose; verdicts/obligations against a superseded version become historical — without depending on the orchestrator package. egg_anchor models extended additively: ReviewVerdict / ReviewEdgeVerdict / OpenNack / ConditionalAckObligation / BRCDerivedAnchors, plus an optional BRCState.derived field (default None). BRCState.acks/nacks/last_message_id keep their original meaning untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Skip-guarded tests for the four-field deterministic anchor derivation the coder lands in task-3-1: last-reviewed SHA per producer, latest verdict per reviewer->producer edge, open NACK reasons on the current proposal version, and conditional-ACK obligations with resolved/unresolved status. Two ground-truth tests run today (no guard): the ApprovalMatrix substrate projection (orchestrator) and BRCState legacy-field non-regression (egg_anchor). The seven derivation-output assertions skip until the coder's symbol merges, per the parallel-BRC-producer slice convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The coder's task-3-1 (derive_brc_anchors, BRCDerivedAnchors) merged: messages are plain dicts with a nested metadata, and ACK/NACK carry the producer in to_role. Align the fixtures to that contract so the previously skip-guarded assertions activate. All 9 tests pass against the merged implementation: four-field derivation correctness, resolved-vs-unresolved obligation, deterministic output, ApprovalMatrix substrate cross-check, and BRCState legacy non-regression. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
Autofix tracking{"Lint/Python": 2} |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Contract verification — PR #3238 (issue-3200, slice-3 "Derive")
Verdict: Approve. Both slice-3 tasks are fully implemented and every per-task acceptance criterion is objectively met. I re-ran the two derivation test files locally (shared/egg_anchor/tests/test_brc_anchor_derivation.py + orchestrator/tests/test_brc_anchor_derivation.py) — 9 passed.
task-3-1 — derive the four #3189 anchor fields ✅
shared/egg_anchor/brc_derive.py::derive_brc_anchors computes all four fields mechanically from the BRC message record:
| Field | Evidence |
|---|---|
| (i) last-reviewed SHA per producer | _assemble picks the SHA of the highest version any reviewer verdicted on (brc_derive.py:210-221); superseded v1 is correctly excluded |
| (ii) latest verdict per reviewer→producer edge | edge map overwrites on each ACK/NACK in replay order (:160-187), emitted as ReviewEdgeVerdict |
| (iii) open NACKs (current version only) | gated on state["version"] == current (:241-254) — superseded NACKs dropped |
| (iv) conditional-ACK obligations w/ resolved status | pre_merge_condition → ConditionalAckObligation, CONSENSUS_OBLIGATION_RESOLVED flips resolved (:189-197, :255-264) |
- Purely from the message record / no agent prose — verified: only structured fields are read (
message_type,from_role,to_role,metadata);_nack_reasondeliberately takes the structuredpayload.reason/meta.reason, never the free-formbody(:104-109). Sound, and the design avoids any orchestrator-package dependency. - Additive, no break to legacy fields — verified:
BRCState.acks/nacks/last_message_idkeep their original agent-id-list meaning; the newBRCState.deriveddefaults toNone(models.py:184-202). New types (ReviewVerdict,ReviewEdgeVerdict,OpenNack,ConditionalAckObligation,BRCDerivedAnchors) are purely additive and exported in__init__.py. - Matches a fixture record exactly —
test_derivation_agrees_with_matrixasserts exact values against theApprovalMatrixground-truth projection.
Replay correctness spot-checks I verified by hand against the fixture: unversioned ACK/NACK fall back to the producer's current version at processing time (:168-169), bool is correctly rejected as a version (int subclass, :73-74), and outputs are deterministically sorted by (producer, reviewer) — test_derivation_is_deterministic confirms.
task-3-2 — fixture tests ✅
- Four-field correctness against a realistic multi-producer fixture (ACK → re-propose → NACK + conditional-ACK) — asserted in both the shared and orchestrator suites.
- Resolved vs unresolved obligation distinguished —
test_resolved_obligation_marked_resolved;test_derivation_agrees_with_matrixpinscoder_ob.resolved is False/tester_ob.resolved is True. - Legacy non-regression —
test_legacy_brcstate_fields_untouched(unguarded, runs today). - The orchestrator-side test cross-checks the derivation against the live
ApprovalMatrixsubstrate, which is a strong correctness anchor.
Commit linkage ✅
Commits map cleanly to tasks (34278c6 derivation → task-3-1; 226412c/3c0c9ad tests → task-3-2; dcfe077 BRC-history persistence (#2548); 9bb6452 coder/tester merge).
Non-blocking notes (not gating)
- Scope leak (cosmetic):
951f2cf("apply automated formatting fixes") also reformats one line inorchestrator/agent_model_resolution.py:457-461(multi-line → single-line, line-length only). Behavior-neutral and outside the slice's logical scope, but worth a glance from the human reviewer — it's unrelated to the anchor work and was swept in by the auto-formatter. - Criterion marking: this sliced contract has no top-level
ac-Nacceptance criteria (they live as per-task free text), soegg-contract verify-criterion --criterion ac-Nis not applicable here. The orchestrator was also unreachable for the duration of this review (egg-contract showreturned "Orchestrator unreachable"); I read the contract directly from.egg-state/contracts/issue-3200.json.
No contract violations found. All acceptance criteria for both tasks are satisfied.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review: slice-3 BRC anchor derivation (#3189 / #3200)
Verdict: Approve. No blocking issues. The feature works end-to-end against real data, is purely additive, and is well-tested. Details below, plus non-blocking suggestions.
I went beyond the unit fixtures and validated the derivation against the real captured message record shipped in this PR (.egg-state/brc-history/3200-implement-slice-3.json, 37 real messages), and traced field-name consistency against the orchestrator's own message reader/writer. This is the check the hand-built fixtures can't provide on their own.
What I verified
1. The derivation is functional against real data (not a silent no-op). Running derive_brc_anchors on the captured record produces correct output:
last_reviewed_sha→{"coder": "34278c681", "tester": "3c0c9ad5a"}(no-opdocumentercorrectly omitted — emptycommit_sha, nothing to anchor)- 11
latest_verdictswith correct per-edgereviewed_sharesolved via the version→SHA join - empty
open_nacks/obligations(matches reality — that pipeline had no NACK/conditional-ACK)
2. Field-name consistency across modules — the main cross-module risk for this kind of "consume a serialized record" feature. The fixtures hand-build message dicts; I confirmed every field the derivation reads matches what the orchestrator actually emits and what its own replay reader expects:
- PROPOSE:
metadata.version+metadata.commit_sha— present in real record (brc_derive.py:82-84,_versionreadsmeta.get("version")). ✓ - ACK/NACK: producer in
to_role, version inmetadata.version(= producer proposal version in the real record), reason/condition undermetadata.payload.*—_payloadhandles the nesting,_commit_sha/_pre_merge_condition/_nack_reasoncheck bothmetaandpayload. ✓ CONSENSUS_OBLIGATION_RESOLVED: the derivation readsmetadata.reviewer_role/metadata.producer_role(brc_derive.py:191-192). This is an exact match to the message-bus message written inroutes/signals.py:3117-3126and to the orchestrator's own replay reader atpeer_consensus.py:2268-2271. (Note the SSEemit_eventinhandle_resolve_obligationuses different keysreviewer/producer— that's a separate event bus the derivation correctly does not consume.) ✓
3. Logic correctness. Replay semantics (latest verdict per edge wins; re-propose advances producer_version and supersedes prior NACKs/obligations via the state["version"] != current filter in _assemble); bool-rejection in _version (brc_derive.py:73); to_role == "all" guard; structured-fields-only (never free-form body) — all correct. Additive model extension preserves BRCState.acks/nacks/last_message_id (asserted by the un-guarded test_legacy_brcstate_fields_untouched).
4. Tests pass and exercise the real path. All 9 tests green locally. The orchestrator-side test_derivation_agrees_with_matrix builds the real ApprovalMatrix via its public API and asserts the message-fed derivation agrees with the matrix projection — a legitimate ground-truth cross-check, not a self-seeded golden.
5. No security surface. Read-only, no eval/exec/pickle/subprocess/deserialization, O(n), structured fields only.
The feature is not yet wired into any consumer — expected: this is the substrate slice; slice-4 (protected root) consumes it. BRCState.derived defaults to None (additive/optional).
Non-blocking suggestions
-
Add a real-record regression test (highest value). The unit fixtures are hand-built dicts; I had to manually confirm they match the real message shape. A small test that feeds an actual
.egg-state/brc-history/*.json(or a trimmed copy) throughderive_brc_anchorswould lock the real-shape contract so a future change to the orchestrator's message metadata keys breaks a test rather than silently turning the derivation into a no-op. Today, a key rename (e.g.metadata.version) would pass every existing test while producing wrong anchors on live data. -
Document the caller's scoping responsibility.
derive_brc_anchorsdoes no slice/phase filtering — unlike the orchestrator'sreconstruct_tracker_from_messages, which filters byslice_id+phase(peer_consensus.py:2128-2135) precisely to avoid cross-slice state conflation (#2761). The brc-history files are already per-slice, so the contract is "pass a pre-scoped record," but that expectation is implicit. A one-line note in the docstring would save slice-4 from accidentally passing an unscoped, multi-slice stream. -
last_reviewed_shanaming. It's a per-producer max-across-reviewers aggregate, while the per-edge reviewed SHA lives inlatest_verdicts[].reviewed_sha. The field doc covers it, but the name reads as if it were per-edge; a half-sentence clarifying "highest version any reviewer verdicted on" inline at the map would reduce misuse risk. -
Fixture timestamps. The unit fixtures omit
timestamp, so_ordered's(timestamp, id)sort path (brc_derive.py:122-123) — the path real records actually take — is never exercised by a unit test. Consider adding timestamps to one fixture variant. -
Scope creep (trivial). The
orchestrator/agent_model_resolution.pychange is an unrelated one-line reformat (collapsing a multiline ternary); semantically identical, harmless, but unrelated to this slice.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…ations - Add a real-record regression test that derives anchors from an actual captured BRC message record (committed under tests/data/), locking the live message-field shape so a future metadata key rename fails a test rather than silently producing empty anchors. - Add a test exercising the (timestamp, id) ordering path in _ordered, which the hand-built fixtures (no timestamps) never reached. - Document derive_brc_anchors' caller-scoping contract (pass a pre-scoped per-slice/per-phase record; no internal slice/phase filtering). - Clarify inline that last_reviewed_sha is a per-producer max-across- reviewers aggregate, distinct from per-edge latest_verdicts[].reviewed_sha.
Review feedback addressedBoth reviews approved with non-blocking suggestions. Per-item disposition: egg-reviewer suggestions
james-in-a-box (contract-verification) notes
All 9 — Authored by egg |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Re-review: slice-3 BRC anchor derivation (#3189 / #3200)
Verdict: Approve. All non-blocking suggestions from the prior review are properly addressed (not superficially), and the new delta introduces no blocking issues.
Scope of this re-review
The PR branch was rebased since my last review at 951f2cf. The true PR-authored delta since then is two commits — 03ee22cd (address review) and 68193439 (mypy fix) — touching exactly three files:
shared/egg_anchor/brc_derive.py— docstring + one inline comment only; no logic change from the approved version.shared/egg_anchor/tests/data/brc_record_real.json— new real-record fixture (749 lines).shared/egg_anchor/tests/test_brc_anchor_derivation.py— two new tests.
Verification of the addressed suggestions
#1 — real-record regression test. Confirmed it does the job it was asked to do, and confirmed it is not a self-seeded golden. I ran the file (9 passed, 0 skipped — the locator resolves derive_brc_anchors via the package export, so the assertions actually execute rather than skip), then independently checked every pinned value against the fixture content:
- 3
CONSENSUS_PROPOSE: coder v134278c681, tester v13c0c9ad5a, documenter v1''→last_reviewed_sha == {"coder": "34278c681", "tester": "3c0c9ad5a"}is correct, and the empty-SHA documenter is rightly excluded. - 11
CONSENSUS_ACKedges →len(latest_verdicts) == 11is correct. - 0 NACKs / 0 obligations → empty
open_nacks/obligationsis correct.
These are facts about the captured consensus, independently verifiable from the record — not outputs the implementation defined for itself. A future rename of metadata.version / commit_sha / to_role now breaks this test instead of silently emptying live anchors. This is exactly the cross-module shape-lock the hand-built fixtures couldn't provide.
#2 — caller-scoping docstring. Added and accurate: derive_brc_anchors does no slice/phase filtering (verified — it iterates the message list directly), and the docstring correctly states the per-slice/per-phase pre-scoping contract that brc-history/<id>-<phase>.json already satisfies.
#3 — last_reviewed_sha naming. Inline note at _assemble correctly clarifies it is a per-producer max-across-reviewers aggregate, distinct from per-edge latest_verdicts[].reviewed_sha.
#4 — timestamp sort path. test_timestamp_sort_path_recovers_chronology hands the record newest-first and asserts the v2 NACK (not the v1 ACK) is the surviving verdict — assertions that only hold if _ordered's (timestamp, id) sort runs. This genuinely exercises the path real records take and the timestamp-less fixtures never reached.
#5 / contract-note #1 — agent_model_resolution.py scope creep. Now moot, and the disagreement is correct: that change is not in the PR delta at all. It belongs to slice-2, which has advanced two commits (8bdbb9e2, 5b7fa58d "Decouple unknown-model window…") past this PR's branch point (216f1de2). It only appeared as a "reversal" in a two-dot slice-2..HEAD diff. Nothing for this PR to do.
The mypy fix (cast(list[dict[str, Any]], json.loads(...))) is trivial and correct.
Non-blocking note
- The PR branch is 2 commits behind its base
egg/issue-3200/slice-2. Normal stacked-PR drift — the slice-2 refinements (_conservative_unknown_window, Claude-alias keying) will be picked up on the orchestrator-side rebase before merge. Worth a glance from the merger that the base is current, but not a code issue here.
The core derivation logic is unchanged from the prior approval; the delta is purely additive test coverage + documentation. No security surface (read-only, structured-fields-only, O(n)).
— Authored by egg
There was a problem hiding this comment.
Contract re-verification — slice-3 "Derive" (issue #3200)
Verdict: Approve (no blocking issues). Posted as a comment because this PR is self-authored by the egg bot account.
Delta since last review
The last-reviewed commit 951f2cf7 is no longer in history — the PR branch has been collapsed to a single orphan commit (68193439, "Fix mypy no-any-return in test_brc_anchor_derivation"), so a literal 951f2cf..HEAD delta is not recoverable. I re-verified against a direct tree diff slice-2 → slice-3 and re-ran the slice's tests. The named change (a no-any-return mypy fix in the orchestrator test) introduces no regression; all derivation tests are green.
task-3-1 — deterministic derivation + additive model ✅
shared/egg_anchor/brc_derive.py::derive_brc_anchorscomputes all four #3189 fields mechanically from structured message fields (message_type/from_role/to_role/metadata). It never reads agent prose —_nack_reasondeliberately takes the structuredreason, never the free-formbody. Non-consensus messages are ignored; replay semantics (re-propose advances version, superseded verdicts/obligations become historical) mirrorpeer_consensuswithout depending on the orchestrator package.- Model extension is additive (
shared/egg_anchor/models.py): newBRCDerivedAnchors,ReviewEdgeVerdict,OpenNack,ConditionalAckObligation, and theReviewVerdictenum;BRCState.derivedisOptional, defaultNone.BRCState.acks/nacks/last_message_id(themodels.py:96-103contract) are untouched and keep their agent-id-list meaning — confirmed by the no-skiptest_legacy_brcstate_fields_untouched. __init__.pyexports the new symbols.
The task AC ("four fields derive purely from the record; additive without breaking existing fields; match the fixture exactly; no agent-authored content") is met.
task-3-2 — fixture tests ✅
shared/egg_anchor/tests/test_brc_anchor_derivation.py— 9 passed. Covers the full AC scenario: multiple producers, ACK→re-propose→NACK (current-version NACK reason surfaced, superseded v1 SHA correctly excluded), unresolved conditional-ACK obligation, resolved-vs-unresolved distinction, determinism, plus two regression tests added from prior review feedback (a captured real 37-message record locking live field shapes, and an out-of-order timestamped record exercising the(timestamp, id)sort path).orchestrator/tests/test_brc_anchor_derivation.py— 2 passed. Anchors ground truth to the realApprovalMatrixsubstrate.
I traced every assertion against the derivation logic and they are consistent. Per review conventions I did not run the full suite; CI gates on the green check suite.
Note (non-blocking) — base drift, not slice-3 work
The slice-2 → slice-3 tree diff shows orchestrator/agent_model_resolution.py and orchestrator/tests/test_reseed_threshold.py differing: current slice-2 tightened _conservative_unknown_window (decoupled→min-coupled) and added two tests after slice-3 branched from it. These are slice-2/AC-3 territory, not slice-3's "Derive" scope, and reconcile on the orchestrator's controlled rebase onto the base branch. Flagging for awareness so a naive merge doesn't regress slice-2's newer state — it does not affect slice-3's contract compliance.
Contract-marking
Could not run egg-contract verify-criterion: the orchestrator is unreachable from this session, and the on-disk contract is a refine-phase snapshot whose top-level acceptance_criteria list is empty (no ac-N ids exist to mark). Slice-3's task-level acceptance criteria (prose) are both fully satisfied as detailed above.
— Authored by egg
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| egg is addressing review feedback... |
Review feedback addressedThe two most recent reviews — Prior egg-reviewer suggestions (#1–#5) and james-in-a-box notes — already
New note (both latest reviews) — base drift: PR branch 2 commits behind base Contract criterion-marking note — no action needed. This sliced contract carries no top-level No code changes were required this round — the latest reviews are approvals and CI is green. — Authored by egg |
|
egg feedback addressed. View run logs 12 previous review(s) hidden. |
#3264) * docs: update egg_anchor README for BRC anchor derivation [doc-updater] Document the new brc_derive.py module and associated models added in #3238 (slice-3 of #3200/#3189): - Add brc_derive.py to the Files table - Add ReviewVerdict enum to the Enums table - Add BRCDerivedAnchors, ReviewEdgeVerdict, OpenNack, and ConditionalAckObligation to the Key Sub-Models section - Add a Derivation section under Functions documenting derive_brc_anchors() Triggered by: #3238 Authored-by: egg * Clarify last_reviewed_sha is a per-producer aggregate in README --------- Co-authored-by: jwbron <8340608+jwbron@users.noreply.github.com> Co-authored-by: egg-reviewer[bot] <261018737+egg-reviewer[bot]@users.noreply.github.com>
Derive the four #3189 anchor fields (last-reviewed SHA/producer, latest verdicts, open NACK reasons, conditional-ACK obligations) from the BRC message record; extend shared/egg_anchor additively. Closes the substrate gap the NACK flagged (BRCState carries none of these today; #3189 OPEN). Logical dep: none; serialized after slice 2 (#3046). Hard prereq of the protected root (slice 4).
Base PR: #3234
What's in this PR
Commits (4):
This slice
Derive
Files affected:
shared/egg_anchor/orchestrator/shared/egg_anchor/tests/orchestrator/tests/Tasks (2) + acceptance criteria
Stack
issue-3200egg/issue-3200/slice-2