diff --git a/docs/designs/DECISIONS.md b/docs/designs/DECISIONS.md index da2a1b250..15e103431 100644 --- a/docs/designs/DECISIONS.md +++ b/docs/designs/DECISIONS.md @@ -375,8 +375,8 @@ check enforces the mechanical half. Full rationale: | DL-160 | The desktop app is first-class multi-window: every top-level surface (Bridge, a channel, an agent workspace, Backlog/Done, Settings) is an independently mountable window-scoped view (own DL-127 route, own focus zones + command scope, no sibling region required); compass-native spawns/manages OS windows, this record owns the decomposition; in-window tabs (Linear-style) and split views are deferred to the Beta milestone (RIG-1808), admitted by the same decomposition without rework (D6.1) | Active (Matt, 2026-08-05) | [ux foundation §D6](ui/compass-ux-foundation/design.md#d6--rendering-the-frozen-ia-surface-by-surface-composition) | | DL-184 | Token adoption is a FULL CUTOVER, not the DL-157 incremental strangler: a pre-dogfood codebase has no live users to protect, so the legacy `:root` tier is deleted and every consumer flips to `--cx-*` in one atomically-merged migration (canvas → Night Owl, base.css un-shadowed, state dots recolored, D7 stylelint guard wired directly at error), proven by a Playwright visual-smoke harness Matt reviews | Active (Matt, 2026-08-07) | [DS token cutover](ui/compass-ds-token-cutover/design.md) | | DL-174 | Compass test coverage is a differential-oracle pyramid: every seam carries a hermetic in-memory reference in the default gate plus a `pgtest` suite proving the real Postgres backend obeys the same contract; Postgres is the one live dependency the strategy gates on (D1) | Active (Matt, 2026-08-07) | [test strategy §Decisions](meta/compass-test-strategy/design.md#decisions) | -| DL-175 | The real-Postgres `pgtest` suites run INLINE as a step in the one existing `CI` job — no separate CI job, lane, or moon task; one required check, hermetic moon `test` stays dependency-free via the build tag (D-A1, overruling the internal monorepo ancestor's separate `test-pg` lane; Matt: "trimmed but no extra CI job, it goes in the same existing job") | Active (Matt, 2026-08-07) | [test strategy §A1](meta/compass-test-strategy/design.md#a1--one-ci-job-pgtest-inline-no-separate-lane-amends-the-ancestor-records-d2dl-049) | -| DL-176 | CI Postgres is the shipped GitHub Actions SERVICE CONTAINER — digest-pinned `postgres:16-alpine`, health-gated, URL-form TCP DSN, digest kept equal to `pgtest.go`'s image pin — not the internal monorepo ancestor's per-step embedded `postgresql_18` postmaster, which solved a Woodpecker constraint compass does not have (D-A2) | Active (Matt, 2026-08-07) | [test strategy §A2](meta/compass-test-strategy/design.md#a2--postgres-provisioning-in-ci-the-shipped-service-container-amends-the-ancestor-records-d4) | +| DL-175 | The real-Postgres `pgtest` suites run INLINE as a step in the one existing `CI` job — no separate CI job, lane, or moon task; one required check, hermetic moon `test` stays dependency-free via the build tag (D-A1, overruling the ancestor record's separate `test-pg` lane; Matt: "trimmed but no extra CI job, it goes in the same existing job") | Active (Matt, 2026-08-07) | [test strategy §A1](meta/compass-test-strategy/design.md#a1--one-ci-job-pgtest-inline-no-separate-lane-amends-the-ancestor-records-d2dl-049) | +| DL-176 | CI Postgres is the shipped GitHub Actions SERVICE CONTAINER — digest-pinned `postgres:16-alpine`, health-gated, URL-form TCP DSN, digest kept equal to `pgtest.go`'s image pin — not the ancestor record's per-step embedded `postgresql_18` postmaster, which solved a Woodpecker constraint compass does not have (D-A2) | Active (Matt, 2026-08-07) | [test strategy §A2](meta/compass-test-strategy/design.md#a2--postgres-provisioning-in-ci-the-shipped-service-container-amends-the-ancestor-records-d4) | | DL-177 | Require-live teeth live in the harness: `COMPASS_REQUIRE_LIVE=1` (set by the CI pgtest step) turns `RequireDSN`'s no-DSN skip path into `t.Fatal` at the one policy seam every suite passes through — layered with, not replacing, the workflow-level skipped-suite assert step (D2/S1) | Active (Matt, 2026-08-07) | [test strategy §Decisions](meta/compass-test-strategy/design.md#decisions) | | DL-178 | Whole-flow scope is one thin composing test: `runner.Dial` over TLS with a real minted Runner-kind token through the production `RunnerService` door built by `buildNetworkServer` — the one seam no suite on `main` composes; a full smoke rebuild is rejected as re-describing shipped work (D3/S2) | Active (Matt, 2026-08-07) | [test strategy §Decisions](meta/compass-test-strategy/design.md#decisions) | | DL-179 | The `podman`-tagged surface (runtime lifecycle suites and the `go/e2e/` dogfood legs) stays skip-if-absent and out of this record's gate; its CI promotion is owned by the dogfood-e2e/infra lane (D4) | Active (Matt, 2026-08-07) | [test strategy §Decisions](meta/compass-test-strategy/design.md#decisions) | @@ -411,7 +411,7 @@ check enforces the mechanical half. Full rationale: | ID | Decision | Status | Record | | --- | --- | --- | --- | | DL-164 | **Start-half (Active):** starting an agent is the lifecycle operation (`startAgent` → composite `SpawnAgent`), which rejects when the target agent already holds a live session; an agent owns multiple cards, so the `SessionBinding` map is keyed by card (`workstreamId` = `Issue.id`), not agent, inside one container / one live session. **Add-half superseded by DL-185 (Matt, 2026-08-07):** the manual add-a-workstream board mutation (`addWorkstream`) and UI-side agent creation (`CommsService.CreateAgent`) are dropped. | Superseded by DL-253 (Matt, 2026-08-25) | [spawn control §Control flow](agent/compass-spawn-control/design.md#control-flow-start-an-agent-spawnagent) | -| DL-165 | The Bridge spawn-control lane builds live-wired against the shipped `AppStoreOptions` client seam (real RPC awaits when clients are present, surfaced offline refusals when not — the shipped `stopAgent` shape), superseding the internal monorepo's walking-skeleton posture whose premises (no injection seam, no live streams, stub stop) no longer hold in compass; parked for Matt's ratification (OQ-P1) | Superseded by DL-253 (Matt, 2026-08-25) | [spawn control §Posture](agent/compass-spawn-control/design.md#posture-live-wired-from-the-start-amends-the-walking-skeleton-posture--dl-165) | +| DL-165 | The Bridge spawn-control lane builds live-wired against the shipped `AppStoreOptions` client seam (real RPC awaits when clients are present, surfaced offline refusals when not — the shipped `stopAgent` shape), superseding the ancestor record's walking-skeleton posture whose premises (no injection seam, no live streams, stub stop) no longer hold in compass; parked for Matt's ratification (OQ-P1) | Superseded by DL-253 (Matt, 2026-08-25) | [spawn control §Posture](agent/compass-spawn-control/design.md#posture-live-wired-from-the-start-amends-the-walking-skeleton-posture--dl-165) | | DL-166 | Spawn is one server-side composite `CompassService.SpawnAgent` RPC orchestrating Provision→Start under a single `client_request_id` with server-owned end-to-end dedup (retry returns the same `session_id`, no second container) and a pre-Provision reject-on-live short-circuit ordered after the dedup-join lookup; client-orchestrated two-call flow rejected | Superseded by DL-253 (Matt, 2026-08-25) | [spawn control §DL-166](agent/compass-spawn-control/design.md#dl-166-prior-decision--server-side-composite-spawnagent) | | DL-167 | `AgentSessionStatus` gains `agent_account_id`, populated at every construction site (board projection, SubscribeEvents push synthesis, Runner-side Status) — a join onto the live hub binding Server-side and new Runner-local account carriage (AgentSpec→handle→liveSession), with the terminal STOPPED status resolving its account before `unbindSession`; makes the UI reconcile full-fleet within the binding's live scope and is the prerequisite of the reject-on-live scan | Superseded by DL-253 (Matt, 2026-08-25) | [spawn control §DL-167](agent/compass-spawn-control/design.md#dl-167-prior-decision--agent_account_id-on-agentsessionstatus) | | DL-168 | A stopped card stays restartable: the card's start affordance shows on no-binding OR a `stopped` binding (agent not live), the exact predicate the `startAgent` guard reads, and restart mints a fresh binding — a no-binding-only affordance would strand every stopped card since `applyStopped` keeps the binding | Superseded by DL-253 (Matt, 2026-08-25) | [spawn control §DL-168](agent/compass-spawn-control/design.md#dl-168-prior-decision--a-stopped-card-stays-restartable) | diff --git a/docs/designs/agent/compass-forks-reversal/design.md b/docs/designs/agent/compass-forks-reversal/design.md index 419578b6d..ab57b0995 100644 --- a/docs/designs/agent/compass-forks-reversal/design.md +++ b/docs/designs/agent/compass-forks-reversal/design.md @@ -24,7 +24,7 @@ machinery that existed only to carry them. - **FROZEN (Matt, 2026-08-19): shared `RigelBuild/{devenv,nix2container,oh-my-pi}` repos + combined patch work.** Compass consumes the shared canonical fork repos — one canonical fork per upstream. Sealed patches useful to both the - internal monorepo and compass land in the shared repos, never duplicated. Do + fleet and compass land in the shared repos, never duplicated. Do not relitigate; tasks execute it. - **Shared-repo patch ownership is disjoint (forge coordination, 2026-08-19).** On the shared canonical repos each lane owns a disjoint patch set: forge owns @@ -274,7 +274,7 @@ this record does not require it. repos: one fork per upstream, patch work combined. Two forks of the same upstream would duplicate the sealed patches and re-create the divergence this reversal exists to end. Frozen; not relitigated here. -- **Defer until the internal monorepo's reversal fully lands** — rejected. Only +- **Defer until the fleet's reversal fully lands** — rejected. Only the nix2container lane has a genuine cross-repo dependency (the shared nix-DB-drop fix); serializing the whole reversal behind that completion keeps 7424 vendored files (and @@ -576,7 +576,7 @@ Interfaces: `devenv.nix:476`, `ci.yml:812`, `publish-agent-image.yml:139,160`, `tools/agent-image-env-gate/index.ts:100,118`) — **LOAD-BEARING, but narrower than first framed.** The *flake-input* half is - settled: the internal monorepo's prior art froze the nix-flake-input class as + settled: the prior art froze the nix-flake-input class as `github:RigelBuild/` pinned **via lockfile** (the deliberate default plus a whole-repo narHash fix), so compass's one flake-input consumer, `agent-image/devenv.lock`, converges on that with no reason to diverge. What @@ -598,7 +598,7 @@ Interfaces: has no prior-art analog. The coherent alternative is the literal style — keep the `github:…/` literals but have L1/L2 add a CI assert that each literal's rev equals the corresponding `devenv.lock` rev, named in the lane - gates; this mirrors the internal monorepo's terraform-provider class, a pinned + gates; this mirrors the prior art's terraform-provider class, a pinned **non-flake** consumption (tagged GitHub Release + committed sha256 manifest, verified at build time) — the prior-art shape for "pin and verify a path not resolved through a lockfile." This is the record's one genuine fork — Matt's diff --git a/docs/designs/agent/compass-forks-reversal/oq-resolutions.md b/docs/designs/agent/compass-forks-reversal/oq-resolutions.md index 62bd7e56b..f894fb007 100644 --- a/docs/designs/agent/compass-forks-reversal/oq-resolutions.md +++ b/docs/designs/agent/compass-forks-reversal/oq-resolutions.md @@ -59,7 +59,7 @@ Impact on **L3** (`design.md:437-490`): **Ruled (Matt, 2026-08-21): install the fork tools as pinned packages; do not keep raw `nix run` literals.** The flake-input half of OQ2 was already settled -(converge on the internal monorepo's lockfile-pinned `github:RigelBuild/` default). For +(converge on the prior art's lockfile-pinned `github:RigelBuild/` default). For the raw-CLI half — the six sites that invoke a fork CLI with `nix run` and so bypass `devenv.lock` — the resolution is to **install** the two fork tools (devenv's patched CLI carrying compass's container module, and diff --git a/docs/designs/agent/compass-spawn-control/design.md b/docs/designs/agent/compass-spawn-control/design.md index c172eafc1..916424dae 100644 --- a/docs/designs/agent/compass-spawn-control/design.md +++ b/docs/designs/agent/compass-spawn-control/design.md @@ -5,9 +5,9 @@ Status: Active This record freezes on merge; later changes supersede by citation, never rewrite. -Ported from the internal monorepo's prior record with +Ported from a prior ancestor record with Matt-ruled amendments, re-grounded against the current compass tree -(`main@origin`, 2026-08-07). The internal monorepo's prior decisions are +(`main@origin`, 2026-08-07). The ancestor record's prior decisions are re-expressed here as DL-164..DL-171. > **Amendment (DL-185, Matt 2026-08-07):** the manual add-a-workstream / @@ -36,9 +36,9 @@ control that starts a workstream agent (provision + start, with an optional initial prompt) from the board, and hardens the existing stop into the same control model. -*(Port note — superseding the internal monorepo's premise: the source record +*(Port note — superseding the ancestor record's premise: the source record described stop as a no-op stub, `const stopAgent = () => {};`. That was true of -the internal monorepo's snapshot; compass has since shipped the real +the ancestor record's snapshot; compass has since shipped the real `stopAgent`, so every stop-side task below hardens or extends shipped behavior rather than replacing a stub.)* @@ -69,7 +69,7 @@ were consequences of the now-shipped change.)* ### Posture: live-wired from the start (amends the walking-skeleton posture — DL-165) -The internal monorepo's prior record froze a walking-skeleton posture (its +The ancestor record froze a walking-skeleton posture (its OQ-A) on three facts of that tree: `createAppStore` took no arguments, `SubscribeEvents` had zero UI consumers, and no live client seam existed. **All three are false in compass today**: `createAppStore(options: @@ -244,7 +244,7 @@ lifecycle affordance is start/stop on an existing card: incidental property DL-170 exists to stop leaning on). The check **must not** be sourced from Server-side in-memory state. - Compass now carries the reverse index the internal monorepo lacked — + Compass now carries the reverse index the ancestor record lacked — `Hub.SessionForAccount` (`relay_comms.go:157-171`, over `accountSessions`) — but it is still **live-scoped and cleared on every Runner re-enroll** (`hub.go:707-711`, pinned by @@ -305,7 +305,7 @@ agent-keyed map would bleed one card's pill onto siblings). The binding carries its `agentAccountId` for the RPC. Bindings are store-internal wire-lifecycle bookkeeping, not a fixture-shape change: the compass board's `Issue` (`stub-data.ts:202-240`) and `Agent` shapes stay frozen. -*(Terminology port note: the internal monorepo's UI had a `Workstream` type; the compass +*(Terminology port note: the ancestor record's UI had a `Workstream` type; the compass board renders `Issue` cards (`board.ts:39-56`, `components/IssueCard.tsx`) and has no `Workstream` symbol. This record keeps "workstream" for the concept — an issue promoted to a unit of work — and `workstreamId` binds to @@ -355,7 +355,7 @@ equally. ### Alternatives considered -- **Walking-skeleton-first** (the internal monorepo's prior ruling, Matt-ruled there): build the +- **Walking-skeleton-first** (the prior, superseded ruling): build the control UX as fixture mutations, wire later in a stacked lane. Superseded by the shipped compass store: the injection seam and live streams the skeleton waited on already exist (`store.ts:551`, `:667`, `:897-932`), and @@ -370,7 +370,7 @@ equally. session started by another client or surviving a refresh can't reconcile. Rejected (Matt ruled the wire attribution, DL-167). - **Server-side reject-on-live check over `SessionForAccount`**: compass now - has the reverse map the internal monorepo lacked (`relay_comms.go:157-171`), but it fails + has the reverse map the ancestor record lacked (`relay_comms.go:157-171`), but it fails open after a Runner re-enroll (`hub.go:707-711`); the Runner scan is authoritative. Rejected — the Control-flow section carries the argument. - **Browser `confirm()` for stop**: rejected — blocks the event loop, @@ -761,7 +761,7 @@ the compass service-owner. Independent of the UI tasks, so no freeze block. (`compass.proto:59`). Request = `agent_account_id`=1, `initial_prompt`=2, `client_request_id`=3; Response = `session_id`=1, `container_name`=2. Server orchestrates the existing RunnerHub `Provision` then `Start` - (`runnerhub/commands.go:40-88`). *(The internal monorepo's T0 additionally relaxed the + (`runnerhub/commands.go:40-88`). *(The ancestor record's T0 additionally relaxed the repo requirement in `runner/spec.go` and guarded `cloneRepo` — all shipped in compass under RIG-1527; `BuildSpec` at `spec.go:76-88` already builds a repo-less spec. Dropped from scope.)* @@ -870,11 +870,11 @@ the compass service-owner. Independent of the UI tasks, so no freeze block. ## Resolved decisions -The internal monorepo's prior record resolved eight load-bearing forks with +An ancestor record resolved eight load-bearing forks with Matt and ratified two deferrals. This port re-expresses them as compass ledger -rows DL-164..DL-171, plus one port-amendment row (DL-165). The prior rulings' -full arguments live in the source record; the compass-grounded substance is -folded into the sections above. Mapping: +rows DL-164..DL-171, plus one port-amendment row (DL-165). Each row below +carries its own compass-grounded argument; the sections above hold the +substance. Mapping: ### DL-164 (prior decision) — start-an-agent; multiple cards per agent; reject-on-live diff --git a/docs/designs/infra/ci/compass-local-dev/design.md b/docs/designs/infra/ci/compass-local-dev/design.md index e2a3d718e..ebc0dcb65 100644 --- a/docs/designs/infra/ci/compass-local-dev/design.md +++ b/docs/designs/infra/ci/compass-local-dev/design.md @@ -38,8 +38,8 @@ This record therefore only documents the hazard and the interim workaround; it designs no compass-side gate change. Local dev is the developer's own box — not a deployed `main` or `preview` -environment. Those deployed environments are internal infrastructure, defined -in the private infrastructure design repo, and are not redesigned here. The +environment. Those deployed environments are a managed-plane concern, out of +tree, and are not redesigned here. The repo-facing PR-validation surface (the expanded e2e harness and its results-on-PR) is Record B (`docs/designs/platform/compass-pr-validation/design.md`). diff --git a/docs/designs/infra/ci/compass-pr-validation/design.md b/docs/designs/infra/ci/compass-pr-validation/design.md index db7fcafd8..101c4d1a9 100644 --- a/docs/designs/infra/ci/compass-pr-validation/design.md +++ b/docs/designs/infra/ci/compass-pr-validation/design.md @@ -10,9 +10,9 @@ Status: Draft > (`docs/designs/platform/compass-dogfood-e2e/design.md`, RIG-1681, H1-H8). > Local-dev / gate mechanics are a separate record > (`docs/designs/platform/compass-local-dev/design.md`). UI-visible changes -> are additionally previewable in an isolated PR-preview environment defined -> in the private infrastructure design repo; that environment's hosting, -> deploy workflow, and selection mechanism live in that repo's records, not +> are additionally previewable in an isolated PR-preview environment, which is +> out of tree: that environment's hosting, deploy workflow, and selection +> mechanism are a managed-plane concern, out of scope > here — this record owns only the repo-side validation surfaces, including > the configurable UI build the preview consumes. @@ -165,8 +165,8 @@ format/lint/test. - **Scripts over bash.** Any summary/capture logic beyond a one-liner is a bun/TS tool under `tools/`, not shell in YAML. - **De-leak.** This is a public repo. The isolated PR-preview environment is - referred to only generically — "an isolated PR-preview environment defined - in the private infrastructure design repo". No internal hostnames, + referred to only generically — as "an isolated PR-preview environment", out + of tree. No internal hostnames, addresses, ports, service/unit names, or private repo names appear in this record or in anything it produces (workflow YAML, skill text, PR comments). - **Sequencing floor.** Tasks that extend the CI gate land AFTER #256 @@ -190,7 +190,7 @@ A2 and the Plan has no B2. A general compass-ui capability: make the UI bundle buildable against ANY configured door URL + bearer via build-time env — the isolated PR-preview -environment (defined in the private infrastructure design repo) consumes this +environment, which is out of tree, consumes this capability; local/dev targets can too. No code change to connection resolution is expected — `resolveConnection` already requires a base URL and normalizes an absent token to a no-auth client diff --git a/docs/designs/infra/release/compass-release-bundling/design.md b/docs/designs/infra/release/compass-release-bundling/design.md index ab91bce00..0f8e90516 100644 --- a/docs/designs/infra/release/compass-release-bundling/design.md +++ b/docs/designs/infra/release/compass-release-bundling/design.md @@ -4,7 +4,7 @@ Status: Active > **Design record.** Citations name paths in `compass` = RigelBuild/compass at > `c25ce94f` (this repo, main at authoring). Line numbers drift as code evolves; -> resolve against that revision. This is a public repo: the internal CD monorepo +> resolve against that revision. This is a public repo: the CD pipeline elsewhere in the fleet > that consumes these artifacts is referred to by role, never by name, path, PR, > or quoted source. > @@ -40,8 +40,8 @@ rebuilding from source. owns the surface: GitHub Releases attach to a GitHub repo, and the public `RigelBuild/compass` repo is where the release artifacts' sources live, where the existing GHA publish lane runs, and where an in-repo `GITHUB_TOKEN` can -create Releases with zero new credentials. The internal CD monorepo is -Woodpecker-driven and would need a cross-repo PAT to write Releases anywhere +create Releases with zero new credentials. A Woodpecker-driven CD pipeline +elsewhere in the fleet would need a cross-repo PAT to write Releases anywhere (§Fork 1). ## Approach @@ -54,9 +54,9 @@ Four design forks, each with options, a recommendation, and tradeoffs. - **(a) compass repo, GitHub Actions** — a new `.github/workflows/release.yml` beside the existing publish lane. -- **(b) the internal CD monorepo, Woodpecker CD** — a push→main CD job like its +- **(b) a Woodpecker CD pipeline elsewhere in the fleet** — a push→main CD job like its image-publish lane, writing Releases on some GitHub repo via a PAT. -- **(c) hybrid** — compass GHA creates the Release; the internal CD appends its +- **(c) hybrid** — compass GHA creates the Release; a fleet CD pipeline appends its own assets to it. **Recommendation: (a) compass GHA.** Grounds: @@ -82,7 +82,7 @@ Four design forks, each with options, a recommendation, and tradeoffs. ``` A Release must attach to the repo whose commits it versions; releasing - compass artifacts on the internal monorepo would version them against the + compass artifacts on a different repo in the fleet would version them against the wrong history. 2. *The GHA precedent already exists and is the right shape.* The compass repo @@ -109,17 +109,17 @@ Four design forks, each with options, a recommendation, and tradeoffs. a *new* repo-scoped PAT to provision, rotate, and fork-gate (§Fork 4). 4. *The public repo is the consumption point.* `RigelBuild/compass` is public, - so Release assets download anonymously — which is exactly what the internal - config-publish consumer needs (§Fork 3). The internal monorepo is not the + so Release assets download anonymously — which is exactly what the + config-publish consumer needs (§Fork 3). No out-of-tree repo offers that public surface. -**Tradeoffs accepted:** (b) would co-locate the Release cut with the internal -CD's other push→main GHCR legs, keeping one CD brain; but none of those legs +**Tradeoffs accepted:** (b) would co-locate the Release cut with a fleet CD +pipeline's other push→main GHCR legs, keeping one CD brain; but none of those legs produce compass artifacts, and the cross-repo PAT + Woodpecker↔GitHub seam outweighs the co-location. (c) hybrid is -deferred as non-load-bearing: today no internally-built artifact belongs in a -compass Release (the internal CD's images are CI step images, not product -artifacts). If that changes, the internal CD can append assets to an existing +deferred as non-load-bearing: today no fleet-built artifact belongs in a +compass Release (that pipeline's images are CI step images, not product +artifacts). If that changes, a fleet CD pipeline can append assets to an existing Release with a narrowly-scoped PAT without reopening this record. ### Fork 2: what artifacts, and how each is produced @@ -424,7 +424,7 @@ ancestry guard; documented in the workflow header. **T4 — Consumer cutover: the internal config-publish job downloads the Release asset.** Sequenced strictly AFTER the in-flight RIG-2025 fixes (ci-go routing + module rename), which land now and independently — T4 is the later revert of that -routing, not its substitute. In the internal CD monorepo, two reviewed steps: +routing, not its substitute. In the fleet's CD pipeline, two reviewed steps: (1) **pin advance** — move the pinned-rev constant to the first released sha (no Release covers the current pin `a61d0caf` retroactively); (2) replace the `go install` provisioning with a download-and-verify of @@ -445,7 +445,7 @@ lane; append the DECISIONS.md ledger rows for the choices in Forks 1-4 and the OQ-7 semver policy. Ordering: T1 → T2 fold into one PR if small; T3 independent after T1; T4 lands -in the internal CD monorepo only after the RIG-2025 fixes are green on main AND +in the fleet's CD pipeline only after the RIG-2025 fixes are green on main AND T1 has minted a Release at the advanced pin (the pin advance is T4 step 1); T5 with the record freeze. diff --git a/docs/designs/meta/compass-test-strategy/design.md b/docs/designs/meta/compass-test-strategy/design.md index 3c641f950..9bbe6bc1d 100644 --- a/docs/designs/meta/compass-test-strategy/design.md +++ b/docs/designs/meta/compass-test-strategy/design.md @@ -2,7 +2,7 @@ Status: Draft -> **Design record** — ported from the internal monorepo's frozen +> **Design record** — ported from a frozen ancestor > test-strategy record into compass, with Matt-ruled amendments grounding it > against the shipped compass CI. Ledgered as DL-174..DL-181. @@ -22,9 +22,9 @@ remaining unexecuted deliverables: in-harness require-live teeth, one thin client↔server contract lane (a follow-up owned conceptually by the dogfood-e2e harness record). -**Provenance and amendments.** This is a port of the internal monorepo's -frozen test-strategy record, which designed the strategy against its -Woodpecker/moon CI before compass forked. Two of its decisions are amended by +**Provenance and amendments.** This is a port of a frozen ancestor +test-strategy record, which designed the strategy against a Woodpecker/moon CI +before compass forked. Two of its decisions are amended by Matt's ruling to match compass's shipped reality (see D-A1/D-A2 below): the ancestor record mandated a separate `compass-go:test-pg` CI lane — compass runs the pgtest suites **inline in the one existing CI job**, with no extra job — @@ -47,7 +47,7 @@ and contract testing — the layered pyramid underneath it. Neither the `pgtest` nor the `podman` suites compile into it. **The live-Postgres surface runs inline in CI — shipped.** Unlike the -internal monorepo's ancestor record (where no CI lane ran the pgtest suites at all), compass CI already +ancestor record (where no CI lane ran the pgtest suites at all), compass CI already runs them: `.github/workflows/ci.yml` attaches a Postgres **service container** to the one `CI` job (`ci.yml:108-127`) and, after the moon battery, a folded-in step runs @@ -214,7 +214,7 @@ here. ### A4 — Client-transport contract lane: a follow-up owned with dogfood-e2e -The internal monorepo's ancestor F5 lane — a `bun test` suite spawning the real `compass-server` +The ancestor record's F5 lane — a `bun test` suite spawning the real `compass-server` binary and driving the generated TS client against it over a loopback endpoint — remains a real gap (mock-fetch on the TS side, in-process servers on the Go side; the two generated stubs never meet a real wire in any gate). diff --git a/docs/designs/repo/compass-drop-proto.md b/docs/designs/repo/compass-drop-proto.md index 291a2aeee..429c18e28 100644 --- a/docs/designs/repo/compass-drop-proto.md +++ b/docs/designs/repo/compass-drop-proto.md @@ -2,10 +2,10 @@ Status: Draft -Tracker: RIG-1983. Template: the internal monorepo's proto-drop — +Tracker: RIG-1983. Template: the proto-drop prior art — "refactor(ci): drop proto; pin bun/node/moon via nix, go via go-overlay". Compass diverges from that template wherever the CI substrate does: the -internal monorepo runs the internal Woodpecker CI/CD against a nix-built CI +prior art runs a Woodpecker CI/CD pipeline against a nix-built CI step image; compass runs GitHub Actions with `setup-*` actions fed by a `.prototools`-parsing pins step. Every decision below is grounded in this clone. @@ -24,7 +24,7 @@ formats, and a parity gate built around the asymmetry. `devenv.nix:9-13`: > ``` Drop proto entirely and make devenv/nix the single owner of every toolchain, -as the internal monorepo already did — one pin format, one activation path, one parity method, +as prior art already did — one pin format, one activation path, one parity method, and no `proto` shim quirks (the `PROTO_REPORTER` NDJSON-banner workaround, `devenv.nix:90-108`, exists only because proto's shims corrupt `go list` output in agent shells). @@ -38,7 +38,7 @@ monorepo's shape, relocated to compass's existing toolchain-gate directory: - `bun.nix`, `node.nix`, `moon.nix` — `rec { version = "…"; srcs = { "" = { url, hash }; }; }` vendored-release pins: each pins a `version` plus a `srcs` set of - per-system release URL + hash, mirroring the internal monorepo's file shape. + per-system release URL + hash, mirroring the prior-art file shape. Compass pins stay at today's versions — this is a pure manager cutover, no version bumps: bun `1.3.13`, node `24.18.0`, moon `2.4.2` (`.prototools:6-8`: `bun = "1.3.13"` / `node = "24.18.0"` / `moon = "2.4.2"`). Systems covered: @@ -53,7 +53,7 @@ monorepo's shape, relocated to compass's existing toolchain-gate directory: `purpleclay/go-overlay@main:manifests/go/`). A sibling `tools/toolchain/toolchain-tools.nix` builds bun/node/moon -derivations from the pin files (the internal monorepo's equivalent +derivations from the pin files (the prior-art equivalent tool-builder role): fetch the release artifact for `pkgs.stdenv.system`, unpack, install `bin/`. Both the dev shell (`devenv.nix`) and CI (via `gate-tools.nix`, below) import this one file, so they cannot drift. @@ -97,11 +97,11 @@ with NO default (`gate-tools.nix:25`), so a bare file is restructured to `{ attrs ? [ ] }:` — `langs` never consumes `attrs` (the language set is closed), so phase 1 below needs no `--arg attrs`. -**The bootstrap ordering constraint (compass-specific, absent in the internal monorepo):** +**The bootstrap ordering constraint (compass-specific, absent in the prior art):** today CI needs bun *before* the nix step, because that step runs `bun tools/toolchain/parity.ts --print-nix-attrs` to derive the attr list -(`ci.yml:242`) — and bun currently arrives from setup-bun. The internal -monorepo never hit this: its Woodpecker image pre-bakes everything. The fix is a two-phase nix +(`ci.yml:242`) — and bun currently arrives from setup-bun. Prior art +never hit this: a pre-baked Woodpecker image carries everything. The fix is a two-phase nix bootstrap: phase 1 `nix build`s the fixed `langs` output (no attr parse needed — the language set is closed, and `attrs` now has a default) and puts its `bin/` on PATH; phase 2 runs the existing `--print-nix-attrs` flow with @@ -120,7 +120,7 @@ miss; both phases hit the substituters already configured ### Fork 2 — Go: adopt the purpleclay/go-overlay input -**Decision: go-overlay**, the internal monorepo's choice (it version-selects +**Decision: go-overlay**, the prior-art choice (it version-selects `go-overlay.packages.${pkgs.stdenv.system}` for the exact go pin in both the dev shell and the CI step image). Compass adds the input to `devenv.yaml` (which today declares nixpkgs as "the only input this shell needs" precisely @@ -135,7 +135,7 @@ shell can't run a GitHub action; today it gets Go from `proto install`, `devenv.nix:161`). Why not nixpkgs' `go`: the pin must be exact and promptly bumpable for security releases (the floor-policy comment, `.prototools:9-12`), and a rolling nixpkgs controls neither. go-overlay is -purpose-built for exact Go pins, proven in the internal monorepo, and its manifest already +purpose-built for exact Go pins, proven prior art, and its manifest already carries `1.26.6`. One constraint is load-bearing and open: the dev shell's go and the parity @@ -231,7 +231,7 @@ Grounded in the current file, the complete delta set: **Add:** - `devenv.yaml`: the `go-overlay` input (`url: github:purpleclay/go-overlay`, - `inputs.nixpkgs.follows: nixpkgs` — the internal monorepo's exact block) and a comment + `inputs.nixpkgs.follows: nixpkgs` — the prior art's exact block) and a comment update (`devenv.yaml:3-5` currently: "the toolchain is nixpkgs derivations plus the proto-managed runtimes (.prototools)"). `devenv.lock` gains the input's nodes. @@ -298,7 +298,7 @@ protobuf/`proto/` schema hits are unrelated and excluded): | `tools/toolchain/gate-tools.nix` | — | gains `langs` output | | `.moon/workspace.yml:4-7` | "bun/node/go/moon via proto … keeps .prototools the single version source" | reword | | `go/go.mod:10-12` | floor-policy comment | re-point at `versions/go.nix` | -| `go/moon.yml:11-14` | proto clause + stale `ci/ci-toolchain.nix` (leftover from the internal monorepo's layout; no `ci/` dir in compass) | reword whole provenance sentence | +| `go/moon.yml:11-14` | proto clause + stale `ci/ci-toolchain.nix` (leftover from a prior-art layout; no `ci/` dir in compass) | reword whole provenance sentence | | `package.json:5` | "proto (.prototools) owns the bun/node toolchains" | reword | | `AGENTS.md:9-11` | "The toolchain is proto … plus devenv" | reword | | `CONTRIBUTING.md:8-18` | proto install path incl. the no-nix route | reword (no-nix route: install the pinned versions by hand from `versions/*.nix`) | @@ -331,8 +331,8 @@ the runtime cost. One less file shape, but forfeits exact pinning: moon "nixpkgs … lags" (`.prototools:4-5`), and the agent image's bun assert exists because nixpkgs -bun drifts (`agent-image/toolchain.nix:51-55`). Rejected; the internal -monorepo reached the same verdict (its versions/ files are the artifact of that rejection). +bun drifts (`agent-image/toolchain.nix:51-55`). Rejected; prior art +reached the same verdict (its versions/ files are the artifact of that rejection). ### Retire the parity gate @@ -352,7 +352,7 @@ detection retain value independent of CI's install path. `tools/toolchain/versions/go.nix`. 3. **GitHub Actions substrate, not Woodpecker.** No CI step image exists or is introduced; everything lands in `.github/workflows/ci.yml` steps. - The internal monorepo's toolchain layout is a template only. + The prior-art toolchain layout is a template only. 4. **Pure manager cutover — zero version bumps.** bun `1.3.13`, node `24.18.0`, moon `2.4.2`, go `1.26.6` before and after. 5. **Frozen design records are not edited** (see fork 5 table footnote). @@ -432,7 +432,7 @@ root:markdownlint` green. (`rec { version; srcs..{url,hash}; }`; go.nix version-only) and `tools/toolchain/toolchain-tools.nix` (`{ pkgs }: { bun; node; moon; }`, each a derivation with `bin/`). Consumes: release URLs/hashes for bun - 1.3.13, node 24.18.0, moon 2.4.2 (the internal monorepo's `versions/*.nix` + 1.3.13, node 24.18.0, moon 2.4.2 (the prior-art `versions/*.nix` as the shape reference). - [ ] **T2: devenv cutover** *(one landing unit with T4)* Interfaces: consumes T1; edits `devenv.yaml` (go-overlay input, OQ2 → A), @@ -470,14 +470,14 @@ root:markdownlint` green. ## Open Questions 1. **Pin-bump automation (non-load-bearing — deferred).** Compass has no - renovate (the internal monorepo added four `custom.regex` managers there); dependabot + renovate (prior art carries four `custom.regex` managers for it); dependabot covers only github-actions/bun-lockfile/gomod (`.github/dependabot.yml:12,28,40`) and has no nix ecosystem, so bun/node/moon/go pin bumps become manual PRs. This is no regression — `.prototools` bumps are manual today (RIG-1982 is one) — and the design is correct without automation. Recommendation: accept manual bumps now; - revisit if/when compass adopts a renovate config, reusing the internal - monorepo's regex managers re-targeted at `tools/toolchain/versions/*.nix`. + revisit if/when compass adopts a renovate config, reusing the prior-art + regex managers re-targeted at `tools/toolchain/versions/*.nix`. 2. **RESOLVED (Matt, design PR #300) — go derivation single-sourcing: A, both sides consume go-overlay.** The dev shell's go and the parity gate's `langs` go MUST be the same derivation: `verifyStorePath` compares the @@ -489,7 +489,7 @@ root:markdownlint` green. (as an earlier draft claimed): triggering it forces devenv.yaml/devenv.nix (T2) to also drop the go-overlay input and vendor go — a cross-fork change. **Decision — A: both routes read go-overlay** at the devenv.lock-pinned - rev, keeping fork 2 and the internal monorepo's shape. The two routes use *different, + rev, keeping fork 2 and the prior-art shape. The two routes use *different, asymmetric* selectors against the same upstream — the asymmetry is load-bearing (verified against `purpleclay/go-overlay@main`): - devenv.nix (flake route) selects the flake-only package attribute diff --git a/docs/designs/repo/compass-eng-docs/design.md b/docs/designs/repo/compass-eng-docs/design.md index 66d9a9083..6d04e0ea6 100644 --- a/docs/designs/repo/compass-eng-docs/design.md +++ b/docs/designs/repo/compass-eng-docs/design.md @@ -23,8 +23,8 @@ authored in `RigelBuild/compass` at ## Problem / Intent -The Compass design corpus (39 records + the living spec) lives in a PRIVATE -internal monorepo, invisible to the public the product is being +The Compass design corpus (39 records + the living spec) lives out of tree, +invisible to the public the product is being built in the open for; the public `RigelBuild/compass` repo has no docsite and no `docs/designs/` tree (only `docs/architecture/build-and-ci.md`, verified this session). Move the Compass records + specs here and publish them on a diff --git a/docs/designs/repo/compass-renovate-migration.md b/docs/designs/repo/compass-renovate-migration.md index 56fad201f..53ac50b31 100644 --- a/docs/designs/repo/compass-renovate-migration.md +++ b/docs/designs/repo/compass-renovate-migration.md @@ -7,9 +7,9 @@ Status: Draft Compass runs GitHub Dependabot for its three ecosystems (`.github/dependabot.yml`: github-actions at `/`, bun at `/`, gomod at `/go`, all weekly single-group). Matt wants Dependabot off — it carries hidden GitHub-billed features, and the fleet -should run ONE dependency manager, not two. The internal monorepo already runs -self-hosted Renovate, proven through the catalog, devenv-nixpkgs, and toolchain-pin -lockstep machinery. Migrate compass onto the same Renovate, adapted to compass's +should run ONE dependency manager, not two. Self-hosted Renovate is proven prior +art in the fleet, through the catalog, devenv-nixpkgs, and toolchain-pin +lockstep machinery. Compass adopts that same Renovate, adapted to compass's layout — with the hard constraint that it runs in **GitHub Actions** (compass has no Woodpecker; all its CI is GHA). The repo is pre-prepped: the design-ledger gate already exempts `renovate/` branches (`tools/design-ledger-gate/index.ts:87`, @@ -24,9 +24,9 @@ with `osvVulnerabilityAlerts: true` replacing the coverage. - **NEVER `vulnerabilityAlerts: { enabled: true }`** — a vuln fix injects a packageRule with `force.enabled` truthy, which clears `skipReason` and CANCELS - the fork fence (the internal monorepo's Renovate config). Use + the fork fence (a known Renovate-config hazard). Use `osvVulnerabilityAlerts: true` only. `config.test.ts` must guard both facts, - as the internal monorepo's does. + as the prior art does. - **`minimumReleaseAge: "5 days"` + `internalChecksFilter: "strict"`** — consistent with compass's `bunfig.toml:6` `minimumReleaseAge = 432000` (5 days). Mirror bunfig's exact-name exemptions (`bunfig.toml:20-24`: @@ -45,16 +45,16 @@ with `osvVulnerabilityAlerts: true` replacing the coverage. (root `forks/`, not a nested location). A packageRule `matchFileNames: ["forks/*/**"], enabled: false` (a scoped disable, never `ignorePaths`, which replaces Renovate's safe defaults, mirroring the - internal monorepo's prior art). + prior art). - **Toolchain pins auto-open solo branches** — Matt's standing ruling: every - toolchain bump (bun/node/moon/go) opens its own un-grouped PR (ported from - the internal monorepo's prior art). + toolchain bump (bun/node/moon/go) opens its own un-grouped PR (following the + prior art). - **Every postUpgradeTasks command in bot-config `allowedCommands`, `^…$`-anchored** — a repo config can't self-authorize a command; `config.test.ts` - pins the two lists together (as the internal monorepo's does). + pins the two lists together (as the prior art does). - **TypeScript `<7` cap (RIG-1867)** — compass's catalog pins `"typescript": "^6.0.3"` (`package.json:21`), so the Project Corsa cap applies: - TS 7.0 ships no stable programmatic API (ported from the internal monorepo). + TS 7.0 ships no stable programmatic API (following the prior art). - **Timezone/schedule alignment (RIG-1220)** — `timezone: "America/New_York"` in the repo config, and the GHA cron (UTC) must land inside the `schedule:daily` before-4am-ET window WITH margin: GHA scheduled runs are best-effort and @@ -68,11 +68,11 @@ with `osvVulnerabilityAlerts: true` replacing the coverage. structurally out of reach — no extra rule needed; `config.test.ts` should pin this.) - **`RENOVATE_X_IGNORE_RE2=true`** on the runner — `bunx renovate` installs no - native re2 addon; take the RegExp fallback deliberately (as the internal - monorepo's CI/CD does). + native re2 addon; take the RegExp fallback deliberately (as the prior-art + CI/CD does). - **Writable HOME for postUpgradeTasks** — `customEnvVariables: { HOME: … }` in bot-config (RIG-2245: `devenv update nixpkgs` panics on an unwritable - `$HOME/.local/share/devenv`; ported from the internal monorepo). GHA runners have + `$HOME/.local/share/devenv`; following the prior art). GHA runners have a writable `$HOME` natively, but keep the declaration versioned and testable. - **A new `tools/*` test package is inert until registered in `.moon/workspace.yml`** — moon discovers projects ONLY from the explicit map @@ -84,7 +84,7 @@ with `osvVulnerabilityAlerts: true` replacing the coverage. ## Approach -Port the internal monorepo's proven self-hosted Renovate (repo config + bot config + lockstep +Adopt the proven self-hosted Renovate prior art (repo config + bot config + lockstep scripts + config tests) into compass, adapted to compass's paths and ecosystems, and run it as a plain GitHub Actions workflow that provisions the language toolchains the same way compass's other CI jobs do, plus the `devenv` CLI @@ -106,7 +106,7 @@ renovate@44.33.1` (exact pin — see below). Why B: compass's postUpgradeTasks need `nix` (toolchain-hash prefetch), `devenv` (devenv-nixpkgs relock shells `devenv update nixpkgs` from PATH, as in the -internal monorepo), and `bun` (all three scripts + +prior art), and `bun` (all three scripts + `bun install --lockfile-only`). Compass's GHA CI already provisions the language toolchains per job via `cachix/install-nix-action@630ae543…` (`.github/workflows/ci.yml:150`) + gate-tools.nix — the Renovate job composes @@ -141,9 +141,9 @@ the initial pin). The pin line is itself a managed dependency: a `custom.regex` manager on `.github/workflows/renovate.yml` (datasource `npm`, depName `renovate`) bumps it through a reviewable PR under the normal soak, and a `config.test.ts` guard asserts the workflow pins an exact version (no bare -`bunx renovate`). Note the internal monorepo has the same exposure — its meta job runs bare +`bunx renovate`). Note this same exposure exists in the fleet's prior art — its meta job runs bare `bunx renovate` (its publish image bakes devenv/skopeo, NOT Renovate) — -fix it there as a fleet follow-up, out of scope +fix that as a fleet follow-up, out of scope here. Triggers: `on: schedule: - cron: "0 6 * * *"` (06:00 UTC = 02:00 EDT / 01:00 @@ -151,8 +151,8 @@ EST — inside the before-4am-ET `schedule:daily` window with 2-3h margin per the RIG-1220 constraint; GHA cron is best-effort and routinely 5-30+ minutes late, so a tighter cron like `0 7` — 60 min of EDT margin — risks a delayed start past 04:00 ET reproducing the RIG-1220 silent-zero-PR symptom) + -`workflow_dispatch` for manual runs (the GHA analogue of the internal -monorepo's Woodpecker `{event: manual}` trigger; it also revives the +`workflow_dispatch` for manual runs (the GHA analogue of the prior art's +Woodpecker `{event: manual}` trigger; it also revives the schedule if GHA auto-disables it after 60 days of repo inactivity — see T6). Cadence: daily (resolved decision, OQ5 — Matt 2026-08-21), dropping dependabot's weekly. @@ -176,33 +176,33 @@ request the Workflows repository permission") — without it every github-actions bump PR fails to push with a workflows-scope error. Full App permission set: Contents (read/write — git access + non-workflow commits), Pull requests (read/write), Workflows (read/write), Issues (read/write — the -dependency dashboard is an issue). The internal monorepo's second secret -`RENOVATE_GITHUB_COM_TOKEN` is a read-only github.com PAT for release-notes +dependency dashboard is an issue). The prior art carries a second secret +`RENOVATE_GITHUB_COM_TOKEN`, a read-only github.com PAT for release-notes lookups against github.com from a non-github.com platform host; compass IS on -github.com, so the App token covers it — do not port the second secret. +github.com, so the App token covers it — no second secret is needed here. Registering/installing the App is a human action (T8; skill://human-action-handoff). -Port the internal monorepo's `tools/renovate-preflight` probe +Port the `tools/renovate-preflight` probe from the prior art so an expired/unscoped token fails with a named diagnosis instead of Renovate's opaque `platform-unknown-error`. The ported preflight reads `REPO` (owner/name) from the environment and exits fail-closed (exit 2) when it is missing — "could -not evaluate (missing REPO env) — fail closed". The internal monorepo's CI/CD -supplies `REPO` from `CI_REPO`; GHA has no `CI_REPO`, so T6's workflow sets +not evaluate (missing REPO env) — fail closed". In the prior art's CI/CD `REPO` +comes from `CI_REPO`; GHA has no `CI_REPO`, so T6's workflow sets `REPO: ${{ github.repository }}`. ### Managers `enabledManagers`: `bun`, `npm`, `gomod`, `github-actions`, `custom.regex`. -Dropped from the internal monorepo's list: `cargo`, `rust-toolchain` +Dropped from the prior art's list: `cargo`, `rust-toolchain` (compass has no Rust), `woodpecker` (no Woodpecker), and `nix` — Renovate's nix manager tracks `flake.lock`, and compass has NO root flake: the only `flake.lock` files in the tree live under `forks/devenv/` and `forks/nix2container/` (glob-verified), both inside the `forks/*/**` fence this record mandates `enabled: false`; `devenv.lock`/`devenv.yaml` are not `flake.lock` (the custom git-refs manager covers them), so a ported nix -manager would be dead config. Added: **`github-actions`** — the internal -monorepo deliberately omits it (its meta jobs moved off GHA), but compass +manager would be dead config. Added: **`github-actions`** — the prior art +deliberately omits it (its meta jobs moved off GHA), but compass keeps every workflow `uses:` pinned to a commit SHA precisely so a reviewable PR moves the pin forward (`.github/dependabot.yml:1-8`). Renovate's `github-actions` manager natively updates an existing SHA pin and keeps the @@ -220,16 +220,16 @@ Dockerfiles in the tree are `forks/oh-my-pi/Dockerfile`, `forks/oh-my-pi/Dockerfile.robomp`, and `forks/devenv/containers/devcontainer/Dockerfile`, all inside the `forks/*/**` fence this record disables — a dockerfile manager would be dead -config, same reasoning as the nix-manager drop above. (Auto-updating the internal -monorepo's harvester `oven/bun` base image is a separate fleet follow-up, filed separately.) +config, same reasoning as the nix-manager drop above. (Auto-updating the +prior art's harvester `oven/bun` base image is a separate fleet follow-up, filed separately.) -### customManagers: 6 of the internal monorepo's 7 port, +1 compass-new +### customManagers: 6 of the 7 prior-art managers port, +1 compass-new -| # | Internal-monorepo manager | Compass disposition | +| # | Prior-art manager | Compass disposition | | --- | --- | --- | | 1 | Root `package.json` catalog regex | **Port unchanged.** Compass has the same unmanaged-catalog gap: `workspaces.catalog` (`package.json:12-22`, 9 pins) with `catalog:` consumers; Renovate's bun manager doesn't extract it. Keep `versioningTemplate: "npm"` (range preservation) and the recursive two-stage matchStrings; port the truncation-guard tests. | | 2 | devenv-nixpkgs channel git-refs digest | **Port unchanged.** Compass has the same shape: `devenv.yaml:9-10` → `github:cachix/devenv-nixpkgs/rolling`, locked in `devenv.lock`; `devenv.nix:75-81` bakes `biome` + `markdownlint-cli2` from that channel while `@biomejs/biome` is also a catalog pin (`package.json:15`) — the same dual-source lockstep applies. Compass difference: only **biome** is dual-sourced (markdownlint-cli2 has no catalog pin — `grep markdownlint compass/package.json` → none), so the ported relock script rewrites one catalog pin, not two. | -| 3-5 | bun/node/moon toolchain pins | **Port with path change**: the internal monorepo's `versions/*.nix` → `tools/toolchain/versions/*.nix` (compass pin files confirmed: `tools/toolchain/versions/{bun,node,moon,go}.nix`; same `rec { version; srcs.{x86_64-linux,aarch64-linux,aarch64-darwin} }` shape, e.g. `bun.nix:2-17`). | +| 3-5 | bun/node/moon toolchain pins | **Port with path change**: the prior art's `versions/*.nix` → `tools/toolchain/versions/*.nix` (compass pin files confirmed: `tools/toolchain/versions/{bun,node,moon,go}.nix`; same `rec { version; srcs.{x86_64-linux,aarch64-linux,aarch64-darwin} }` shape, e.g. `bun.nix:2-17`). | | 6 | Go version attr in devenv.nix | **Port, retargeted at `tools/toolchain/versions/go.nix`** — see "Go source of truth" below. | | 7 | googleworkspace provider lockstep | **Drop.** Compass has no pulumi and no `provider.lock.json`. | @@ -239,7 +239,7 @@ regex on `.github/workflows/renovate.yml`'s `bunx renovate@` line ### Go source of truth: `go.nix`, one regex manager -Compass differs from the internal monorepo: there the go version lives ONLY in `devenv.nix` as the +Compass differs from the prior art, which keeps the go version ONLY in `devenv.nix` as the `"go_1_26_5"` attr string, so that manager regexes `devenv.nix`. Compass single-sources the version in `tools/toolchain/versions/go.nix` (`{ version = "1.26.6"; }`, version-only — hashes come from go-overlay) and @@ -250,14 +250,14 @@ goPin = import ./tools/toolchain/versions/go.nix; goToolchain = inputs.go-overlay.packages.${pkgs.stdenv.system}."go_${lib.replaceStrings [ "." ] [ "_" ] goPin.version}"; ``` -So `devenv.nix` contains no literal `go_X_Y_Z` string — the internal monorepo's regex would match +So `devenv.nix` contains no literal `go_X_Y_Z` string — the prior art's regex would match nothing there. Track `go.nix` instead: one regex manager, `managerFilePatterns: ["/^tools/toolchain/versions/go\\.nix$/"]`, `matchStrings: ["version = \"(?[^\"]+)\""]`, `datasourceTemplate: "golang-version"`, `depTypeTemplate: "toolchain"`. No dots↔underscores gymnastics (the version is dotted in the file), no postUpgradeTasks leg (go-overlay ships the hashes; the refresh script must -self-gate past `go.nix` exactly as the internal monorepo's script no-ops on go, +self-gate past `go.nix` exactly as the prior-art script no-ops on go, and `devenv.nix` updates automatically at eval time. One bump PR touches one line. This was OQ4, now decided (see Resolved decisions). Note the `go.nix:8-9` floor policy: the `go` directive in @@ -271,7 +271,7 @@ go.mod follow-up. ### packageRules -Port from the internal monorepo, adapted: +Port from the prior art, adapted: - "TypeScript dependencies" rollup: `bun`/`npm`/`custom.regex` patch+minor. Drop the Rust rollup (no cargo). @@ -304,15 +304,15 @@ Port from the internal monorepo, adapted: rule — an `overrides` pin, out of the catalog manager's reach, as Global Constraints already argue.) - Toolchain un-grouping: `matchFileNames: ["tools/toolchain/versions/*.nix"], - groupName: null` (ported from the internal monorepo, path adapted). Because the go manager now + groupName: null` (from the prior art, path adapted). Because the go manager now targets `go.nix` under the same glob, this one rule un-groups all four pins — - the internal monorepo's separate go un-group rule is NOT needed; note this in the + the prior art's separate go un-group rule is NOT needed; note this in the config comment and pin it in config.test.ts. - TypeScript `<7` cap: port as-is. - devenv-nixpkgs solo branch: own groupName, `schedule: ["before - 4am"]` — DAILY, not the internal monorepo's weekly-Monday `["before 4am on monday"]` + 4am"]` — DAILY, not the prior art's weekly-Monday `["before 4am on monday"]` (resolved decision, OQ5 — Matt: nixpkgs also daily; the deliberate - divergence from the internal monorepo's prior art gets a config comment), aligned with the + divergence from the prior art gets a config comment), aligned with the `0 6 * * *` UTC cron inside the before-4am-ET window; `minimumReleaseAge: null` (a moving-branch digest never clears a release-age window — the RIG-1220 silent-pending shape), branch-mode @@ -321,10 +321,10 @@ Port from the internal monorepo, adapted: - Catalog lockfile coupling: `matchDepTypes: ["workspaces.catalog"]`, `postUpgradeTasks: { commands: ["bun install --lockfile-only"], fileFilters: ["bun.lock"], executionMode: "update" }`. `executionMode` MUST stay `"update"` - — the internal monorepo's comment documents the one-branch-mode-task-per-branch + — the prior art's comment documents the one-branch-mode-task-per-branch collision this avoids; port that rationale. - Fork fence: `matchFileNames: ["forks/*/**"], enabled: false` (adapted from - the internal monorepo's fork fence to compass's root `forks/`). + the prior art's fork fence to compass's root `forks/`). - Drop: "Nix flake inputs" group (dead config with the nix manager omitted; see Managers), provider solo branch, pulumi SDK disable, container-images group (compass has @@ -342,13 +342,13 @@ resolved decision, see Resolved decisions): - **`refresh-toolchain-hashes.ts` + test** — port with compass paths (`BUN_NIX/NODE_NIX/MOON_NIX = "tools/toolchain/versions/*.nix"`) and the entire Rust FOD leg removed (`TOOLCHAIN_TOML`/`MANIFEST_HASH_NIX` constants, - `readChannel`, `channelManifestUrl`, `renderManifestHashFile` — from the internal - monorepo's script). Keep the self-gate, per-leg + `readChannel`, `channelManifestUrl`, `renderManifestHashFile` — from the + prior-art script). Keep the self-gate, per-leg rewrite, fail-loud, idempotence contracts. - **`refresh-devenv-nixpkgs.ts` + `.core.ts` + tests** — port; compass adaptation: only the biome catalog pin is rewritten (markdownlint-cli2 has no catalog pin in compass — `package.json:12-22`), and compass's baked-vs-catalog - coupling is the dev-shell parity story, not the internal monorepo's image gate; the + coupling is the dev-shell parity story, not the prior art's image gate; the relock still must refresh `devenv.lock` consistently (rev + narHash + inner nixpkgs-src) and re-resolve `bun.lock`. - **`config.test.ts`** — port the guard suite: allowedCommands ↔ postUpgradeTasks @@ -371,15 +371,15 @@ Compass has no `ci/` directory — every first-party tool lives under `tools/*` workspace member (`package.json:10`), giving the scripts the standard tsconfig/test wiring. The bot config's `configFileNames: ["tools/renovate/config.json5"]` makes the repo-config path free (mirroring the -internal monorepo's bot config). The workflow itself is `.github/workflows/renovate.yml` +prior-art bot config). The workflow itself is `.github/workflows/renovate.yml` (GHA requires that location). The preflight probe ports to -`tools/renovate-preflight/` (the internal monorepo's own location, already `tools/`-shaped). +`tools/renovate-preflight/` (keeping the prior art's own location, already `tools/`-shaped). ### Bot config Port `bot-config.json5` with: `configFileNames: ["tools/renovate/config.json5"]`; `repositories: ["RigelBuild/compass"]` (must match the live slug — a renamed repo -is silently skipped, as the internal monorepo's bot config documents); `platform: github`; +is silently skipped, as the prior-art bot config documents); `platform: github`; `gitAuthor` = the App's `[bot]` noreply identity (`+[bot]@users.noreply.github.com` — Renovate autodetects it from the installation token; pin it explicitly here once T8 registers the @@ -390,7 +390,7 @@ exactly the three anchored entries compass's config declares: `^bun install --lockfile-only$`, `^bun tools/renovate/refresh-devenv-nixpkgs\.ts$`. -Fleet note: the internal monorepo's own bot config still pins the +Fleet note: the prior art's own bot config still pins the retired pre-RigelBuild-rename bot identity as its gitAuthor — a separate fleet cleanup, not fixed by this record. (For non-App contexts the fleet agent identity is `mintaka `, GitHub `rigel-mintaka`, @@ -410,9 +410,9 @@ custom Renovate image (that's option C) or mounting a host toolchain into the container (fragile, and nix store paths don't relocate). Loses to B: same workflow-trigger surface, strictly less toolchain access. -### C — bake a compass-ci image with renovate + devenv (the internal monorepo's approach) +### C — bake a compass-ci image with renovate + devenv (the prior-art approach) -The internal monorepo runs Renovate in its Woodpecker publish monolith — a CI +The prior art runs Renovate in a Woodpecker publish monolith — a CI image that bakes devenv. Compass has no equivalent image: its only published image is the agent image (`publish-agent-image.yml`), not a CI toolchain image — compass CI provisions per-job via install-nix-action + @@ -450,7 +450,7 @@ one human action and gates first live run, not the merge. ### T1 — Port the repo config: `tools/renovate/config.json5` -Adapt the internal monorepo's repo config per Approach: extends +Adapt the prior-art repo config per Approach: extends `config:recommended` + `schedule:daily` + `helpers:pinGitHubActionDigests`; `timezone: "America/New_York"`; `dependencyDashboard: true`; `rebaseWhen: "behind-base-branch"`; `osvVulnerabilityAlerts: true`; `minimumReleaseAge: "5 @@ -497,7 +497,7 @@ Interfaces: ### T3 — Port `refresh-toolchain-hashes.ts` + test -Port the internal monorepo's `refresh-toolchain-hashes.ts` (+ `.test.ts`) to +Port the prior-art `refresh-toolchain-hashes.ts` (+ `.test.ts`) to `tools/renovate/`: path constants become `BUN_NIX/NODE_NIX/MOON_NIX = "tools/toolchain/versions/{bun,node,moon}.nix"`; DELETE the Rust FOD leg entirely (`TOOLCHAIN_TOML`, `MANIFEST_HASH_NIX`, `readChannel`, @@ -518,7 +518,7 @@ Interfaces: ### T4 — Port `refresh-devenv-nixpkgs.ts` + `.core.ts` + tests -Port the internal monorepo's `refresh-devenv-nixpkgs{.ts,.core.ts,.test.ts,.core.test.ts}` +Port the prior-art `refresh-devenv-nixpkgs{.ts,.core.ts,.test.ts,.core.test.ts}` to `tools/renovate/`. Compass adaptation: rewrite ONLY the `@biomejs/biome` catalog pin (compass's catalog has no markdownlint-cli2 entry — `package.json:12-22`; drop `MARKDOWNLINT_CATALOG_KEY` and its rewrite leg). Preserve: devenv.lock @@ -535,14 +535,14 @@ Interfaces: `rewriteCatalogPin(packageJsonText, key, version): string`. - Reads/writes at runtime: `devenv.lock`, `package.json`, `bun.lock`. - Requires on PATH: `nix`, `devenv` (the VENDORED fork CLI via T6's shim — - the script shells `devenv update nixpkgs` from PATH, as in the internal - monorepo, and a nixpkgs devenv is rejected per + the script shells `devenv update nixpkgs` from PATH, as in the prior + art, and a nixpkgs devenv is rejected per Alternatives §D), `bun`, `git`; writable `$HOME` (bot config sets `/tmp/renovate-home`). ### T5 — Port `config.test.ts` -Port the internal monorepo's `config.test.ts` guards, adapted: (1) every +Port the prior-art `config.test.ts` guards, adapted: (1) every postUpgradeTasks command in config.json5 has an anchored allowedCommands entry in bot-config.json5 and vice versa; (2) `vulnerabilityAlerts.enabled` is absent and `osvVulnerabilityAlerts` is true; (3) real-manifest catalog extraction — @@ -598,7 +598,7 @@ repo's standard runner label per `ci.yml`), steps: missing shim reds at setup instead of exit-127ing silently on the first channel-bump branch (a known regression class: on an image without devenv the relock "exits 127 (`devenv: command not found`) on every channel-bump - branch, shipping a half-refreshed lock", the internal monorepo's regression + branch, shipping a half-refreshed lock", the prior art's regression evidence, RIG-2245). 6. Mint the App installation token: `actions/create-github-app-token@ # vX` (SHA-pin + version @@ -606,10 +606,10 @@ repo's standard runner label per `ci.yml`), steps: vars.RENOVATE_APP_CLIENT_ID }}` and `private-key: ${{ secrets.RENOVATE_APP_PRIVATE_KEY }}`. Its `token` output feeds every later step — no long-lived PAT exists (see Approach §Secrets/Auth). -7. Port `tools/renovate-preflight/` from the internal monorepo and run it with +7. Port `tools/renovate-preflight/` from the prior art and run it with `GH_TOKEN=${{ steps..outputs.token }}` and `REPO: ${{ github.repository }}` — the preflight reads `REPO` and exits - fail-closed when missing (as in the internal monorepo's preflight; + fail-closed when missing (as in the prior-art preflight; GHA has no `CI_REPO`, so the workflow must set it or every run dies at preflight). Adapt the ported index.ts comment (`REPO - owner/name (from github.repository)`). Register `tools/renovate-preflight` in @@ -740,14 +740,14 @@ folded into the record as decisions: all first-party tooling is `tools/*`, a bun workspace glob (`package.json:10`), so the scripts and tests get standard wiring; `.github/` would strand TypeScript outside the workspace. The preflight - keeps the internal monorepo's own `tools/renovate-preflight/` naming. The bot config's + keeps the prior art's own `tools/renovate-preflight/` naming. The bot config's `configFileNames` makes any choice mechanically workable — convention only. - **Go source of truth: `go.nix`** (was OQ4) — compass derives the `go_X_Y_Z` attr at eval time (`devenv.nix:30-31`); there is no literal attr string for - the internal monorepo's devenv.nix regex to match, and `go.nix` is the declared single + the prior art's devenv.nix regex to match, and `go.nix` is the declared single source (`go.nix:1-9`). One regex manager on `go.nix`; `devenv.nix` untouched by Renovate; the gomod `go`-directive update disabled (see packageRules). -- **Grouping: internal-monorepo parity** (was OQ6) — TS rollup, Go rollup, GitHub Actions +- **Grouping: prior-art parity** (was OQ6) — TS rollup, Go rollup, GitHub Actions group; majors solo; toolchain pins solo. Same review granularity across the fleet; dependabot's old single-group-per-ecosystem shape maps 1:1 (actions→"GitHub Actions", bun→"TypeScript dependencies", gomod→"Go @@ -766,7 +766,7 @@ folded into the record as decisions: `bunx renovate@` requirement. - **Cadence: daily — top-level AND devenv-nixpkgs** (was OQ5; Matt 2026-08-21) — `schedule:daily` with the `0 6 * * *` UTC cron, and the - devenv-nixpkgs solo branch drops the internal monorepo's weekly-Monday restriction to - `["before 4am"]` daily (a deliberate divergence from the internal monorepo's - prior art). `minimumReleaseAge: null` stays on that branch — + devenv-nixpkgs solo branch drops the prior art's weekly-Monday restriction to + `["before 4am"]` daily (a deliberate divergence from the prior + art). `minimumReleaseAge: null` stays on that branch — a moving-branch digest never clears a release-age window. diff --git a/docs/designs/ui/compass-badge-clarity/design.md b/docs/designs/ui/compass-badge-clarity/design.md index 0f7282eff..3cb04006e 100644 --- a/docs/designs/ui/compass-badge-clarity/design.md +++ b/docs/designs/ui/compass-badge-clarity/design.md @@ -224,7 +224,7 @@ semantic tier correctly. ### The reference — a shape floor, but ahead on color routing -The internal monorepo's company-site board is prior art here — its Bridge board +A company-site board elsewhere in the fleet is prior art here — that Bridge board renders the same bare squares, 7px, no glyphs, so on **shape** it is a floor this record improves on. @@ -629,7 +629,7 @@ above). The rationale each proceeded on is kept below for the executor. size and the open question already tracked at `components.md:111-114`. Whatever answer Matt gives there should bind these glyphs too. - **Q5 (non-load-bearing): should the chosen option back-port to - the internal monorepo's company-site board** (which has the same bare + the fleet's company-site board** (which has the same bare squares)? Assumption: yes eventually, out of scope for RIG-2117. ## Plan / Tasks