Adopt settled-reach's Q&D record convention. Confirmed decisions live under decisions/<domain>.md as D-NNN; open questions under questions-<domain>.md as Q-NNN; rejected alternatives in rejected.md as R-NNN. Markdown is source of truth; .pql/pql.db (added later) is a query index. Backlog captured from the Tier-0 Flutter planning sessions: bare WidgetsApp, theme pipeline, kernel admission rule, feature-first layout, a11y + i18n as Tier-0 contracts, test pyramid, kanban over Scrum, pql-owns-planning, Python stopgap sunset clause. ADR migration (D-001, D-003-D-006 confirmed, R-002 rejected) is staged for the next commit so the diff stays readable. Co-Authored-By: Claude <noreply@anthropic.com>
4.2 KiB
4.2 KiB
Extension Decisions
Extension contract, Lua runtime, grain, contribution points.
D-015: Extension grain — container-level, multi-contribution
- Date: 2026-04-21
- Decision: An extension is a shipping unit that contributes one or more named contributions (panel, command, theme, keybinding, language, layout, provider, view). Grain is container-sized — a single
builtin.gitextension contributes panel + commands + keybindings + status-bar items; we do not ship one extension per contribution. - Rationale: Finer grain (one extension per contribution) multiplies manifest files with no win and fragments ownership. Coarser grain (one mega-extension per domain) hides which parts a user might reasonably disable.
- Cost: Extension authors make a taste call about grouping; disagreements go to review.
- Raised by: 2026-04-21 planning.
D-016: Built-ins in Dart, third-party in sandboxed Lua
- Date: 2026-04-21
- Decision: Bundled extensions (every
app/lib/builtin/<name>) are Dart — they link into the app binary. Third-party extensions (Tier 6) run in sandboxed Lua via theptyc-peer Lua runtime (see D-019). The contribution contract is language-agnostic — same contribution shapes, same manifest schema. - Rationale: Dart built-ins get full SDK power (custom painters, isolates, FFI); third-party Lua gets a narrow capability API, no arbitrary syscalls, no deps on pub.dev. VS Code's Node-runs-with-full-power model is a supply-chain nightmare we're explicitly rejecting.
- Cost: Two implementation paths for the same contract; we pay in API design to keep them equivalent at the seams.
- Raised by: 2026-04-21 planning.
D-017: Panels are extension-shaped from day one
- Date: 2026-04-21
- Decision: Every bundled panel (file tree, git, problems, pql query, terminal, etc.) is a contribution on the extension contract, not a hardcoded widget tree in the panel manager. First party contributes via Dart; third party contributes via Lua; same contract.
- Rationale: Forces the contract to be real on day one. The alternative ("extensions can contribute panels later") always becomes "the contract doesn't quite fit our bundled panels, so built-ins get a shortcut" — and the shortcut becomes permanent.
- Cost: Every panel goes through the manifest/registration path even when it's trivial. Price paid once.
- Raised by: 2026-04-21 planning.
D-018: 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-021).
- 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.3is exact-pinned. - Raised by: 2026-04-21 planning.
D-019: Lua runtime as ptyc-peer supporter tool
- Date: 2026-04-21
- Decision: Third-party extensions run Lua inside a sandboxed runtime (working name TBD; same peer-status as
ptycandpql). The runtime vendors liblua, links from Dart viadart:ffi, exposes a narrow capability API, and takes contributions as a declarative render-intent DSL (widget shapes, not arbitrary widget code). - Rationale: Lua is small, embeddable, battle-tested (Neovim, World of Warcraft, Redis). Native sandboxing at the VM level is cheap. A declarative render-intent DSL keeps "run arbitrary Flutter widgets from Lua" off the table — the runtime interprets the DSL into Dart widgets, which keeps Tier 6 supply-chain risk bounded.
- Cost: Runtime is a separate supporter tool to build; ffi is tricky. Deferred to Tier 6; only the slot is reserved now.
- Raised by: 2026-04-21 planning.
See also the existing builtin.grammars_core stub for tree-sitter
questions (Q-015,
Q-016).