Skip to content

D-MCAL-6: build the consumers against the arc, don't grep them - #1070

Merged
AdaWorldAPI merged 12 commits into
mainfrom
claude/d-mcal-6-consumer-build
Aug 27, 2026
Merged

D-MCAL-6: build the consumers against the arc, don't grep them#1070
AdaWorldAPI merged 12 commits into
mainfrom
claude/d-mcal-6-consumer-build

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

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.

Note on the diff: this branch carries the merge of #1066#1069 so the consumer could be built against the combined head. Merge it after those four; what's unique to it is .claude/plans/mul-consumer-build-gate-v1.md plus board hygiene.

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 paths override (reverted afterwards; ada-rs's tree is unchanged).

The override was verified to actually bind, not assumed. A probe compiled inside ada-rs:

use lance_graph_contract::kanban::KanbanColumn;
assert_eq!(KanbanColumn::Planning.veto(), Some(KanbanColumn::Prune));

veto() exists only on the head under test — it is D-MCAL-4's addition. It resolved with no E0599, so the compiler was reading the arc. Without this check the whole gate could have run against main and reported a meaningless pass.

Result — ada-rs

Does not compile. Three errors. Zero from this arc.

error[E0559]: variant `...mul::GateDecision::Block` has no field named `reason`  -- contract_impls.rs:75
error[E0559]: variant `...mul::GateDecision::Hold`  has no field named `reason`  -- contract_impls.rs:83
error[E0559]: variant `...mul::GateDecision::Hold`  has no field named `reason`  -- contract_impls.rs:90
    = note: available fields are: `texture`, `flow`

All three are the pre-existing #1045 break, which predates every deliverable in this arc.

deliverable expected effect observed
D-MCAL-2 — PlannerContract::gate_check removed none; ada-rs never implemented it none
D-MCAL-2 — MulProvider::gate_check deprecated a warning, never an error no error
D-MCAL-3 / D-MCAL-5 — docs + tests none none
D-MCAL-4 — KanbanColumn::{advance, veto} none; purely additive none

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 texture and a flow at 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 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 — 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.md row · INTEGRATION_PLANS.md prepend · supersession index regenerated last.


Generated by Claude Code

claude added 5 commits August 27, 2026 15:58
…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
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 74f8a62e-55d4-487a-a53f-14297635f64d


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Aug 27, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot 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)

claude added 2 commits August 27, 2026 16:19
…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
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review August 27, 2026 16:20
claude added 2 commits August 27, 2026 16:20
… 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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment on lines +105 to +108
**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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 anythingMulAssessment 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 + compass only, no gate_check, consent routed through veto()). If gate_check ever 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

Comment on lines +163 to +168
/// 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).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 exposes Prune — and veto_agrees_with_the_pre_existing_next_phases_route pins 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, whose Block variant requires a TrustTexture and a FlowState; 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

claude added 2 commits August 27, 2026 16:24
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
AdaWorldAPI pushed a commit that referenced this pull request Aug 27, 2026
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
@AdaWorldAPI
AdaWorldAPI merged commit 32a130a into main Aug 27, 2026
2 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Aug 27, 2026
#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
AdaWorldAPI added a commit that referenced this pull request Aug 27, 2026
Board hygiene: PR_ARC_INVENTORY entries for the D-MCAL arc (#1065#1070)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants