Repository navigation
A dispatch's destination, validation composition and scope are per-node facts, not per-instance constants - #11248
gunbai-bot[bot] wants to merge 96 commits into
Conversation
…s, stub the deriver
NodeSizing fused four facts under one discriminant: whether a roadmap row
is a dispatchable work item, the repository the work happens in, the
evidence its acceptance expects, and a hand-authored intricacy/volume
guess at how big it is. Only the last is a size, and an author's ordinal
guess is not a measurement — nothing observed it and nothing could
contradict it, yet the spawn request published it, the page badged it,
and the forecast keyed its cycle-time calibration on it.
The first three facts are now RoadmapNode.dispatch: WorkItemDispatch =
NotDispatchable | Dispatchable { repo, acceptance }. The fourth leaves
the authored surface entirely: gunbc.roadmap_sizing owns Intricacy,
Volume and NodeSizing, and derive_task_sizing answers for a SizingSubject
(title, description, exit criterion) rather than for a RoadmapNode, so a
plan item in another repository can be sized by the same authority. It is
a stub today and says so through a distinct SizingNotDerivable arm; there
is no default cell anywhere.
Sizing no longer reaches admission at all, by construction rather than by
policy (operator ruling 2026-09-10). LaunchSizeMissing is renamed
LaunchDispatchBindingMissing — it never checked a size, it checked the
repo+acceptance binding, which is a destination fact and stays.
gunbc.dispatch_selection, the consumer that legitimately wants a size,
receives a two-arm SizingProfileExpectation and records it on the
receipt; both arms resolve identically today and the carrier says so.
The forecast takes its sizings as a parameter instead of reading them off
the node, which keeps its positive controls authorable while the deriver
is a stub. Production passes derived_node_sizings, which is empty, so the
live graph REFUSES with NodeUnsized rather than rendering a schedule —
executed, not asserted. That loss is declared:
gunbc.rung_drop.roadmap_sizing_authored_to_derived, whose trigger names
the capability and explicitly refuses to be satisfied by any
constant-returning function.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…ctation, retire the live calibration witnesses with their subject, and admit the wave-admission relocations Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…invariance controls Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…t the two recomputed folds Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
# Conflicts: # dag/gunbc/rung_drop/roster.dag # docs/design-rung-drops.md
…conversion flattened witness_unsized_node_refuses was handed a cell, making the NodeUnsized arm unreachable; unsized is now absence from the assignment list, so it passes an empty list. witness_empty_calibration_cell_refuses was handed the shared medium/medium cell, which the fixture observations calibrate, so its gap could not exist; it names high/small explicitly again. Both return true by execution. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…hority The merge driver's repair route leaves the base side's bytes in place and defers regeneration to heal; that is correct while the authority merge is in flight. The merge is committed, so the projection is derived here from the merged roster instead of left disagreeing with it. Verified by set difference against origin/main rather than by count: no row went dark, and the only delta is this PR's own drop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
roadmap_node_identity_law in the same module names the slug a FORBIDDEN identity input, so keying a derivation to rn.node would join later sizing evidence to a name that can change under it. Operator merge-gate ruling on gunbc#10994. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…t was retyped The sentence survived from the first design, which the 2026-09-10 ruling reversed: dispatch_selection keeps the passenger as the two-arm SizingProfileExpectation. The load-bearing claim is unchanged and was correct -- no dispatch path refused on a size before or after -- but a rung-drop row is where a future reader looks for what a change touched, so the false clause is repaired rather than left standing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…wo live witnesses that must fail witness_cited_acceptance_pr_history_joins_without_refusal asserted four observations and zero refusals from a join that now refuses every link, and witness_live_calibration_keeps_small_sample_intervals asserted exact intervals for three cells nothing sizes. The first is rewritten to assert the honest state -- EVERY cited link refuses as HistoryNodeUnsized, which measures the loss as total and loud and goes red when a link joins again. The second is retired by name into the drop population beside the three already there. The drop's population also cited a symbol that does not exist (cycle_time_history_for_link); it names observation_for_link now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
… reads sizing_profile_expectation_label had no call site outside a witness and rendered the byte-identical string sizing_derivation_detail already produced -- a dangling declaration and a second name for one concept. sizing_derivation_detail was the same shape one module over: its only reader was the same witness. Both are deleted rather than given a speculative consumer; the witness asserts through intricacy_label and volume_label, which the spawn request and the page badge do execute. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
The launch-admission note named the NEW arm spelling as the old one -- my own blanket rename rewrote the sentence that records what the rename was. The roadmap_status note named gunbc.roadmap_sizing as the fold's caller, which contradicts that module's own rule that it imports nothing from the roadmap; the caller is gunbc.roadmap_model node_sizing_subject. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…ster The floor adjudicates enrolled debt identities against the declared tree and refuses when a roster names a claim that no longer exists, which is what it did: retiring the witnesses into the drop population left their identities standing in v2.workflow.floor_cost_debt. Delisted at identity grain, not by count. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…po fact The pin still expected the fused badge span class="sizing">i:low v:small gunbc</span>, which production cannot emit now that the badge is split into a repo fact and a derived sizing fact the stub refuses. It expects class="repo">gunbc</span>, asserts no sizing span anywhere, and says in the note that a sizing span reappearing is the declared drop retiring. Green by execution on the real emit path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…reintroduced Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
witness_active_sizes_are_intentional_and_nonuniform asserted that the authored cells across the active rows were deliberate rather than one value copied down the file. Nothing carries a cell now, so the claim has no population and the mechanical conversion had already flattened its two any-clauses into the same vacuous check. Retired by name into the drop population rather than weakened into a green that asserts what the row shape witness already checks by identity. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
… subject, refuse two cells for one subject
The subject was keyed to the node's minted identity and then REATTRIBUTED
positionally: sizing_derived_cell erased the subject the deriver answered
under and derived_node_sizings rebound the cell to the caller's slug. So
derive_task_sizing(A) returning SizingDerived{subject: B} would have given
A B's cell. Dormant only because the stub refuses -- and this adapter is
written to start producing with no second edit, so it was a live defect
scheduled to arrive silently at the seam built to activate later.
NodeSizingAssignment now carries the SizingSubjectId the deriver answered
under, every lookup projects the node through the single
node_sizing_subject_id, and node_sizing_adaptation compares asked against
answered: a mismatch is SizingForAnotherSubject, never an assignment. The
derivation is a parameter there so the control is authorable.
assigned_sizing takes the first match, which is only correct if a subject
appears once; nothing in a List enforced that, so two cells for one
subject were adjudicated by list order. schedule_forecast now refuses with
SizingAssignedTwice before any fold reads the population.
The live-stub witness compared a non-empty NodeUnsized list, which a
forecast that dropped all but one node would also satisfy. It now joins
the refused population against the live active graph by identity in both
directions, so the sentence the PR body builds on it is the sentence it
proves.
Unchanged: the authored-size deletion, the dispatch/admission separation,
the named witness retirements, the declared rung drop.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…control The controls live in test.claim.roadmap_forecast_witness, beside the type they exercise, not in test.claim.roadmap_sizing_witness. A reader following the pointer to check whether the rebind seam is guarded would have found nothing and concluded it is not. Third instance of this class in the branch, so I swept rather than patched: every module/symbol citation this PR adds was checked to resolve, and every witness it names was checked to exist -- or, for the five retired ones, to be genuinely gone. This was the only miss. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
The adapter's own note says a fold reading only .assignments makes a wrong-subject answer indistinguishable from an unsized node, and that is exactly what roadmap_cycle_time_observation_builds did: a SizingForAnotherSubject degraded silently into HistoryNodeUnsized and blamed the wrong cause, and duplicate_sizing_subjects never ran, so two conflicting cells for one subject were back to being adjudicated by list order inside assigned_sizing. I fixed the live forecast path and skipped its sibling. Both checks now run there, and the whole build refuses with a typed HistorySizingAssignmentRefused carrying the located refusals rather than proceeding on a population it cannot trust -- the shape the sibling HistoryAcceptanceCarrierLoadRefused arm already uses. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
# Conflicts: # src/v1/stage0/src/namespace_wave_admission.rs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
…facts. A dispatched node used to publish to gunb-ai/gunbc regardless of its repo slug, so private work would have landed on the public remote. Destination now resolves from the node's repo slug, spawn records repository plus base SHA, claim argv can compose pinned-public plus local roots, allowed paths refuse wander, and non-agent modes refuse as themselves rather than as a missing contract. Co-authored-by: Cursor <cursoragent@cursor.com>
The verify gate already blocked unpinnable attempts from completing; spawn still spent a worktree, seat, and turn on work that could not verify. Ask the same observation before worktree-add and fail with the pin-refusal reason, leaving the verify-side gate unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
A slug observes owner and name only. Treat privacy and default branch as unobserved standings; safety reads unobserved as not known to be public instead of as a fabricated private:true Repository fact. Co-authored-by: Cursor <cursoragent@cursor.com>
…tor from the roster; move the annotation to module grain The witness asserted a transcribed count(builds) == 10 and merely that SOME refusal existed and all refusals were HistoryNodeUnsized. A PARTIAL deriver satisfies that: observation_for_link reaches the bundled-delivery exclusion only after a cell is present, so a deriver that sized exactly the previously-bundled links would turn those into exclusions while the rest stayed unsized -- observations still zero, refusals still non-empty and all-unsized, control still green. That is the opposite of the claim the name, the comment and the drop row make. It now joins refusals to accepted_node_pull_links in both directions, requires the exclusion population to be empty, and takes every denominator from the live roster rather than from a literal copied out of the current tree. Also: the assignment-check annotation I added to roadmap_cycle_time_observation_builds sat INSIDE the body, which the parse phase refuses -- DESIGN section 4c admits annotations only at module-item grain. Moved above the declaration, and I checked every file this PR touches for the same shape. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YT3CM7TgQNeyBp1REtuxWE
# Conflicts: # dag/gunbc/rung_drop/roster.dag # docs/design-rung-drops.md
Take main's namespace-wave admission file (#11165 candidate-set shape, empty roster). Re-author the 17 sizing TargetChanged rows with expected_candidates as the head sets the required floor printed for those identities. Co-authored-by: Cursor <cursoragent@cursor.com>
…loor print. expected_candidates records the intended head set: each spelling is declared in one module and named by that import. Copying a found-candidates line would make the equality check tautological. Co-authored-by: Cursor <cursoragent@cursor.com>
roadmap_sizing.dag is absent on main, so the head candidate cannot already be satisfied there. Each spelling has one declaring module on each side of the unbundling. Co-authored-by: Cursor <cursoragent@cursor.com>
Unobserved destinations no longer emit "default_branch": "unobserved", which a consumer could not tell from a branch literally named that. Co-authored-by: Cursor <cursoragent@cursor.com>
The claim is the identity-join refusal through derived_node_sizings, not a live-graph walk; the enrolled identity is unchanged so the floor remeasures the same row. Co-authored-by: Cursor <cursoragent@cursor.com>
…b-deriver red. The floor on df53916 admitted namespace-wave and enrolment; it refused because this witness completed at 520ms CPU. It compared the same Gate arms via gunbc.ci_spec, whose module is surplus to the roster projection. Co-authored-by: Cursor <cursoragent@cursor.com>
…apening. The quadratic snoc folds were the cost defect. The import swap was not shown necessary for cost and is reverted, so the witness's declared-gates source is unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
…ening it. Launch and validation each had three copied arms and label strings beside the one mode authority. Wire labels for launch still join the hyphenated mode words with underscores so the dashboard ok-set does not move. Also rename destination_from_dispatch, delete the unused no_calibration_gap_count fold, and drop unused forecast/belt imports. Co-authored-by: Cursor <cursoragent@cursor.com>
This is the recut the operator CHANGES_REQUESTED on #11014 already offered: current main without that migration, using Sized/Unsized. Destination, privacy refusal, and validation composition stay. The 17 namespace-wave Binding rows go with the sizing subject so they cannot stale-red the fleet after #10994 lands. Co-authored-by: Cursor <cursoragent@cursor.com>
… gate. count != 2 already closed the split; the two first() Absent arms could not fire and repeated the same owner/name reason. Classify no longer resolves destination a second time after it has already admitted the spawn tree. Co-authored-by: Cursor <cursoragent@cursor.com>
…ness. The path_scope field edit removed the import line and left a brace block the parser could not attach to a declaration, so module index refused the file. Co-authored-by: Cursor <cursoragent@cursor.com>
…ontract matches. Floor refused resolve on belt_actuate: validation_operation_command needs source_roots, and verify-run plus authority-test matches omitted the three NonAgent arms. Co-authored-by: Cursor <cursoragent@cursor.com>
…ng closure. review 64621: first_closing_validation's Absent arm was unreachable once contract_closure already yielded ContractCloses, and it restated the unbound reason string. Carry first(validations) from that arm and delete the helper. Co-authored-by: Cursor <cursoragent@cursor.com>
Floor refused resolve at roadmap_verify.dag:453 — ContractCloses is nonempty in meaning, but List.first is still optional, so the match must name Absent. The arm does not reuse the unbound author-a-contract reason. Co-authored-by: Cursor <cursoragent@cursor.com>
review 64665: negating contract_has_closing_validation treated OperatorExclusive as a missing contract and minted a task whose brief wraps the parent in an agent contract. Authoring is warranted only for unspecified or empty agent contracts. Co-authored-by: Cursor <cursoragent@cursor.com>
review 64681: OperatorExclusive/ExternalLead/CalendarObservation duplicated NonAgentWorkMode and the 1:1 map was copied through contract_closure, the oracle gate, belt verify, and stringy decode. One arm forwards the mode; consumers read contract_closure. Co-authored-by: Cursor <cursoragent@cursor.com>
…standing. review 64692: ContractClosesNothing was an explicit pass via an empty validation fold, while verify and dispatch already treat that arm as unbound/refused. Program view still cited contract_has_closing_validation after task derivation stopped using it, so NotAgentWork would look contract-held. Co-authored-by: Cursor <cursoragent@cursor.com>
Floor refused resolve: non_agent_work_mode_from_label called some, which is not in scope. Option constructors here are Present and none. Co-authored-by: Cursor <cursoragent@cursor.com>
contract_has_closing_validation had no production caller after program_view moved to contract_closure. The three declared-frontier arms and the spawn-pin standing now bind Disposition Scaffold rows instead of restating consumer and trigger in comments. Co-authored-by: Cursor <cursoragent@cursor.com>
The remaining DECLARED FRONTIER sentence on AttemptOraclePinCapture restated standing the typed row already carries. Co-authored-by: Cursor <cursoragent@cursor.com>
Scaffold.bind named folds this diff already lands, so the trigger was true the moment it was written. FrontierRow UnboundDissolution names the missing production producer: an authority NotAgentWork node, a PinnedPublicPlusLocalRoot contract, a verify name-status call, and an admitted-base spawn-pin call. Co-authored-by: Cursor <cursoragent@cursor.com>
Floor refused the name: the same spelling is an arm of WorkItemExecutionContract. DispatchNotAgentWork matches LaunchNotAgentWork and ValidationNotAgentWork. Co-authored-by: Cursor <cursoragent@cursor.com>
A wildcard on WorkItemExecutionContract classified any new arm as not a binding and dropped it from witness_every_binding_carries_a_validation. Exhaustive matches restore the compiler wall. Co-authored-by: Cursor <cursoragent@cursor.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Closing this as a duplicate, not as a rejection: its content is already on main. This is the post-squash-merge auto-reopen. gunbc#11014 landed as a squash at Verified before closing rather than assumed: the head is not an ancestor of main (expected after a squash), and the branch carries no commit authored after the merge — its session reports the worktree still at The landed work is #11014: a dispatch's destination, validation composition and path scope are per-node facts rather than per-instance constants, taken by the recut route the native review offered — rebuilt without #10994's sizing migration on the old What remains open from that change is recorded as declared frontiers on #11014 and is deliberately not carried here: no production — sent from bright-boar-435 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ad16aba050
ℹ️ 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".
| WorktreeHeadObserved { revision } => { | ||
| let origin = DispatchSpawnOrigin { | ||
| identity: identity, | ||
| base_ref: instance.dispatch_base_ref, |
There was a problem hiding this comment.
Record the continuation branch as the spawn base ref
For every ContinueFromAttempt, the worktree is created from the prior attempt's branch via attempt_origin_base_ref, but this receipt always pairs the resulting HEAD SHA with instance.dispatch_base_ref. The new spawn-destination.json therefore records false provenance for continuation turns; pass the AttemptOrigin into this function and persist the same ref actually supplied to git worktree add.
Useful? React with 👍 / 👎.
| ObligationContractHeld => true | ||
| ObligationAccepted => false | ||
| ObligationDependencyHeld { unmet: _ } => false | ||
| ObligationNotAgentWork => false |
There was a problem hiding this comment.
Include non-agent work in primary-constraint candidates
When an unaccepted program frontier consists of a NotAgentWork node, that node has ObligationNotAgentWork standing while its descendants are dependency-held, so this filter removes every candidate and the program view reports no primary constraint. This also makes the newly added NonAgentWorkConstraint arm in program_constraint_of unreachable through its only caller; admit this standing here so the view identifies the operator/external/calendar work that is actually blocking the program.
Useful? React with 👍 / 👎.
Auto-opened by session-dashboard for session
vivid-ant-470.Pushing to
session/vivid-ant-470advances this PR.Worker attestation
Before flipping this PR to ready for review, confirm each item:
npm test,cargo test) and the result.Closes #Ndirective.Summary
TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.
Test plan