Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions docs/designs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
36 changes: 18 additions & 18 deletions docs/designs/DECISIONS.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/designs/infra/ci/compass-agent-image-publish/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion docs/designs/infra/ci/compass-dogfood-e2e/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion go/e2e/client_mode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
57 changes: 26 additions & 31 deletions tools/design-ledger-gate/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,11 @@ describe("splitLink", () => {
});

describe("touchesRecord", () => {
test("a <name>/design.md product record is a record", () => {
expect(touchesRecord("docs/designs/product/compass-0.6/design.md")).toBe(
true,
);
test("a <name>/design.md record is a record", () => {
expect(touchesRecord("docs/designs/ui/compass-0.6/design.md")).toBe(true);
});
test("a top-level <name>.md product record is a record", () => {
expect(touchesRecord("docs/designs/product/compass-tauri-shell.md")).toBe(
true,
);
test("a top-level <name>.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);
Expand All @@ -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);
Expand All @@ -142,19 +138,19 @@ 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);
});
});

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
Expand Down Expand Up @@ -286,9 +282,9 @@ function row(overrides: Partial<LedgerRow> = {}): LedgerRow {

function header(overrides: Partial<RecordHeader> = {}): 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,
Expand Down Expand Up @@ -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'", () => {
Expand All @@ -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()],
[
Expand Down Expand Up @@ -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",
}),
],
Expand All @@ -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",
}),
],
Expand All @@ -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",
}),
],
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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<Deps>): {
d: Deps;
Expand Down
7 changes: 2 additions & 5 deletions tools/design-ledger-gate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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`;
Expand Down
2 changes: 1 addition & 1 deletion tools/renovate/config.json5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading