Skip to content

D-MCAL-3: name the execution gate what it is (doc-first, with pins) - #1067

Merged
AdaWorldAPI merged 3 commits into
mainfrom
claude/d-mcal-3-name-the-execution-gate
Aug 27, 2026
Merged

D-MCAL-3: name the execution gate what it is (doc-first, with pins)#1067
AdaWorldAPI merged 3 commits into
mainfrom
claude/d-mcal-3-name-the-execution-gate

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Doc-first, per the plan's own scoping ("rename is a separate, later PR"). Gate: F-MUL-4.

The claim, in the type's own docs

contract::mul::GateDecision gains a "What this type actually is" section: it is the execution / commit gate, not MUL's output. It lives in a module called mul for historical reasons, and that name has been misleading consumers for as long as it has existed.

The consumer table is inlined from the D-MCAL-1 census:

consumer what it does
kanban::KanbanColumn::advance_on_gate phase-DAG move; BlockPrune (Libet "free won't" veto)
action::ActionInstance commit / emit ActionState::{Committed, Pending, Cancelled}
sigma-tier-router BlockRest { GateBlocked }
supervisor::kanban_actor::mul_target next kanban column

Every one commits, cancels, or defers work. None routes to a compass, an exploration, or a learn-first path; none reads texture or flow. The MUL-shaped output the architecture diagram calls for already exists as the planner's MulGateDecision{Proceed, Sandbox, Compass}.

Why no rename in this PR

A rename touches four in-tree consumers plus ada-rs and MedCare-rs, and would bury a semantic decision inside a mechanical diff. The wrong name is load-bearing — it is why two external repos reached for a MUL type to express a consent veto and an evidence contradiction — so it gets its own reviewable PR.

Tracked as ISS-MUL-GATE-NAMED-FOR-THE-WRONG-LAYER, blocked on D-MCAL-4 (producers off the type) and D-MCAL-6 (consumers build green). Renaming first would break the same consumers twice. The issue records a candidate landing shape — move to a module named for what it gates, with a deprecated re-export for one cycle per I-LEGACY-API-FEATURE-GATED.

Three pins, so a future change is a diff and not a drift

  • f_mul_4_hold_is_a_phase_stay_with_no_learning_path — F-MUL-4's red state, asserted on purpose. Hold returns None from every column: the mailbox stays put and re-evaluates next cycle with no learn / map / recover / sandbox route attached (OQ-MCAL-2). The failure message says so, and says to update the pin when learn-routing lands.
  • f_mul_4_flow_does_move_so_the_hold_pin_is_not_vacuous — the anti-vacuity twin. Hold-returns-None-everywhere would be uninformative if the gate moved nothing at all, so Flow must advance where the DAG has a successor and must not invent one where it does not (Commit / Prune are absorbing).
  • f_mul_4_routing_ignores_the_calibration_payload — the naming evidence in executable form. Two Blocks with different (texture, flow) pairs must route identically from every column (with assert_ne! on the payloads first, so the test cannot pass by them being equal). If this ever fails, the payload became load-bearing and the D-MCAL-2 deprecation needs revisiting.

Verification

cargo test -p lance-graph-contract --lib        → 1224 passed, 0 failed
cargo clippy -p lance-graph-contract --all-targets → clean
cargo fmt -p lance-graph-contract --check          → clean

Board hygiene (same commit)

ISSUES.md entry for the deferred rename · STATUS_BOARD.md row · INTEGRATION_PLANS.md prepend · supersession index regenerated last.


Generated by Claude Code

`contract::mul::GateDecision` gains a "what this type actually is" section.
It is the EXECUTION / COMMIT gate, not MUL's output, and it lives in a module
called `mul` for historical reasons that have been misleading consumers for as
long as the name has existed.

The consumer table is inlined from the D-MCAL-1 census: kanban phase moves
(`Block` -> `Prune`, the Libet free-won't veto), `ActionState::{Committed,
Pending, Cancelled}`, the tier-router's `Rest` dispatch, and the supervisor's
next-column pick. Every one of them commits, cancels, or defers WORK. None
routes to a compass, an exploration, or a learn-first path, and none reads the
calibration payload. The MUL-shaped output the architecture diagram calls for
already exists as the planner's `MulGateDecision{Proceed, Sandbox, Compass}`.

No rename here, deliberately. A rename touches four in-tree consumers plus
ada-rs and MedCare-rs, and would bury a semantic decision inside a mechanical
diff. The wrong name is load-bearing — it is why two external repos reached
for a MUL type to express a consent veto and an evidence contradiction — so it
gets its own reviewable PR, tracked as ISS-MUL-GATE-NAMED-FOR-THE-WRONG-LAYER
and blocked on D-MCAL-4 and D-MCAL-6. Renaming before those land would break
the same consumers twice.

Three falsifiers pin today's behaviour so a future change is a visible diff
rather than a silent drift:

- `f_mul_4_hold_is_a_phase_stay_with_no_learning_path` — F-MUL-4's RED state.
  `Hold` returns `None` from every column, so the mailbox stays put with no
  learn / map / recover / sandbox route attached (OQ-MCAL-2). Asserted on
  purpose; when learn-routing lands, this pin moves in the same commit.
- `f_mul_4_flow_does_move_so_the_hold_pin_is_not_vacuous` — the anti-vacuity
  twin. A gate that moved nothing would make the pin above uninformative, so
  `Flow` must advance where the DAG has a successor and must not invent one
  where it does not.
- `f_mul_4_routing_ignores_the_calibration_payload` — the naming evidence in
  executable form. Two `Block`s carrying different (texture, flow) pairs route
  identically from every column. If this ever fails the payload became
  load-bearing and the D-MCAL-2 deprecation needs revisiting.

1224 contract lib tests green; clippy --all-targets and fmt clean.

Board hygiene in the same commit: ISSUES entry for the deferred rename with
its candidate landing shape, 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: 91a6bae2-5a1b-4c62-b33e-2ec8ecfbab64


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_0a9cb14f-adb7-44c5-a134-5fa60e9b4559)

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

ℹ️ 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 +150 to +151
/// The census (`.claude/plans/mul-consumer-census-v1.md`) enumerated every
/// consumer. Each of them commits, cancels, or defers **work**:

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 Point the census reference at an existing file

The central consumer claim links to .claude/plans/mul-consumer-census-v1.md, but a repository-wide file search and rg find no such file; the classification currently exists in §2 of .claude/plans/mul-calibration-not-verdict-v1.md. As written, readers cannot inspect the evidence supporting this doc-first semantic decision, so either link the existing plan or add the referenced census.

Useful? React with 👍 / 👎.

/// | consumer | what it does |
/// |---|---|
/// | [`crate::kanban::KanbanColumn::advance_on_gate`] | phase-DAG move; `Block` → `Prune` (Libet "free won't" veto) |
/// | [`crate::action::ActionInstance`] `commit` / `emit` | `ActionState::{Committed, Pending, Cancelled}` |

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 Link the actual action gate type and methods

This public documentation names and links crate::action::ActionInstance, but the module exposes ActionInvocation; its relevant methods are commit and commit_via, not commit and emit. Consequently the intra-doc link is unresolved and the consumer table directs readers to an API that does not exist.

Useful? React with 👍 / 👎.

…the-execution-gate

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