From 526daed23781f016dd333ee776330805510d1d5a Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Sat, 6 Jun 2026 12:33:51 +0200 Subject: [PATCH] =?UTF-8?q?sweep=20stale=20DQR=20anchor=20slugs=20to=20can?= =?UTF-8?q?onical=20(em-dash=20=E2=86=92=20double-hyphen,=20retitled=20rec?= =?UTF-8?q?ords)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes 11 distinct inline anchor slugs that drifted from the generated canonical form: em-dash titles render `--` (single-hyphen links were stale), plus several truncated/old slugs (D-5, D-10, D-21, D-39, D-40, D-43, D-68, Q-1, Q-32, Q-33). pql resolves cross-refs by ID so these were never "broken" to the tooling, but they'd fail GitHub markdown anchor navigation. Verified: every inline anchor now matches the README index; pql decisions sync reports 0 broken refs. Does NOT touch the separate stale-path class (flat `questions-*.md` / `rejected.md` naming from before the DQR subdir split) — surfaced for a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) --- governance/decisions/architecture.md | 16 ++++++++-------- governance/decisions/extensions.md | 2 +- governance/questions/architecture.md | 8 ++++---- governance/questions/process.md | 2 +- governance/rejected/accessibility.md | 2 +- governance/rejected/architecture.md | 8 ++++---- governance/rejected/process.md | 10 +++++----- governance/rejected/testing.md | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/governance/decisions/architecture.md b/governance/decisions/architecture.md index 5814404b..13dfbdef 100644 --- a/governance/decisions/architecture.md +++ b/governance/decisions/architecture.md @@ -73,7 +73,7 @@ Core, rendering, IPC, kernel, panel manager. ### D-1: CLI-first, not MCP - **Date:** 2026-04-20 (was ADR 0001; ported from the claudian lineage) -- **Amendment (2026-05-15):** D-1's intent — the CLI is the *primary* agent-facing surface, with the same contract as pql — stands. An additional `/ide`-compatible MCP surface is added per [D-68](#d-68-dual-integration-surface-bash-cli-primary-mcp-secondary); both wrap the same in-process dispatcher. The escape-hatch line in this record's Cost ("nothing here precludes adding [MCP] later that shells out to the same CLI") is realised — the MCP server does not bypass the CLI's surface, it offers a second transport to it. +- **Amendment (2026-05-15):** D-1's intent — the CLI is the *primary* agent-facing surface, with the same contract as pql — stands. An additional `/ide`-compatible MCP surface is added per [D-68](#d-68-dual-integration-surface--bash-cli-primary-mcp-secondary); both wrap the same in-process dispatcher. The escape-hatch line in this record's Cost ("nothing here precludes adding [MCP] later that shells out to the same CLI") is realised — the MCP server does not bypass the CLI's surface, it offers a second transport to it. - **Decision:** Claude talks to clide exclusively via Bash (`clide …`). No MCP server. No protocol layer in Claude's face. The CLI uses the same exit-code + stderr-JSON contract as pql. - **Context:** The two mainstream options for the agent-facing surface were an MCP server or a plain Bash CLI matching pql's contract. - **Rationale:** Same mental model as pql for the agent — one tool-use pattern covers both. No MCP runtime to host, authenticate, or keep in sync with client versions. User/Claude parity is easier to enforce: every CLI subcommand must have a UI affordance in the Flutter app and vice versa ([D-6](#d-6-cli-and-event-surface-contract)). Claude Code's `Bash(clide *)` allow rule is the only configuration clide needs on the agent side. @@ -86,7 +86,7 @@ Core, rendering, IPC, kernel, panel manager. - **Context:** [`pql`](https://github.com/postmeridiem/pql) is a pre-existing Go CLI that indexes a markdown-bearing directory tree into SQLite and exposes frontmatter, wikilinks, tags, headings, and bases through a query surface. Clide needs those capabilities for its Query panel, canvas drivers, graph view, and any feature that needs to know structure. - **Rationale:** One source of truth for markdown semantics. Any new query capability the UI wants goes through a pql upstream PR, not a local workaround. Users never have to learn pql's config file to get consistent behaviour — clide manages it. The arrow clide → pql is never inverted: pql stays ignorant of its wrapper. - **Cost:** Clide's `lib/src/pql/` package is deliberately thin. pql is also the **only** query engine — Obsidian-style inline "bases" are explicitly not supported; queries live at the repo level. In repos without clide, pql works standalone unaffected. -- **Raised by:** Ported from the claudian lineage. Load-bearing for [D-39](process.md#d-39-planning-tooling-lives-in-pql). +- **Raised by:** Ported from the claudian lineage. Load-bearing for [D-39](process.md#d-39-planning-tooling-lives-in-pql-not-clide). ### D-4: Ignore file strategy - **Date:** 2026-04-20 (was ADR 0004; ported from the claudian lineage) @@ -112,7 +112,7 @@ Core, rendering, IPC, kernel, panel manager. - **Decision:** The CLI is organised into **subsystems**. Each subsystem owns a noun, a set of verbs, and a set of events. The set is closed at any point in time (documented); growth is additive (new verbs, new events — never renaming existing ones without a version bump). Initial subsystems (by tier): `pane`, `tab`, `open`, `editor`, `panel`, `tree`, `git`, `pql`, `canvas`, `graph`, `theme`, `settings`, `project`. Two umbrella entry points sit outside any subsystem: `clide tail --events [--filter [:]]` and `clide status`. Command shape: `clide [...] [--flag ...] [-- argv...]`. Exit codes parity with pql (`0/1/2/3/4` + `64-78` sysexits reserved); diagnostic JSON on **stderr** on non-zero exit; stdout stays machine-parseable on success. Events are JSON objects, one per line, with `v`, `ts`, `type` (`.`), `subsystem`, `id`, and `payload`; binary payloads base64. Every state-changing command emits at least one event; read-only commands emit nothing. Replay buffer per subsystem (default depth 16) so late subscribers still see recent effects. Parity rule: every UI affordance has a matching CLI verb (or a follow-up task naming the verb); every CLI verb surfaces in the UI (or documents why it's Claude-only). - **Context:** [D-1](#d-1-cli-first-not-mcp) established that Claude drives clide via a Bash CLI. That decided the *channel* — it did not define the *surface*. CLAUDE.md stated the rule colloquially ("every CLI subcommand has a UI affordance … if you add one side without the other, the feature is incomplete"); this record restates it as an implementable contract that satisfies user/Claude parity, daemon-as-authoritative-state, and pql-style ergonomics at once. - **Rationale:** Surface is enumerable — adding a subsystem means adding a row and specifying verbs + events. Wire schema is versioned (`v: 1` starting point; compatibility breaks bump the major and land alongside a `pubspec.yaml` `schema_version:` bump — see [Q-5](questions-architecture.md#q-5-ipc-wire-format-stability)). Events are the only UI→app state channel; the Flutter app does not poll. Extensions inherit this — a Dart extension publishes a subsystem; the same registration pipeline exposes it to Claude via the CLI. -- **Cost:** Replay-buffer memory per subsystem (cheap — most emit seldom). Back-pressure on firehose streams ([Q-2](questions-architecture.md#q-2-back-pressure-on-event-streams)), authorisation granularity ([Q-1](questions-architecture.md#q-1-authorisation-granularity)), and event persistence ([Q-3](questions-architecture.md#q-3-event-persistence-audit-undo)) are all deferred until Tier 1 is in real use. +- **Cost:** Replay-buffer memory per subsystem (cheap — most emit seldom). Back-pressure on firehose streams ([Q-2](questions-architecture.md#q-2-back-pressure-on-event-streams)), authorisation granularity ([Q-1](questions-architecture.md#q-1-authorisation-granularity-on-the-ipc-socket)), and event persistence ([Q-3](questions-architecture.md#q-3-event-persistence-audit-undo)) are all deferred until Tier 1 is in real use. - **Raised by:** 2026-04-20 planning. ### D-43: Design handoff — adopt token palettes, reject Material wrapper @@ -128,7 +128,7 @@ Core, rendering, IPC, kernel, panel manager. - **Decision:** Ship four bundled themes replacing the single summer-night preset. `clide` (cool near-black + periwinkle, default), `midnight` (VS Code-adjacent muted dark), `paper` (drafting-sheet light), `terminal` (near-black + amber). All share the same semantic token names. Source palettes in `docs/claude-design/themes/`; runtime YAML under `lib/kernel/src/theme/themes/`. - **Rationale:** Summer-night was a placeholder carried from the legacy TUI. The design system delivers a coherent set of four that covers dark, muted-dark, light, and monochrome workflows. - **Cost:** Summer-night users lose their theme (acceptable — it was dev-only). Four YAML files to maintain. -- **Cross-reference:** [D-43](#d-43-design-handoff-adopt-token-palettes-reject-material-wrapper), [D-22](accessibility.md#d-22-wcag-aa-contrast-gate-on-bundled-themes). +- **Cross-reference:** [D-43](#d-43-design-handoff--adopt-token-palettes-reject-material-wrapper), [D-22](accessibility.md#d-22-wcag-aa-contrast-gate-on-bundled-themes). - **Raised by:** 2026-04-22 design handoff review. ### D-45: Syntax highlighting tokens in the theme pipeline @@ -250,11 +250,11 @@ Core, rendering, IPC, kernel, panel manager. ### D-68: Dual integration surface — Bash CLI primary, MCP secondary - **Date:** 2026-05-15 - **Amendment (2026-05-19):** Both surfaces implemented in T-99. CLI lands as `IpcServer` over the unix socket (T-124, per D-70/71/72) with the C client at `native/clide-cli/clide.c` (T-126); the argv grammar lives in `lib/src/cli/argv_to_request.dart` (T-125). MCP lands as `McpServer` over HTTP+SSE (T-130, per D-73) — the transport choice closed Q-33. The two `/ide` minimum tools ship as stubs; real implementations follow as Q-32 resolves the broader tool-surface question. -- **Decision:** clide exposes two integration surfaces over the same in-process `DaemonDispatcher`. **(1) Bash CLI over Unix socket — primary.** Per [D-1](#d-1-cli-first-not-mcp) and [D-56](#d-56-dissolve-daemon-process-flutter-app-hosts-ipc-server), a thin C client (`clide …`) connects to a per-user Unix socket served in-process by the Flutter app, exchanges JSON-lines, and exits. This is the surface Claude-Code-in-a-pane uses; it is also the surface for human shell use, scripts, and external editor integrations. Full action surface — `pane.*`, `files.*`, `editor.*`, `git.*`, `pql.*`, …. **(2) `/ide`-compatible MCP server — secondary.** clide additionally serves an MCP endpoint compatible with Claude Code's `/ide` integration (the same protocol VS Code and JetBrains plugins serve). Minimum tools: `mcp__ide__getDiagnostics`, `mcp__ide__executeCode`. Optional `mcp__clide__*` namespace exposing high-leverage clide tools is deferred to [Q-32](../questions/architecture.md#q-32-mcp-tool-surface-minimum-slash-ide-or-extended-clide-tools). Transport closed by [D-73](#d-73-mcp-transport-for-ide-is-sse-over-http) — SSE over HTTP. The MCP server wraps the *same* `DaemonDispatcher`; there is no second source of truth. +- **Decision:** clide exposes two integration surfaces over the same in-process `DaemonDispatcher`. **(1) Bash CLI over Unix socket — primary.** Per [D-1](#d-1-cli-first-not-mcp) and [D-56](#d-56-dissolve-daemon-process-flutter-app-hosts-ipc-server), a thin C client (`clide …`) connects to a per-user Unix socket served in-process by the Flutter app, exchanges JSON-lines, and exits. This is the surface Claude-Code-in-a-pane uses; it is also the surface for human shell use, scripts, and external editor integrations. Full action surface — `pane.*`, `files.*`, `editor.*`, `git.*`, `pql.*`, …. **(2) `/ide`-compatible MCP server — secondary.** clide additionally serves an MCP endpoint compatible with Claude Code's `/ide` integration (the same protocol VS Code and JetBrains plugins serve). Minimum tools: `mcp__ide__getDiagnostics`, `mcp__ide__executeCode`. Optional `mcp__clide__*` namespace exposing high-leverage clide tools is deferred to [Q-32](../questions/architecture.md#q-32-mcp-tool-surface--minimum-slash-ide-or-extended-clide-tools). Transport closed by [D-73](#d-73-mcp-transport-for-ide-is-sse-over-http) — SSE over HTTP. The MCP server wraps the *same* `DaemonDispatcher`; there is no second source of truth. - **Context:** [D-1](#d-1-cli-first-not-mcp) chose CLI-first over MCP-only because MCP alone doesn't cover the action surface clide needs — Claude Code's `/ide` MCP exposes only two narrow tools (`getDiagnostics`, `executeCode`), enough for Claude to read diagnostics and run Jupyter cells but not enough to *drive* an IDE. The CLI surface gives full reach. But for users who run Claude Code *outside* clide and connect via `/ide`, MCP is the only path Claude Code knows; not serving it means clide is invisible to that workflow. The two surfaces are complementary, not alternatives. Reinforced by the [2026-05-14 consultant review](../../consultants.md): the architect flagged the absent socket server as the most critical drift; user confirmed the socket server (D-56 path a) plus an MCP companion. - **Rationale:** Both surfaces wrap the same dispatcher, so neither becomes a second source of truth. CLI remains the contract user/Claude parity ([D-6](#d-6-cli-and-event-surface-contract)) is enforced against. MCP is added because the `/ide` ecosystem is real and growing — VS Code, JetBrains, Cursor, Windsurf all serve compatible MCP — and clide should be a peer there. The implementation cost is a protocol adapter + tool definitions, not duplicate business logic. - **Cost:** Two transports to maintain. Mitigated by both wrapping the same dispatcher: the MCP adapter is the only thing that has to track `/ide` protocol evolution. If `mcp__clide__*` tools are added (pending Q-32), surface bloat is the obvious risk — every CLI verb invites an MCP twin; resist by default, justify on user need. -- **Cross-reference:** [D-1](#d-1-cli-first-not-mcp) (amended — see amendment line there), [D-6](#d-6-cli-and-event-surface-contract), [D-56](#d-56-dissolve-daemon-process-flutter-app-hosts-ipc-server), [Q-32](../questions/architecture.md#q-32-mcp-tool-surface-minimum-slash-ide-or-extended-clide-tools), [Q-33](../questions/architecture.md#q-33-mcp-transport-sse-websocket-stdio-or-all). +- **Cross-reference:** [D-1](#d-1-cli-first-not-mcp) (amended — see amendment line there), [D-6](#d-6-cli-and-event-surface-contract), [D-56](#d-56-dissolve-daemon-process-flutter-app-hosts-ipc-server), [Q-32](../questions/architecture.md#q-32-mcp-tool-surface--minimum-slash-ide-or-extended-clide-tools), [Q-33](../questions/architecture.md#q-33-mcp-transport--sse-websocket-stdio-or-all). - **Raised by:** 2026-05-15 — consultant review (`consultants.md`) flagged the absent socket server (D-56 unimplemented) as the highest architectural drift; user chose option (a) "implement the server" and asked for MCP coverage alongside. ### D-70: IPC socket path is per-workspace, deterministic @@ -267,10 +267,10 @@ Core, rendering, IPC, kernel, panel manager. ### D-71: IPC socket access gated by chmod 0600 on socket + parent - **Date:** 2026-05-18 -- **Decision:** The IPC socket file and its parent directory ([D-70](#d-70-ipc-socket-path-is-per-workspace-deterministic)) are created with permissions `0600` (owner read/write only) and `0700` respectively. No token-based auth at the IPC layer; the Unix file-permission check is the only gate. Capability-scoped auth for third-party Lua/Dart extensions is a separate concern and remains tracked by [Q-1](../questions/architecture.md#q-1-authorisation-granularity) for when extensions actually need it. +- **Decision:** The IPC socket file and its parent directory ([D-70](#d-70-ipc-socket-path-is-per-workspace-deterministic)) are created with permissions `0600` (owner read/write only) and `0700` respectively. No token-based auth at the IPC layer; the Unix file-permission check is the only gate. Capability-scoped auth for third-party Lua/Dart extensions is a separate concern and remains tracked by [Q-1](../questions/architecture.md#q-1-authorisation-granularity-on-the-ipc-socket) for when extensions actually need it. - **Rationale:** clide's threat model on a developer workstation is "another user on the same host should not be able to drive my IDE." File perms cover this exhaustively — the kernel enforces the check on every `connect(2)`, no userspace token comparison can match that. Adding a session token on top would be belt-and-suspenders without expanding the threat model. Capability tokens become useful when extensions can publish their own dispatcher routes and we want to gate which third-party code can reach which subsystem — but that's a Tier-6 concern. - **Cost:** Doesn't defend against same-uid attacks (a malicious process running as the user can connect). Accepted — same-uid is outside this layer's threat model; that's a sandboxing / capability concern that lives further out. Doesn't work on shared multi-user dev hosts where one socket needs to be reachable by multiple uids — clide isn't targeted at that workflow today. -- **Cross-reference:** [D-70](#d-70-ipc-socket-path-is-per-workspace-deterministic), [Q-1](../questions/architecture.md#q-1-authorisation-granularity). +- **Cross-reference:** [D-70](#d-70-ipc-socket-path-is-per-workspace-deterministic), [Q-1](../questions/architecture.md#q-1-authorisation-granularity-on-the-ipc-socket). - **Raised by:** 2026-05-18 — T-99 design pass. ### D-72: IPC server is multi-connection with serial dispatch on the main isolate diff --git a/governance/decisions/extensions.md b/governance/decisions/extensions.md index cf3940d7..34ad8303 100644 --- a/governance/decisions/extensions.md +++ b/governance/decisions/extensions.md @@ -27,7 +27,7 @@ Extension contract, Lua runtime, grain, contribution points. ### D-18: YAML for themes + manifests; JSON for i18n catalogs - **Date:** 2026-04-21 -- **Decision:** Themes and extension manifests are YAML; i18n catalogues are JSON (fframe parity — see [D-21](accessibility.md#d-21-i18n-is-a-tier-0-contract)). +- **Decision:** Themes and extension manifests are YAML; i18n catalogues are JSON (fframe parity — see [D-21](accessibility.md#d-21-i18n-is-a-tier-0-contract-fframe-pattern--locale-fallback-chain)). - **Rationale:** YAML for human-edited config files (themes, manifests) — comments, multi-line strings, less noise. JSON for machine-written / machine-read files (i18n catalogs get generated by translation tooling eventually). Mixing is fine; each format is where it's best. - **Cost:** Two parsers in the tree. `yaml: 3.1.3` is exact-pinned. - **Raised by:** 2026-04-21 planning. diff --git a/governance/questions/architecture.md b/governance/questions/architecture.md index d8b352cb..1a0d2594 100644 --- a/governance/questions/architecture.md +++ b/governance/questions/architecture.md @@ -134,15 +134,15 @@ ticket persistence. ### Q-32: MCP tool surface — minimum slash-ide or extended clide tools? - **Status:** Resolved → [D-86](../decisions/architecture.md#d-86-mcp-tool-surface--full-clide-namespace-generated-from-the-co-registered-command-registry) - **Resolved (2026-06-06):** Full `mcp__clide__*` namespace, but **generated from the co-registered command registry** ([D-74](../decisions/architecture.md#d-74-ipc-command-schema-is-co-registered-with-the-handler-validated-at-dispatch)) that already feeds the CLI + palette — so breadth costs no hand-maintained second surface, and the extensions-first model needs registry-driven surfacing anyway. Per-command MCP opt-out for poor-fit verbs. -- **Question:** [D-68](../decisions/architecture.md#d-68-dual-integration-surface-bash-cli-primary-mcp-secondary) commits clide to an `/ide`-compatible MCP server. The minimum surface is the two tools Claude Code's `/ide` integration currently expects: `mcp__ide__getDiagnostics` (lint/diagnostics for a file) and `mcp__ide__executeCode` (run code in a Jupyter kernel). Do we stop there, or also expose a `mcp__clide__*` namespace with higher-leverage tools (`open_file`, `goto_symbol`, `pql_query`, `pane_spawn`, `git_status`, …) so MCP clients other than Claude Code (Cursor, Windsurf, VS Code Copilot) can drive clide as a real backend? +- **Question:** [D-68](../decisions/architecture.md#d-68-dual-integration-surface--bash-cli-primary-mcp-secondary) commits clide to an `/ide`-compatible MCP server. The minimum surface is the two tools Claude Code's `/ide` integration currently expects: `mcp__ide__getDiagnostics` (lint/diagnostics for a file) and `mcp__ide__executeCode` (run code in a Jupyter kernel). Do we stop there, or also expose a `mcp__clide__*` namespace with higher-leverage tools (`open_file`, `goto_symbol`, `pql_query`, `pane_spawn`, `git_status`, …) so MCP clients other than Claude Code (Cursor, Windsurf, VS Code Copilot) can drive clide as a real backend? - **Context:** The minimum surface keeps clide a good citizen in the `/ide` ecosystem and avoids duplicating the CLI in MCP form. The extended surface would let non-Claude-Code MCP clients integrate richly, but invites surface bloat (every CLI verb tempted to gain an MCP twin) and a maintenance second front. Note that for *Claude-Code-in-a-clide-pane*, the CLI surface already covers this — extended MCP tools serve external MCP clients only. -- **Source:** [D-68](../decisions/architecture.md#d-68-dual-integration-surface-bash-cli-primary-mcp-secondary). +- **Source:** [D-68](../decisions/architecture.md#d-68-dual-integration-surface--bash-cli-primary-mcp-secondary). ### Q-33: MCP transport — SSE, WebSocket, stdio, or all? - **Status:** Resolved → [D-73](../decisions/architecture.md#d-73-mcp-transport-for-ide-is-sse-over-http) - **Resolved (2026-05-19, drift-fixed 2026-06-06):** SSE over HTTP only. Closed by D-73 (and confirmed in D-68's amendment) at the time, but this index was never flipped from Open. Re-confirmed 2026-06-06: stdio/WebSocket not added — D-73's reasoning (the always-running GUI is *connected to*, not spawned) still holds and no external process-spawn MCP client is a concrete need yet. - **Question:** Claude Code's `/ide` integration connects via SSE-IDE or WS-IDE (URL passed at startup). MCP also supports stdio for process-spawn clients. Which transport(s) should clide's MCP server expose — SSE only (the most common `/ide` server pattern), SSE + WS (broader compatibility), or all three including stdio? -- **Context:** Transport choice affects discovery and lifecycle. SSE/WS need a port and a published URL, which collides with the `XDG_RUNTIME_DIR` Unix-socket model used for the CLI; we'd likely publish the URL alongside the socket path (env var or `XDG_RUNTIME_DIR` discovery file). stdio is process-per-client and works for clients that prefer process-spawn over network. Decision interacts with [Q-32](#q-32-mcp-tool-surface-minimum-slash-ide-or-extended-clide-tools) — if the surface stays at the `/ide` minimum, SSE alone is sufficient. -- **Source:** [D-68](../decisions/architecture.md#d-68-dual-integration-surface-bash-cli-primary-mcp-secondary). +- **Context:** Transport choice affects discovery and lifecycle. SSE/WS need a port and a published URL, which collides with the `XDG_RUNTIME_DIR` Unix-socket model used for the CLI; we'd likely publish the URL alongside the socket path (env var or `XDG_RUNTIME_DIR` discovery file). stdio is process-per-client and works for clients that prefer process-spawn over network. Decision interacts with [Q-32](#q-32-mcp-tool-surface--minimum-slash-ide-or-extended-clide-tools) — if the surface stays at the `/ide` minimum, SSE alone is sufficient. +- **Source:** [D-68](../decisions/architecture.md#d-68-dual-integration-surface--bash-cli-primary-mcp-secondary). --- diff --git a/governance/questions/process.md b/governance/questions/process.md index 91a277fd..18896523 100644 --- a/governance/questions/process.md +++ b/governance/questions/process.md @@ -33,7 +33,7 @@ Tooling-domain questions currently live here too. Split into ### Q-19: (withdrawn) - **Status:** Resolved → n/a -- **Note:** Earlier floated as "ticket markdown mirror vs SQLite" — no longer a split question. Markdown mirror is tracked in [Q-22](questions-architecture.md#q-22-ticket-persistence-strategy); SQLite is the current stopgap per [D-40](process.md#d-40-python-stopgap-under-toolsscriptsplan). +- **Note:** Earlier floated as "ticket markdown mirror vs SQLite" — no longer a split question. Markdown mirror is tracked in [Q-22](questions-architecture.md#q-22-ticket-persistence-strategy); SQLite is the current stopgap per [D-40](process.md#d-40-superseded-python-stopgap-under-toolsscriptsplan). ### Q-20: Kernel DB service — namespaced SQL access? - **Status:** Open diff --git a/governance/rejected/accessibility.md b/governance/rejected/accessibility.md index bbf0b135..d310c234 100644 --- a/governance/rejected/accessibility.md +++ b/governance/rejected/accessibility.md @@ -8,6 +8,6 @@ future reference. ### R-4: Flutter `intl` + ARB codegen for i18n - **Rejected:** 2026-04-21 - **Reason:** ARB codegen is inflexible for plugin-contributed catalogs — every catalogue needs a codegen pass, every extension ships with pre-generated Dart, and runtime merging is fighting the tool. The fframe text-driven pattern reads JSON at runtime with no codegen, which fits extension-shipped catalogs cleanly. -- **Cross-reference:** [D-21](../decisions/accessibility.md#d-21-i18n-is-a-tier-0-contract) +- **Cross-reference:** [D-21](../decisions/accessibility.md#d-21-i18n-is-a-tier-0-contract-fframe-pattern--locale-fallback-chain) --- diff --git a/governance/rejected/architecture.md b/governance/rejected/architecture.md index 00ec582f..c792d049 100644 --- a/governance/rejected/architecture.md +++ b/governance/rejected/architecture.md @@ -6,9 +6,9 @@ future reference. --- ### R-2: Go sidecar -- **Rejected:** 2026-04-20 (was ADR 0002; superseded by [D-5](../decisions/architecture.md#d-5-dart-core-ptyc-peer)) +- **Rejected:** 2026-04-20 (was ADR 0002; superseded by [D-5](../decisions/architecture.md#d-5-dart-core-sidecar-dissolved-ptyc-as-pql-peer)) - **Reason:** The ADR picked Go on two premises — (a) the heavy work belongs in a language separate from the UI layer, and (b) pql is Go so muscle memory transfers. Both broke on reassessment. The sidecar stripped of PTY is I/O-bound glue that `dart:io` covers cleanly (unix sockets, JSON-lines framing, process tables, shell-outs). The real axis was *separate process vs shared language*, not Go vs Rust, and separate-process is what matters (session persistence needs the daemon to outlive the app), not language. PTY is the one place Dart is genuinely weak — Dart's multi-threaded VM can't safely `fork()` — and that single constraint forces a native helper regardless, independent of whether the rest of the core is Dart. Once a small native helper is accepted, the question "does *everything else* need to be in that same native language" answers itself: no. Go sidecar directory dissolved; `ptyc` (C, PTY-only, pql-peer) is the surviving native supporter tool. -- **Cross-reference:** [D-5](../decisions/architecture.md#d-5-dart-core-ptyc-peer) +- **Cross-reference:** [D-5](../decisions/architecture.md#d-5-dart-core-sidecar-dissolved-ptyc-as-pql-peer) ### R-3: `MaterialApp` root - **Rejected:** 2026-04-21 @@ -23,11 +23,11 @@ future reference. ### R-8: Riverpod / Provider / BLoC for state - **Rejected:** 2026-04-21 - **Reason:** Violates [D-31](../decisions/tooling.md#d-31-prefer-zero-deps-exact-pin). `ChangeNotifier` + `ListenableBuilder` ship in the SDK, fake trivially, and cover the state model we need. The ergonomic wins of Riverpod / Provider don't clear the "new dependency" bar at clide's scale. -- **Cross-reference:** [D-10](../decisions/architecture.md#d-10-state-management-changenotifier) +- **Cross-reference:** [D-10](../decisions/architecture.md#d-10-state-management--changenotifier--listenablebuilder) ### R-12: MaterialApp wrapper from design handoff - **Rejected:** 2026-04-22 - **Reason:** The design handoff delivers theme files as `MaterialApp`/`ThemeData` Dart classes. This is the delivery format of claude.ai/design, not a design intent. Adopting Material's widget system would contradict [D-7](../decisions/architecture.md#d-7-app-root-is-bare-widgetsapp) (bare WidgetsApp, no Material/Cupertino). We translate the palette tokens and syntax roles into our existing YAML + `SurfaceTokens` pipeline. -- **Cross-reference:** [D-43](../decisions/architecture.md#d-43-design-handoff-adopt-token-palettes-reject-material-wrapper) +- **Cross-reference:** [D-43](../decisions/architecture.md#d-43-design-handoff--adopt-token-palettes-reject-material-wrapper) --- diff --git a/governance/rejected/process.md b/governance/rejected/process.md index 7d583b52..e2afe73c 100644 --- a/governance/rejected/process.md +++ b/governance/rejected/process.md @@ -12,17 +12,17 @@ future reference. ### R-9: Port planning tooling into clide - **Rejected:** 2026-04-21 -- **Reason:** Earlier in the planning session the assumption was "clide owns Dart subcommands for decisions + tickets." That breaks the day a contributor works in a terminal or in VS Code / JetBrains — they have no `clide` binary to run. Reversing: pql owns planning long-term (see [D-39](../decisions/process.md#d-39-planning-tooling-lives-in-pql)); clide consumes via shell-out. -- **Cross-reference:** [D-39](../decisions/process.md#d-39-planning-tooling-lives-in-pql) +- **Reason:** Earlier in the planning session the assumption was "clide owns Dart subcommands for decisions + tickets." That breaks the day a contributor works in a terminal or in VS Code / JetBrains — they have no `clide` binary to run. Reversing: pql owns planning long-term (see [D-39](../decisions/process.md#d-39-planning-tooling-lives-in-pql-not-clide)); clide consumes via shell-out. +- **Cross-reference:** [D-39](../decisions/process.md#d-39-planning-tooling-lives-in-pql-not-clide) ### R-10: Python-script stopgap under `tooling/db/` - **Rejected:** 2026-04-21 -- **Reason:** Location, not language. Settled-reach puts scripts at `tooling/db/` — copying that path here creates a script-pollution problem: every project using the pattern commits its own copy. The accepted Python port ([D-40](../decisions/process.md#d-40-python-stopgap-under-toolsscriptsplan)) lives at `tools/scripts/plan`, clearly signalled as dev-tooling and time-limited. -- **Cross-reference:** [D-40](../decisions/process.md#d-40-python-stopgap-under-toolsscriptsplan) +- **Reason:** Location, not language. Settled-reach puts scripts at `tooling/db/` — copying that path here creates a script-pollution problem: every project using the pattern commits its own copy. The accepted Python port ([D-40](../decisions/process.md#d-40-superseded-python-stopgap-under-toolsscriptsplan)) lives at `tools/scripts/plan`, clearly signalled as dev-tooling and time-limited. +- **Cross-reference:** [D-40](../decisions/process.md#d-40-superseded-python-stopgap-under-toolsscriptsplan) ### R-11: Permanent stopgap - **Rejected:** 2026-04-21 - **Reason:** If the Python port under `tools/scripts/plan` outlasts pql's feature parity, delete it. The deletion commit should be one changeset: remove `tools/scripts/plan`, remove its Makefile target (`decisions-validate` rewires to `pql decisions validate`), add a `CHANGELOG.md` entry under Removed, and verify `.pql/pql.db` still opens under the new `pql` binary. -- **Cross-reference:** [D-40](../decisions/process.md#d-40-python-stopgap-under-toolsscriptsplan) +- **Cross-reference:** [D-40](../decisions/process.md#d-40-superseded-python-stopgap-under-toolsscriptsplan) --- diff --git a/governance/rejected/testing.md b/governance/rejected/testing.md index fd71b8da..3b70f7d2 100644 --- a/governance/rejected/testing.md +++ b/governance/rejected/testing.md @@ -8,6 +8,6 @@ future reference. ### R-5: Patrol test runner - **Rejected:** 2026-04-21 - **Reason:** Adds a dependency (violates [D-31](../decisions/tooling.md#d-31-prefer-zero-deps-exact-pin)) for a capability we get from Playwright + Flutter's own semantics tree. Patrol's value proposition (native-gesture emulation) is less relevant on Linux desktop than on mobile. -- **Cross-reference:** [D-26](../decisions/testing.md#d-26-web-driver-raw-playwright-plus-flutter-semantics) +- **Cross-reference:** [D-26](../decisions/testing.md#d-26-web-driver--raw-playwright--flutter-semantics) ---