Skip to content

Alignment checkpoints: rooted chains, checkpoint-due epochs, issue breadcrumbs + project suites - #12684

Merged
briansrls merged 16 commits into
test/main-plus-roadmap-dailyfrom
work/name-logout-fix
Sep 30, 2026
Merged

briansrls merged 16 commits into
test/main-plus-roadmap-dailyfrom
work/name-logout-fix

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

Three commits on top of the deployed line (f9793c8), implementing reviews 5354823380 and the follow-up map/fold direction's harness-side half.

What changes

Harness (42a6136) — a chain-carrying worker turn that spends its step quantum no longer ends TurnStepBudgetExhausted. It writes turn.alignment_checkpoint_due (bound to the chain fingerprint) and returns TurnAlignmentCheckpointDue; adjudication is the workflow's, outside the worker loop — no provider call at the boundary, no worker self-grading. Reviewers/auditors/supervisors/probes keep hard budgets. The provider-event reader admits the new event; the round notice says what zero means in each mode.

Alignment model (e7d85d0) — the membership walk must terminate at an admitted root (declared_roadmap_roots() = gunbc-project-root); any other standalone end resolves AlignmentWalkUnrooted naming the halt. AlignmentChainLink carries the full ticket (approach, red control, handback, displaced cost) plus contribution_to_parent from the edge; RoadmapMembership gains contribution; the fingerprint preimage covers all of it (alignment-chain/v2). Levels and renders are root→leaf, cadence still leaf-indexed. Hierarchy authored: gunbc-project-root ← harness-work-lifecycle ← harness-recursive-alignment ← harness-alignment-checkpoint-resume and harness-conversation-log-forking, plus the shell batch attached to the root.

Dashboard (f73cd93) — the issue page renders the derived project path as a breadcrumb (root→leaf, via the same alignment_resolve the dispatch gate uses); project crumbs link to the new /project/<id> suite page listing direct members in stable topological order; unresolved chains render the typed refusal, never a partial path.

Deployment consequence (deliberate, flagged)

Dispatch of a node whose walk does not reach gunbc-project-root now refuses at the alignment step. Today that is everything outside the shell batch and the harness lineage. Attaching the wider population (with honest per-edge contributions) is follow-on authoring. Do not merge into the live line until that population decision is made.

Verification

12 affected suites run serially under MemoryMax=6G: all green except two pre-existing reds (witness_ticket_brief_budget_holds_and_reds, the_two_production_lineages_escalate_and_convene_naming_their_derived_supervisor) confirmed reproducible on the clean baseline. Live-checked on the preview entry: /project/shell-typed-invocation → 200 with 10 ordered members; issue page breadcrumb renders; unknown project → 404.

Not in this PR

The belt adjudication lane (independent per-level probes as durable obligations, parallel fan-out, deterministic roundup, guidance-consumption receipts, durable cadence state) and the conversation-log/fork-point mechanism (node authored, unimplemented).

…int announcement, not a terminal

A chain-carrying turn (workers; reviewers/auditors/probes stay hard-budgeted) that spends its step
quantum no longer ends TurnStepBudgetExhausted: it writes turn.alignment_checkpoint_due -- bound to
the chain fingerprint the attempt spawned with -- and returns TurnAlignmentCheckpointDue to the
workflow. Adjudication belongs outside the worker loop (review 5354823380): the harness never calls
the provider at the boundary and never asks the worker to grade itself; the belt's adjudication lane
reads the due event and decides resume, steer, re-plan, route or stop. The provider-event reader
admits the new event type and folds it into the stopped-but-not-failed standing, and the per-round
budget notice now says what zero means in each mode rather than threatening a finish line that does
not exist. Witness pins the event's fingerprint binding, the outcome's spelling, and the two notice
conclusions.
…e whole ticket, and every edge argues its contribution

The membership walk no longer accepts a standalone end at an arbitrary node: only a declared root
(gunbc.roadmap_nesting declared_roadmap_roots = gunbc-project-root) may be parentless, and any
other halt resolves AlignmentWalkUnrooted naming where the walk stopped -- a chain that never
reaches the top of its functional decomposition has no alignment answer (review 5354823380).
AlignmentChainLink keeps the full ticket carrier (approach, red control, handback, displaced cost)
plus contribution_to_parent, the edge's own argument for why the child's work advances its parent;
RoadmapMembership gains that field and the fingerprint preimage covers it (alignment-chain/v2).
Levels and renders are root-to-leaf with cadence still counted from the leaf. The hierarchy is
authored: gunbc-project-root <- harness-work-lifecycle <- harness-recursive-alignment <-
harness-alignment-checkpoint-resume and harness-conversation-log-forking, plus the shell batch
attached at the root. KNOWN GATE: dispatch of any node whose walk does not reach the root now
refuses at the alignment step; attaching the wider population is follow-on authoring, not assumed
here. Witnesses updated to the rooted fixtures; two pre-existing reds (page ticket-brief budget,
belt two-lineage escalation) reproduce on the clean baseline and are untouched.
…oject level gets a suite page

The issue detail page now shows the node's alignment chain as a breadcrumb, root to leaf, derived
from the same alignment_resolve the dispatch gate consumes -- never a second path answer. Project
crumbs link to the new GET /project/<node_id> suite page, which lists the project's direct members
in stable topological order (declared dependency edges restricted to the member set, Kahn-layered,
authored order within a layer) with links to their issues; the task crumb is plain text, and an
unresolved chain renders the typed refusal instead of a partial path. Four presentation witnesses
pin root-to-leaf rendering, refusal honesty, exact direct-membership, and prerequisite-first
ordering.
…ots, plans, render receipts

A prompt is a projection of an admitted context snapshot, never an authored string (scoped review
against 81e7c77; owner direction 2026-09-29). PromptInput types the five input kinds with their
authority revisions; PromptContextSnapshot binds them to an attempt lineage, epoch, and source
revision; PromptPlan assembly refuses a required segment whose source stands Withdrawn rather than
rendering a retracted claim as established; PromptRenderReceipt digests exactly what rendered, so
identical snapshots render identical digests and a moved authority revision invalidates the old
render. Segment content is rendered prose, digested -- the types guard provenance and revision, not
the prose, and semantic contradiction between free-text inputs is NOT inferred (conflicts must be
typed to refuse). Roadmap: harness-prompt-context-model authored under harness-work-lifecycle, with
its edge contribution. Next cuts: harness_guidance emits modeled segments; the belt probe DAG
consumes snapshots from day one; harness_turn migrates to PromptPlan last.
…ender projection

harness_guidance_segments turns the grounded-premise/derived-conclusion population into
PromptSegments on gunbc.harness.harness_prompt_context: each premise segment's source is an
AuthorityInput naming its grounding DeclarationRef at the caller's source revision, and each
conclusion segment is a DerivedConclusionInput naming its grounds, so a retracted premise moves the
conclusion's input digest. The prose stays the render projection of the same population, pinned by
a parity witness so the two cannot fork; a second witness pins that a moved source revision moves
the segment inputs while content digests stay stable. This is the first consumer of the prompt
context model and the shape the worker, reviewer, and alignment-probe prompts converge on.

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cut 2 / checkpoint continuation review — HOLD before belt execution

Reviewed exact head 859d1b4313a78be8c7d42ac5e56309970857a555 (five commits). This review is scoped to the rooted-alignment, checkpoint, and prompt-context program. It does not claim the two reported baseline reds are introduced here, and it performs no live dispatch or deployment.

The direction is right: TurnAlignmentCheckpointDue returns advancement to the workflow; the rooted chain and edge contributions are real improvements; and harness_guidance now has a modeled segment projection. The belt lane may begin at the pure checkpoint-subject / obligation-planning seam. It must not execute probes or resume workers until the blockers below are repaired and the conversation/fork substrate exists.

P0 — prompt_plan_assemble does not establish its stated law

The function accepts an arbitrary rendered: List<PromptSegment> and stores it unchanged. It does not prove:

  • every rendered segment's source belongs to snapshot.inputs;
  • every required non-withdrawn input is rendered exactly once;
  • no input is duplicated;
  • no snapshot input is silently omitted;
  • withdrawn inputs are excluded.

The witness currently codifies the opposite of the declared/red-control law: a non-required EvidenceInput { standing: Withdrawn } is passed through and the test requires count(plan.ordered_segments) == 1.

Replace the free list with an exact join over stable input identities. Assembly should return typed refusals for missing, extra, duplicate, source-mismatched, and withdrawn-rendered populations. A withdrawn optional input is absent from the plan; it is not rendered stale text.

P0 — semantic standing is absent from the identities

prompt_input_canonical_text drops:

  • EvidenceInput.standing;
  • GuidanceInput.resolved.

Thus Hypothesis → EstablishedObservation, OpenQuestion → Withdrawn, or unresolved → resolved guidance can retain the same snapshot/input identity; if the prose happens not to move, the render digest also stays the same. That is the exact causal-state change this model exists to preserve.

All semantically relevant fields must enter a canonical, unambiguous encoding. Do not use delimiter concatenation over unconstrained strings unless the encoding proves delimiter exclusion; use a structural/length-prefixed canonical form.

P0 — the render receipt has no exact boundaries and conflates semantic text with provider wire

The owner's requirement was that we always know exactly where modeled prompt text starts/stops and generated text starts/stops. PromptSegment has no stable node identity or extent, and PromptRenderReceipt has only one rendered_digest.

The current witness requires that Anthropic and OpenAI projections over the same supplied string have the same render digest. That can be a semantic prompt-text digest, but it cannot also be the digest of the exact provider request: the provider envelopes differ.

Carry both:

semantic prompt artifact
  ordered segment identities
  UTF-8 byte extent [start,end) per segment
  semantic digest

provider wire artifact
  exact emitted request bytes
  wire digest
  projection identity/version
  mapping from semantic artifact to its encoded wire fields

Use UTF-8 byte offsets as the canonical boundary unit; derive code-point/grapheme display positions only when needed. The conversation-log cut must apply the twin law to generated output: retain the exact raw response/frame bytes plus decoded block extents. Hashes alone prove equality, not start/stop boundaries.

P1 — conclusion causality is over-approximated and duplicated

Every derived conclusion currently records all premise declarations as grounds, regardless of which premises caused that conclusion. This loses the causal graph and causes unrelated premise changes to invalidate everything. Also DerivedConclusionInput.conclusion: String duplicates PromptSegment.content; a caller can make them disagree.

Derive a typed conclusion node once, with the exact premise/input identities its rule consumed, and render its prose from that node. Do not independently author the same conclusion as both source text and segment text.

P1 — the alignment fingerprint does not cover the full carried contract

AlignmentChainLink now carries handback and displaced_cost, and the PR/body says the fingerprint covers the full ticket, but alignment_chain_canonical_text omits both. The current alignment render also omits both. Changing either field therefore leaves the chain fingerprint and the worker's rendered alignment context unchanged.

Include every alignment-relevant carried field, or explicitly remove a field from the alignment carrier with a reason. Add one discriminator per field.

P1 — missing contribution can masquerade as the root

alignment_membership_contribution takes .first() and defaults missing to ""; rendering interprets "" as “this level is the admitted root project.” A missing/duplicate contribution is therefore representable as a plausible root standing.

Model the distinction structurally:

RootLevel
MemberLevel { contribution: NonEmptyStr }

and refuse missing or multiple matching membership rows. Rootness comes from the admitted-root authority, never from an empty-string sentinel.

P1 — checkpoint identity and process standing are not complete yet

The due event carries steps_taken and chain_fingerprint, but repeated checkpoints need a stable operation identity binding at least attempt lineage + epoch/checkpoint ordinal + frozen work/conversation subject. The belt may freeze the larger subject, but the due event/derived obligation needs an idempotency seed that distinguishes checkpoint 1 from checkpoint 2 and survives retry.

Also, the guidance currently says “the turn does not end” and “answer the checkpoint honestly,” while the harness returns control without another provider call and the witness requires harness_turn_exit to return ExitFailure { code: 1 }. The truthful wording is that the work/lineage does not end; this execution epoch does. The worker does not adjudicate it. Either give the normal control-transfer outcome a modeled admitted exit standing, or prove every process/systemd/worker-evidence consumer distinguishes this exit from failure. Add a wet consumer-path control; do not rely only on the provider JSON fold.

Rollout — do not solve the chicken-and-egg with a fallback

The PR correctly says not to merge into the live line while almost every dispatchable node is unrooted. The migration does not require the new checkpoint harness: it is authority authoring and can be performed with the current tools.

Before activation, derive and close this census:

current dispatchable node population
− nodes whose unique membership walk reaches an admitted root
= explicit attachment obligations

Fan those obligations out by existing top-level project, review the edge contributions, then fold to one zero-unrooted receipt. Make node creation/dispatchability refuse when its rooted attachment is absent so the population cannot regress. Plan a drain/cutover for already-running attempts; do not add a compatibility mode that silently crowns unrooted nodes.

Correct dependency DAG from here

A  repair PromptInput/Plan identity, exact assembly, and render boundaries
B  root-population census + attachments                         (parallel with A)
C  freeze checkpoint subject + derive durable per-level obligations  (depends A)
D  conversation AST/log + typed fork points + exact output persistence
   + fabric cache-residency observations                        (depends A)
E  execute independent level probes through PromptPlan          (depends C + D)
F  deterministic roundup                                        (depends every probe terminal)
G  publish guidance/cadence and resume exactly once             (depends D + F)
H  finish migration of the ordinary worker path to PromptPlan

The pure C slice may start now. Do not add new probe prompts as ad-hoc strings: even before the full worker migration, the alignment-probe entry must consume a PromptPlan through one temporary projection adapter. Do not claim end-to-end resume until D exists; otherwise “resume” is another cold re-brief and the causal lineage is lost.

Fabric / KV state belongs in D, as an observation

Do not say the AST nodes themselves are physically stored in KV unless the runtime exposes that fact. Model the causal relation:

conversation/context nodes
→ semantic rendered byte extents
→ token sequence/prefix under exact tokenizer + chat template
→ observed KV-prefix residency at a fabric serving location

A residency observation should bind location/serving unit, model/checkpoint, tokenizer/template/tool/projection identities, prefix digest and token cut, covered context-node refs, generation, observed-at time, and expiry/unknown standing. Warm placement may reduce cost; a cache miss must reconstruct the same request and cannot change correctness.

Required REDs

  1. Extra, missing, duplicate, and source-mismatched segments refuse assembly.
  2. Optional Withdrawn input produces zero rendered segments.
  3. Every standing/resolved transition moves the snapshot/input identity.
  4. Segment extents concatenate exactly to semantic text, including Unicode and empty/newline boundaries.
  5. Same semantic plan under two provider projections has one semantic digest and two exact wire digests.
  6. Generated response raw bytes and decoded blocks retain exact extents.
  7. Each conclusion names only the premise/input identities its derivation consumed.
  8. Changing handback or displaced cost moves the chain fingerprint.
  9. Missing, duplicate, or empty non-root contribution refuses; it never renders as root.
  10. Checkpoints 1 and 2 on one lineage have different durable identities; crash/retry launches exactly one next epoch.
  11. No dispatchable production node remains unrooted at activation.
  12. Warm-cache and cold-cache execution render identical request bytes.

Disposition: COMMENT retaining HOLD at 859d1b4313. Continue with the bounded repairs and the pure belt-planning slice; keep live dispatch and worker resume held until the dependency join above is satisfied. GitHub does not permit the authenticated PR author to submit REQUEST_CHANGES on their own PR, so this exact-head comment carries the hold.

briansrls and others added 11 commits September 29, 2026 22:30
…t prompt assembly, standing-sensitive identities, honest checkpoint handoff

Prompt model: assembly is now an EXACT JOIN between the snapshot's eligible inputs and their
renderings -- every non-withdrawn input renders exactly once, withdrawn inputs render zero
segments, foreign or duplicate segments refuse with typed causes (RequiredSourceUnrendered /
MissingRendering / DuplicateRendering / UnexpectedRendering / WithdrawnSourceRendered), and the
plan's segment order derives from the snapshot, never the caller's render order. Canonical
preimages are length-prefixed and carry standing/resolved/required, so a hypothesis becoming an
observation is a different input, and no field containing a separator can manufacture another
sequence's preimage. SemanticPromptArtifact carries per-segment extents with an honestly declared
char-count-fallback basis until a UTF-8 byte primitive exists; ProviderPromptArtifact separates the
shared semantic digest from the per-envelope wire digest. harness_guidance conclusions now record
their EXACT premise grounds (a moved test-process premise no longer invalidates the write-form
conclusion), conclusions are keyed once and rendered, and required is derived from the source
input, never asserted beside it.

Alignment: the fingerprint preimage covers handback and displaced_cost and the render shows them;
the contribution read is a typed fail-closed lookup (missing/vacuous/conflicting edges refuse with
the edge named) rather than defaulting to the empty string that used to read as root membership;
rootness in the render comes only from declared_roadmap_roots; duplicated same-project membership
rows are no longer misread as an ownership fork (they reach the contribution read, which judges
agreement). AlignmentCheckpointIdentity (lineage, epoch, ordinal, chain fingerprint, conversation
tip, candidate subject) is the belt adjudication lane's idempotency key.

Handoff honesty: the worker notice now states the epoch boundary returns control for an INDEPENDENT
checkpoint -- the harness makes no provider call and the worker is not asked to grade itself --
and checkpoint-due exits with the distinct admitted standing 3, never the generic failure code 1.

Witnesses: per-field fingerprint mutation controls (purpose, boundary, approach, red control,
handback, displaced cost, contribution), vacuous and conflicting contribution refusals, exact-join
assembly controls, standing-sensitive identity, extents, and the semantic/wire digest split. Full
affected suite sweep green; the two known pre-existing reds are untouched.
…rsive-alignment

The pure planner node (review 5358022153 lane C): freeze the checkpoint subject and derive the
homogeneous probe obligations idempotently, so the parallel probe fan-out is a schedule over
derived facts rather than an in-loop improvisation.
…ver the alignment ladder

Lane C of review 5358022153: checkpoint_probe_obligations walks the resolved
chain's levels root-to-leaf and derives one probe obligation per level
(principles, project, task), each keyed by a content digest over the checkpoint
identity digest plus the level identity, so a crash re-derives byte-identical
keys. A checkpoint whose chain fingerprint moved refuses rather than minting
obligations a stale checkpoint would execute; outstanding guidance carries the
cadence state's recorded verdict payload at the level's leaf distance, and
nothing for ALIGNED. No model calls, no effects, no verdicts -- the population
a durable scheduler executes later.
…bric KV residency as observation (review 5358022153, lane D)

- harness_turn: every round persists its exact request and response bytes
  under <events_path>.wire/<round>.{request,response}.json (same round
  numbering as round.usage); a refused wire-log write emits the non-terminal
  turn.wire_log_unwritable event and the turn continues -- the event stream
  is the terminal record, the wire log is recoverable evidence, and trading
  the work for the receipt is the wrong trade. Filesystem.Write does not
  create parents; the writes rely on the wire directory being provisioned
  with the attempt state directory, the same reliance the scratch pair
  carries.
- harness_conversation_fork: ConversationForkPoint/ConversationForkAdmittance
  -- a fork is admitted only while model identity, wire shape and alignment
  chain fingerprint all still hold, each refusal naming its cause (a fork
  across a model change replays context the engine never computed). The
  receipt states the law: the durable log is the correctness authority, KV
  residency is a performance derivation, never a correctness dependency.
  KvPrefixResidency/Observation model the fabric cache standing as pure
  observation: Resident prefers a warm location, every other standing --
  Unobserved honestly included -- executes cold from durable state; a fork
  receipt binds model/checkpoint/tokenizer/template/tool-schema/projection/
  prefix digests, and a shared chain fingerprint alone never establishes the
  same KV prefix.
- roadmap_provider_events: admits turn.wire_log_unwritable as a classified,
  non-terminal event with provider state unchanged (round.usage arm pattern);
  the jq projection passes unknown types through as {type} so the bounded
  envelope classifier is the single admission point.
- witnesses: fork admitted on exact identity match; each invalidation refuses
  with its named cause; five residency standings are distinct variants with
  Unobserved defaulting to cold; pure parts only, no harness IO wet-tested.
Lane B of review 5358022153. The census derived from declared_roadmap_nodes()
and declared_roadmap_memberships() found 195 nodes, 18 rooted, 177 unrooted --
18 carrying an ExecutionContract (thirteen active rows plus five completed
belt-era rows still bound), the population dispatch refuses at the alignment
step today.

Author the attachments: seven program-level nodes (dag-scm-program,
namespace-unique-on-chain, v1-deletion-program, v2-emitter-production,
ci-end-to-end-execution, progress-observation, roadmap-acceptance-integrity)
carry the thirteen rows that had no honest existing parent, and the five
completed belt-era rows ride the existing harness-work-lifecycle. Twenty-five
new membership rows, each edge's contribution arguing why that child's work
advances that parent, each program's root edge arguing why the program serves
the factory. extended-admission-cardinality stays unrooted on purpose -- it is
the named refusal subject of the unrooted controls, and it carries
ExecutionContractUnspecified, so it sits outside the dispatchable population.

roadmap_alignment_witness_test gains
every_dispatchable_node_reaches_the_admitted_root: every node whose execution
is an ExecutionContract must derive AlignmentChained, derived from the
authority, with no named exclusions.
…re separate triggers; session standing reads the profile projection; wire-log directory provisioned

Fixes the reported regression where clicking an issue title link intercepted the anchor, selected
the row, and opened the project's topological strip instead of navigating: the link click now
returns untouched (middle-click and modifiers were already untouched), and focus/topological
strip are the topological-sort chip, the row body, or Enter/Space. Cut B repairs: the session
standing endpoint prefers the durable profile projection's members (session stays the identity
authority, projection the display authority), reports the roster's degradation as data
(profile store unread / N records unreadable), and the profile read's skipped entries are
carried with reasons instead of silently dropped. The attempt-state prepare now provisions the
wire-log directory (<events>.wire/) so the harness's per-round request/response persistence
lands (harness-conversation-log-forking).
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.

1 participant