diff --git a/docs/designs/CONTRIBUTING.md b/docs/designs/CONTRIBUTING.md index cd58de1f7..9dea63760 100644 --- a/docs/designs/CONTRIBUTING.md +++ b/docs/designs/CONTRIBUTING.md @@ -108,7 +108,7 @@ outgrows flat scanning; until then records sit directly under their bucket. ### The design-ledger-gate governs every bucket `tools/design-ledger-gate` scans every governed bucket (the six taxonomy buckets -above plus the transitional `product/` root, below): every record's `Status:` +above): every record's `Status:` header is checked for presence and grammar, and a PR that touches a governed record must either touch the ledger (`docs/designs/DECISIONS.md`) or declare a `Ledger-impact:` line in its description. The `DECISIONS.md` ledger rows stay @@ -126,9 +126,3 @@ deletion — a move leaves the same dangling-link rot a deletion would. Two narr metadata edits ride the same standard and are likewise not freeze violations: normalizing a newly-governed record's `Status:` header to the gate grammar, and a one-line correction of a record's stale self-described location. - -### `product/` is transitional - -A `product/` bucket persists transitionally alongside the six above until the -`compass-native-*` records clear their in-flight lane and the final sweep -removes it; records still under `product/` remain governed in the meantime. diff --git a/docs/designs/DECISIONS.md b/docs/designs/DECISIONS.md index 40e8b1393..969f45f60 100644 --- a/docs/designs/DECISIONS.md +++ b/docs/designs/DECISIONS.md @@ -269,23 +269,23 @@ check enforces the mechanical half. Full rationale: | ID | Decision | Status | Record | | --- | --- | --- | --- | -| DL-044 | The Tauri desktop shell is a thin webview→daemon shell over a swappable transport seam; the daemon spawns detached and outlives the shell | Superseded by DL-106 (Matt, 2026-08-02) | [Tauri shell §Approach](product/compass-tauri-shell.md#approach) | -| DL-106 | The Compass native app is one binary in two modes (embedded / native-client); the mode difference is confined to the connection provider and the stack supervisor, and nothing above the transport boundary assumes local | Superseded by DL-235 (Matt, 2026-08-23) | [native app §A1](product/compass-native-app/design.md#a1--one-binary-two-modes-mode--which-connection-the-resolver-produces) | -| DL-107 | One framework-neutral shell IPC contract (`compass_rpc` + `head\|body\|end\|error` frames) carries gRPC-Web over a custom `fetch` for both modes — embedded pumps to the UDS, native-client to the TLS network door with shell-side private-CA trust and a shell-injected bearer | Active (Matt, 2026-08-02) | [native app §A2](product/compass-native-app/design.md#a2--the-transport-seam-one-frame-contract-two-bridges) | -| DL-108 | Embedded lifecycle is a Go stack supervisor (`go/internal/stack` + `compass-stack up\|down\|status`) of spawned children (never in-process), linger-by-default, productizing the dogfood chain with a supervised private Postgres, expiry-aware cert rotation, and lockfiled attach | Active (Matt, 2026-08-02) | [native app §A3](product/compass-native-app/design.md#a3--embedded-lifecycle-a-go-stack-supervisor-spawned-by-the-shell) | -| DL-109 | Native-app mode selection is `$XDG_CONFIG_HOME/compass/app.toml` (absent → embedded default); the native-client bearer is entered in a connect screen and stored keychain-first (0600-file fallback), never in config-file or argv | Active (Matt, 2026-08-02) | [native app §A4](product/compass-native-app/design.md#a4--mode-selection-and-native-client-configuration) | -| DL-110 | The Compass native shell is Wails v3 (Go), its module under `go/` (`go/cmd/compass-app`) importing `go/internal/stack` and the bridge pump directly; re-decides DL-044's framework on the Go stack (Wails, not Tauri) | Active (Matt, 2026-08-02) | [native app §OQ1](product/compass-native-app/design.md#oq1--shell-framework-tauri-rust-vs-wails-go-vs-other--blocks-t3) | -| DL-111 | A new `compass.v1` `WhoAmI` RPC returns the caller's account id from its own credential (embedded: socket ambient-admin; native-client: bearer subject), retiring the parked `caller_account_id` seam and the connect-screen caller-id field | Active (Matt, 2026-08-02) | [native app §OQ7](product/compass-native-app/design.md#oq7--embedded-caller-identity-mechanism--blocks-t4-cross-lane-compass-server) | -| DL-112 | The `compass-agent` image is published to GHCR and `podman pull`ed by `compass-stack` at first run (not bundled in the app), making a GHCR publish lane for `compass-agent` a native-app packaging dependency | Active (Matt, 2026-08-02) | [native app §OQ6](product/compass-native-app/design.md#oq6--agent-image-distribution-for-embedded-mode--blocks-t4-reshapes-t6) | -| DL-183 | Cross-process embedded-stack teardown: `up` persists each supervised child's process-group ID plus a start-time identity token to an atomic `stack.pgids` record beside the lockfile; a fresh `down` refuses while an `up` holds the lock, then reads the record, verifies each group's identity before signaling, SIGTERMs each exact persisted pgid in reverse start order with bounded SIGKILL escalation, and confirms teardown per component (server/postgres socket quiescence, runner group-ESRCH) — scoped to the three supervised stack children (postgres, compass-server, compass-runner); live agent containers escape the process group via conmon double-fork and are OUT of scope (RIG-1884). Refines DL-108 (which stays Active) and realizes the frozen record's `down`-SIGTERMs-the-tree claim for the supervised children | Active (Matt, 2026-08-05) | [cross-process teardown §Approach](product/compass-stack-cross-process-teardown/design.md#approach--option-a-persist-child-pgids-at-up-down-signals-the-persisted-groups) | -| DL-214 | The T6 Linux app artifact is a versioned tarball of a nix-closure-backed bundle directory (store-rpathed binaries via the devenv.lock-pinned GTK closure + cc-wrapper, `.desktop` inside), not AppImage/`nix bundle`/`wails3 package`; no-nix-store end-user distribution is the A5 installer follow-up's concern, which wraps this same bundle dir | Active (Matt, 2026-08-19) | [packaging §A1](product/compass-native-packaging/design.md#a1--bundle-format-a-versioned-tarball-of-a-nix-closure-backed-bundle-dir-fork-1-resolved) | -| DL-215 | Bundle binary carriage is the sidecar `bin/` layout the shell already resolves (stack sibling + `dist` beside the executable), completed by the app prepending its executable dir to the spawned `compass-stack`'s PATH so the stack's LookPath children resolve in-bundle — never Go `embed` of ELF sidecars, never Wails asset bundling | Superseded by DL-238 (Matt, 2026-08-23) | [packaging §A2](product/compass-native-packaging/design.md#a2--binary-embedding-sidecar-bin-layout--path-threading-fork-2-resolved) | -| DL-216 | The bundle build is a moon-registered project (`compass-app-bundle`) riding affected-detection per-PR and the unconditional main/nightly full sweep — the `compass-agent-image` heavy-build precedent — with a built-in completeness sanity gate (binaries present, uniform `--version` stamp, dist present); never a per-PR unconditional build, never a ci.yml-enumerated job | Active (Matt, 2026-08-19) | [packaging §A4](product/compass-native-packaging/design.md#a4--ci-cadence-affected-gated-per-pr-unconditional-on-main--nightly-fork-3-resolved) | -| DL-217 | Postgres tooling (`postgres`/`initdb`/`createdb`) ships in the bundle `bin/` from the devenv.lock-pinned bare `postgresql` attr, leaving rootless podman as the sole host prerequisite of the packaged embedded mode | Superseded by DL-238 (Matt, 2026-08-23) | [packaging §OQ1](product/compass-native-packaging/design.md#oq1-load-bearing-for-matt--postgres-tooling-bundled-or-host-prerequisite) | -| DL-235 | The Compass native app is CLIENT-ONLY: `compass-app` retires embedded mode entirely (supervisor invocation, host preflight, UDS bridge target, embedded config arm) and connects exclusively over the authenticated TLS door to a headless Compass stack — normally on a dedicated KVM-capable machine, or the same box via `compass-stack up` + `https://localhost`; driven by the microVM Runner's KVM floor retiring local agent execution. Supersedes DL-106 (dual-mode charter) | Active (Matt, 2026-08-23) | [client-only §A1](product/compass-native-client-only/design.md#a1--thesis-compass-app-is-a-native-client-only-binary) | -| DL-236 | `compass-stack` survives the app's retirement of embedded mode as the standalone headless single-user bring-up CLI (`up`/`down`/`status`, DL-183 teardown intact); the app never spawns, supervises, or tears down a stack. Refines DL-108 (which stays Active — the supervisor design lives; only the app's shell-spawn invocation retires) | Active (Matt, 2026-08-23) | [client-only §A1](product/compass-native-client-only/design.md#a1--thesis-compass-app-is-a-native-client-only-binary) | -| DL-237 | app.toml is client-only: absent or `mode="client"` → client (`server_url` required); `mode="embedded"` is a legible retirement error, never a compatibility arm; the `--mode`/`$COMPASS_APP_MODE` override retires with the second mode. Supersedes the embedded-default mode-selection half of DL-109 (whose keychain-first bearer clause stays Active) | Active (Matt, 2026-08-23) | [client-only §A3](product/compass-native-client-only/design.md#a3--appconfig-the-clean-cut-client-is-the-only-mode) | -| DL-238 | The app bundle is the THIN CLIENT: `compass-app` + `dist` + `.desktop` + LICENSE, no sidecar binaries, no postgres tooling; headless-stack distribution (`compass-stack`+`compass-postgres` onto the dedicated machine) is a releases-lane follow-up, and RIG-2477 re-scopes to client-app release artifacts with macOS as the first new target. Supersedes DL-215 (sidecar `bin/` + PATH threading) and DL-217 (bundled postgres tooling) | Active (Matt, 2026-08-23) | [client-only §A4](product/compass-native-client-only/design.md#a4--cutover-plan-sequenced-clean-no-shims) | +| DL-044 | The Tauri desktop shell is a thin webview→daemon shell over a swappable transport seam; the daemon spawns detached and outlives the shell | Superseded by DL-106 (Matt, 2026-08-02) | [Tauri shell §Approach](ui/compass-tauri-shell.md#approach) | +| DL-106 | The Compass native app is one binary in two modes (embedded / native-client); the mode difference is confined to the connection provider and the stack supervisor, and nothing above the transport boundary assumes local | Superseded by DL-235 (Matt, 2026-08-23) | [native app §A1](ui/compass-native-app/design.md#a1--one-binary-two-modes-mode--which-connection-the-resolver-produces) | +| DL-107 | One framework-neutral shell IPC contract (`compass_rpc` + `head\|body\|end\|error` frames) carries gRPC-Web over a custom `fetch` for both modes — embedded pumps to the UDS, native-client to the TLS network door with shell-side private-CA trust and a shell-injected bearer | Active (Matt, 2026-08-02) | [native app §A2](ui/compass-native-app/design.md#a2--the-transport-seam-one-frame-contract-two-bridges) | +| DL-108 | Embedded lifecycle is a Go stack supervisor (`go/internal/stack` + `compass-stack up\|down\|status`) of spawned children (never in-process), linger-by-default, productizing the dogfood chain with a supervised private Postgres, expiry-aware cert rotation, and lockfiled attach | Active (Matt, 2026-08-02) | [native app §A3](ui/compass-native-app/design.md#a3--embedded-lifecycle-a-go-stack-supervisor-spawned-by-the-shell) | +| DL-109 | Native-app mode selection is `$XDG_CONFIG_HOME/compass/app.toml` (absent → embedded default); the native-client bearer is entered in a connect screen and stored keychain-first (0600-file fallback), never in config-file or argv | Active (Matt, 2026-08-02) | [native app §A4](ui/compass-native-app/design.md#a4--mode-selection-and-native-client-configuration) | +| DL-110 | The Compass native shell is Wails v3 (Go), its module under `go/` (`go/cmd/compass-app`) importing `go/internal/stack` and the bridge pump directly; re-decides DL-044's framework on the Go stack (Wails, not Tauri) | Active (Matt, 2026-08-02) | [native app §OQ1](ui/compass-native-app/design.md#oq1--shell-framework-tauri-rust-vs-wails-go-vs-other--blocks-t3) | +| DL-111 | A new `compass.v1` `WhoAmI` RPC returns the caller's account id from its own credential (embedded: socket ambient-admin; native-client: bearer subject), retiring the parked `caller_account_id` seam and the connect-screen caller-id field | Active (Matt, 2026-08-02) | [native app §OQ7](ui/compass-native-app/design.md#oq7--embedded-caller-identity-mechanism--blocks-t4-cross-lane-compass-server) | +| DL-112 | The `compass-agent` image is published to GHCR and `podman pull`ed by `compass-stack` at first run (not bundled in the app), making a GHCR publish lane for `compass-agent` a native-app packaging dependency | Active (Matt, 2026-08-02) | [native app §OQ6](ui/compass-native-app/design.md#oq6--agent-image-distribution-for-embedded-mode--blocks-t4-reshapes-t6) | +| DL-183 | Cross-process embedded-stack teardown: `up` persists each supervised child's process-group ID plus a start-time identity token to an atomic `stack.pgids` record beside the lockfile; a fresh `down` refuses while an `up` holds the lock, then reads the record, verifies each group's identity before signaling, SIGTERMs each exact persisted pgid in reverse start order with bounded SIGKILL escalation, and confirms teardown per component (server/postgres socket quiescence, runner group-ESRCH) — scoped to the three supervised stack children (postgres, compass-server, compass-runner); live agent containers escape the process group via conmon double-fork and are OUT of scope (RIG-1884). Refines DL-108 (which stays Active) and realizes the frozen record's `down`-SIGTERMs-the-tree claim for the supervised children | Active (Matt, 2026-08-05) | [cross-process teardown §Approach](ui/compass-stack-cross-process-teardown/design.md#approach--option-a-persist-child-pgids-at-up-down-signals-the-persisted-groups) | +| DL-214 | The T6 Linux app artifact is a versioned tarball of a nix-closure-backed bundle directory (store-rpathed binaries via the devenv.lock-pinned GTK closure + cc-wrapper, `.desktop` inside), not AppImage/`nix bundle`/`wails3 package`; no-nix-store end-user distribution is the A5 installer follow-up's concern, which wraps this same bundle dir | Active (Matt, 2026-08-19) | [packaging §A1](ui/compass-native-packaging/design.md#a1--bundle-format-a-versioned-tarball-of-a-nix-closure-backed-bundle-dir-fork-1-resolved) | +| DL-215 | Bundle binary carriage is the sidecar `bin/` layout the shell already resolves (stack sibling + `dist` beside the executable), completed by the app prepending its executable dir to the spawned `compass-stack`'s PATH so the stack's LookPath children resolve in-bundle — never Go `embed` of ELF sidecars, never Wails asset bundling | Superseded by DL-238 (Matt, 2026-08-23) | [packaging §A2](ui/compass-native-packaging/design.md#a2--binary-embedding-sidecar-bin-layout--path-threading-fork-2-resolved) | +| DL-216 | The bundle build is a moon-registered project (`compass-app-bundle`) riding affected-detection per-PR and the unconditional main/nightly full sweep — the `compass-agent-image` heavy-build precedent — with a built-in completeness sanity gate (binaries present, uniform `--version` stamp, dist present); never a per-PR unconditional build, never a ci.yml-enumerated job | Active (Matt, 2026-08-19) | [packaging §A4](ui/compass-native-packaging/design.md#a4--ci-cadence-affected-gated-per-pr-unconditional-on-main--nightly-fork-3-resolved) | +| DL-217 | Postgres tooling (`postgres`/`initdb`/`createdb`) ships in the bundle `bin/` from the devenv.lock-pinned bare `postgresql` attr, leaving rootless podman as the sole host prerequisite of the packaged embedded mode | Superseded by DL-238 (Matt, 2026-08-23) | [packaging §OQ1](ui/compass-native-packaging/design.md#oq1-load-bearing-for-matt--postgres-tooling-bundled-or-host-prerequisite) | +| DL-235 | The Compass native app is CLIENT-ONLY: `compass-app` retires embedded mode entirely (supervisor invocation, host preflight, UDS bridge target, embedded config arm) and connects exclusively over the authenticated TLS door to a headless Compass stack — normally on a dedicated KVM-capable machine, or the same box via `compass-stack up` + `https://localhost`; driven by the microVM Runner's KVM floor retiring local agent execution. Supersedes DL-106 (dual-mode charter) | Active (Matt, 2026-08-23) | [client-only §A1](ui/compass-native-client-only/design.md#a1--thesis-compass-app-is-a-native-client-only-binary) | +| DL-236 | `compass-stack` survives the app's retirement of embedded mode as the standalone headless single-user bring-up CLI (`up`/`down`/`status`, DL-183 teardown intact); the app never spawns, supervises, or tears down a stack. Refines DL-108 (which stays Active — the supervisor design lives; only the app's shell-spawn invocation retires) | Active (Matt, 2026-08-23) | [client-only §A1](ui/compass-native-client-only/design.md#a1--thesis-compass-app-is-a-native-client-only-binary) | +| DL-237 | app.toml is client-only: absent or `mode="client"` → client (`server_url` required); `mode="embedded"` is a legible retirement error, never a compatibility arm; the `--mode`/`$COMPASS_APP_MODE` override retires with the second mode. Supersedes the embedded-default mode-selection half of DL-109 (whose keychain-first bearer clause stays Active) | Active (Matt, 2026-08-23) | [client-only §A3](ui/compass-native-client-only/design.md#a3--appconfig-the-clean-cut-client-is-the-only-mode) | +| DL-238 | The app bundle is the THIN CLIENT: `compass-app` + `dist` + `.desktop` + LICENSE, no sidecar binaries, no postgres tooling; headless-stack distribution (`compass-stack`+`compass-postgres` onto the dedicated machine) is a releases-lane follow-up, and RIG-2477 re-scopes to client-app release artifacts with macOS as the first new target. Supersedes DL-215 (sidecar `bin/` + PATH threading) and DL-217 (bundled postgres tooling) | Active (Matt, 2026-08-23) | [client-only §A4](ui/compass-native-client-only/design.md#a4--cutover-plan-sequenced-clean-no-shims) | | DL-257 | The client app ships a full per-OS matrix from day one — Linux x86_64 (thin-client tarball, DL-238 content) AND macOS arm64 (signed+notarized `.app` in a dmg, built on a macOS runner, never cross-compiled) — attached to the RIG-1746 release lanes, extending the release-bundling record's Fork 2(i) asset boundary and resolving its OQ-1 deferral (RIG-2477) | Active (Matt, 2026-08-24) | [distribution §S1](infra/release/compass-distribution/design.md#s1--client-app-per-os-matrix) | | DL-258 | Client install channels are homebrew (RigelBuild/homebrew-tap: cask for the macOS app + a cross-OS CLI formula, semver-bumped by the release workflow) and a repo `flake.nix` (client + stack packages pinned to the devenv.lock nixpkgs), over the raw release assets; distro-native packages (deb/rpm/AUR) deferred | Active (Matt, 2026-08-24) | [distribution §S2](infra/release/compass-distribution/design.md#s2--client-app-install-channels) | | DL-259 | The self-host stack stays a host-level bring-up on a KVM-capable Linux machine (`compass-stack up`; microVM D3 hard-fail consumed, no compose/Swarm packaging); `compass-stack` joins the release binary matrix, and the flake + preflight + self-host doc are its install surface — resolving the client-only record's OQ-3 (RIG-2608) | Active (Matt, 2026-08-24) | [distribution §S3](infra/release/compass-distribution/design.md#s3--self-host-stack-host-level-kvm-bring-up) | @@ -293,7 +293,7 @@ check enforces the mechanical half. Full rationale: | DL-261 | macOS signing identity provisioning waits for the company rename (Sealed Security Inc → Rigel AI Software Inc, same DE entity so its D-U-N-S carries over as an update, not a new request); enroll the Apple Developer Program org clean as Rigel AI Software Inc post-rename. Nothing pre-GA needs public signing, so dev/internal builds self-sign meanwhile (ad-hoc `codesign --sign -`, mandatory on Apple Silicon, or a local self-signed cert — no Apple account); the Developer ID cert + notarization (the distribute-to-other-Macs leg) is GA-gated on the enrollment. Resolves distribution OQ-2 | Active (Matt, 2026-08-25) | [distribution §GC6](infra/release/compass-distribution/design.md#global-constraints) | | DL-262 | Containerized-postgres teardown extends the DL-183 pgid record to format v2: `pgidFileVersion` `"1"`→`"2"`, entries become a kind-tagged discriminated union (`proc ` torn down by group signal as today; `ctr ` torn down by `podman stop`/`rm -f`), `readPgidFile` dispatches on the tag and a shipped v1 binary hard-errors on a v2 entry line by the entry-grammar (not a header check) under the unchanged signal-off-a-half-understood-record discipline. The per-agent microVMs are the runner's sandbox one layer below the stack and are untouched (the stack tears the runner down by pgid as a plain host process); what forces v2 is postgres containerizing, not microVMs. Extends DL-183 (which stays Active); resolves distribution OQ-7 | Active (Matt, 2026-08-25) | [distribution §S4](infra/release/compass-distribution/design.md#s4--postgres-as-container-the-dl-217-supersession) | | DL-263 | darwin CI cadence mirrors the shipped affected-on-PR + full-sweep-on-main + nightly shape (`ci.yml:25-36`): a `macos-14` compile+bundle sweep runs on every push to main AND nightly ALWAYS (the backstop), plus an affected-on-PR leg gated by a small ubuntu pre-job asking moon which projects the PR affects (moon's own affected-detection — the signal `moon ci` uses — never a GitHub `paths:` filter, so moon stays the single source of affected-truth per the ci.yml header's rejection of a YAML project list), so a scarce mac runner spins up on a PR only when a darwin-relevant project is affected. Resolves distribution OQ-8 | Active (Matt, 2026-08-25) | [distribution §T3](infra/release/compass-distribution/design.md#t3--macos-app-bundle--ci-lane-unsigned) | -| DL-282 | The Compass Linux shell builds Wails' default GTK4 + webkitgtk-6.0 stack (repo tag `gtk4`; closure `gtk4`/`webkitgtk_6_0` in gtk-closure.nix), retiring the legacy `gtk3` + webkit2gtk-4.1 variant ahead of its Wails v3.1 removal; the closure edit is in place (one definition, all consumers). DL-110 (Wails v3) stays Active unchanged, and DL-214/DL-216 (packaging) stay Active — the bundle shape is unchanged, only its closure contents move | Active (Matt, 2026-08-28) | [gtk4 migration §Ledger delta](product/compass-gtk4-migration/design.md#ledger-delta-for-the-coordinator-to-encode-at-freeze--not-edited-here) | +| DL-282 | The Compass Linux shell builds Wails' default GTK4 + webkitgtk-6.0 stack (repo tag `gtk4`; closure `gtk4`/`webkitgtk_6_0` in gtk-closure.nix), retiring the legacy `gtk3` + webkit2gtk-4.1 variant ahead of its Wails v3.1 removal; the closure edit is in place (one definition, all consumers). DL-110 (Wails v3) stays Active unchanged, and DL-214/DL-216 (packaging) stay Active — the bundle shape is unchanged, only its closure contents move | Active (Matt, 2026-08-28) | [gtk4 migration §Ledger delta](ui/compass-gtk4-migration/design.md#ledger-delta-for-the-coordinator-to-encode-at-freeze--not-edited-here) | ## Agent batteries diff --git a/docs/designs/infra/ci/compass-agent-image-publish/design.md b/docs/designs/infra/ci/compass-agent-image-publish/design.md index 0b86553f2..540a7143b 100644 --- a/docs/designs/infra/ci/compass-agent-image-publish/design.md +++ b/docs/designs/infra/ci/compass-agent-image-publish/design.md @@ -10,7 +10,7 @@ Tracking: RIG-1690 (blocks compass-native RIG-1683/T2, RIG-1685/T4, RIG-1687/T6) > below is a path in that repo at HEAD `b3fc25311`, not this one (line numbers > drift as the code evolves; resolve them against that commit). It lives in the > sealed design corpus (`docs/designs/infra/ci/`) because that is where the wave's design -> records freeze; the `docs/designs/product/*` cross-references (e.g. DL-112) +> records freeze; the `docs/designs/ui/*` cross-references (e.g. DL-112) > are paths in this (sealed) corpus. > > **Superseded in part** (RIG-1746, Matt 2026-08-25): the *CI-placement* @@ -37,7 +37,7 @@ Tracking: RIG-1690 (blocks compass-native RIG-1683/T2, RIG-1685/T4, RIG-1687/T6) The `compass-agent` base image already builds and loads locally (`dogfood:agent-image` → `containers-storage:compass-agent:latest`), but per -frozen decision DL-112 (`docs/designs/product/compass-native-app/design.md` +frozen decision DL-112 (`docs/designs/ui/compass-native-app/design.md` §OQ6) the native app does not bundle the agent image: `compass-stack` `podman pull`s it from GHCR at first run. Nothing publishes the image today. This record designs the publish lane — the GHCR side of that seam; the pull side is @@ -75,7 +75,7 @@ decision, not an assumption: A settled fact, not an open question: the consumer's arch is **frozen** in compass-native's merged record (PR #1073, -`docs/designs/product/compass-native-app/design.md`) to Linux x86_64 for the +`docs/designs/ui/compass-native-app/design.md`) to Linux x86_64 for the dogfood milestone — non-Linux runner support and macOS packaging are deferred there to a GA follow-up (`:522-524` "reproducible build of the app bundle for Linux (the dev/dogfood target; macOS packaging diff --git a/docs/designs/infra/ci/compass-dogfood-e2e/design.md b/docs/designs/infra/ci/compass-dogfood-e2e/design.md index 5544c8230..9a828cc3e 100644 --- a/docs/designs/infra/ci/compass-dogfood-e2e/design.md +++ b/docs/designs/infra/ci/compass-dogfood-e2e/design.md @@ -255,7 +255,7 @@ UI today is a browser SolidJS app that dials a door from `VITE_COMPASS_BASE_URL` + `VITE_COMPASS_CALLER_ID` (`apps/ui/src/boot.ts:1-17` "resolving the live connection from the Vite env"; `apps/ui/.env.development:23`), and the native shell (Wails v3, product record -`docs/designs/product/compass-native-app/design.md`) adds an embedded mode +`docs/designs/ui/compass-native-app/design.md`) adds an embedded mode that itself supervises the stack via the SAME `go/internal/stack` (its §A3: "the Wails v3 shell … spawns and monitors ONE" stack) — so the harness core and the native app share the bring-up seam by construction. HOW a test drives diff --git a/docs/designs/infra/release/compass-distribution/design.md b/docs/designs/infra/release/compass-distribution/design.md index e9accd448..08e19e816 100644 --- a/docs/designs/infra/release/compass-distribution/design.md +++ b/docs/designs/infra/release/compass-distribution/design.md @@ -72,7 +72,7 @@ self-host stack (`compass-stack` + `compass-server` + `compass-runner` + postgres) has no distribution home at all — the client-only record's OQ-3 recorded exactly this orphan ("`compass-stack`/`compass-postgres` have no release-artifact home today", -`../../product/compass-native-client-only/design.md:447-462`). This record +`../../../ui/compass-native-client-only/design.md:447-462`). This record designs both surfaces: the client's full OS matrix (Linux AND macOS together) with the install channels users actually reach for (homebrew, nix flakes, a tarball), and the self-hoster's host-level KVM-stack bring-up with postgres diff --git a/docs/designs/infra/release/compass-release-bundling/design.md b/docs/designs/infra/release/compass-release-bundling/design.md index f4d6eaa52..ab91bce00 100644 --- a/docs/designs/infra/release/compass-release-bundling/design.md +++ b/docs/designs/infra/release/compass-release-bundling/design.md @@ -469,7 +469,7 @@ the frozen contract. OQ-4/5/6 stay deferred (non-load-bearing). `compass devenv.nix:189-190` notes the app links the system WebKit framework on macOS, so it does NOT cross-compile from an ubuntu runner) are out of scope here; their release-artifact distribution is decided in the native-packaging - lane (`compass docs/designs/product/compass-native-packaging/design.md`, RIG-1687 + lane (`compass docs/designs/ui/compass-native-packaging/design.md`, RIG-1687 umbrella). The deferral is filed as **RIG-2477** (parented under RIG-1687) so it has a tracked home rather than living only as a design-record note. - *Cross-ref (companion record, same PR):* the client-only pivot's **DL-238** diff --git a/docs/designs/infra/runtime/compass-runner-arbitrary-uid/design.md b/docs/designs/infra/runtime/compass-runner-arbitrary-uid/design.md index 263af0b86..8e5fe7b0c 100644 --- a/docs/designs/infra/runtime/compass-runner-arbitrary-uid/design.md +++ b/docs/designs/infra/runtime/compass-runner-arbitrary-uid/design.md @@ -6,7 +6,7 @@ Status: Draft The embedded compass-runner refuses to start unless its real uid is 1000, which blocks hosted/GA deployments where the host uid is arbitrary -(`docs/designs/product/compass-native-app/design.md` §OQ5 froze the split: +(`docs/designs/ui/compass-native-app/design.md` §OQ5 froze the split: preflight-and-refuse is the interim, arbitrary-uid is the GA-blocking follow-up — this record). The **launch mechanism is already decided and frozen** in the Active record diff --git a/docs/designs/product/compass-gtk4-migration/design.md b/docs/designs/ui/compass-gtk4-migration/design.md similarity index 100% rename from docs/designs/product/compass-gtk4-migration/design.md rename to docs/designs/ui/compass-gtk4-migration/design.md diff --git a/docs/designs/product/compass-multi-window/design.md b/docs/designs/ui/compass-multi-window/design.md similarity index 100% rename from docs/designs/product/compass-multi-window/design.md rename to docs/designs/ui/compass-multi-window/design.md diff --git a/docs/designs/product/compass-native-app/design.md b/docs/designs/ui/compass-native-app/design.md similarity index 100% rename from docs/designs/product/compass-native-app/design.md rename to docs/designs/ui/compass-native-app/design.md diff --git a/docs/designs/product/compass-native-client-mode/design.md b/docs/designs/ui/compass-native-client-mode/design.md similarity index 99% rename from docs/designs/product/compass-native-client-mode/design.md rename to docs/designs/ui/compass-native-client-mode/design.md index 874b67be0..560ff6c61 100644 --- a/docs/designs/product/compass-native-client-mode/design.md +++ b/docs/designs/ui/compass-native-client-mode/design.md @@ -2,7 +2,7 @@ Status: Draft -Refines the frozen parent record `docs/designs/product/compass-native-app/design.md` §T5 + §A4. Design only; no implementation. +Refines the frozen parent record `docs/designs/ui/compass-native-app/design.md` §T5 + §A4. Design only; no implementation. ## Problem / Intent diff --git a/docs/designs/product/compass-native-client-only/design.md b/docs/designs/ui/compass-native-client-only/design.md similarity index 100% rename from docs/designs/product/compass-native-client-only/design.md rename to docs/designs/ui/compass-native-client-only/design.md diff --git a/docs/designs/product/compass-native-packaging/design.md b/docs/designs/ui/compass-native-packaging/design.md similarity index 100% rename from docs/designs/product/compass-native-packaging/design.md rename to docs/designs/ui/compass-native-packaging/design.md diff --git a/docs/designs/product/compass-stack-cross-process-teardown/design.md b/docs/designs/ui/compass-stack-cross-process-teardown/design.md similarity index 99% rename from docs/designs/product/compass-stack-cross-process-teardown/design.md rename to docs/designs/ui/compass-stack-cross-process-teardown/design.md index 831b61c60..d8abbef72 100644 --- a/docs/designs/product/compass-stack-cross-process-teardown/design.md +++ b/docs/designs/ui/compass-stack-cross-process-teardown/design.md @@ -178,7 +178,7 @@ killing the *server* first makes a surviving runner exit on its own when its link drops — both facts the teardown sequence below relies on. **The frozen record's claim this realizes.** -`docs/designs/product/compass-native-app/design.md:204-206`: +`docs/designs/ui/compass-native-app/design.md:204-206`: > ```text > On app quit, per DL-108: the stack lingers by default; diff --git a/docs/designs/product/compass-tauri-shell.md b/docs/designs/ui/compass-tauri-shell.md similarity index 100% rename from docs/designs/product/compass-tauri-shell.md rename to docs/designs/ui/compass-tauri-shell.md diff --git a/go/e2e/client_mode_test.go b/go/e2e/client_mode_test.go index 430bce2cd..a642ff7f6 100644 --- a/go/e2e/client_mode_test.go +++ b/go/e2e/client_mode_test.go @@ -3,7 +3,7 @@ package e2e // TestClientModeHeadlessChain is the T5.7 headless CI variant -// (docs/designs/product/compass-native-client-mode/design.md §T5.7, lines +// (docs/designs/ui/compass-native-client-mode/design.md §T5.7, lines // 582-598). The webview-dependent steps (connect screen renders, paste-token, // board renders, auto-connect-no-screen) are manual QA on the dev box with // T5.3's TestConnectClassification as the CI proxy, mirroring T4's split — they diff --git a/tools/design-ledger-gate/index.test.ts b/tools/design-ledger-gate/index.test.ts index ddb490114..c4adf2705 100644 --- a/tools/design-ledger-gate/index.test.ts +++ b/tools/design-ledger-gate/index.test.ts @@ -106,15 +106,11 @@ describe("splitLink", () => { }); describe("touchesRecord", () => { - test("a /design.md product record is a record", () => { - expect(touchesRecord("docs/designs/product/compass-0.6/design.md")).toBe( - true, - ); + test("a /design.md record is a record", () => { + expect(touchesRecord("docs/designs/ui/compass-0.6/design.md")).toBe(true); }); - test("a top-level .md product record is a record", () => { - expect(touchesRecord("docs/designs/product/compass-tauri-shell.md")).toBe( - true, - ); + test("a top-level .md record is a record", () => { + expect(touchesRecord("docs/designs/ui/compass-tauri-shell.md")).toBe(true); }); test("a record under a second governed root (agent) is a record", () => { expect(touchesRecord("docs/designs/agent/compass-x/design.md")).toBe(true); @@ -131,7 +127,7 @@ describe("touchesRecord", () => { expect(touchesRecord("docs/designs/DECISIONS.md")).toBe(false); }); test("a nested non-design.md file is not a record", () => { - expect(touchesRecord("docs/designs/product/foo/bar.md")).toBe(false); + expect(touchesRecord("docs/designs/ui/foo/bar.md")).toBe(false); }); test("a flat .md inside a subgroup is NOT a record (governed at root only)", () => { expect(touchesRecord("docs/designs/infra/ci/foo.md")).toBe(false); @@ -142,8 +138,8 @@ describe("touchesRecord", () => { test("a file under a non-bucket path is not a record", () => { expect(touchesRecord("docs/designs/notabucket/x.md")).toBe(false); }); - test("a non-markdown product file is not a record", () => { - expect(touchesRecord("docs/designs/product/notes.txt")).toBe(false); + test("a non-markdown file is not a record", () => { + expect(touchesRecord("docs/designs/ui/notes.txt")).toBe(false); }); }); @@ -151,10 +147,10 @@ describe("resolveRecordRelative", () => { test("a nested record's `../sibling` pointer → designs-root-relative sibling", () => { expect( resolveRecordRelative( - "product/compass-0.6/design.md", + "ui/compass-0.6/design.md", "../compass-0.8/design.md", ), - ).toBe("product/compass-0.8/design.md"); + ).toBe("ui/compass-0.8/design.md"); }); test("a cross-bucket pointer resolves inside DESIGNS_ROOT", () => { // A ui/ record superseded by an agent/ record: `../../agent/...` from @@ -286,9 +282,9 @@ function row(overrides: Partial = {}): LedgerRow { function header(overrides: Partial = {}): RecordHeader { return { - // A top-level product record NOT in the version-narrative chain, so a + // A top-level record NOT in the version-narrative chain, so a // baseline `Status: Active` is valid. - path: "docs/designs/product/compass-tauri-shell.md", + path: "docs/designs/ui/compass-tauri-shell.md", statusLine: "Status: Active", line: 3, ...overrides, @@ -720,7 +716,7 @@ describe("evaluate — record Status: header presence & grammar", () => { ); expect(vs.length).toBe(1); expect(vs[0]?.message).toContain("missing"); - expect(vs[0]?.file).toBe("docs/designs/product/compass-tauri-shell.md"); + expect(vs[0]?.file).toBe("docs/designs/ui/compass-tauri-shell.md"); expect(vs[0]?.line).toBe(3); }); test("malformed status header → 'malformed'", () => { @@ -734,13 +730,12 @@ describe("evaluate — record Status: header presence & grammar", () => { expect(vs[0]?.message).toContain("malformed"); expect(vs[0]?.line).toBe(3); }); - test("newly-governed non-product bucket record, statusLine null → 'missing'", () => { - // The cutover made non-product buckets governed (repo/, infra/, …), - // which is why compass-eng-docs/design.md had to gain `Status: Active`. - // This locks that a record under a NON-product governed bucket is - // header-enforced identically — a regression that special-cased the - // product bucket for header presence would pass the product tests above - // yet silently un-enforce every repo/infra/ui/… record. + test("a record under any governed bucket, statusLine null → 'missing'", () => { + // Every governed bucket (repo/, infra/, ui/, …) is header-enforced + // identically — which is why compass-eng-docs/design.md had to gain + // `Status: Active`. This locks that a record under a governed bucket + // other than the one the fixtures above use is enforced the same way, + // so no bucket can be silently un-enforced. const vs = evaluate( [row()], [ @@ -777,7 +772,7 @@ describe("evaluate — Historical-set membership", () => { [], [ header({ - path: "docs/designs/product/compass-tauri-shell.md", + path: "docs/designs/ui/compass-tauri-shell.md", statusLine: "Status: Historical", }), ], @@ -793,7 +788,7 @@ describe("evaluate — Historical-set membership", () => { [], [ header({ - path: "docs/designs/product/compass-tauri-shell.md", + path: "docs/designs/ui/compass-tauri-shell.md", statusLine: "Status: Active", }), ], @@ -820,7 +815,7 @@ describe("evaluate — record-level Superseded pointer", () => { [], [ header({ - path: "docs/designs/product/compass-tauri-shell.md", + path: "docs/designs/ui/compass-tauri-shell.md", statusLine: "Status: Superseded by ../other/design.md", }), ], @@ -833,7 +828,7 @@ describe("evaluate — record-level Superseded pointer", () => { }); test("record-relative pointer resolves to a sibling under a nested record", () => { // A nested non-chain record + `../sibling/design.md` → designs-root-relative - // `product/sibling/design.md`. The resolver only knows that path, so a + // `ui/sibling/design.md`. The resolver only knows that path, so a // correct base is the only way this passes. expect( evaluate( @@ -894,19 +889,19 @@ describe("evaluate — record-level Superseded pointer", () => { [], [ header({ - path: "docs/designs/product/compass-tauri-shell.md", + path: "docs/designs/ui/compass-tauri-shell.md", statusLine: "Status: Superseded by other-record.md", }), ], noChange, - onlyExists("product/other-record.md"), + onlyExists("ui/other-record.md"), ), ).toEqual([]); }); }); describe("evaluate — touch-coupling (DL-Q1)", () => { - const rec = "docs/designs/product/compass-0.6/design.md"; + const rec = "docs/designs/ui/compass-0.6/design.md"; test("touches a record, not the ledger, no declaration → one violation", () => { const vs = evaluate( @@ -982,7 +977,7 @@ describe("runOnce", () => { "| --- | --- | --- | --- |", "| DL-001 | use X | Active (Matt, 2026-07-22) | [r](compass-0.6/design.md) |", ].join("\n"); - const oneRecord = "docs/designs/product/compass-tauri-shell.md"; + const oneRecord = "docs/designs/ui/compass-tauri-shell.md"; function deps(overrides: Partial): { d: Deps; diff --git a/tools/design-ledger-gate/index.ts b/tools/design-ledger-gate/index.ts index 5823616ba..e2a1d3a27 100644 --- a/tools/design-ledger-gate/index.ts +++ b/tools/design-ledger-gate/index.ts @@ -44,10 +44,8 @@ import { $ } from "bun"; /** The design-corpus root the gate governs (all buckets beneath it). */ export const DESIGNS_ROOT = "docs/designs"; /** - * The governed buckets under `DESIGNS_ROOT`. `product` is transitional — the - * reorg (RIG-2577) dissolves it into the other buckets; it stays in the list - * (still governed) until the RIG-2542-gated native sweep empties it. An empty - * bucket directory scans to zero records, which is green. + * The governed buckets under `DESIGNS_ROOT`. Every record lives under exactly + * one of these; a file outside them is not a governed record. */ export const GOVERNED_ROOTS: readonly string[] = [ "ui", @@ -57,7 +55,6 @@ export const GOVERNED_ROOTS: readonly string[] = [ "infra", "observability", "repo", - "product", ]; /** The canonical ledger, parsed as the decision table (never as a record). */ export const DECISIONS_PATH = `${DESIGNS_ROOT}/DECISIONS.md`; diff --git a/tools/renovate/config.json5 b/tools/renovate/config.json5 index 78e39a4db..c61a090ab 100644 --- a/tools/renovate/config.json5 +++ b/tools/renovate/config.json5 @@ -444,7 +444,7 @@ { // ── wails/v3: hold below v3.1 (GTK4-migration floor, RIG-2818/RIG-2819) ── // The GTK4 migration record freezes a hard "Never v3.1" floor - // (docs/designs/product/compass-gtk4-migration/design.md §Global Constraints + // (docs/designs/ui/compass-gtk4-migration/design.md §Global Constraints // "Wails floor"): wails v3.1 drops the legacy GTK3 build tag, so bumping to it // before the GTK4 flip (RIG-2819) is proven would strand the app with no // working native shell. go/go.mod pins a v3.0.0 prerelease today; Renovate would