Repository navigation
Omega: runner-capacity lane consolidated (5 of 6 constituents) - #8016
Conversation
…ed replacement classification
Split MemberAction's collapsed upsert into four arms per operator ruling:
MemberAdded{to} | MemberChanged{from,to} | MemberRemoved{from} |
MemberRemovalRefused{from, cause}.
The discarded `from` was the load-bearing loss. Every safe realization of a
change consumes the prior value: an SCM ref update is a compare-and-swap that
names the expected prior (git update-ref <ref> <new> <old>), and a host resource
whose address moved needs the prior endpoint to retire. With only `to` in hand
the sole reachable realization is the unconditional write. MemberEffect splits
the same way (EffectAdd/EffectReplace{from,to}/EffectRemove) so the apply grain
can retire a prior realization instead of overwriting it blind.
gunbc.host_resource: identity is allocator-minted at declaration, never derived
from unit/path/content. HostResourceIdentity{host, occurrence} +
HostResource<R,V>{identity, role, value}, role a type parameter so a new role is
an instantiation rather than a widened central enum. This is the closed-system
answer to renames: git does not track them, it INFERS them from content
similarity, and DESIGN 4 rules a heuristic never necessary in a closed system --
a content-derived key_of is that inference wearing a bundle. Distinct carrier
from std.occurrence_identity (source-occurrence specific; one shared Int space
would let occurrence_id_eq answer true on a numeric coincidence -- the
cross-family comparison the ContentHash grounding closed). The subject-
parameterized extraction is registered as a trigger, not built under a
load-bearing module with stage0 work in flight.
gunbc.change_realization: the classification table. SCM ref -> atomic CAS;
source declaration move -> atomic SCM tree transformation; same runtime address
-> in-place update; changed host address -> staged replacement with declared
intermediates. Kills a live conflation: a .dag module re-home is an SCM tree
transformation, NOT a host migration. StagedIntermediates is head+tail so an
empty intermediate plan has no constructor, and an undeclared one refuses
(typed, located) rather than degrading to an overwrite -- the srv4 lesson (its
build-cache server died with its cgroup, never unlinked its socket, ran uncached
for weeks) made unwritable rather than warned about in prose.
A change-refusal arm was built during this work and WITHDRAWN: gunbc.ownership
defines Ensured as "requires present but does NOT own (never torn down)", a
constraint on removal, not update. It broke tool_readiness and
repo_local_git_config (whose job is re-installing drifted pins/bindings) and was
unreachable elsewhere. Per DESIGN 4c a carrier note is not evidence, so the
withdrawal is enrolled as w_ensured_member_converges_but_refuses_removal.
All three new guards verified DISCRIMINATING by planting their exact
regressions: reintroducing the change-refusal arm reds the Ensured control
alone; reintroducing the collapse reds the both-sides rows; turning the
staged-replacement refusal into an InPlaceUpdate fallback reds the srv4 row.
Caught during migration: repo_local_git_config's apply fold has a `_ => acc`
wildcard for its construction-unreachable removal arms, and MemberChanged would
have fallen into it -- silently dropping the drift that module exists to
converge. Both write arms are now explicit. live_deploy's EffectReplace is
structurally unreachable at both degenerate poles and emits a loud typed poison
per that module's discipline; its 44 byte-identity goldens pass unchanged.
Witnesses green by execution: membership_reconcile 10/10, change_realization
8/8, live_deploy 44/44, plus tool_readiness, repo_local_git_config,
workflow_reconcile, srv3, host_phase_status, roadmap_belt, host_axis_caps.
Corpus compile carries the same 10 pre-existing diagnostics as main, none mine.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ice). Introduce typed RunnerConnectivityAction with incarnation replace, canary-first fleet breaker, verified postcondition, and per-host reach refusal so wedged acquire-job slots plan repair without watchdog fanout. Co-authored-by: Cursor <cursoragent@cursor.com>
…ions webhook incident) The PR opened during the Actions backend incident and no workflow runs were created at all -- absent, not queued. ci.yml triggers on pull_request [opened, synchronize, reopened, ready_for_review], so this empty commit fires a synchronize to get the affected-set run executed against the branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Project RunnerIncarnationReplace into a four-step observe-replace-observe sequence with scaffold binds to still-ram-738's HostEffect variants; witnesses green for replace and noop paths. Co-authored-by: Cursor <cursoragent@cursor.com>
…ivate, verify Split from parked #7931 joint-solver PR per operator ruling (deep-badger-594): this lane owns HostEffect arms, runner_lifecycle ADD sequence, slot provision, disk observation, srv4 width-7 at allocation with apply-time disk preflight, and fleet observation producer scaffolding. Not included here: host_capacity_solve joint enumeration (stays on #7931). Judgement calls in this PR body: - runner_host_deploy / runner_slot_allocation: provisioning materialization target (runner_count=7, disk gate at apply). - fleet_shell_transport_observation, build_cache_endpoint_observation, host_swap_backing, session_residency shell gate: interim observation producers gated on transport; unsure → delivery PR. - host_converge_slice1: under-count is postcondition for provision ADD, not pre-refuse (count equality after RunnerSlotProvision). Local verification: claim_batch on runner_lifecycle, runner_slot_provision, runner_slot_allocation, host_allocation_conservation, runner_host_deploy witnesses (pull_request checks absent repo-wide since 2026-08-06T19:36:59Z). Co-authored-by: Cursor <cursoragent@cursor.com>
…lip) Parked off capacity-delivery critical path per operator ruling — NOT presented as progress toward gunbc apply / seven runners. Lifecycle, HostEffect arms, and provisioning live on session/still-ram-738-pr-b. This PR contains only host_capacity_solve + witness and the jobserver helper split needed for per-token pool sizing in the enumeration. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep producer-Unobserved as Unobserved with dated receipts as provenance only, not authoritative ReachRefused. Refuse fabricated Owned on observed slot dirs until systemd drop-in provenance lands (ownership_of Absent). Co-authored-by: Cursor <cursoragent@cursor.com>
Connects gunbc.apply mode=apply to runner_capacity_plan + disk preflight + ADD dispatch seam (depends on #7939 plan, #7946 effects). Witnesses: two additions not count-refusal, disk unobservable refuses (not width-5 fallback), replay no-op when observed satisfies request. Local claim_batch: 3/3 PASS on runner_capacity_realize_witness_test. Co-authored-by: Cursor <cursoragent@cursor.com>
Import hardware_thread_count_value so the tokens-cap refusal witness resolves; author srv3_non_compile_residency_observed as a scaffold producer so the dissolve DeclarationRef cites a live symbol; ground slice_unit via host_layout.gunbc_managed_compile_pool_slice_unit. Co-authored-by: Cursor <cursoragent@cursor.com>
Only SessionsObservedAbsent maps to CapacityEvidenceObserved; observed session presence caps at candidate-only with an explicit reason. Add srv1_session_present_live_capacity_is_candidate_only witness. Co-authored-by: Cursor <cursoragent@cursor.com>
Models the conjunction predicate (remote offline + broker silence + no worker + grace elapsed), evidence grades, re-read refusal, and derived 10-minute bound with discriminating witnesses wired into runner_connectivity_recovery. Co-authored-by: Cursor <cursoragent@cursor.com>
The floor's extdeps scope placement gate refused PR C: dag/extdeps/github/ actions_runner.dag landed as a new extdeps module enrolled in neither scope_carrier_paths nor the machinery exemption, and the frozen legacy manifest is not a landing state for anything added after the freeze. Subject is actions_runner_release_2_334_0 — the cited upstream release row, which is what GitHub actually publishes and what this module exists to pin. Appended to the carrier roster rather than re-sorted; re-sorting that list produced a pointless merge conflict on #7891 earlier today. carriers_declare_scope_on_disk, frontier_rosters_are_disjoint, roster_paths_resolve_on_disk and preflight_rows_counted green by execution. The other diagnostics in that run were the floor refusing to spend budget once batch 1 went red, not separate defects.
Add missing HostEffect match arms in fleet_converge_cli, fix lifecycle witness construction (no bare _ values), and model post-convergence width via converged-seven roster fixture so a second apply plans zero additions and succeeds without disk preflight when nothing remains to materialize. Co-authored-by: Cursor <cursoragent@cursor.com>
Add fleet plan builder with per-host replacement cap, five-step repair choreography (observe before mutate), SIGPIPE diagnostic-read refusal, and reobservation witnesses. Co-authored-by: Cursor <cursoragent@cursor.com>
'release' is a reserved word; using it as a match binder made runner_lifecycle_witness_test.dag unparseable, which killed regen and heal before they did any work and left ci reporting FloorUpstreamAlreadyRed. All three red jobs had this one cause. Underneath it, witness_runner_lifecycle_host_effects_declared constructed each HostEffect variant and matched it straight back. That establishes only that the constructor typechecks -- already the typechecker's guarantee -- and cannot go red on any behavioral defect. The compiler refused each single-arm match as non-exhaustive over the 31-variant coproduct; answering that with thirty '=> false' arms would make the tautology compile without making it a check. Deleted, with its now-dead imports. fleet_converge_cli already carries the claim by execution: it matches HostEffect exhaustively and fails to compile if an arm goes missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ReplaceRunnerIncarnation now carries LocalRunnerSlotIncarnation plus RunnerReplacementCause so repair plans can refuse stale incarnations and name why replacement fired; witness binding renamed from release to cited to avoid the reserved keyword that broke regen. Co-authored-by: Cursor <cursoragent@cursor.com>
…se shape. Auto-heal correctly removed witness_runner_lifecycle_host_effects_declared (parse error + no behavioral oracle). ReplaceRunnerIncarnation grounding on LocalRunnerSlotIncarnation and RunnerReplacementCause remains in host_effect. Co-authored-by: Cursor <cursoragent@cursor.com>
Add runner_lifecycle_realize_wet_transport_dissolve_on (srv3/srv4 SSH reach + HostEffectTransport) and cite it from every NotConverged arm; update runner_capacity_realize authority note to state apply does not provision until the scaffold retires. Co-authored-by: Cursor <cursoragent@cursor.com>
Move LocalRunnerSlotIncarnation to gunbc.runner_incarnation, add ReplaceRunnerIncarnation seam witnesses, and model in-band ADD admission (LocalShell + derived execution target; Step E void). Capture operator constraints: workflow-only application, srv1 row-6 control, unit/process width authority, imperative caps, and ctrl installer read-before-realize. Co-authored-by: Cursor <cursoragent@cursor.com>
srv1 probe shows complete dormant install trees without .runner until JIT start. Add three-state installation carrier and witnesses; correct width notes. srv3/srv4 slot-06/07 state still unobserved from this session. Co-authored-by: Cursor <cursoragent@cursor.com>
Collapse materialized-never-activated and materialized-previously-activated into SlotMaterializedNotActive; unit_active drives readiness. Record srv3 06/07/08 probe, srv3 reach via srv2 jump, and width-8 vs intent-7 ceiling. Co-authored-by: Cursor <cursoragent@cursor.com>
RunnerSlotInstallationObservation separates observed states from Unobserved/ReachRefused so srv4 never defaults to SlotAbsent. Pin srv3 01-08 mapping from sibling probe; witnesses enforce srv4 blocks add without extract routing. Co-authored-by: Cursor <cursoragent@cursor.com>
…rows. Restore srv3 shell transport session receipt for producer-unobserved authority, pin incident desired_width at 22, pass roster into connectivity repair planning, and enroll connectivity verdict predicates in the non-fold-residue roster. Co-authored-by: Cursor <cursoragent@cursor.com>
…nt width. Wire vivid-eagle srv3 shell transport as producer-observed success while srv4 stays unobserved with dated receipt provenance; derive incident desired_width=22 from srv4's five-slot outage pin instead of a naked literal. Co-authored-by: Cursor <cursoragent@cursor.com>
…jection. Introduces medium-neutral CiExecutionPlan carriers from ci_spec (not ci.yml), a poll-first ci_control_plane daemon with durable queue and lease reclaim, GitHub Checks create/update, and /ci serve routes for run receipts. Co-authored-by: Cursor <cursoragent@cursor.com>
…old marker. Load repo/stages/floor plan from gunbc.owned_ci_seed via eval; persist ledger before check create; mark CheckPublicationPending on API failure without duplicate enqueue; document seed REST transport as dissolve-on scaffold. Co-authored-by: Cursor <cursoragent@cursor.com>
…nesty. Ground lease duration on std.measure.Second and queue expiry on NumericDate; load state root and lease seconds from gunbc.owned_ci_seed in the Rust bin; fix unpublished-completed conclusion mapping and UpdateRun wire encoding; dissolve ci_subject_is_fork_refused Bool predicate into direct coproduct match. Co-authored-by: Cursor <cursoragent@cursor.com>
Drop dead failed/completed ternary on queue move (always completed dir); remove tautological Rust unit tests — decision procedure stays in .dag witnesses. Co-authored-by: Cursor <cursoragent@cursor.com>
Propagate system-clock errors from now_unix instead of fabricating 0; persist fork PR refusals to index/run ledger so the /ci UI can observe them. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace Bool lease expiry with typed reclaim/validity decisions that carry LeaseClockRefused for fractional NumericDate arms; witness the refusal. Co-authored-by: Cursor <cursoragent@cursor.com>
…amilies. NFR rows would stale the roster — these helpers are exhaustive matches without top-level wildcard arms (unlike connectivity_verdict_is_*). Document predicate-dissolution at authoring via explicit Terminal disposition rows. Co-authored-by: Cursor <cursoragent@cursor.com>
…ega-runner-capacity
… omega-runner-capacity
…ega-runner-capacity
…a-runner-capacity
…ga-runner-capacity
Three conflicts, all resolved additively — no side's facts dropped: - host_effect.dag: both import sets kept (runner-incarnation carriers from this lane, CandidateRelease from main). - non_fold_residue.dag: both frontier roster rows kept; the two lanes appended independent subjects to one list. - ci_deploy_target_host_witness_test.dag: took main's side. Its rename deploy_runner_labels_contain -> deploy_runner_label_list_contains repairs a real homonym collision against gunbc.design.component's byte-identical declaration; this branch carried only the older colliding name and no other content in that file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two conflicts:
- extdeps_scope_frontier.dag: additive roster on both sides, union kept
(actions_runner.dag from this lane; claude_sdk.dag + codex_app_server.dag
from main). Neither side's carriers dropped.
- DESIGN.md: the generated-artifact driver refused, correctly — both sides
changed this projection since the merge base. The regenerator could not be
run to resolve it: `generated_artifact_gate main_wet` was OOM-killed at
"resolved 605 sources" on three attempts, twice locally and once through
ctrl-build --remote. The kill is not this session's cgroup cap
(memory.events.local `max 0`, `oom 0`; only `oom_kill` incremented, which
counts processes that died, not the cap that decided).
Resolved structurally instead of by picking a side, and the structure is
checkable: base, ours and theirs have identical line counts; ours changed
exactly line 148 and theirs exactly line 152, disjoint. The authority
(design_document.dag) auto-merged with BOTH edits. Each side's line was
then verified to appear verbatim in the merged authority's li(text:) rows
under the source escapes (\{ and \"), so the union of the two disjoint line
replacements IS the projection of the merged authority, not a chosen side.
This is asserted from structure, not from an executed regeneration. The
drift gate in CI is the independent check and has not yet run.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The type is referenced twice in this module and was resolving only by pool coincidence — the Class B binding failure the corpus already tracks. Picked up from session/still-ram-738-pr-c commit 5df7f02, which fixed the same review finding on the now-superseded branch. That commit's other half — a stray brace in non_fold_residue_frontier — does not apply here: it came from that branch's own conflict resolution, and this branch's roster resolution did not produce one (checked, the list closes clean). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…urface. CI ci job red: 'Refused' not found in module 'gunbc.membership_reconcile' (imported by 'gunbc.runner_slot_provision'), 3 occurrences. A genuine fold defect, not a flake and not memory (floor peak 9.85 GB against memory.max 17179869184 = 57%, so the cap was not reached). CAUSE: runner_slot_provision came from #7947 and was written against the pre-rework membership_reconcile surface (MemberUpsert / MemberTeardown / MemberTeardownRefused / membership_upsert_count). The fold also brought in #7938's MemberChanged{from,to} rework of that module, which splits the old fused upsert into distinct MemberAdded and MemberChanged arms. Neither PR was wrong alone; consolidating them created the mismatch. NOT A MECHANICAL RENAME. The old MemberUpsert fused add and change, and the operator's Decision 1 split them deliberately, so each site is a decision: - MemberAdded -> emit the slot extract script. This is the add path. - MemberChanged -> []. Decision 2 says apply may execute RunnerSlotAdd only and must refuse Change/Remove/IncarnationReplace; emitting an extract script for a changed member would materialize a change the apply path is required to refuse. - MemberRemoved / MemberRemovalRefused -> [], unchanged in meaning. - membership_upsert_count -> membership_added_count, NOT the derived membership_write_count (= adds + changes). The consumer is runner_slot_provision_has_width_increase: a width INCREASE is adds; counting changes would overcount. membership_write_count exists for consumers that want both, and this is not one. The witness carried the same stale vocabulary and is migrated with it; its assertion is preserved exactly (7 desired - 2 observed = 5, and the 2 observed match desired so they are Unchanged, not Changed). VERIFICATION, stated at its real strength. A local single-entry run does NOT verify this: a stashed-fix control returns the IDENTICAL 2000 errors and zero 'Refused' reports on the pre-fix tree, so that instrument never surfaces this defect class -- it dies at parse before resolution, and 2000 is a truncation cap rather than a count. Verified instead at symbol grain: all 7 symbols imported from membership_reconcile resolve to declarations, with a positive control confirming the query reports the two removed names as MISSING. CI's ci job is the instrument that found this and is the one that settles it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
REQUEST_CHANGES verified against current code rather than taken on trust, and the finding is correct: gunbc.owned_ci check_publication_reports_github_success and check_publication_is_pending_honest are coproduct is_*/reports_* predicates carrying no disposition, while this same diff already dispositions two sibling families — extdeps.github.ci_runner github_runner_registration_predicate_family_disposition (review 50232) and gunbc.runner_incarnation runner_slot_installation_predicate_family_disposition. Inconsistent within one PR is the reviewer's point and it stands. Adds check_publication_predicate_family_disposition = Terminal, matching the runner_incarnation precedent's shape and reason. TOTALITY CHECKED, NOT ASSERTED. The row claims both matches are total, so that claim is measured: CheckPublicationState has six variants (NotStarted, Queued, InProgress, Completed, Pending, Failed) and both fns carry an explicit arm for all six with zero top-level wildcard arms. Positive control: the same query reports a fictitious variant as missing, so an all-present result is a real negative rather than a blind read. (First pass counted the type name itself as a seventh variant and reported a false miss — the query was wrong, the code was not.) Terminal rather than NFR enrollment is the right arm for the same reason the precedent gives: these dissolve at authoring, so an NFR row would stale the roster. fleet_runner_connectivity connectivity_verdict_is_* is the contrasting case — wildcard false arms, correctly enrolled in non_fold_residue_frontier. Scope checked: exactly two Bool fns in gunbc.owned_ci match over a coproduct, and both are fixed. owned_ci_run_id_char_is_digit / _is_hex take String, not a coproduct. check_conclusion_is_success lives in extdeps.github.checks, outside this diff. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ogy authority. OPERATOR DIAGNOSIS, and it corrects mine. I had read the double count as a property of the current topology and concluded the arithmetic had merely drifted under a stable defect. Wrong on the load-bearing point: main ALREADY carries the correct rule, and #7931 reintroduced the defect locally. THE DEFECT IS A DUAL REPRESENTATION OF ONE SEMANTIC FACT — where compile RSS lives in the host's resource topology. Representation 1, the authority (gunbc.fleet_host_budget): CompilePoolInRunnerSlots => CompilePoolDerived { bytes: byte_size(0) } CompilePoolSliceDeclared => resolve_compile_pool(...) Compile memory is CONTAINED in runner-slot accounting under the current topology, so it is not a second claim on host RAM. Representation 2, the parked solver (gunbc.host_capacity_solve): per_slot_runner_pool_charge(CompilePoolInRunnerSlots) = full MemoryMax compile_pool = jobserver_build_pool_bytes_for_tokens(...) [EVERY placement] host_allocation_conserves(runner_pool: .., compile_pool: .., ..) Two additive SIBLING charges. The placement argument steers the runner-side charge but never gates whether the compile charge is added at all. A containment relation (compile RSS subset-of runner-slot RSS) flattened into a partition of disjoint siblings. The solver imports the placement and then reimplements its accounting meaning, which makes the solver a second authority over a fact fleet_host_budget already owns. WHY THE WITNESS FAILED NOW. joint_solve_double_counted_topology_refuses_seven_slots_at_derived_tokens asserts best.runner_slots < 7 — a NUMERIC CONSEQUENCE, not the invariant its name claims. At 16GiB slots, 7 x 16 = 112GiB against 125GiB usable, so the doubled charge pushed 7 over and the witness passed. At 14GiB (#7891's measured ruling, already on main) 7 x 14 = 98GiB leaves ~27GiB, so the same broken model now fits. The modeling error is unchanged; only its numerical shadow moved. Flipping the assertion to >= 7 would have been a tree-copied measurement — a change detector, which DESIGN section 5 forbids as an oracle. WHY REMOVAL RATHER THAN REPAIR. #7931 is parked, non-delivery content, and main's capacity authority already carries the correct placement-dependent decomposition, so deleting the fork restores single authority with no capability lost. Repairing in place would mean routing candidate accounting through one placement-aware charge and replacing the numeric witness with structural placement/charge controls — real work that belongs to the capacity lane, not to a consolidation. REVERTED TO MAIN, all four paths #7931's merge touched: D dag/gunbc/host_capacity_solve.dag (absent on main) D dag/test/claim/host_capacity_solve_witness_test.dag (absent on main) M dag/extdeps/jobserver.dag -> main (the _for_tokens split served only the solver) M dag/gunbc/host_layout.dag -> main (gunbc_managed_compile_pool_slice_unit had exactly one consumer, the solver; keeping it would strand an unconsumed carrier) Checked: zero dangling references to host_capacity_solve, jobserver_build_pool_bytes_for_tokens, or gunbc_managed_compile_pool_slice_unit remain in the corpus, and per_slot_runner_pool_charge is gone entirely. NOT CONFLATED WITH THIS: the live jobserver admits 128 tokens where the declared formula derives 62. That is an over-admission pointing the opposite way (too permissive) from the double count (too conservative). Untouched here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re: review 50446 (REQUEST_CHANGES) — verified against the current tree, and not fixing, because the finding's premise does not hold. Detail below so it is checkable rather than asserted. Both files are pre-existing on main, not added by this PR. The review calls each a "New Both are already enrolled — as rows of the frozen legacy manifest.
So they occupy the third permitted state. There is no gap. The placement gate will not refuse them. Per the law, The genuinely new file was handled exactly as the review asks. Why I am not making the change anyway. Adding Happy to be shown wrong if the gate reds on either path — that would be the instrument disagreeing with this reading, and I would take the instrument. — sent from deep-badger-594 |
* Delete the owned-CI control plane at the root The control plane was built once (#8016), never deployed, and never ran: it is in no release-bin roster, no systemd unit, no converge membership, and no .gunbc state exists anywhere. Its only live surface was a /ci route that answered a permanent 503 by construction. It therefore holds no boundary, which makes this the cleanest form of the DESIGN 3 delete-first cut: nothing depended on it, so nothing regresses. What it was: 1754 lines of hand-written Rust implementing semantics the substrate already models -- a poll loop, a filesystem queue, a lease, HTTP to GitHub, and JSON state -- under a declared scaffold whose three dissolve-on items were all still open. Per DESIGN 7 the seed shrinks toward zero, and this was the seed growing instead. Two forks die with it. QueueLease was a nickname for std.temporal_effect HeldLease, which already carries lease_key, resource_fingerprint, owner_fingerprint, generation, and a five-armed observed state, and whose decision_for_held_lease_verdict already yields stale-lease reclaim and foreign-holder refusal. CiExecutionSubject fused demand and work into one identity, so a retry had nowhere to live. Deleted whole rather than migrated, per the standing rule that a replacement cuts at the root: both Rust files and the bin registration, gunbc.owned_ci, owned_ci_seed (which existed only to feed the Rust seed), owned_ci_serve, owned_ci_page, gunbc.ci_execution_plan, the witness module, and the design doc whose sequencing was the old shape's gravity. Git history keeps all of it as quarry. The witnesses are retired rather than re-enrolled, with a receipt: their subject is the fused subject/run model, and evidence whose only subject is a rejected shape must not be left standing (DESIGN 4b). The lease obligations they covered are already witnessed against HeldLease in temporal_effect_spine_witness_test. The generated crate-layout artifacts are edited mechanically here rather than regenerated locally; the drift gate is the oracle for them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GJgwfCsHvvRLD5EAErgP7F * Drop the /ci route assertions from the roadmap_serve witness review 52992 (cursor): roadmap_serve_witness_test still imported CiRunsPageHandler, CiRunDetailPageHandler and CiRunsJsonHandler and asserted that /ci, /ci/runs.json and /ci/run/{run_id} select them. Those variants, routes and dispatch arms are deleted by this cut, so the enrolled witness would not resolve against the updated module. Correct and confirmed by reading the file; fixed rather than argued. Why the first sweep missed it: the residual grep searched for the deleted MODULE names (owned_ci, ci_execution_plan, ci_control_plane). These three symbols contain none of those strings -- they are symbols removed from a SURVIVING module. A deletion has two reference surfaces, not one, and only the first was swept. The re-sweep covers both: every symbol removed from a surviving module, every exported symbol of each deleted module, and the route literals. All clean across dag/, src/ and .github/. No route-count assertion exists that the three removals would falsify. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GJgwfCsHvvRLD5EAErgP7F --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… not the emission (#8476) * Delete the owned-CI control plane at the root The control plane was built once (#8016), never deployed, and never ran: it is in no release-bin roster, no systemd unit, no converge membership, and no .gunbc state exists anywhere. Its only live surface was a /ci route that answered a permanent 503 by construction. It therefore holds no boundary, which makes this the cleanest form of the DESIGN 3 delete-first cut: nothing depended on it, so nothing regresses. What it was: 1754 lines of hand-written Rust implementing semantics the substrate already models -- a poll loop, a filesystem queue, a lease, HTTP to GitHub, and JSON state -- under a declared scaffold whose three dissolve-on items were all still open. Per DESIGN 7 the seed shrinks toward zero, and this was the seed growing instead. Two forks die with it. QueueLease was a nickname for std.temporal_effect HeldLease, which already carries lease_key, resource_fingerprint, owner_fingerprint, generation, and a five-armed observed state, and whose decision_for_held_lease_verdict already yields stale-lease reclaim and foreign-holder refusal. CiExecutionSubject fused demand and work into one identity, so a retry had nowhere to live. Deleted whole rather than migrated, per the standing rule that a replacement cuts at the root: both Rust files and the bin registration, gunbc.owned_ci, owned_ci_seed (which existed only to feed the Rust seed), owned_ci_serve, owned_ci_page, gunbc.ci_execution_plan, the witness module, and the design doc whose sequencing was the old shape's gravity. Git history keeps all of it as quarry. The witnesses are retired rather than re-enrolled, with a receipt: their subject is the fused subject/run model, and evidence whose only subject is a rejected shape must not be left standing (DESIGN 4b). The lease obligations they covered are already witnessed against HeldLease in temporal_effect_spine_witness_test. The generated crate-layout artifacts are edited mechanically here rather than regenerated locally; the drift gate is the oracle for them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GJgwfCsHvvRLD5EAErgP7F * Drop the /ci route assertions from the roadmap_serve witness review 52992 (cursor): roadmap_serve_witness_test still imported CiRunsPageHandler, CiRunDetailPageHandler and CiRunsJsonHandler and asserted that /ci, /ci/runs.json and /ci/run/{run_id} select them. Those variants, routes and dispatch arms are deleted by this cut, so the enrolled witness would not resolve against the updated module. Correct and confirmed by reading the file; fixed rather than argued. Why the first sweep missed it: the residual grep searched for the deleted MODULE names (owned_ci, ci_execution_plan, ci_control_plane). These three symbols contain none of those strings -- they are symbols removed from a SURVIVING module. A deletion has two reference surfaces, not one, and only the first was swept. The re-sweep covers both: every symbol removed from a surviving module, every exported symbol of each deleted module, and the route literals. All clean across dag/, src/ and .github/. No route-count assertion exists that the three removals would falsify. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GJgwfCsHvvRLD5EAErgP7F * DESIGN.md is a first-principles doc: cut it 68%, and catalogue the patterns that would have caught the forks Open threads had become the parallel ledger §6 forbids: 15,336 words across 40 rows, 53% of the file, against ~6,800 words for the reasoning the document exists for. The file had already diagnosed this once, in one row -- the five-minute-CI-gate paragraph records its own six-step copy going stale after the roadmap authority was recut. This generalizes that fix. Deleted (operator ruling, overriding the enumerate-before-deleting rule): the whole Open threads section. Four lanes went outright -- SCM economics, gunb.ai site subsumption, srvN build-cache, srv4 subsumption -- each verified first against the test that matters: every module it named resolves and its plan doc exists, so the row was a summary of live carriers and removing it loses nothing. Re-homed the nine rows that had no plan doc, bodies verbatim with provenance: cross-platform-instrument-motion, witness-cost-derives-from-purpose, secret-version-lifecycle, determinism-boundary-relative, disk-tier-repeat-resolve-closeout, content-hash-family-grounding, and parked-questions for the three too small to warrant a document. Extracted two doctrines that were principle-shaped only from a distance: replacement-migration (4,405w, 77% of §3 and 31% of the whole file) and scaffold-admission (792w from §5). Each leaves a statement of the principle and a link; the procedure, carve-outs, disposition census, terminal receipt and dated receipts live in the doc. §3 is 5,729 -> 1,257, §5 2,344 -> 1,755. Added "The recurring patterns": realization, materialization, leasing and fencing, reconcile, allocation, authorization, identity and keying, evidence and claims, observation-to-verdict, dissolution. Each carries its authority and a fork test, because that is the part that does work -- a census of one lane found eleven forked carriers, and every one was introduced by an author who did not know the pattern already had an owner. "If you are writing a record with a generation in it, you are re-declaring leasing" would have caught LeaseIdentity before it dropped owner_fingerprint and left the receipt fence with no owner to compare. Also lands three new design notes from the fabric/CI-minutes work: fabric-concept-reconciliation (the authority census), ci-minutes-product-design, floor-semantic-artifact-design. 29,084 -> 9,340 words. No section over 1,800. Three links, all resolving. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012q31BK3okLA8vG4kdTWtBf * Revert the DESIGN.md hand-edit: it is a generated artifact, and I edited the emission instead of the model DESIGN.md carries `merge=generated-artifact` in .gitattributes and is emitted from dag/gunbc/design_document.dag via expected_design_md, consumed by gunbc.generated_artifact_emit. The previous commit hand-edited the emitted file, which is out-of-band actuation -- hand-applying an actuator with a commit wrapped around it -- and left live model/emission drift: the model still carried every Open threads row the emission had lost, so the next regen would have silently reverted the whole cut. Caught by checking .gitattributes before flipping the PR to ready. It should have been the first check, not the last. This restores DESIGN.md to the model's current output. The eleven new docs/plans/*.md files are unaffected -- they are hand-authored and were never generated -- so the re-homed lanes and the two extracted doctrines stand. The cut itself is re-applied in dag/gunbc/design_document.dag, where it belongs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012q31BK3okLA8vG4kdTWtBf * DESIGN.md: cut to first principles, at the model rather than the emission Operator ruling: DESIGN.md is a first-principles document; per-lane status in it is a dual representation. 27,516 -> 9,279 words. Every edit is to dag/gunbc/design_document.dag; DESIGN.md is regenerated from it, so the committed bytes are a fixed point of the model rather than a hand-patched file that happens to match. Deleted: the Open threads section, 37 per-lane status rows. Ten lanes that named no design document were re-homed to docs/plans/ first (the other 27 already cited one), so nothing was dropped without a home. Compressed to principle, with the operative detail moved out rather than deleted: the section 3 replacement-migration rule (why leaf-upward editing creates authority before removing any; the attractor and its A3 grounding; delete-first with the deletion as the census; the two carve-outs; what "atomic" means) now cites docs/plans/replacement-migration-doctrine.md for the loop, the disposition census, the cut search and the receipts. The section 5 scaffold ruling keeps the rule -- a dissolution condition is a lifecycle fact, not a permit; the default landing state is the final construction -- and cites docs/plans/scaffold-admission-doctrine.md for the verdict vocabulary and the out-of-band-actuation case. Section 3's opening paragraph keeps interface/realization/policy as three facts and drops the worked extdeps detail. Four documentary citations retired with the paragraph that cited them (three body-lowering refs, the five-minute-CI-gate ref); their DeclarationRef declarations survive in doc_graph_roots where other consumers use them. Evidence, all green by execution on this tree: - documentary_refs_generated_document_renders_the_rows: true - documentary_refs_population_is_the_union: true - documentary_refs_renamed_system_refuses: true - documentary_refs_ambiguous_system_refuses: true - doc_graph_bind_identities_unique / works_refs_carry_symbols / production_doc_binds_all_carry_a_retirement / hand_authored_slugs_not_registered: true - compile-clean gate (3 roots, primary-precedence): 0 blocking errors The two perturbation controls were RED for one edit before this landed: their specimen was a body-lowering symbol the document no longer cites, so they were retargeted onto the surviving citation. That red is the receipt that they still discriminate. Orphan wall: the ten re-homed documents are registered as HandAuthoredDocBind rows, each naming a verified carrier symbol and a retirement condition. That moves doc_graph_orphan_count 16 -> 4. The residual 4 orphans and all 5 dangling links predate this branch (docs/plans/ci-selection-vs-scheduling.md is deleted but still linked from ROADMAP.md and four plans); not fixed here, and reported rather than absorbed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012q31BK3okLA8vG4kdTWtBf --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Consolidation of the deep-badger-594 runner-capacity lane into one PR, per operator request.
What merged cleanly (5 constituents)
session/jolly-swift-846ci=successsession/still-ram-738-pr-cci=successsession/vivid-otter-718ci=successsession/still-ram-738ci=failure(own witness)session/quick-bear-899ci=failure(known flake)Branched from
origin/mainat08887c6e913and merged each constituent (merge commits, no rebase, no cherry-pick). 91 files, +10582/-220. No conflict markers in the tree.Cost paid to build this, stated plainly: #7938, #7940 and #7947 were each 2/2 with
ci=successon frozen heads at the moment of folding. This PR starts at 0/2 and needs a fresh CI round. That was an accepted trade to get a single artifact to reason about.What did NOT merge — #7939, and this is the remaining work
#7939(session/vivid-eagle-131) conflicts on 9 files, of which 5 areadd/add:An
add/addconflict means two lanes independently authored the same carrier. That is the §3 dual-representation violation, and resolving it is a modeling decision — pick the single authority and delete the fork — not a textual merge. Taking either side by convenience would land two representations of runner capacity in one tree, which is the exact failure the design doc says gets consolidated later at higher cost.So the residual work in this lane is one question, not nine: which lane owns
runner_capacity_plan,fleet_runner_connectivity, andapply?What this PR does NOT do
runner_lifecycle_realize_*arms returnNotConvergedas declared scaffolds with a named dissolution trigger (runner_lifecycle_realize_wet_transport_dissolve_on). The fleet stays at 20 runners.disabled+inactive, and a stale.runneris harmless (its mtime tracks unitActiveEnterTimestampto the second, so it is rewritten every incarnation).Known reds among constituents
joint_solve_double_counted_topology_refuses_seven_slots_at_derived_tokens, a witness in its own diff. Genuinely its own red, superseded by nothing.cross_module_qualified_reference_emits_call_from_correct_modulekilled at 5446ms against a 5000ms budget, 1 of 7594 witnesses. The fleet-wide contended witness, not attributable to this diff.Superseded and already closed: #7946 (contained in #7947, verified by path comparison), #7930 (control law rejected as circular).
— sent from deep-badger-594