Skip to content

Namespace keystone (§8 step 1): §13 unique-on-chain resolver in the executing v1 seed, default-off - #7093

Merged
briansrls merged 3 commits into
mainfrom
cursor/namespace-only-unique-on-chain-keystone-a408
Jul 23, 2026
Merged

briansrls merged 3 commits into
mainfrom
cursor/namespace-only-unique-on-chain-keystone-a408

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

What

Lands namespace-resolution-design.md §8 step 1 in the executing v1 seed resolver — the §13 unique-on-chain semantics (operator-ratified 2026-07-21) behind a swappable NameResolutionPolicy gate, default OFF = ImportScoped, byte-for-byte today's behavior. No subtree is flipped; the flip (step 4) still gates on import→alias transmutation.

Mechanism

  • Policy gate — name_resolution_policy_is_namespace_only thread-local builtin (runtime_rust.dag → v1_rt, mirroring the resolution_silent_pick_is_enabled precedent). Host-side setter only, no .dag surface can flip it, zero env plumbing (no TypeEnv/ResolvedFuncEnv field). Registered in 04_method.dag builtins + extdeps/languages/rust/emit.dag rt rows.
  • Type/value path (04_env.dag) — under NamespaceOnlyY, a global_bare homonym resolves to the unique binder on the referencing module's ancestor chain: exactly-one resolves; zero-or-multiple refuses. The zero-on-chain whole-pool homonym is Ambiguous, never a fabricated bind — exact parity with the census containment walk (containment_resolve_fn_v1). Nearest-wins LCP preserved verbatim under the default arm.
  • Fn path (04_sigs.dag / 04_lookup.dag) — the §13-named gap ("no refusal arm at all") closed by the return-type rewrite: lookup_resolved_sig / lookup_func_sig now return FuncSigLookup = FuncSigResolved | FuncSigUnresolved | FuncSigAmbiguous{candidates}, so a refusal finally has somewhere to go. FuncSigAmbiguous never falls through to the census fallback; the Absent-as-"keep looking" straddle is dead as a class. First-hit preserved verbatim under the default. Analysis-only consumers (provenance/descent, 8 sites) project through func_sig_if_resolved — conservative no-enrichment, never a fabricated bind; the semantic bind sites (04_infer.dag ExprVar/ExprCall) match the full outcome and refuse.
  • Typed diagnostic — AmbiguousReference { name, candidates, span } minted in 00_core.dag (span-extractor + formatter arms), raised at the reference site with the full candidate fix-menu (§13: qualify / alias / rename). Emission sites: 04_resolve.dag bare-miss, 04_infer.dag type-annotation miss + record-lit presence, and both fn bind sites.

Proof (green-by-execution + RED)

  • Discriminating witness src/v1/tests/src/namespace_unique_on_chain_policy_test.rs (6 tests, all green): the same homonym fixtures compile clean under ImportScoped and refuse — typed, located, full candidate list — under NamespaceOnlyY, on both paths (ancestor-chain type homonym; 2-parent-match fn homonym, the fn_parent_first_hit silent-pick class). Controls pin the boundary: exactly-one-on-chain still resolves under the strict policy; a genuinely-unbound name stays UnresolvedType (Ambiguous and Unresolved are distinct states); the zero-on-chain homonym discriminates the diagnostic label between the two policies.
  • Regen fixed point: regen_stage0 (write) converged in two generations; regen_stage0 --verify green with regen_divergence_count=0.
  • cross_representation_equality_test (4/4), func_env_scope_chain + func_env_semantic_equivalence (6 passed / 2 pre-existing opt-in ignores), flat_parents_* (3/3), all resolution_divergence_* fixture tests (4/4), and the corpus-scoped resolution_divergence_fn_parent_first_hit_subset_holds_on_closure_scoped_corpus (green, 113s). cargo fmt --all --check clean.

Census corroboration (Brief A verified-context, re-run fresh on this base)

resolution_divergence_census whole-tree (dag + src/v2, 1309 modules, 40,592 sites): diverge=0, containment_unresolved=0, owner_mismatch=0, containment_ambiguous=38, cost shape lexical_steps={1:17175, 2:1} — the §12.3 substitution-not-rewrite claim held. Raw rows checked in at docs/probes/resolution_divergence_census_2026-07-22.tsv; design doc §8/§12.3/§12.4/§13 updated to consume it (stale #6936 numbers annotated with the refresh).

Finding surfaced (pre-existing on main, not fixed here)

The census silent-pick gate exits 1 on main in both scopes (whole-tree and --closure-scoped): 1 genuine §13 fail-open — gunbc.falsifier_workflow's bare ci_repo_root_shell first-hits gunbc.ci_spec over the byte-identical duplicate decl in gunbc.merge_admission_produce (a real §3 fork). Recorded in §12.4; needs consolidation or qualification in its own change.

Bootstrap note

The committed stage0 .rs changes are the regen fixed point of the .dag edits (the fn-path outcome type changes emitted code even default-off, as briefed). The seed was bootstrapped through the standard maneuver: minimal hand-mirror of the three new-builtin surfaces (v1_rt, builtin map, rt rows) → regen → rebuild → regen → --verify green.

Open in Web Open in Cursor 

cursoragent and others added 2 commits July 23, 2026 00:49
…er in the executing v1 seed, default-off

- NameResolutionPolicy gate: name_resolution_policy_is_namespace_only thread-local
  builtin (runtime_rust.dag -> v1_rt), host-side setter only, default OFF =
  ImportScoped byte-for-byte; registered in 04_method builtins + extdeps rust rt rows
- type/value path (04_env.dag): under NamespaceOnlyY a global_bare homonym resolves
  to the unique binder on the ancestor chain; zero-or-multiple refuses (census-walk
  parity: zero-on-chain whole-pool homonym is Ambiguous, never a fabricated bind);
  nearest-wins preserved verbatim under the default
- fn path (04_sigs/04_lookup): lookup_resolved_sig/lookup_func_sig rewritten to the
  3-state FuncSigLookup (Resolved|Unresolved|Ambiguous{candidates}) so a refusal has
  somewhere to go; FuncSigAmbiguous never falls through to the census fallback;
  first-hit preserved verbatim under the default; analysis-only consumers project
  through func_sig_if_resolved, bind sites (ExprVar/ExprCall) match the full outcome
- typed diagnostic: AmbiguousReference{name, candidates, span} in 00_core.dag with
  span/message arms; emitted at the reference site with the full candidate fix menu
  (04_resolve bare-miss, 04_infer type annotation + record-lit presence, fn bind sites)
- discriminating witness: namespace_unique_on_chain_policy_test.rs — same homonym
  fixtures compile clean under ImportScoped, refuse typed+located under NamespaceOnlyY
  on both paths; unique-on-chain-still-resolves + unbound-stays-UnresolvedType controls
- regen_stage0 two-generation fixed point: regen_divergence_count=0, --verify green
- census refresh consumed into namespace-resolution-design.md §8/§12.3/§12.4/§13 +
  raw rows in docs/probes/resolution_divergence_census_2026-07-22.tsv (diverge=0,
  containment_ambiguous=38, owner_mismatch=0, lexical_steps={1:17175,2:1})

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…usy' race)

Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
@briansrls briansrls closed this Jul 23, 2026
@gunbai-bot gunbai-bot Bot reopened this Jul 23, 2026
This was referenced Jul 23, 2026
…split

The §13 namespace-only keystone (this PR) added a host-Rust-only seed test
(namespace_unique_on_chain_policy_test.rs) that toggles the thread-local
NameResolutionPolicy gate — unreachable from a .dag witness, so it cannot
migrate and must stay .rs. It tripped test_migration_debt_module_count_does_not_grow
(81 > 80 baseline).

Principled fix (NOT a baseline bump, NOT a delete-only _retired.dag which would
be a false record + fail-open):

- dag/test/retirement/model.dag: add the non-delete variant
  RetainedNonMigratable { reason } to RetirementDisposition.
- cli_run.rs: add test_migration_retained_nonmigratable_stems() keyed on the
  _retained.dag filename suffix + a RetainedNonMigratable { constructor. SPLIT
  the single covered set into two: the debt-exclude set (floor ∪ retired ∪
  retained) feeds build_test_migration_debt_report; the delete-authorize set
  (floor ∪ retired ONLY) feeds the delete-guard. A retained stem in the
  delete-authorize set would be a §5 fail-open — silently green-lighting the
  deletion of a test that has no .dag replacement — so it is deliberately absent.
- dag/test/retirement/namespace_unique_on_chain_policy_retained.dag: the typed
  retention record for the keystone seed test.

Verified by execution: debt ratchet 4/4 PASS (module count back to 80); the 6
policy witnesses green; new §5 RED control
delete_guard_refuses_deleting_retained_nonmigratable_module green (9/9 in
test_migration_debt_tests); regen_stage0 --verify divergence=0; whole-tree
compile-clean HISTOGRAM_TOTAL_HARD 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot closed this Jul 23, 2026
@gunbai-bot gunbai-bot Bot reopened this Jul 23, 2026
@briansrls
briansrls marked this pull request as ready for review July 23, 2026 12:35
@cursor

cursor Bot commented Jul 23, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@briansrls
briansrls merged commit 0fada2c into main Jul 23, 2026
4 checks passed
@briansrls
briansrls deleted the cursor/namespace-only-unique-on-chain-keystone-a408 branch July 23, 2026 12:35
briansrls pushed a commit that referenced this pull request Jul 24, 2026
… escape; witness locks escape semantics

The ${...}-in-strings gotcha, root-caused: interpolation triggers on '{' +
identifier (the dollar is irrelevant), and a failed interpolation-body parse
escaped as a bare expression error ('expected RParen, found Colon') with no
pointer to the existing \{ escape — which works, verified by execution
(the principled shell form is "$\{VAR:-default}"; no bare-dollar
workaround needed). parse_interp_parts now wraps body-parse failures with
the interpolation context and the escape hint. Witness battery (4 claims,
green by execution) locks the escape semantics via discriminating lengths.

STAGED: stage0 regen for the 02_parse change is fail-closed BLOCKED on a
main-head breakage this work exposed — regen_stage0's v2-self-compile leg
cannot resolve name_resolution_policy_is_namespace_only from 04_env/04_sigs
(calls landed in #7093; resolution broken by the 09:0x emit-import-closure
wave). Pre-existing on the clean tree, verified by stash + --verify.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
briansrls pushed a commit that referenced this pull request Jul 24, 2026
… retract the main-breakage alert

CORRECTION: main was never broken — the regen 'breakage' was this
session's stale debug binaries (name_resolution_policy_is_namespace_only
is a native builtin registered post-#7093; a fresh build resolves it, and
main is green 12/12 through the 09:0x wave). The prior commit's STAGED
note is superseded here.

The real second defect, found by reproducing the worker's exact error
shape: parse_interp_parts' fallback arm returned SUCCESS on an unexpected
token after an interpolation expression (a fail-open — a well-formed node
handed back mid-string), letting the caller trip later with the
context-free 'expected RParen, found Colon'. The arm now refuses with the
interpolation context + literal-brace hint. Verified by execution: the
worker's shape now reports the hint; regen_stage0 --verify is
byte-clean (regen_divergence_count=0 — no legitimate interpolation in the
closure relied on the silent arm); the escaped form evaluates to
${GITHUB_BASE_REF:-origin/main} exactly; 4/4 escape witnesses PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
briansrls added a commit that referenced this pull request Jul 24, 2026
…ps, lens-door, observation UX contract (#7169)

* Plan §9.8: fleet-wide budget diagnosis — no regression, mis-denominated budget

Seven observed full-corpus batch-3 walls (1344-1629s) across five branches,
every sampled failure with all witnesses passing and memory healthy; main
12/12 green through #7129's merge. A scalar wall-time budget conflates
workload size (diff-proportional by design), host speed, and per-entry cost
creep (the actual regression dial, stable ~1.57-2.0 s/entry). Interim: one
signed raise to ~1680s on main's row; durable: re-denominated budget
(overhead + units x rate[host-class]) riding PR-1's CiSpec work.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Plan: operator rulings — atomic PR-1 with lens-door reintroduction; two-constant clamp model

Witness clamps: 5s hard max per witness (existing fast-lane authority,
unchanged) + 1s expected-average as the aggregate coefficient (batch =
overhead + units x avg; full corpus ~44min under the 55m cap). Hand-set
budget rows delete; constants signed via the existing budget_note
discipline. PR-1 is the atomic full rework (no migrations): placement
roster + gauntlet split + DiffBaseline + derived clamps + ts-lens-door
(v2-door routing, empty_complexity_report stamping deleted, complexity
lens AuditOnly -> Blocking with planted-quadratic RED). Pre-PR probe
gains the lens-audit inventory so the door flips knowing its red set.
D4 rides PR-1 iff a green cadence run exists at landing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Progress-observation plan: §6b addendum — interaction with the CI two-tier rework

Model and laws unchanged; CI renderer contract gains three event classes
(derived-clamp refusals with their arithmetic, placement dispositions,
lens findings), heartbeat keys on clamp units, AttentionLevel grounds on
the signed constants, pain point migrates to the gauntlet context, and
P1 sequences after the atomic CI PR to avoid double-churning the floor's
emit sites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Progress-observation plan: atomic-PR ruling, human-legibility contract, §6c frontend relation

One atomic PR (P0-P3 together, after the CI rework PR). Heartbeat:
identity-first, vitals-suffix, human units, once/minute max; raw byte
dumps are census violations — [floor-memory]'s current shape is the
named negative example. §6c: register thesis shared with the site lane;
glyph color roles re-ground on gunbc.design.* when it lands (dissolution
trigger, not dependency); dashboard belt B = renderer N+1 of the same
JSONL stream; gunb.ai terminal a future renderer of the shared schema.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Progress-observation plan: tone ruling — plain sentences, real emojis, clock pulse

Arm's-length lines are readable sentences, never key=value chains (dense
form lives in receipt boxes/files); glyphs are real emojis from the one
glyph authority with the reward-animal rows kept; the periodic status
line uses the clock, not the heart.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Progress-observation plan: selection prominence — the diff→runs chain is the preamble centerpiece

Per-file attribution (touched file → selected entries/witnesses), skip
count with the falsifier audit pointer, now-vs-later placement split,
and widening named in plain language with the causing file. Same
selection authority projected per file — no new telemetry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Progress-observation plan: attribution grain is the declaration, not the file

Under each touched file, the qualified names the diff actually touches
(hunks intersect declaration spans) with change kind, then the witness
count attributed at selection's real grain (module closure today, stated
honestly); decl-grain selection shrinks the same display when the
namespace lane lands it — the UI leads, selection catches up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Progress-observation plan: change-kind coloring + typed no-op taxonomy

Git-diff convention colors (green/yellow/red) as glyph-authority rows,
textual kind tag always beside color. No-ops are a closed sum — docs-policy,
uncovered (a visible coverage nudge), no-decls-touched, generated-artifact,
deletion (widens, not a no-op) — a bare unlabeled 'nothing' is a census
violation (the Option/None conflation pattern applied to UX).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Plan §8: two blessed stage collapses + best/worst-case envelope

Regen job folds into the floor as a spec row (serial chain becomes
build → ci → deploy; cold control stays a gauntlet row on main); the two
receipt gates fold into merge admission. Envelope: leaf PR 6-8 min;
whole-repo diff ~35-41 min honest wall (clamp ceiling ~44m, 55m cap),
with the cold-build and memory-pathology tails named and the shrink path
owned by store-econ/native-flip + W3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Plan §8: delivery restructure — #7162 grows to hold everything

Operator ruling: PR-0/PR-1 split dissolved; #7162 absorbs all remaining
pieces. Build order: clamps first (self-greening — the floor reads CiSpec
from the PR tree). D4's gate restated for the growing PR: a branch
falsifier run is the deletion receipt (main-cadence green impossible
pre-merge by construction); one green cold run post-D0 triples as D0
acceptance, D4 receipt, and cold-side probe timings. D5's Env.Get mock
is its own named part, finished in-PR. Probe: worker-driven
workflow_dispatch on fleet slots, serial, >=2 hosts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Parse: interpolation-body errors name the context + the literal-brace escape; witness locks escape semantics

The ${...}-in-strings gotcha, root-caused: interpolation triggers on '{' +
identifier (the dollar is irrelevant), and a failed interpolation-body parse
escaped as a bare expression error ('expected RParen, found Colon') with no
pointer to the existing \{ escape — which works, verified by execution
(the principled shell form is "$\{VAR:-default}"; no bare-dollar
workaround needed). parse_interp_parts now wraps body-parse failures with
the interpolation context and the escape hint. Witness battery (4 claims,
green by execution) locks the escape semantics via discriminating lengths.

STAGED: stage0 regen for the 02_parse change is fail-closed BLOCKED on a
main-head breakage this work exposed — regen_stage0's v2-self-compile leg
cannot resolve name_resolution_policy_is_namespace_only from 04_env/04_sigs
(calls landed in #7093; resolution broken by the 09:0x emit-import-closure
wave). Pre-existing on the clean tree, verified by stash + --verify.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Parse: close the interpolation fallback fail-open; regenerate stage0; retract the main-breakage alert

CORRECTION: main was never broken — the regen 'breakage' was this
session's stale debug binaries (name_resolution_policy_is_namespace_only
is a native builtin registered post-#7093; a fresh build resolves it, and
main is green 12/12 through the 09:0x wave). The prior commit's STAGED
note is superseded here.

The real second defect, found by reproducing the worker's exact error
shape: parse_interp_parts' fallback arm returned SUCCESS on an unexpected
token after an interpolation expression (a fail-open — a well-formed node
handed back mid-string), letting the caller trip later with the
context-free 'expected RParen, found Colon'. The arm now refuses with the
interpolation context + literal-brace hint. Verified by execution: the
worker's shape now reports the hint; regen_stage0 --verify is
byte-clean (regen_divergence_count=0 — no legitimate interpolation in the
closure relied on the silent arm); the escaped form evaluates to
${GITHUB_BASE_REF:-origin/main} exactly; 4/4 escape witnesses PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* DESIGN §5: the workaround rule — an absorbing fallback executed by the author

Operator ruling 2026-07-24: noticing you are implementing a workaround IS
the line-stop signal — back up, reassess, root-cause or flag for help; the
only landing states are the real fix or a declared scaffold with a named
dissolution trigger. A workaround is an unmarked scaffold; the marking is
the entire difference. Added to the recurring-failure-modes roster as
'unmarked workaround'. Receipt: the ${…}-in-strings dodge — the bare-$
respelling concealed the existing \{ escape and two real parser defects;
stopping the line surfaced all three within the hour.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Dashboard: raw-text serialization fix + progressive disclosure + register corrections

Root cause of the dead strikethrough (operator screenshots 2026-07-24):
inline <style> text was HTML-escaped, emitting '.node-superseded &gt; .title'
— an inert selector in every browser. Per the HTML spec's raw-text elements
(script, style), std.markup's MarkupMedium gains raw_text_tags and emits
their text raw; try_serialize_html_source refuses fail-closed when raw-text
content contains its own close sequence (same escape class as the
dispatch-button inline-script incident — the style copy was never fixed).

Page: rows render their LEAD (first ' — '/'. ' segment) with the full brief
behind a native <details> disclosure (188 blocks; zero JS). Style: .status
Width→MinWidth (the 'superseded' chip overflowed its fixed box into the
title); .roadmap/.daily-workspace gain auto side margins (centered);
dispatch-btn carries the figure-role border accent (actions carry the
accent; status stays quiet). Witnesses: 6 new page claims incl. the
unescaped-combinator check and the raw-text refusal RED; 10/10 green by
execution; markdown/jsx media unchanged (raw_text_tags: []) and main_wet
byte-stable.

Named follow-up (belt B lane): deploy refreshes files but the serve path's
artifact/process refresh is unproven — the live page lagged tree styling;
a served-page fingerprint check belongs in live_deploy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Plan: the roadmap as a daily workspace — readable, observable, tactile

Three pillars with exists/missing stated honestly: P1 readability (largely
landed 2026-07-24, section-collapse residue); P2 observable dispatch — the
stateful workflow: GET /sessions projection from belt B's existing observe
half, live row states, Stop/re-dispatch verbs (absorbs the filed
ts-dispatch-redispatch), progress depth via the observation lane's stream
(renderer N+1 by contract); P3 the feel register — gunbc.design.motion
tokens + the acknowledgment law (total assignment, censused like unthemed
colors), dashboard as first consumer on existing state flips, sound a
named later axis. Doc bound to roadmap_page_for_authority.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* UX plan: the dispatch button's full lifecycle + the analog root principle

Operator-directed exemplar: one control end to end. The story: rest →
pressed (ack on DOWN, act on UP) → requested (still, distinct — no pulse;
the keyframes wall holds) → spawned (settle beat, morphs into the
workflow-stage chip) → working (live stages from P2a, changes animate,
steady states still) → done (settle + re-arm; re-dispatch fix in scope) →
refused (blocked-travel dip + typed reason). Every edge a tokenized row,
totality censused. Root principle recorded for gunbc.design.principles:
simulate real analog behavior — every control an individual physical
instrument (car-knob rule): travel, mass, detents, mechanical state;
still-until-touched is analog honesty; sound = mechanism click, later
axis. Register inventory: hover/press rows exist; missing = transform
responses, settle_spring easing, lifecycle edges, sessions read.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* UX plan: binding end-to-end contract for the dispatch exemplar

Six person-observable checkpoints; the consumption rule (no register row
lands without its consumer in the same PR); the single-line-item workflow
representation (stages as detent positions, not a progress bar; history
as belt-fact projections); everything else in Pillar 3 explicitly parked;
two PRs total with PR-A independently shippable as the anti-shelf-ware
test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Observation plan: atomic ruling reaffirmed — completeness is the merge bar

Operator 2026-07-24, against the P0-carve-out argument: one PR, P0-P3
entirely, after the CI rework. The controlling rationale is completeness
(only finished work merges — landed vocabulary with no renderer is the
consumed-by-nothing state the consumption rule forbids); the
shared-emit-site rationale is secondary and not load-bearing. #7168 grows
to P0-P3 rather than merging alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

* Plan §11: D5 discharged — superseded by #7146's gunbc.diff_baseline on main

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg

---------

Co-authored-by: Claude <noreply@anthropic.com>
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