Skip to content

D-MCAL-4: domain evidence routes the phase DAG without MUL ground - #1068

Merged
AdaWorldAPI merged 6 commits into
mainfrom
claude/d-mcal-4-domain-evidence
Aug 27, 2026
Merged

D-MCAL-4: domain evidence routes the phase DAG without MUL ground#1068
AdaWorldAPI merged 6 commits into
mainfrom
claude/d-mcal-4-domain-evidence

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Discharges F-MUL-1 (consent veto) and F-MUL-2 (evidence contradiction). This is the deliverable the whole arc was pointing at.

The change: two methods, no type

KanbanColumn::advance()  // forward successor (first non-Prune)
KanbanColumn::veto()     // Prune iff a legal successor (Libet free-won't)

advance_on_gate now delegates to both, so exactly one copy of the DAG routing rule survives and callers that genuinely hold a MUL assessment — gate_decision_i4, the supervisor's cycle driver — are unaffected.

The gap being closed

Before this, the only route into the phase DAG was advance_on_gate(&GateDecision), whose Block and Hold variants require a TrustTexture and a FlowState. A domain that measures neither had to invent both — and the two measured external producers did exactly that:

  • ada-rs contract_impls.rs:72 — consent veto → Block { texture, flow }, neither axis in its data flow.
  • medcare-first-thought — evidence contradiction at four sites, with the source itself recording that the payload is "descriptive, not behavior-affecting".

Since the routing never read those coordinates — pinned in #1067 by f_mul_4_routing_ignores_the_calibration_payload — naming the transition directly loses nothing and fabricates nothing.

D-MCAL-5's prohibition is respected

No fourth gate enum joins the three that already exist. These are transitions named as transitions, not a new verdict vocabulary. "Stay put" needs no symbol — it is None.

Anti-vacuity, satisfied mechanically

The plan's §5 requires F-MUL-1/2 shown red first against main. Not asserted — demonstrated. The falsifier file, compiled unchanged against main:

error[E0599]: no method named `veto` found for enum `KanbanColumn`
error[E0599]: no method named `advance` found for enum `KanbanColumn`

That is the red state in its strongest available form: on main there is no route into the DAG that does not construct MUL ground. Green after.

The 9 falsifiers

Each case models the external producer's real shape — ada-rs's ConsentLevel, MedCare's NARS expectation plus supporting/contradicting cardinality — and asserts three things:

  1. the route is correct;
  2. no GateDecision is constructed anywhere in the domain path;
  3. the route is identical to the fabricating path it replaces, across all six columns.

The third is the load-bearing one: it is F-MUL-5's premise, that removing the fabrication costs no behaviour.

Guards against passing by accident:

  • each domain axis exercises advance / stay / veto — a gate that only ever vetoed would be a constant;
  • non-finite expectations (NaN, ±∞) refuse to route rather than falling through a comparison that is false for NaN;
  • advance() and veto() are checked to stay inside the DAG, and to not collapse onto each other at columns where both edges are legal (otherwise one is decoration).

Verification

cargo test -p lance-graph-contract  → 1221 lib + 56 integration, 0 failed
cargo clippy -p lance-graph-contract --all-targets → clean
cargo fmt --check → clean

What this does NOT do

It does not touch ada-rs or MedCare-rs. Those migrations are theirs, and per the plan's §6 invariant the ada-rs stopgap stays unpushed. D-MCAL-6 builds the consumers against this head — a classification is not a build.

Board hygiene (same commit)

LATEST_STATE.md inventory delta · STATUS_BOARD.md row · INTEGRATION_PLANS.md prepend · supersession index regenerated last.


Generated by Claude Code

Discharges F-MUL-1 (consent veto) and F-MUL-2 (evidence contradiction).

Two methods on an existing enum, no type minted:

  KanbanColumn::advance()  -> forward successor (first non-Prune)
  KanbanColumn::veto()     -> Prune iff a legal successor (Libet free-won't)

`advance_on_gate` now delegates to both, so exactly one copy of the DAG
routing rule survives and callers that genuinely hold a MUL assessment —
`gate_decision_i4`, the supervisor's cycle driver — are unaffected.

The gap being closed: before this, the only route into the phase DAG was
`advance_on_gate(&GateDecision)`, whose `Block` and `Hold` variants require a
`TrustTexture` AND a `FlowState`. A domain that measures neither had to invent
both, and the two measured external producers did: ada-rs's consent veto, and
medcare-first-thought's evidence contradiction at four sites. Since the routing
never read those coordinates — pinned in D-MCAL-3 by
`f_mul_4_routing_ignores_the_calibration_payload` — naming the transition
directly loses nothing and fabricates nothing.

D-MCAL-5's prohibition is respected. These are transitions named as
transitions, not a new verdict vocabulary, so no fourth gate enum joins the
three that already exist. "Stay put" needs no symbol: it is `None`.

Anti-vacuity is satisfied mechanically rather than by assertion. The falsifier
file, compiled unchanged against `main`, fails with `no method named veto` and
`no method named advance` — the red state in its strongest available form: on
main there is no route into the DAG that does not construct MUL ground.

+9 tests in tests/d_mcal_4_domain_evidence.rs. Each case models the external
producer's real shape (ada-rs's ConsentLevel; MedCare's NARS expectation plus
supporting/contradicting cardinality) and asserts three things: the route is
correct, no `GateDecision` is constructed anywhere in the domain path, and the
route is IDENTICAL to the fabricating path it replaces — the last being
F-MUL-5's premise, that removing the fabrication costs no behaviour. Each
domain axis exercises advance / stay / veto so no single arm can pass by
accident, non-finite expectations refuse to route rather than falling through
a NaN comparison, and the two primitives are checked to stay inside the DAG
and to not collapse onto each other where both edges are legal.

1221 lib + 56 integration tests green; clippy --all-targets and fmt clean.

Board hygiene in the same commit: LATEST_STATE inventory delta, 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: 99bd3cdc-1c9c-4822-9e78-52f565271b5d


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_732e0a5e-2fa1-4abf-8563-d2660d67fed7)

…n-evidence

# Conflicts:
#	.claude/board/SUPERSESSION-INDEX.md
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review August 27, 2026 16:05

@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: b0ad5d681b

ℹ️ 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".

Comment on lines +9 to +13
//! Measured on `main` before this change
//! (`.claude/plans/mul-consumer-census-v1.md` §3), the only route into the
//! kanban phase DAG was `advance_on_gate(&GateDecision)`, whose `Block` and
//! `Hold` variants require a `TrustTexture` **and** a `FlowState`. Two external
//! producers reached it with neither axis in their data flow and invented both:

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 Remove the false red-state proof

Compiling this test against main only proves that the new convenience method names were absent; it does not prove that routing without MUL ground was impossible. KanbanColumn::next_phases() was already public in the parent revision and already exposed Prune for Planning and Evaluation (and in-tree callers such as scheduler.rs route through that API), so a domain could express the same veto without constructing GateDecision. Consequently, this test and the accompanying board updates incorrectly claim that F-MUL-1/F-MUL-2 were red and are now discharged; the falsifier must test a behavior unavailable through the prior public API, or the red-state/discharge claims must be revised.

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.

Confirmed against source, and you're right. Fixed in b362bb9 + follow-up.

next_phases() is public on main and returns Prune for Planning and Evaluation, so the veto was always expressible by hand:

phase.next_phases().iter().copied().find(|c| *c == KanbanColumn::Prune)

The compile failure proved only that two convenience method names were absent. Presenting that as the strongest form of evidence is exactly the vacuous-falsifier trap this repo's CLAUDE.md warns about, so the claim is withdrawn rather than softened — recorded in the test file's header and corrected in place on LATEST_STATE.md and INTEGRATION_PLANS.md.

What survives, scoped to what's actually true: the honest route existed but was unnamed, so the obvious path into the phase DAG (advance_on_gate(&GateDecision)) demanded two calibration coordinates — and both measured producers took it and invented them. Naming the transition makes the honest route the reachable one. That is an ergonomics-and-naming fix with a measured behavioural consequence, not a new capability, and the falsifiers now say so.

Added veto_agrees_with_the_pre_existing_next_phases_route, which pins exactly the equivalence you identified for both veto() and advance(), so the wrappers can never drift from the raw DAG walk and the honest scope stays visible in code rather than only in a commit message.

One related fix carried in the same commit, from your other finding on #1067 (already merged): the consumer table named crate::action::ActionInstance with methods commit/emit. The type is ActionInvocation and the methods are commit/commit_via. Corrected.

Your third finding — that .claude/plans/mul-consumer-census-v1.md did not exist — was verified stale: true of the reviewed commit, resolved by the merge that brought #1065's census onto this branch. No action taken there.


Generated by Claude Code

…n-evidence

# Conflicts:
#	.claude/board/LATEST_STATE.md
#	.claude/board/STATUS_BOARD.md
AdaWorldAPI pushed a commit that referenced this pull request Aug 27, 2026
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
@AdaWorldAPI
AdaWorldAPI force-pushed the claude/d-mcal-4-domain-evidence branch from a37c4a3 to b362bb9 Compare August 27, 2026 16:16
Two codex findings, both verified against source before acting.

1. The red-state proof was a naming artifact. WITHDRAWN.

   The earlier text claimed F-MUL-1/F-MUL-2 were shown red "mechanically",
   because the falsifier file failed to compile against `main` with
   `no method named veto`. That proves only that two convenience method NAMES
   were absent. `KanbanColumn::next_phases()` is public on `main` and already
   returns `Prune` for `Planning` and `Evaluation`, so a domain could always
   have routed a veto by hand:

       phase.next_phases().iter().copied().find(|c| *c == KanbanColumn::Prune)

   Presenting that as the strongest form of evidence is exactly the
   vacuous-falsifier trap CLAUDE.md warns about. The correction is recorded in
   the test file's header and on both board files rather than quietly deleted.

   What remains true, and is what this deliverable actually delivers: the
   honest route existed but was unnamed, so the OBVIOUS path into the phase
   DAG — `advance_on_gate(&GateDecision)` — demanded two calibration
   coordinates, and both measured producers took it and invented them. Naming
   the transition makes the honest route the reachable one. That is an
   ergonomics-and-naming fix with a measured behavioural consequence, not a
   new capability, and the falsifiers are now scoped to that claim.

   New test `veto_agrees_with_the_pre_existing_next_phases_route` pins the
   equivalence codex identified, so the wrappers can never drift from the raw
   DAG walk they wrap and the honest scope stays visible in code.

2. `crate::action::ActionInstance` does not exist.

   The consumer table added in #1067 (now on main) named a type that is not
   there and methods that are not its: the type is `ActionInvocation` and its
   methods are `commit` and `commit_via`, not `commit` and `emit`. The
   intra-doc link was unresolved and the table pointed readers at an API that
   does not exist. Fixed here because #1067 has already merged.

A third finding — that the census file the doc links did not exist — was
verified stale: it was true of the reviewed commit and resolved by the merge
that brought #1065's census onto this branch.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HKHLL6NTnRr1XGvKFA1j2L
@AdaWorldAPI
AdaWorldAPI force-pushed the claude/d-mcal-4-domain-evidence branch from b362bb9 to 1719107 Compare August 27, 2026 16:16
AdaWorldAPI pushed a commit that referenced this pull request Aug 27, 2026
… 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
claude added 2 commits August 27, 2026 16:22
…n-evidence

# Conflicts:
#	.claude/board/STATUS_BOARD.md
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
@AdaWorldAPI
AdaWorldAPI merged commit 012fe7f into main Aug 27, 2026
8 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Aug 27, 2026
… 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
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