Repository navigation
probe 2: two contributor commits - #7
Merged
Merged
Conversation
quad341
pushed a commit
that referenced
this pull request
Oct 3, 2026
…unwired) (gastownhall#6970) ## Summary Reconciler v2, slice P3-3: the allocator's per-pass inputs, read in memory. Built for P3-5a (decide), P3-4 (ledger clearing) and P3-7 (wiring), and **not wired into the runtime**. Nothing outside tests constructs the new code. Legacy behavior is unchanged: the legacy edits are pure extractions (listed below), and their callers pass the same values they did before. ## Census (`allocator_census.go`, I2) **Legs.** The census covers every open session row on every leg of `sessionCensusStoreCandidates`, with the sessions leg first. It reads only indexes (AM6): - **Exact leg** (the SQLite binding): read from its `CachingStore` through the session front door, which overlays dirty rows. - **Recording leg** (bd, native Dolt, Postgres): served from the P3-2 backstop lane's recording of legacy's own live `ListAll` (`[]session.Info` with `At` and `Err`). A pass never touches a non-exact store. - P3-2 is being built in parallel, so the census takes a two-function seam (`censusLegFeed`): one function classifies the leg, the other returns the recording, keyed by store. **Last-good bounds and incomplete or stale legs.** - A failed read serves the leg's last good rows whole, within a bound: 60s for an exact leg, 2 × patrol for a recording. Past the bound the leg is **stale**: its rows Keep, and the census is incomplete. - A stale leg, or one with nothing to serve, leaves the census **incomplete**. That blocks every fresh create, as legacy does (POOL-047; owner decision 2026-10-03). - A partial read keeps its rows, on the sessions leg too. The pass fails only on a hard sessions-leg error with nothing to serve, or when there are no legs at all. **Fold and duplicates.** - Rows are keyed `(leg, bead ID)`, never by name, so rows that share an enterprise slot-scoped name are one row each (F8). - The fold keeps legacy's first-leg-wins rule by bead ID. A later copy is a duplicate (C2.11): it stays in `Rows`, the unfolded census the ledger reads, but it is not a canonical row and not a sharer of its name. - Each row carries the facts `ledgerRow` reads, under the same names: `Incarnation`, `InstanceToken`, `StartLease` (START-043, including the claim-or-creating condition via `pendingCreateStartInFlightInfo`) and `PendingCreate`. These are set on the canonical copy only. - `Ledger(cfg)` is the `ledgerCensus` adapter. It returns every row on every leg with its `endpointKeyForAgent` endpoint, resolved from the normalized template, and `Legs: CompleteLegs()`. - Rows in states main does not know are flagged and counted per template (F9), and keep their slots. **Indexes.** - Canonical rows by runtime session name. - Pool identity leases over every copy on every leg. These are deduped by `(ID, session_name, alias, agent_name)`, the same key as the create effect's locked check (`freshPoolAvailabilityInfos`), so plan time and effect time agree. - `IdentityLeaseHolder` answers the snapshot leg of `ensurePoolIdentityNotHeldByOpenRow` in O(1). ## Observation adapter (`allocator_observe.go`, I3, AM3) Liveness states: - **alive**: listed and fresh, its pane and process are not known dead, and the runtime is attributed to this row or its name is unique. - **occupied**: another bead owns the name, whether that runtime is alive or dead. - **dead**: listed and fresh, but `Running` or `ProcessAlive` is a fresh No (tmux remain-on-exit keeps exited panes listed), attributed to this row or its name is unique. A dead row is not uncertain. Like absent, it is a start candidate, and the start path recycles the pane. It is not alive for dependencies (BEHAVIORS #7). - **absent**: listed No by a complete, attested pass. - **absent-unconfirmed**: not listed by a fresh pass on which every backend was complete or unattested. - **unknown**: anything else, including a shared name whose runtime has no known owner or carries no owner. An unknown row is uncertain. "Present" means a fresh Listed Yes, or listed by the latest fresh pass on a backend that did not fail, even if that backend never primes (exec, ssh, herdr, t3bridge, or a partial listing). Attach and pending: - Unsupported attach reads as not attached. A stale or unprimed attach on a backend that reports attach makes an alive row uncertain. - Pending is an input only as a fresh Yes on an alive row, because legacy probes pending only on live targets. - A dead row reports neither attach nor pending. ## Readers (`allocator_health.go`) - **Provider health (I7) and suspension (I9)** are memoized on `(mtime, size)`: one stat per pass. A reader reloads while its last load is within the filesystem's mtime granularity, so a same-size rewrite within one tick is still seen. - **Provider health** is parsed once per change and aged at the pass clock. - **Startup-health episodes** come from the sessions leg's cache: through the dirty-row overlay on an exact leg, strictly from memory on any other leg, and from the last good read for up to 60s. They are resolved as `LoadStartupHealthEpisode` resolves them: newest created wins, ties go to the largest ID. ## scale_check lane (`allocator_scalecheck_lane.go`, I5) - **Cadence.** A paced lane on the patrol cadence. The first pass runs at start, and each pass runs under the host's `safeTick` (`v2-scale-check`). - **Work.** Each pass runs every enabled custom scale_check pool through `evaluatePendingPools`. The allocator is woken only when the counts or the partial set change. - **Partial results.** A pool whose probe env cannot be built is marked partial, not skipped (BEHAVIORS gastownhall#38). A missing or stale result also reads as partial. - **City suspended** (`Workspace.Suspended`, the suspension file, or `GC_SUSPENDED=1`): a pass runs nothing and publishes nothing. Legacy's demand pass returns before any scale_check in this case (`TestBuildDesiredState_ProductionDemandSkipsAllScaleChecksWhenCitySuspended`). - The lane reads suspension through its own memoized I9 reader, and derives suspended rigs from that same state. - A skipped pass does not count toward the duty cycle (`startGatedPacedLane`), so a wake after resume runs at once. - A pass that panics does count, so wakes cannot rerun it back to back. - **Parity with legacy.** `TestScaleCheckLaneWorkMatchesBuildDemandTargets` compares the lane's work element by element against legacy's `pendingPools`: agent index, scale params including the expanded check, pool dir, probe env, and the new-demand flag. The env failures must be exactly the pools legacy silently skips. Fixtures: - P3-1's randomized cities; - `build_desired_state_test.go`'s scale_check fixtures; - a suspended rig, and a rig outside the city dir; - same-named agents in two rigs, where only one backs a named session. ## Legacy refactors (byte-identical behavior) - `evaluatePendingPools` takes the runner, and `evaluatePendingPoolsMapWith` exposes it; `evaluatePendingPoolsMap` passes `shellScaleCheck` as before. - `buildDemandTargets` takes the probe-env builder (`probeEnvFunc`); legacy passes `controllerQueryRuntimeEnv`. `TestBuildDemandTargetsGoldenAgainstInlineLoop` still pins it to the pre-refactor loop. - `loadProviderHealthSnapshot` is split into `parseProviderHealthFile` and `snapshotAt(now)`. - `ensurePoolIdentityNotHeldByOpenRow`'s predicate is extracted into `poolIdentityLeaseOf` and `poolIdentityLeaseTemplateMatches`. Legacy and the census call the same functions. - `buildSuspendedRigPathsForCity` delegates to `suspendedRigPathsWithState(cfg, st)`. - `TestV2RuntimeDoesNotReferenceCityRuntime` now also covers the four new files. ## Tests and mutations New tests cover every row of the spec's P3-3 table, plus these added at re-review: - the lane skipping passes while the city is suspended (all three sources, then a pass after resume); - suspended rigs read from the pass's suspension state; - a skipped pass not pacing the next wake; - a wake after a panicking pass being paced; - a duplicate copy not counting as a sharer; - the lease dedupe key fields; - endpoint resolution through the normalized template. I re-ran the reviewer's mutants against the final tree, together with five new ones for the suspension gate. R-C5 is gone because its code was deleted (`ListAll` never returns closed rows). Of the 30 mutants, 25 are killed and 5 survive, all from the original review and none targeted: - R-O9, R-C3, R-H1 and R-S3 move a boundary or change last-good serving; - P-4 (empty query topology) is equivalent for custom-check pools. Local gates: - `gofmt`, `go vet ./cmd/gc`, and `go build -o /dev/null ./...`; - the slice tests with `-race -count=20`; - the cmd/gc fast suite (`GC_FAST_UNIT=1`); - `./internal/testpolicy/...` and `./scripts/...`; - golangci-lint 2.12.0 `--new-from-rev=<merge base> --whole-files ./cmd/gc`: 0 issues; - gazelle diff: none; - the pre-commit and pre-push hooks. ## Obligations deferred (recorded in the P3 spec, "Obligations from P3-3", §4.4 and §4.11) **P3-5a** - Ask `IdentityLeaseHolder` with the template-defaulted identity, and only for bead-scoped identities. - Read liveness through `alive` and `startCandidate`. - Read POOL-052's singleton occupancy from the observation cache by the planned runtime name, including unowned runtimes, with unknown counting as occupied. A corpse frees the name, but a zombie holds it, because legacy's `IsRunning` reads a zombie as running. - Ask `scaleCheckResult.partial` only for custom-check templates. - Either grant dead non-named rows a start (the interim divergence below) or classify them `None(dead-runtime)`. **P3-7** - Make the host's sessions leg `legs[0]`. - Re-pace the lane's patrol and the census `recordingMaxAge` on reload. - Pass the leg classification to `episodeReader.read`, and give the lane the host's `safeTick`. - Wake the scale_check lane on resume. **P4.1** - Keep the dead-pane recycle in the start path. **P4.4 and P4.1** - Legacy closes non-named dead rows as `dead-runtime` before demand (MAINT-031) and releases their work. MAINT-031 is off under v2 until P4.4, so in the interim a dead row is granted a start in place. Once MAINT-031 runs under v2, its close must win over a granted start. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
quad341
pushed a commit
that referenced
this pull request
Oct 11, 2026
…stale apt index) (gastownhall#7554) ## Summary **This fixes the fork pool outage.** Since about 20:05Z on 2026-10-10, every fork pool VM has failed setup with `apt-get install` exit 100. The image's apt index names `libxml2 2.9.14+dfsg-1.3ubuntu3.9`, which the Blacksmith mirror now 404s, so fork lanes have had no workers (114 actions queued). This bumps `gastownhall/rbe-worker` from `421eb59c` to `3bfd8aea`: - #6 refreshes the apt index once and retries the toolset install, before the worker-env measurement (which measures upstream major.minor only). - #5 (S4b) and its revert #7 cancel out, so S4b doesn't ship in this bump. ## Test plan - [x] rbe-worker `product-check` at `3bfd8aea` against this tree: ok - [x] `go test ./scripts/ -run 'RBE|Worker|Pool'` - [ ] After merge: fork pool runs succeed, and fork queued drains on core 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Throwaway attribution probe for mpr cherry-pick design (gm-ubcxn). No workflows in base; nothing to review.