Skip to content

Merge upstream/main into fork — v1.4.0 resync (352 commits) - #109

Merged
bourgois merged 355 commits into
mainfrom
resync/upstream-20260726
Jul 27, 2026
Merged

Merge upstream/main into fork — v1.4.0 resync (352 commits)#109
bourgois merged 355 commits into
mainfrom
resync/upstream-20260726

Conversation

@bourgois

Copy link
Copy Markdown
Collaborator

Merges gastownhall/gascity origin/main (bccc52f61) into the fork, spanning v1.3.5 → v1.4.0. 30 conflicted files / 65 hunks resolved; every non-trivial resolution carries an inline MERGE INTENT note naming what was kept and why.

Resolutions worth reviewing

internal/events/reader.go — both sides changed the same function's second return for different purposes: the fork renamed readFilteredTrackedreadFilteredCore and used the slot for degraded-read warnings (vc-89s); upstream kept the name and used it for the archive seq-window set ReadFilteredWithInFlight needs. Neither is a superset, so the core now returns both, with three thin wrappers.

cmd/gc/order_dispatch.goorderTrackingHistoryIndexLimit stays at the fork's 2048: it has no config override, so upstream's 256 would be an unescapable change on a fleet with a documented starvation incident (vp-cixi.6). Settle upstream via gastownhall#3961. defaultMaxOrderDispatchesPerTick lands at 5, not upstream's 4 — 4 is the old starvation default and TestOrderDispatchBudgetDefaultRaised guards that floor; 5 is what NOTE(vc-wz5.4) itself named.

cmd/gc/cmd_dolt_cleanup.go — protected-port set is now the union of the fork's live-state detection and upstream's recorded rig ports. Dropping the recorded ports left a port with no attributable live process unprotected in a destructive path (SIGKILL + DataDir removal).

Six defects found in clean merges (no conflict marker)

719 files auto-merged; intent-per-hunk covers only the 30 conflicts, and this fork's failure mode is silent loss in the other 97%. Found by build/vet/tests:

  • internal/api/server.go — same import merged twice
  • cmd/gc/cmd_nudge.go — upstream's clockless signature wired to the fork's clock-using body; did not compile
  • cmd/gc/dolt_project_id_test.go — 4 call sites kept, definitions deleted
  • internal/api/status_warm.go — the fork's wedged-leader escape forgot only the outer singleflight, so the retry it starts rejoins upstream's wedged inner storeHealthFlight — a no-op for exactly the case it exists to handle
  • cmd/gc/status_provider.go — SWR path served last-known-good without marking the result partial
  • cmd/gc/api_state.go — rig containment compared a canonicalized target against a raw city root, rejecting valid rigs

Generated artifacts

Regenerated, not hand-merged. Note productmetrics_command_census.json is an input, not an output: unioned by path (upstream 285 + 5 fork-only), with gc provider quota reallocated 195 → 199 where it collided with upstream's runtime-heartbeat, and next_id → 200. Resource-census baselines and the TESTING.md ledger re-derived from a fresh scan; CI policy hashes re-derived per pin.

Test state

go build ./... and go vet ./... clean. 8 of 9 merge-induced failures fixed.

Roughly 60 remaining failures are pre-existing upstream macOS breakage — reproduced on a clean origin/main worktree, caused by upstream's symlink resolution meeting /var → /private/var, invisible to upstream's Linux CI. Not introduced here.

Known red: TestAgentImageRebuildsBDAndGCWithPatchedGRPC. Upstream's new agent image builds bd from a release URL and cannot consume the fork's TIME-BOXED commit pin (deps.env, ADR-0026 C5); repinning isn't a drop-in because that commit is not an ancestor of beads v1.1.2. Tracked for WS-2c — deliberately not worked around, since quietly weakening a container-security test is worse than a visible failure.

Pushed with --no-verify: the pre-push hook runs the full suite, which is red on the pre-existing upstream macOS failures above.

julianknutsen and others added 30 commits July 18, 2026 23:03
…rics-single-tagged-build

test: share one tagged binary across metrics process contracts
…empotence-double

test: use stateful double for idempotent Dolt start
…load-event-driven

test: signal supervisor death in reload failure test
…t-recovery-crisp

test: remove duplicate raw bd recovery check
…y-crisp

test: cut mail testscript from 54s to 9s
…nsistency-direct-dolt

test: cut worktree store consistency from 59s to 7s
…starter-fast-clock

test: simulate slow concurrent Dolt startup
…fast-composition

test: replace managed mail city with direct Dolt fixture
## Summary

- Strengthens the shared `mail.Provider` conformance suite so Archive
and Delete remove a message from every public view.
- Makes terminal operations return typed `mail.ErrNotFound` without
resurrecting archived messages.
- Gives `mail.Fake` deterministic clock and thread-ID suppliers, then
aligns beadmail, the exec adapter/fixture, and the MCP bridge with the
same contract.

## Why

The interface already promised that Archive removes a message from all
views, but shared conformance only checked Inbox. That allowed providers
and test doubles to disagree on Get, Read, Reply, MarkRead, MarkUnread,
Thread, All, and Count behavior. One reusable contract now owns those
semantics instead of duplicating slow end-to-end scenarios.

## Test-pyramid impact

- The same provider contract runs against Fake, beadmail, the stateful
exec fixture, and the mocked MCP bridge.
- No new real-service or end-to-end test was added.
- `go test -count=1 ./internal/mail/...`: **62.80s**, versus **58.63s**
baseline (**+4.17s / +7.1%**).
- Peak RSS: **1,370,480 KB**, versus **1,367,368 KB** baseline
(**+0.2%**).
- An over-tested draft measured **80.83s**; its unrelated read-survivor
setup was removed before review.

## Verification

- `go test -count=1 ./internal/mail/...`
- `go test -race -count=20 ./internal/mail -run '^TestFakeConformance$'`
- `go test -race -count=20 ./internal/mail/beadmail -run
'^TestBeadmailConformance$'`
- `go test -race -count=20 ./internal/mail/exec -run
'^TestExecConformance$'`
- `go test -count=3 ./internal/mail/exec -run
'^TestMCPMailConformance$'`
- `bash -n contrib/mail-scripts/gc-mail-mcp-agent-mail`
- `shellcheck contrib/mail-scripts/gc-mail-mcp-agent-mail`
- `make test-fast-parallel`
- `go vet ./...`
- Active pre-commit and pre-push hooks
- Three-prong exact-diff council: correctness, maintainability, and test
policy all approved

## Tracking

- `ga-80po0c.25`

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Test User <test@test.com>
…s start under herdr (gastownhall#4349)

## Problem

Any agent with MCP servers configured cannot run under the herdr session
provider, and on-demand pool sessions hang in `start-pending` /
`agent_not_found` forever. gastownhall#3837 shipped the herdr provider without
wiring it into skill/MCP materialization, and three distinct gaps stack
up:

**1. herdr never executed `cfg.PreStart`.** Stage-2 skill/MCP
materialization is delivered *as* a PreStart entry, so
`isStage2EligibleSession` (cmd/gc/skill_integration.go) correctly holds
out any runtime that doesn't run PreStart — the same reason subprocess
is excluded. With `"herdr"` in neither eligibility allowlist,
`resolveProjectedMCPForTarget` hard-fails every MCP-configured agent:

```
effective MCP cannot be delivered to workdir %q with session provider "herdr"
```

For pool sessions this error surfaces inside `buildDesiredState`, so the
session is dropped from desired state and `provider.Start` is never
called: the reconciler polls (`herdr agent get`) an agent that was never
created (`herdr agent start` never issued), and the polecat sits in
`start-pending` forever.

**2. Ownership metadata was never readable.** The reconciler's
pending-create ownership check
(`runningSessionMatchesPendingCreateInfo`) reads `GC_SESSION_ID` /
`GC_INSTANCE_TOKEN` via `Provider.GetMeta` on ticks that fire while
`Start` is still delivering the startup nudge. tmux satisfies those
reads for free — its `GetMeta` is tmux `GetEnvironment`, and
`new-session` seeds the session environment from `cfg.Env`. herdr's meta
store is a sidecar populated only by `SetMeta`, so the reads came back
empty and the reconciler reaped every freshly started pool session
seconds after a *successful* start:

```
session reconciler: rolling back pending create <wisp>: live runtime belongs to another session
```

**3. pre_start `chdir`'d into a workdir that may not exist yet.** A pool
session's worktree is often created concurrently with (or by) pre_start
itself, so resume-path starts failed instantly with `chdir ... no such
file`.

## Fix (one commit per concern)

- **`fix(runtime/herdr): execute pre_start`** — implements PreStart in
the herdr provider mirroring tmux (`runPreStart`/`runSetupCommand`): `sh
-c` per entry, cwd from `GC_DIR`, process env + `cfg.Env`, bounded by
`[session] setup_timeout` (wired through `New()` from the runtime
registry, matching tmux), `ErrWaitDelay` treated as success for
daemonizing commands, output tail attached to failures, failures fatal.
With PreStart executing, herdr joins both eligibility allowlists
(`canStage1Materialize`, `isStage2EligibleSession`) with doc-comment
justification.
- **`fix(runtime/herdr): seed GetMeta sidecar from cfg.Env + tolerate
not-yet-created workDir`** — `Start` seeds the metadata sidecar from
`cfg.Env` immediately after agent creation (before the long idle-wait
window), honoring tmux's env-as-meta contract; later `SetMeta` calls
still override per key. pre_start's cwd falls back to the city root when
`GC_DIR` doesn't exist yet — the same fallback `effectiveWorkDir`
already applies to the agent's own cwd (the injected materialize/project
commands carry their target as an explicit `--workdir` flag and don't
depend on cwd).

## Tests

`internal/runtime/herdr/prestart_test.go` (runs commands in order,
GC_DIR cwd, env passthrough, fatal failure with output tail + failing
index, setup-timeout bound, default timeout, missing-GC_DIR fallback)
and `seedmeta_test.go` (identity keys readable via GetMeta after
seeding, SetMeta override, empty-env no-op). Plus herdr cases in
`TestIsStage2EligibleSession`.

## Verification

Live-tested on a real city with an MCP server configured, iterating
until green:
- Before: `herdr agent start` never issued for a slung pool polecat
(captured via a herdr CLI shim); stuck `start-pending`. Removing the MCP
server made it start — isolating the eligibility gate.
- After commit 1: `agent start` fires and `Start` returns success — then
the reconciler reaped it ("live runtime belongs to another session").
- After commit 2: pool polecat goes **ACTIVE** under herdr with MCP
configured and claims its bead.

## Related

- Depends conceptually on gastownhall#4342 (stale herdr socket read as "server
running" — without it, the provider swap aborts before any of this
runs). Independent code paths; either merges cleanly alone.
- Complementary to gastownhall#4225 (ProcessAlive tree-walk): gastownhall#4225 fixes a
liveness false-negative in `provider.go`; this fixes materialization +
ownership metadata. No overlapping hunks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…l#4413)

## Summary

- makes `TESTING.md` the normative source for test placement, design,
timing, and review
- defines the one-risk/one-smallest-owner loop, testability refactors,
conformance obligations, event-driven waits, failure-edge selection, E2E
admission, and flake policy
- sets the protected PR feedback objective while clearly separating
policy targets from enforcement that exists today
- corrects stale inventories, examples, provider interfaces, CI cadence
claims, and test-double descriptions

## Current enforcement

The document now distinguishes checked resource/runtime ledgers from
work still owned by `ga-80po0c.4` (workflow timing) and `ga-80po0c.6`
(executable E2E manifest). It also calls out current Playwright retry,
coarse integration routing, live-inference cadence, and production-store
conformance gaps instead of presenting them as solved.

## Validation

- `go test -count=1 ./test/docsync`
- `go test -count=1 ./internal/testpolicy/resourcecensus -run
^TestRepositoryLedgerMatchesCensusAndDocumentation$`
- `go test -count=1 ./internal/testutil/providerledger`
- `git diff --check`
- repository pre-push fast suite: 8/8 shards passed

## Review

Three delegated reviewers covered semantic usability, speed/failure
policy, and repository accuracy/enforceability. Their concrete findings
were incorporated before commit.

Tracking bead: `ga-yfgl4b`.
## Summary

- carry the assigned work-bead title through concrete resume and
wake-known-identity pool requests
- preserve the launcher's title-qualified worktree path during the
claim-before-current-marker reconcile window
- cover the exact cold-pool trigger shuffle observed in the
supported-pack nightly artifact

## RCA

Supported Pack Nightly run 29385443130, artifact 8331737677, launched
pool session gpig-8m6 in `fi-kar-implement-owned-work`. Concurrent
cold-pool demand temporarily rebound its metadata to another trigger
while the provider stayed in its original cwd. When fi-kar was assigned
back, the resume reconcile ran before `currently_processing_bead_id` was
stamped.

The resume request carried fi-kar's ID but omitted its title, so
`poolTriggerWorkDir` derived nonexistent suffixless `.../fi-kar`. Ralph
then failed its check while trying to chdir there. The same omission
existed in wake-known-identity requests. PR gastownhall#4230 correctly protects
same-trigger and marker-backed live retries, but this
claim-before-marker seam needs the complete work-bead identity to
reconstruct the launcher path.

## Verification

- RED before fix: both regression tests reported an empty
`WorkBeadTitle`; the resume case derived `.../fi-kar` instead of
`.../fi-kar-implement-owned-work`
- focused pool desired-state/trigger tests pass
- focused tests pass under repeated and race-enabled runs
- `go vet ./cmd/gc`
- repository pre-commit hooks pass
- `LOCAL_TEST_JOBS=8 make test-fast-parallel` passes
- mandatory pre-push fast suite passes
- independent five-axis review approved with no required findings

No Ralph executor or workdir-preservation heuristic changes are
included; the fix uses the existing `SessionRequest.WorkBeadTitle` seam
and path-safe slugging.
## What this changes

`gc dolt cleanup --force` now tracks Dolt data directories for
data-dir-only SQL server processes and removes confirmed test-owned
orphan directories after the process is reaped. Test startup also sweeps
old, unheld `.dolt` store directories left by killed tests, which keeps
stale temporary Dolt stores from accumulating across repeated local and
CI runs.

The sweep is deliberately conservative: it reuses the existing
test-owned path allowlist, requires an old `.dolt` marker, and treats
`lsof` scan errors as a reason to skip removal instead of guessing.

## Review notes

- Deletion remains limited to test-owned config/data paths accepted by
the existing guard logic.
- The symptom-based sweep requires the age gate, `.dolt` marker, and no
live `lsof` holder.
- The main surfaces are `cmd/gc` cleanup/reaper code,
`internal/doltorphan`, `test/dolttest`, the gastown integration test,
and the resource-census ledger.
- `docs/PROJECT_MANIFEST.md` is not present in this checkout; the
release gate uses the deployer criteria and local `TESTING.md` gates.

## Test plan

- [x] `go build ./...`
- [x] `go vet ./...`
- [x] `go test ./internal/testpolicy/resourcecensus/...
./internal/doltorphan/... ./test/dolttest/...`
- [x] `go test -tags integration ./examples/gastown/... -run
TestSweep_ReapsRealDoltDataDirAfterSIGKILL -count=1`
- [x] `make test-fast-parallel`
- [x] Release gate:
[`release-gates/ga-trvdd9-1-dolt-reaper-datadir-gate.md`](release-gates/ga-trvdd9-1-dolt-reaper-datadir-gate.md)

---------

Co-authored-by: quad341 <james@wordelman.name>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…ed work re-enters dispatch (ga-n2d.2) (gastownhall#3377)

## What

When a worker session is reaped (dead-runtime or stale-session close)
with work still assigned, `releaseWorkFromClosedSessionBead` already
clears the assignee and reopens in_progress work. This adds: it now also
**restores the work bead's pool route** (`gc.routed_to`, or
`gc.run_target` for workflow-kind beads) when that route is empty,
recovering the value from the closing session bead's own `template` /
`agent_name` metadata.

## Why

A polecat that finishes its bead and pushes its branch but **dies before
completing the done-handoff** leaves the bead `open` with an **empty
`gc.routed_to`** (a "handoff-orphan"). With no route, the pool demand
probe (`bd ready --metadata-field gc.routed_to=<pool>`) never matches
it, so no worker is dispatched — the completed work sits invisible and
open indefinitely, and can block downstream beads. (Confirmed on a rig:
two done-and-pushed beads stranded ~20h.) Existing
`releaseOrphanedPoolAssignments` explicitly skips empty-routed beads —
this closes exactly that gap.

## Behavior / safety

- Routes the orphan back to the **dead worker's own pool template**
(e.g. `<rig>/<pack>.polecat`), so it re-enters pool demand and a **fresh
worker** re-attempts the (idempotent) done/handoff. It does **not**
route to a merge/refinery role and cannot merge incomplete work.
- Only fires on a **confirmed-dead / reaped** session (gated on
`IsDeadRuntimeSession` + stop, or `!IsRunning` + startup-grace) — never
touches a live worker's assigned work.
- Restores only when the route is empty (`gc.routed_to == "" &&
gc.run_target == ""`); beads still carrying a route are untouched.
Per-key metadata merge preserves `branch`/`gc.kind`/etc. Idempotent.

## Scope

This is the Go **safety-net** half. The complementary **atomic
done-handoff** (set the route on a clean done so the crash window
shrinks) lives in the pack layer and is tracked separately.

## Tests

4 new table tests: restore-pool-route, restore-run-target-for-workflow,
leave-existing-route-untouched, no-template-still-releases.
Touched-scope tests green.

## Stacking

Cut from `main`; self-contained and independent. Touches only
`cmd/gc/session_beads.go` (+ its new test). No dependency on gastownhall#3373 or
gastownhall#3366.

Co-authored-by: Brandon Martin <b+git@heyomayeah.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d stream (adopts gastownhall#3718) (gastownhall#3931)

## Summary

Adopts and supersedes gastownhall#3718 by @csells, carrying its provider-neutral
structured transcript work forward and porting the UI from the retired
dashboard to the current React/Vite SPA.

This PR adds:

- The typed `session.structured.v1` REST and SSE contract across
supported transcript providers.
- Provider-neutral message, tool, usage, thinking, interaction, and
error projections.
- React transcript rendering with snapshot, upsert, reset, pending, and
degraded-state convergence.
- Stable REST-to-SSE resume tokens, including empty, suffix, and
interior paginated windows.
- Go wire-level and Playwright Chromium end-to-end coverage.

## Maintainer hardening

The adoption review additionally fixed:

- Append-stable synthetic IDs for repeated id-less OpenCode and Gemini
messages.
- A required, closed provider-neutral tool-error category enum.
- Sticky degraded dashboard state across heartbeat frames.
- Shared `Last-Event-ID` precedence and generated-client header
serialization.
- Empty-page handoff using a bounded inclusive anchor upsert.
- Interior paginated handoff using stable ID-anchored windows.
- Cursor invalidation when a retained pagination anchor disappears after
history rewrite.

## Rebase and review

- Head: `774515714`
- Base: `main` at `e025d64bc`
- The five-commit `git range-diff` preserves the complete series:
commits 1 and 3 remain patch-equivalent; commits 2, 4, and 5 differ only
where regenerated API/dashboard artifacts incorporate current-main
cockpit contracts.
- Formal segmented Claude, Codex, and Gemini review completed; all
merge-blocking findings were resolved.
- Final merge simulation against current `main` is clean.

## Verification

Green:

- All affected Go packages and focused race tests.
- 1,031 shared/frontend tests (152 shared + 879 React).
- Spec CI and dashboard CI/check/smoke.
- `go vet ./...`
- `make check-docs`
- Dashport Go end-to-end tests.
- Playwright Chromium structured-transcript end-to-end test.
- Pre-commit hook.
- Fast test shards: 8/8.
- Pre-push shards: 8/8.

## Follow-ups

`ga-ju1u4d.6` and `ga-ju1u4d.8` track scoped watcher-readiness and
generated-SSE runtime follow-up work. The deterministic reconnect path
and production-browser transcript flow are covered and green here.

## Credit

PR integration and dashboard port by @julianknutsen. Original
structured-stream work from gastownhall#3718 by @csells; the adoption commit and
this PR retain that provenance explicitly.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Chris Sells <csells@sellsbrothers.com>
Co-authored-by: Eddie the Engineer <adopt-pr@gascity.com>
…ill-collision during deacon patrol [● P1 · IN_PROGRESS] (gastownhall#4396)

Implements saitoc-fx5kqf
## What this changes

Schema generation for Gas City config docs no longer recursively scans
every non-hidden top-level directory in the worktree. Before this
change, leaked scratch checkouts or abandoned worktree directories at
the repository root could make the docgen comment walk parse thousands
of unrelated Go files and push docgen tests toward timeouts under
parallel test load.

The docgen path now asks git for the tracked top-level directories at
HEAD and only feeds those directories to jsonschema's comment extractor.
Non-git roots, or roots where the git lookup fails, keep the previous
walk-all-visible-directories behavior.

## Review notes

- The main behavior is in `internal/docgen/schema.go`:
`gitTrackedTopLevelDirs` plus the filter in `addGoCommentsFiltered`.
- The regression test builds a disposable git repo with one tracked
top-level package and one untracked `ga-leaked-worktree` directory, then
verifies only the tracked package contributes comments.
- The resource census changes are expected because the new test fixture
invokes real git. The ledger mirror is updated in
`internal/testpolicy/resourcecensus/census.go`,
`test/test-resources.toml`, and `TESTING.md`.
- This does not add a new runtime config knob or change schema output
for committed source trees.

## Test plan

- [x] `go test ./internal/docgen/...
./internal/testpolicy/resourcecensus/...`
- [x] `make test-fast-parallel`
- [x] `go vet ./...`
- [x] Release gate:
[`release-gates/ga-9ajrc0-docgen-tracked-dir-scan-gate.md`](release-gates/ga-9ajrc0-docgen-tracked-dir-scan-gate.md)

---------

Co-authored-by: quad341 <james@wordelman.name>
## Summary

Fixes monochrome Claude/Codex TUIs caused by `CI=1` leaking from the
controller into a newly-created per-city tmux server and then into every
pane.

- Wraps only commands whose parsed executable basename is `claude` or
`codex` with `env -u CI -u NO_COLOR`.
- Classifies from `runtime.Config.Command` before prompt assembly, then
wraps the final command, so provider aliases, empty legacy ProviderName,
and long-prompt `sh -c` commands behave correctly.
- Excludes Kiro/custom commands even when the launch family is `claude`;
leaves OMP and other custom providers unchanged.
- Applies at the shared `buildLaunchCommand` seam, so fresh starts and
warm `respawn-pane` relaunches both get the same environment.
- Does not manage a Claude `theme`; Claude documents `dark` as the
default and supports `auto`, light, and custom user themes, so color
support comes solely from removing leaked environment variables.

## Root cause evidence

Claude Code's Ink/chalk `supports-color` returns color level 0 when `CI`
is set without a recognized CI vendor variable. Isolated A/B on the same
account/settings:

- `CI=1`: 0 colored SGR escapes
- `env -u CI`: 14 colored SGR escapes
- `FORCE_COLOR=3`: 14 colored SGR escapes

The live controller and tmux server both carried `CI=1`; a fresh pane
after removing the server-global CI rendered color. `NO_COLOR` was a
secondary leak, not the primary cause.

## Verification

- `TestBuildLaunchCommandUnsetsColorKillersForInteractiveExecutables`
pins Claude/Codex executable classification, provider aliases, empty
legacy provider names, Kiro/custom exclusions, `/tmux-cli` behavior, and
final long-prompt `sh -c` wrapping.
- Real tmux integration test uses a unique fresh socket, an executable
fixture named `claude`, explicit runtime `Env` values (`CI=1`,
`NO_COLOR=1`, `CIRCLECI=true`), an atomic environment file, and a tmux
`wait-for` lifecycle signal. The pane process has CI/NO_COLOR absent
while preserving CIRCLECI.
- With Homebrew ICU flags
(`CGO_CPPFLAGS=-I/opt/homebrew/opt/icu4c@78/include`,
`CGO_LDFLAGS=-L/opt/homebrew/opt/icu4c@78/lib`): full
`internal/runtime/tmux` tests, real color integration test,
`internal/hooks` tests, resource census test, affected vet, `make -s
test-fsys-darwin-compile`, and `.githooks/pre-commit` all passed.

Rebased onto current `upstream/main` (209ad3e). The four-file diff
includes startup-path assertions because they close the create/respawn
command regression. No live sessions or Qlandia configuration were
touched.

---------

Co-authored-by: a3ackerman <user.email=28374790+A3Ackerman@users.noreply.github.com>
)

## Problem

`gc doctor` runs its checks sequentially with no per-check bound. One
check that wedges — in production, `order-firing-current`, whose
per-order `LastRunAcrossStores` store reads stall behind a saturated
data plane — stalls the entire run indefinitely: no summary, no exit,
and every check registered after the wedged one (import-state,
jsonl-archive, MCP, rig coverage…) silently never runs. On a busy host
this makes doctor unusable exactly when it's most needed, and the
operator can't tell "doctor is slow" from "doctor is dead."

Observed in production: doctor produced zero results past 150s while the
first ~34 (config-layer) checks complete in under a minute;
line-buffered capture + the check registration order pinned the wedge to
`order-firing-current` under load.

## Fix

- `Doctor.CheckTimeout` (zero = unbounded, preserving historical
behavior for embedders): each check runs under a wall-clock bound. A
check exceeding it is **abandoned** and reported as `StatusError` /
`SeverityAdvisory` with `TimedOut: true` — advisory because the check's
real outcome is unknown, so automation gates shouldn't fire on it; the
run continues to the remaining checks.
- Abandonment is race-safe: each bounded check runs against a context
whose `Output` is a private buffer, flushed to the real writer on
completion — an abandoned goroutine can never interleave writes with the
rest of the run. `--fix` and `RenderExtras` are skipped for timed-out
checks (unknown state / possibly still mutating).
- `gc doctor --check-timeout` (default 60s, 0 disables). The `gc start`
warm-up scan constructs its own Doctor and is unchanged.
- `CheckResult.TimedOut` is exported for `--json` consumers.

## Tests

- Wedged check (5s sleep, 25ms budget): abandoned in milliseconds,
reported as timed-out advisory error, subsequent checks still run,
report counts correct.
- Zero timeout: unbounded inline behavior pinned.
- Timed-out check: `--fix` not attempted.
- Completed check's incidental `ctx.Output` writes still reach the real
writer through the buffering.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Wldc4rd <charlie@thriva.app>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Eddie the Engineer <julianknutsen@users.noreply.github.com>
…townhall#4245) (gastownhall#4248)

Fixes gastownhall#4245 (partially — see Scope note).

### Bug

`beads.OpenStoreAtForCity` already computes a `BeadsDiagnostic` naming
the preflight gate and reason whenever native-store eligibility fails
and store selection falls back to the fork-per-op `BdStore` (which
execs a `bd` CLI process — and opens 3 SQL connections — per store
operation). But `cmd/gc`'s doctor wiring (`openStoreAtForCity` in
`main.go`) only ever kept the opened `Store` from that result and
discarded the `Diagnostic`. `BeadsStoreCheck` (`gc doctor`'s
`beads-store` check) never saw it, so it can only ever report `✓
store accessible` — a city silently running the dramatically more
expensive fallback looks identical to a healthy native-store city.
The reporter measured ~27 `bd` forks/second (~80 SQL connections/sec)
sustaining 1-4 Dolt cores for hours before the fallback was found via
manual process-spawn sampling.

### Fix

Added `openStoreResultForCity` alongside the existing
`openStoreForCity` in `cmd/gc/cmd_doctor.go` — same underlying
`openStoreResultAtForCity`, but preserving the `Diagnostic` instead of
discarding it. Changed `BeadsStoreCheck`'s factory field from
`func(string) (beads.Store, error)` to
`func(string) (beads.StoreOpenResult, error)` and wired the new
factory into `gc doctor`'s registration. After a successful
open+ping, `Run` now checks `Diagnostic.Store ==
beads.BeadsStoreNameBdStore` (set only on the actual fallback path,
confirmed by reading `internal/beads/factory.go`) and reports
`StatusWarning` naming the gate and reason instead of `StatusOK`.
`StatusWarning` never contributes to `gc doctor`'s blocking exit code
(only `StatusError` with `SeverityBlocking` does — confirmed in
`doctor.go`), so this is purely additive visibility, matching the
issue's own "Expected" behavior.

### Validation

- New tests `TestBeadsStoreCheck_WarnsOnBdStoreFallback` (asserts
  `StatusWarning`, message names the gate and reason, non-empty
  `FixHint`) and `TestBeadsStoreCheck_NativeStoreDiagnosticStaysOK`
  (inverse — a native-store diagnostic stays `StatusOK`). TDD RED
  confirmed against the pre-fix `Run` (both new tests written, the
  warning test failed with `status = 0 (OK), want Warning` before the
  diagnostic branch was added) → GREEN after.
- All 8 pre-existing `BeadsStoreCheck` tests updated for the factory
  signature change (mechanical: wrap returned stores in
  `beads.StoreOpenResult{Store: ...}`) and still pass unchanged in
  behavior.
- Full `internal/doctor` suite green. `cmd/gc`
doctor/store/status-focused
  tests (`Doctor|BeadsStore|OpenStoreResult|CityStatus` filter) green.
Full `cmd/gc` sharded suite (`GC_FAST_UNIT=1 test-go-test-shard ./cmd/gc
  1 6`) green except one confirmed pre-existing, unrelated timing flake
(`TestStopManagedCityForcesCleanupAfterTimeout`,
`cmd_supervisor_test.go`
  — reproduces intermittently in isolated re-runs regardless of this
  diff; touches only managed-city stop/cleanup timing, disjoint from the
  beads-store diagnostic path this PR changes).
- `go build ./...` and `go vet ./...` clean across the full workspace;
  `gofmt -l` clean on all touched files.

### Scope note

This PR implements only the issue's suggested fix #1 (a `gc doctor`
warning). Deliberately left out of scope:

- Suggested fix #2 (`gc status` human-output line showing `store:
  BdStore (fallback: <gate>)`) — a separate command's output
  formatting, not required to close the "silent" problem since `gc
  doctor` is the primary operator health-check surface.
- Suggested fix #3 (periodic re-preflight so long-lived processes can
  upgrade off the fallback once its gate clears) — a bigger lifecycle
  change to a supervisor/session-scoped process, not a same-day fix.
- Surfacing `PreflightResult.RepairSteps` in the warning message — that
  data lives on `contract.PreflightResult`, not on the `BeadsDiagnostic`
  struct that reaches the doctor check; threading it through would touch
  `diagnosticFromPreflight` and widen `BeadsDiagnostic`'s shape beyond
  what's needed to make the fallback visible. Gate + reason (already on
  `BeadsDiagnostic`) covers the issue's core ask. Happy to follow up if
  useful.
- gastownhall#4246 (the fallback's per-tick polling cost / caching) is a distinct,
  larger issue about reducing `BdStore`'s cost via cursors/caching —
  correctly filed separately by the reporter; not touched here.
## Summary

- reuse the current Go test executable as the `gc` CLI instead of
rebuilding the binary for this fixture
- remove unused rig initialization from the city-only setup
- preserve real managed Dolt startup, HQ schema verification, raw `bd
create`, provider-store creation, runtime publication and cleanup, and
both `gc-` prefix assertions

## Performance

- focused local test body: 55.72s -> 22.54s
- reduction: 33.18s, or about 59.5% (2.47x faster)
- historical Blacksmith body: 15.17s

The local environment has a v55 database with v53 code, so it falls back
from the native store. These measurements demonstrate wall-time
improvement only; they do not claim native-path validation.

## Validation

- focused fresh-city and re-exec tests
- test resource-census guard
- `make test-fast-parallel`
- `go vet ./...`
- active pre-commit and pre-push hooks
- two independent delegated reviews: approved with no blocking findings

## Scope

Test infrastructure only. No production behavior or retry policy
changes.
## Summary

- extract the existing pool-death phase into
`CityRuntime.reconcilePoolDeaths`
- keep the `tick` call at the exact original position
- let the two pool-death policy tests exercise that phase directly
instead of traversing unrelated config reload, reconciliation, and
store-opening work

## Performance

- focused pair before: about 7.32s
- focused pair after: about 0.01s
- improvement: roughly 730x

The extraction is mechanical and changes no production ordering, retry
policy, error handling, hook behavior, or state transitions.

## Preserved edges

- canonical rig environment reaches the death hook
- partial session listings skip hook execution and preserve prior state
- full `tick` coordination remains covered by the existing tick test
inventory

## Validation

- focused pair and five-run timing
- test resource-census guard
- `make test-fast-parallel`
- `go vet ./...`
- active pre-commit hook
- two independent delegated reviews: approved with no required findings

## Scope

One reconciliation phase and its two focused tests. No broader
controller refactor.
… align, +TTL prune) (gastownhall#4281)

## What

Publishes a per-session **run-map file at claim time** so external
proxies can stamp `X-Gc-Run-Id` for run-scoped spend/cost attribution —
restoring `manifold.spend` run_id fill (dead since the Jul-11 v55 skew
day).

Cherry-picks `c0ff9d217` from `feat/hook-runmap` (the minimal writer, 2
files) onto `main`, plus two adaptations.

## Why this shape

`gc hook --claim` already resolves the run_id in hand
(`beadmeta.ResolveRunID` of the just-claimed bead). `writeRunMap`
publishes it to
`${GC_RUNMAP_DIR:-/run/gc-manifold-runmap}/<session>.json = {run_id,
bead_id, ts}` under each of the session's address keys
(`GC_SESSION_NAME`, session-bead-id, `BEADS_ACTOR`). The proxy reads it
by `x-manifold-affinity`.

Because it writes the **in-hand run_id** and never reads the session
bead back, it sidesteps two problems at once that blocked the old
bead-pointer path:
- the **v55 schema skew** on the work store (no `bd` read), and
- the **wisp/graph-tier blindness** (no `bd`/`gc bd` reaches ephemeral
graph-store session beads).

Rewritten per claim keyed by session, so it tracks the *current* run
even when one session completes multiple beads.

## Commits

1. `c0ff9d217` (cherry-pick) — the runmap writer + tests.
2. Default the writer dir to `/run/gc-manifold-runmap` to match what the
deployed manifold proxy (`gc-manifold-proxy.go`, `GC_PROXY_RUNMAP_DIR`
default) already reads — the two defaults previously disagreed so
nothing was stamped.
3. **TTL prune** (`GC_RUNMAP_TTL`, default 48h): reap files not
refreshed within the TTL so the dir stays bounded by the live session
set instead of leaking one stale file per ended session (tmpfs clears
`/run` only on reboot). 48h is generous enough to exceed the longest a
live session goes between claims, so a working session is never pruned
out from under the proxy.

## Tests

`cmd_hook_claim_runmap_test.go`: per-key atomic write, empty-runID
no-op, dir override, TTL parse/default/fallback, prune
reaps-stale-keeps-fresh (and never touches non-`.json`), and
prune-on-write. Build + vet + tests green.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Eddie the Engineer <adopt-pr@gascity.com>
## Summary

- inject the existing retry sleeper into root-store verification
- replace managed-Dolt and wall-clock traversal with a stateful
`beads.Store` double
- preserve the production path by passing `time.Sleep` at the sole
production call site

## Performance

| Scenario | Before | After |
| --- | ---: | ---: |
| root-store retry test body | 27.09s | effectively 0s |

The slice also removes three process-environment mutations from the
checked `cmd/gc` resource ledger.

## Coverage retained

The direct test proves the same contract at the policy boundary:

- the store fails twice and succeeds on the third `List`
- every attempt uses `ListQuery{AllowScan: true, Limit: 1}`
- the two retry delays are exactly 500ms
- production still supplies the real wall-clock sleeper

## Verification

- two independent delegated reviewers: APPROVE
- `GC_FAST_UNIT=1 go test -count=20 ./cmd/gc -run
^TestVerifyCanonicalBdScopeStoreReadyRetries$`
- `go test -count=1 ./internal/testpolicy/resourcecensus -run
^TestRepositoryLedgerMatchesCensusAndDocumentation$`
- `git diff --check origin/main...HEAD`

## Local hook note

The local pre-push fast sweep is currently blocked by 11 run-map tests
introduced on `main` by gastownhall#4281. All 11 reproduce on the exact parent
commit under inherited `umask 0002` and pass under `umask 022`; this
branch does not touch their source or tests. The branch was therefore
pushed with the local hook bypassed, while required GitHub CI remains
authoritative.
## Summary

- extract only external issues-table scan-result classification into a
pure helper
- replace one real-Dolt negative test with a table-driven unit test for
success, missing table, and generic scan failure
- retain the real endpoint query and both existing real-Dolt
project-identity composition tests

## Performance

| Scenario | Before | After |
| --- | ---: | ---: |
| missing issues-table policy test body | 10.82s local / 7.00s CI |
effectively 0s |

The checked test-resource ledger also drops two subprocess sites, one
subprocess-owning file, three environment mutations, and one
slow-process gate.

## Coverage retained

The unit edge pins:

- nil scan result succeeds
- exact `sql.ErrNoRows` produces the same trimmed-database missing-table
message
- any other scan error keeps the same contextual message and wrapped
cause

`TestVerifyExternalDoltEndpointRejectsProjectIdentityMismatch` and
`TestVerifyExternalDoltEndpointRejectsMissingLocalProjectID` still start
real Dolt and traverse `Ping`, `active_branch()`, `SHOW TABLES LIKE
issues`, and project metadata reads. The production SQL query remains at
the endpoint boundary.

## Verification

- two independent delegated reviewers after rebase: APPROVE
- focused mapping test at `-count=20`
- both retained real-Dolt composition tests
- checked resource-census/document synchronization
- `go vet ./...`
- changed-package lint and pre-commit hooks
- `git diff --check`

## Local hook note

The repository pre-push sweep remains blocked locally by the inherited
gastownhall#4281 run-map tests under `umask 0002`; the exact failures reproduce on
`main` and pass under `umask 022`. This slice does not touch that
subsystem, so the branch was pushed with only the broken local pre-push
hook bypassed. Required GitHub CI remains authoritative.
…im + trust it in run-detail (gastownhall#4435)

The dashboard run-detail showed "session unresolved for this current
node" for every step of every pool-routed run (0/524 execution instances
resolved on maintainer-city).

## Root cause (two independent defects)
1. **Claim-time stamp never built.** The gastownhall#2843 design intends every work
bead to carry a durable session back-reference so run-detail resolves
the executing session after the transient Assignee is cleared on close.
graphroute implements this for DIRECT routing but deliberately defers
the POOL case to claim time — and `gc hook --claim` only ever stamped
`gc.work_branch`, never `gc.session_id`, though `GC_SESSION_ID` is in
hand at claim.
2. **Resolver gate rejects real ids.** `sessionIDRe` is a TS-supervisor
port accepting only `gc`/`td`/`th`/4-letter prefixes; it rejects real
OSS session-bead ids (`mc-`/`ga-`/`gcy-`), so even a live or stamped id
resolved to nothing.

## Fix
- `cmd/gc/cmd_hook_claim.go`: stamp `gc.session_id` + `gc.session_name`
on the claimed work bead at claim time — one combined,
compare-and-skip-idempotent write; stamped even with no worktree;
skipped for control beads; best-effort (never fails the claim).
- `internal/runproj/detail_sessionlink.go`: resolve the durable
`gc.session_id` **first**, index-independently, so closed steps resolve
to the correct session even after it leaves the active-only index;
validated by a provenance-trusted `sessionBeadIDRe`. The legacy
name/assignee fallback keeps the strict `sessionIDRe` gate, so a
recycled pool-slot-name collision yields **no** link, never a wrong one.

## Review
Adversarially red-teamed. A wrong-attribution P1 (recycled-slot byName)
was found and fixed (durable-id-first precedence); a follow-up re-verify
cleared all four attack angles (sibling-preassign stamps only Assignee;
retry-clone staleness self-heals, tracked ga-se3gb5; garbage rejected).
RED-confirmed tests for each.

## Validation
`go build ./...`, `go vet`, `go test ./cmd/gc ./internal/runproj`, cold
`make test-fast-parallel` (pre-push) — all green.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
## Summary

- Replace the redundant normal-binary process test with exact
`go/build.MatchFile` checks and direct normal command-tree assertions.
- Reuse the normal `gc` binary already built by
`check-native-dependency-surface.sh` for symbol, literal, and
help-surface checks.
- Keep the tagged real-binary end-to-end test unchanged.
- Bank the resulting subprocess and slow-process-marker reductions in
the checked resource census.

## Assertion ownership

| Risk | Owner after this change |
| --- | --- |
| Normal versus `productmetrics_testhook` file selection | Fast
in-process `MatchFile` assertions for all six tagged/normal files |
| Normal command tree contains `gc metrics` but excludes the testhook
command | Fast in-process command-tree assertion |
| Normal artifact excludes private symbols and literals | Existing
native-dependency guard, using its one already-built binary |
| Normal artifact help excludes the private command | Existing
native-dependency guard with isolated `HOME` and `GC_HOME` |
| Tagged artifact runtime contracts | Existing
`TestProductMetricsTaggedBinaryProcessContracts`, unchanged |

No production behavior changes.

## Timing and resource impact

| Measure | Before | After |
| --- | ---: | ---: |
| Blacksmith normal product-metrics process test | 10.45s |
approximately 0s test-body time |
| Full normal `gc` builds across these checks | 2 | 1 |
| Child processes in the fast Go test | 5 | 0 |
| Tagged real-binary builds | 1 | 1 |

The focused test passed 10 times in 2.453s package time. The native
dependency guard passed in 17.64s and still performs exactly one normal
build.

## Verification

- Focused test, `-count=10`
- `scripts/check-native-dependency-surface.sh`
- Resource-census ledger and generated-table consistency test
- Pre-commit lint, `go vet ./...`, and doc-sync checks
- Two independent read-only council reviews of the final effective diff
- `git diff --check`; `go.mod` and `go.sum` unchanged

The broad local pre-push sweep also ran. Its affected gates passed; the
remaining failures were the existing host-umask-sensitive run-map tests,
which are unrelated to this diff and run in a clean environment in CI.

Tracking: `ga-yrotsuu`
## Outcome

Replace wall-clock coordination in the concurrent managed-Dolt starter
proof with strict `flock`, `sleep`, and logical-clock doubles while
continuing to execute the real materialized `gc-beads-bd` lifecycle
script.

The behavior is unchanged; the proof is faster, deterministic, and more
mutation-sensitive.

## Exact edge

> Lock acquisition exhausts all six attempts; the first concurrent-start
observation is non-reusable; its managed probe reaches a query and fails
closed; after one logical 500 ms wait the second observation is reusable
on port 3311; PID 4242 and the adopted port are persisted; Dolt is never
launched.

## Ownership map

| Risk | Owning proof |
| --- | --- |
| Six start-lock failures, failed probe/query ordering, reusable second
observation, PID/port persistence, no launch |
`TestGcBeadsBdStartWaitsForConcurrentStarterSuccess` using the real
lifecycle script and strict PATH doubles |
| Real kernel `flock` and lock-file inode behavior |
`TestGcBeadsBdStartDoesNotReplaceLiveLockFileInode` (unchanged) |
| Readiness beyond the legacy 10-second window |
`TestGcBeadsBdStartWaitsForSlowConcurrentStarterSuccess` (unchanged) |
| Remaining-budget plumbing into `existing-managed` |
`TestGcBeadsBdStartConcurrentWaitPassesRemainingExistingManagedBudget`
(unchanged) |

## Measurements

| Measurement | Before | After |
| --- | ---: | ---: |
| Focused test, local | 4.32 s | 0.17–0.25 s |
| Focused test, CI baseline | 4.07 s | pending CI |
| Repeated focused run | — | 10/10 in 4.29 s package time |

Independent council measurement reproduced 4.28–4.36 s before and
0.17–0.25 s after.

## Resource ratchets

| Scope | Resource | Before | After |
| --- | --- | ---: | ---: |
| All tracked test source | subprocess | 530 | 529 |
| All tracked test source | fixed sleep | 440 | 439 |
| Untagged test source | subprocess | 401 | 400 |
| Untagged test source | fixed sleep | 286 | 285 |
| Untagged Small debt | subprocess | 398 | 397 |
| Untagged Small debt | fixed sleep | 286 | 285 |

## Verification

- focused edge: 20 consecutive passes in correctness review
- retained real-boundary owner quartet: pass
- resource ledger consistency: pass
- `git diff --check`: pass
- pre-commit lint, generated-doc checks, `go vet ./...`, and docsync:
pass
- two independent read-only council approvals on effective diff
`7ebe79acc338d85269ba0522aa13c2bcb32a7568f63558af748078dfee7c58ba`

The full pre-push fan-out encountered the known host-umask
`TestPruneRunMapReapsStaleKeepsFresh` failure plus a load-only
product-metrics failure. The product-metrics owner passed 10/10
immediately in isolation, and the changed focused edge passed another
10/10; no product-metrics or run-map code is touched here.
## Outcome

Move the import-state missing-lock and invalid-config assertions to
their smallest owning seams, and remove a redundant full-doctor
registration journey.

This is behavior-neutral and test-only: one file changes, with no
production, policy, ledger, or dependency edits.

## Assertion migration

| Retired assertion | Smallest owner after this change | Retained
composition owner |
| --- | --- | --- |
| Import-state check is registered for a valid city |
`TestBuildDoctorChecks_NameSetUnchanged` plus
`doctor_check_names.golden` containing `packv2-import-state` | Existing
`doDoctor` compositions and `internal/doctor` register/run/render tests
|
| Missing `packs.lock` reports the import-state error and both repair
commands | `TestImportStateDoctorCheckReportsMissingLockfile`, through
the real read-only `packman.CheckInstalled` path |
`TestDoDoctorFixConvergesWave1CityRootImportsThroughImportState` |
| Malformed `city.toml` excludes the import-state check while retaining
the core config check |
`TestBuildDoctorChecksSkipsImportStateCheckWhenCityConfigInvalid` | Core
`city-config` run/render coverage |

The existing `TestImportStateDoctorCheckReportsInstallHint` continues to
own detailed result and repair-hint formatting with an injected report.
The new missing-lock owner deliberately does not stub
`checkInstalledImports`, so the production integration with
`packman.CheckInstalled` remains covered.

## Measurements

CI baselines come from run `29697921488`; the three old journeys landed
on separate `cmd/gc process` shards.

| Edge | Before | After |
| --- | ---: | ---: |
| Valid registration journey | 7.22 s | removed as duplicate |
| Real missing-lock state | 6.90 s | 0.00–0.01 s |
| Invalid-config registration gate | 6.99 s | 0.00–0.01 s |

The two new owners passed 10 repetitions in 2.52 s total package time,
including `cmd/gc` TestMain overhead. The change removes about 21.1
seconds of aggregate CI test work and roughly 7 seconds from each
affected shard.

## Verification

- new direct owners, 10 repetitions: pass
- retained `TestBuildDoctorChecks_NameSetUnchanged`: pass
- broader import-state and builder slice: pass
- retained full `doDoctor` convergence composition: pass
- poisoned GC/BEADS path run: pass
- resource census: pass, unchanged
- `git diff --check`: pass
- pre-commit lint, generated-doc checks, and `go vet ./...`: pass
- two independent read-only council approvals on effective diff
`02a3935e3586b66b69d08d5e340ed487523c95b87c70ff51a74c43511c0bf916`

A pre-change local full-doctor measurement activated the host
managed-Dolt leak guard, so the before table uses the successful
like-for-like CI timing artifact rather than presenting that
contaminated local run as a benchmark.
…n with SHOW COLUMNS (gastownhall#4272)

## Problem

`repairIDDefault` probes `INFORMATION_SCHEMA.COLUMNS` once per repair
table (`dependencies`, `events`, `wisp_events`) on **every native store
open**. Dolt does not push the `WHERE` predicate into
`INFORMATION_SCHEMA`, so each probe is a full catalog scan. Observed
live on a shared fleet Dolt server during a polecat batch (load avg 64
on a 6-core host, Dolt ~77% CPU): `SHOW FULL PROCESSLIST` dominated by
these `SELECT COUNT(*), COUNT(COLUMN_DEFAULT) …` probes.

Measured on that server (idle): the catalog-scan probe costs **50.65
ms/op** vs **0.74 ms/op** for the equivalent `SHOW COLUMNS` (68×) — ×3
tables ≈ 150ms of server CPU per store open, eliminated. (Upstream beads
made the same replacement for its content_hash probe in
gastownhall/beads#4479, same rationale.)

## Fix

Probe with `SHOW COLUMNS FROM \`<table>\` LIKE 'id'` and read the
`Default` cell directly. Semantics are identical: NULL Default → same
idempotent `ALTER`; present Default → no-op; absent column → no-op;
absent table (now surfaced as error 1146 / "table not found" instead of
zero rows) → tolerated via `isTableNotExistError`, covering both the
go-sql-driver error type and the embedded driver's message shape.
Verified against dolt 2.1.10: intact expression default shows as
`(uuid())`, stripped default as NULL, missing table errors `table not
found`.

## Tests

New `TestRepairIDDefaultAgainstDoltServer` (integration tag) runs the
probe + repair end-to-end against a real throwaway `dolt sql-server`
over the same wire protocol the fleet uses: stripped default detected
and repaired, intact default untouched, absent table and id-less table
tolerated. The pre-existing `TestNativeDoltStoreEventsIDDefaultRepair`
continues to cover the repair through the vendored storage handle where
that handle exposes a raw DB. `./internal/beads` unit suite green (1106
tests).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Eddie the Engineer <julianknutsen@users.noreply.github.com>
quad341 and others added 22 commits July 25, 2026 14:45
…e to the worktree reaper (gastownhall#4655)

## Summary
- Bead: ga-vzt5pq.1 (implements FR-1/FR-2/FR-3/FR-5/FR-7 +
NFR-1/NFR-3/NFR-5 from ga-vzt5pq's design)
- Before reaping a closed-bead worktree at path P, batch-queries the
rig's bead store for ANY bead in ANY molecule whose
`gc.work_dir`/`work_dir` metadata equals P, and protects the worktree if
any match is non-terminal — fixes cross-molecule worktree reuse, where a
bead in a different, unrelated molecule can still be actively using a
path whose nominal owner molecule already closed.
- Adds a config-driven freshness quarantine
(`AutoReapClosedBeadWorktreesMinAgeMinutes`): a worktree younger than
this is exempt from reaping regardless of other gates, computed from the
`.git` pointer file's mtime, fails closed if unstattable.
- Extends `reapDecision.Reason` to name the referencing bead ID when
protecting via borrow-veto, matching the existing liveness/git-state
gate reasoning detail.
- Rebased cleanly onto the now-merged liveness-gate base (PR gastownhall#4598 /
ga-e2g9do); no enable flag needed — strictly additive protection gated
by the existing `AutoReapClosedBeadWorktreesEnabled`/`DryRun` switches.

## Test plan
- [x] 26/26 reaper-related tests green (`TestReapClosedBeadWorktrees*`,
`TestExtractBeadIDFromWorktreeName*`, `TestIsStrictlyUnderDir*`)
- [x] Full `internal/config` suite green
- [x] `go vet ./...` clean
- [x] `make test-fast-parallel` — all 8 shards green

<!-- mpr:issue-refs v1 -->
---
🔗 **Maintainer cross-reference** — added by the gascity maintainers, no
action needed from you:
- Related to gastownhall#4492 — implements the daemon-side borrow veto and
freshness quarantine proposed in part 2 of that issue's fix — the reaper
now protects a closed-bead worktree when any non-terminal bead in any
molecule still points at its path via gc.work_dir/work_dir metadata, and
exempts worktrees younger than a configurable window; it does not cover
part 1 (converging do-work worktree creation on the framework discovery
root), publisher-owned self-removal, or the remaining reaper defects in
part 3, and the veto checks the known work-dir metadata keys rather than
every metadata key

<sub>Linked for triage visibility — not auto-closing. If this looks off,
just delete this block.</sub>
<!-- /mpr:issue-refs -->

---------

Co-authored-by: investigator <investigator@gascity.local>
## What

If `CachingStore.SetMetadataBatch` returns an error, treat the backing
outcome as unknown. The cache now advances the row mutation fence and
marks the pre-write row dirty, without applying the proposed patch or
emitting a success notification. The next ordinary read installs backing
truth.

This is an independent reconciler-safety extraction; it does not depend
on PR gastownhall#4652 and adds no new abstraction.

Tracking: ga-f7v2ft.64.1

## TDD evidence

RED before the production change:

```text
ambiguity fence = seq:0 start:0 dirty:false local:false
```

The failure reproduced for rejected, partially committed, and fully
committed backing outcomes.

GREEN after the seven-line production change:

- All `TestCachingStoreSetMetadataBatch*` tests pass.
- Focused race test passes.
- Full `internal/beads` package passes.
- All six fast `cmd/gc` shards pass.
- `go vet ./...` and changed-package lint pass.

`make test-fast-parallel` retains one unrelated environment failure in
`internal/doctor/TestCustomTypesCheck_TableDrift`: the installed bd
binary has `CGO_ENABLED=0` and cannot initialize embedded Dolt. The
exact failure was already reproduced on pristine base for PR gastownhall#4652; no
doctor, bd, or Dolt code is changed here.

## Scope guard

Two files and exactly 100 added lines. The monolith version used 305
lines and a dedicated 295-line harness; this extraction uses the
existing cache invariants and one table-driven test instead.
## What this changes

This documents the claim identity convention for pack authors: Tier-1
recovery and claim commands should use the concrete running session
identity (`${GC_ALIAS:-$GC_TEMPLATE}`), while Tier-2 and Tier-3
discovery should continue to use the shared template route.

The main addition lives beside the existing prompt-template tier table,
with a short cross-reference from the session identity design note. That
keeps the rule close to the place pack authors already look when writing
prompt claim loops.

## Review notes

- This PR is docs-only in the Gas City repo:
`engdocs/architecture/prompt-templates.md` and
`engdocs/design/session-model-unification.md`.
- The related prompt-template changes are in the local-only
`gc-management` repo, which has no remote and cannot have a GitHub PR.
The merge authority has to handle that local merge separately.
- No Go code, config schema, generated docs, OpenAPI, or dashboard files
change here.

## Test plan

- [x] `make check-docs`
- [x] Local pack-branch acceptance checks: remaining bare `$GC_TEMPLATE`
matches are only Tier-2 `bd ready --assignee` lines; 37
concrete-identity replacements present
- [x] Local pack-branch TOML parse check for
`packs/actual/deployer/formulas/mol-deployer-gate.formula.toml`
- [x] Release gate:
[`release-gates/concrete-identity-claims-gate.md`](release-gates/concrete-identity-claims-gate.md)

---------

Co-authored-by: quad341 <james@wordelman.name>
…astownhall#4490)

Fixes gastownhall#4488.

Five documentation defects in `internal/bootstrap/packs/core/skills/`,
all re-verified against the running binary immediately before this PR
(`go version -m $(which gc)`:
`vcs.revision=730c9b2e0a99e29dc9aefc1ec58b14d8da1b36ef`,
`vcs.modified=false`).

1. **Dangerous, in gc-dispatch/SKILL.md** — `gc convoy check`/`gc convoy
autoclose` descriptions were inverted. `check` takes no id and is an
unscoped city-wide auto-close mutation; `autoclose` is the scoped one
requiring `<bead-id>`. A reader who copies the doc's `gc convoy check
<id>` gets an argument error, and the doc's own `autoclose` line (no id)
models "fix" as dropping the argument — which yields the unscoped sweep
under the name that reads as a safe check. Swapped the descriptions,
fixed the arg placeholders, and marked `check` as mutating.
2. **gc-work/SKILL.md** — documented a claim path (`gc hook show
<agent>`, `gc agent claim <agent> <id>`) whose subcommands don't exist.
Replaced with the real `gc hook --claim` path, and fixed two more dead
flags in the same section (`--label`/`--note` →
`--add-label`/`--append-notes`), plus a race caveat on `bd update
--claim`.
3. **Four more dead flags/commands**: `gc dashboard --port` (no such
flag — replaced examples with real ones: `--no-open`, `serve`), `gc
order check <name>` (takes no name), and a `gc skills dashboard`
reference (top-level command is `skill`, not `skills`, and no
`dashboard` subcommand exists under it either — pointed at the
gc-dashboard skill by name instead).
4. **gc-dashboard/SKILL.md self-contradiction** — the per-city `[api]`
port section didn't note that supervisor mode overrides it, which
contradicted the "per-city `[api]` ports are ignored" statement later in
the same file. Added the precedence note where the config is first
introduced.
5. **gc-mail/SKILL.md** — `archive`/`delete` were presented as routine
operations with no indication that both permanently delete the
underlying bead (they're the same operation under two names; there's no
reversible "put this away" path). Added an explicit warning and pointed
at `mark-read` as the non-destructive alternative.

Also documented three formulas that ship in the core pack but were
missing from gc-dispatch/SKILL.md's formula catalogue
(`mol-prompt-synth`, `mol-review-quorum`, `mol-scoped-work`) — a smaller
sixth item from the same issue.

**Verification**: `go test ./internal/bootstrap/packs/core/...
./internal/config/... ./internal/doctor/... ./internal/materialize/...
./internal/validation/...` all pass.

Not in scope for this PR: `gc mail delete --help`'s own description text
(in `cmd/gc/cmd_mail.go`) also undersells what the command does — the
issue's "sharper half" — but that's a code change, not a skill-doc fix;
flagging it here in case a maintainer wants it as a follow-up.

<!-- mpr:issue-refs v1 -->
---
🔗 **Maintainer cross-reference** — added by the gascity maintainers, no
action needed from you:
- Related to gastownhall#4422 — documents in the gc-mail skill that `archive` and
`delete` are the same operation and both irrecoverably destroy the
message's underlying bead, and points readers at `mark-read` as a
non-destructive alternative; this is a docs-only change — the
destructive behavior itself, and the absence of a safe drain verb inside
the `gc mail` namespace, are untouched

<sub>Linked for triage visibility — not auto-closing. If this looks off,
just delete this block.</sub>
<!-- /mpr:issue-refs -->

---------

Co-authored-by: Jacob Hausler <jacob@hausler.cc>
…nhall#4658)

Fixes `registry-sfn`. The pack registry now serves community packs under
**scoped** names
(`owner/pack`), but rig include-list resolution rejected any
slash-bearing token *before* it ever
looked the name up — so `--include alice/foo` silently resolved as a
local directory path instead of
the registry pack. The failure was a confusing "not found" or a *wrong
local pack*, never a clear
error.

Before scoping, every pack name was single-segment, so "contains a
slash" was a safe proxy for "this
is a path". Scoped names broke that assumption.

## The obvious fix is a no-op — worth knowing why

Flipping the grammar check alone changes **nothing observable**: every
bundled pack name is
single-segment, so `alice/foo` still falls through to a broken
`./alice/foo` local import, and *no
test can fail on revert*. So this also adds the registry-catalog lookup
that fix implies, behind a
nil-optional `rig.Deps.ResolveRegistryPack` seam. `cmd/gc` implements it
read-only over the on-disk
registry caches — no fetch, no config write, so `gc rig add` stays
offline.

(Also: the bead points at `cmd/gc/cmd_rig.go:684`, but that resolution
has since moved to
`internal/rig/imports.go`. Same code, same bug.)

## Classification and precedence

A token is a pack-*name* candidate only if it matches
`packregistry.ValidatePackName` — the existing
grammar, reused rather than copied a fourth time. Precedence is now
documented in the function
comment rather than incidental:

1. `[packs]` entry (raw token or `packs/`-stripped)
2. real local pack in the city (`<city>/<tok>/pack.toml`)
3. bundled builtin matching the `packs/`-stripped name
4. exact name in a cached registry catalog
5. verbatim fallback (path / URL)

Two ambiguities decided deliberately: **local content beats the
registry** (a directory you can see
and edit must never be silently swapped for a fetched pack), and
**builtins beat the registry** (a
published pack cannot shadow a name shipped in the binary). Two extra
refusals: a token that
*declares* itself a path (`./x`, or the documented city-local
`packs/<name>`) is never read as a
scoped name — so a registry owner segment literally named `packs` cannot
reinterpret existing include
lists — and *any* existing directory at that path blocks registry
resolution, even without a
`pack.toml`.

Requiring `./` for local imports was rejected outright: it breaks every
existing bare-directory
include.

## Compatibility

The registry step is appended **after** every existing step, so no
existing decision changes. A bare
builtin, `packs/<builtin>`, `./<builtin>`, a `[packs]` key, and a local
pack directory all take the
same branch they took before. **Zero existing test expectations
changed** —
`TestDoRigAdd_WithPack`,
`TestRigAddIncludeCanonicalizesBuiltinPackSource` and
`TestRigAddIncludePrefersConfiguredPackOverBuiltin` pass unmodified.
That's the compatibility evidence
that matters.

## Verification

Red→green proven by restoring the original slash gate: the end-to-end
failure is the bug verbatim —
`rig import sources = ["./wespd/cacc-twin-team"]` persisted as a local
import.

`gofmt` clean · `go build ./...` · `go vet` · `golangci-lint run`
(v2.12.0, the Makefile pin) **0
issues** on both touched packages · `go test ./internal/rig/...
./internal/packregistry/...
./test/docsync/...` · full `GC_FAST_UNIT=1 go test ./cmd/gc/` **765s
ok** · `make
check-core-boundary check-native-dependency-surface
check-eventexport-isolation` · genschema
drift-clean. All under the Makefile's `env -i` discipline to match CI.

`internal/rig` now imports `internal/packregistry`; no cycle,
`check-core-boundary` passes.

**Pushed with `--no-verify`**: the pre-push hook's parallel suite kept
being killed by the tooling's
timeout rather than failing, and the verification above is a strict
superset of it for the touched
packages. CI re-runs everything here.

## Caveats, for follow-up rather than this PR

- **Cache-only resolution.** A user who never refreshed a registry gets
today's behaviour. Deliberate
— `rig add` must not become a network op — but the fix depends on a warm
cache.
- **No version pin.** The legacy include→import conversion has no
version channel, so a
registry-resolved include writes a bare source that resolves latest at
install. Identical to pasting
the URL, but weaker than the registry's own `--version >=<latest>`
suggestion.
- **Ambiguity across registries** (same name, two sources) resolves to
*unresolved* rather than a clear
error, because `canonicalizePackIncludes` has no error channel. So the
confusing not-found persists
  for that narrow case.
- The remote `gc rig add --git-url` path resolves against the *server's*
cache; wired for consistency
  but not exercisable here (no network egress).

<!-- mpr:issue-refs v1 -->
---
🔗 **Maintainer cross-reference** — added by the gascity maintainers, no
action needed from you:
- Related to gastownhall#1396 — extends what `--include` accepts to registry pack
names, including scoped owner/pack forms, in the same
include-canonicalization code path that issue is about; it does not
change how a bundled or `packs/<name>` token is handled, so the
system-pack case reported there is untouched by this change

<sub>Linked for triage visibility — not auto-closing. If this looks off,
just delete this block.</sub>
<!-- /mpr:issue-refs -->

---------

Co-authored-by: Claude <noreply@anthropic.com>
…ga-n2d Gap C) (gastownhall#3373)

## Summary

Reduces this PR to **Gap C only**: a one-time **startup sweep** that
releases stale runtime
session-name claims held by CLOSED configured named-session beads, so a
freshly started
controller/supervisor begins from a clean name index and on-demand
respawn of a same-named
session (refinery, witness, …) is not blocked by a pre-fix legacy claim
inherited across a
binary restart (the ga-n2d "refinery no-respawn" class).

Rebased onto current `main`.

## What changed vs the original PR

The original PR bundled two parts:

- **Gap A — read-side lazy release**
(`ensureSessionNameAvailableForSelfAndOwner` recognizing a
closed bead by the full identity signal set). **Dropped** — superseded
on `main` by gastownhall#3366
(`0c5c1b912`) plus the existing `ensureConfiguredSessionNameAvailable`,
which already release a
closed configured-named bead's name lazily via
`wasConfiguredNamedSession` when the configured
  identity reclaims it.
- **Gap C — startup sweep** (`ReleaseStaleConfiguredNameClaims`).
**Kept** — still absent from
`main`; the lazy path alone does not eagerly clean the name index for
ownerless availability
checks or `gc session list`, nor for legacy pre-flag beads whose
identity survives only on an
  `alias` / `agent_name` / `template` (role) label.

`configuredNamedIdentitySignalsMatch` is retained as the sweep's
legacy-signal recognizer (its
former Gap-A read-side use is removed).

## Behavior

- Wired into `runController` and `reconcileCities`, **best-effort** — a
sweep failure never blocks
startup. The `IncludeClosed` query reads through the cache to the
backing store, so it is
  effective regardless of cache priming.
- Only **CLOSED** beads are swept; a live or asleep bead keeps its name.
- A closed bead's claim is released only when its reserved
`session_name` matches a configured
named-session runtime name AND the bead is recognized as that configured
identity (boolean flag,
recorded identity, or a legacy alias/agent_name/template signal that
resolves to it).

## Scope

5 files, +335 / -0 (purely additive on `main`):

- `internal/session/name_claim_sweep.go` (new) — the sweep
- `internal/session/name_claim_sweep_test.go` (new) — release
(legacy/flagged) + preserve (live/ad-hoc) cases
- `internal/session/named_config.go` —
`configuredNamedIdentitySignalsMatch` helper
- `cmd/gc/controller.go`, `cmd/gc/cmd_supervisor.go` — startup wiring

## Test

`make test` green locally.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: test <test@test.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tring (gastownhall#4649)

## Summary

`mapRunPhase` ORed a substring scan into the authoritative status check:

```go
if i.status == "blocked" || strings.Contains(textForIssue(i), "blocked") {
```

`textForIssue` concatenates a step's title, description and metadata, so
any run whose text merely **contains** the word — a verdict enum, a
prompt, an instruction — was bucketed into the blocked lane.

`mol-review-quorum` hits this on every run: its review step describes
the verdict as `"pass, pass_with_findings, fail, or blocked"`, so
mid-review quorum runs surface as **BLOCKED** in the dashboard Runs
summary, and the operator is offered a claim-a-worker remedy that cannot
apply to them.

Hoisting the terminal check above this branch (already in `main`) fixed
only the fully-closed case — an **open** run still mislabels, because it
never reaches the terminal branch. This drops the substring scan so the
blocked lane is driven solely by `status == "blocked"`.

That's the invariant the codebase already states elsewhere, in
`detail_displaystate_fixes_test.go`:

> `"blocked"` is reserved for nodes the store itself marks blocked.

`textForIssue` is retained for the `"review"` keyword path.

### How it was found

Observed on a live city: completed and mid-review `mol-review-quorum`
runs both showed in the blocked lane. The same root cause was
independently diagnosed and fixed downstream before this PR; only the
substring half is still outstanding on `main`, since `main` already has
the terminal-check reorder (and the `rootID`/`gc.outcome=fail` labelling
that came with it).

## Testing

- [x] `make check` — every gate passes except one load-sensitive flake
in `internal/productmetrics`, detailed below. Not caused by this change.
- [ ] `make check-docs` — not applicable, no docs/navigation/link
changes
- [ ] `make test-integration` — not applicable; this is a pure
projection/labelling change in `internal/runproj` with no runtime,
controller, or workflow behaviour change

Green: `fmt-check`, `golangci-lint run ./...` (**zero findings**), `go
vet ./...`, `check-release-dist-ignore`, `check-routed-test-rows`, and
the unit suite including `cmd/gc` (881s) and `internal/runproj` in full
with goldens.

**One possible upstream issue worth your attention, now filed separately
as gastownhall#4653** — `internal/productmetrics`, the `DisableAndPurge` family,
appears to be load-sensitive under `make test`'s `-p=4`. Across two full
runs it failed on two *different* tests:

- `TestDisableAndPurgeExactTokenConflictAndPeerCleanRecovery` —
`control_unix_test.go:1386: purge error = productmetrics:
disable-write-failed, want class "state-changed-concurrently"`
- `TestDisableAndPurgeRejectsPeerSuccessorReplacedDuringCleanProof`

The package passes **3/3 standalone**, and under `GOMAXPROCS=1`. The
differing test names across runs suggest a genuine scheduling flake on a
CPU-constrained machine (2 cores here) rather than anything to do with
run-phase mapping. Filed as gastownhall#4653 with the mechanism analysis so it does
not clutter this PR.

<details>
<summary>Two earlier local failures were my own environment, not
upstream — retracted</summary>

An earlier revision of this description reported four failures in
`cmd/gc` (`pool_test.go:119`) and `internal/doctor`
(`TestCustomTypesCheck_TableDrift`) as reproducing on unmodified `main`.
They did reproduce, but the cause was entirely local: my `bd` binary had
been built with `CGO_ENABLED=0`, so it could not open an embedded Dolt
store and every test shelling out to `bd init` failed with `embedded
Dolt requires a CGO build`. Rebuilding `bd` correctly (`CGO_ENABLED=1`
**and** `-tags gms_pure_go` — the combination `make doctor-build` warns
about) fixed all four. No upstream defect there; apologies for the
noise.

`cmd/gc` also initially exceeded `make test`'s `-timeout 15m` at 900.5s
on this hardware; it now completes in 881s. Tight on 2 cores, but
passing.
</details>

Three cases added in `phasemapping_blocked_status_test.go`:

| Test | Before | After |
|---|---|---|
| open run whose step text only *mentions* "blocked" | **FAILS** (`phase
= "blocked"`) | passes |
| fully-closed run with the same text | passes | passes |
| open run with a real `status == "blocked"` member | passes | passes |

The first is the regression test proper — verified failing against
unmodified `main` and passing with the change. The second documents the
already-correct terminal behaviour so a future reorder cannot silently
regress it. The third guards against over-correcting, asserting a
genuine store-marked blocked member still drives the lane.

Existing `runproj` goldens (summary + detail) are **unchanged** — their
blocked fixture is a real `status == "blocked"` bead, not a text match.

## Checklist

- [ ] Linked an issue — no issue exists upstream for *this* defect; the
reproducer is the in-repo `mol-review-quorum` formula, whose
verdict-enum wording is what triggers it, so it is self-evident from the
diff. Happy to file one if you'd prefer it tracked. (gastownhall#4653 is referenced
above but is an unrelated flake found while validating, not this fix.)
- [x] Added or updated tests for behavior changes
- [x] Updated docs for user-facing changes — none needed; no documented
behaviour describes text-matched blocking
- [x] Called out breaking changes or migration notes — none. The only
behaviour change is that runs which merely mention "blocked" stop being
reported as blocked. Any run genuinely marked `status == "blocked"` is
unaffected.
…#4660)

## What this changes

The test resource census now treats `testing.T`/`testing.TB` calls to
`Setenv` and `Chdir` as auto-restoring helpers instead of ambient
environment or working-directory debt. Direct process mutations through
`os.Setenv`, `os.Unsetenv`, `os.Clearenv`, and `os.Chdir` continue to
count.

The checked `cmd/gc+untagged` environment/CWD baselines and generated
testing ledger are lowered to the remeasured values, so migrations can
adopt `t.Setenv` and `t.Chdir` without consuming the anti-growth
ratchet.

## Review notes

- Receiver classification remains type-based; there is no
environment-key special case.
- Unresolvable receiver bindings still fail closed.
- The shared classifier feeds both repository census and
reviewed-hermetic-body reachability.
- No new resource type, scope, runtime behavior, or configuration
surface is introduced.

## Test plan

- [x] Differential regression proves `t.Setenv`/`t.Chdir` are excluded
while aliased direct `os.*` calls still count.
- [x] Full resource-census package and exact ledger/document
synchronization pass.
- [x] Repository-wide build and vet pass.
- [x] `make test-fast-parallel` passes all eight jobs, including the
real push hook.
- [x] Release gate:
[`release-gates/ga-lay45s-resourcecensus-testing-receiver-gate.md`](release-gates/ga-lay45s-resourcecensus-testing-receiver-gate.md)

---------

Co-authored-by: investigator <investigator@gascity.local>
Co-authored-by: quad341 <quad341@users.noreply.github.com>
…0p) (gastownhall#4661)

## Summary
- Pre-push gate had no concurrency control: independent agents
converging on the gate at the same time oversubscribed the box and
manufactured red gates indistinguishable from real regressions (measured
twice on 2026-07-25, load 88.07 with 5 concurrent `test-fast-parallel`
runs + 2 gates + 1 `make test`).
- `scripts/test-local-parallel` now acquires one of
`PUSH_GATE_MAX_CONCURRENT` (default 2) numbered `flock(1)` slots under
`<city_root>/.gc/gate-slots` before running any jobs, holding it for the
invocation's entire lifetime. On contention it polls with a bounded wait
(`PUSH_GATE_MAX_WAIT_SECONDS`, default 600s), printing current slot
holders immediately so a queued agent knows it's queued, not hung.
Exhausting the wait maps to `exit 75`, distinct from a real test
failure. `GC_PUSH_GATE_NO_CAP=1` bypasses the cap for one invocation.
- Adapted from `packs/maintainer-pr-review/scripts/run-lock-lib.sh`'s
`mpr_acquire_global_slot` pattern.
- The self-test (`scripts/test-push-gate-lock.sh`, 29 assertions) runs
as a direct `test-local-parallel` job (`push-gate-lock-selftest`, wired
into `fast` and `full` modes) rather than through a `go test`
trampoline. A trampoline's `exec.Command` call would add a tracked
subprocess occurrence to `internal/testpolicy/resourcecensus`'s
baselines, including the `scope=all` audit row, which fails on any
change (growth or shrinkage) with no per-file exemption available — so
the self-test is driven as a plain shell job instead, following the
existing `fsys-darwin-compile` precedent for non-`go-test` jobs in the
same file.

## Deviations from the original design (documented in `ga-owh20p`'s bd
notes)
- FR7 not implemented: it assumed an existing bd claim-lease heartbeat
mechanism that needed extending across the wait+run phases. Verified
false — no such mechanism exists (`bd heartbeat` leases are
node-local/ephemeral, never committed to Dolt). The underlying
claim-staleness concern is tracked separately under `ga-aw5356`.
- Mayor's test-local-job-count addendum (governing total shard
concurrency across in-flight gates, not just gate count) deferred to a
follow-up bead (`ga-g6h06h`, P2) rather than expanding this bead's scope
further.

## Test plan
- [x] `go build ./...`
- [x] `go vet ./...`
- [x] `bash scripts/test-push-gate-lock.sh` direct run — 29/29
assertions pass
- [x] `go test ./internal/testpolicy/resourcecensus/...` — ratchet
green, baseline unchanged (535/163, 396/112, 391/109)
- [x] `go test ./scripts/...` — pass
- [x] `./scripts/test-local-parallel fast` (real pre-push hook run) —
all 9 jobs pass, including `push-gate-lock-selftest`

---------

Co-authored-by: investigator <investigator@gascity.local>
…get (gastownhall#4664)

## Summary
- Converts the remaining fixed hang-guard literals in
`cmd/gc/cmd_stop_test.go` to the shared `hangBudget` constant /
`awaitCond`/`awaitClose` helpers, matching the pattern established
elsewhere in this sweep (ga-wbjjvx/ga-ezitr0).
- Best-effort cleanup waits (not hang detectors) now use `hangBudget`
directly.
- Real hang-detector assertions now use `awaitCond`/`awaitClose` instead
of a raw `time.After` race against the fatal path.

## Scope notes
- Out of scope, left untouched: the sub-~200ms site, and the
`cmdStop(..., N*time.Second, ...)` argument-feed sites — those are
tracked separately under ga-5lsj2k.
- Rebased onto current `origin/main` (5 unrelated commits landed since
fork, none touching this file).

## Test plan
- [x] `go build ./cmd/gc/...`
- [x] `go test ./cmd/gc/... -run 'TestCmdStop'` — all pass
- [x] `go vet ./cmd/gc/...` — clean
- [x] Pre-push hook fast suite (`test-local-parallel fast`, 8 jobs) —
all pass

refs ga-m77au0

Co-authored-by: investigator <investigator@gascity.local>
…l#4669)

## What this changes

Three `cmd_config_test.go` tests now set `GC_CITY_PATH` to their
temporary city instead of relying on ambient upward `city.toml`
discovery. This keeps the tests hermetic and prepares them for the later
test-binary guard that will disable ambient discovery.

There is no production behavior change in this PR. Explicit city-path
resolution already precedes ambient directory discovery in the command
startup flow.

## Review notes

- The diff is test-only: three one-line environment bindings in one
file.
- The tests retain their existing temporary-directory and `clearGCEnv`
setup.
- The broader ambient-discovery guard is intentionally not included; the
migration is landing in small batches first.

## Test plan

- [x] `make test-fast-parallel` — all 9 jobs pass
- [x] `go build ./...`
- [x] `go vet ./...`
- [x] All three changed `cmd_config_test.go` tests pass in a focused run
- [x] Release gate:
[`release-gates/ga-clpi8u-cmd-config-ambient-discovery-gate.md`](release-gates/ga-clpi8u-cmd-config-ambient-discovery-gate.md)

---------

Co-authored-by: investigator <investigator@gascity.local>
…se name (gastownhall#4659)

## Summary

Fixes `ga-vqs6xr`: pooled agent sessions (`max_active_sessions > 1`) got
their trigger bead's `work_dir`/`gc.work_dir` metadata bound to the
shared
**base** qualified name instead of their own per-slot identity, on every
reconcile tick that **rebinds** an already-existing pooled session to a
new
work bead (routine and frequent — not just first-create).

### Root cause

In `realizePoolDesiredSessions` (`cmd/gc/build_desired_state.go`):

- `qualifiedName := cfgAgent.QualifiedName()` is computed once, at
function
  entry, from the base agent config — before any per-slot resolution.
- The bind call `bindPoolSessionTriggerBead(bp, cfgAgent, qualifiedName,
sbInfo, item.request)` used that stale base name for *every* pooled
slot.
- The correct per-slot identity (`manualSession` branch, or
  `poolDesiredRequestIdentity(cfgAgent, slot)`) was computed 12-16 lines
  *after* the bind call had already run.

`bindPoolSessionTriggerBead` → `poolTriggerWorkDir` →
`resolveConfiguredWorkDir` expands the agent's `work_dir` template using
whatever qualified name it's handed. Because the stale base name was
handed
in, every pooled instance's session-bead metadata got bound to the
**same**
path whenever a reconcile tick reassigned a pooled session to a new work
bead.

This only manifests on **rebind**, not on a fresh multi-slot create:
create-
time planning (`selectOrPlanPoolSessionBead`/`poolTriggerMetadata`)
already
sets correct per-slot metadata, and a same-trigger preservation guard
(`oldWorkBeadID == workBeadID`) protects the very first bind. It's the
routine "rebind an existing pooled slot to new work" path that
regresses.

### Fix

Hoist per-slot identity resolution above the
`bindPoolSessionTriggerBead`
call, and pass the freshly-resolved `qualifiedInstance` instead of the
loop-invariant `qualifiedName`. `cfgAgent` (not the deep-copied
`resolveAgent`) is kept to match existing create-time precedent. The
stale
`qualifiedName` var is left as-is for the unrelated `fmt.Fprintf`
error-log
string.

### Verification

- New regression test:
`TestRealizePoolDesiredSessionsRebindPreservesDistinctWorkDirPerSlot` —
  red before the fix, green after.
- `go test ./cmd/gc/... -run 'Pool'` clean.
- Full sharded suite (`make test-cmd-gc-process-parallel`): 2 shard
  failures observed, both independently root-caused as pre-existing/
  unrelated:
  - `TestBdRigWorktreeStoreConsistentAcrossRawBdGcBdAndProviderStore` —
Dolt schema-init flakiness under load (unrelated subsystem), confirmed
    via differing failure symptoms across reruns.
- `TestSendReloadControlRequestNoChange` — reconcile-timing flake under
    6-way parallel contention; its injected fake `buildFn` never calls
    `realizePoolDesiredSessions`, and it passed 3/3 in isolation.
- Pre-push `test-fast-parallel` also hit one transient failure
  (`TestDockerSessionProtocol` in the unrelated `scripts` package — a
10ms-poll-interval tmux/Docker timing test, confirmed unrelated by diff
  scope and 3/3 clean isolated reruns); the retried push ran all 8 fast
  jobs clean.
- `go vet ./...` clean.
- Checked for merge/file overlap against the bead's flagged PRs: gastownhall#4501
  (merged, no file overlap) and gastownhall#4551 (open, touches
  `cmd/gc/build_desired_state.go` but in a fully disjoint line range,
  ~3944-4017 vs this change's ~2765-2790).

### Out of scope (per bead description, left to `ga-ighomh`)

`SharedCwdGuard`, config validation for `max_active_sessions` without
per-instance `work_dir` variance, and `gc session list` real-cwd display
—
tracked separately by `ga-ighomh` (P1, defense-in-depth/observability
follow-up).

## Test plan

- [x] New regression test fails before the fix, passes after
- [x] `go test ./cmd/gc/... -run 'Pool'` passes
- [x] `make test-cmd-gc-process-parallel` — clean aside from two
      independently-confirmed pre-existing/unrelated flakes (see above)
- [x] `go vet ./...` clean
- [x] Pre-push fast suite passes clean

---------

Co-authored-by: investigator <investigator@gascity.local>
…all#4676)

## Summary

- Normalize registry attribution into safe effective `tier` and
`publisher` values; malformed or missing claims downgrade without
rejecting the catalog.
- Expose attribution consistently in `gc pack registry search` and
`show`, in text output and schema-v1 JSON.
- Stamp new pack releases with safe `community / Unknown publisher`
attribution so generated catalogs are valid by construction.
- Keep attribution presentation-only: it does not authorize installs or
alter pack selection.

## Testing

- [x] `make test-fast-parallel` on rebased HEAD via the normal pre-push
hook (all 9 jobs passed)
- [x] `go vet ./...`
- [x] formatting and `git diff --check`
- [x] focused release-stamp, catalog normalization, CLI entrypoint,
text, JSON, and schema tests
- [x] full local parallel lane: all feature-relevant unit and
integration groups passed; REST shards 7 and 8 passed on isolated rerun
after repairing a transient shared `bd` install race
- [x] delegated five-axis pre-commit review: APPROVE, no required
findings

The full lane also reproduced pre-existing
`TestSweep_ReapsRealDoltDataDirAfterSIGKILL` twice. It is unrelated to
this diff and is tracked in `ga-em9pd`; the cause is context-canceled
`lsof` output being treated as a completed nonzero result.

## Checklist

- [x] No standalone issue is needed; this is the Gas City half of the
coordinated Registry publisher-trust feature.
- [x] Added or updated tests for behavior changes.
- [x] Documentation impact reviewed; no existing command-output field
reference requires an update.
- [x] No breaking changes or migration steps. Registry schema remains
version 1.
…l#4671)

## What this changes

Seventeen command tests now set `GC_CITY_PATH` to the temporary city
they already enter. Order show/history, event emission, formula preview,
and formula version-check tests therefore select their fixture city
explicitly instead of depending on an ambient upward search for
`city.toml`.

This is a test-hermeticity change only; production command behavior is
unchanged.

## Review notes

- The diff is 17 identical one-line additions across four `cmd/gc` test
files.
- The explicit city path is set immediately after each existing
`t.Chdir` call.
- This is batch 2 of the migration. The test-binary ambient-discovery
guard is intentionally not included and must wait until every affected
test file has migrated.
- There are no config, API, wire-format, or migration changes.

## Test plan

- [x] `go build ./...`
- [x] `go vet ./...`
- [x] All 17 directly affected tests
- [x] `make test-fast-parallel` (all nine jobs)
- [x] Release gate:
[`release-gates/ga-e66rtz-ambient-city-discovery-batch-2-gate.md`](release-gates/ga-e66rtz-ambient-city-discovery-batch-2-gate.md)

---------

Co-authored-by: investigator <investigator@gascity.local>
## Summary

- Resolve the non-city push-gate fallback through the repository common
Git directory.
- Make sibling linked worktrees share one valid slot directory instead
of trying to create a directory beneath their .git gitfile.
- Preserve city-root precedence and normal-clone behavior.

Tracks bead ga-3rd1m.

## Testing

- [ ] `make check` (not run; the documented sharded fast gate and vet
were run directly)
- [ ] `make check-docs` (not applicable; no docs changed)
- [ ] `make test-integration` (not applicable; no runtime, controller,
or workflow behavior changed)
- [x] `bash scripts/test-push-gate-lock.sh` (48/48)
- [x] `shellcheck scripts/push-gate-lock-lib.sh
scripts/test-push-gate-lock.sh`
- [x] `go test ./scripts -count=1`
- [x] `make test-fast-parallel`
- [x] `go vet ./...`

## Checklist

- [x] Linked bead ga-3rd1m
- [x] Added a real two-linked-worktree regression and acquisition proof
- [x] No user-facing documentation change required
- [x] No breaking change or migration required
…paths (gastownhall#4674)

## What this changes

Makes the `gc prime` session-hook tests, session-nudge tests, and
formula-cook tests select their temporary city explicitly through
`GC_CITY_PATH` instead of relying on an upward search from the process
working directory. This keeps the tests hermetic and prevents an
unrelated ambient city from changing their behavior.

The shared formula test helper now accepts the working directory and
exact city root separately. That preserves cwd-based rig selection while
still making city resolution explicit.

## Review notes

- This is test-only; no production command behavior changes.
- `internal/formulatest.SetupHermeticCookEnv` changes from one path
argument to separate `chdirDir` and `cityRootDir` arguments; its only
two callers are updated here.
- This intentionally does not add the test-binary ambient-discovery
guard. Remaining migration batches must land before that guard is
enabled.

## Test plan

- [x] Run all 36 directly affected, indirectly affected, and guard-blind
control tests in `./cmd/gc`.
- [x] Run `make test-fast-parallel`; all nine jobs pass.
- [x] Run `go build ./...` and `go vet ./...`.
- [x] Release gate:
[`release-gates/ga-ql2s5k-ambient-city-discovery-batch-3-gate.md`](release-gates/ga-ql2s5k-ambient-city-discovery-batch-3-gate.md)

---------

Co-authored-by: investigator <investigator@gascity.local>
## Summary

- Forward the documented push-gate bypass and tuning variables from
`make test-fast-parallel` across its scrubbed `env -i` boundary.
- Keep the environment scrub intact; an unrelated ambient sentinel
remains excluded.
- Extend the existing Make contract without adding another
subprocess-census entry.

Tracks bead ga-4bbeq.

## Testing

- [ ] `make check` (not run; the relevant sharded inventory and vet were
run directly)
- [ ] `make check-docs` (not applicable; no docs changed)
- [ ] `make test-integration` (not applicable; no runtime, controller,
or workflow behavior changed)
- [x] RED proof: focused contract failed on missing
`GC_PUSH_GATE_NO_CAP` forwarding before the Makefile change
- [x] `go test ./scripts -run
TestTestFastParallelUsesSanitizedEnvironmentAndMachineAwareConcurrency
-count=1`
- [x] `go test ./scripts -count=1`
- [x] Live linked-worktree proof: `GC_PUSH_GATE_NO_CAP=1 make
test-fast-parallel` launched all nine shards instead of failing at
`.git/gate-slots`
- [x] Full non-cmd/gc core inventory with a pinned CGO-capable `bd`
- [x] All six fast `cmd/gc` shards, push-gate self-test, and Darwin
compile
- [x] `go vet ./...`

Host note: the wrapper run itself had one unrelated failure because
another process replaced the global `bd` with a CGO-disabled build
during the run. The exact failing doctor test and the complete core
inventory passed with a pinned CGO-capable `bd`.

## Checklist

- [x] Linked bead ga-4bbeq
- [x] Added a regression for all four controls plus unrelated-variable
exclusion
- [x] No user-facing documentation change required
- [x] No breaking change or migration required
## What this changes

Go test binaries now refuse to proceed when a surviving Dolt-port
environment variable matches the managed Dolt port of a city
discoverable from their current working directory. Previously, the guard
only recognized the static local port `3307`; tests launched beneath a
live city could instead discover that city’s actual port from runtime
state and escape the guard.

The new check is additive. It keeps the existing environment-based arm,
walks upward for the nearest `city.toml`, and reads that city’s
`.gc/runtime/packs/dolt/dolt-state.json` with a minimal standard-library
parser. This makes the comparison self-relative without introducing
another fleet-specific magic port.

## Review notes

- Scope is limited to `internal/testenv`; production command behavior
and configuration are unchanged.
- The runtime-state arm accepts only a positive JSON `port` and only
adds refusal conditions.
- Synthetic end-to-end coverage uses ports `19999` and `20000`, distinct
from both `3307` and the fleet port used during the incident.
- `GC_ALLOW_PROD_DOLT_PORT_IN_TESTS=1` remains the explicit opt-out for
deliberate local-Dolt tests.
- A separately executed production `gc` subprocess does not import
`internal/testenv`; that known boundary is documented and remains out of
scope.

## Test plan

- [x] `go build ./...` and `go vet ./...`
- [x] Focused ambient-city and legacy production-port tests (36
subtests)
- [x] Full `internal/testenv` package and resource-census ledger-sync
test
- [x] `make test-fast-parallel` (9/9 jobs)
- [x] Release gate:
[`release-gates/ga-ceutvg-ambient-city-dolt-port-gate.md`](release-gates/ga-ceutvg-ambient-city-dolt-port-gate.md)

---------

Co-authored-by: investigator <investigator@gascity.local>
## Summary

- distinguish a controller that was definitely unavailable before
request entry from a stop request that may already have entered
- accept only the exact `ok\n` acknowledgement
- fail closed after any post-connect write, read, timeout,
malformed-response, or socket-identity ambiguity instead of starting
direct provider/tmux cleanup
- preserve legacy direct cleanup when no request could have entered

This is an independently useful reconciler-adjacent correctness fix. It
does not introduce the new reconciler or shadow-mode implementation.

## Why

Previously, any non-`ok` result collapsed to “controller absent.” If the
controller accepted the stop but the response was lost or malformed, the
CLI could become a second shutdown owner and race the controller over
session/provider cleanup.

## Verification

- regression tests were written against the unsafe fallback and observed
failing before the implementation
- focused stop-client and caller tests pass
- focused race tests pass
- all `cmd/gc` fast shards pass
- `make test-fast-parallel` passes
- changed-package lint passes
- `go vet ./...` passes
- resource census and Darwin cross-compile pass
- active pre-commit hook passes

Requirement: `SESSION-RECON-012`
Bead: `ga-f7v2ft.64.2`
…#4678)

## Summary

Fresh provider sessions can otherwise reach an empty prompt after a
context-cycle handoff: the handoff is durable, but ordinary mailbox
injection waits for a later `UserPromptSubmit` hook that may never
occur. Deliver explicitly marked auto-handoff mail in the managed
`SessionStart` context instead.

The change uses the existing handoff labels and the existing sanitized,
priority-aware mail formatter. It archives only the messages that were
actually delivered, and only after provider-hook output succeeds.

## Behavior

- Given a managed `SessionStart` and unread mail carrying both
auto-handoff delivery labels, when `gc prime --hook` writes startup
context successfully, then the successor receives the handoff before its
first user prompt and the delivered handoff is archived.
- Given ordinary, already-read, or partially marked mail, it is not
injected at `SessionStart`; the normal `UserPromptSubmit` inbox path is
unchanged.
- Given provider-hook output fails, the handoff remains durable and
unread for retry.

## Why this is safe

This does not change handoff, reset, or wake decisions. It only supplies
durable continuation context at the `SessionStart` hook boundary.
Continuation mail is deliberately read through beadmail because `gc
handoff --auto` persists that class of mail there regardless of an
independently configured ordinary-mail provider.

## Related work

- gastownhall#1552 introduced `gc handoff --auto` for PreCompact handoffs.
- gastownhall#2920 archives injected auto-handoff mail after successful delivery.
- gastownhall#3762 is a related fresh-start handoff issue on the manual attach
path; it is not fixed by this PR.

## Scope

- `cmd/gc`: SessionStart hook context and regression coverage.
- `internal/mail/beadmail`: explicit selector for delivery-marked
auto-handoff messages.

## Testing

- [x] `go test ./cmd/gc -run
'^TestDoPrimeWithHook_DeliveredStartupPromptKeepsStepReminder$'
-count=1`
- [x] `go test ./internal/mail/beadmail -run
'^TestCheckAutoHandoffsReturnsOnlyUnreadDeliveryMarkedMail$' -count=1`
- [x] `go build ./cmd/gc/`
- [x] `go vet ./...`
- [ ] `make check` (CI)
- [ ] `make test-integration` (CI runtime coverage)

## Checklist

- [x] Related upstream work is linked above; no separate issue is needed
for this narrow regression fix.
- [x] Tests cover the delivery, exclusion, archive, and output-failure
boundaries.
- [x] No docs change is needed: there is no public CLI or configuration
surface change.
- [x] No breaking change or migration is required.

---------

Co-authored-by: wbern <kenneth.bernting@me.com>
…ess (gastownhall#4012) (gastownhall#4137)

## Summary

Adds an opt-in `[session] claim_holder_stall_timeout` for a desired,
alive session that still owns in-progress work but has stopped reporting
provider activity. The existing `progress_stall_timeout` remains
claim-less only.

A confirmed stale holder is fresh-restarted only when its provider is
healthy. A new pool worker re-adopts the same canonical session bead and
its existing in-progress work.

## Safety contract

- Default remains disabled; no city changes behavior without the new
timeout.
- The claim read must succeed. Unknown ownership, human
attachment/interaction, startup grace, and a known-unhealthy provider
all suppress the destructive restart.
- The pool minimum-floor exemption remains for truly idle workers, but
cannot hide a real in-progress claim when the new policy is enabled.
- Claim-holder and claim-less thresholds are independent, so a holder is
not recycled at the shorter claim-less deadline.

## Verification

- Serial focused and package suites: `go test -p=1 -parallel=1 ./cmd/gc
./internal/config ./internal/doctor`
- `go vet ./...`
- `make check-docs` and regenerated config schema/reference docs
- Scoped changed-file lint: zero issues
- Adversarial reconciler coverage proves stale recovery, default-off
behavior, unknown claim fail-safe, red-provider suppression, independent
thresholds, and two-pass pool re-adoption with the in-progress bead
preserved.

Addresses gastownhall#4012.

Co-authored-by: wbern <kenneth.bernting@me.com>
Co-authored-by: architect <architect@gascity.local>
Merges gastownhall/gascity origin/main (bccc52f) into the Voxist fork,
spanning v1.3.5 -> v1.4.0. 30 conflicted files / 65 hunks resolved; every
non-trivial resolution carries an inline MERGE INTENT note naming what was
kept and why.

Notable resolutions
-------------------
internal/events/reader.go: both sides changed the same function's second
return for different purposes — the fork renamed readFilteredTracked to
readFilteredCore and used it for degraded-read warnings (vc-89s), upstream
kept the name and used it for the archive seq-window set consumed by
ReadFilteredWithInFlight. Both are load-bearing and neither is a superset,
so the core now returns BOTH and three thin wrappers take what they need.

cmd/gc/order_dispatch.go: orderTrackingHistoryIndexLimit stays at the fork's
2048 — it has no config override, so taking upstream's 256 would be an
unescapable behaviour change on a fleet with a documented starvation
incident (vp-cixi.6); settle it upstream via PR gastownhall#3961.
defaultMaxOrderDispatchesPerTick lands at 5, not upstream's 4: 4 is the old
starvation default, and TestOrderDispatchBudgetDefaultRaised guards that
floor. 5 is the value NOTE(vc-wz5.4) itself named.

cmd/gc/cmd_dolt_cleanup.go: protected-port set is now the UNION of the
fork's live-state detection and upstream's recorded rig ports. Dropping the
recorded ports left a port with no attributable live process unprotected in
a DESTRUCTIVE path (SIGKILL + DataDir removal).

Defects found in CLEAN merges (no conflict marker)
--------------------------------------------------
719 files auto-merged; intent-per-hunk covers only the 30 conflicts, and
this fork's failure mode is silent loss in the other 97%. Found by build,
vet and tests:
  - internal/api/server.go: same import merged twice
  - cmd/gc/cmd_nudge.go: upstream's clockless signature wired to the fork's
    clock-using body — did not compile
  - cmd/gc/dolt_project_id_test.go: 4 call sites kept, definitions deleted
  - internal/api/status_warm.go: the fork's wedged-leader escape forgot only
    the outer singleflight, so the retry it starts rejoins upstream's wedged
    inner storeHealthFlight — a no-op for exactly the case it handles
  - cmd/gc/status_provider.go: the fork's stale-while-revalidate path served
    last-known-good without marking the result partial
  - cmd/gc/api_state.go: rig containment compared a canonicalized target
    against a raw city root, rejecting valid rigs

Regenerated, not hand-merged
----------------------------
OpenAPI/schema docs, the dashboard client, and the command census. The
census manifest (productmetrics_command_census.json) is an INPUT, not an
output: unioned by path (upstream 285 + 5 fork-only), with the fork's
"gc provider quota" reallocated 195 -> 199 where it collided with upstream's
runtime-heartbeat, and next_id bumped to 200. Resource-census baselines and
the TESTING.md ledger re-derived from a fresh scan; CI policy hashes
re-derived per pin (the nightly pin lands on the fork's prior value).

Test state
----------
Build and go vet ./... clean. Of the failures on this tree, ~60 are
PRE-EXISTING upstream macOS failures — reproduced on a clean origin/main
worktree, caused by upstream's symlink resolution meeting /var ->
/private/var, invisible to upstream's Linux CI. 8 of 9 genuinely
merge-induced failures are fixed here.

Known red: TestAgentImageRebuildsBDAndGCWithPatchedGRPC. Upstream's new
agent image builds bd from a release URL and cannot consume the fork's
TIME-BOXED commit pin (deps.env, ADR-0026 C5); repinning is not a drop-in
because that commit is not an ancestor of beads v1.1.2. Tracked for WS-2c.
if seq > uint64(math.MaxInt) {
total = math.MaxInt
} else {
total = int(seq)
bourgois added 2 commits July 27, 2026 09:02
Brings #105, #106, #107 and #108 onto the resync branch.

#108 landed while this branch was open and raised the cwd census baseline
284->287 / 43->44 to make CI green. #105 landed too and fixes the same
failure properly, by deleting the three t.Chdir calls in
cmd_config_lint_test.go so the count genuinely returns to 284/43. With both
merged, fork/main held a raised ceiling over a reduced count — inconsistent
in the opposite direction, and against the ledger's own rule that
"reductions must lower this baseline".

Resolved to the correct values:
  - cwd baselines stay at the pre-#108 figures; the calls really were removed
  - catalog assertion is 195, not #108's 194 — the resync restores 4 fork-only
    runnable commands to productmetrics_command_census.json, which is an INPUT
    to the generator
  - TESTING.md ledger block and census.go kept in sync with the above

Verified: internal/testpolicy/resourcecensus and the catalog round-trip both
pass on the merged result.
…oard retirement)

Clean merge, no conflicts. The 4607-file cmd/gc/dashboard tree is now gone
from this branch too, matching upstream.
@bourgois
bourgois merged commit 05cb5f9 into main Jul 27, 2026
22 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.