A collaborative coding-agent orchestrator for atproto radl.app

add fdr (feature design record) to builtin artifact types as analogy to the existing adr #142

Merged disnetdev.com
targeting main from radial/impl-6c790516c837
Merged opened by and assigned to disnetdev.com
targeting main from radial/impl-6c790516c837

fdr seeded beside adr #

radial space create now seeds an eighth built-in artifact type: fdr — a feature design record, project-scoped and append-only, the same register as adr one altitude down. An ADR settles why the system is shaped as it is; an FDR settles what one feature does and why it is designed that way. They are separate chains rather than one because they are superseded by different things: a structural decision outlives the feature that provoked it, and a feature's design is replaced by the next design of that feature, not by the next decision about the system.

Nothing about the fold, the lexicons, or the turn model changed — artifact types are per-space registry data (design §4), so this is one more seeded record and the comment above builtinTypes saying why it is there.

Branch and commit #

  • Branch: radial/impl-6c790516c837 (new, from main @ 5988cd7)
  • Commit: ef76919f9e1cb912516c79903bca1f204569d953 — "seed an fdr artifact type beside adr"
  • Pushed to git@tangled.org:disnetdev.com/radial; no pull request opened from here (Radial opens it).

What changed #

The seed

  • packages/sidecar/src/commands.ts — fdr appended to builtinTypes (scope: project, durability: 'append-only'), with a brief that asks for the design-record register — problem, the behaviour committed to, the design, the alternatives weighed — and explicitly hands a decision about the shape of the system back to adr. The doc comment above the list is updated (five project-scoped types → six) and gains a paragraph on why adr and fdr are two chains.
  • packages/lexicons/fixtures/builtins.json — the matching shipped seed record (createdAt …00:00:08Z). space-create.test.mjs asserts the writer and this fixture say the same thing word for word, so the two cannot drift.

Operator defaults

  • packages/daemon/src/config.ts — the scaffolded planner profile carries fdr beside the other system types, so a fresh radiald config init covers everything a fresh space seeds and no seeded type lands as a ⊕ entry with an empty assignee list.
  • packages/daemon/src/cli.ts — the uncovered advisory's doc comment names the current seed list.

UI

  • packages/ui/src/lib/units.ts — typeLabel capitalises fdr → FDR. It was a single adr comparison; it is now a small set of spoken acronyms, still typography only (§3.3) and still passing anything unknown through unchanged.
  • packages/ui/src/lib/components/Glyph.svelte — a glyph of its own, deliberately unlike the adr book: the two sit side by side in the System section, and rows that draw alike have to be read to be told apart. Unknown types keep the generic fallback.

Docs — docs/design.md §8 (both the prose list of system artifacts and the "decision records" durability bullet), docs/radial-json.md (seeds seven → eight, the sample config, the init output), docs/running-an-agent.md (same three places), packages/sidecar/README.md.

Checks #

Run from the repo root after pnpm install (the offline install failed — typescript-5.9.3.tgz was missing from the store — so a plain pnpm install was used):

  • pnpm build — clean
  • pnpm lint — clean across all 9 projects, including generate.mjs --check (no lexicon changed; the generated file is untouched and current) and check-no-nul
  • pnpm test — clean across all 9 packages, including @radial/ui's node --test and both vitest projects (862 tests)

Three test expectations were counts of the seed list and were updated with it: core/test/validation.test.mjs, sidecar/test/space-create.test.mjs, daemon/test/config.test.mjs, plus ui/src/lib/write.test.ts (a browser-side space create seeds 8 types and the registry rows now include fdr). Added typeLabel coverage in ui/src/lib/units.test.ts — it had none, and the capitalisation rule now has more than one member.

Risks and things left out #

  • Existing spaces do not gain the type. Seeds are written at space create, so a space created before this change has no fdr until an admin adds the registry record (the registry form in the UI, or a hand-written artifactType). That is how registry data works here; there is no migration path and this change does not invent one.
  • An agent has to publish it. A space that seeds fdr with no profile listing it gets a request that sits open. New operators are covered by the scaffold above; an existing radial.json needs the name added and radiald init planner --update — which is exactly what radiald run's uncovered advisory will say at startup.
  • The brief is the one judgement call with no test behind it: it leans on "keep it to this feature" to hold the ADR/FDR line, and only real turns will show whether that is enough separation.

Radial artifact

Commits 0