D-MCAL-6: build the consumers against the arc, don't grep them - #1070
Conversation
…mcal-6-consumer-build # Conflicts: # .claude/board/STATUS_BOARD.md
…onsumer-build # Conflicts: # .claude/board/LATEST_STATE.md # .claude/board/STATUS_BOARD.md
…nsumer-build # Conflicts: # .claude/board/ISSUES.md # .claude/board/STATUS_BOARD.md # crates/lance-graph-contract/src/mul.rs
…mer-build # Conflicts: # .claude/board/STATUS_BOARD.md
Discharges the second half of F-MUL-6 — the half a grep cannot reach. A classification tells you a symbol is mentioned; only a compiler tells you a change is source-compatible. ada-rs was COMPILED against the combined arc head (#1065 merged, plus #1066, #1067, #1068, #1069) using a temporary `paths` override, reverted afterwards. The override was VERIFIED to bind rather than assumed: a probe calling `KanbanColumn::veto()` — a method that exists only on the head under test — compiled without E0599. Without that check the entire gate could have run against `main` and reported a meaningless pass. Result: ada-rs does not compile, with exactly three errors, and all three are the pre-existing #1045 `reason:` break that predates every deliverable in this arc. Zero errors are attributable to the arc: - `PlannerContract::gate_check` removal -> ada-rs never implemented it - `MulProvider::gate_check` deprecation -> a warning by construction - `KanbanColumn::{advance, veto}` -> purely additive - D-MCAL-3 and D-MCAL-5 -> docs and tests only So the arc is source-compatible with its one live external implementor, and the single red consumer is red for a reason the arc exists to explain rather than one it caused. The stopgap stays unpushed. The three errors are trivially silenced by supplying a texture and a flow at each site, and that fix is refused: inventing two calibration coordinates ada-rs never measured would reproduce exactly the defect the census found in MedCare-rs. The honest fix is D-MCAL-4's route, which now exists on this head — a consent veto is domain evidence, so it calls `veto()` and constructs no `GateDecision` at all. Two of the adapter's three arms are genuine MUL and keep working through `assess()`; only the consent arm moves. MedCare-rs is covered at symbol level plus the in-tree pins rather than by a compile, and that asymmetry is recorded as a LIMITATION in the report rather than reported as a pass. The report's final section states what the gate does not certify at all, including the fifteen other dependent repos whose non-involvement rests on a grep — which, by this deliverable's own argument, is not a build. Board hygiene in the same commit: STATUS_BOARD row, INTEGRATION_PLANS prepend, supersession index regenerated last. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_31464e8f-6732-425c-91ce-91a295e7664b) |
…onsumer-build # Conflicts: # .claude/board/LATEST_STATE.md # .claude/board/STATUS_BOARD.md
…nsumer-build # Conflicts: # .claude/board/ISSUES.md # .claude/board/STATUS_BOARD.md
… capability proof Brings the codex-driven corrections on #1068 and #1069 into the combined head the build gate measures, so the gate reports on the corrected arc. Also adds a note to the gate's method section drawing a distinction the arc got wrong once and should not get wrong again. "`KanbanColumn::veto` is absent from `main`" is valid evidence for WHICH SOURCE cargo bound — that is a question about symbol availability, and symbol availability is what it answers. It is NOT valid evidence that routing without MUL ground was previously IMPOSSIBLE, because `next_phases()` was already public and already exposed `Prune`, so the capability existed unnamed. D-MCAL-4's original red-state claim made that second, invalid inference; this gate's probe makes only the first. Recording both readings of the same fact means the next session does not have to re-derive why one use is sound and the other was not. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0dc8984256
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | falsifier | status | | ||
| |---|---| | ||
| | F-MUL-6, first half (classify per symbol) | discharged by D-MCAL-1 (#1065) | | ||
| | F-MUL-6, second half (BUILD against the head) | **discharged for ada-rs by compilation**; MedCare covered at symbol level with the limitation stated in §3 | |
There was a problem hiding this comment.
Keep F-MUL-6 open until MedCare is built
This marks the build half of F-MUL-6 as discharged even though §3 explicitly says MedCare, a known consumer, was not rebuilt and was covered only by symbol-level reasoning. That contradicts this report's §0 criterion that every known consumer must be built and that classification/grep is not a substitute; leaving the gate discharged can prematurely unblock the planned contract rename or removal without its required compatibility proof.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Agreed, and this one stung — the report contradicted its own §0 in its own verdict table. F-MUL-6's build half is now marked OPEN, not discharged:
ada-rs: built, real compile. MedCare-rs: NOT built (§3). §0 requires every known consumer to be built and says a grep is not a substitute, so one built consumer out of two is a partial result, not a pass.
Your point about the downstream consequence is the reason this needed to be an issue and not a footnote, so I filed ISS-F-MUL-6-HALF-BUILT: the rename tracked by ISS-MUL-GATE-NAMED-FOR-THE-WRONG-LAYER is blocked on D-MCAL-6, so a gate read as passed would unblock it without the compatibility proof it's meant to wait for. The issue records what closing it requires — standing up MedCare's git dep graph (ogar-obo, jc, medcare-cohorts, the lance stack) and compiling medcare-first-thought against the arc head.
I expect that build to come back green, since MedCare touches no symbol the arc changed and the one it does touch is behaviour-identical and pinned. But expected is not measured, which is the entire point of this deliverable, so the falsifier stays open until someone runs it.
Generated by Claude Code
| **The honest fix is D-MCAL-4's route**, now available on this head: ada-rs's | ||
| consent veto is domain evidence, so it calls `KanbanColumn::veto()` and | ||
| constructs no `GateDecision` at all. That migration is ada-rs's to make, in | ||
| ada-rs's repo — this gate only proves the destination exists and compiles. |
There was a problem hiding this comment.
Provide a migration that satisfies the required trait
For the documented ada-rs migration, MulProvider::gate_check remains a required trait item in crates/lance-graph-contract/src/mul.rs:421; deprecation does not make it optional. Moving consent to veto() and implementing only assess() therefore produces E0046, while retaining the method still requires returning GateDecision and addressing the two failing Hold constructors. The new method alone is not yet the compiling route out of all three errors claimed here; remove/default the trait item first or document the required interim implementation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Verified and fixed at the trait rather than documented around. You're right that veto() alone was never a compiling route out of all three errors.
gate_check is now a provided method:
fn gate_check(&self, assessment: &MulAssessment) -> GateDecision {
GateDecision::from_axes(assessment.trust.texture, assessment.homeostasis.flow_state)
}I picked default-it over remove-it because the default can be written without fabricating anything — MulAssessment already carries both coordinates, measured by the implementor's own assess(). That is precisely the distinction this arc is about: deriving from measured axes, versus the two external producers inventing them to satisfy a constructor. Removing the item instead would have been a second source-breaking change on a trait with a live external implementor, for no gain.
The rule is extracted to GateDecision::from_axes so it has one definition, now shared by i4_eval::gate_decision_i4 and this default rather than copied into both.
Two falsifiers now carry the claim the report was asserting:
the_documented_migration_compiles_and_behaves— implements the exact migration shape (assess+compassonly, nogate_check, consent routed throughveto()). Ifgate_checkever becomes required again, that file stops compiling.the_inherited_gate_check_default_reads_measured_axes_not_invented_ones— pins the default to the assessment's own coordinates, so it can't drift into a constant.
Landed on both this branch and #1068, since the code belongs with D-MCAL-4 and shouldn't depend on merge order.
Generated by Claude Code
| /// own uncertainty estimate. Before this method, the only route into the | ||
| /// phase DAG was [`advance_on_gate`](KanbanColumn::advance_on_gate), whose | ||
| /// `GateDecision::Block` variant requires a `TrustTexture` **and** a | ||
| /// `FlowState`. A domain that measures neither had to invent both, and the | ||
| /// two measured external producers did exactly that | ||
| /// (`.claude/plans/mul-consumer-census-v1.md` §3). |
There was a problem hiding this comment.
Describe veto as a wrapper over the existing route
When a domain lacked calibration coordinates, it did not have to invent them: the already-public next_phases() exposed Prune, and the newly added veto_agrees_with_the_pre_existing_next_phases_route test explicitly proves that veto() is equivalent to that route. This public rustdoc retains the same false capability claim that the test file's correction withdraws; describe the method as the ergonomic named wrapper it is rather than saying it was the only ground-free route.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Caught cleanly — I corrected the test file and the boards but left the rustdoc, which is the copy users actually read. Fixed.
It now describes the method as what it is:
This is an ergonomic named wrapper, not a new capability. A caller could always have walked the DAG by hand —
next_phases()is public and already exposesPrune— andveto_agrees_with_the_pre_existing_next_phases_routepins that equivalence so the two can never diverge.What the name changes is which route is obvious. […] the only named entry point was
advance_on_gate, whoseBlockvariant requires aTrustTextureand aFlowState; a domain measuring neither had to supply both anyway, and the two measured external producers invented them.
The equivalence test is named inline, so a reader who doubts the wrapper claim has the check one grep away rather than having to take the prose on faith.
Worth noting the failure mode for the record: a claim withdrawn in three places and left standing in a fourth is still a live claim, and the one left standing was the most public of the four. Landed on this branch and #1068.
Generated by Claude Code
The keep-both-sides resolutions used to carry this branch across four merges
landed three sections twice, plus one header-only orphan. Removed:
LATEST_STATE.md - the D-MCAL-2 inventory section, exact duplicate
ISSUES.md - ISS-MUL-GATE-NAMED-FOR-THE-WRONG-LAYER, exact duplicate
INTEGRATION_PLANS - a header-only orphan of the D-MCAL-3 entry, left above
the real one when a conflict hunk split the section
Only exact duplicates were dropped automatically; the D-MCAL-3 pair diverged in
length, so it was inspected by hand rather than auto-resolved — copy 0 turned
out to be a bare header with no body (merge debris), copy 1 the real entry.
A divergent repeat with real content on both sides would have been kept and
flagged, never silently collapsed: these files are append-only and losing a
revised entry is worse than carrying a duplicate.
Board files are otherwise unchanged; the supersession index is regenerated last
as usual.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
…ted veto docs All three findings verified against source before acting. 1. The documented migration did not compile. FIXED, not documented around. `MulProvider::gate_check` was a REQUIRED trait item; deprecating it does not make it optional. An implementor that deleted its `gate_check` got E0046, and one that kept it still had to return a `GateDecision` — which still meant fixing the two `Hold` constructors. So `veto()` alone was never a compiling route out of all three ada-rs errors, and the report claimed it was. `gate_check` is now a PROVIDED method. Its default applies the canonical `(TrustTexture, FlowState) -> GateDecision` rule to the two coordinates already on the `MulAssessment` the implementor computed. Nothing is fabricated: those are measured values, which is exactly the difference between this default and what the two external producers were doing by hand. The rule itself is extracted to `GateDecision::from_axes` so it has ONE definition, shared by the i4 evaluator and the trait default rather than copied. Two new falsifiers carry the claim the report used to assert: `the_documented_migration_compiles_and_behaves` implements the exact migration shape (assess + compass only, no `gate_check`, consent routed through `veto()`), so if `gate_check` ever becomes required again this file stops compiling; and `the_inherited_gate_check_default_reads_measured_axes_not_invented_ones` pins the default to the assessment's own coordinates. 2. F-MUL-6's build half was marked discharged with one of two consumers built. That contradicted the report's own §0 criterion — every known consumer must be BUILT, and a grep is not a substitute. ada-rs was compiled; MedCare-rs was not. The falsifier is now OPEN, the verdict table says so, and ISS-F-MUL-6-HALF-BUILT records what closing it requires. This matters beyond bookkeeping: the rename tracked by ISS-MUL-GATE-NAMED-FOR-THE-WRONG-LAYER is blocked on D-MCAL-6, so a gate read as passed would unblock it without its compatibility proof. 3. `KanbanColumn::veto`'s public rustdoc still carried the withdrawn claim. The test file and boards were corrected earlier; the rustdoc — the copy users actually read — still said this was the only ground-free route. It now describes the method as what it is: an ergonomic named wrapper over the already-public `next_phases()` walk, whose value is making the honest route the obvious one, with the equivalence test named inline. 1227 lib + 12 D-MCAL-4 integration tests green; clippy --all-targets and fmt clean. Board hygiene in the same commit; supersession index regenerated last. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
Two review findings from #1070 that belong with this deliverable's code rather than with the build-gate report that surfaced them, so they land here regardless of merge order. 1. `MulProvider::gate_check` was a REQUIRED trait item, so the migration this deliverable documents did not compile. Deprecation does not make a method optional: an implementor that deleted its `gate_check` got E0046, and one that kept it still had to return a `GateDecision` and fix its `Hold` constructors. `veto()` alone was never a compiling route. It is now a PROVIDED method whose default applies the canonical `(TrustTexture, FlowState) -> GateDecision` rule to the two coordinates already on the `MulAssessment` the implementor computed — measured values, not invented ones, which is the whole difference between this default and what the external producers were doing by hand. The rule is extracted to `GateDecision::from_axes` so it has one definition shared with the i4 evaluator instead of a second copy. `the_documented_migration_compiles_and_behaves` now implements the exact migration shape — assess + compass only, no `gate_check`, consent routed through `veto()` — so if `gate_check` ever becomes required again this file stops compiling. `the_inherited_gate_check_default_reads_measured_axes_not_invented_ones` pins the default to the assessment's own coordinates. 2. `KanbanColumn::veto`'s public rustdoc still carried the red-state claim this PR already withdrew in its test file and on the boards. The rustdoc is the copy users read, and it still said this was the only ground-free route into the phase DAG. It now describes the method as what it is — an ergonomic named wrapper over the already-public `next_phases()` walk, whose value is making the honest route the obvious one — and names the equivalence test inline. 1227 lib + 12 integration tests green; clippy --all-targets and fmt clean. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
… board claim The merge itself is the D-MCAL-6 branch catching up to #1068. Two board fixes ride with it because the conflict put me in the file and leaving them would be the same defect twice. 1. D-MCAL-2/3/4/5 still read "In PR" after all four merged. Flipped to Shipped with their PR numbers. 2. The D-MCAL-4 row still carried the WITHDRAWN red-state claim — "F-MUL-1/F-MUL-2 red-on-main (no compile) then green". That claim was retracted in the test file, in LATEST_STATE, in INTEGRATION_PLANS and in the veto rustdoc, and was still standing here. `next_phases()` already exposed `Prune`, so the capability existed unnamed; what D-MCAL-4 delivers is an ergonomics-and-naming fix with a measured behavioural consequence, not a new capability. The row now says so and marks the old wording withdrawn rather than deleting it. This is the third place the same retraction had to be chased. A claim withdrawn in four places and live in a fifth is still a live claim, and the board is the surface future sessions read first. D-MCAL-2's row also records that the deprecation alone left `gate_check` required, and that #1068 gave it a default — otherwise the row reads as though the migration worked from #1066 onward, which it did not. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
#1070 merged before this branch was cut, not after — `origin/main` already carried it at 32a130a when the branch was created. So the claim in this PR's original description that "#1070 is still open and gets its entry after it merges" was wrong when written, and the entry belongs here rather than in a later pass. Adds the D-MCAL-6 entry, flips its STATUS_BOARD row to Shipped, and retitles the LATEST_STATE section to six-of-six. The entry records what the gate actually established and, as prominently, what it did not. F-MUL-6 stays OPEN: one of two known consumers was built. It also keeps the distinction the arc got wrong once — "`veto` is absent from `main`" is valid evidence for WHICH SOURCE cargo bound, and invalid as evidence that ground-free routing was impossible. Both readings stay visible so the wrong one is not re-derived. Still hygiene-only, so the termination clause still applies: no arc entry for this PR itself, no LATEST_STATE row for itself. The chain stops here. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
Discharges the second half of F-MUL-6 — the half a grep cannot reach. A classification tells you a symbol is mentioned; only a compiler tells you a change is source-compatible.
Method — and why the override was verified
ada-rs consumes lance-graph as a git dependency, so the head under test was bound with a temporary
pathsoverride (reverted afterwards; ada-rs's tree is unchanged).The override was verified to actually bind, not assumed. A probe compiled inside ada-rs:
veto()exists only on the head under test — it is D-MCAL-4's addition. It resolved with noE0599, so the compiler was reading the arc. Without this check the whole gate could have run againstmainand reported a meaningless pass.Result — ada-rs
Does not compile. Three errors. Zero from this arc.
All three are the pre-existing #1045 break, which predates every deliverable in this arc.
PlannerContract::gate_checkremovedMulProvider::gate_checkdeprecatedKanbanColumn::{advance, veto}Verdict: the arc is source-compatible with its one live external implementor. The consumer is red, and was red before the arc, for the reason the arc exists to explain.
The stopgap stays unpushed
The three errors are trivially silenced by supplying a
textureand aflowat each site. That fix is refused, per the plan's §6 invariant: inventing two calibration coordinates ada-rs never measured would reproduce exactly the defect the census found in MedCare-rs. A red compiler is preferable to a green lie.The honest fix now exists on this head — a consent veto is domain evidence, so it calls
veto()and constructs noGateDecisionat all. Two of the adapter's three arms are genuine MUL and keep working throughassess(); only the consent arm moves.MedCare-rs — stated as a limitation, not a pass
MedCare is already on the post-#1045 shape (it absorbed the break by fabricating both coordinates — the D-MCAL-1 finding). It touches no symbol this arc changes, and the one it does touch (
advance_on_gate) is behaviour-identical and pinned.But it was not rebuilt end-to-end, and the report says so rather than reporting a pass. Its half of F-MUL-6 is symbol-level reasoning plus in-tree pins; ada-rs's half is a real compile. A future session with the MedCare build stood up should close that asymmetry.
What the gate does not certify
§5 of the report is explicit: it does not certify ada-rs works, does not run either consumer's tests, and does not cover the other 15 dependent repos — whose non-involvement rests on a grep, which by this deliverable's own argument is not a build.
Board hygiene (same commit)
STATUS_BOARD.mdrow ·INTEGRATION_PLANS.mdprepend · supersession index regenerated last.Generated by Claude Code