You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Persona: the maintainer or contributor who, six months from now, asks "why isn't the Koine extension system just wasm like Zed's?"
The extension system (#1936) rests on a decision that is genuinely non-obvious and, without a record, looks like an omission rather than a choice: Koine adopts Zed's packaging but not its runtime, and ships a declarative-first extension model with no executable tier.
Read cold, that decision invites exactly the wrong correction. Someone will propose "just use the Component Model like Zed" — a reasonable-sounding suggestion that costs weeks to re-disprove, because the disproof depends on facts that are neither in the codebase nor intuitive:
Browsers cannot execute components natively — a Phase 1 proposal with zero engine support — and jco's transpile is ahead-of-time, so a gallery cannot ingest an unseen third-party component at runtime.
componentize-dotnet cannot build on macOS at all, which is this project's primary development platform.
CLAUDE.md is unambiguous that this needs an ADR: significant architecture decisions — "a new emitter target, a change to the compiler pipeline layering, a new cross-cutting validator, ... a dependency the whole repo will lean on" — must be captured under /adr/ in MADR 4.0 format, before or alongside the implementing PR. An extension system is all of those at once.
There is a second reason this ADR is not optional: it interacts with decisions already on record. ADR 0011 chose an out-of-process sandbox for scenario execution and explicitly rejected a collectible AssemblyLoadContext as isolation; ADR 0012 built the OS confinement that goes with it. Stage 1 (#1939) introduces a collectible ALC for extensions — for dependency isolation and unload, not isolation — and that distinction has to be recorded, or it reads as silent drift against ADR 0011.
Proposed solution
Write adr/0020-declarative-first-extension-model.md in MADR 4.0 format from adr/template.md, and add it to adr/README.md's index.
It records one decision — declarative-first, executable tier deferred behind a spike — with the evidence that forced it, the options rejected and why, and the consequences accepted. It carries links entries relating it to ADR 0011, ADR 0012 and ADR 0004, and it is the document #1940's spike updates with its outcome.
Alternatives considered
No ADR; let the issues carry the reasoning. Issues are the wrong medium: they close, they are not indexed, and CLAUDE.md's policy exists precisely to stop decisions living only in closed threads. It would also leave the ADR 0011 interaction unrecorded, which is the definition of the drift the policy forbids.
Related:#1936 (epic), #1937, #1938, #1939, #1940 (the spike that updates this ADR), #1941, #1942 — and ADR 0011 / ADR 0012 / ADR 0004, which this ADR must link to explicitly
🧠 Brainstorm
Problem / context
Three research passes (~13.5M tokens, adversarially vote-verified against live primary sources on 2026-08-04) produced a decision that inverts the obvious approach. The obvious approach — copy Zed, which is what was originally asked for — is blocked on facts that are external, time-sensitive and invisible from inside this repository.
That combination is exactly what an ADR exists for. The code will show a JSON manifest and no wasm runtime; nothing in the code explains that this was chosen over wasm rather than as a stepping stone toward it, nor that the wasm path was investigated to the level of specific unmerged pull requests.
The time-sensitivity matters too, and cuts both ways. The blocking facts could change — wasmtime-dotnet #324 could land; componentize-dotnet could gain macOS support. An ADR that records why the door is closed also records what would reopen it, which a code comment never does.
Approaches
A — One ADR for the extension model, updated by the spike. ✅ Recommended.
B — No ADR. Violates CLAUDE.md and leaves the ADR 0011 interaction as silent drift.
C — Defer until after the spike. Inverts the dependency.
D — Per-stage ADRs. Over-records a single decision.
Recommendation
Approach A. Three things it must do that a routine ADR would not:
Name the revisit trigger. The decision is contingent on external facts; the ADR should say which ones, so a future contributor can check them rather than re-run the research.
Status starts proposed and flips to accepted when the implementing PR merges, per the README's own workflow.
📋 Spec
Goal
A MADR 4.0 record of the declarative-first extension decision, its evidence, its relationship to ADRs 0011/0012/0004, and the conditions under which it should be revisited.
Deliverable
adr/0020-declarative-first-extension-model.md plus an index row in adr/README.md.
Context and Problem Statement — Studio has no extension system; #69 shipped compiler seams that are invisible to users and unisolated. State the four verified constraints as facts understood at the time, not as the conclusion: .NET has no component hosting; browsers cannot run components natively and jco is AOT-only; no IDE ecosystem ships a hard runtime sandbox; Zed's capability model is default-allow, global, and its real boundary produced two CVEs.
Considered Options —
Faithful Zed copy (Component Model wasm)
Core-module wasm hosted in .NET
Component-model wasm in the Rust Tauri host
Out-of-process .NET plugins on the ADR 0012 harness
Declarative-first, executable tier deferred to a spike
Decision Outcome — option 5, stated as a decision ("We will …"): ship a declarative tier that hosts no untrusted code and works identically in the Tauri webview, the browser tab and the CLI; adopt Zed's packaging (two tiers, a versioned contract with a never-raised floor, precompiled artifacts, a pointer-index registry); reject Zed's capability model in favour of default-deny, per-extension capabilities modelled on VS Code's capabilities.untrustedWorkspaces; and defer the executable tier to #1940.
Consequences — accepted trade-offs stated honestly, not just benefits:
No third-party analyzers, custom panels or diagram renderers until the spike resolves.
No plugin UI/custom-view API at all, matching Zed's two-year position.
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.
Goal: Record the declarative-first extension decision as ADR 0020, linked to ADRs 0011/0012/0004.
Architecture: A single MADR 4.0 document from adr/template.md, plus an index row.
Tech Stack: Markdown, MADR 4.0 (ADR 0010).
Global Constraints
MADR 4.0 format, copied from adr/template.md — required sections are Context and Problem Statement, Considered Options, Decision Outcome, Consequences (ADR 0010).
status: proposed at creation; flip to accepted when the PR merges.
Do not edit ADR 0011's or 0012's Decision Outcome — this is a relationship, not a supersession.
Step 1: Copy adr/template.md to adr/0020-declarative-first-extension-model.md and fill the frontmatter exactly as the spec gives it, including the three links entries.
Step 3: Write Considered Options — all five, each with its genuine appeal stated before its disqualifier, so the record reads as a decision rather than a justification.
Step 4: Write Decision Outcome in the "We will …" form, naming what is adopted from Zed and what is explicitly rejected.
Step 5: Write Consequences, covering every accepted trade-off in the spec — including the ADR 0011 relationship on the collectible ALC and the ADR 0004 constraint on themes.
Step 6: Add a Revisit triggers subsection naming the four concrete conditions.
Step 7: Commit: docs(adr): record the declarative-first extension model for Koine Studio
Step 1: Add the ADR 0020 row to adr/README.md's index table, matching the existing rows' format exactly.
Step 2: Add a links: [{ type: relates-to, target: 0020 }] entry to each of ADR 0011, 0012 and 0004 — frontmatter only; do not touch their Decision Outcome or Consequences prose.
Step 3: Verify every links target resolves to a real ADR id and that the relationships are reciprocal.
Step 4: Commit: docs(adr): index ADR 0020 and cross-link the related decisions
Task 3: Point the epic and stage issues at the ADR
Problem / motivation
Persona: the maintainer or contributor who, six months from now, asks "why isn't the Koine extension system just wasm like Zed's?"
The extension system (#1936) rests on a decision that is genuinely non-obvious and, without a record, looks like an omission rather than a choice: Koine adopts Zed's packaging but not its runtime, and ships a declarative-first extension model with no executable tier.
Read cold, that decision invites exactly the wrong correction. Someone will propose "just use the Component Model like Zed" — a reasonable-sounding suggestion that costs weeks to re-disprove, because the disproof depends on facts that are neither in the codebase nor intuitive:
wasmtime-dotnetexposes no Component Model hosting API at all (only an inertConfig.WithComponentModel(bool)toggle); PR Harden the Studio main-thread boot fallback (CSP-safe loader) + sharpen the boot smoke-test diagnostics (#359) #360 was closed unmerged on 2026-06-12 and issue Explicit-id create factories: allow a create factory on a non-Guid (natural/sequence) identity via an explicit id parameter #324 has been open since 2024-07-09.jco's transpile is ahead-of-time, so a gallery cannot ingest an unseen third-party component at runtime.componentize-dotnetcannot build on macOS at all, which is this project's primary development platform.CLAUDE.md is unambiguous that this needs an ADR: significant architecture decisions — "a new emitter target, a change to the compiler pipeline layering, a new cross-cutting validator, ... a dependency the whole repo will lean on" — must be captured under
/adr/in MADR 4.0 format, before or alongside the implementing PR. An extension system is all of those at once.There is a second reason this ADR is not optional: it interacts with decisions already on record. ADR 0011 chose an out-of-process sandbox for scenario execution and explicitly rejected a collectible
AssemblyLoadContextas isolation; ADR 0012 built the OS confinement that goes with it. Stage 1 (#1939) introduces a collectible ALC for extensions — for dependency isolation and unload, not isolation — and that distinction has to be recorded, or it reads as silent drift against ADR 0011.Proposed solution
Write
adr/0020-declarative-first-extension-model.mdin MADR 4.0 format fromadr/template.md, and add it toadr/README.md's index.It records one decision — declarative-first, executable tier deferred behind a spike — with the evidence that forced it, the options rejected and why, and the consequences accepted. It carries
linksentries relating it to ADR 0011, ADR 0012 and ADR 0004, and it is the document #1940's spike updates with its outcome.Alternatives considered
status: proposedand updated by the spike.Area
Docs / website
Related: #1936 (epic), #1937, #1938, #1939, #1940 (the spike that updates this ADR), #1941, #1942 — and ADR 0011 / ADR 0012 / ADR 0004, which this ADR must link to explicitly
🧠 Brainstorm
Problem / context
Three research passes (~13.5M tokens, adversarially vote-verified against live primary sources on 2026-08-04) produced a decision that inverts the obvious approach. The obvious approach — copy Zed, which is what was originally asked for — is blocked on facts that are external, time-sensitive and invisible from inside this repository.
That combination is exactly what an ADR exists for. The code will show a JSON manifest and no wasm runtime; nothing in the code explains that this was chosen over wasm rather than as a stepping stone toward it, nor that the wasm path was investigated to the level of specific unmerged pull requests.
The time-sensitivity matters too, and cuts both ways. The blocking facts could change — wasmtime-dotnet #324 could land; componentize-dotnet could gain macOS support. An ADR that records why the door is closed also records what would reopen it, which a code comment never does.
Approaches
A — One ADR for the extension model, updated by the spike. ✅ Recommended.
B — No ADR. Violates CLAUDE.md and leaves the ADR 0011 interaction as silent drift.
C — Defer until after the spike. Inverts the dependency.
D — Per-stage ADRs. Over-records a single decision.
Recommendation
Approach A. Three things it must do that a routine ADR would not:
runtime.osx-arm64package is what makes the ADR re-checkable later. A vague "wasm wasn't ready" ages into folklore.links: relates-toon both, and the partial-relationship spelled out in Consequences, following the ADR 0008 ↔ ADR 0002 precedent the README already cites.Status starts
proposedand flips toacceptedwhen the implementing PR merges, per the README's own workflow.📋 Spec
Goal
A MADR 4.0 record of the declarative-first extension decision, its evidence, its relationship to ADRs 0011/0012/0004, and the conditions under which it should be revisited.
Deliverable
adr/0020-declarative-first-extension-model.mdplus an index row inadr/README.md.Frontmatter
Required content
Context and Problem Statement — Studio has no extension system; #69 shipped compiler seams that are invisible to users and unisolated. State the four verified constraints as facts understood at the time, not as the conclusion: .NET has no component hosting; browsers cannot run components natively and
jcois AOT-only; no IDE ecosystem ships a hard runtime sandbox; Zed's capability model is default-allow, global, and its real boundary produced two CVEs.Considered Options —
Decision Outcome — option 5, stated as a decision ("We will …"): ship a declarative tier that hosts no untrusted code and works identically in the Tauri webview, the browser tab and the CLI; adopt Zed's packaging (two tiers, a versioned contract with a never-raised floor, precompiled artifacts, a pointer-index registry); reject Zed's capability model in favour of default-deny, per-extension capabilities modelled on VS Code's
capabilities.untrustedWorkspaces; and defer the executable tier to #1940.Consequences — accepted trade-offs stated honestly, not just benefits:
Revisit triggers — named concretely: wasmtime-dotnet ships component hosting (#324);
componentize-dotnetgains macOS/osx-arm64support; the Component Model reaches meaningful browser engine support; or #1940 returns a viable substrate.Non-goals
Assumptions
status: proposeduntil the implementing PR merges, peradr/README.md.🛠️ Implementation plan
Goal: Record the declarative-first extension decision as ADR 0020, linked to ADRs 0011/0012/0004.
Architecture: A single MADR 4.0 document from
adr/template.md, plus an index row.Tech Stack: Markdown, MADR 4.0 (ADR 0010).
Global Constraints
adr/template.md— required sections are Context and Problem Statement, Considered Options, Decision Outcome, Consequences (ADR 0010).status: proposedat creation; flip toacceptedwhen the PR merges.git -c user.email=phmatray@gmail.com -c user.name="Philippe Matray".docs(adr): ….Task 1: Write ADR 0020
Files:
adr/0020-declarative-first-extension-model.mdInterfaces: none (decision record).
adr/template.mdtoadr/0020-declarative-first-extension-model.mdand fill the frontmatter exactly as the spec gives it, including the threelinksentries.docs(adr): record the declarative-first extension model for Koine StudioTask 2: Index it and cross-link the related ADRs
Files:
adr/README.md(index table)adr/0011-scenario-execution-sandbox.md,adr/0012-scenario-sandbox-os-confinement.md,adr/0004-concept-colors-single-palette-and-lsp-kind-modifiers.md(linksfrontmatter only)Interfaces: none.
adr/README.md's index table, matching the existing rows' format exactly.links: [{ type: relates-to, target: 0020 }]entry to each of ADR 0011, 0012 and 0004 — frontmatter only; do not touch their Decision Outcome or Consequences prose.linkstarget resolves to a real ADR id and that the relationships are reciprocal.docs(adr): index ADR 0020 and cross-link the related decisionsTask 3: Point the epic and stage issues at the ADR
Files: none in-repo (issue bodies).
Interfaces: none.
adr/0020-declarative-first-extension-model.mdin Koine Studio extension system: a user-facing plugin gallery with a declarative-first extension model #1936's body so the epic points at the decision record./adr/is published there; fix any frontmatter the site rejects.