From 760a88c578c7256e6696a156dc13ffce533ef9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Darko=20Miji=C4=87?= Date: Wed, 4 Nov 2026 12:09:11 +0100 Subject: [PATCH] design: start the design foundation and orient every session through the graph Opens the design arc for the Protocol's human readings (UX and information architecture of role- and work-specific Studio views), stacked on the article refresh. This is the first of many iterations. Owner's working rules for the arc: - Design sessions record what they find for engineering sessions; they never edit carriers, Packs, anchors or anything else that feeds the graph. - The graph first: load the reading skill, ask the graph through sdp:q, and read a carrier last, only for its exact wording. Specify part of every piece of work as graph queries, not only prose. - Keep personas and the niche, specialised, ultra-specialised and AI-powered options on the table; traditional delivery roles are the first cycles' focus, not the limit. - The core stays open source and free; a commercial Studio (desktop, web, CI/CD) is exploratory. - No visual style until the existing UI library and design system arrive. - Corpus counts are derived, never quoted. Design questions are answered over months of iterations; technical questions are answered from the repository. Base: 53804437 (docs/articles-refresh-1). Arc's Pack: none. By the owner's rule the design material stays outside the corpus; a corpus home for it is recorded as a proposal for an engineering session (docs/design/07-graph-needs.md). What lands: - PRODUCT.md: the product record for design work (users, purpose, positioning, constraints, principles). - docs/design/: README and documents 01-12 (roles and personas, the seed design's experience mapped to now, reading material, reading model and IA, specialised and AI readings, design cycles, graph needs with reader frictions and on-ramp observations, what the repository settles, design method, a Studio baseline, RUP roles and artifacts as projections, analogous products). - AGENTS.md: "Orient before work" replaces the owner's TODO, pointing to eleven mandatory sdp:q queries; also the owner's reformatting of the "Where to look" table. - .agents/skills/sdp-agent-surface/orientation.md: the eleven queries with reading notes, behind a one-line pointer in SKILL.md (checkout only; not in the package's files list). Evidence: every orientation query ran from the committed file with exit 0 (each also ran twice with byte-identical output); the design documents' factual claims were checked against the graph; npm run check is green for this tree in a clean worktree with the new files staged. In the main checkout the check-clean steps failed only on macOS Finder .DS_Store files inside an open generated/ folder (recorded in docs/design/07-graph-needs.md). Co-Authored-By: Claude Opus 5.5 --- .agents/skills/sdp-agent-surface/SKILL.md | 4 + .../skills/sdp-agent-surface/orientation.md | 139 +++++ AGENTS.md | 43 +- PRODUCT.md | 272 +++++++++ docs/design/01-roles-and-perspectives.md | 232 ++++++++ docs/design/02-seed-experience-map.md | 111 ++++ docs/design/03-reading-material.md | 214 +++++++ docs/design/04-reading-model-and-ia.md | 249 ++++++++ docs/design/05-specialised-and-ai-readings.md | 135 +++++ docs/design/06-design-cycles.md | 230 ++++++++ docs/design/07-graph-needs.md | 246 ++++++++ docs/design/08-what-the-repo-settles.md | 547 ++++++++++++++++++ docs/design/09-design-method.md | 277 +++++++++ docs/design/10-studio-baseline.md | 244 ++++++++ docs/design/11-rup-roles-and-artifacts.md | 322 +++++++++++ docs/design/12-analogous-products.md | 252 ++++++++ docs/design/README.md | 142 +++++ 17 files changed, 3644 insertions(+), 15 deletions(-) create mode 100644 .agents/skills/sdp-agent-surface/orientation.md create mode 100644 PRODUCT.md create mode 100644 docs/design/01-roles-and-perspectives.md create mode 100644 docs/design/02-seed-experience-map.md create mode 100644 docs/design/03-reading-material.md create mode 100644 docs/design/04-reading-model-and-ia.md create mode 100644 docs/design/05-specialised-and-ai-readings.md create mode 100644 docs/design/06-design-cycles.md create mode 100644 docs/design/07-graph-needs.md create mode 100644 docs/design/08-what-the-repo-settles.md create mode 100644 docs/design/09-design-method.md create mode 100644 docs/design/10-studio-baseline.md create mode 100644 docs/design/11-rup-roles-and-artifacts.md create mode 100644 docs/design/12-analogous-products.md create mode 100644 docs/design/README.md diff --git a/.agents/skills/sdp-agent-surface/SKILL.md b/.agents/skills/sdp-agent-surface/SKILL.md index 46272b77..d0fb1e33 100644 --- a/.agents/skills/sdp-agent-surface/SKILL.md +++ b/.agents/skills/sdp-agent-surface/SKILL.md @@ -40,6 +40,10 @@ checkout: `exec` resolves dependency binaries, while this package does not link own `node_modules/.bin`; an unresolved `sdp` can select macOS's unrelated binary. Do not invoke a global `sdp` either. +**Orient first in the source checkout.** Before any work there, run the eleven queries in +[`orientation.md`](orientation.md), beside this file, in order. They present the corpus and show +the practice. The file lives in the Protocol checkout only; the package does not ship it. + The catalog of ready-made bodies is `docs/agent-surface/recipes.md` in the Protocol repository and `node_modules/@libar-dev/software-delivery-protocol/docs/agent-surface/recipes.md` in an adopter. Each recipe opens under a numbered heading that names it. Every body there runs verbatim diff --git a/.agents/skills/sdp-agent-surface/orientation.md b/.agents/skills/sdp-agent-surface/orientation.md new file mode 100644 index 00000000..5d2ca970 --- /dev/null +++ b/.agents/skills/sdp-agent-surface/orientation.md @@ -0,0 +1,139 @@ +# Orient before work + +The orientation queries the repository handbook ([AGENTS.md](../../../AGENTS.md)) makes mandatory before work, disclosed from [SKILL.md](SKILL.md) so the skill stays short. They are written for the Protocol source checkout; the bodies are not run by the recipe tests, so a failing query is a finding to report. + +Run these eleven queries in order before work of any kind, after `CONTEXT.md`. Together they present the corpus, its honesty, the next work and what is undecided, and they show the practice: a body over `g` and `graph`, the `report` as data, recipes composed with `recipes(n, params)`, subjects passed with `--params`, the entry adapters (`findByConcept`, `byFile`, `blastRadius`) and the frozen joins (`specContext`, `packContext`, `resolveEntryAddress`). The bodies also show where each answer keeps its rows, so copy those paths rather than guessing them. + +The commands are written for the Protocol source checkout, with its Pack, file, term and Spec ids as parameters. In an adopter, run the same bodies through the repository's runner with `--root` and `--exclude` (see "Bootstrap discipline" in [SKILL.md](SKILL.md)) and pass your own ids. To ask about another subject, change the `--params` value, never the body. Every number belongs to the commit it ran at: re-run, never quote. Before reading an empty list or a zero as absence, read "Empty answers that mislead" in [SKILL.md](SKILL.md). + +## 1. The corpus and its surface + +Specs by family, altitude, named coordinate and stated readiness; node, edge and claim counts; the reader's methods, every field a Spec row or an edge carries, and the parameters ten recipes accept. + +```bash +pnpm --silent sdp:q 'const specs = g.specs(); const tally = (xs) => xs.reduce((t, x) => ({ ...t, [x]: (t[x] ?? 0) + 1 }), {}); const keys = (rows) => [...new Set(rows.flatMap((r) => Object.keys(r)))].join(" "); const byKind = {}; for (const s of specs) { const row = (byKind[`${s.kindDisplayLabel} (${s.specKind})`] ??= { idea: 0, scoped: 0, defined: 0, ready: 0 }); row[s.statedReadiness] = (row[s.statedReadiness] ?? 0) + 1; } const accepts = {}; for (const n of [3, 4, 6, 20, 23, 25, 29, 46, 53, 54]) accepts[n] = (await recipes(n, { "?": 1 })).accepts.join(" ") || "none"; return { specs: specs.length, byFamily: tally(specs.map((s) => s.id.split(/[:.]/)[1])), byAltitude: tally(specs.map((s) => s.altitude)), byKind, nodesByType: tally(graph.nodes.map((n) => n.nodeType)), edgesByType: tally(graph.edges.map((e) => e.type)), edgesByClaim: tally(graph.edges.map((e) => e.claim)), surface: { reader: Object.keys(g).join(" "), specRow: keys(specs), edge: keys(graph.edges), recipeParams: accepts } }' +``` + +**Teaches:** An ad-hoc body over `g` and the raw `graph`, pre-shaped into counts; field names collected across every row rather than the first; the unknown-parameter probe, `recipes(n, { "?": 1 }).accepts`, in place of reading the catalog for parameter names. + +**Read:** Readiness here is stated readiness, the author's statement; query 4 reads the floor. Kind and altitude are tallied apart, not crossed. A missing key means none exists at that commit (in this checkout, no `inferred` claim and no `supersedes` edge). `g.specs()` rows carry no sections, relations or bindings (some carry `narrative`): a field read off a row returns a silent `undefined`, so read them through `g.specContext(id)` (query 10). `none` means a recipe takes no parameters. + +## 2. The capabilities + +Each capability epic as a one-line promise, with counts over its refinement descendants, and one `distinct` line of corpus totals. + +```bash +pnpm --silent sdp:q 'const map = await recipes(52); const t = map.totals; const count = (k, one, many = `${one}s`) => `${k} ${k === 1 ? one : many}`; const line = (r) => `${count(r.specs, "Spec")} (${count(r.byKind.example, "example")}, ${count(r.byKind.decision, "decision")}), ${r.byStatedReadiness.ready} stated ready, ${r.withImplementationBinding} implementation-bound, ${r.withVerifierBinding} verifier-bound, ${count(r.blockingQuestions, "blocking question")}`; return { epics: t.epics, unreached: t.unreached, cycles: map.cycles.length, damage: map.damage.length, distinct: line(t), rows: map.epics.map((e) => `${e.id}: ${e.title} | ${line(e.rollup)}${e.parentEpicIds.length > 0 ? `; under ${e.parentEpicIds.join(", ")}` : ""}`) }' +``` + +**Teaches:** A shipped recipe composed in a body, `recipes(52)`, cut to one line per epic. + +**Read:** Rows overlap: an epic shown 'under' another is counted again in its parent, and a Spec refining two epics is counted under both. A rollup leaves out the epic itself. Never sum the rows; the `distinct` line is the corpus count. Zero unreached, cycles and damage is the healthy answer. Verifier-bound says a verifier binding exists, not that tests pass. Examples are verification evidence and decisions are ratified records. Neither needs an implementation binding, so an epic made mostly of them shows few implementation bindings without missing any work. + +## 3. The Packs + +Every Pack with its order, members, stated-ready count, implemented members outside examples and decisions, verifier gaps and unresolved members. + +```bash +pnpm --silent sdp:q 'const count = (k, one, many = `${one}s`) => `${k} ${k === 1 ? one : many}`; return g.packs().map((p) => { const pack = g.packContext(p.id); const members = pack.members.filter((m) => m.resolved); const work = members.filter((m) => m.specKind !== "example" && m.specKind !== "decision"); return `${p.id} [${pack.order ?? "reading"}] ${p.title}: ${count(members.length, "member")}, ${members.filter((m) => m.statedReadiness === "ready").length} stated ready, ${work.filter((m) => m.deliveryFacts.includes("implemented")).length}/${work.length} implemented outside examples and decisions, ${count(pack.verifierGaps.length, "verifier gap")}, ${pack.members.length - members.length} unresolved`; })' +``` + +**Teaches:** The frozen join `g.packContext(id)`, reached with ids `g.packs()` returned. + +**Read:** Only a priority Pack orders work, as the corpus's advisory priority: never a schedule, a date or a gate. In this checkout, `pack:self-hosting-v1` holds the whole corpus. A Pack's verifier gaps include members below `ready`; only its ready gaps match query 4's `honesty/gaps` warnings, and decisions are exempt from both. A Pack states no system truth; `g.packContext(id).framing` holds its prose. + +## 4. Honest and built + +The validation report as data, the drift alarm, readiness divergence, delivery facts outside examples and decisions, the build and design backlogs, and every Spec below `ready` with the clause holding its next rung. + +```bash +pnpm --silent sdp:q 'const signals = await recipes(8); const drift = await recipes(2); const divergence = await recipes(7); const build = await recipes(1); const ladder = await recipes(11); const design = await recipes(33); const errors = report.findings.filter((f) => f.severity === "error"); const work = g.specs().filter((s) => s.specKind !== "example" && s.specKind !== "decision"); const has = (fact) => work.filter((s) => s.deliveryFacts.includes(fact)).length; const floor = (r) => `${r.id}: stated ${r.statedReadiness}, floor ${r.floorReached}`; return { findings: report.findings.length, errorCount: errors.length, errors: errors.slice(0, 10).map((f) => `${f.validatorId} ${f.subjectId ?? f.file ?? ""}`), warnings: signals.signals.map((s) => `${s.validatorId} ${s.subjectId}`), warningsLeftOut: signals.leftOut, exemptions: signals.exemptions, driftAlarm: drift.alarms.map(floor), statedAboveFloor: divergence.map(floor), realization: `${work.length} Specs outside examples and decisions: ${has("implemented")} implemented, ${has("has-verifier")} has-verifier`, buildBacklog: Object.values(build.byFamily).flat().map((r) => r.id), designBacklog: design.totals.specs, belowReady: Object.values(ladder.byFamily).flat().map((r) => `${floor(r)}${r.statedNextRung ? `, next ${r.statedNextRung} ${r.nextUnmetClause ? `held by ${r.nextUnmetClause}` : "nothing blocks"}` : ""}`), excludedReady: { examples: build.excludedReadyExamples, decisions: build.excludedReadyDecisions, examplesWithoutVerifier: build.excludedWithoutVerifier.length } }' +``` + +**Teaches:** The `report` binding read as data, never a gate, beside six composed parameterless recipes (8, 2, 7, 1, 11, 33); a truncated list keeps its count beside it. + +**Read:** No errors means conformance and honesty hold, not that the design is right. `errors` shows at most ten, `errorCount` counts them all, and a non-empty `warningsLeftOut` says the warnings list is cut. In this checkout the `honesty/gaps` warnings are intentional and the self-hosting oracle pins them; any other warning is a regression. A drift alarm is drift to resolve deliberately, never permission to promote what the code does into intent. `implemented` says a code anchor binds the Spec, not that it is live; `has-verifier` says a verifier binding resolves, not that tests pass. Only `buildBacklog` is build work. An empty design backlog means no Spec stated `defined` lacks an implementation binding (examples and decisions aside); `belowReady` lists what is left to design. 'nothing blocks' means no floor clause holds the stated next rung: it waits only for its author's statement. A floor reported as not evaluated marks an unratified kind or altitude; report it so, never as a rung nothing blocks. This reads the same report as `sdp validate`, with the same exclusions, without that command's build side effects. + +## 5. Next work + +The roadmap over `pack:roadmap`: each entry's need, stated rung against its floor, holding questions, build-now ids and drift, plus the statements and the selected decider's questions waiting. + +```bash +pnpm --silent sdp:q 'const answer = await recipes(53, { pack: params.pack, decider: params.decider }); if (answer.diagnostics) return answer; return { decider: answer.decider, roadmaps: answer.roadmaps.map((roadmap) => ({ pack: roadmap.pack, totals: roadmap.totals, entries: roadmap.entries.map((e) => `${e.place}. ${e.id}: ${e.need} (stated ${e.statedReadiness}, floor ${e.floorReached})${e.blockingQuestions.length > 0 ? `; held by ${e.blockingQuestions.map((q) => q.address ?? q.spec).join(", ")}` : ""}${e.buildNow.length > 0 ? `; build now ${e.buildNow.join(", ")}` : ""}${e.work.drift > 0 ? `; ${e.work.drift} drift` : ""}`), apart: roadmap.apart.map((a) => `${a.place}. ${a.id}: ${a.need}`), unresolved: roadmap.unresolved.map((u) => `${u.place}. ${u.id}`), waitingStatements: roadmap.waiting.statements.map((s) => s.id), waitingQuestions: roadmap.waiting.questions.map((q) => q.address ?? q.spec), waitingWithoutDecider: roadmap.waiting.withoutDecider.map((q) => q.address ?? q.spec) })) }' --params '{"pack":"pack:roadmap"}' +``` + +**Teaches:** Subjects passed as `--params` to a composed recipe, `recipes(53, { pack: params.pack, decider: params.decider })`, with a diagnostics guard; the body maps `roadmaps[].entries` instead of truncating the answer. + +**Read:** The order is advisory priority: never a schedule, a date or a gate. An entry needs the first of to design, to state and to build that any Spec of its work needs. Coding work is the build-now ids, on whichever entry carries them. 'to design' means the floor does not reach `ready` yet: read the holding questions and their deciders. 'to state' waits only on a person's `ready` statement. 'built' means every Spec of the entry's work states `ready` and every one outside examples and decisions is `implemented`, never that it is live. A drift count is the drift alarm inside the entry. `waitingQuestions` and `totals.questions` count only the decider's questions (`owner` unless `--params` names another `decider`), and `waitingWithoutDecider` lists those naming none. An entry's 'held by' lists every blocking question in its work, whatever its decider. In this checkout, the open arc's record is its draft pull request. + +## 6. Undecided + +Every open question by entry address, as a hold, a deferral or non-blocking, with its decider and any provisional answer; then the readiness statements waiting, in dependency order. + +```bash +pnpm --silent sdp:q 'const register = await recipes(20); const queue = await recipes(46, { decider: params.decider }); if (queue.diagnostics) return queue; return { questions: register.totals, rows: register.specs.flatMap((s) => s.questions.map((q) => `${q.deferral ? "deferred" : q.blocking ? "holds" : "non-blocking"} | ${q.key ? `${s.id}#question.${q.key}` : `${s.id} (unkeyed)`} | decider ${q.decider ?? "none"}${q.provisional ? ", provisional" : ""}`)), queue: queue.totals, waitingStatements: queue.statements.map((w) => `${w.place}. ${w.id}: stated ${w.statedReadiness}, floor ${w.floorReached}${w.restsOn.length > 0 ? `, after ${w.restsOn.join(", ")}` : ""}`) }' --params '{"decider":"owner"}' +``` + +**Teaches:** A parameterless recipe (20, whose rows sit under `specs[].questions`) composed with a parameterized one (46, `decider` from `--params`). + +**Read:** Every blocking question, hold or deferral, keeps its Spec's floor below `defined`. A hold waits on its decider now; a deferral is parked until its trigger fires, so do not reopen it before then. 'decider none' names no decider, and the queue counts these as `withoutDecider`. A decider is a corpus token that references nothing; in this checkout 'delegated' marks a question an agent may answer provisionally, pending the owner's review. The queue states no rung: a waiting statement waits for its author's statement. The register covers the corpus, the queue only the selected decider's questions, query 5 only the roadmap's share for its decider. A ruled-out topic may be a decision, not a question: search it with query 8. + +## 7. Architecture and decisions + +Each anchored component with its layer, units, satisfied Specs and uses; the direction unit-level `uses` edges run across layers; the decision register's totals; the decisions with the widest reach, by name. + +```bash +pnpm --silent sdp:q 'const arch = await recipes(17); const crossings = await recipes(32); const register = await recipes(31); const map = await recipes(18); const count = (k, one, many = `${one}s`) => `${k} ${k === 1 ? one : many}`; const short = (id) => id.replace(/^component:/, ""); const titles = new Map(map.decisions.map((d) => [d.id, d.title])); return { components: arch.components.map((c) => `${short(c.id)} [${c.layer ?? "no layer"}] ${c.label ?? ""}: ${count(c.members.length, "unit")}, satisfies ${count(c.satisfiedSpecs.length, "Spec")}, uses ${c.usesOut.map(short).join(" ") || "nothing"}`), unresolvedUses: arch.unresolvedUses.length, layerDirection: crossings.totals.byLayerPair, decisions: register.totals, mostShaping: map.ranking.slice(0, 8).map((r) => `${r.fanIn} ${r.id}: ${titles.get(r.id)}`) }' +``` + +**Teaches:** Four parameterless recipes (17, 32, 31, 18) composed into one bounded view. Run bare in this checkout, 17 prints about 344K characters and 18, 31 and 32 print 13-32K each. + +**Read:** This is anchored structure, not exhaustive import reach: an unanchored file does not appear (recipe 40 ranks those, but needs an imports file `sdp build --imports` writes). `layerDirection` counts unit-level `uses` edges between components that state different layers. The Protocol orders no layers, and layer and role confer nothing; whether a pair is lawful is a corpus rule (recipe 42). Fan-in ranks reach, not priority. Read one decision's ruling with query 10. The graph has no MD-n field: in this checkout `docs/concept/DECISIONS.md` maps numbers to names, and a few Specs cite numbers in prose. In prose, lead with the name. Never run recipe 17 bare. + +## 8. Arrive with a word + +Where several terms live, through both matchers: the nodes `findByConcept` matches, with the fields matched, and entry search's count, cap and first addresses with lines. + +```bash +pnpm --silent sdp:q 'const terms = [params.terms ?? params.term ?? []].flat(); if (terms.length === 0) return { diagnostics: [{ parameter: "terms", problem: "Expected a list of terms." }] }; const count = (k, one, many = `${one}s`) => `${k} ${k === 1 ? one : many}`; const out = {}; for (const term of terms) { const nodes = g.findByConcept(term); const entries = await recipes(23, { term }); out[term] = { findByConcept: `${count(nodes.length, "node")}${nodes.length > 0 ? ": " : ""}${nodes.slice(0, 5).map((n) => `${n.id} [${n.matchedIn.join(",")}]`).join("; ")}`, entrySearch: `${count(entries.totals.matches, "entry", "entries")} in ${count(entries.totals.specs, "Spec")}, ${entries.totals.shown} shown${entries.matches.length > 0 ? ": " : ""}${entries.matches.slice(0, 4).map((m) => `${m.address ?? `${m.id} ${m.entry ?? m.section}`} line ${m.line}`).join("; ")}` }; } return out' --params '{"terms":["statement queue","localStorage","accessib"]}' +``` + +**Teaches:** The word entry adapter `g.findByConcept(term)` beside entry search composed per term, `recipes(23, { term })`, over one graph derivation; `terms` takes a list. + +**Read:** `findByConcept` matches a case-insensitive substring of ids, titles or labels, Pack framing, narrative and sections. Entry search (recipe 23) matches whole tokens, splits camelCase, and returns addresses and lines. Each misses what the other finds (`localStorage`, `accessib`), so a zero from one is not absence; a spaced phrase can also miss a hyphenated id, so try that form. Entry search shows at most 50 rows: compare `shown` with `matches`, and never filter its rows down to a scope. `line null` means the entry is not located, not absent. Neither searches outside the graph: not `CONTEXT.md`, nor, in this checkout, the concept documents or the job stories. + +## 9. Arrive with a file or a changeset + +The nodes recorded at one file and the Specs reachable from them; then a changeset's impacted Specs, at-risk nodes and the files the graph records nothing at. + +```bash +pnpm --silent sdp:q 'const file = params.file === undefined ? null : g.byFile(params.file); const change = await recipes(4, { files: params.files }); return { file: file && { path: file.path, nodes: file.nodes.map((n) => `${n.nodeType} ${n.id}${n.line === undefined ? "" : ` at line ${n.line}`}`), specs: file.specs }, changeset: { totals: change.totals, impactedSpecs: change.impactedSpecs, impactedPacks: change.impactedPacks, atRiskOther: change.atRisk.other, coverageUnknownFiles: change.coverageUnknownFiles, unlinkedUnits: change.unlinkedUnits, leftOut: change.leftOut } }' --params '{"file":"src/reader/reader.ts","files":["src/projections/studio/pages/roadmap-page.ts","specs/consumers/roadmap.sdp.md","AGENTS.md"]}' +``` + +**Teaches:** The file entry adapter `g.byFile(path)` called directly, and the changeset adapter `g.blastRadius(files)` through recipe 4's summary, paths passed as JSON data. + +**Read:** A file the graph records nothing at lands in `coverageUnknownFiles` (here `AGENTS.md`): its reach is unknown, not empty. `byFile` on such a path returns empty nodes and specs, with the same meaning. A carrier path resolves to its own Spec; a unit bound to no Spec is a lawful identity-only anchor. `impactedPacks` lists only changed Pack manifests; a Pack holding an impacted Spec appears in `atRiskOther`. At-risk is one hop either way and asserts no dependency. For your own changes, pass recipe 4's git-diff file beside a file: `--params "@$changed" --params '{"file":"..."}'` (params merge). + +## 10. Read Specs + +For a list of Specs, or a Pack's members: named coordinate, stated and derived readiness, delivery facts, carrier file, outcome, keyed rules with their lines, a decision's ruling, Design and UI keys, open questions, relations with claims, implementations and verifiers. + +```bash +pnpm --silent sdp:q 'const ids = params.specs === undefined ? g.packContext(params.pack)?.members.map((m) => m.id) : [params.specs].flat(); if (ids === undefined) return { specs: params.specs ?? null, pack: params.pack ?? null, found: false }; return ids.map((id) => { const c = g.specContext(id); if (c === undefined) return { id, found: false }; const s = c.sections; const line = new Map(c.entryLocations.map((l) => [l.entry, l.line])); const keyOf = Object.fromEntries(Object.entries(s.behavior?.ruleKeys ?? {}).map(([k, v]) => [v, k])); const clip = (t) => { const x = typeof t === "string" ? t : JSON.stringify(t); return x.length > 110 ? `${x.slice(0, 110)}...` : x; }; const inbound = {}; for (const r of c.relationsIn) inbound[r.type] = (inbound[r.type] ?? 0) + 1; return { id, title: c.title, coordinate: `${c.kindDisplayLabel}, ${c.altitude}`, readiness: `stated ${c.statedReadiness}, derived ${c.derivedReadiness}`, deliveryFacts: c.deliveryFacts, file: c.file, outcome: clip(s.intent?.outcome ?? ""), ...(s.decision ? { decision: clip(s.decision.decision) } : {}), rules: (s.behavior?.rules ?? []).map((r, i) => `line ${line.get(`rule[${i}]`) ?? "-"} ${keyOf[`rules[${i}]`] ? `#${keyOf[`rules[${i}]`]}` : "(unkeyed)"}: ${clip(r)}`), designKeys: Object.keys(s.design ?? {}), uiKeys: Object.keys(s.ui ?? {}), questions: (s.intent?.openQuestions ?? []).map((q) => `${q.key ?? "(unkeyed)"}${q.blocking ? ", blocking" : ""}`), relationsOut: c.relationsOut.map((r) => `${r.type} ${r.otherId} [${r.claim}]`), relationsIn: inbound, implementations: c.implementations.map((u) => `${u.codeId} at ${u.file}:${u.line} [${u.claim}]`), references: c.references.length, verifiers: c.verifiers.map((v) => `${v.verifierId} via ${v.via}${v.enabled ? "" : ", not enabled"}`) }; })' --params '{"specs":["spec:consumers.agent-surface","spec:decisions.agent-front-door"]}' +``` + +**Teaches:** The frozen join `g.specContext(id)` over ids from `--params`, joining `ruleKeys` (`rules[N]`) to `entryLocations` (`rule[N]`); `found: false` is the honest answer for an unknown id or Pack. + +**Read:** Pass `specs` (a list or one id) or `pack`; a large Pack floods, so pass a list. Read the outline first, then fetch exact wording by address (query 11); rule text is clipped at 110 characters. When stated and derived readiness disagree, report both. Only `implementations` (a `satisfies` edge) confers `implemented`; `references` confers no delivery fact. A verifier via an example counts only when it is enabled. Recipe 3 adds every section's entries and floor clauses for one Spec, but often prints more than the carrier. Open the carrier only for the exact prose to edit, at the printed line. + +## 11. Check a citation + +For each entry address: the slot it resolves to, its file and line and its full wording, or why it fails and which keys the named section holds. + +```bash +pnpm --silent sdp:q 'const answer = await recipes(25, { addresses: [params.addresses ?? []].flat() }); if (answer.diagnostics) return answer; return { totals: answer.totals, rows: answer.rows.map((r) => r.resolves ? `${r.address} -> ${g.resolveEntryAddress(r.address).entry} at ${r.file}:${r.line}: ${typeof r.value === "string" ? r.value : JSON.stringify(r.value)}` : `${r.address} UNRESOLVED (${r.reason})${r.available ? `; its ${r.section} keys: ${r.available.join(" ") || "none"}` : ""}${r.expected ? `; expected ${r.expected}` : ""}`) }' --params '{"addresses":["spec:consumers.agent-surface#rule.entryAdapters","spec:consumers.spec-studio.index-page#rule.packList","spec:consumers.spec-studio.index-page#ui.packList","spec:consumers.agent-surface"]}' +``` + +**Teaches:** The frozen join `g.resolveEntryAddress(address)` beside address resolution, `recipes(25, { addresses })`, which adds the wording and the line the join leaves out. + +**Read:** Run it before writing any entry address into prose, a test or a page. A miss names its reason: `spec`, `section`, `entry` (with the keys that section holds) or `malformed`. A bare Spec id is not an entry address: check it with query 10. Decision sections and narrative carry no entry address, so quote them from the carrier. diff --git a/AGENTS.md b/AGENTS.md index b24b56dd..20156541 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,6 +25,19 @@ code behavior into intent. > `pnpm --silent sdp validate . --exclude explorations --exclude examples --exclude test/fixtures/import/parity` > and read recipes 8 and 11. Recipe 1 is the operational backlog, not the census. Never invoke a bare `sdp`. +## Orient before work + +**Before any work in this repository** (code, Specs, documents or a review), and before answering +a question about the Protocol: read `CONTEXT.md`, load the `sdp-agent-surface` skill, and run the +eleven queries in [its orientation file](.agents/skills/sdp-agent-surface/orientation.md) from the +repository root, in order, reading each answer with the notes beside it. Re-run them in every +session; never quote their numbers. When briefing another agent, name the skill and give it exact +`sdp:q` bodies, not a description of the graph. + +1. The corpus and its surface · 2. The capabilities · 3. The Packs · 4. Honest and built · +5. Next work · 6. Undecided · 7. Architecture and decisions · 8. Arrive with a word · +9. Arrive with a file or a changeset · 10. Read Specs · 11. Check a citation + ## The frame An **executable, self-validating meta-model of the software-delivery process**, on three clean levels: @@ -52,21 +65,21 @@ event log**. Coding agents **script the typed graph** (the **agent surface** — Progressive disclosure — start at the top, follow the pointers down. -| Look here | What you get | Read | -|---|---|---| -| `CONTEXT.md` (repo root) | **the vocabulary** — the ratified lean glossary (terms · relations · a worked dialogue · flagged ambiguities); sole source of truth for terminology; the model exposition lives in the Specs under `specs/` and in the surviving concept docs | **first, always** | -| `.agents/skills/` + `docs/agent-surface/recipes.md` | **the agent on-ramps** — five repository-owned skills: `sdp-agent-surface` (reading the graph), `sdp-authoring` (authoring intent), `sdp-sessions` (advisory delivery-session routing), `sdp-studio` (publishing, sharing and reading the Studio), `sdp-vault` (keeping the Obsidian vault), also exposed to Claude through the `.claude/skills` symlink; plus the catalog of runnable `sdp q` bodies | **mandatory** — after `CONTEXT.md`, load the matching skill before any corpus question, Spec authoring, delivery-session routing, Studio publishing or reading, or vault work; see "Query the graph first" | -| `specs/` | **the self-hosted corpus** — the Protocol's own Specs in its own carrier (families: `model` · `extraction` · `validation` · `carrier` · `consumers` · `protocol` · `observation` · `decisions`, plus Pack manifests for self-hosting and grouped design work); the primary carrier of intended truth | when design truth is in question — but query it through `sdp q` first, then read the carrying Spec | -| `jtbd-stories/` | **the jobs (functional spec)** — stable `When / I want / so I can` stories (themes A–H); no personas, because consumers are heterogeneous (humans, CI, CLIs, **AI agents**) | to know *what* we serve | -| `docs/concept/` (+ README) | **the technical design** — the surviving principle-led docs: vision & MVP boundary, founding principles (P1–P10), authoring & binding, the consumer pointers and discipline mapping (06), and the MVP acceptance of record (07); the core model, the one graph, validation & honesty and the consumer law dissolved into the `model.*`, `extraction.*`, `validation.*` and `consumers.*` Spec families; the historical MVP slice record lives in the slice-5 plan under `plans/` and in `examples/checkout-v1`, while forward roadmap intent lives in capture Specs — locate any of them with concept search (recipe 6) | to know *how* it is designed | -| `docs/concept/DECISIONS.md` | **the lean decision registry** — ratified names, one-line glosses, carrying Specs, and the D1–D6 lookup; historical rationale lives in git, plans, and the Specs themselves | when resolving a decision name or following its canonical pointer | -| `src/` | **the engine** — `model` (Spec/descriptors/pack/anchors) · `extract` · `graph` · `validate` · `reader` (agent surface) · `projections` (Design Review, census, Mermaid, Gherkin and Studio) · `cli` (`sdp build` · `validate` · `view` · `census` · `mermaid` · `gherkin` · `studio` · `vault` · `stamp` · `generate` · `import` · `new spec` · `q`) · `import` (carrier conversion and import analysis) · `testing` (the registrar runtime exported through `./testing`) · `runner` / `codegen` / `notation` / `adapters` | when implementing or verifying **current engine** behavior | -| `examples/checkout-v1` | **the worked MVP example** (Markdown carriers; originally the TS DSL tracer bullet) — specs, anchors, untracked `generated/` (regenerated in-pipeline); walkthrough in its README | when proving the loop end-to-end | -| `explorations/` | **evidence only** (carrier exhibits, executable-example findings) — mapping evidence for design; **never promote spike code into product** | when judging design evidence; not a source tree to ship | -| `docs/lineage/` | historical design evidence — the v0 concept set, restored verbatim with lineage headers, plus two authored annotation notes: the short annotation context (`annotation-context.md`) and the dated research scout, kept temporarily under an `archive-` name; each note states its own status; all of it is evidence for design reviews, never intended truth | when a review needs superseded design, or the background to the annotation decisions, on the table rather than in git history | -| `pack:roadmap` + recipe 53 | **the next work** — the owner's advisory priority over upcoming capabilities, each entry placed by the graph as to design, to state, to build or built; the open arc's record is its draft pull request | before writing code | -| `npm run check` | **the green gate** — `check:temporal` → `lint` → `format:check` → `build` → `generate:self-hosting` → `generate:example` → `typecheck` → `typecheck:examples` → `test` → `check:self-hosting-gates` → `check:self-hosting` → `check:example` → `preflight` | before claiming green / after engine edits | -| `plans/`, `reviews/` | **frozen history** of earlier arcs: plans, session reviews, prompts and assets; read for provenance; nothing is added | rarely | +| Look here | What you get | Read | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `CONTEXT.md` (repo root) | **the vocabulary** — the ratified lean glossary (terms · relations · a worked dialogue · flagged ambiguities); sole source of truth for terminology; the model exposition lives in the Specs under `specs/` and in the surviving concept docs | **first, always** | +| `.agents/skills/` + `docs/agent-surface/recipes.md` | **the agent on-ramps** — five repository-owned skills: `sdp-agent-surface` (reading the graph), `sdp-authoring` (authoring intent), `sdp-sessions` (advisory delivery-session routing), `sdp-studio` (publishing, sharing and reading the Studio), `sdp-vault` (keeping the Obsidian vault), also exposed to Claude through the `.claude/skills` symlink; plus the catalog of runnable `sdp q` bodies | **mandatory** — after `CONTEXT.md`, load the matching skill before any corpus question, Spec authoring, delivery-session routing, Studio publishing or reading, or vault work; see "Query the graph first" | +| `specs/` | **the self-hosted corpus** — the Protocol's own Specs in its own carrier (families: `model` · `extraction` · `validation` · `carrier` · `consumers` · `protocol` · `observation` · `decisions`, plus Pack manifests for self-hosting and grouped design work); the primary carrier of intended truth | when design truth is in question — but query it through `sdp q` first, then read the carrying Spec | +| `jtbd-stories/` | **the jobs (functional spec)** — stable `When / I want / so I can` stories (themes A–H); no personas, because consumers are heterogeneous (humans, CI, CLIs, **AI agents**) | to know *what* we serve | +| `docs/concept/` (+ README) | **the technical design** — the surviving principle-led docs: vision & MVP boundary, founding principles (P1–P10), authoring & binding, the consumer pointers and discipline mapping (06), and the MVP acceptance of record (07); the core model, the one graph, validation & honesty and the consumer law dissolved into the `model.*`, `extraction.*`, `validation.*` and `consumers.*` Spec families; the historical MVP slice record lives in the slice-5 plan under `plans/` and in `examples/checkout-v1`, while forward roadmap intent lives in capture Specs — locate any of them with concept search (recipe 6) | to know *how* it is designed | +| `docs/concept/DECISIONS.md` | **the lean decision registry** — ratified names, one-line glosses, carrying Specs, and the D1–D6 lookup; historical rationale lives in git, plans, and the Specs themselves | when resolving a decision name or following its canonical pointer | +| `src/` | **the engine** — `model` (Spec/descriptors/pack/anchors) · `extract` · `graph` · `validate` · `reader` (agent surface) · `projections` (Design Review, census, Mermaid, Gherkin and Studio) · `cli` (`sdp build` · `validate` · `view` · `census` · `mermaid` · `gherkin` · `studio` · `vault` · `stamp` · `generate` · `import` · `new spec` · `q`) · `import` (carrier conversion and import analysis) · `testing` (the registrar runtime exported through `./testing`) · `runner` / `codegen` / `notation` / `adapters` | when implementing or verifying **current engine** behavior | +| `examples/checkout-v1` | **the worked MVP example** (Markdown carriers; originally the TS DSL tracer bullet) — specs, anchors, untracked `generated/` (regenerated in-pipeline); walkthrough in its README | when proving the loop end-to-end | +| `explorations/` | **evidence only** (carrier exhibits, executable-example findings) — mapping evidence for design; **never promote spike code into product** | when judging design evidence; not a source tree to ship | +| `docs/lineage/` | historical design evidence — the v0 concept set, restored verbatim with lineage headers, plus two authored annotation notes: the short annotation context (`annotation-context.md`) and the dated research scout, kept temporarily under an `archive-` name; each note states its own status; all of it is evidence for design reviews, never intended truth | when a review needs superseded design, or the background to the annotation decisions, on the table rather than in git history | +| `pack:roadmap` + recipe 53 | **the next work** — the owner's advisory priority over upcoming capabilities, each entry placed by the graph as to design, to state, to build or built; the open arc's record is its draft pull request | before writing code | +| `npm run check` | **the green gate** — `check:temporal` → `lint` → `format:check` → `build` → `generate:self-hosting` → `generate:example` → `typecheck` → `typecheck:examples` → `test` → `check:self-hosting-gates` → `check:self-hosting` → `check:example` → `preflight` | before claiming green / after engine edits | +| `plans/`, `reviews/` | **frozen history** of earlier arcs: plans, session reviews, prompts and assets; read for provenance; nothing is added | rarely | Key decisions (names first): the executable meta-model (MD-1); one primitive named coordinates (MD-4); the carrier ruling (MD-18); the agent front door (MD-22); the shipped projections stay frozen (MD-32); planning truths live in ruled graph homes (MD-33); the comment form (MD-36); bindings are optional, plural, and may reference a design (MD-37); architectural significance is annotated where it is realized (MD-38). diff --git a/PRODUCT.md b/PRODUCT.md new file mode 100644 index 00000000..8026cebe --- /dev/null +++ b/PRODUCT.md @@ -0,0 +1,272 @@ +# Product + + + +> The product brief for design work on the Libar Software Delivery Protocol's human-facing readings: users, +> jobs, positioning and constraints, with no visual decisions. It is not a requirements document and confers +> nothing. Intended truth lives in the carrying Specs, and on any conflict they and the ratified language in +> [`CONTEXT.md`](CONTEXT.md) win. Design words used here, such as _reading_, _delivery role_ and _persona_, are +> provisional and listed in [`docs/design/`](docs/design/README.md). Corpus counts are derived, never quoted. + +## Platform + +web + +The open-source Studio is a static HTML page set, deterministic for one graph and its named inputs, and +stamped when it is published. A commercial Studio is under exploratory consideration as a desktop app, a web +app and a CI/CD surface (see Capabilities and Constraints); all three are assumed to be built on web +technology, which is why the platform stays `web`. + +## Users + +The design work serves **typical software delivery roles**: the people whose work the classic Rational Unified +Process disciplines describe. The Protocol maps those disciplines onto its graph as filters by kind or section, +never as roles or phases ([`docs/concept/06`](docs/concept/06-consumers-and-projections.md), section 6); which +readings each delivery role needs is design work ([RUP roles and artifacts](docs/design/11-rup-roles-and-artifacts.md)). +A delivery role is a person's job in delivery, distinct from the ratified `role`, the architectural pattern on a +code anchor. Every role below is in scope. The first design cycles concentrate on technically minded roles, +because that is where the Protocol is strongest. + +| Delivery role | Situation | Job the readings serve | +| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Technical product manager** | Owns what a bounded context should do and why, and thinks in capabilities, constraints and architecture rather than visual product design | Survey where intent stands across Packs, find what blocks a capability, decide where to invest next, and send precise change requests (JS-A6, JS-E3, JS-F1) | +| **Readiness author / question decider** | States a Spec's readiness by editing its carrier and settles the open questions whose `decider` names them; the graph records no Spec owner, and git records who stated what | Review a Spec or Pack in context, see what holds its stated next rung, work the statement queue, state `ready` as a deliberate edit (JS-E4) | +| **Software architect** | Works with components, contexts, layers, decisions and architecture rules | See planned against realized components, follow a decision to what it shaped, judge a change's impact before it happens (JS-G1, JS-G5) | +| **Engineer / implementer** | Builds against `ready` Specs, usually through an AI coding agent | Trace a Spec to its bindings, verifiers and source, read blast radius over a changeset, hand scoped context to an agent (JS-G1, JS-G2, JS-E2) | +| **Tester / QA** | Works on examples, example spaces and verifier bindings | Find Specs that still need a verifier, see example-space coverage, read supplied run evidence beside the bindings (JS-G2, JS-G4) | +| **Engineering leader / project lead / auditor** | Needs a trustworthy picture of delivery without hand-authored status | Read the roadmap's needs, readiness and realization side by side, follow decision trails, without a progress score that invents certainty (JS-A6, JS-G5) | + +**Pull-request reviewer.** The first cycles also take the pull-request reviewer who holds only a link to a +stamped preview, the actor the Studio is written for (`spec:consumers.spec-studio`): see what changed in the +design, what it touches and whether it is ready, from the pages alone (JS-E3, JS-G1). +[Roles and perspectives](docs/design/01-roles-and-perspectives.md) keeps it in its extended tier. + +**The full range stays open.** The roles above are the first design cycles' focus, not the limit of the +product. Because readings are cheap to regenerate, the product deliberately keeps room for niche, specialised +and ultra-specialised personas (for example a security or compliance reviewer, an NFR budget owner, a newcomer +onboarding to a codebase, a corpus curator) and for AI-powered readings. None of them is ruled out by focusing +on traditional delivery views first. _Persona_ is a design-material word here: the +[job stories](jtbd-stories/README.md) deliberately name no personas, so each persona is paired with the job +stories it serves. The working catalogue lives in [`docs/design/`](docs/design/README.md). + +**Later audience.** Product designers who work on visual product design are a later audience for the +readings, not an early design target. + +**Non-human consumers.** AI coding agents are first-class consumers through the agent surface (`sdp q`, +recipes, context bundles), and CI is a consumer of the checks. Neither needs a visual view, but every human +reading must hand off cleanly to an agent as scoped intent and must agree with what the agent surface +answers. + +## Product Purpose + +The Protocol models the whole software delivery lifecycle as typed content in the repository, derives +**one graph** from it, and generates every other artifact from that graph. The graph is the single read +model. Design Review, census, Mermaid, Gherkin, the Spec Studio and the vault's notes are **projections**: +pure, disposable, regenerable readings of it, never second stores. Agents and the command line read the same +graph through `sdp q` and its shipped recipes. + +Because a projection is cheap to regenerate, readings can change freely. The design work exists to turn that +freedom into **dedicated readings for each delivery role and kind of work**, instead of one general Studio +that exposes data because it is available. The current Studio is working material for learning which readings +help, not a layout to preserve. Its present layout is still intended truth, carried by ready Specs in +`pack:spec-studio-v1` (for example `spec:consumers.spec-studio.navigation#rule.topEntries`), so changing it +means an engineering session revises those Specs and their tests. + +Success is a direction, not yet a measure: a person in one of the roles above can do their delivery job from +a published reading, without opening the repository, and can see what the reading rests on. The nearest +measure on record is the Studio's manual acceptance, in which a person given only a link completes named +review tasks from the pages alone (`spec:consumers.spec-studio`, `spec:consumers.spec-studio.slice-page`). + +## Positioning + +- **One primitive, one graph, many readings.** Ideas, use cases, NFRs, decisions, contracts and examples + are all one `Spec`, enriched in place and positioned by `kind`, `altitude` and stated `readiness`. Every + view is a function of the same graph (and, for the Studio, of the inputs it names), so views agree with + each other and with the repository state they were built from; a stamped Studio names that commit. +- **Honest by construction.** The `claim` of every fact (`declared`, `anchored`, `inferred`) is never + collapsed. Delivery facts (`implemented`, `has-verifier`, `observed`) are derived, never authored. + Stated readiness sits beside derived readiness, the floor reached. The Protocol claims "deterministically + validated," never "provably correct." +- **Disciplines without gates.** It keeps the established delivery nouns and RUP's disciplines as + filters over the graph, and rejects phase gates, ticket state machines and hand-authored status. + Phase, iteration and milestone are descriptive words a roadmap may use; the roadmap itself is a Pack read + in the owner's priority order, and release and baseline views stay deferred + (`spec:consumers.projections-model.roadmap-views#question.releaseReader`). None is a gate. +- **AI-native, not AI-dependent.** The spec is the prompt is the design. Agents script the typed graph + instead of guessing from raw files, and people review in readings built for review. +- **The membrane, not a replacement.** It is designed to complement ticketing, design and observability + tools and, later, to link to them; it does not try to replace Jira, Figma or CI dashboards. The links are + aspirational today ([`docs/concept/00`](docs/concept/00-vision-scope-and-mvp-boundary.md)). + +## Operating Context + +- **Where truth lives.** Authored Specs and Packs in carriers (Markdown `.sdp.md` by default; behavior and + example Specs may use Gherkin, `.sdp.gherkin`, and the TypeScript DSL is a lawful per-ID option), anchors + in source code, and git as the event log. A reading shows what the graph derives, plus a stamp and any + outside inputs, each labelled as such; none of them becomes graph data or delivery truth. +- **How readings are produced.** `sdp generate` publishes all five projection roots from one validated + graph. The Studio is a static page set that works from `file://` or any static host, with no server. + A publishing step after the build (`sdp stamp`) writes a stamp naming the corpus commit, the engine, the + graph schema version and the publishing time, and optionally a source template that turns each recorded + file and line into a code-host link; a page opened through `file://` shows no stamp. The same graph is + also projected into an Obsidian vault (generated notes and Bases beside a person's own notes), and every + diagram is generated from the graph, never drawn by hand. A UI view is one more projection. +- **How the graph grows to serve readings.** The graph is not complete: architecturally significant + units may carry no anchor and relations may be missing. Design work is one of the ways those gaps + are found. A reading never invents missing material. Design sessions record the need + ([`docs/design/07-graph-needs.md`](docs/design/07-graph-needs.md)) for engineering sessions to + consider; they never edit anchors or other graph inputs themselves. When an engineering session + extends the graph, the reading is generated from it. +- **How readings are shared.** A reusable workflow builds, stamps and uploads a Studio for each pull + request, and deploys it as a preview where the repository has chosen a host, as this one has (for + example the [PR #34 preview](https://libar-dev.github.io/software-delivery-protocol/preview/34/index.html)). + A Pack exports as one self-contained HTML file. Reviews happen on desktop and on phones. +- **How change flows.** A reader gathers **scoped intent** in the composing panel, which hands it off as a + change proposal and its memo against a named base; an agent applies it as an ordinary source edit; git + records it; the conformance and honesty checks evaluate it; a regenerated graph produces new readings. A + view never writes to canonical source. +- **Outside inputs.** A base graph (for the design diff) and CTRF run records (run evidence) can be + supplied to a Studio build (`sdp studio --base`, `--runs`); `sdp generate` takes neither. Each is named + on every page that shows it: the base graph by its label, schema version and Spec count, and a run by the + commit its record holds, or `not recorded`. Neither becomes graph data or a delivery fact. +- **Rituals the readings serve.** Pack design passes, Design Review before stating `ready`, pull-request + review from a preview link, roadmap reading (recipe 53 over `pack:roadmap`), the statement queue + (recipe 46, and the Studio's owner queue page), and review findings that travel as change proposals. + +## Capabilities and Constraints + +**Fixed ground for every design.** Each line is carried by the Spec or decision it cites. The seed design +and the article series' brief first wrote much of it down, but they are evidence, not its authority. + +- The repository is canonical and the graph is the sole read model; a view states no truth and confers + nothing back into the graph (`spec:consumers.projections-model`, + `spec:consumers.spec-studio#rule.noSecondGraph`). +- Claims, stated readiness, derived readiness and delivery facts stay visibly distinct, and none is merged + into a progress score (`spec:extraction.claim-taxonomy`, `spec:consumers.pack-design`, + `spec:consumers.capability-map`). +- A binding is not a verdict: `implemented` and `has-verifier` mean a binding exists, not that code works + or a test passed (`spec:decisions.binding-not-liveness`). +- Absence is named. Missing verifiers, example-space values no example binds, spaces that are + `not measurable`, slots that are `not enumerable`, `coverage-unknown` files and floors that are + `not evaluated` each read as their own kind of absence (`spec:consumers.spec-studio.lenses.tests`, + `spec:consumers.spec-studio.verification-panels`). +- Every diagram has a complete text equivalent that survives when the drawing is folded or omitted + (`spec:consumers.spec-studio.diagrams#rule.textEquivalent`). +- The only write affordance is composing scoped intent; source edits and git history happen outside the + view (`spec:consumers.edit-model`). +- Outside inputs stay named wherever they appear (`spec:consumers.spec-studio#rule.namedInputs`). +- Conformance and honesty checks never judge content, visual or design quality + (`spec:validation.two-check-families`). +- The shipped-projections decision (MD-32) freezes Design Review, census, Mermaid and Gherkin; reshaping one + needs a decision that refines or supersedes it. The Studio and any new reading evolve under their own + Specs, within the Studio's own decisions: the derived-HTML decision (MD-41), the custom-elements decision + (MD-42), the build-renders decision (MD-43) and the diagram-layout decision (MD-44). A design that + crosses one of them needs a decision that refines or supersedes it. + +**Open design space:** navigation and page structure; which current Studio pages survive, merge or +disappear; role- and work-specific readings; how a person moves between a Pack, a Spec, an entry and its +source; desktop against phone review; what belongs in the first reading and what behind disclosure. + +**Product direction:** + +- The core Protocol is and stays **open source and free** (Apache-2.0), as the package + `@libar-dev/software-delivery-protocol`, installed from a pinned commit until a first release is + published. The Studio's Spec records that the read-only Studio ships in that package, and that hosted + review, shared comments and hosted previews may later ship under the commercial `@libar-ai/` namespace + (`spec:consumers.spec-studio`). +- **Exploratory:** a **commercial Studio** is under consideration, possibly as a desktop app, a web app + and a CI/CD surface. This is the owner's direction for the design work and is recorded in no Spec yet; + its scope, packaging and pricing are undecided. The open-source package already ships a CI preview + workflow (`spec:consumers.spec-studio.sharing#rule.previewWorkflow`). + +**Open product questions.** A long-horizon research backlog, answered over many design cycles rather than +settled now. Giving these questions a corpus home, as keyed open questions in a design Pack, is a proposal +for an engineering session and the owner, recorded with the other [graph needs](docs/design/07-graph-needs.md); +design sessions do not author it. These questions sit in the one register of design questions, +[`docs/design/06`](docs/design/06-design-cycles.md#design-questions-for-the-long-horizon). + +- What separates the free static Studio from a commercial Studio, and which readings belong to each. +- Which product state a commercial surface may hold, where it lives, and how it stays out of the graph. The + static Studio already keeps a reader's gathered intents in the browser + (`spec:consumers.spec-studio.intent-panel#rule.persist`), and shared comments are already named as a + commercial candidate. +- How AI-assisted reading works. `spec:consumers.ai-assisted-reading` states `idea`. Its provisional answer + lets an assistant only select existing deterministic readings, and keeps any generated text outside the + Studio and the frozen projections, labelled as assistant output with its source commit and scope, adding + no claim, fact or validator. How that output is retained with its model, prompt and inputs is part of the + open question. The design pass may prototype assistant selection or a generated explanation against a + named review task, which is the question's trigger; shipping either waits on the owner's decision. + +## Brand Commitments + +- **Names:** product **Libar Software Delivery Protocol**, short form "the Protocol"; CLI **`sdp`**; the + human workbench is the **Spec Studio** ("the Studio"). +- **Language:** the ratified vocabulary in [`CONTEXT.md`](CONTEXT.md) is binding in every reading, label + and message. Readiness is _stated_, never "claimed"; `claim` names epistemic status only. Pre-ratification + terms are bugs to fix. +- **Voice:** lean, plain, technical language that a wider open-source audience can follow; no insider + shorthand, no overclaiming, uncertainty stated as uncertainty. +- **Design system:** an existing UI library and design system will be introduced later and will be + binding. The custom-elements decision (MD-42) builds the Studio without a framework, so a CSS-level + system fits as things stand, while a framework-based component library would need a decision that + refines or supersedes it. Until then, design work stays at the level of UX, information architecture and + task flows, and defines no visual styles, palettes or type. + +## Evidence on Hand + +- **Seed design**, written before any code: [`docs/lineage/v0-design/`](docs/lineage/v0-design/README.md), + above all [00](docs/lineage/v0-design/00-vision-and-product.md) (vision, personas, the North Star + scenario) and [07](docs/lineage/v0-design/07-spec-studio-and-projections.md) (the Studio as a workbench). + It is product context and direction, not current law. +- **Article series:** [`docs/articles/`](docs/articles/README.md); Article 2 holds the compact brief for the + first UX/UI design pass and its open questions; Article 5 sets the AI-reading boundaries. +- **Jobs:** [`jtbd-stories/`](jtbd-stories/README.md), themes A–H, with acceptance criteria per job. +- **Working prototype:** the current Studio. The preview workflow builds it for each pull request with + `sdp studio`, a base graph and run records, then stamps it with `sdp stamp`; `sdp generate` writes the + same Studio locally without those inputs. Its manual acceptance tasks live in `spec:consumers.spec-studio` + and `spec:consumers.spec-studio.slice-page`, one of them on a phone. At the close of PR #35 a reader job + given only the pages of the first adopter's copy completed the Studio's tasks; no recorded session shows a + person completing them. +- **First-adopter feedback**, kept in the first adopter's repository and cited by + `spec:consumers.spec-studio` and `spec:consumers.review-perspectives`: agent readers working named review + tasks from a generated page, and the adopter's request to make the human reading experience the next + milestone. It is agent task evidence and adopter demand, not human usability results. +- **Real corpora:** the Protocol's own self-hosted corpus under `specs/`, the worked example + `examples/checkout-v1`, and one first adopter (historical figures cited to the pull requests that + measured them). +- **Absent, and not to be fabricated:** user research or human usability results, testimonials, named + customers, adoption metrics beyond those measured in pull requests, commercial pricing or packaging, and + benchmarks for AI-assisted reading. + +## Product Principles + +1. **Design for the job, not for the data.** Readings are free to regenerate, so each one should serve a + named delivery role doing a named task. A page that only exposes what the graph happens to hold has not + earned its place. +2. **Make the basis visible.** A reading keeps intent, bindings, inferred structure and outside inputs + visibly apart, and a published Studio names the commit and engine it was built from through its stamp. + Pages opened through `file://`, Pack exports and vault notes name no commit today; how they show their + basis is an open design question. Trust comes from what a reader can inspect, not from polish. +3. **Disciplines are filters, never gates.** A discipline selects Specs by kind or section, a perspective + selects and orders a Pack's members for one concern, and a delivery role decides which readings a person + needs. No reading implies a phase to pass, a quota to fill or a status someone typed in. +4. **Read richly, write through intent.** A view helps people understand, compare and decide, and its only + output is scoped intent for an agent and git to carry. It never becomes an editor of truth. +5. **Name every absence.** What is missing, unmeasured or unknown is shown as its own kind of absence, so + no empty space is left for a reader to guess about. + +## Accessibility & Inclusion + +- Every diagram keeps a complete text equivalent + (`spec:consumers.spec-studio.diagrams#rule.textEquivalent`), as both an accessibility rule and an honesty + rule. +- The Studio's Specs already set a baseline: every link and control is reachable from the keyboard with + visible focus (`spec:consumers.spec-studio.shell#rule.keyboard`) and is a native, labelled control + (`spec:consumers.spec-studio.page-elements#rule.nativeControls`); every meaning a colour conveys is also + in words (`spec:consumers.spec-studio.shell#rule.wordsBesideColor`, + `spec:consumers.spec-studio.shell#rule.rungBadge`), including the current page + (`spec:consumers.spec-studio.navigation#rule.currentPage`); and every page but search reads without its + script (`spec:consumers.spec-studio.shell#rule.withoutScript`). +- Phone review is a real use: reviewers open stamped previews on phones, so readings must keep their + meaning at phone width. +- A formal conformance target (such as a WCAG level) has not been set. diff --git a/docs/design/01-roles-and-perspectives.md b/docs/design/01-roles-and-perspectives.md new file mode 100644 index 00000000..0103783b --- /dev/null +++ b/docs/design/01-roles-and-perspectives.md @@ -0,0 +1,232 @@ +# 01 — Roles and perspectives + +Readings are cheap to regenerate, so the product can afford readings for many delivery roles. This +catalogue keeps the whole range in view, from core delivery roles down to niche, ultra-specialised +and AI-assisted readers. The first design cycles concentrate on tier 1. That is where the work +starts, not where it stops: nothing in the lower tiers is ruled out. + +## The principle the seed set + +The seed design gave every role the same reading surface and left authoring native to each role: + +> No persona is forced to learn an unfamiliar surface. The Spec Studio is the *reading* surface for +> everyone; authoring surfaces remain native to each role. +> ([seed 04, section 6](../lineage/v0-design/04-authoring-surfaces.md)) + +This foundation keeps that principle and sharpens it. Everyone reads the **same graph** and lands +on the **same Spec and Pack pages**. What differs by persona is the entry, the selection, the order +and the emphasis: the role home (a provisional term, see below) and what it selects. + +What a shipped entry can select is narrower than it sounds. The Studio shows a recipe's answer only +when its design names that recipe (`spec:consumers.spec-studio#rule.recipeAnswers`), and beside the +graph it reads only a base graph and run records (`spec:consumers.spec-studio#rule.namedInputs`). +Perspectives are corpus data that each corpus owns, and the Protocol ships none +(`spec:consumers.review-perspectives`). So a Protocol-shipped entry selects through named recipes and +disciplines. A home built from a corpus's own perspectives would need a further named input, which +is an open design question. The outside-register input, stated at `scoped` +(`spec:consumers.spec-studio.register-input`), is the precedent for adding one. + +The seed named five personas, each with a value proposition ([seed 00, sections 4–5](../lineage/v0-design/00-vision-and-product.md)): +domain engineer, architect, product manager or business analyst, QA engineer and AI agent, with an +auditor in the value table. Its North Star scenario follows one product manager from a Studio +page to a reviewed change, and its last line is a status report for leadership "generated from the +graph; nobody had to write it." The tiers below extend that cast. + +## Persona, delivery role, perspective, reading + +Four words that are easy to confuse. Only **perspective** is ratified. The other three are +provisional design words: they stay out of labels, Specs and the glossary until the owner rules on +them. + +- A **persona** is a person we design for: a delivery role, a situation, a job. It lives in design + material only. The [job stories](../../jtbd-stories/README.md) deliberately bind to no persona, so + this design pairs each persona with job stories and writes any new job it finds as a persona-free + story. Inside a Spec, whom it serves is its Intent `actor` line, which a minority of Specs carry. +- A **delivery role** is a person's job in delivery, in the RUP sense (catalogued in + [11](11-rup-roles-and-artifacts.md)). This document says "role" in that sense, and it collides + with the ratified **role** in [`CONTEXT.md`](../../CONTEXT.md): the one-token architectural pattern + on a code anchor (the architectural-annotation ruling, MD-38). "Role home" and any other compound + on it are therefore provisional and must not become a Studio label as written. `decider` collides + the same way: it is both the open-question field and an anchor role value + (`spec:protocol.role-vocabulary#term.decider`). +- A **perspective** is corpus data that filters and orders a Pack's members for one concern + (`spec:consumers.review-perspectives`). It runs through recipe 37. That Spec traces it to the + seed's one reading surface, read from each reader's own concern, and to the first adopter's + advisor lenses. +- A **reading** is what the persona actually opens: a page, a projection or a recipe answer, + selected and arranged for a concern. It stays a plain design-prose word; the [README](README.md) + holds the working definition and [04](04-reading-model-and-ia.md) breaks it into parts. The corpus + already uses it informally ("a reading and not an artifact", `spec:consumers.design-slice`) and in + fixed phrases such as a Pack's reading order. + +One persona usually needs several perspectives, and one perspective serves several personas. + +## No owner in the graph + +The seed's Spec carried an optional `owner`, a team or person handle, and so did its open +questions ([seed 01](../lineage/v0-design/01-core-primitives.md)). Today's intended truth goes the +other way. Concept 00 lists "a Spec names no owner" among its deliberate non-goals +([section 5](../concept/00-vision-scope-and-mvp-boundary.md)), and the Markdown envelope is closed, +so an `owner:` key is refused (`spec:carrier.envelope-contract`). The per-Spec `owner` left the +model at the reboot (commit `ed5f6ad3`) without a decision record; the question's owner became +today's `decider`. + +What the graph holds about people: + +- An open question's `decider`: one lowercase kebab token the corpus owns, such as `owner` or + `delegated`. It references nothing, authorizes nothing and is checked against no list; an + off-grammar value is a conformance error (`spec:model.open-question-fields`). Some questions name + no decider. +- An Intent `actor` line: prose naming whom a Spec serves. It is not ownership. +- A Pack's `order: priority`, read as its owner's advisory preference without naming anyone + (`spec:model.pack-aggregate`). + +Consequences for role design: + +- A "my Specs" or "my team's work" reading cannot be computed from the graph. +- A decider's queue can be computed, but only for questions. The statement queue (recipe 46) + selects open questions by `decider`; its waiting readiness statements are corpus-wide and belong + to no one (`spec:consumers.readiness-planner#rule.waiting`, + `spec:consumers.readiness-planner#rule.ownerQuestions`). The Studio's + owner queue page is fixed to decider `owner` + (`spec:consumers.spec-studio.owner-queue#rule.ownerQuestions`); any other decider is reachable + through recipes 46 and 53 with `params.decider`. +- A role home can select by **concern** (perspective, discipline, Pack, context) without knowing who + the reader is. That is the honest default. +- Approval, and who stated `ready`, are never graph values. They live in git and in pull request + descriptions; a reading that shows them would need a supplied, labelled input. + +Governance stays outside the model. The seed kept authorization out on purpose ("`owner` is a soft +pointer … not an authorisation system"; seed 01, section 10) while keeping a descriptive owner. +Today change approval lives in git and CI (concept 00, section 5), a baseline's approval artifact is +its signed git tag, and this repository, which has no CODEOWNERS file, records its rulings and who +made them in pull request descriptions (`spec:decisions.roadmap-over-plans`). + +Whether descriptive ownership should ever return is a long-horizon research question +([06](06-design-cycles.md)), answered with evidence from the cycles. It is not a blank slate. It +would reopen a stated non-goal through a decision Spec, more likely as a section than as an envelope +key (invariant L9 in [concept 01](../concept/01-founding-principles-and-invariants.md)), and it must +avoid the workflow-tracker fields `spec:model.open-question-fields` warns against: no status, date or +assignment. What the repository already settles is collected in [08](08-what-the-repo-settles.md). + +## The RUP frame + +The classic Rational Unified Process disciplines give this design its starting vocabulary for +delivery roles. Concept 06 maps seven of them onto the graph as filters, never phases, under the +adopt-the-nouns decision (MD-2) ([`docs/concept/06`](../concept/06-consumers-and-projections.md), +section 6): Requirements, Analysis & Design, Test, Deployment, Configuration & Change Management, +Project Management and Business Modeling. The Implementation and Environment rows below, and the +cells beyond that mapping, are this design's extension. In the ratified sense a discipline is a +filter by kind or section (`spec:consumers.projections-model`); the other cells are readings grouped +under a discipline's name, and *outside the graph* marks a source a reading takes beside it. The RUP +roles and artifacts behind the last column are catalogued in [11](11-rup-roles-and-artifacts.md). + +| RUP discipline | What a reading draws on | Typical delivery roles | +|---|---|---| +| Business Modeling | `model` Specs, Model terms, the glossary | business or domain analyst | +| Requirements | `behavior` Specs, epics and their refinement, the capability map | technical product manager, requirements specifier | +| Analysis & Design | `design` sections, decision records, components, contexts, layers | software architect | +| Implementation (extension) | `satisfies` and `references` bindings, code units, the drift alarm | engineer, coding agent | +| Test | `example` Specs, example spaces, oracles, `verifies` relations; run evidence (outside the graph: supplied run records) | tester, test designer | +| Deployment | the `observed` delivery fact (designed and deferred) | operations, deployment manager | +| Configuration & Change Management | the design diff (outside the graph: a supplied base graph); git and change proposals (outside the graph) | change manager, reviewer | +| Project Management | Packs, the roadmap, the statement queue | project lead, engineering leader | +| Environment (extension) | capability adoption, the upgrade kit; corpus rules (outside the graph: rules files run over it) | process engineer, adoption lead | + +Concept 06 has drifted behind the graph; +[11](11-rup-roles-and-artifacts.md#drift-this-mapping-found) lists the drift for an engineering +session. + +The hump chart's rows translate cleanly. Its columns do not: phase, iteration and milestone are +descriptive words a roadmap's framing may use, never entry fields, dates or gates +(`spec:consumers.projections-model.roadmap-views`). A reading could show how activity rises and +falls by discipline over time once a history input is ruled. Today the Studio refuses a timeline or +a trend until one exists (`spec:consumers.spec-studio.diagram-kinds#design.timeline`, +`spec:consumers.spec-studio.diagram-kinds#design.xyChart`); an operator can already compute it outside the Studio by building graphs at +successive commits and comparing them with the design diff (recipe 35). A reading may never show a +phase someone must pass. + +## Tier 1 — core delivery roles (first cycles) + +| Persona | Seed ancestor | Situation | Jobs (job stories) | Material the graph already holds | +|---|---|---|---|---| +| **Technical product manager** | product manager / analyst (seed 00 §4); the North Star reader | Shapes what a bounded context should do and why; thinks in capabilities and architecture | Survey where intent stands, find what blocks a capability, decide where to invest, send precise change requests (A6, E3, F1) | capability map (52), roadmap (53), open questions (20), design slice (54), design diff (35) | +| **Readiness author / question decider** | Design Review reader (current) | States readiness in the carriers and settles the open questions that hold other Specs | Review in context, see what stands before the stated next rung, work the queue, state `ready` (E4) | statement queue (46: questions by decider, waiting statements corpus-wide), the owner queue page, promotion preflight (9), Pack design (29), readiness divergence (7) | +| **Software architect** | architect (seed 00 §4) | Holds components, contexts, layers, decisions and rules | Planned against realized, decision reach, impact before change (G1, G5) | architecture map (17), crossings (32), planned against realized (43), decision map (18), architecture walk (42) | +| **Engineer / implementer** | domain engineer (seed 00 §4) | Builds against `ready` Specs, often through an agent | Trace a Spec to bindings and source, read blast radius, hand context to an agent (G1, G2, E2) | Spec guarantees (3), changed-file impact (4), build backlog (1), context bundle (36) | +| **Tester / QA** | QA / test engineer (seed 00 §4) | Writes and keeps examples, example spaces and verifier bindings | Find Specs without verifiers, read space coverage, read run evidence (G2, G4) | orphans and gaps (8), declared against enabled verifiers (10), rule coverage (34), space coverage (44), run evidence (45) | +| **Engineering leader / project lead / auditor** | auditor (seed 00 §5); leadership report (seed 00 §9) | Needs a trustworthy picture without hand-authored status | Readiness and realization side by side, decision trails (A6, G5) | roadmap needs (53), census, decision register (31), lower ladder (11) | + +Letters and numbers in the jobs column are [job story](../../jtbd-stories/README.md) ids; numbers +in the last column are recipes; "seed NN §x" points into the seed's documents +([`docs/lineage/v0-design/`](../lineage/v0-design/README.md)). Each persona describes a person, +never a graph value: no Spec records who owns it, and the RUP role each row draws on is in +[11](11-rup-roles-and-artifacts.md). + +The first cycles also take the pull-request reviewer, the Studio's own Intent actor ("a pull +request reviewer who holds only a link", `spec:consumers.spec-studio`), whose jobs are E3 and G1. +Its row stays in tier 2 below. + +## Tier 2 — extended delivery roles + +| Persona | Situation | What a reading would serve | Notes | +|---|---|---|---| +| **Business / domain analyst** | Maintains the shared domain language | Model terms, term addresses, where a term is used | Business Modeling; concept search (6), entry search (23). The seed's Pack-level shared model (seed 01 §3) made vocabulary coherence a Pack concern | +| **Requirements specifier** | Writes behavior, rules and examples for others to build | Which rules no example exercises, which values no example binds | rule coverage (34), space coverage (44) | +| **Stakeholder in a review** | Plays with a behavior to confirm expectations before work starts | Explore an example space: inputs, expected outcome class, which points have a witness | the seed's harness (seed 04 §4) served this job; today a Spec page shows a space's bound points and per-slot coverage; see [02](02-seed-experience-map.md) | +| **Pull-request reviewer** | Opens a stamped preview from a pull request | What changed in the design, what it touches, whether it is ready | diff page, blast radius; the North Star's developer half | +| **Change / configuration manager** | Keeps the change flow trustworthy | Proposals against bases, moved or incomparable scopes | proposal check (38), proposal memo (49) | +| **Operations / SRE** | Runs what was built | NFR targets, constraint Specs, what would be observed | `observed` is deferred; the evidence lens reads every row as "not tracked" | +| **Release or deployment manager** | Cuts and ships releases | What a release contains, baselines | release and baseline views wait for a reader (`spec:consumers.projections-model.roadmap-views#question.releaseReader`, trigger: the first published release) | +| **Process engineer / adoption lead** | Brings the Protocol into a team's corpus | Capability adoption, corpus rules, upgrade opportunities | capability adoption (47), rule-key proposal (48), the upgrade kit; seed 08 §9.10's adoption advice | +| **Sponsor / stakeholder** | Funds or depends on the work, rarely opens the repo | A short, honest account of where a capability stands | must not become a progress score | + +## Tier 3 — niche and specialised + +Each row is a candidate reading, not a commitment. Rows another home already carries say so. + +| Persona | Job | Material | Gap | +|---|---|---|---| +| **Security reviewer** | Read security constraints and the architecture they cross | `constraint` Specs, crossings (32), forbidden layer pairs | a security perspective is corpus data a team writes | +| **Compliance / regulatory auditor** | Trace requirement → decision → code → verifier at a named commit | decision map (18), Spec guarantees (3), stamp | the seed's SLSA, SBOM and OTel evidence (seed 08) is not built; baseline views wait on the release question above | +| **NFR budget owner** | Watch measurable targets across a context | `constraint` Specs with targets | no measurement in the graph until `observed`; the seed's "last measured: 287 ms" stays unavailable | +| **DDD facilitator / context mapper** | Read contexts, layers and the language each context uses | roles, layers and contexts (28), architecture map (17), Model terms | context-to-term mapping is not a recipe yet | +| **BDD practitioner** | Keep examples, spaces and oracles honest | step and space contracts, witnesses, oracles; a Spec page's bound-points table and per-slot coverage (`spec:consumers.spec-studio.verification-panels#rule.coverageGrid`) | coverage of value combinations; captured in `spec:consumers.agent-surface.combination-coverage`, stated at `idea`, waiting on `spec:consumers.agent-surface.combination-coverage#question.combinationCoverage` | +| **Newcomer onboarding to a codebase** | Learn a bounded context quickly and correctly | capability map, design slice, Spec pages, bound source; a Pack's reading order; the index's task routes | a guided tour across a bounded context does not exist; seed 08 §9.10 names onboarding as an adoption wedge | +| **Technical writer** | Turn a design into outside-facing reference | slimming candidates (39) | already captured: `spec:consumers.reference-projection`, stated at `idea` | +| **Corpus curator** | Keep the corpus lean and connected | orphans (8), mention audit (22), curation report (40), slimming (39), address resolution (25) | no curator home; the seed's suggestion to declare an inferred edge (seed 03 §4.3) is closest to today's mention audit and curation report | +| **API consumer / partner team** | Read the contract two parties share | pinned declarations (24) and the declarations page, key-family register (41) | the declarations page lists by Spec; a reading per contract between two parties does not exist | +| **Due-diligence assessor** | Judge a codebase's design health from outside | census, drift alarm (2), gaps, coverage-unknown | needs a reading that names its own limits plainly | +| **Product designer** (later audience) | Connect visual designs to the behavior they serve | keyed UI entries; the seed linked Storybook, Figma and Playwright flows (seed 01 §2.10, seed 04 §5) | a later audience by product decision ([PRODUCT.md](../../PRODUCT.md)) | + +## Tier 4 — ultra-specialised + +Candidates, unranked. Each names one narrow recurring question and waits for a job story before it +becomes a brief. A narrow reading becomes affordable when it can be produced on demand, by one of +two routes ([05](05-specialised-and-ai-readings.md)): an operator-run `sdp q` body, lawful today +but with no Studio page; or assistant output shown to a reader, which waits on +`spec:consumers.ai-assisted-reading#question.aiPresentationBoundary`, whose provisional reading keeps +generated text outside the Studio. + +- **Decision archaeologist:** how did this decision come to be, what did it supersede, what did it shape? (`supersedes` chains, decision register (31); git history, outside the graph) +- **Readiness author at scale:** many waiting statements, ordered by what rests on what (statement queue (46), dependency cycles (26)) +- **Example-space analyst:** which outcome classes have no witness, which value combinations no example exercises (space coverage (44) answers per slot; combinations wait on the question in tier 3) +- **Architecture-rule author:** what a proposed rule would flag before it is adopted (architecture walk (42) as a rules file) +- **Migration lead:** progress of a structural migration by component; the seed drew this as "migration progress as a heatmap by component" (seed 05 §6) +- **Agent operator:** which context bundle, perspective and budget give an agent the right reading for a task +- **Multi-corpus portfolio lead:** the same questions across repositories; the seed listed cross-repo federation as future (seed 08 §8.6), and an exploratory commercial Studio would raise it again + +## Non-human readers + +- **Coding agents** read through the agent surface (`sdp q`, recipes, context bundles). Every human + reading should hand off to an agent with the same scope and agree with what the agent surface answers. +- **CI** runs the checks and also produces material for readings: this repository's CI writes run + evidence as CTRF records and builds, stamps and uploads the Studio preview for a pull request + (`spec:consumers.spec-studio.sharing#rule.previewWorkflow`). A pull request's forward section is + rendered by its author with recipe 55, not by CI; the Studio's roadmap page shows the same memo. +- **Review bots** could post graph-measured readings on a pull request. +- **Assistants** that select or compose readings are the AI option space in [05](05-specialised-and-ai-readings.md). +- **Apps** would integrate through the MCP surface: designed in, with its build deferred until a + concrete caller establishes its boundary and contract (the MCP-deferred decision, D6, + `spec:decisions.mcp-deferred`). Its shape is a fresh design. The seed's MCP server (seed 07 §13) served + agents, and that job went to the agent surface (the agent front door decision, MD-22). diff --git a/docs/design/02-seed-experience-map.md b/docs/design/02-seed-experience-map.md new file mode 100644 index 00000000..4e302487 --- /dev/null +++ b/docs/design/02-seed-experience-map.md @@ -0,0 +1,111 @@ +# 02 — The seed's experience, mapped to now + +The seed design ([`docs/lineage/v0-design/`](../lineage/v0-design/README.md)) was written before +any code. Its human experience was more ambitious than what the Studio delivers today, and several +of its mechanisms have since been ruled out. This map takes each experience idea, states what became +of it, and names the design opportunity that remains. + +**Reading rule.** The seed is evidence and direction, never law. Where it conflicts with a carrying +Spec, the Spec wins, and a retired mechanism stays retired. What survives a retirement is usually +the **job** the mechanism served; the opportunity column is about that job. The opportunities are a +research backlog for design cycles that run over many months, not decisions to settle now. + +**Citations.** Section references such as (07 §2.3) point into the seed's documents, not into this +folder. In the tables, a short address such as `shell#rule.stamp` stands for +`spec:consumers.spec-studio.shell#rule.stamp`; every other Spec is cited in full. + +**Outcome words.** Each row says what became of the seed idea: + +- **shipped**: the carrying Spec states `ready` and is `implemented` (the condition the roadmap's + `built` need checks for each Spec, `spec:consumers.roadmap#rule.entryNeed`), and the Studio shows it. +- **reshaped**: the job survives under a different mechanism, named with its carrying Spec. +- **retired**: ruled out, by the Spec or decision the row names. +- **deferred**: designed in and held, with the Spec or decision that holds it. +- **not carried**: no Spec carries it yet. + +Re-derive the Studio's side rather than trusting this page: + +```sh +pnpm --silent sdp:q 'return g.specs().filter((s) => s.id.startsWith("spec:consumers.spec-studio") && s.specKind !== "example").map((s) => [s.id, s.statedReadiness, s.deliveryFacts.join(" ")])' --json +pnpm --silent sdp:q 'return g.resolveEntryAddress("spec:consumers.spec-studio.sharing#rule.sourceLinks")' --json +``` + +## The loop + +The seed's closing line was *Generate → Explore → Refine → Export → Validate → Apply → Regenerate* +([07 §14](../lineage/v0-design/07-spec-studio-and-projections.md)). Today the loop is *derive → +read → compose scoped intent → hand off → agent edits source → git → checks → regenerate*. The +seed's patch loop, with its codemods and its trial apply against a copy of the graph, is +**retired**: `spec:consumers.intent-composition.proposal` records the refusal and +`spec:consumers.edit-model` holds the law. A view writes no source. It composes scoped intent, or a +change proposal, that an agent applies as an ordinary edit. + +**Opportunity.** The seed imagined the loop as one continuous experience. Today it crosses several +artifacts: the composing panel, the memo (recipe 49), the change proposal and its check (recipe 38), +the agent's edit, the pull request, the checks and a newly stamped preview. No reading follows a +change across them, and the basis can drop out on the way: a page opened through `file://` has no +stamp, so the person must supply the proposal's base or the intents leave as scoped-intent text +(`intent-panel#rule.proposalBase`). Designing that journey end to end is a first-class UX problem. +Desktop, web and CI surfaces could each add something there; those surfaces are exploratory (see +[04](04-reading-model-and-ia.md)). + +## Studio structure + +| Seed idea | What became of it | Design opportunity | +|---|---|---| +| Four lenses (Packs, Architecture, Tests, Evidence), with Capabilities and Search in the top navigation (07 §2.1–2.2) | **shipped** as the Packs, capabilities, architecture, tests and evidence lenses (`lenses#rule.order`), plus a search page (`spec:consumers.spec-studio.search`) | Lenses are graph views. Today the index is the Packs lens and the landing page, with task routes under `Start here` (`lenses.packs#rule.landing`, `navigation#rule.indexRoutes`). A role's own entry reading (provisional: "role home") could sit above the lenses and decide which one a role meets first; that revises the landing rules | +| Left rail with Pack tree, recent edits and a validation count (07 §2.1) | **reshaped**: a shell with navigation, rail and canvas (`spec:consumers.spec-studio.shell`); recent edits are **retired**, since the shell "shows no recent edits and no other history: git holds it" (`shell#rule.noRecentEdits`) | A recent-change rail would revise that rule and take its history as a named input. Today the diff page, over a supplied base graph, is the lawful place for change since a base | +| Spec page with ten collapsible sections A–J (07 §2.3) | **shipped**: the core's sections, then the Verification, Design view, Runtime, Evidence and Impact panels in a fixed order, each open by default (`spec-page#rule.panelOrder`) | A role may want a different first panel. Changing the order needs a Spec change; a role's entry reading can link deep into a panel instead, since each panel has an element id such as `panel.impact` | +| Readiness colour ramp over seven rungs (07 §2.3 A) | **reshaped**: the seven-rung ramp is retired. The stated rung is a badge carrying its word, coloured from a palette of four that stays distinct under colour blindness; the floor reached sits beside it in words with no colour; only the divergence banner adds a warning colour (`shell#rule.rungBadge`, `shell#rule.wordsBesideColor`) | Stated readiness, the derived floor and delivery facts are three independent coordinates and need three encodings; the badge already keeps the first two apart. One ramp would merge them into a progress score | +| The seed's readiness banner: "claimed `bound`, derived `framed` because runtime bindings missing" (06 §8) | **shipped**: every Spec page's header shows the stated rung beside the floor reached, raises the banner only when the floor stands below the stated rung, and shows the stated next rung with `nothing blocks` or each unmet clause and its targets (`spec-page.core#rule.header`; the banner law is `spec:consumers.derived-readiness-banner`) | The "because" is the valuable part, and both directions are already on the page; promotion preflight (recipe 9) is the agent's form of the upward answer. What is open is how a decider reads many next-rung answers together, beyond the owner queue page (recipe 46) | +| Maturity heatmap of readiness counts (00 §9), and the seed's picture of its `abstraction` axis, now altitude, against readiness (01 §5) | **shipped** as a maturity map on each Pack page, a grid of stated rung against floor reached (`spec:consumers.spec-studio.pack-page.maturity-map`) | Altitude against readiness, the seed's actual picture, is not drawn. It is a strong first reading for a technical product manager | +| Web components embeddable in pull-request bodies, status reports and slides (07 §3) | **reshaped**: `sdp-` custom elements enhance the markup the build wrote, the search results element aside (`page-elements#rule.enhanceOnly`) and work in any HTML page that holds that markup and loads the Studio's script (`components#rule.selfContained`); a Pack exports as one self-contained file with no script (`export#rule.selfContained`) | Hosts that run no script stay open. For a pull-request description the custom-elements decision (MD-42) already rules a static link to a Studio page, never an element; chat and documents are unexplored | +| Mobile: single column, pinch-zoom diagrams, staging that survives a refresh, and a summary mode that hides low-confidence inferred edges (07 §11) | **shipped**, except the summary mode: the same pages serve a desktop and a phone, with one column on a narrow screen and pinch zoom on diagrams (`spec:consumers.spec-studio.responsive`), and gathered intents survive a refresh (`intent-panel#rule.persist`). The summary mode is **retired**: a diagram never drops an edge for a low score, and a narrow screen scales the drawing rather than cutting it (the responsive Spec's narrative) | The nearest surviving idea is "fold, keep the words": an oversized diagram folds by context and layer at every width and keeps its text equivalent (`diagrams#rule.foldByContext`). Phone review as its own task design stays a candidate; readings that differ by width would revise the rule that the same pages serve both | +| Stamped previews per pull request at `/preview//` (07 §12) | **shipped**: `sdp stamp` writes `stamp.json` after the build, and the preview workflow stamps each pull request's merge commit (`spec:consumers.spec-studio.sharing`). Every page served over http or https shows, once its stamp loads, a stamp line with the corpus commit, engine and build time (`shell#rule.stamp`, `shell#ui.stampLine`); the stamp also sets the composing panel's proposal base (`intent-panel#design.baseSource`) and, through an optional source template, turns recorded files and lines into links (`sharing#rule.sourceLinks`) | The stamp is already a trust element on every served page; the open questions are its weight on a reading, and a basis for a page opened through `file://` and for a Pack export, which carry none (`shell#rule.stamp`, `export#rule.exportContent`) | + +## Reading a Spec + +| Seed idea | What became of it | Design opportunity | +|---|---|---| +| Open questions panel with `Mark resolved` and `Promote to ADR` (07 §2.3 B) | **reshaped**: questions carry `decider`, `links`, `provisional` and `trigger` (`spec:model.open-question-fields`). The questions page lists the Specs with a blocking question first, each Spec's questions in authored order (`registers#rule.questionsPage`), and the owner queue page lists the questions the owner decides (`owner-queue#rule.ownerQuestions`). Resolving a question and promoting it to a decision record are composing actions that become scoped intent (`intent-panel#ui.composingActions`) | A keyed question already has an entry address (`spec:#question.`) and an element id on its Spec page, which both pages link to (`spec-page.core#rule.entryIds`). A page of its own would be new and would need a carrying Spec; an unkeyed question has no address | +| Example cards with `View test`, `Run again`, `Edit example` (07 §2.3 C) | **reshaped**: examples are Specs with step contracts; running is CI's; run records supplied with `--runs` show beside the binding, labelled as external evidence (`spec:consumers.spec-studio.runs-page`); proposing or editing an example is a composing action | A card can state the bound point, the witness, the verifier binding and any supplied run, each with its own words | +| NFR sliders, "Adjust target", "last measured: 287 ms" (07 §2.3 D) | **reshaped**: constraints carry targets, and changing one is a composing action. **Deferred**: a slider waits for a design of its own (the decision that the Studio renders derived HTML, MD-41), and "last measured" waits on `observed` | Changing a target is a scoped intent. "Last measured" must not appear until a measurement exists | +| Embedded component diagram with source on hover (07 §2.3 E) | **shipped** as Studio diagrams with text equivalents, including scoped architecture and requirement traces (`spec:consumers.spec-studio.diagrams`) | Diagram-first readings for architects, with the text equivalent as the phone form | +| Runtime section: Fastify routes, Effect layers, Awilix registrations (07 §2.3 F, 05) | **reshaped**: the Runtime panel shows the structural neighbourhood of the Spec's implementation anchors (component, layer, context, and the units they use with file and line) and reads runtime observation as not tracked (`spec-page#rule.runtime`). The framework-specific content is **retired**; anchors carry a generic `role`, `layer` and `context` | Architecture by context, layer and role; the seed's "interface as the unit of reasoning" (05 §5) is a reading choice, not a model one | +| Bindings with "open in IDE" (07 §2.3 G; click-through to source, 06 §8) | **shipped** for the code host: bindings list each unit, test anchor, example or oracle with its file and line as text and a copy action (`spec-page.core#rule.bindings`). When a stamp names a source template, each recorded file and line links to the code host (`sharing#rule.sourceLinks`); this repository's preview workflow stamps a template at the merge commit (`sharing#design.workflowSource`). Editor links are refused: the page set "writes no editor URI" (`spec-page#rule.sourceText`) | Editor deep links, the seed's "open in IDE", would need a Spec of their own; a desktop surface over the working tree (exploratory) is where they would fit. Pages opened through `file://` and Pack exports show file and line as text only | +| Verification panel with harness coverage and `MISSING TEST` rows (07 §2.3 H) | **reshaped**: `has-verifier` says a verifier binding exists, never that it passed. For a Spec that owns an example space, the verification panel shows recipe 44's coverage grid, slot by slot, with `no example` for a value no example binds (`verification-panels#rule.coverageGrid`), and the tests lens counts keyed rules an enabled example exercises (recipe 34) | Coverage over combinations of slot values, the seed's matrix, is held by the blocking question `spec:consumers.agent-surface.combination-coverage#question.combinationCoverage` on a Spec stated at `idea`. A matrix reading must stay honest about what "covered" means | +| Evidence: SLSA, SBOM, OTel, deployments (07 §2.3 I, 08) | Runtime observation is **deferred** behind `observed` (`spec:observation.runtime-overlay`, stated at `idea`). Build attestations, deployments and bills of materials are **not carried**: the evidence lens reads each source as not tracked, because "no Spec designs a source for the other three" (`lenses.evidence#rule.notTracked`) | Honest empty states now; the evidence readings wait for `observed` and for a Spec that designs a source for supply-chain inputs | +| Impact panel, upstream and downstream; `impactOf` "one of the most-used queries" (07 §2.3 J, 03 §8) | **reshaped** and **shipped**: the Spec page's Impact panel draws the trace graph one hop each way and lists what the Spec rests on (recipe 21) and every Spec that rests on it, by distance (recipe 30) (`spec-page#rule.impact`); `sdp-impact-view` shows it on its own (`components#design.impactView`). File-level blast radius (recipe 4) and the planning slice (recipe 19) stay recipes | Impact is the most important verb for architects and engineers. No reading yet starts from a changeset or a file | + +## Working with the Studio + +| Seed idea | What became of it | Design opportunity | +|---|---|---| +| Patch panel, always visible: pending changes, Discard, Export, Open as PR (07 §2.4) | **reshaped** as the composing panel, on every page (`intent-panel#rule.everyPage`): gathered intents persist in the browser's local storage under the page set's own key (`intent-panel#rule.persist`); a `Preview memo` disclosure shows the text that `Copy memo` and `Save memo` hand off (`intent-panel#ui.memoPreview`); the panel requests nothing over the network (`intent-panel#rule.noRequest`) | Within one page set the panel already follows a person across pages and refreshes. Carrying gathered intent across page sets, devices, people and surfaces is the open part. A commercial surface could carry the memo onward; that is exploratory, and the Studio Spec names hosted review, shared comments and hosted previews only as possible later `@libar-ai/` work | +| "Propose via AI" emits a prompt rather than running AI; "the browser never has API keys" (07 §4) | **kept** as a posture: the memo is the hand-off and the agent does the work; the page opens no pull request, because a static page holds no credentials (`intent-panel#rule.handOff`) | Keep this as the boundary for every AI option in [05](05-specialised-and-ai-readings.md) | +| Harnesses: controls, expected result, coverage, "Propose scenarios" (04 §4, 07 §7) | **reshaped**: example spaces, space contracts and an implementation-side oracle; witnesses mark covered outcome classes; proposing examples for values no example binds is a composing action. **Deferred**: running a scenario harness waits for its own Spec (the decision that the Studio renders derived HTML, MD-41) | Stakeholders playing with inputs to confirm expectations was a real job. A static reading can show the space and its witnesses; evaluating the oracle live needs a surface that can run code | +| Architecture lens subpages: capability map, container and component maps, forbidden dependencies, a force-directed dependency graph (07 §8) | **shipped** in part: the capability map page (`spec:consumers.spec-studio.capability-map-page`), the architecture lens by context and layer, and the architecture walk as a rules file (recipe 42). The lens draws planned components apart from realized ones (`lenses.architecture#rule.plannedApart`) and draws no import the impact graph infers (`lenses.architecture#rule.membershipAndUses`); inferred imports reach a reader only through the curation report (recipe 40) | Inferred structure must stay visibly separate from curated intent; the seed's 03 §4.3 already said dotted, faded, never authoritative. Today the lens keeps it out entirely | +| Tests lens: coverage by capability, flaky tests, slow tests, orphans (07 §9) | **shipped** in part: one row per Spec that is not an example, with its verifier binding, enabled verifiers, rule coverage and example-space coverage (`lenses.tests#rule.coverageRows`); with run records supplied, labelled external pass and fail counts that are never a verdict on the Spec (`lenses.tests#rule.bindingsOnly`, recipe 45). Flaky and slow tests need a series of runs over time, which no input supplies | Run history over time is outside the graph; a CI surface (exploratory) could supply it as named evidence | +| Status report for leadership, generated, "nobody had to write it" (00 §9) | **not carried**. The closest readings are the roadmap page, recipe 53's board with recipe 55's memo for each roadmap (`roadmap-page#rule.roadmapPage`), and the owner queue page (`owner-queue#rule.queuePage`) | A leader reading that is honest by construction is a strong tier-1 candidate | +| `akg watch`: the same generated Studio served locally with live reload (02 §10) | **reshaped**: `sdp studio --watch` republishes after carrier changes; it serves no page and injects no script, so a reader reloads (`publisher.watch#rule.watch`) | The natural base for a desktop surface over the working tree (exploratory) | +| Stale open question after a time limit (06 §6.3.6) | **retired**: staleness never becomes graph structure or workflow authority (the planning-truths decision, MD-33); an open question carries no status or date (`spec:model.open-question-fields`), and the Spec page shows none (`spec-page.core#rule.questions`) | A neutral reading of question age, derived from git history supplied as a named input, stays a candidate. It must never become a flag or a gate, and it would revise the no-date and no-history rules (`spec-page.core#rule.questions`, `shell#rule.noRecentEdits`) | + +## Things the seed got right about adoption + +Seed 08 §9.10 is product advice, not mechanism, and it still holds: + +- Start with one bounded context. +- **Make the Studio the first visible win**; the checks come second. +- **Pair adoption with an existing pain** (a refactor, an audit, onboarding) so the cost is tied to a + visible benefit. + +Each of those pains is a reading: an impact reading for the refactor, a trace reading for the +audit, a tour for onboarding. They are good candidates for the first role-specific readings. + +## What the seed modelled that the graph does not + +Some seed concepts have no home in today's graph: the seed's optional `owner` on a Spec (its +open-question owner survives as `decider`), `tags`, decision statuses, run results and timestamps. +Design must not assume them. [03 — What the graph does not hold](03-reading-material.md#what-the-graph-does-not-hold) +keeps the one absence list and says what would supply each; new gaps go to the +[graph needs log](07-graph-needs.md). diff --git a/docs/design/03-reading-material.md b/docs/design/03-reading-material.md new file mode 100644 index 00000000..3d7d9985 --- /dev/null +++ b/docs/design/03-reading-material.md @@ -0,0 +1,214 @@ +# 03 — Reading material + +A reading can only show what the graph holds, what a recipe derives from it, or what a named input +beside the graph supplies. This is the material a designer works from. It was checked against the +graph with `sdp q` at commit `53804437`; re-run the queries rather than trusting this page as the +corpus changes. + +## What the graph holds + +The graph is flat: nodes, edges, a location table and a citation table. Every node and edge carries +exactly one `claim`. + +| Material | What it gives a reading | +|---|---| +| **Spec** (`Primitive` node) | id, title, narrative, `specKind` (8 kinds), `altitude` (`epic`, `feature`, `story`), stated `readiness` (`idea`, `scoped`, `defined`, `ready`), sections (a closed set: intent, behavior, constraints, model, design, decision, verification, ui), derived `deliveryFacts` | +| **Pack** | title, framing prose, members in authored order, optional `order: priority` (a roadmap), model references | +| **Code unit** (`CodeNode`) | file, line, label, and optional `role`, plus `layer` and `context` on a `component:` unit | +| **Test or oracle binding** (`Anchor`) | file and line of the binding | +| **Twelve edge types** | authored: `refines`, `dependsOn`, `constrainedBy`, `decidedBy`, `verifies`, `supersedes`; derived: `belongsTo`, `satisfies`, `references`, `models`, `memberOf`, `uses`. An authored edge may carry a one-line `reason` | +| **Location table** | the source line of every keyed Design and UI entry, every rule and flow, every Model term, every open question and its fields, and every relation target | +| **Citations** | inferred, located occurrences of entry addresses in source files that carry a recognized anchor | + +**Derived beside the graph.** The validation report (the `report` binding) is computed alongside +the graph, not held in it. It carries the Protocol's conformance and honesty findings. Corpus-rule +findings exist only in an operator's `sdp validate --rules` run, reported apart from Protocol +findings; the Studio takes no corpus configuration and shows Protocol findings only. + +**Addresses.** Spec and Pack ids (`spec:consumers.reader`, `pack:roadmap`) and entry addresses +(`spec:#question.`, `#rule.`, `#design.`, `#ui.`, `#term.`) make deep +links possible. Every Spec, Pack and keyed entry can be linked exactly: an id maps to its page, an +entry address to an element id on its Spec's page. Everything else links less precisely: + +- An unkeyed rule or flow links only to its section. The rule-key proposal (recipe 48) totals how + many are still unkeyed. +- A Design or UI entry's `description` has no address. +- A component links to its section of the architecture lens. +- A code unit or test anchor has no page. It shows as its file and line in text, which becomes a + code-host link only in a stamped page set served over http or https with a source template + (`spec:consumers.spec-studio.spec-page#rule.sourceText`). + +## How a reading is composed: a test drive of the reader + +Every reading starts from the reader, never from the carriers. `sdp q` evaluates a JavaScript body +over the derived graph with five bindings: `g` (the reader), `graph` (the raw graph), `report` (the +validation report), `params`, and `recipes(n, params)`. There is no verb per question. The reader +exposes nine entry points; everything else is composed in a few lines. + +| Entry point | Arrives holding | Returns, in brief | +|---|---|---| +| `g.specs()` | nothing | one row per Spec: id, title, `specKind` and its familiar `kindDisplayLabel`, altitude, stated and derived readiness, delivery facts, file, Packs | +| `g.packs()` | nothing | the Packs: id, title, framing, file, model references | +| `g.findings()` | nothing | validation findings: validator, family, severity, message, subject, file | +| `g.findByConcept(word)` | a word | matching nodes, each naming the fields it matched in (title, narrative, a section), never a fuzzy score | +| `g.byFile(path)` | a file | every node recorded at the path and the Specs reachable from it | +| `g.blastRadius(files)` | a changeset | impacted Specs and Packs with the binding and claim behind each reason, at-risk neighbours, `unlinked` units, and `coverageUnknown` files the graph records nothing at | +| `g.resolveEntryAddress(address)` | an address | whether `spec:#
.` resolves, and which entry | +| `g.specContext(id)` | a Spec id | the whole Spec in context: sections, design columns, floor and next-rung failures, relations in and out with claim and reason, implementations and references with file, line, role, layer and context, verifiers, entry locations, citations, findings | +| `g.packContext(id)` | a Pack id | framing, every member with its next-rung failures, design columns, bindings, verifiers and examples; the boundary (what the Pack rests on and what rests on it); verifier gaps; findings | + +**Named coordinates are already there.** `kindDisplayLabel` turns each kind into a familiar delivery +noun: *Use Case / Behavior*, *Business Rule*, *Decision Record*, *Contract*, *Domain Model*, +*Workflow*, *Constraint (NFR)*, *Example / Scenario*. A reading for a delivery role can speak those +nouns without teaching the schema. (Here "role" means the delivery role a person plays, a +provisional design sense; the ratified `role` is the architectural pattern on a code anchor.) + +**Role readings are short scripts.** A technical product manager's "where does intent stand?" per +Pack (members by named coordinate and stated rung, blocking questions with deciders, realization, +boundary size, then the roadmap's needs) took about twenty lines: three reader calls and two shipped +recipes (20 and 53). An architect's "which decisions shape the most Specs, and do their relations +say why?" took ten. Neither needed a new verb. A role home is a composition of this kind, published +as a projection. + +**What the test drive taught the design:** + +- **Pack sizes range from a handful of members to the whole corpus.** `pack:self-hosting-v1` holds + every Spec. A landing that expands every Pack cannot scale; Packs need a summary-first reading. +- **Naive ratios mislead.** In `pack:adopter-speed-v1`, far fewer members are `implemented` than + have a verifier, because most of its members are examples, and examples are verified, never + implemented (the example realization posture, MD-24). A leader reading must apply the per-kind + postures, never show "implemented out of total". +- **Most blocking questions are deferrals, not holds.** Most carry a `trigger`: they wait for an + event, not a decision today. A decider's home must separate *decide now* (holds) from *waiting for + its trigger* (deferrals), or it reads as a backlog of overdue work. +- **Reasons are sparse.** Most `decidedBy` relations carry no `reason`, the most-cited decisions' + included. A "why" reading must show a missing reason as missing, not as a blank. +- **The adapters name their own blind spots.** A changeset over files the graph records nothing at + returns them in `coverageUnknown`; an address with an unknown key returns `resolves: false`. Human + readings should keep that habit: an honest "the graph cannot see this" instead of an empty panel. +- **The self-hosted corpus holds barely any Constraint (NFR) Specs.** NFR-centred readings need the + worked example or an adopter corpus to be tested. + +Re-run these rather than trusting the words above (each body goes to `pnpm --silent sdp:q ''`): + +| Lesson | Query | +|---|---| +| Pack sizes | `return graph.nodes.filter((n) => n.nodeType === "Pack").map((p) => [p.id, p.members.length])` | +| Naive ratios | `const m = g.specs().filter((s) => s.packs.includes("pack:adopter-speed-v1")); return { members: m.length, implemented: m.filter((s) => s.deliveryFacts.includes("implemented")).length, hasVerifier: m.filter((s) => s.deliveryFacts.includes("has-verifier")).length }` | +| Deferrals and holds | `return (await recipes(20)).totals` | +| Sparse reasons | `const d = graph.edges.filter((e) => e.type === "decidedBy"); return { relations: d.length, withReason: d.filter((e) => e.reason).length }` | +| Constraint Specs | `return g.specs().filter((s) => s.specKind === "constraint").map((s) => s.id)` | + +## What the recipes already answer + +The recipe catalog ([`docs/agent-surface/recipes.md`](../agent-surface/recipes.md)) is the best +evidence the project has of the questions people and agents need answered: each recipe is a +question someone needed answered often enough to write down and test. It does not measure how often +a question is asked, and some recipes exist to feed a projection or a check rather than a recurring +question. Grouped by the job each serves: + +| Job family | Recipes | Studio page today | +|---|---|---| +| **Where does intent stand?** | capability map (52), lower ladder (11), readiness divergence (7) | capabilities lens (52); the index summary and the Pack page's maturity map place Specs by stated rung and floor; no page runs 7 or 11 | +| **What comes next?** | roadmap (53), roadmap memo (55), build backlog (1), design backlog (33) | roadmap page (53, 55); backlog page (the design backlog, 33); no page runs the build backlog (1) | +| **What must a person decide?** | statement queue (46), open-question register (20), promotion preflight (9) | owner queue (46), questions page (20); Pack member cards show each stated next rung and its unmet clauses; no page runs 9 | +| **Review one Pack** | Pack review backbone (5), Pack design (29), design slice (54), perspective filter (37), references into a design (27) | Pack page (29), slice page (54); no page runs 5, 27 or 37, and the Studio takes no perspective | +| **What changed?** | design diff (35, needs a base graph) | diff page, plus a row on each Pack and Spec page (only when built with `--base`) | +| **What does this touch?** | changed-file impact (4), design-change impact (30), planning slice (19), dependency footing (21), dependency cycles (26) | Spec page Impact panel (21, 30); the owner queue names any dependency cycle the statement queue finds; no page runs 4, 19 or 26 | +| **What does this guarantee and who checks it?** | Spec guarantees (3), declared versus enabled verifiers (10), rule coverage (34), example-space coverage (44), run evidence (45) | Spec page and tests lens (34, 44, and 45 given run records), runs page (45); no page runs 3 or 10 | +| **Architecture** | architecture map (17), crossings (32), architecture walk (42), planned against realized (43), component membership and reach (12, 13, 14), roles, layers and contexts (28) | architecture lens (17, 43); no page runs 12, 13, 14, 28, 32 or 42 | +| **Decisions** | decision map (18), decision register (31) | decisions page (31); no page runs 18 | +| **Find something** | concept search (6), entry search (23), address resolution (25), entry citations (51) | search page (6's matcher and 23's entry walk); entry citations (51) on Spec pages and the declarations page; no page runs 25 | +| **Keep the corpus healthy** | orphans and gaps (8), drift alarm (2), mention audit (22), curation report (40), slimming candidates (39), key-family register (41), pinned declarations (24), external registers (50), census structural coverage (15), projection coverage upper bound (16) | declarations page (24); the index's findings section (Protocol findings only); no page runs the others | +| **Change and hand off** | context bundle (36), proposal check (38), proposal memo (49) | the composing panel writes recipe 49's memo byte for byte; no page runs 36 or 38 | +| **Upgrade a corpus** | capability adoption (47), rule-key proposal (48) | none | + +"No page runs N" means the Studio's build does not evaluate that recipe +(`spec:consumers.spec-studio.data.recipe-answers#design.recipeEvaluations`); a page may still show +related reader values. The column covers the Studio only. Other human readings stand beside it: the +Design Review, census, Mermaid and Gherkin projections, held by the shipped-projections decision +(MD-32); the Obsidian vault (`spec:consumers.obsidian-vault`); and the memos agents render into a +pull request (recipes 49 and 55). [10](10-studio-baseline.md) reads the Studio as it stands. + +Three gaps stand out: + +- **Impact from a changeset.** Every Spec page's Impact panel already shows what a Spec rests on and + what rests on it (recipes 21 and 30), so the per-Spec walk the seed called one of the Studio's + most-used queries ([seed 03 §8](../lineage/v0-design/03-graph-metamodel.md)) is built. No reading + starts from a file or a changeset (recipe 4) or covers a planning slice across Specs (recipe 19), + and the Studio takes no changeset input. +- **The build backlog.** The backlog page shows the design backlog only; recipe 1 has no page. +- **Corpus upgrade.** The upgrade kit (recipes 47 and 48) has no human reading. This is a different + sense of adoption from the seed's advice that the Studio be a team's first visible win + ([seed 08 §9.10](../lineage/v0-design/08-delivery-evidence-and-tooling.md)). + +## Named inputs beside the graph + +Beside the graph the Studio reads at most two optional inputs, each named on the command line +(`spec:consumers.spec-studio#rule.namedInputs`). Each is named in words on every page that shows +it, never becomes graph data, a delivery fact or a verdict, and never answers in the graph's name. + +| Input | Supplied as | Gives | How a page names it | +|---|---|---|---| +| **Base graph** | `sdp studio --base PATH`, optionally `--base-label TEXT`: a graph `sdp build` wrote at an earlier commit | the design diff (recipe 35): what changed in the design since that graph | by its label, schema version and Spec count; a commit shows only when the label names one, as the preview workflow's `base ` label does | +| **Run records** | `sdp studio --runs PATH`, repeatable (CTRF) | supplied test results beside verifier bindings, joined at test-file grain (recipe 45) | by tool, build, branch, recorded commit (or `not recorded`) and times | + +Two things sit near the inputs but are not inputs: + +- **The stamp** is publishing metadata. `sdp stamp` writes it beside the page set after the build, + and the next build removes it. It names the schema version, the corpus commit (or `unknown`), the + engine, the UTC publishing time and, optionally, a source template that turns each recorded + `file:line` into a code-host link. The shell shows it only when the page set is served over http + or https, never through `file://` (`spec:consumers.spec-studio.sharing`, + `spec:consumers.spec-studio.shell#rule.stamp`). +- **An outside register** is not built. It is a `scoped` capture on the roadmap + (`spec:consumers.spec-studio.register-input`) with blocking questions of its own, and admitting it + means amending the two-input rule. Agents can already check prose tokens against a register with + external registers (recipe 50). + +Agents reach more named inputs than the Studio: a recipe whose contract admits it may take a base +graph, imports, a perspective, a proposal or run records through `--params`. + +## What the graph does not hold + +This is the one list of what the graph does not hold; what would supply each gap is logged in +[07](07-graph-needs.md#log). It also takes in what the seed modelled and the graph does not hold, +marked *the seed had*. A prototype must not invent any of it, but a gap is not a dead end: design +work is one of the ways the graph's gaps are found, and an engineering session extends the graph, +on the owner's word, to serve the readings it needs. Each row names its row in 07, or says the gap +is ruled out; new findings go to the same log. The graph may also lack material it is *meant* to +hold: an architecturally significant unit with no anchor, or a relation nobody declared. Those are +curation gaps, found by the curation report (recipe 40) as well as by design work. + +| Absent | Consequence for design | Logged in 07 | +|---|---|---| +| **People, ownership and approval** | No owner or tags on a Spec (*the seed had* both): the envelope is closed, so an `owner:` or `tags:` key is refused, and a Gherkin tag is decoration that authors no graph state. The only person-shaped value is an open question's `decider`, a corpus token that references and authorizes nothing. No "my Specs" or "my team" reading; a decider's queue filters questions only. That a review occurred, or who approved, is never a graph fact | [*Who is responsible for a Spec, Pack or context*](07-graph-needs.md#log) and [*Who reviewed, approved or stated `ready`*](07-graph-needs.md#log) | +| **Time and history** | No timestamps (*the seed had* `createdAt` and `lastRunAt`), ages, trends, velocity or "recently changed"; the shell shows no recent edits, by rule. The reach past one commit today is the two-point design diff and the commits run records carry | [*History*](07-graph-needs.md#log); [08](08-what-the-repo-settles.md#3-history-beyond-one-commit) says how a history reading may ship | +| **Runtime observation and delivery events** | No "is it live?", no measured NFRs, and no build, deployment, attestation or bill-of-materials nodes (*the seed had* them). The evidence lens names these sources and reads each as not tracked | [*Runtime observation*](07-graph-needs.md#log) and [*Build attestations, deployments and software bills of materials*](07-graph-needs.md#log) | +| **Test verdicts as facts** | No pass rate or pass and fail inside the graph (*the seed had* test runs in it); `has-verifier` says a binding exists, not that a test passed. Run evidence appears only as a labelled input | [*Run results across many pipeline runs*](07-graph-needs.md#log); the verdict itself stays CI's, by design | +| **Decision status** | No `proposed`, `accepted` or `superseded` status (*the seed had* one). A decision is a Spec with stated readiness, and replacement is a `supersedes` relation. A decision reading shows those, never an adoption status | Ruled out: `status` on a decision is rejected under the typing law (MD-11) | +| **A longer readiness ladder** | Four stated rungs only (*the seed had* seven, including `executable` and `verified`). Verification is a delivery fact, never a rung. Stated readiness, the derived floor and delivery facts are three separate coordinates and must not merge into one progress ramp | Ruled out | +| **Effort, estimates, dates, sprints** | None | Ruled out: the roadmap is never a schedule, a date or a gate (a roadmap states advisory priority, MD-46), and lifecycle gating is rejected; phase, iteration and milestone survive only as descriptive nouns | +| **Visual design artifacts** | Keyed UI entries only; no thumbnails or design-tool frames | [*Links from UI entries to visual design artifacts*](07-graph-needs.md#log) | +| **Discussion and comments** | None | Not a graph need: discussion lives in the pull request. A commercial Studio, under consideration and exploratory, could hold review threads as product state, never as delivery truth | + +## Derivable but not yet derived + +Candidates that need no model change but that the graph alone cannot give. All but the last read +graphs from several commits, so each needs the named history input logged in +[07](07-graph-needs.md#log), and in the Studio the history diagrams that +`spec:consumers.spec-studio.diagram-kinds` refuses until "a ruled history input and a history +reader" exists. Each is a candidate, not a commitment, and each would need a +carrying Spec: + +- **Discipline activity over time:** per discipline filter, how many Specs, entries or bindings + changed per commit range, in the shape of RUP's hump chart (see [11](11-rup-roles-and-artifacts.md)). +- **Question age:** when an open question first appeared. Defined only for keyed questions: unkeyed + entries have no identity across two graphs. +- **Decision lineage:** a `supersedes` chain with the commit each step landed in. A chain exists in + one graph only while both records do, so a deleted predecessor needs an older graph. +- **Readiness trajectory:** a Spec's stated rung across commits. It breaks at an id rename, since + ids carry no history (`spec:model.stable-ids`). +- **Change narrative for a pull request:** the design diff plus blast radius plus statement-queue + movement, in one reading. It needs a base graph and the changed files, which an agent can pass to + `sdp q` today; the Studio takes no changeset. diff --git a/docs/design/04-reading-model-and-ia.md b/docs/design/04-reading-model-and-ia.md new file mode 100644 index 00000000..c4577876 --- /dev/null +++ b/docs/design/04-reading-model-and-ia.md @@ -0,0 +1,249 @@ +# 04 — Reading model and information architecture + +A proposal for how readings are composed, how they fit together, how people arrive and move, and +which surfaces carry them. UX level only: no layout, no styles. Terms marked provisional in the +[README](README.md) are flagged for the owner, not ratified. This document also coins **task flow**, +**claim cue**, **absence word**, **agent hand-off** and **jump**; treat them as provisional too. +"Reading" means what the README says it means; the anatomy below is a proposed way to compose one, +not a second definition. + +## 1. Anatomy of a reading + +Every reading, from a phone-sized question page to a full architecture map, is built from the same +six parts. Naming them lets us design new readings by choosing values, rather than drawing pages +from scratch. + +| Part | Question it answers | Values | +|---|---|---| +| **Subject** | What is this about? | the corpus · a Pack · a Spec · an entry · a component or code unit · a file or changeset · a decision · a question · a change against a base | +| **Selection** | Which part of the subject? | a discipline (by kind or section) · a perspective (recipe 37; on the agent surface only today) · a Pack · a context or layer · everything | +| **Time** | As of when? | now (the graph derived from the working tree) · against a base (the design diff: a base graph the caller supplies) · over history (a series of graphs the caller supplies at named commits; not built) | +| **Arrangement** | In what form? | answer sentence · list · register · queue · matrix · map · diagram with text equivalent · card · narrative memo | +| **Basis** | Why should I trust it? | corpus commit and engine (from the stamp, when one loads) · supplied inputs as named (a base graph by its label, a run by its commit) · what was left out | +| **Hand-off** | What can I do next? | open the source · compose scoped intent · hand the same scope to an agent · share the reading | + +The design treats basis and hand-off as never optional: a reading without a basis cannot be +trusted, and a reading without a hand-off leaves the reader stuck. That is a hypothesis to test, not +current law. Today a page opened through `file://`, a page set never passed through `sdp stamp`, +and every Pack export show no stamp, and an export carries no composing panel +(`spec:consumers.spec-studio.shell#rule.stamp`, `spec:consumers.spec-studio.export#rule.exportContent`). +A basis that is always present needs an honest "not stamped" state, or a change to those rules. + +**Example.** "What blocks the checkout capability?" is subject *a Pack*, selection *blocking +questions and floor clauses*, time *now*, arrangement *queue ordered by what rests on what*, basis +*the stamp when the page set was published, or a stated absence*, hand-off *compose an intent per +question, or give the scope to an agent*. + +## 2. How people arrive + +The agent surface was designed from a **demand map**: agents arrive holding a string, a file or a +changeset, never the Spec id they need. The repository itself is navigated that way: the graph is +the starting point, never a text search over carriers. People have a demand map too, and the Studio +should be designed from it, so that a person enters the graph the way an agent does (see the reader +test drive in [03](03-reading-material.md#how-a-reading-is-composed-a-test-drive-of-the-reader)): + +| A person arrives holding | Typical situation | Where they should land | +|---|---|---| +| **A link** | a pull-request preview, a shared Pack export, a link in chat | the exact object or reading linked, with its basis visible and a way up to its context | +| **A question** | "what's blocking us?", "is this ready?", "what changed?" | the role home or task flow that answers it | +| **A word** | a term, a feature name, a half-remembered title | search over ids, titles, prose, entry keys and terms (concept and entry search) | +| **A file or changeset** | an engineer mid-change, a pull request | the impact reading: what this touches, what is at risk, what the graph cannot see (`coverage-unknown`) | +| **A role** | "I'm the architect; where do I start?" | the role home | +| **An address** | a Spec id or entry address pasted from a review or an agent answer | the object page, scrolled to the entry | + +Today's Studio serves *a word* through search, and *a link* or *an address* when the link was built +for it: every Spec and Pack has a page, and every keyed entry has an element id. It partly serves +*a question*: the index's `Start here` routes include "See what comes next" and "See what the owner +can state first" (`spec:consumers.spec-studio.navigation#rule.indexRoutes`). It partly serves *a +file*: search matches a node's recorded file path. It has no landing for *a role* or *a changeset*, +and a pasted address finds only the Specs whose text quotes it, because search indexes nothing +beyond its listed fields (`spec:consumers.spec-studio.search#rule.addedFields`). The index opens +with a counted summary, then the task routes, every Pack as a closed disclosure of its members, +every Spec as a filterable row, and the findings. + +## 3. Information architecture + +Four layers, plus elements present everywhere. + +```text + Role homes what a role opens first; composed, never a separate store + │ + Task flows guided paths across readings for one job + │ + Registers & maps collections: roadmap, queue, questions, decisions, declarations, + │ backlog, capability map, architecture, tests, evidence, glossary, + │ findings, diff, runs + │ + Object pages one canonical place per addressable thing +``` + +### 3.1 Object pages + +One canonical place per thing with an address, shared by every role. Role homes and task flows +link **into** these places; they never copy them. + +| Object | Address | Holds | Today | +|---|---|---|---| +| Spec | `spec:` | the whole Spec in context: stated rung beside floor, delivery facts, relations with claims and reasons, bindings, questions, examples | a page per Spec | +| Entry | `spec:#
.`, where the address section is `design`, `ui`, `rule`, `question` or `term`, not a Spec section name | one keyed rule or flow, question, design entry, UI entry or term, with its source line and citations | an element on its Spec page, with its key, recorded line and a copy action; an unkeyed entry has no address and is reached through its section | +| Pack | `pack:` | framing, members, Pack design, boundary, maturity map | two pages by design, the Pack page and the slice page, because "the two readings answer different questions in different orders" (`spec:consumers.spec-studio.slice-page`); plus one export file | +| Component / code unit | `component:`, `impl:`, `api:` | role, layer, context, members, uses, the Specs it satisfies or references | a component has a detail section on the architecture lens; a code unit has no page, by a ready rule (`spec:consumers.spec-studio.spec-page#rule.sourceText`); test and oracle anchors (`test:`, `oracle:`) have ids but no page either | +| Decision | a `decision`-kind Spec | what it decided, what it shaped, what superseded it | its own Spec page, which shows its relations both ways; a row on the decisions register | +| Question | `spec:#question.`, keyed questions only | the question, decider, provisional reading, trigger, links, what it holds | an element on its Spec page; rows on the questions register and the owner queue; an item on the slice page | +| Change | base graph (as labelled) → current graph | what changed in the design at entry grain | the diff page, when the build is given a base graph | + +Most of this layer already exists. A decision is a Spec, so every decision already has its own page, +and that page already shows what the decision shaped and what supersedes it. What a decision object +page might add beyond that, such as the decision map's reach (recipe 18), is a design question. +Questions are the real gap: none has a page of its own. Making questions object pages is the largest +single IA change proposed here. It needs a carrying Spec and a path scheme, and it reaches only +keyed questions, since an unkeyed question is lawful and has no address +(`spec:model.open-question-keys#rule.keyGrammar`). A question is the unit a decider works on, and a +decision is the unit an auditor traces. A code-unit page, or one page per Pack, would revise ready +rules, so either is a Spec change and not only an IA choice. + +Role homes and task flows can link into these places today. The URL scheme is deterministic: a +Spec at `specs/.html`, a keyed entry at `specs/.html#
.`, a Pack at +`packs/.html` and `slices/.html`, a component at `architecture.html#`. + +### 3.2 Registers and maps + +Collections that answer "show me all of X". They exist today in several forms: the register pages +(questions, decisions, declarations and the design backlog, +`spec:consumers.spec-studio.registers#rule.registerPages`); the lenses (capabilities, architecture, +tests and evidence, with the index as the Packs lens); pages of their own (roadmap, owner queue, +glossary, and diff and runs when their inputs are given); and the findings section of the index. +Most are top-navigation entries. They stay, but they move below the role homes, so a reader reaches +them through a question rather than a long, flat menu. The current entries and their order are ready +law (`spec:consumers.spec-studio.navigation#rule.topEntries`, `spec:consumers.spec-studio.lenses#rule.order`), +so regrouping them is a Spec change, not a styling choice. + +### 3.3 Task flows + +Guided paths for one job, crossing object pages and registers. The first six, chosen because each +is either a tier-1 job or one of the existing pains the seed pairs adoption with (refactor, audit, +onboarding; [seed 08 §9.10](../lineage/v0-design/08-delivery-evidence-and-tooling.md)): + +| Flow | Who | Path | +|---|---|---| +| **Review a Pack for readiness** | decider, technical product manager | Pack → what stands before each member's stated next rung → blocking questions → compose intents → hand off | +| **Review a pull request's design change** | reviewer, architect | stamped preview → what changed (diff) → what it touches (impact) → readiness movement → intents | +| **Trace a requirement to its verification** | tester, auditor | Spec → examples and space coverage → verifier bindings → supplied runs, each in its own words | +| **Assess impact before a change** | engineer, architect | file, changeset or Spec → blast radius, at-risk, `coverage-unknown` → hand the scope to an agent | +| **Work the decider's queue** | decider | queue → question object → provisional reading and what it holds → answer as scoped intent | +| **Onboard to a bounded context** | newcomer | capability map → design slice → key Specs → their code → open questions | + +The index's `Start here` routes are already phrased as jobs; they are the seed of this layer. + +### 3.4 Role homes (tier 1) + +A role home is an ordered composition of existing readings, opened first by one role. It answers +that role's first question in one sentence, then shows the evidence. It holds no state. + +Tier 1, the traditional delivery roles in [01](01-roles-and-perspectives.md), is the first cycles' +focus, not the limit. The specialised and AI-powered readings in +[05](05-specialised-and-ai-readings.md) compose from the same parts. Each row is a candidate to test, +paired with a job story where one fits; the job stories name no persona, so the persona stays design +material. A role home the Protocol ships would select by named recipes and disciplines. One built +from the corpus's own perspectives would need the Studio to take a perspective as a named input, +which it does not today (`spec:consumers.spec-studio#rule.namedInputs`). + +| Role home | First question | Composed from, in order | +|---|---|---| +| **Technical product manager** | "Where does intent stand, and what blocks it?" | capabilities by altitude against readiness → roadmap needs → blocking questions by capability → what changed since the base | +| **Decider** | "What can only I settle, and in what order?" | my open questions, blocking first, with the Specs each holds → roadmap entries whose need is a statement → the corpus's waiting statements | +| **Architect** | "What is planned, what is built, and what crosses a boundary?" | planned against realized → crossings and architecture-walk findings → decisions and what they shaped → impact of open work | +| **Engineer** | "What can I build, and what does my change touch?" | build backlog → impact of my changeset → Spec guarantees for the work at hand → hand-off to an agent | +| **Tester** | "What is unverified, and what is uncovered?" | Specs with no verifier binding → keyed rules no enabled example exercises → example-space values no example binds → supplied runs | +| **Leader** | "Where do we stand, honestly?" | readiness and realization side by side per capability → roadmap needs → open decisions → what the reading cannot see | + +Each first question ends where the honest answer ends. The leader home in particular must say what +it does not know (no runtime observation, no verdicts) rather than fill the space. The decider home +also has a limit today: the statement queue selects open questions by decider, but its waiting +statements are corpus-wide, because no graph value says whose statement a Spec awaits. The Studio's +queue page lists only the questions whose decider is `owner` +(`spec:consumers.spec-studio.owner-queue#rule.ownerQuestions`); another decider reaches theirs +through recipes 46 and 53 with `params.decider`. + +### 3.5 Elements present everywhere + +| Element | What it does | Where it comes from | +|---|---|---| +| **Basis line** (provisional; [README](README.md#words-used-here)) | states the corpus commit, engine and supplied inputs of the reading in view, and says so plainly when no stamp loads | the stamp, when published and served over http(s); inputs as `spec:consumers.spec-studio.data.inputs#rule.inputNaming` names them. The build writes no commit (`spec:consumers.spec-studio.sharing#rule.buildWritesNoStamp`), so an always-present line needs a "not stamped" state or a Spec change | +| **Claim cues** | distinguish declared intent, anchored bindings and inferred structure wherever a relation appears | the claim taxonomy | +| **Readiness and realization, apart** | stated rung and floor reached (readiness) beside delivery facts (realization), never merged | the readiness floor; delivery facts; the rung badge (`spec:consumers.spec-studio.shell#rule.rungBadge`) | +| **Absence words** | name each kind of absence in the words the Studio already uses: `none` for a verifier binding, `no example` and `uncovered` for example-space values, an `unbound` slot, `not enumerable`, `not measurable`, `not tracked`, `floor not evaluated`, and `coverage-unknown` for impact | the Studio's display Specs: `spec:consumers.spec-studio.shell#rule.rungBadge`, `spec:consumers.spec-studio.verification-panels#rule.coverageGrid`, `spec:consumers.spec-studio.lenses.tests#rule.coverageRows`, `spec:consumers.spec-studio.lenses.evidence#rule.notTracked`; the glossary's coverage-unknown | +| **Composing panel** | gathers scoped intents from any reading, previews the exact memo, hands it off | `spec:consumers.spec-studio.intent-panel`: already on every page, with gathered intents kept per browser and per page set | +| **Agent hand-off** | gives the same scope to an agent: the Pack or member ids on screen, as the context bundle's parameters | recipe 36; the page embeds no bundle (`spec:consumers.spec-studio.data`) | +| **Jump** | search by word or file from anywhere | search; landing on a pasted address needs new intent, since search does not resolve addresses | + +## 4. Progressive disclosure: answer, evidence, source + +Every reading layers its content the same way: + +1. **Answer:** one sentence or one number that answers the reading's question, in plain words. +2. **Evidence:** the rows, cells or boxes that justify it, each with its claim and its absences named. +3. **Source:** the carrier line, the code location, the recipe that computed it, the commit. + +A reader can stop at any layer. A phone reading usually stops at the first, a reviewer at the +second, an auditor goes to the third. Nothing in a lower layer may contradict the layer above it. +Today the source layer links out only in a stamped page set served over http(s), through the +stamp's source template; elsewhere a file and line stay text with a copy action +(`spec:consumers.spec-studio.spec-page#rule.sourceText`). + +## 5. Surfaces + +**Define a reading once; render it per surface.** The Protocol already projects the same graph into +more than one medium: the five projection roots (Design Review, census, Mermaid, Gherkin and the +Studio's HTML pages) and the Obsidian vault's notes and Bases. A role home is therefore a reading, +not a page: the same composition could be a Studio page, a vault note with a Base, or a section of a +pull-request description. The four frozen projections are the exception; the shipped-projections +decision (MD-32) keeps them as they are unless a refining decision says otherwise. The anatomy in +section 1 is the medium-independent definition; each surface renders it under its own constraints. + +The same readings, carried by different surfaces. The core stays open source and free. A commercial +Studio is under consideration as a web app, a desktop app and a CI/CD surface; the commercial rows +below are design exploration, not a decision. The one repository record about later commercial +hosting is in the Studio's carrying Spec, `spec:consumers.spec-studio`: "hosted review, shared +comments and hosted previews may later ship under `@libar-ai/`". No Spec, open question or roadmap +entry scopes a desktop app, a commercial web app or a commercial CI surface. + +| Surface | What it uniquely enables | Constraint to respect | +|---|---|---| +| **Static Studio** (open source) | a deterministic page set anyone can open from a link or a file, stamped when published; Pack export | no server; no graph value computed in the page (`spec:consumers.spec-studio#rule.noSecondGraph`); one same-origin request, for the stamp, and only over http(s); the only stored state is the composing panel's gathered intents, per browser and per page set | +| **Agent surface** (open source) | the same questions scripted by an agent | read-only; the schema is the contract | +| **Vault** (open source) | generated notes beside a person's own notes | the generated folder is owned by the Protocol | +| **Pull-request surface** (open source) | a reading where review already happens: the reusable preview workflow's per-pull-request Studio with its base graph and runs (`spec:consumers.spec-studio.sharing#rule.previewWorkflow`), the forward section (recipe 55), design diff, impact | names what it read: checks, previews and their stamp name the pull request's merge commit, and a base graph is named by its label (`base ` in the workflow) | +| **Desktop app** (commercial, exploratory) | live reload without a manual refresh, an in-app view of the working tree, deep links into the editor. The open-source `sdp studio --watch` already rebuilds from the working tree on carrier changes, and the reader reloads (`spec:consumers.spec-studio.publisher.watch#rule.watch`); the seed's `akg watch` promised the live reload | a reading of uncommitted work must say so, and no reading can today: pages carry no commit by law, so an "uncommitted" basis needs a new Spec. Editor links would revise `spec:consumers.spec-studio.spec-page#rule.sourceText`, which writes no editor URI. Nothing it shows is delivery truth until committed | +| **Web app** (commercial, exploratory) | teams, many corpora, shared review threads, saved readings and filters, intents shared across devices, people and page sets | view state may persist; delivery truth may not. Review threads and preferences are product state, never graph facts, and a proposal carries no status or approval. A perspective is corpus data the repository owns (`spec:consumers.review-perspectives`), so whether a web app may save one elsewhere needs a ruling. Running people's `sdp q` bodies on a server has no sandbox | +| **CI/CD surface** (commercial, exploratory) | extends the open-source preview workflow: readings attached to every pipeline run; run history over time as several named inputs | the Protocol's checks police conformance and honesty only. An adopter may gate on its own corpus rules (`sdp validate --rules`), reported apart and moving no floor (`spec:validation.corpus-rules#rule.neverMovesFloor`); the Protocol imposes no quality gate on design. Run records read at test-file grain, never as fresh, stale or a verdict; when a run goes stale is an open owner question (`spec:observation.run-evidence.bound-file-freshness#question.freshness`) | + +The question running through all three commercial surfaces is where product state is allowed to +live, a research question for the long horizon rather than one to settle now. Current law says only +what such state may never become: graph data, a delivery fact, a rung, a status or approval on a +proposal, or a recorded review. The proposed answer: preferences, saved readings, review threads and +intent drafts are product state; anything about the delivery itself stays in the repository and the +graph. Two precedents exist for state a person writes beside a projection: the composing panel's +gathered intents in browser storage (`spec:consumers.spec-studio.intent-panel#rule.persist`), and +the vault, which keeps a Base a person changed and never writes the `intent/` notes outside its +folder (the vault owns one folder, MD-45). + +## 6. From today's Studio to this IA + +| Today | In this IA | +|---|---| +| index: a counted summary, `Start here` task routes, every Pack as a closed disclosure of its members, every Spec as a filterable row, and the findings | a landing that asks *who are you / what do you hold*, with role homes and the arrival table above | +| a long, flat top navigation: the lenses, then each register and page, with Diff and Runs only when their inputs are given | registers and maps, reached from role homes and task flows; a compact menu remains for experts | +| Spec page with its sections and panels, each already linkable by element id | Spec object page, unchanged in law; role homes link into its existing panel and entry ids | +| decisions on their own Spec pages; questions as register and queue rows and as elements on Spec and slice pages | question object pages; a decision page that shows more than its Spec page only if a cycle finds the need | +| composing panel on every page, keeping gathered intents per browser and page set | the same composing panel, given more weight in every reading; sharing intents across devices and people only on a commercial surface (exploratory) | +| stamp line: corpus commit, engine (whose version names its own build commit) and build time, shown only when a stamp loads | basis line, in plain words, with an honest state when no stamp loads | +| `Start here` task links | the seed of the task-flow layer; already phrased as jobs | + +Every row on the right changes ready, implemented Studio Specs. Most are ordinary Spec revisions: +navigation, the landing, role entry and question pages. A code-unit page revises +`spec:consumers.spec-studio.spec-page#rule.sourceText`. Rendering views or switching roles in the +browser, a framework-based UI library, or in-page diagram layout would each need a decision Spec +refining the build-renders decision (MD-43), the custom-elements decision (MD-42) or the +diagram-layout decision (MD-44). [08](08-what-the-repo-settles.md) records what the repository +already settles; [06](06-design-cycles.md) carries the rest as long-horizon design questions. diff --git a/docs/design/05-specialised-and-ai-readings.md b/docs/design/05-specialised-and-ai-readings.md new file mode 100644 index 00000000..d2d63ee8 --- /dev/null +++ b/docs/design/05-specialised-and-ai-readings.md @@ -0,0 +1,135 @@ +# 05 — Specialised and AI-powered readings + +The first cycles design traditional delivery views (tier 1 in [01](01-roles-and-perspectives.md)). +That is the first focus, not the limit. This document keeps the wider option space open: +specialised readings for niche and ultra-specialised roles, and AI roles that could make those +readings affordable. Nothing here is a commitment; it is a map of what the foundation allows, kept +as a long-horizon research backlog. *Reading* and *persona* are provisional design-material words +(see the [README](README.md)), not ratified terms. + +## Why specialised readings are affordable here + +In most tools, every new view is a product feature with its own data, permissions and maintenance. +Here, a reading is a function of the graph and of the inputs a caller names beside it (a base +graph, run records, a perspective): no new store, nothing to keep in sync. Its output is +regenerated, never maintained by hand. Its cost is the code that composes it, which is reviewed and +tested like any other source, plus the design work any Protocol reading carries: + +- A reading the Protocol ships needs a carrying Spec stated `ready` before its code, because + maturity gates implementation. +- A Studio page shows only the recipe answers the Studio's design names + (`spec:consumers.spec-studio#rule.recipeAnswers`), and the recipe catalog runs only the bodies + the package ships, never one found in the corpus + (`spec:consumers.agent-surface.evaluation-sink#design.recipeSource`). +- An adopter's own body over the reader needs neither: past the entry adapters, the agent surface + grows by bodies an agent scripts (`spec:consumers.agent-surface#rule.growByRecipe`). + +That changes the economics: a reading for one role and one question is reasonable to build, as +long as it keeps the same honesty obligations as every other reading. Readings over git history +are an open extension. The graph holds one commit and only the extractor reads the repository, so +such a reading would take graphs written at named commits as a named input, as the design diff +takes its base graph ([08](08-what-the-repo-settles.md#3-history-beyond-one-commit) says how it may +ship; [06](06-design-cycles.md#history) asks whether any reader needs one; +[07](07-graph-needs.md) logs the need). + +## Candidate specialised readings + +Each row is a candidate, not a commitment. [01](01-roles-and-perspectives.md) lists the personas by +job (tiers 3 and 4); this table lists the readings by the material they draw on, and one reading +may serve several personas. Where a persona helps, pair it with the +[job stories](../../jtbd-stories/README.md) it serves, which deliberately name no persona. Each +status cell states what the repository confirms today. + +| Reading | Serves | Material | Status of the material | +|---|---|---|---| +| **Discipline activity over time** (the RUP hump chart, derived) | leader, process engineer | a series of graphs written at named commits, filtered by discipline | not built; needs a named history input and a carrying Spec (the design diff's pattern: the caller writes each graph) | +| **Decision lineage** | auditor, architect, decision archaeologist | decision register (recipe 31), decision map (recipe 18) for `decidedBy` reach, `supersedes` edges | register and reach available; a superseded record stays only while its text is still needed, so older lineage and its dates need graphs from earlier commits | +| **Example-space explorer** | stakeholder, requirements specifier, BDD practitioner | example-space slots, bound points and slot-value coverage (recipe 44); the Outcome union the space contract derives from the parent's Then steps | slot-value coverage available; witnesses are not in the graph, because they need the oracle evaluated at test time; the seed's harness ([seed 04 §4](../lineage/v0-design/04-authoring-surfaces.md)) is the precedent | +| **NFR board** | NFR budget owner, operations | `constraint` Specs with their `target` and `measurableBy` entries | targets available; measurements wait on the deferred `observed` fact | +| **Contract handshake** | API consumer, partner team | pinned declarations shared by two parties (recipe 24), key-family register (recipe 41) | material available; no per-contract reading yet | +| **Context tour** | newcomer | capability map (recipe 52), design slice (recipe 54), Model terms, bound code | available; ordering is design work | +| **Due-diligence dossier** | outside assessor | census, drift alarm (recipe 2), gaps (recipe 8), coverage-unknown (recipe 4), decision register (recipe 31) | available; must lead with its own limits | +| **Corpus hygiene board** | corpus curator | orphans (recipe 8), mention audit (recipe 22), curation report (recipe 40), slimming candidates (recipe 39) | available | +| **Adoption board** | adoption lead | capability adoption (recipe 47), rule-key proposal (recipe 48), the upgrade kit | available | +| **Pull-request change narrative** | reviewer, leader | design diff (recipe 35, with a base graph), blast radius (recipe 4, with changed files), statement-queue movement | diff and blast radius available; queue movement would need the statement queue (recipe 46) run at both commits, and no reading compares the two yet | +| **Migration progress by component** | migration lead | planned against realized components (recipe 43) | available; the seed drew it as a heatmap ([seed 05 §6](../lineage/v0-design/05-runtime-anchors.md)) | +| **Release contents** | release manager | git tags | deferred; the first published release reopens the owner's blocking question (`spec:consumers.projections-model.roadmap-views#question.releaseReader`) and does not by itself authorize the view | + +## The AI ladder + +[Article 5](../articles/05-ai-can-shape-the-reading.md), a direction article rather than intended +truth, separates three AI roles: **reader** (built), **editor through hand-off** (built) and +**presentation assistant** (future). This ladder breaks the third role into steps and adds the +drafting edge of the second (A6), ordered roughly by how much of the deterministic guarantee each +one keeps. Today, `graph = f(repo)`, and a shipped projection is a pure function of the graph and +the inputs a caller names: the same graph and inputs give the same bytes. + +The boundary's carrying Spec is `spec:consumers.ai-assisted-reading`, stated `idea`, with nothing +built. Its blocking question +(`spec:consumers.ai-assisted-reading#question.aiPresentationBoundary`, decided by the owner) asks +what contract keeps an assistant's own explanations or arrangements apart from what the graph +states and makes the exact reading reviewable, including how the exact output is kept with its +model, prompt and inputs. Its provisional answer +is intent, not a ruling: select existing deterministic readings only; any generated text stays +outside the Studio and the frozen projections, labelled as assistant output with its source commit +and scope, and adds no claim, fact or validator. + +| Step | What the AI does | Determinism | Boundary | Where it stands | +|---|---|---|---|---| +| **A0 · None** | nothing; a person navigates | full | — | today | +| **A1 · Select** | picks which existing reading answers a person's question | full: the reading is unchanged | the choice is shown with why it was selected and what scope it omits, and is reversible | within the provisional answer; not built, and building waits on the owner's question and a `ready` statement | +| **A2 · Compose a perspective** | writes the perspective JSON (selectors and order) for a concern the person names; the perspective filter (recipe 37) applies it | full once written: the perspective is data, reviewable and saveable | the perspective is named as a supplied input and shown with its selectors; every selected member's blocking questions stay visible by rule, and unselected members are listed by id | prototypable on the agent surface today (recipe 37, with recipes 36 and 54 taking its selection); the Studio takes no perspective input, so a Studio version is a Spec change to its named inputs; whether a written perspective counts as selection is part of the owner's question | +| **A3 · Write a projection** | writes the code of a new reading for a narrow question; it is reviewed, checked and then runs like any projection | full once accepted: the AI wrote the generator, not each render | lands as code through git and the checks; for a Protocol reading, a carrying Spec stated `ready` comes first | open; the strongest route to ultra-specialised readings. Precedents: corpus rules (operator-named code over the graph), the edit model, and the vault's prototype generator, kept as evidence before the vault was specified and built. Whether it needs the assistant-output contract is part of the owner's question | +| **A4 · Explain beside** | writes prose beside a deterministic reading: why two Specs conflict, what a floor clause means | none: model output varies | labelled as assistant output with its source commit and scope; under the provisional answer, outside the Studio and the frozen projections; how its model, prompt and inputs are kept is the open question | beyond the provisional answer; waits on the owner's question | +| **A5 · Converse** | answers questions about the graph in conversation, citing addresses for every statement | none for the words; every cited fact is checkable | every sentence that states a fact links to its address; unsupported statements are marked | beyond the provisional answer; waits on the owner's question | +| **A6 · Draft intent** | drafts scoped intents or a change proposal from a person's review notes | none for the draft | the person sees the exact memo before it leaves; the proposal check (recipe 38) runs against its base | editor role: agents already return change proposals from the advisory design loop (`spec:consumers.delivery-session-on-ramp`), and the rule-key proposal (recipe 48) writes one mechanically; drafting from review notes inside a reading is open | +| **A7 · Adapt arrangement** | reorders or condenses a reading for one reader | varies | may not drop a blocking question, turn an inferred edge into an authored one, or hide an input whose commit differs from the page | riskiest; an arrangement beyond selection, so it waits on the owner's question and needs measured evidence first | + +**The key observation.** Steps A2 and A3 are the candidate route by which tier-3 and tier-4 +personas become affordable while the output stays a deterministic function of the graph: the AI +authors the selection (a perspective) or the generator (a projection's reviewed code), and the graph +supplies the content. The provisional answer allows only selecting existing readings, so this route +is not law yet. Whether a written perspective counts as selection, and whether a reviewed generator +needs the assistant-output contract, both sit inside the owner's blocking question. "AI authors the +selection; the graph supplies the content" is a candidate answer to that question, to be tested over +the design cycles. It avoids *lens* on purpose: lens is the Studio's owner-ruled name for its graph +views (`spec:consumers.review-perspectives`), and the glossary lists it as a word to avoid for a +perspective. + +## Boundaries every step keeps + +From Article 5, restated as tests a prototype must pass: + +- A model may explain a `declared` relation but may not present its own inference as declared. +- `implemented` still means a resolving `satisfies` edge; `has-verifier` still means a resolving + verifier exists. A summary may not soften or strengthen either. +- Supplied run results never become `observed` and never imply a pass that no record shows. +- A model may recommend a readiness statement. Only an author states readiness. +- A displayed proposal is not canonical. The view writes no source: a proposal leaves it only as a + hand-off, a saved proposal and memo that an agent checks against its base before applying. +- Omitting detail is allowed only when the reading says what was left out, as a context bundle does. +- The page set stays static and offline under current law: the Studio is a static page set + (`spec:consumers.spec-studio#rule.staticPageSet`), its composing panel requests nothing over the + network and sends its intents nowhere (`spec:consumers.spec-studio.intent-panel#rule.noRequest`), + and no page element requests anything under `file://` + (`spec:consumers.spec-studio.page-elements#rule.noRequest`). The seed's further rule, that the + browser runs no model and holds no keys + ([seed 07 §4](../lineage/v0-design/07-spec-studio-and-projections.md)), is a proposed boundary, + not current law. An AI step that needs a model runs where the person's agent runs, or in a + commercial service (exploratory; see [PRODUCT.md](../../PRODUCT.md)), and the reading states + which. + +## What the design pass should measure + +The capture's trigger reopens its blocking question when "the UX design pass measures that +assistant selection or a generated explanation helps a named review task". These are long-horizon +research questions for the design cycles, not one-off checks. The Studio is static and sends +nothing, so evidence comes from task sessions with named readers, never from usage analytics; +[09](09-design-method.md) holds the method. Measurements for prototypes: + +1. Does A1 selection get a reviewer to the right reading faster than navigating from the index + alone? +2. Does an A2 perspective, written from a stated concern, select the members a human would? +3. Does an A4 explanation help a reviewer understand a Pack without making them less likely to open + its Specs? +4. Does an A7 arrangement save effort, or does a stable structure make review easier? diff --git a/docs/design/06-design-cycles.md b/docs/design/06-design-cycles.md new file mode 100644 index 00000000..606f5223 --- /dev/null +++ b/docs/design/06-design-cycles.md @@ -0,0 +1,230 @@ +# 06 — Design cycles + +How the design work is sequenced, which briefs to shape first, what the repository already settles, +and which design and product questions stay open for the long horizon. + +**Status.** This is design material and it confers nothing. No cycle here counts as next work, and +nothing here dates, gates or sequences delivery. The Protocol reads its next work from the roadmap +(recipe 53 over `pack:roadmap`). A cycle joins the roadmap only on the owner's word +(`spec:consumers.graph-first-planning`, `spec:protocol.roadmap-replaces-plans#rule.readsRoadmap`). +Terms the [README](README.md) flags as provisional (reading, persona, role home, object page, basis +line) stay provisional here. + +## The starting point + +The current Studio is the baseline. Read it as a prototype, not a target. What it teaches, and the +record every later prototype is compared with, are in [10 — Studio baseline](10-studio-baseline.md). + +One finding shapes every cycle. The Studio's manual acceptance tasks (`spec:consumers.spec-studio`, +manual verification) are written for a person who holds only a link. They include the first +adopter's findability tasks. They also ask the person to name what the owner can state first, what +changed since the base, and which components are designed but not yet built. None is written from +the job of a technical product manager, a leader or a tester. Role acceptance tasks are therefore a +design output in their own right. + +## Cycle plan + +Every cycle follows the method in [09 — Design method](09-design-method.md). The method covers the +named task sets, the readers who take them, how each session is scored and recorded, and how +prototypes are built over the graph. Every cycle measures; no cycle leaves measurement to a later +one. A cycle ends with prototypes tested against named tasks, not with a visual design. Visual +design starts when the design system is introduced. + +| Cycle | Focus | Outputs | Closes when | +|---|---|---|---| +| **0 · Baseline** | today's Studio at a stamped commit, read against the task sets on the self-hosted corpus, `examples/checkout-v1` and the first adopter's corpus | the baseline record ([10](10-studio-baseline.md)); a list of current readings, each with a keep, merge or retire hypothesis (Article 2's seventh question) | every task in the sets has a recorded outcome at a named commit | +| **1 · Foundation and tier-1 core** | the IA skeleton; the landing and arrival; role homes for the technical product manager, the decider and the architect, selected by concern rather than by person; flows *review a Pack for readiness* and *review a pull request's design change* | briefs; low-fidelity structure prototypes; role acceptance tasks paired with job stories ([01](01-roles-and-perspectives.md), [11](11-rup-roles-and-artifacts.md)); candidate words for the provisional terms | the tier-1 tasks have outcomes on the same corpora, compared with the baseline | +| **2 · Remaining tier 1 and phone** | engineer, tester and leader homes; flows *trace to verification*, *assess impact* and *work the queue*; phone review as a task design of its own, within the rule that the same pages serve a desktop and a phone (`spec:consumers.spec-studio.responsive`) | briefs, prototypes, phone task results | the same, phone tasks included | +| **3 · Object pages and hand-off** | question pages (each decision already has its Spec page); the composing panel across readings; the agent hand-off | briefs and prototypes; a map of the end-to-end change journey from [02](02-seed-experience-map.md), step by step, with the artifact and the basis each step carries | a change completes the journey in a session, from a reading to a checked proposal | +| **4 · Specialised readings and AI steps** | a few tier-3 readings (onboarding tour, example-space explorer, decision lineage); A1 prototypes measured against review tasks; A2 tried on the agent surface ([05](05-specialised-and-ai-readings.md)) | measurements for the AI capture's re-entry trigger; A2 results as separate evidence | each AI step has an outcome on a named review task, compared with the same task without it | +| **5 · Commercial surfaces (exploratory)** | desktop reading over the working tree, web team review, CI run readings; where product state may live | concept briefs only; the commercial questions below made explicit | the owner has the evidence those questions need | +| **then · Visual design** | introduce the existing UI library and design system, within the custom-elements decision (MD-42) unless a decision supersedes it | DESIGN.md, then visual work per surface | — | + +- **Every cycle tests against the same sets**: the design questions in + [Article 2](../articles/02-one-graph-many-views.md), the Studio's manual acceptance tasks and the + new role acceptance tasks. It compares the results with the baseline. +- **Every cycle runs as an arc.** The owner's instruction opens it, and its record is its draft pull + request. The description shows the prototypes at base and head, the task results, the rulings the + owner made and the rulings delegated. Once a design Pack exists, it also shows Pack design + (recipe 29) and the design diff (recipe 35) over that Pack. A cycle closes on evidence, never on a + date. +- **Prototypes are evidence, not product.** A prototype reads the graph. Where material is missing, + it shows the gap as a named absence and logs it in [07](07-graph-needs.md); it never hard-codes + the missing data. Prototypes are committed on the arc's branch with the commands that made them, + and removed before merge (`spec:protocol.roadmap-replaces-plans#rule.evidence`). +- **What the AI trigger counts.** The blocking question + `spec:consumers.ai-assisted-reading#question.aiPresentationBoundary` re-enters when "the UX design + pass measures that assistant selection or a generated explanation helps a named review task". + A1 (select) is assistant selection, and A4 (explain beside) is a generated explanation. A2 + measurements meet the trigger only if the owner rules that composing a perspective counts as + selection. An A4 prototype joins cycle 4 if the pass is to test the explanation half. +- **The commercial cycle is exploratory.** The core is and stays open source and free. A commercial + Studio is under consideration, possibly as a desktop app, a web app and a CI/CD surface. The + corpus records only that hosted review, shared comments and hosted previews "may later ship under + `@libar-ai/`" (`spec:consumers.spec-studio`). Cycle 5 writes concept briefs. Where commercial + design intent is recorded is itself one of its open questions. + +## First briefs to shape + +Candidates, in recommended order. Each brief names its job, its reader, the recipes the reading +shows, its basis and its hand-off. A Studio page shows a recipe's answer only when its Spec names +that recipe (`spec:consumers.spec-studio#rule.recipeAnswers`). The brief itself stays in the session +that shapes it. What lasts is its evidence on the arc and what it becomes in the corpus. + +1. **The landing and arrival.** Who are you, and what do you hold? This is the doorway to role + homes and flows: small, and high in leverage. It tests whether a new landing should replace the + index. Today the index opens with a count summary, routes by task under `Start here`, and lists + each Pack as a closed disclosure (`spec:consumers.spec-studio.index-page`). +2. **The technical product manager's home.** This is the strongest-fit persona. The brief tests + whether the graph can answer "where does intent stand?" honestly. +3. **Review a Pack for readiness.** The Design Review's job as a flow. It exercises stated + readiness, the floor reached and the delivery facts, shown apart, together with blocking + questions and the composing panel. +4. **Review a pull request's design change.** The reviewer's job, starting from a stamped preview. + It exercises the stamp, the diff page and impact. The seed's whole loop, from a product manager's + reading to verified code, is cycle 3's change journey. + +## Answered from the repository + +This document first put these questions to the owner. The repository answers their technical half. +Each row points to the section of [08 — What the repository settles](08-what-the-repo-settles.md) +that carries the evidence. What stays open moves to the next section. + +| Question | What the repository settles | Section in 08 | +|---|---|---| +| Should ownership return to the model? | A Spec names no owner: this is a stated non-goal ([vision, §5](../concept/00-vision-scope-and-mvp-boundary.md)), and the envelope's key set is closed (`spec:carrier.envelope-contract`). Ownership can return only through a decision that reopens the non-goal | ownership | +| What should the provisional terms be? | None is ratified. `role` is a ratified anchor value. "Lens" names the Studio's graph views and is an alias to avoid for perspective. "Census" names the `sdp census` projection. The Studio calls its intent element the composing panel | terminology | +| Is "AI authors the selection; the graph supplies the content" a principle? | An assistant may select existing readings; that is the provisional answer to `#aiPresentationBoundary`. An agent can write a perspective on the agent surface today. The Studio reads only two named inputs | perspectives and AI | +| May a reading derived from git history ship? | Only as caller-supplied named input beside the graph, and never as a gate. The design diff already reads a graph built at another commit, and run records carry their own commits; neither enters the graph | history | +| Where may commercial product state live? | The law says what such state may never become: graph data, a delivery fact, a rung, an approval or a recorded review. It does not say where such state may live | state | +| Which Studio pages are retired, merged or kept? | The repository says which Specs each change touches, and which changes are ordinary revisions and which need a decision | evolution | +| Do questions and decisions become object pages? | Every decision is a Spec and already has its own page. Only question pages would be new, and each would need a carrying Spec and a path | objects | +| Where does the design project itself live? | Design intent and questions belong in carriers, forward planning in the roadmap, and prototypes in arc evidence | self-hosting | + +## Design questions for the long horizon + +These design and product questions will be answered over months of iterative work. They are not to +be settled up front: each is answered from the evidence a cycle gathers, and the owner rules on each +once that evidence is in. This is the one register of them: [08](08-what-the-repo-settles.md), +[10](10-studio-baseline.md), [11](11-rup-roles-and-artifacts.md), [12](12-analogous-products.md) +and [`PRODUCT.md`](../../PRODUCT.md) point here. They stay here until an engineering session and the +owner give them a corpus home ([07](07-graph-needs.md#a-corpus-home-for-these-needs-a-proposal)). + +### People and entry + +| Question | Evidence from | +|---|---| +| Do "my work" readings justify reopening the non-goal that a Spec names no owner, and in what form: per Spec or per Pack, a section rather than an envelope key, more `decider`-style tokens, or authorship derived from a history input? Any form is weighed against the closed envelope, the stability law L9 and the workflow-tracker risk `spec:model.open-question-fields` names | cycles 1–2: role homes built by concern show what a person-scoped reading would add | +| Do role homes ship in the Protocol at all? If so, are they fixed readings composed from named recipes, or built from corpus-owned perspectives? The latter needs a third named input | cycles 1–2 | +| Does `owner`, already the default decider token in the statement queue, the roadmap and the owner queue page, become a ratified term? Does the Studio serve deciders other than `owner`? Where do `delegated` questions surface, given that the token names nobody? | cycle 2 (*work the queue*) | +| Do "decide now" and "parked until a trigger" become separate readings wherever questions appear? | cycle 2 (*work the queue*) | +| Does an explanation-first "what stands before the stated next rung" reading help a readiness author or decider decide faster than today's Pack page? | cycle 1 (*review a Pack for readiness*) | +| Which personas need intent where they write code (the IDE, the vault) rather than in the Studio? | cycle 2; cycle 5 (desktop) | + +### Words + +| Question | Evidence from | +|---|---| +| Do "reading" and "persona" join the glossary's guidance-only labels, or stay design words? What are role homes, the basis line and object pages called if any of them ships, given the ratified anchor `role`? Which provisional words, if any, does the owner ratify? | every cycle; the cycle-1 briefs try the words with readers | +| How are the two kinds of design session named so that neither reads as the other ([08](08-what-the-repo-settles.md#2-terminology))? | cycle 0 | + +### Landing, navigation and pages + +| Question | Evidence from | +|---|---| +| Does the index stay the landing page and the Packs lens, or does a new landing replace it? What must a landing do to orient a newcomer and route by delivery role, and what does it drop from today's census-first index? | cycles 0–1 | +| How does the top navigation regroup, given the order the navigation and lenses Specs fix? | cycle 1 | +| Which pages merge or retire (Article 2's seventh question), and which become parts of role homes? Candidates from [10](10-studio-baseline.md): the roadmap Pack page and the Roadmap lens, the evidence lens and runs, the two backlogs | the cycle-0 list of readings, tested in cycle 1 | +| What does search rank first (the defining Spec, the entry or the code), and do entry addresses and decision registry names become search terms? | cycle 1 (the landing and arrival) | +| How does a count state its scope, so that one concept never shows different numbers unexplained? | cycles 1–2 | +| How should the rail and panel defaults behave when one Pack holds the whole corpus, and per kind? | cycle 1 | +| Do open questions get pages of their own? Do code units, which a Spec page shows as text today? Does a reader holding an entry address get a landing? | cycle 3 | +| Does phone review get readings of its own, against the rule that the same pages serve both widths? | cycle 2 | +| Do the Markdown Design Review and the Studio stay equal in rank, as the derived-HTML decision (MD-41) holds? | cycle 3 | + +### Basis and trust + +| Question | Evidence from | +|---|---| +| Is a basis visible on every reading worth giving up the rule that a page set carries no commit, or should the basis stay in the stamp? What does a `file://` page or a Pack export show? How does a reading of uncommitted work state its basis? | cycle 1 (*review a pull request's design change*); cycle 5 (working tree) | +| Does a reading-scoped count of findings and absences in every header help, or does it become noise the way suspect links did ([12](12-analogous-products.md))? | cycles 1–2 | +| Does a derived "changed since the base" indicator give reviewers the value of suspect links without their noise? | cycle 1 (*review a pull request's design change*) | + +### History + +| Question | Evidence from | +|---|---| +| Does any reader need a history reading? Nothing about history is on the roadmap | cycle 4 (decision lineage) | +| What does a "ruled" history input mean: a decision or a capture Spec? What is its shape, which commit metadata may a page show, and where may dates appear? | cycle 4 | +| Release and baseline views stay held by `spec:consumers.projections-model.roadmap-views#question.releaseReader` | its own trigger: the first published release | + +### AI-assisted reading + +| Question | Evidence from | +|---|---| +| Where is the boundary for assistant-written presentation (`#aiPresentationBoundary`, decided by the owner)? Does composing a perspective (A2) count as selection? Does a generator an agent writes and git reviews (A3) need the assistant-output contract, or is it ordinary authored code? | cycle 4 measurements | +| Does the Studio accept a perspective as a third named input, or render saved corpus perspectives? | cycles 1–2 (role homes), cycle 4 | +| Does code a corpus writes to generate a reading get a publishing path, or does it stay an adopter's own script over the exported reader? | cycle 4 | +| Does "AI authors the selection; the graph supplies the content" become a principle? | cycle 4 | +| How are this design pass's measurements recorded and presented as evidence for the AI-reading trigger? | cycle 0 (the session record in [09](09-design-method.md)); cycle 4 | + +### Leader, audit and RUP-shaped readings + +| Question | Evidence from | +|---|---| +| Can a leader reading built from counts of named kinds, with drill-down and no percentage, earn a leader's trust? What do leaders do when no single number is offered? | cycle 2 (the leader home) | +| Will an auditor accept stamped readings, a Pack export and git history in place of a signed review record, or does a commit-keyed evidence set need a reading of its own? | cycle 4 | +| Which RUP-shaped readings come first, starting from the cheapest that need no model change ([11](11-rup-roles-and-artifacts.md#long-horizon-research-backlog))? Do stakeholder entities, a business-versus-system use-case scope, effort estimates, or risk probability and impact ever enter the model? | cycles 1–4, as the RUP roles in 11 are taken up | + +### Commercial surfaces (exploratory) + +| Question | Evidence from | +|---|---| +| What does the commercial line cover? The corpus names only hosted review, shared comments and hosted previews; the desktop, web and CI surfaces appear nowhere in it | cycle 5 | +| Where may product state live (review threads, saved perspectives, preferences, drafts across devices), given that the corpus owns its perspectives? Two precedents exist for state a person writes beside a projection: the composing panel's gathered intents in browser storage (`spec:consumers.spec-studio.intent-panel#rule.persist`), and the vault, which keeps a Base a person changed and never writes the `intent/` notes outside its folder (the vault owns one folder, MD-45) | cycle 5 | +| May a hosted service run user-supplied `sdp q` bodies or rules files? Neither claims a sandbox | cycle 5 | +| Which app is the concrete caller for MCP, which the MCP-deferred decision (D6) holds? | cycle 5 | +| When does a run become stale (`spec:observation.run-evidence.bound-file-freshness#question.freshness`)? | cycle 5 (CI readings) | +| How are readings of a private corpus shared, given that previews deploy to the repository's own served pages? Do editor deep links belong on a desktop surface? | cycle 5 | +| Is commercial design intent recorded in this open-source corpus or elsewhere? | cycle 5 | +| Which habits from analogous products (comments, notifications, private drafts) belong in a commercial surface, and can each stay product state without becoming delivery truth ([12](12-analogous-products.md))? | cycle 5 | + +### The design project and visual design + +| Question | Evidence from | +|---|---| +| Do `PRODUCT.md` and `docs/design/` stay on main as status-labelled prose that confers nothing, or live as per-arc evidence? | cycle 0: the first arc's first commit forces the choice | +| Is a corpus home wanted at all? If so, is the effort one design Pack or several, and what are they named? | cycle 0 | +| Which design system is adopted, and does it fit the custom-elements decision (MD-42) or need a superseding decision? Until then, IA patterns stay within what native disclosure and custom elements carry | visual design | +| Which accessibility conformance target applies beyond the shell's existing rules (keyboard, words beside color, reading without script)? | keyboard, no-script and phone passes from cycle 1; the target at visual design | + +## How design outputs become product + +Design material lives here and confers nothing. A design session edits no graph input: no carrier, +Pack or anchor. When a design decides what a projection does, an engineering session moves the +decision into a Spec through the authoring workflow (the `sdp-authoring` skill), and the Spec becomes +the authority. The path runs like this: + +1. The brief names its job, reader, recipes, basis and hand-off. +2. A capture at `idea` refines the Studio's carrying Spec (`spec:consumers.spec-studio`). +3. UI entries and manual verification tasks, the role acceptance tasks among them, take it toward + `defined`. +4. Promotion preflight (recipe 9) shows what stands before the stated next rung, and the owner + states `ready`. +5. An implementation arc builds it. + +A change to a `ready` Studio Spec, such as the landing, the navigation order, the stamp, a Spec +page's source text or what search indexes, travels as a change proposal. The proposal check +(recipe 38) checks it against its base, and the proposal memo (recipe 49) renders it for review. + +Some changes need a decision. The frozen projections (Design Review, census, Mermaid, Gherkin) +change only through a decision that refines or supersedes the shipped-projections decision (MD-32). +The Studio is not frozen, but its own decisions bind it: the derived-HTML decision (MD-41), the +custom-elements decision (MD-42), the build-renders decision (MD-43) and the diagram-layout decision +(MD-44). A Studio Spec changes by ordinary revision while the design stays static, derived, rendered +at build time and framework-free. Anything else needs a decision Spec that refines or supersedes the +relevant record. Everything proposed here targets the Studio and new readings. + +**Proposed corpus home (a proposal, not done).** A design Pack holding the questions above as keyed +open questions is engineering-session work for the owner to decide, set out in +[07](07-graph-needs.md#a-corpus-home-for-these-needs-a-proposal); design sessions do not build it. diff --git a/docs/design/07-graph-needs.md b/docs/design/07-graph-needs.md new file mode 100644 index 00000000..baef742f --- /dev/null +++ b/docs/design/07-graph-needs.md @@ -0,0 +1,246 @@ +# 07 — Graph needs + +A UI view is a projection like any other. It can only show what the graph holds, plus any input +it names apart from the graph, such as a base graph or run records. The graph is not complete: +architecturally significant units may carry no anchor, relations may be missing, and some material +the seed design modelled has no home yet. Design work is one of the ways those gaps are found. +[03](03-reading-material.md) describes the material a reading can draw on, and +[08](08-what-the-repo-settles.md) lists the limits the repository already settles. This page is the +one log of what a reading needs and the graph lacks. + +The log is a hand-off from design sessions to engineering sessions: **design sessions record needs +here for consideration; they never edit carriers, Packs, anchors or anything else that feeds the +graph.** An engineering session, with the owner, decides whether and how the graph grows, and the +reading regenerates once it does. "Design session" here means a session of this UX and +information-architecture project. The handbook's design sessions ([AGENTS.md](../../AGENTS.md), +"Design vs execution") author Specs and edit carriers; on these pages that work belongs to the engineering +session a row hands off to. + +## The loop + +1. **A reading names its material.** Every brief or prototype states which reader calls, recipes or + inputs it reads (see the anatomy in [04](04-reading-model-and-ia.md#1-anatomy-of-a-reading)). +2. **A gap is recorded, never faked.** When the material is missing, the prototype shows the gap as + a named absence and a row lands here. A prototype never hard-codes data the graph does not hold. +3. **An engineering session considers it.** A need may become an anchor (identity, `role`, `layer`, + `context`), an authored relation or its `reason`, a section entry or a key, a keyed open + question or a decision Spec, a new projection input, a new projection, or no change. The design + session that found it does not make the change. +4. **The reading regenerates.** Once the graph holds the material, the reading is a function of it, + like every other projection. + +Tools that find gaps without design work: the curation report (recipe 40), given an imports file, +ranks files the anchors miss and component imports that disagree with anchored uses; planned +against realized components (recipe 43) compares component designs with the anchors that realize +them; orphans and gaps (recipe 8) lists the warn-level absences; the mention audit (recipe 22) finds +prose mentions that do not resolve or that no declared relation backs. + +## How to write a row + +| Field | Content | +|---|---| +| **Need** | the material, in one line | +| **Reading** | the role reading or flow that needs it | +| **Today** | what the graph holds instead, and how the reading behaves without it | +| **Evidence** | the query, recipe or carrying entry that shows the gap; named queries are under [Evidence queries](#evidence-queries) | +| **Candidate home** | anchor · relation · reason · section or key · keyed question or decision Spec · projection input · new projection · deferred delivery fact · none (the law keeps it outside the graph) | +| **Decision home** | the entry address or Spec id that holds the open question, when the corpus has one; otherwise `proposed` (see [A corpus home for these needs](#a-corpus-home-for-these-needs-a-proposal)); `none needed` for plain curation | + +A row holds no status. Its state is read from its decision home: the open-question register +(recipe 20) for a question, and git and the pull request that made it for a ruling. + +## Log + +Reading names such as role home and basis line are the provisional design terms listed in the +[README](README.md#words-used-here). + +| Need | Reading | Today | Evidence | Candidate home | Decision home | +|---|---|---|---|---|---| +| Who is responsible for a Spec, Pack or context | role homes that start from "my work" | No node carries an owner. The only person-shaped value is an open question's `decider`, a corpus token that references nothing and authorizes nothing; an Intent `actor` says whom a Spec serves, in a small minority of Specs. "A Spec names no owner" is a current non-goal ([concept 00](../concept/00-vision-scope-and-mvp-boundary.md)), and the closed envelope refuses an `owner:` key (`spec:carrier.envelope-contract`). A reading can group by concern (Pack, perspective, context, kind), never by person | *fields*, *deciders*, *actors* | a decision Spec weighing a section field, decider-style tokens beyond questions, or authorship read from supplied history; never an authorization or a gate | `proposed` | +| History: when a Spec, question or decision changed | discipline activity over time; question age; decision lineage with dates; readiness trajectory | The graph is derived from one checkout and names neither its commit nor any time; the design diff compares a supplied base graph with the current one. Ready Studio law shows no history (`spec:consumers.spec-studio.shell#rule.noRecentEdits`) and holds history diagrams until "a ruled history input and a history reader" (`spec:consumers.spec-studio.diagram-kinds#design.gitGraph`). Question age needs a keyed question, and a trajectory breaks where an id is renamed | *graph keys* | a named projection input: graphs `sdp build` wrote at caller-named commits, the caller or CI doing the git work, as the design diff's base graph already does (git is the event log). A consumer reading git itself would test the one derived read model principle (P2: no consumer reads source directly), so it would likely need a decision | `proposed`; release and baseline views wait on `spec:consumers.projections-model.roadmap-views#question.releaseReader` | +| Who reviewed, approved or stated `ready` | leader and reviewer readings; decision lineage | Never a graph fact: that a review occurred is never recorded ([CONTEXT.md](../../CONTEXT.md)), approval lives in git and CI ([concept 00](../concept/00-vision-scope-and-mvp-boundary.md)), and a change proposal carries no approval (`spec:consumers.intent-composition.proposal`). The record is git history and pull request descriptions | the glossary's note under `ready` | none in the graph; a labelled outside input read from git or the pull request host, if a reading needs it | `proposed`, beside the history question | +| A `reason` on the relations a "why" reading explains | decision lineage; architect home | Sparse: most `decidedBy` relations carry no reason, including most of those on the decisions that shape the most Specs | *reasons*; the decision map (recipe 18) ranks decisions by fan-in | authored `reason` lines (curation, no model change) | `none needed` | +| A key on each rule and flow entry a reading links to | object pages and deep links ([04](04-reading-model-and-ia.md#31-object-pages)); comments and proposals scoped to one rule | A large share of rule and flow entries carry no key, so they have no entry address; the closest link is their section | *rule keys* | rule keys, proposed by the rule-key proposal (recipe 48) and checked by the proposal check (recipe 38) before an engineering session applies them | `none needed` | +| Measurable constraints to read | NFR board; operations reading | The self-hosted corpus holds almost no constraint Specs with a measurable target (the NFR named coordinate); the worked example carries a latency constraint | *constraints* | corpus content; prototype on the worked example or an adopter | `none needed` | +| Runtime observation | operations; leader "is it live?" | `observed` is a designed, deferred delivery fact; the evidence lens reads runtime observation as not tracked | `spec:observation.runtime-overlay` (stated `idea`) | the deferred delivery fact | `spec:observation.runtime-overlay#question.observationIdentity` | +| Build attestations, deployments and software bills of materials | release, operations and security readings | The evidence lens names each source and reads it as not tracked; no Spec designs a source for them | `spec:consumers.spec-studio.lenses.evidence#rule.notTracked` | named projection inputs with carrying Specs | `proposed` | +| Run results across many pipeline runs | tests lens trends; CI surface | A Studio build reads the run records it is given as one named input; each run shows its own commit and times, and no page compares runs or calls one fresh or stale | `spec:consumers.spec-studio.runs-page#rule.namesEachRun`; `spec:consumers.spec-studio.data.inputs#rule.namedInputs` | a named projection input (a run series) with a carrying Spec | staleness: `spec:observation.run-evidence.bound-file-freshness#question.freshness`; trends: `proposed` | +| The basis of every reading: commit, engine and supplied inputs | the basis line on every reading; phone and export readers | The graph names no commit. The stamp names one only after `sdp stamp` and shows only over http(s), so a page opened through `file://` and a Pack export show no basis. Nothing marks a working-tree graph as holding uncommitted edits | *graph keys*; `spec:consumers.spec-studio.sharing#rule.buildWritesNoStamp`; `spec:consumers.spec-studio.shell#rule.stamp`; `spec:consumers.spec-studio.export#rule.exportBytes` | a projection input, or a revision of the sharing and export Specs; at minimum an honest "not stamped" absence | `proposed` | +| A perspective applied inside a reading | role homes; reading a Pack for one concern | Perspectives are corpus data the perspective filter (recipe 37) takes on the agent surface. The Studio reads at most two inputs, a base graph and run records, and evaluates no recipe 37. This repository keeps no perspective file | `spec:consumers.spec-studio.data.inputs#rule.namedInputs`; `spec:consumers.spec-studio.data.recipe-answers#design.recipeEvaluations` | a named projection input, designed the way the scoped `spec:consumers.spec-studio.register-input` designs a third one | `proposed` | +| Questions for a decider other than `owner`, and who acts on a `delegated` question | "what only I can settle" in a role home | The Studio's queue page lists only `owner` questions (`spec:consumers.spec-studio.owner-queue#rule.ownerQuestions`); another token, such as `delegated`, is read through recipes 46 and 53 with `params.decider`. The token references nothing, so no reading can say who acts on a `delegated` question. Waiting readiness statements belong to no decider | the statement queue (recipe 46) with `{"decider":"delegated"}`; *deciders* | a projection change: a queue per decider token | `proposed` | +| A recorded basis for an assistant's selection or explanation | AI-assisted readings ([05](05-specialised-and-ai-readings.md)) | Only deterministic readings exist. A blocking question the owner decides holds generated presentation; its provisional reading allows selecting existing readings only, with generated text kept outside the Studio | `spec:consumers.ai-assisted-reading` (stated `idea`) | the output contract that question asks for; its trigger is a measurement from this design pass | `spec:consumers.ai-assisted-reading#question.aiPresentationBoundary` | +| Links from UI entries to visual design artifacts | product-designer reading (later audience) | UI entries are keyed open entries with no convention for design-tool links. The seed's `UiFacet` type listed Figma nodes, Storybook stories and screenshots ([seed core primitives, §2.10](../lineage/v0-design/01-core-primitives.md)) | *ui entries*; `g.findByConcept("figma")` returns nothing | a UI-entry convention | `proposed` | +| A route from a decision's registry name (such as MD-22) to its Spec | decision lineage; architect home; any reader holding a registry name from prose | The registry is [`DECISIONS.md`](../concept/DECISIONS.md), outside the graph, and few decision Specs mention their registry name, so search cannot find a decision by it ([10](10-studio-baseline.md)) | `g.findByConcept("MD-22")` returns nothing | a named projection input, as the scoped `spec:consumers.spec-studio.register-input` designs one for an outside register; or the registry name as authored decision content | `proposed` | +| "The other end of this relation changed since the base" | Spec and Pack pages read against a base; the auditor ([12](12-analogous-products.md)) | The design diff (recipe 35) reports changed parts per Spec, relation targets among them, but no reading says that the other end of a relation changed | `g.findByConcept("suspect")` returns nothing; recipe 35's contract in the [catalog](../agent-surface/recipes.md) | a recipe composed over the two graphs recipe 35 already reads; derived, never authored | `proposed` | +| Which readings select a Spec | every Spec page; the corpus curator ([12](12-analogous-products.md)) | Perspectives are corpus data passed to the perspective filter (recipe 37) on the agent surface; nothing lists which readings select a given Spec, so a Spec no reading selects stays invisible | recipe 37's contract in the [catalog](../agent-surface/recipes.md) | the reading layer, once role readings are declared as data | `proposed` | +| A small or deliberately awkward test corpus | the test states every reading must survive ([09](09-design-method.md#4-test-corpora-and-states)) | The self-hosted corpus and the worked example cannot supply every state; neither holds an idea-only Pack | the idea-only Pack query in [09](09-design-method.md#4-test-corpora-and-states), run on both roots | corpus content outside the self-hosted corpus, such as a fixture corpus | `proposed` | + +Rows are design findings, not commitments. Design questions here run over many months of iterative +work, so a row may stay open for the whole horizon; that is a valid state, and a reading shows the +absence until the graph holds the material. + +## Reader frictions found by design research + +The log above records material the graph lacks. This section records frictions in the agent +surface: places where the reader (`g`), a shipped recipe or the +[catalog](../agent-surface/recipes.md) cost an agent extra calls, or gave an answer that read as +more than it said. They were observed when agents explored this repository for the design research, +found by mining those agents' transcripts, and each was reproduced with the query in its row. Each +is a consideration for an engineering session, not a decision, and its candidate responses are +options. A design session records them and changes nothing: the reader, the recipes, the catalog, +the skills and [AGENTS.md](../../AGENTS.md) are all engineering edits. + +The yardstick is the outcome of `spec:consumers.agent-surface.answer-shapes`: "each answer in one +call that fits its context, with every miss explained". Each body runs as +`pnpm --silent sdp:q '' --json` and answers at the commit it runs on; re-run it rather than +trusting the row. Some bodies pass a deliberately wrong id, address or field to show how a miss is +answered; those are not citations. One friction found the same way is already a log row: a decision registry number +such as MD-22 finds no Spec. Two mining notes about duplicated lines in the event logs describe the +logs, not the surface, and are left out. + +| Friction | How it shows | Effect on a reader | Candidate response | Ruling | +|---|---|---|---|---| +| **Recipe answer shapes are guessed, and a wrong path is silent.** Envelopes differ: some recipes answer under `totals`, others under `total` or `errors`; the open-question register (recipe 20) nests its rows under `specs[].questions`, the roadmap (recipe 53) under `roadmaps[0].entries` | `const r = await recipes(20, {}); return [r.rows, r.questions, Object.keys(r)]` gives `null`, `null` and `totals specs malformed`; `Object.keys(await recipes(53, { pack: "pack:roadmap" }))` gives `decider roadmaps`; `await recipes(20, { nope: 1 })` gives `{ unknownParams, accepts }` and no answer fields | A guessed path prints `[]` or `0`, which reads as "no open questions" or "an empty roadmap". Several agents probed keys, grepped the catalog or dumped a whole answer before they could filter it | The unknown-parameter reply also naming the answer's top-level fields; an answer-shape line at the head of each catalog entry; one envelope, such as `totals` beside named lists, for the recipes that lack it | | +| **Summary rows lack a Spec's content, so a field read off them is a silent zero.** `g.specs()` rows carry the id, coordinates, delivery facts, file, Packs and sometimes the narrative, but no sections, bindings or open questions; `g.packs()` rows carry no members | `return [g.specs().filter((s) => s.sections?.intent?.actor).length, g.specs().filter((s) => g.specContext(s.id).sections.intent?.actor).length, g.packs().filter((p) => p.members).length]` gives `0`, a non-zero count, `0` | Optional chaining turns a missing field into "no Spec names an actor" or "no Pack has members". Agents read the zero as data, or fell back to grep once they doubted it | The row fields listed in the skill and the catalog, naming `g.specContext` and `g.packContext` as the place for content; rows that throw on an unknown field; or sections on rows, weighed against the flooding row below | | +| **Field names on nodes, edges and adapter answers are guessed.** Node types are `Primitive`, `Pack`, `Anchor` and `CodeNode`; edges carry `from`, `type`, `to` and `claim`; `g.findByConcept` names matches in `matchedIn`; `g.specContext` is flat; Pack membership is `belongsTo`, while `memberOf` is component structure | `return [graph.nodes.filter((n) => n.nodeType === "spec").length, graph.edges.filter((e) => e.kind === "belongsTo").length, Object.keys(g.findByConcept("roadmap")[0])]` gives `0`, `0`, `id nodeType matchedIn` | Hedged reads such as `e.type ?? e.kind` and `r.fields ?? r.matchedIn`, a probe call per surface, and misleading counts: one agent counted `memberOf` edges as Pack membership | A field table for nodes, edges and each reader method's answer, in the skill or the catalog (the skill names node and edge types but not edge fields) | | +| **A reader method that does not exist fails without naming the ones that do** | `return g.spec("spec:consumers.reader")` exits 1 with `sdp q: g.spec is not a function`, and `g.resolveAddress` the same; `return Object.keys(g)` lists the methods | Agents guessed `g.spec`, `g.resolveAddress` and `g.decisions()`, spent a call listing the methods, or looped `g.specs().find` where `g.specContext` was the join they wanted | A clearer error naming the reader's methods and the nearest match; the method list in the skill's contract section | | +| **`recipes()` returns a Promise, and a missing `await` reads as a missing field** | `const a = recipes(12, {}); return [typeof a.then, a.components]` gives `function` and `undefined` | An `undefined` field and an error further on, with nothing at the call site pointing to the missing `await` | A sentence in the skill's contract that `recipes` is async; a sink error when a body reads a field of a pending recipe answer | | +| **`g.resolveEntryAddress` returns no wording, file or line, and names slots unlike `ruleKeys`.** It answers `{ entry, resolves, reason }`; `entry` is a slot such as `rule[4]`, which `sections.behavior.ruleKeys` writes `rules[4]`. A key in the wrong section fails with a one-word reason | `const id = "spec:consumers.agent-surface"; return [g.resolveEntryAddress(id + "#rule.entryAdapters"), g.specContext(id).sections.behavior.ruleKeys.entryAdapters]` gives `entry: "rule[4]"` and `"rules[4]"`; `g.resolveEntryAddress("spec:consumers.reference-projection#rule.namedOutsideReader")` gives `reason: "section"`, though the key resolves as `#question.namedOutsideReader` | To quote an address with its line, agents grepped carriers for the key or hand-joined `ruleKeys` with `entryLocations`, translating slot names. Address resolution (recipe 25) returns the value, file and line, but agents reach for the reader join first | A skill line sending quote checks to recipe 25; one slot naming across `ruleKeys`, `entryLocations` and the join; file and line on the join's answer, or a reason naming the section where the key does resolve | | +| **The two concept searches disagree, and neither says what it did not search.** `g.findByConcept`, which concept search (recipe 6) wraps, matches a literal substring of ids, titles, labels, framing, narrative and sections; entry search (recipe 23) matches whole tokens, splits camelCase and drops punctuation | For `accessib`, `localStorage`, `growByRecipe`, `graph only` and `--runs`, compare `g.findByConcept(t).length` with `(await recipes(23, { term: t })).totals.matches`: the stem is found only by substring; the camelCase word, the rule key and the phrase only by token; `--runs` becomes `runs` and matches hundreds of entries. `g.findByConcept("role vocabulary")` misses `spec:protocol.role-vocabulary`, and `decision readiness posture` finds nothing in either | An empty answer from one search reads as absence, and agents grepped `src/` or `specs/` instead. A common word floods: `owner` also matches prose ownership, a different sense | A catalog note on each search's matching rule, what it skips and when to try the other; a field in each answer naming its matching rule; spaces and hyphens treated alike in `g.findByConcept` | | +| **Entry search shows at most 50 rows, in Spec-id order, and takes no scope.** Concept search likewise lists 25 rows beside its total | `const q = await recipes(23, { term: "question" }); return [q.totals, q.matches.filter((m) => m.id === "spec:consumers.spec-studio.registers").length]` gives `shown: 50` of many more matches and `0` rows for a Spec with matching entries; adding a `spec` parameter gives `{ unknownParams: ["spec"], accepts: ["term"] }` | Filtering the rows to named Specs or a family silently drops matches past the cap, and agents concluded that a Spec held no such entry | A `specs` or `pack` scope parameter on recipe 23; a `leftOut` field, as the recipes taking `detail` carry; a catalog note that `shown` below `matches` means rows were cut | | +| **Large answers flood, and agents cut them with `head` or `slice`.** Concept search takes one term and has no summary mode; an unshaped `g.specs()` filter, the decision register (recipe 31), entry search on a common word and the architecture map (recipe 17) print tens to hundreds of thousands of characters | Recipe 17's shipped body with `--json` prints several hundred thousand characters. Recipe 53's answer cut with `head -c 600` no longer parses as JSON, while `return (await recipes(53, { pack: "pack:roadmap" })).roadmaps[0].entries.map((e) => [e.place, e.id])` prints a few hundred characters. `await recipes(6, { terms: ["owner", "stamp"] })` gives `unknownParams` | Invalid JSON, spent context, and a shell loop over recipe 6 that derives the graph once per term | A `detail` summary, as recipes 4, 29, 35 and 54 carry, on the large recipes; a list of terms for recipe 6; a catalog example looping `g.findByConcept` in one body; the skill's pre-shape rule repeated beside its recipe table | | +| **Reading one Spec through a recipe prints more than its carrier.** The guarantees recipe (recipe 3) returns each section's entries with their binding fields, as its law asks; the context bundle (recipe 36) adds more | With `--json`, recipe 3 prints about 1.4 times the bytes of the carrier of `spec:consumers.spec-studio.sharing` (its path is `g.specContext(id).file`), and about 1.6 times for `spec:model.open-question-fields`; recipe 36 over five Studio Specs prints more than twice their carriers. A body returning each Spec's outcome and rules from `g.specContext` is smaller than the carriers. Not reproduced for the design slice (recipe 54): its summary over the same five is smaller than their carriers | Agents went back to `cat` for "what does this Spec say", short of the answer-shapes outcome | A wording-only reading, as a recipe or a catalog body over `g.specContext`; a catalog note naming the leanest call for each question; answer size compared with carrier size in the recipe tests | | +| **The context bundle's budget counts compact JSON, but `--json` pretty-prints** | `const b = await recipes(36, { pack: "pack:spec-studio-v1", part: 1, budget: 40000 }); return [b.used, JSON.stringify(b, null, 2).length]` gives `used` just under the budget and a printed size about 1.4 times it | A part sized to fit a context overflows it once printed; the mining measured up to about 1.6 times | The budget counting the printed form; the catalog and the answer stating which form `used` measures; a compact `--json` | | +| **Floor clauses name no carrying Spec.** Promotion preflight and the lower ladder (recipes 9 and 11) name an unmet clause, such as `kind-evidence-present`, with a one-line description | `return (await recipes(9, { spec: "spec:carrier.sdp-import.feature-adapter" })).aboveStated.failures` gives the clause id and "The kind's natural evidence is present (per-kind evidence table)."; `g.findByConcept("kind-evidence-present")` returns two child Specs, not `spec:validation.kind-evidence` | One agent read `src/validate/readiness-floor.ts` to find the law behind a clause | The carrying Spec's id on each clause in the answer; a clause table in the catalog | | +| **Names the handbook and the skill use are not in the graph** | `return ["MD-22", "second-caller bar", "second machine consumer"].map((t) => g.findByConcept(t).length)` gives `0`, `0` and a non-zero count; entry search agrees. The [skill](../../.agents/skills/sdp-agent-surface/SKILL.md) uses both phrases for the same bar; the corpus uses only the second | Agents that met a registry number grepped [DECISIONS.md](../concept/DECISIONS.md); the skill's "second-caller bar" leads nowhere | For registry numbers, the options in the [log](#log)'s registry-name row; the skill's wording aligned with the corpus | | +| **The ratified glossary is outside the graph, and the searches do not say so.** [CONTEXT.md](../../CONTEXT.md) holds no node, and keyed Model terms sit in a small minority of Specs; words such as perspective, lens and stamp are not among them | `return [g.byFile("CONTEXT.md").nodes.length, (await recipes(6, { term: "ubiquitous language" })).total, Object.keys(await recipes(6, { term: "ubiquitous language" }))]` gives `0`, `0` and `term total matches`, though the glossary uses the phrase; no field says the glossary went unsearched | Agents read the whole glossary, tens of thousands of characters, or grepped it, after an empty search read as "no such concept" | A note in each search answer, or in the catalog, that the glossary is not searched; the glossary as a named input, as the log weighs for the decision registry; more keyed Model terms | | +| **Decision entries, Intent outcomes and narrative carry no location rows** | `const id = "spec:decisions.roadmap-priority"; return [g.specContext(id).entryLocations.map((l) => l.entry), (await recipes(23, { term: "priority" })).matches.filter((m) => m.id === id).map((m) => [m.entry, m.line])]` gives relation lines only, and `line: null` on every decision entry | A line cited in a decision Spec cannot be checked from the graph; agents read decision carriers whole | Location rows for decision entries, Intent fields and narrative; until then, a catalog note that these entries are never located | | +| **Address resolution (recipe 25) calls a bare Spec or Pack id malformed, and throws on a non-list** | `return (await recipes(25, { addresses: ["spec:consumers.reader", "pack:roadmap"] })).rows.map((r) => r.reason)` gives `malformed` twice, though both ids resolve; `await recipes(25, { addresses: "spec:consumers.reader#rule.x" })` exits 1 with `addresses.map is not a function` | Checking a document's citations needs a second, hand-rolled id check, and about half the tokens these design pages cite are bare ids; a wrong parameter ends the body instead of returning diagnostics | Bare ids resolved, or reported under their own reason apart from `malformed`; parameter diagnostics like the other recipes' | | +| **The design slice refuses everything when one id does not resolve, and ids and paths are guessed from each other** | `return await recipes(54, { specs: ["spec:consumers.reader", "spec:consumers.spec-studio.pack"] })` gives only `diagnostics`; the second id was guessed from the Pack manifest `spec-studio.pack.sdp.md`, which `g.byFile` names `pack:spec-studio-v1`. `g.byFile("specs/model/spec-envelope.sdp.md")`, a guessed path, answers like a file the graph records nothing at | One wrong id costs the whole slice; a wrong path reads as "nothing is recorded here" | The ids that resolve sliced and the rest listed; a near match in the diagnostic; `g.byFile` saying when no file exists at the path | | +| **One field name carries two shapes.** `design.openQuestions` is a list of questions on `g.packContext` members and a count on the design slice's member rows | `return [Array.isArray(g.packContext("pack:roadmap").members[0].design.openQuestions), typeof (await recipes(54, { pack: "pack:roadmap" })).members[0].design.openQuestions]` gives `true` and `"number"` | Code written against one surface iterates a number, or counts a list, on the other | A distinct name for the count; or a catalog note on the difference | | +| **Some empty answers do not say what they never looked at.** Entry citations (recipe 51) record citations only in files that carry a recognized anchor; the open-question register holds open questions, while a deferral is a decision Spec | `return [(await recipes(51, { specs: ["spec:consumers.spec-studio.shell"] })).totals.citations, g.byFile("test/self-hosting-oracle/consumers.ts").nodes.length]` gives `0` and `0`, though that test file cites `spec:consumers.spec-studio.shell#rule.stamp`. No open question mentions MCP, while `g.findByConcept("MCP")` returns `spec:decisions.mcp-deferred` | "Uncited" and "nothing rules on this" are read from answers that never looked | A field in recipe 51's answer naming what it does not scan; both cases among the skill's "Empty answers that mislead" (recipe 51's limit is stated only in its entry-address notes) | | +| **The handbook's "Next work" block runs a command with a side effect for a read.** It tells readers to re-run `sdp validate`, which enters the shared build and removes the five page roots | Not run here, because it would remove the generated pages. The effect is the law at `spec:consumers.wholesale-view-rewrite#rule.buildInvalidates` ("every command that enters this build, including validate ..."). `return report.findings.length` reads the same validation report through `sdp:q`, which writes nothing | A reader who wanted only the findings loses the Design Review, census, Mermaid, Gherkin and Studio pages until the next generation | The block reading findings through `sdp:q` (`report`, recipes 8 and 11), an edit to [AGENTS.md](../../AGENTS.md); or a validate mode that skips the build's removal | | + +## Agent on-ramp observations + +The frictions above are in the reader. These are in the on-ramp to it: the handbook and the skills +that should bring an agent to the graph first. They come from the owner's review of this design +session and from what the session itself did. Like every row on this page, they are considerations +for an engineering session; the owner marked the skills for the very next one. + +- **The mandatory order was not followed, even where it was read.** [AGENTS.md](../../AGENTS.md) + says to load the matching skill, then ask the graph, then read files. The main thread of this + session explored by text search and loaded `sdp-agent-surface` only after the owner insisted; the + first research workflow's brief listed graph queries last among its tools and never named the skill, + and its agents searched and read carriers far more than they queried the graph. Briefs that named + the skill and gave exact `sdp:q` bodies were followed. +- **The on-ramps are large single files.** Each repository skill is one `SKILL.md` with no disclosed + reference files, and the mandatory reading skill is several hundred lines; `AGENTS.md`, loaded on + every turn, is larger still. Steps such as "Bootstrap discipline" sit among long reference, so the + first thing an agent must do is easy to miss or to skip. Progressive disclosure (short steps in the + body, reference behind well-worded pointers) is the owner's direction. Measure with + `wc -c AGENTS.md .agents/skills/*/SKILL.md`. +- **The CLI's value needs a better pitch.** The first generation's fixed verbs suited earlier models; + a modern agent prefers its own ad hoc tools. `sdp q` is not a replacement for them but a complement: + the graph answers structure, claims, derived facts and its own blind spots in one call, and a text + search then reads the exact lines the graph points at. The on-ramps should say so, and promote the + CLI by showing that pairing rather than forbidding the other tools. A hook could force the order; + the owner prefers that the on-ramp earn it. +- **Specify work partly in graph queries, not only prose.** A brief, plan, task or cycle record should + carry the queries that define its scope and its evidence, so that whoever picks it up starts from + the graph. The design method applies this to design work ([09](09-design-method.md)); the same rule + could shape plans, arc records and agent briefs generally. +- **Orientation queries now open every session.** The owner's TODO in AGENTS.md asked for about ten + mandatory `sdp:q` queries that teach the practice and present the project. Eleven were drafted, + ranked by what the research agents actually needed, and each ran twice with identical output. By the + owner's choice, AGENTS.md carries a short "Orient before work" block, and the bodies live in + [`orientation.md`](../../.agents/skills/sdp-agent-surface/orientation.md) beside the skill, behind a + one-line pointer. Two considerations remain: the recipe tests do not run these bodies, and the + package's `files` list names each `SKILL.md` only, so the orientation file does not ship to + adopters. Whether it should, and in what adopter-neutral form, is an engineering decision. +- **The skills are outside the graph.** No Spec, anchor or concept search reaches the skill folder: + `g.byFile(".agents/skills/sdp-agent-surface/SKILL.md").nodes` and + `g.findByConcept("skills/sdp-agent-surface")` are both empty. The on-ramps that teach the graph + are themselves invisible to it, so nothing checks them against the law they teach. +- **The green gate reads operating-system files as projection drift.** On macOS, Finder writes + `.DS_Store` into a `generated/` folder that is open in a window. `--check-clean` reads every file in + a published root as a page, so `npm run check` failed with "generated Mermaid differs" and then + "generated Studio differs", and each failing check removed its root. The same tree passed in a + clean worktree. Ignoring such files when reading a published root is one option for an + engineering session. +- **Pending evaluation: map research output to the graph.** The owner's intended check is to take the + research run's findings and ask, for each, what the graph could have fetched directly. The + transcript mining above answers a neighbouring question (what agents needed while researching); + the output mapping would measure the graph's coverage of what the research concluded. + +## Evidence queries + +Each body runs in this checkout as `pnpm --silent sdp:q '' --json`. They answer at the commit +you run them on; re-run them rather than quoting an earlier answer. + +| Name | Body | What to read | +|---|---|---| +| *fields* | `return [...new Set(graph.nodes.flatMap((n) => Object.keys(n)))]` | every field any node carries; none names an owner | +| *deciders* | `return (await recipes(20, {})).specs.flatMap((s) => s.questions.map((q) => q.decider ?? null))` | the decider token on each open question | +| *actors* | `return g.specs().filter((s) => g.specContext(s.id).sections.intent?.actor).map((s) => s.id)` | the Specs whose Intent names an actor | +| *graph keys* | `return Object.keys(graph)` | the graph object holds no commit and no time | +| *reasons* | `const d = graph.edges.filter((e) => e.type === "decidedBy"); return { all: d.length, withReason: d.filter((e) => e.reason).length }` | how many `decidedBy` relations carry a reason; swap the type for another authored relation | +| *constraints* | `return g.specs().filter((s) => s.specKind === "constraint").map((s) => s.id)` | the constraint Specs; add `--root examples/checkout-v1` for the worked example | +| *rule keys* | `return (await recipes(48, { commit: params.commit })).totals` with `--params '{"commit":""}'` | `proposed` beside `entries`: the rule and flow entries with no key | +| *ui entries* | `return graph.nodes.filter((n) => n.sections?.ui).map((n) => ({ id: n.id, keys: Object.keys(n.sections.ui) }))` | the keys each UI section uses | + +Address resolution (recipe 25) checks every entry address this page writes: pass them as +`params.addresses`. An address that stops resolving was settled, renamed or moved; git says which. + +## A corpus home for these needs (a proposal) + +This is the one statement of the proposal; the [README](README.md), [06](06-design-cycles.md), +[08](08-what-the-repo-settles.md) and [09](09-design-method.md) point here. It is for an engineering +session and the owner. A design session does not make it, and none of it exists in the corpus yet: +concept search (recipe 6) finds no carrier for "persona", "role home", "basis line" or "object +page". + +- **A design Pack** named for the capability it designs, never a number or a date, holding `idea` + capture Specs that refine `spec:consumers.spec-studio`, or `spec:consumers.projections-model` for + a new projection. Candidate captures: the landing and arrival, the technical product manager's + entry reading, the flows *review a Pack for readiness* and *review a pull request's design + change*, and question pages. +- **Existing captures.** The Pack may list the captures already waiting on this work: + `spec:consumers.ai-assisted-reading` (its trigger names the UX design pass), and those held for a + named reader (`spec:consumers.reference-projection#question.namedOutsideReader`, + `spec:consumers.structural-mermaid#question.namedStructuralReader`, + `spec:consumers.projections-model.roadmap-views#question.releaseReader`). A persona from + [01](01-roles-and-perspectives.md) could become such a reader only through the owner. +- **Keyed questions in place of `proposed` and of 06's tables.** Each row above that needs a ruling, + and each long-horizon question in [06](06-design-cycles.md#design-questions-for-the-long-horizon), + becomes a keyed open question on the capture it bears on, blocking where it holds that capture, + with `decider: owner`, the current lean as its `provisional` line, `links` to the Specs or entries + it rests on, and a `trigger` only where it waits on evidence from a design cycle. A ruling that + passes the three-part decision test becomes a decision Spec below `ready` that the shaped Specs + name through `decidedBy`. +- **What comes with it.** The self-hosting obligations every new Spec carries; candidate words + flagged in `CONTEXT.md`'s Flagged ambiguities; new jobs written as job stories, paired with + personas in the design material. +- **A slimmer log.** Once those land, a row keeps only its need, its evidence and its question's + address, and the question's state is read from recipe 20 and the Studio's questions page. +- **No priority and no roadmap entry.** The Pack takes no `order`: the roadmap stays the one place + for priority, and a capture landing adds nothing to it + (`spec:protocol.roadmap-replaces-plans#rule.oneRoadmap`). The design Pack joins `pack:roadmap` + only on the owner's word. +- **Precedent.** `pack:obsidian-vault-v1` began as `idea` captures with a throwaway prototype as + their cited evidence (commit `1b014d01`); its members all state `ready` today (Pack design, + recipe 29, over that Pack). + +| For | Against | +|---|---| +| The project becomes readable by its own readings: the open-question register (recipe 20), the statement queue (recipe 46), the Studio's questions and owner queue pages, and Pack design, the design slice and the design diff (recipes 29, 54 and 35), as the [handbook](../../AGENTS.md) asks of an arc's Pack | Each capture brings the self-hosting obligations: membership in `pack:self-hosting-v1`, the self-hosting oracle tests and the green gate (`npm run check`), so each costs engineering time | +| Questions carry who decides, the provisional reading and the trigger with no hand-kept status; the question tables in 06 stop being a register beside the graph | A capture names a reading before the cycles show it is needed; `idea` is cheap and lawful, but unneeded captures must later be withdrawn | +| The design project uses the readings it designs | Its open questions join everything the self-hosted corpus reports to every reader of it | +| | 06's question tables and this log's `proposed` rows must retire in the same change, or they become a second register | + +Other options stay open: keep the design questions in [06](06-design-cycles.md) until evidence +settles them, as today; or keep a person's long-running notes in a vault's `intent/` folder, outside +the delivery record (`spec:consumers.obsidian-vault.iteration#rule.composeHome`). Whether a corpus +home is wanted, whether it is one Pack or several, and where exploratory commercial Studio design +intent is recorded stay open +([06](06-design-cycles.md#the-design-project-and-visual-design)). diff --git a/docs/design/08-what-the-repo-settles.md b/docs/design/08-what-the-repo-settles.md new file mode 100644 index 00000000..c3615cbb --- /dev/null +++ b/docs/design/08-what-the-repo-settles.md @@ -0,0 +1,547 @@ +# 08 — What the repository settles + +This document answers the technical questions the design work raised, one section per question, +from the repository's intended truth: the carrying Specs, [`CONTEXT.md`](../../CONTEXT.md) and the +concept documents, each claim confirmed against the graph with `sdp q`. It is design material, not +intended truth: where it disagrees with a carrying Spec, the Spec wins. + +Each section gives the question in one line, the answer, the governing text, and what stays open. +The answers were checked against the graph at commit `53804437`; re-run the queries rather than +trusting this page as the corpus changes. Counts are never quoted: where a number matters, the +section names the query that derives it. "What stays open" points to the part of +[06](06-design-cycles.md#design-questions-for-the-long-horizon)'s register that carries the design +and product judgement a section leaves. Those questions form a long-horizon research backlog for +the design cycles ([06](06-design-cycles.md), [09](09-design-method.md)), not owner to-dos to settle +now. + +| Section | The question in short | +|---|---| +| [1. Ownership and people](#1-ownership-and-people-in-the-model) | Does the model record owners, and where does approval live? | +| [2. Terminology](#2-terminology) | Do the provisional design words collide with ratified ones? | +| [3. History](#3-history-beyond-one-commit) | May a reading show history beyond one commit? | +| [4. View state and commercial surfaces](#4-view-state-and-commercial-surfaces) | What state may a surface keep, and what would new surfaces inherit? | +| [5. Object pages and deep links](#5-object-pages-and-deep-links) | Which things get pages, and how does an address become a link? | +| [6. Perspectives and AI](#6-perspectives-and-ai) | Can the Studio take a perspective, and may AI shape a reading? | +| [7. How the Studio may evolve](#7-how-the-studio-may-evolve) | Which Studio changes are ordinary Spec edits, and which need a decision? | +| [8. Recording a long design effort](#8-recording-a-long-running-design-effort) | Where do months of design intent and questions live? | + +## 1. Ownership and people in the model + +**The question.** Does the model record who owns a Spec or approves a change, and does anything +rule ownership out? + +**The answer.** + +- **No decision rules out a descriptive owner; the model simply holds none.** The seed design gave + a Spec and an open question an optional `owner` and kept "Roles / RBAC" out on purpose + ([seed 01](../lineage/v0-design/01-core-primitives.md), section 10). The reboot (commit `ed5f6ad3`) + dropped `owner` without comment. `tags` was dropped through a plan item (commit `4e5cfa13`), + carried into the language ratification (`857e1077`) and applied in `7140c3dc`; that plan was later + deleted, so git is the only record. A later doc repair (`71334fda`) brought the concept vision in + line with the model ("a Spec names no owner"). It matched the model; it did not weigh descriptive + ownership. +- **The only person-shaped graph field is an open question's `decider`.** It is a lowercase kebab + token the corpus owns, on the grammar a role uses. It references nothing, authorizes nothing and is + compared with no author, and the Protocol ships no list of values. A value off that grammar is a + conformance error. +- **Shipped defaults favour the token `owner`.** The statement queue (recipe 46) and the roadmap + (recipe 53) default `params.decider` to `"owner"`. The Studio's Queue page renders recipe 46 with + that default, so it lists only `owner` questions. Its waiting statements are corpus-wide and + belong to no one; only the questions are selected by decider. Any other token works on the agent + surface through `--params '{"decider":"…"}'`. +- **Nearby, but not ownership.** The Intent `actor` is prose naming whom a Spec serves, carried by + a small minority of Specs. Pack framing is a plain descriptive note. A Pack's `order: priority` is + read as "its owner's advisory preference" and names nobody. The anchor `role` is an architectural + pattern, and `decider` is also one of this corpus's role values + (`spec:protocol.role-vocabulary#term.decider`). "The owner" appears across the Specs and the + [handbook](../../AGENTS.md) as one corpus-level person in prose (the readiness planner's actor is "The owner of a + corpus"), but it is neither a graph value nor a `CONTEXT.md` term. +- **Approval lives outside the model.** Change approval is git and CI: pull request review and + CODEOWNERS (this repository keeps no CODEOWNERS file). A baseline's approval artifact is a signed + git tag. `ready` is a person's declared edit, and that a review occurred is never a graph fact. A + change proposal carries no status, approval or proposer. In this repository, rulings "with who + made them" go in pull request descriptions (the roadmap-over-plans decision, MD-47). +- **What is ruled out** is ownership as authorization, a gate or workflow state. A descriptive owner + would reverse the concept vision's current statement and, as an envelope key, would meet the + closed envelope and the stability law L9, under which new capability arrives as sections, not + envelope keys. A decision Spec is the honest route. Today a frontmatter `owner:` or `tags:` is + refused as `extract/unrecognized-property`; in a Gherkin carrier a free tag such as `@team-x` is + decoration and authors no graph state. The prose-ownership law (MD-19) concerns prose on typed + graph owners, not people. + +**Re-check.** Deciders in use, and how many Specs carry an `actor`: + +```bash +pnpm --silent sdp:q 'const r = await recipes(20); const by = {}; for (const s of r.specs) for (const q of s.questions) by[q.decider ?? "none"] = (by[q.decider ?? "none"] ?? 0) + 1; return by' --json +pnpm --silent sdp:q 'const specs = graph.nodes.filter((n) => n.nodeType === "Primitive"); return { withActor: specs.filter((n) => n.sections?.intent?.actor).length, specs: specs.length }' --json +``` + +**Governing text.** + +| Source | What it says | +|---|---| +| [Concept vision](../concept/00-vision-scope-and-mvp-boundary.md), section 5 (Non-goals) | "Not an embedded RBAC / governance engine. Change approval lives in git/CI (PR review, CODEOWNERS); a Spec names no owner, and an open question's `decider:` names who settles it, never an authorization." | +| `spec:model.open-question-fields` (Behavior) | "Who decides a question names the person, role or body whose ruling settles it. It authorizes nothing, gates no edit, and no validator compares it with the author of a change." "The graph holds no person or role to point at, so the value references nothing." | +| `spec:carrier.envelope-contract#rule.reservedProperties` | An unknown envelope key is refused "as `extract/unrecognized-property`"; the key set "is closed" (same Spec, Behavior). | +| `spec:consumers.spec-studio.spec-page.core#rule.header` | "It shows no owner, capability, tag or last-verified time: the envelope holds none." | +| `CONTEXT.md`, Validation & honesty; Delivery-process vocabulary | "that a review occurred is never a graph fact"; a baseline's "signed git tag is the approval artifact — approval remains outside the model". | +| `spec:consumers.intent-composition.proposal` (Behavior) | "A proposal carries no status, approval or verdict"; "A proposal carries no proposer." | + +**What stays open.** Carried in 06's register, under [People and +entry](06-design-cycles.md#people-and-entry). + +## 2. Terminology + +**The question.** Do the design pass's provisional words collide with ratified or Studio vocabulary, +and what governs coining a word? + +**The answer.** + +- **The rubric.** `CONTEXT.md` governs: adopt the established delivery noun; coin a word only for a + genuine differentiator, and make the word name the difference; pass both naming tests (carry + epistemic status where it matters, and be unambiguous to typed code, the coding agent and a + Studio user). One concept takes one word; the rest are aliases to avoid. The handbook adds: flag a + new word, never silently invent one. The adopt-the-nouns decision (MD-2) carries the rubric. +- **How a word becomes shared vocabulary.** The owner rules it. "Perspective" landed through a + carrying Spec (`spec:consumers.review-perspectives`, whose narrative records the ruling) plus a + `CONTEXT.md` row and ledger entry. A shipped Studio element name follows `stamp` and + `text equivalent`: a Surfaces & projections row plus a carrying Spec. `CONTEXT.md`'s + guidance-only labels name particular design activities and recipe answers (design pass, design + diff, design slice and a few more); they are not a general home for unratified words. +- **The provisional words.** The [README](README.md#words-used-here) records how each is used for now; + the collisions the repository shows are these: + +| Word | What it collides with | What the repository shows | +|---|---|---| +| **reading** | fixed phrases: reading order and the roadmap answer's `order` value `"reading"` (`spec:consumers.roadmap#rule.readingOrder`), a question's provisional reading, the reading skill, the context bundle's reading material | Already plain corpus prose: "A design slice is therefore a reading and not an artifact" (`spec:consumers.design-slice`). Fine in design prose; not a label or a locked term. Exact nouns: projection, page, page set, recipe answer. | +| **persona** | nothing ratified; but the job stories bind to no persona, and "richer persona surfaces" are deferred and not backed by stories ([job stories README](../../jtbd-stories/README.md)) | The concept vision speaks of "multi-persona consumption". A design-material word, paired with job stories. A Spec names whom it serves through its Intent `actor`; the graph holds no person. | +| **role home** | the ratified `role`, an anchor's architectural pattern (the architectural-annotation ruling, MD-38), shown on the same Studio pages | The index is already "the default landing page" (`spec:consumers.spec-studio.lenses#rule.order`) with task routes (`spec:consumers.spec-studio.index-page#rule.taskRoutes`); selection by concern is a perspective. The idea stays a candidate; the name collides. | +| **object page** | the Studio's own names: Spec page, Pack page, slice page | Prefer "*thing* page". Some candidates contradict `ready` rules: the page set holds no code-unit page, a Pack has a Pack page and a slice page, and only a keyed question has an address ([section 5](#5-object-pages-and-deep-links)). | +| **basis line** | the stamp and its stamp line (`spec:consumers.spec-studio.shell#ui.stampLine`); "basis" for the dependencies a `ready` statement rests on (`spec:validation.typed-dependency-floor`); "base" (base graph, `--base`) | Collides twice, and "always present" contradicts `ready` rules: the build writes no stamp, a `file://` page shows none, an export holds none. The need, saying what a reading projects, stays real ([section 4](#4-view-state-and-commercial-surfaces)). | +| **design session** | the handbook's "design session", which designs Specs and "edits carriers" | In this project, by the owner's rule, a design session edits no graph input and records needs in [07](07-graph-needs.md) for engineering sessions. One phrase, two activities: say which where it matters. | + +- **Words the base already settles.** `status` is an alias to avoid for readiness, for question + fields and for a roadmap need. `abstraction`, "two axes", `Facet` and `provenance` (as a claim) + are rejected; the seed name `UiFacet` is fine as an attributed citation. `claim` is reserved, so + readiness is stated, never claimed. "Lens" names only the Studio's graph views and is an alias to + avoid for perspective; "discipline" is the kind-or-section filter, never a phase. "Census" is the + `sdp census` projection, not a summary on the index. "Dashboard" and "view" are plain words the + founding principles use and the base does not reject; `sdp view` is the Design Review's verb. + "Built" already carries several senses (the roadmap need `built`, the architecture lens's + "Designed, not built" section), so it makes a poor word for where a thing stands. A delivery fact is never "a + readiness rung", so a phrase that files delivery facts under readiness misleads. + +**Governing text.** + +| Source | What it says | +|---|---| +| `CONTEXT.md`, Governing rubric | "Adopt the established delivery noun … Coin/keep a distinct word only for a genuine differentiator — and then the word must name the difference." Two naming tests follow. | +| `CONTEXT.md`, opening note | "one concept → one word; the rest are aliases to avoid." | +| The adopt-the-nouns decision (MD-2, `spec:decisions.adopt-the-nouns`) | "Invented terminology taxes users"; "Terms must be concrete, unambiguous, and carry authored-versus-derived status where it matters." | +| `spec:consumers.review-perspectives` (narrative) | "The owner ruled the word: perspective. The Spec Studio keeps lens for its graph views." | +| `CONTEXT.md`, the `role` row | "the optional one-token value on a code anchor … naming the architectural pattern its unit plays (`service` · `decider` · `projection` · …)". | +| [Job stories README](../../jtbd-stories/README.md) | Stories capture the job "without binding to a persona"; "Richer persona surfaces … are deliberately deferred post-MVP and are not yet backed by stories." | + +**What stays open.** Carried in 06's register, under [Words](06-design-cycles.md#words). + +## 3. History beyond one commit + +**The question.** May a reading show history (discipline activity over time, question age, a +readiness trajectory, dated decision lineage), and what would it take? + +**The answer.** + +- **Yes, as named input beside the graph; never inside it, and never as a gate.** The graph is the + current projection of the repository at one commit, and git is the event log. To see a past state, + check out the prior commit and regenerate. +- **Consumers do not read source.** Founding principle P2 makes the extractor the only component + that reads source. So a history reading consumes graphs `sdp build` wrote at named commits, and the + caller or CI does the git work. That is already the design diff's pattern: the base graph is input + the caller holds. The repository's preview workflow does exactly this, building the base commit in + a worktree and passing it as `--base`. The engine-provenance rule "never runs git at run time" + governs only how `--version` learns its commit; it is not a general ban. +- **Ready Studio rules a history reading would revise:** the Studio reads "only two optional inputs" + (`spec:consumers.spec-studio#rule.namedInputs`, `spec:consumers.spec-studio.data.inputs#rule.namedInputs`); + the shell "shows no recent edits and no other history" (`spec:consumers.spec-studio.shell#rule.noRecentEdits`); + an open question "shows no date" (`spec:consumers.spec-studio.spec-page.core#rule.questions`); and + the diagram catalog refuses git graphs, timelines, trends and Gantt charts until a ruled history or + time-series input exists (`spec:consumers.spec-studio.diagram-kinds`). +- **None of these limits an operator's `sdp q` body.** A series of graphs passed with + `--params KEY=@PATH` (`spec:consumers.agent-surface.recipe-parameters`) can be read today, so a + history reading can be prototyped on the agent surface before anyone writes a Spec, for example by + writing graphs at successive commits and running the design diff (recipe 35) over each pair + through the package's exported `evaluateBody`. +- **What a history reading must satisfy.** It takes its history as named input: graphs written at + caller-named commits, plus any commit metadata the caller states. It names that input and its range + in words wherever it shows (`spec:consumers.spec-studio.data.inputs#rule.inputNaming`). It is + byte-deterministic over its inputs (`spec:extraction.determinism`). It confers nothing: no fact, + finding, rung, staleness flag or gate; the design diff "raises no staleness flag", run evidence is + never called fresh or stale, and an open question carries no date. It stays out of the validators + and the four frozen projections. It respects identity limits: ids carry no history + (`spec:model.stable-ids`), a `supersedes` chain exists in a graph only while both records exist, and + an entry without a key has no identity across two graphs. +- **Decision or Spec.** A Studio reading or recipe over supplied graphs needs a new carrying Spec and + ordinary revisions of the rules above; the precedent is `spec:consumers.spec-studio.register-input`, + a `scoped` story adding a third named input. History inside the Design Review, census, Mermaid or + Gherkin needs a decision refining the shipped-projections decision (MD-32). History inside the + graph, or history as a gate, is refused by founding law. A consumer reading `.git` itself would + contradict P2; a decision is the likely vehicle, though the repository does not say so. One + tension stays held: `spec:consumers.projections-model.roadmap-views` is titled "Roadmap views read + releases, baselines and phases from git and the graph" without saying how git reaches the view, + and its deferral (`#question.releaseReader`) waits for the first published release. + +**Re-check.** Nothing history-related is on the roadmap: + +```bash +pnpm --silent sdp:q "$(cat dist/recipes/53-the-roadmap.js)" --params '{"pack":"pack:roadmap"}' --json +``` + +**Governing text.** + +| Source | What it says | +|---|---| +| `spec:extraction.derive-graph` (narrative) | "The graph is the current projection of the repository at a commit. Git holds lifecycle history, so removed records disappear from the current graph." | +| [Founding principles](../concept/01-founding-principles-and-invariants.md), P2 | "recipes and views whose contracts admit it may read separately identified input beside it, while validators and shipped projections stay graph-only. No consumer reads source directly or maintains a parallel model." | +| `spec:consumers.design-diff` (Behavior) | "The base graph is input the caller holds, derived from the repository alone at the base commit; it never answers in the graph's name"; a comparison "raises no staleness flag". | +| `spec:consumers.spec-studio#rule.namedInputs` | "Beside the graph the Studio reads only two optional inputs, a base graph and run records." | +| `spec:consumers.spec-studio.diagram-kinds#design.gitGraph` | "commits and branch ancestry are not nodes in the current graph. Re-enter with a ruled history input and a history reader." | + +**What stays open.** Carried in 06's register, under [History](06-design-cycles.md#history). + +## 4. View state and commercial surfaces + +**The question.** What state does the static Studio keep, what separates view state from delivery +truth, and what would a hosted, desktop or CI surface inherit? + +**The answer.** + +- **The static Studio keeps one thing between visits:** the composing panel's gathered intents, in + the browser's local storage under `sdp-studio:intents:`, so two page sets on one host + never share them. Nothing else is stored: the panel's base and reason fields, filters and open + disclosures are lost on reload, and a search keeps its term in the URL fragment + (`search.html#q=`). The panel "requests nothing over the network", and the only request any + element makes is the stamp element fetching `stamp.json` over http or https; through `file://` + nothing is requested. +- **What separates view state from delivery truth.** Every view is a pure function of the + repository with no parallel model (P1 to P3). The Studio never builds a second graph: every join, + claim, fact and floor it shows was computed at build. A view composes scoped intent and an agent + makes the ordinary edit under the same checks; a composing surface writes no source. Named inputs + never become graph data, a fact or a rung. A proposal carries no status, approval or proposer, and + a review is never a graph fact. A perspective is corpus data, passed as a parameter. +- **The MCP surface** is "integration for user-facing apps (designed-in, deferred build)", distinct + from the agent surface. The MCP-deferred decision (D6) holds it until "a concrete caller + establishes its boundary and contract". It is not on the roadmap. +- **Commercial surfaces.** Intended truth holds one line: the read-only Studio ships in the + open-source package, and "hosted review, shared comments and hosted previews may later ship under + `@libar-ai/`" (`spec:consumers.spec-studio`). `CONTEXT.md` and the handbook record the namespace + split, and the package is licensed Apache-2.0. Concept search finds nothing on "commercial", and no + Spec mentions a desktop app, a commercial web app or a commercial CI surface. Those come from the + owner's framing in [PRODUCT.md](../../PRODUCT.md): the core is and stays open source and free, and + a commercial Studio (desktop, web, CI/CD) is under consideration, exploratory and labelled as + such. "Hosted previews" is undefined in the corpus; the open-source preview workflow already + deploys to an adopter's own static host. +- **The existing CI surface.** The repository ships a reusable GitHub Actions workflow that runs + `sdp studio` with optional base and run inputs and stamps the checked-out merge commit + (`spec:consumers.spec-studio.sharing#rule.previewWorkflow`). It deploys a preview only when the + caller asks, and never from a fork (`#rule.previewDeploy`). +- **What any new surface inherits.** One canonical repository and one graph, no second store. Claims + never collapsed; delivery facts derived. One change-proposal contract, and no source writes from a + view. Named inputs that never move a rung. Run evidence at test-file grain, never called fresh or + stale. Protocol checks that judge only conformance and honesty; an adopter's own gate runs as + corpus rules (`sdp validate --rules`) and reaches no projection. Perspectives stay corpus data. + MCP waits for a named app caller. A host that embeds Studio elements also inherits the + build-renders decision (MD-43, no graph data from the host) and the custom-elements decision + (MD-42, element names and attributes as a public contract). +- **What belongs to the static Studio alone:** no server and `file://` opening, one classic script, + the search index embedded only on the search page, the stamp read only over http or https and + absent from exports, local storage keyed by page-set path, and "opens no pull request" because "a + static page holds no credentials". +- **Per surface, exploratory.** A hosted web app may hold credentials but still writes no carrier + itself; review threads or preferences would be its own product state, never projected back as + graph truth; running user-supplied bodies server-side meets the evaluation sink, which "claims no + sandbox". A desktop app over the working tree largely exists in open-source form already + (`sdp studio --watch` on carriers, `sdp vault --watch`, `sdp validate --watch`); the working-tree + graph includes uncommitted edits, and no "uncommitted" signal exists. "Studio local mode" is an + alias to avoid for the vault. A CI surface would extend the reusable workflow: its basis is the + merge commit, a run record joins only at file grain, and trends across runs would need new Specs. + +**Governing text.** + +| Source | What it says | +|---|---| +| `spec:consumers.spec-studio.intent-panel#rule.persist` | "Gathered intents persist in the browser's local storage under the page set's own key … two page sets served from one host never share intents." | +| `spec:consumers.spec-studio.page-elements#rule.noRequest` | "No element requests anything on a page opened through `file://`; the stamp element requests `stamp.json` only over http or https." | +| `spec:consumers.spec-studio#rule.noSecondGraph` | "The Studio never builds a second graph … the page computes none of them again." | +| `spec:consumers.spec-studio` (Behavior) | "The read-only Studio ships in the open-source package `@libar-dev/software-delivery-protocol` … hosted review, shared comments and hosted previews may later ship under `@libar-ai/`." | +| The MCP-deferred decision (D6, `spec:decisions.mcp-deferred`) | "MCP integration is deferred until a concrete caller establishes its boundary and contract." | +| `spec:consumers.agent-surface.evaluation-sink#rule.exportedEvaluator` | "the evaluator writes and prints nothing and claims no sandbox, as the sink claims none." | + +**What stays open.** Carried in 06's register, under [Commercial +surfaces](06-design-cycles.md#commercial-surfaces-exploratory) and [Basis and +trust](06-design-cycles.md#basis-and-trust). + +## 5. Object pages and deep links + +**The question.** Which things get a page of their own in the Studio, how does an entry address +become a link, and how do source links work? + +**The answer.** + +- **Only Specs and Packs get pages of their own.** Each Spec has one page, `specs/.html`, and + decision records are Specs, so every decision already has its page. Each Pack has a Pack page + (`packs/.html`), a slice page (`slices/.html`) and a one-file export + (`exports/.html`). Every other page is a collection: the index (the Packs lens), the other + lenses, the register pages, the Queue, the roadmap, the glossary and search; Diff and Runs exist + only when the build is given their inputs. +- **Entries, questions and terms carry element ids on their Spec page.** The element id is the + address after the `#`: `design.`, `ui.`, `rule.`, `question.` or `term.`. + These address section names are not Spec section names: `rule.` covers the Spec's primary + behavior owner, and `question.` the open questions in Intent. A Spec page also carries ids for its + narrative, each section (`section.`) and each panel (`panel.verification` and the rest). +- **An entry without a key has no address.** The closest link is its section. Many rules and flows + are still unkeyed (the rule-key proposal, recipe 48, proposes keys for them); every open question + is keyed today (recipe 20). +- **Components, code units and anchors.** Each realized component has a detail section on the + architecture lens, with its id as the element id. By `ready` intent, code units and test or + oracle anchors get no page and no element id; they show as an id plus `file:line` text with a + copy action, and appear in search results. +- **From address to URL** is pure construction: `spec:#
.` becomes + `specs/.html#
.`, where `` is the id after its namespace with each + uppercase letter written as `_` plus its lowercase. Inside a Pack export, ids take a `pack/` or + `/` prefix. Nothing in the Studio resolves a pasted address: search matches what + `findByConcept` matches, plus Design, UI, question and rule keys and file paths, and "indexes + nothing else". +- **Source links come only from the publishing stamp.** `sdp stamp --source TEMPLATE` names a URL + holding `{file}` and optionally `{line}`; served over http or https with that stamp loaded, each + recorded file and line becomes a link. The CI workflow uses + `//blob///{file}#L{line}`. Without a template, through + `file://`, or in an export, a location stays text with its copy action. No page writes an editor + link. +- **Navigation is ready law, not free layout.** The top navigation's entries and order, the + current-page marking and the index's `Start here` routes are rules in + `spec:consumers.spec-studio.navigation` and `spec:consumers.spec-studio.lenses`. + +**Governing text.** + +| Source | What it says | +|---|---| +| `spec:consumers.spec-studio#rule.staticPageSet` | "The Studio is a static page set: the index page, which is the Packs lens; a search page; a page for each other lens, each register, the owner queue, the roadmap and the glossary; one page and one slice page per Pack, one page per Spec; one export file per Pack." | +| `spec:consumers.spec-studio.spec-page.core#rule.entryIds` | "Every entry an entry address can name … carries an element id equal to its address after the `#`." | +| `spec:consumers.spec-studio.spec-page#rule.sourceText` | "the page set holds no code-unit page and writes no editor URI, absolute path or assumed source URL." | +| `spec:consumers.spec-studio.publisher#rule.linksResolve` | "Every link a page writes stays inside the page set," apart from the search page's term fragment. | +| `spec:consumers.spec-studio.sharing#rule.sourceLinks` | "when a loaded stamp names a source template the stamp element links each to the template … without such a stamp, or through `file://`, each stays text." | +| `spec:consumers.spec-studio.search#rule.addedFields` | Search also matches coined keys and file paths. "It indexes nothing else." | + +**What stays open.** Carried in 06's register, under [Landing, navigation and +pages](06-design-cycles.md#landing-navigation-and-pages), [Basis and +trust](06-design-cycles.md#basis-and-trust) and, for editor links, [Commercial +surfaces](06-design-cycles.md#commercial-surfaces-exploratory). + +## 6. Perspectives and AI + +**The question.** Can the Studio render or take a perspective, what does the AI-reading capture say, +and may AI author a reading's selection or its generator? + +**The answer.** + +- **Not today.** The Studio reads only two optional inputs (a base graph and run records), the + build's fixed recipe list leaves out the perspective filter (recipe 37), and `sdp studio` takes no + perspective. A perspective works on the agent surface: `sdp q` runs recipe 37 with `pack` and + `perspective`, and the selected members feed the context bundle (recipe 36) and the design slice + (recipe 54). A Studio perspective input would be a Spec change like + `spec:consumers.spec-studio.register-input`, not a UI choice. +- **The AI-reading capture.** `spec:consumers.ai-assisted-reading` is a behavior story stated at + `idea`, with no delivery facts. Its outcome: "Let a reader ask for a useful existing reading and + inspect why it was selected and what scope it omits." Its blocking question, + `#question.aiPresentationBoundary`, asks what contract keeps assistant-generated "explanations or + arrangements beyond selecting deterministic readings" distinct from graph claims and reviewable. + Its decider is `owner`. Its provisional reading allows selection only, and its trigger is "the UX + design pass measures that assistant selection or a generated explanation helps a named review + task". So this design effort's measurements are the evidence that brings it back; the owner still + decides. +- **Precedents for code that runs over the graph.** The agent surface grows by recipe: "every other + question stays a body an agent scripts", run with operator trust and no sandbox (the agent front + door, MD-22). Corpus rules are code the corpus authors, run only from a file the operator names, + reading only the graph by the author's obligation, and reaching no projection. The vault began as + a prototype under `explorations/` that wrote notes from dumped graph and reader values; the + prototype stayed evidence, and the vault the engine ships was built from carrying Specs. Any + agent's code lands as an ordinary git edit under the same checks. +- **No seam publishes corpus- or agent-written code into a Protocol page.** `recipes()` runs only + bodies the package ships, "never from the corpus or the working directory", and a Studio page shows + a recipe answer only when the Studio's design names that recipe. +- **Adding projections.** No rule names who may add one. A projection is a pure function of the + graph, implementation waits for a `ready` Spec (the drift alarm flags `implemented ∧ ¬ready`), the + Studio and the vault each arrived with carrying Specs and decisions, and the shipped-projections + decision (MD-32) freezes only the Design Review, census, Mermaid and Gherkin. +- **"AI authors the selection; the graph supplies the content"** fits current law for selection, + and for a perspective passed as data on the agent surface. A generator an agent writes is ordinary + source under the edit model and needs a carrying Spec stated `ready` before it is a Protocol + reading. The provisional reading allows only selection, so the principle is a candidate answer to + the blocking question, not current law. The [AI article](../articles/05-ai-can-shape-the-reading.md) + explores the generator pattern as one option; it is direction material, not intended truth. + +**Governing text.** + +| Source | What it says | +|---|---| +| `spec:consumers.ai-assisted-reading#question.aiPresentationBoundary` | Provisional: "Select existing deterministic readings only; any generated text stays outside the Studio and the frozen projections, labelled as assistant output with its source commit and scope, and adds no claim, fact or validator." | +| `spec:consumers.spec-studio.data.recipe-answers#design.recipeEvaluations` | The fixed list of recipes a build evaluates; the perspective filter is not among them. | +| `spec:consumers.review-perspectives` (Behavior) | "The corpus owns its perspectives and their questions; the Protocol supplies the filter and ships no list of perspectives." | +| `spec:validation.corpus-rules#rule.operatorNamed`, `#rule.neverMovesFloor` | Rules run "never from a file it finds in the corpus"; a corpus finding "reaches no other surface". | +| `spec:consumers.agent-surface.evaluation-sink#design.recipeSource` | A call runs the shipped body, "never from the corpus or the working directory." | +| `spec:consumers.edit-model#rule.agentEdits` | "The agent edits source as a human would, git records the ordinary edit, and the same conformance and honesty checks evaluate it." | + +**What stays open.** Carried in 06's register, under [AI-assisted +reading](06-design-cycles.md#ai-assisted-reading); the wider option space is in +[05](05-specialised-and-ai-readings.md). + +## 7. How the Studio may evolve + +**The question.** Which Studio redesigns are ordinary Spec revisions, and which need a decision +Spec? + +**The answer.** + +- **The shipped-projections decision (MD-32)** freezes the Design Review, census, Mermaid and + Gherkin. Reshaping one needs a decision that refines or supersedes it, never a follow-up work + item. It does not freeze the Studio, which publishes to its own root beside them. +- **The derived-HTML decision (MD-41)** makes the Studio's surface generated HTML that is never + committed. It stands beside the Markdown Design Review, and "neither view ranks above the other". + Richer interactions wait for their own Specs; the first build is read-only. +- **The other Studio decisions:** custom elements without a framework, with element names and + attributes as a costly public embedding contract (MD-42); the build renders every view and an + element only enhances it (MD-43); diagrams laid out at build time as inline SVG with a text + equivalent (MD-44). Studio Specs also name, through `decidedBy`, the architectural-annotation + ruling (MD-38), binding, never liveness (MD-7), verification posture, not realization (MD-23), the + authored-entry-order decision and the shipped-projections decision. +- **Behaviours `ready` Specs fix:** the Spec page's panels in a fixed order; the lenses in a fixed + order (Packs, capabilities, architecture, tests, evidence), with the index as the Packs lens and + the landing page; the top navigation's entries; the same pages serving desktop and phone, one + column below 720 CSS pixels; a text equivalent for every diagram; and one classic script whose + elements only enhance. Almost every Studio Spec is `ready` and implemented; only the Studio Specs + on the roadmap sit lower (the first query below lists them). +- **How these change.** A behavior rule homed on a carrying Spec changes by ordinary Spec revision + (the planning-truths decision, MD-33, says so for a restated guarantee); commit `332204a2` + revised the lens order and the navigation entries that way. So reworking navigation, the landing + page, entry for delivery roles, or merging and retiring pages is ordinary Spec revision, made in + an engineering session, as long as the result stays derived, rendered at build and + framework-free. Richer interactions arrive through their own Specs (the derived-HTML decision, + MD-41). +- **A change needs a decision Spec when it:** commits the HTML, or lets the Studio replace or + outrank the Design Review (the derived-HTML decision, MD-41; the shipped-projections decision, + MD-32); renders views or switches readers' views in the browser from embedded graph data (the + build-renders decision, MD-43); adopts a framework or a framework-based UI library (the + custom-elements decision, MD-42); lays out diagrams in the page (the diagram-layout decision, + MD-44); reshapes one of the frozen four (the shipped-projections decision, MD-32); or shows + liveness (binding, never liveness, MD-7). The design system to be introduced later meets the + custom-elements decision (MD-42): a CSS-level system or framework-free elements fit it; a + framework-based component library needs a decision. +- **What each redesign touches.** Navigation: the navigation, shell, lenses, capability-map page, + search, page-elements and responsive Specs. A new landing page: the parent's + `#rule.staticPageSet`, the lenses and Packs-lens landing rules, the index page, the navigation's + index routes and the publisher's page set. Entry pages for delivery roles: new story Specs refining + `spec:consumers.spec-studio`, every rendered recipe named under `#rule.recipeAnswers`, and a new + named input if they read corpus perspectives. Merging or retiring a page: its own Spec, the page + set, link resolution, the shell's rail, the manual acceptance tasks, and the `sdp-studio` skill, + which maps tasks to pages. +- **Keeping readiness honest during a redesign.** Lowering an implemented Studio Spec below `ready` + raises the drift alarm. A decision a Studio Spec names through `decidedBy` must state at least + `defined` for that Spec to keep `ready`, so a draft decision matures to `defined` before the edges + are added. + +**Re-check.** The Studio Specs below `ready`, and the reach of a navigation and landing redesign: + +```bash +pnpm --silent sdp:q 'return g.specs().filter((s) => s.id.startsWith("spec:consumers.spec-studio") && s.statedReadiness !== "ready").map((s) => [s.id, s.statedReadiness])' --json +pnpm --silent sdp:q "$(cat dist/recipes/30-design-change-impact.js)" --params '{"specs":["spec:consumers.spec-studio.navigation","spec:consumers.spec-studio.lenses","spec:consumers.spec-studio.lenses.packs","spec:consumers.spec-studio.index-page","spec:consumers.spec-studio.shell"]}' --json +``` + +**Governing text.** + +| Source | What it says | +|---|---| +| The shipped-projections decision (MD-32, `spec:decisions.shipped-projections-frozen`) | "Re-specifying the shipped Design Review, census, Mermaid, or Gherkin projection is refused"; a reshaping "arrives as a decision record that refines this one … never as a follow-up work item." | +| The derived-HTML decision (MD-41, `spec:decisions.studio-html-surface`) | "The HTML is derived and never committed"; "neither view ranks above the other"; "the Studio's first build is read-only." | +| The custom-elements decision (MD-42, `spec:decisions.studio-web-components`) | "custom elements written without React, Vue, Svelte or another framework." | +| The build-renders decision (MD-43, `spec:decisions.studio-build-renders`) | "a custom element adds only the interaction its view needs." | +| The planning-truths decision (MD-33, `spec:decisions.planning-truths-placement`) | "a row that restates a behavior guarantee already homed on a carrying Spec stays on that Spec and changes by ordinary Spec revision." | +| `spec:validation.readiness-floor#rule.readyFloor` | "every resolving `refines`, `dependsOn`, `constrainedBy`, and `decidedBy` target itself states at least `defined`." | + +**What stays open.** Carried in 06's register, under [Landing, navigation and +pages](06-design-cycles.md#landing-navigation-and-pages), [People and +entry](06-design-cycles.md#people-and-entry), [Basis and trust](06-design-cycles.md#basis-and-trust) +and [The design project and visual +design](06-design-cycles.md#the-design-project-and-visual-design). + +## 8. Recording a long-running design effort + +**The question.** Where do months of UX design intent and design questions live under the +repository's own conventions? + +**The answer.** + +- **The conventions put intended truth in carriers.** An idea becomes a capture Spec at `idea`; an + open design question becomes a keyed open question on it; a worked lean becomes a decision Spec + below `ready`; a Pack groups the work. There is no separate product requirements document; + `plans/` and `reviews/` are frozen, and the Protocol adds no plan or review file (the + roadmap-over-plans decision, MD-47). Evidence such as prototypes and screenshots is committed on + an arc's branch with its commands and removed before merge. Briefs and prompts stay in the session. + Counts are derived each time. +- **Two kinds of design session.** In the handbook, a design session designs Specs and "edits + carriers". This project's design sessions, by the owner's rule, edit no graph input: they record + what they find in [07](07-graph-needs.md) for an engineering session and the owner. Neither the + handbook nor any Spec names `docs/design/`; the maintained prose precedents that confer nothing + are `docs/articles/` and `docs/lineage/`. +- **How the Protocol tracks a question for months.** A keyed `[blocking]` or `[non-blocking]` entry + under Intent `### Open questions`, with `decider`, a one-line `provisional` reading (intent, never a + ruling), `links` (Spec ids or entry addresses only; an outside document is named in the text) and, + on a deferral, a `trigger`. It carries no status or date. It is read through the open-question + register (recipe 20), the statement queue (recipe 46), and the Studio's Questions page, which + filters by blocking flag, decider, deferral and Pack. The owner ratifies a decision by stating it + `ready`. History stays in git and in each arc's pull request description. +- **Captures this effort already meets.** `spec:consumers.ai-assisted-reading`, whose trigger names + the UX design pass. `spec:consumers.reference-projection#question.namedOutsideReader` and + `spec:consumers.structural-mermaid#question.namedStructuralReader`, which both wait for a named + reader; a persona from [01](01-roles-and-perspectives.md) could become one only through the owner. + `spec:consumers.projections-model.roadmap-views#question.releaseReader`. +- **A corpus home, as a proposal only.** The corpus does not record this design project today; what + the conventions imply is set out in [07](07-graph-needs.md#a-corpus-home-for-these-needs-a-proposal), + for an engineering session and the owner to weigh and never for a design session to author. +- **What a design round can use today without editing anything.** The design diff (recipe 35) from + a base graph kept outside `generated/`, Pack design (recipe 29), the design slice (recipe 54), the + context bundle (recipe 36) and the perspective filter (recipe 37). Findings against Specs travel as + a change proposal, checked by recipe 38 and rendered by recipe 49, for an engineering session to + apply. A person's long-running notes fit the vault, in `intent/` outside its generated folder. + +**Governing text.** + +| Source | What it says | +|---|---| +| The roadmap-over-plans decision (MD-47, `spec:decisions.roadmap-over-plans`) | The Protocol "keeps its delivery record in git and its pull requests; it adds no plan file and no review file." | +| `spec:protocol.roadmap-replaces-plans#rule.oneRoadmap` | "The Protocol keeps one living roadmap Pack … Its owner selects captured work for the upcoming pull requests; landing a capture does not add it." | +| `spec:protocol.roadmap-replaces-plans#rule.evidence` | Evidence no test or recipe carries "is committed on the arc's branch with the commands that made it, linked from the description at that commit, and removed before the merge." | +| `spec:model.open-question-fields` (Behavior) | "An open question carries no status, date, blocked work unit or record of who checked it … the rest of the history stays in git and in the adopter's own records." | +| `spec:consumers.spec-studio.registers#rule.registerFilters` | "The questions page filters by blocking flag, decider, deferral and Pack." | +| `spec:consumers.obsidian-vault.iteration#rule.composeHome` | "A person composes intent in notes outside the generated folder, by convention in `intent/` … the vault command never writes there." | + +**What stays open.** Carried in 06's register, under [The design project and visual +design](06-design-cycles.md#the-design-project-and-visual-design), +[Words](06-design-cycles.md#words), [AI-assisted reading](06-design-cycles.md#ai-assisted-reading) +and [Commercial surfaces](06-design-cycles.md#commercial-surfaces-exploratory). + +## Re-checking a claim + +Every Spec citation above can be re-checked from the graph: + +```bash +# A Spec's stated and derived readiness, delivery facts and Packs +pnpm --silent sdp:q 'const c = g.specContext(params.spec); return { stated: c.statedReadiness, derived: c.derivedReadiness, facts: c.deliveryFacts, packs: c.packs }' --params '{"spec":"spec:consumers.ai-assisted-reading"}' --json + +# Whether an entry address resolves +pnpm --silent sdp:q 'return g.resolveEntryAddress(params.address)' --params '{"address":"spec:consumers.spec-studio#rule.namedInputs"}' --json + +# Where a concept lives +pnpm --silent sdp:q "$(cat dist/recipes/06-where-is-this-concept.js)" --params '{"term":"perspective"}' --json +``` + +Read a carrier only at the location the graph returns, and only for its exact wording. diff --git a/docs/design/09-design-method.md b/docs/design/09-design-method.md new file mode 100644 index 00000000..9a35a0dd --- /dev/null +++ b/docs/design/09-design-method.md @@ -0,0 +1,277 @@ +# 09 — Design method + +This document describes how the long-running design project is done and judged: who reads, which +tasks they take, how prototypes are built over the graph, which corpora and states they run on, and +how findings reach engineering. It is design material that confers nothing on the corpus; where it +and a Spec disagree, the Spec wins. + +**Every piece of design work is partly specified in graph queries.** A brief, a prototype, a task +given to a reader and a cycle record each carry the runnable `sdp:q` bodies or recipe calls that +define their scope and their evidence, beside the prose. Whoever picks the work up, a person or an +agent, starts from the graph rather than from a description of it, and a claim about the Protocol +carries the query that backs it. Briefs that name exact queries are followed; briefs that only say +"use the graph" are not ([07](07-graph-needs.md#agent-on-ramp-observations)). + +## 1. Evaluation: readers, tasks, success, record + +**Who reads.** A session names its reader by delivery role and situation, never by person. The +first cycles take the tier-1 delivery roles in [01](01-roles-and-perspectives.md), and the pull +request reviewer who holds only a link, the actor the Studio is written for +(`spec:consumers.spec-studio`). The other tiers, the non-human readers and the AI-assisted readings +in [05](05-specialised-and-ai-readings.md) join as the cycles reach them: tier 1 is a focus, not a +limit. A persona is a design-material word here (see the [README](README.md)). It is paired with job +stories (When / I want / so I can) for its jobs, because the +[job stories](../../jtbd-stories/README.md) deliberately bind to no persona. + +Two kinds of reader take the same tasks: + +- **Agent readers**, given a stamped link and no repository. They are cheap and repeatable, and + they run across model families so that one model's habits do not pass for the design's. The + precedent is the first adopter's feedback record (`libar-platform/docs/feedback/sdp-feedback-01.md`, + which the Studio's manual verification cites): passes by agents from different model families + took the same tasks against the same page, each task was scored full or partial, and the missing + material was named. Those tasks became the Studio's manual acceptance tasks. +- **People**: the owner, people at the first adopter, and outside readers as the project finds + them. Slower, and the only evidence of how a person reads. + +**Which tasks.** Every cycle uses three task sets: + +| Set | Source | What it asks | +|---|---|---| +| Studio acceptance | `spec:consumers.spec-studio`, manual verification | the first adopter's findability tasks over its history-view Pack; then naming what the owner can state first (owner queue), what changed since a base (diff page) and which components are designed but not built (architecture lens) | +| Article 2's design questions | [Article 2](../articles/02-one-graph-many-views.md#a-compact-brief-for-the-first-uxui-design-pass) | what a reviewer can do from a stamped link alone; the fastest route from "what changed?" to "is this design ready?" for one Pack; telling intent, code bindings, inferred structure and supplied runs apart; telling the kinds of absence apart; diagram or prose, and on a phone; gathering requests and knowing what goes to an agent; which pages solve real jobs | +| Delivery-role tasks | the first questions and task flows in [04](04-reading-model-and-ia.md) | one job story per task, with its acceptance. For example: "When a Pack is up for review, I want to see what stands before each member's stated next rung, so I can state `ready` or answer what holds it" | + +Article 2 calls the Studio's tasks "specified acceptance criteria, not evidence that a person has +completed them". Sessions are how they become evidence. + +**What counts as success.** Each task is scored per reader, never averaged into one score: + +- **Outcome**: full, partial or failed, with the missing material named. +- **Route**: the pages, or the reader calls, in order. Route length matters most for "what + changed?" to "is this design ready?". +- **Misreadings** of an honesty distinction, each one recorded: `has-verifier` read as tests + passing, `implemented` read as live, stated readiness read as the floor reached, an `inferred` + edge read as `declared`, a supplied run or base graph read as graph data, one kind of absence + read as another. A reading succeeds with no misreadings, not with a shorter route. +- **Agreement**: what the reader took from a page equals the answer of the recipe the page names, at + the same commit. A page computes nothing of its own (`spec:consumers.spec-studio#rule.noSecondGraph`), + so a disagreement is either a misreading or a page defect, and both are findings. +- **Hand-off**: a change proposal composed during a task passes the proposal check (recipe 38) + against its base. + +The Studio's page elements load nothing at run time and request only the stamp +(`spec:consumers.spec-studio.page-elements#rule.noRequest`), and the composing panel sends its +intents nowhere (`spec:consumers.spec-studio.intent-panel#rule.noRequest`). The product reports +nothing about its readers, so every measure comes from sessions. For an AI step, the same task runs +with and without the step: that comparison is what the re-entry trigger of +`spec:consumers.ai-assisted-reading#question.aiPresentationBoundary` asks for ("the UX design pass +measures that assistant selection or a generated explanation helps a named review task"). + +**How a session is recorded.** One record per reader per session: + +| Field | Content | +|---|---| +| Reader | delivery role and situation; an agent with its model family, or a person (by delivery role, never by name) | +| What was read | corpus and commit; the page set's stamp, or "no stamp" for a page opened through `file://` (`spec:consumers.spec-studio.shell#rule.stamp`); each named input and its commit | +| States | the cells of the table in section 4 the session ran in | +| Tasks | each task's wording, as given | +| Results | per task: outcome, route, misreadings, missing material | +| Follow-ups | a row in [07](07-graph-needs.md), a change proposal (section 6), or a design question in [06](06-design-cycles.md) | + +A record is evidence no test or recipe carries. It is committed on the arc's branch with the +commands that made it, linked from the pull request description at that commit, and removed before +merge (`spec:protocol.roadmap-replaces-plans#rule.evidence`). The description carries the summary. + +## 2. The baseline + +The comparison point is [10 — Studio baseline](10-studio-baseline.md): today's Studio, recorded at a +pinned commit before any redesign. The first task run (cycle 0 in [06](06-design-cycles.md)) applies +section 1 to that pin, on the corpora and states in section 4. Every later prototype runs the same +tasks on the same corpora and states, and its arc's description shows its results beside the +baseline's. Moving the baseline to a new pin is a deliberate step, named in the description of the +arc that takes it; the earlier record stays reachable through its commit link. + +## 3. Prototypes + +A prototype is a reading composed over a real graph, never a mock-up with typed-in data. + +- **Material.** An `sdp q` body, or a shipped recipe with its parameters, produces everything the + prototype shows, and the prototype names those recipes. This mirrors the Studio's own law: a page + shows a recipe's answer only when its Spec names that recipe + (`spec:consumers.spec-studio#rule.recipeAnswers`). +- **Renderer.** A disposable script turns that output into the prototype and reads nothing else: no + carrier, no source file. The vault exploration is the working shape, a dump body and a generator + over its output, with a README naming the commit and saying nothing is ratified + ([`explorations/obsidian-vault/`](../../explorations/obsidian-vault/README.md)). +- **Outside `generated/`.** Every build and publisher first removes the projection roots + (`spec:consumers.wholesale-view-rewrite#rule.buildInvalidates`), and a prototype must never be + taken for a projection. +- **Gaps stay visible.** Material the graph lacks shows as a named absence, and a row lands in + [07](07-graph-needs.md) with the query that shows the gap. A prototype never fills a gap by hand. +- **Fidelity, lowest first.** (a) Answer sheets: recipe output laid out as answer, evidence and + source ([04](04-reading-model-and-ia.md)). (b) Obsidian Bases over the vault's notes: the vault + keeps a Base a person changed (the vault-folder decision, MD-45), so an entry reading can be tried + with no engine change. (c) Static HTML over a dump. All three stay at structure, with no visual + style before the design system arrives. Each interaction pattern a prototype relies on is noted, + so it can be checked against the custom-elements decision (MD-42). +- **Where it lives.** On the arc's branch as evidence, with its commands, removed before merge + (`spec:protocol.roadmap-replaces-plans#rule.evidence`). `explorations/` holds evidence only, and + its code is never promoted into the product. The vault exploration landed there in commit + `1b014d01`; the decision that puts the roadmap and the pull request over plan and review files + (MD-47) later refused keeping arc evidence in a committed folder on the main line. Whether any + prototype earns a lasting place is the owner's question. + +## 4. Test corpora and states + +| Corpus | How to read it | Why it is in the set | +|---|---|---| +| The self-hosted corpus | `pnpm --silent sdp:q ''` | large and skewed: examples are about half its Specs, constraint Specs are almost absent, and one Pack holds every Spec (re-derive with the query below) | +| The worked example, `examples/checkout-v1` | `pnpm --silent sdp q '' --root examples/checkout-v1` | small, one bounded context, Specs on every readiness rung, its own roadmap Pack | +| The first adopter's corpus, at a pinned commit | its package runner, with `--root` and its own exclusions | an adopter's own corpus, and the one the Studio's acceptance tasks were written over | +| A small or deliberately awkward corpus | requested through [07](07-graph-needs.md#log) | states the others cannot supply | + +```sh +# The self-hosted corpus by kind, and whether pack:self-hosting-v1 holds every Spec +pnpm --silent sdp:q 'const kinds = {}; for (const s of g.specs()) kinds[s.specKind] = (kinds[s.specKind] ?? 0) + 1; const everySpec = graph.nodes.find((n) => n.id === "pack:self-hosting-v1").members.length === g.specs().length; return { kinds, everySpec }' +# Packs whose members all state idea (add --root examples/checkout-v1 for the worked example) +pnpm --silent sdp:q 'return graph.nodes.filter((n) => n.nodeType === "Pack" && n.members.every((m) => g.specContext(m)?.statedReadiness === "idea")).map((n) => n.id)' +``` + +The states every reading must survive come from the Studio's law: + +| State | Where the law or the query is | +|---|---| +| A stamped page set served over http or https | the stamp line (`spec:consumers.spec-studio.shell#ui.stampLine`) | +| A page opened through `file://`: no stamp, no requests | `spec:consumers.spec-studio.shell#rule.stamp`, `spec:consumers.spec-studio.page-elements#rule.noRequest` | +| No script | every page but search reads in full (`spec:consumers.spec-studio.shell#rule.withoutScript`) | +| Phone width | the same pages serve both widths (`spec:consumers.spec-studio.responsive`) | +| A base graph, run records, both, neither | the diff and runs pages appear only with their inputs, each named where it shows (`spec:consumers.spec-studio#rule.namedInputs`); keep a base graph outside `generated/` (`spec:consumers.spec-studio.data.inputs#rule.inputPlacement`) | +| `floor not evaluated` | `spec:consumers.spec-studio.shell#rule.rungBadge` | +| An idea-only Pack | the query above; neither corpus in this repository holds one today | +| A perspective that selects no member | its diagnostics in the perspective filter (recipe 37) | +| A Pack too large for one context bundle | read in parts (recipe 36) | +| Keyboard only, screen reader | section 9 | + +Each brief and session record names the cells it was tried in. A cell no corpus can supply says so. + +## 5. Design terms + +[`CONTEXT.md`](../../CONTEXT.md) is binding, and the [README](README.md) keeps the provisional +words and their status. A new design word takes this path: + +1. **Flagged where it first appears**, and added to the README's provisional table. +2. **Checked against the governing rubric** in `CONTEXT.md`: adopt the established delivery noun; + coin a word only for a genuine differentiator, and then the word must name the difference; + reject lifecycle gating; and pass both naming tests, carrying epistemic status where it matters + and staying concrete for all three readers (typed code and the CLI, the coding agent, a Studio + user). +3. **Checked for collisions** against the ratified terms and their aliases to avoid. Cases already + found: bare "role" (the ratified anchor value), "lens" (the Studio's graph views, and an alias to + avoid for perspective), "basis" (close to `base`, the base graph), "cycle" (this folder's + stretch of design work, apart from a dependency cycle) and 07's "graph need" (apart from the + *need* of a roadmap entry). +4. **Tried with readers.** A word a reader misunderstands is a misreading under section 1. +5. **Ruled by the owner.** A word that ships lands through a carrying Spec and a `CONTEXT.md` row, + which is engineering-session work recorded in [07](07-graph-needs.md). `CONTEXT.md`'s "Flagged + ambiguities" is where a candidate waits: "vault" and "term address" were flagged there in commit + `1b014d01` and resolved later. It still holds one item for this project: a friendlier + Studio-facing name for the "epistemic boundary". + +## 6. Hand-off to engineering + +AGENTS.md counts Specs, decisions and open questions as design work. In this project an engineering +session makes those carrier edits: the sessions that write this material leave every graph input +alone and hand their findings over in these forms. + +| Finding | Form | Who acts | +|---|---|---| +| Material the graph lacks | a row in [07](07-graph-needs.md), with the query that shows the gap | an engineering session and the owner | +| A change to an existing Spec or entry, such as what a `ready` Studio page shows | one change proposal per review, in the shape of `schemas/sdp-proposal-1.schema.json`, based on the commit the reviewer read; checked with the proposal check (recipe 38) against the graph at that commit; rendered with the proposal memo (recipe 49) and posted to the pull request | an engineering session applies it, and the applying commit carries the proposal's reason line and base | +| A design question left open | a question in [06](06-design-cycles.md) for now; with a corpus home (section 8), a keyed open question with `decider`, `provisional` and `links`, and a `trigger` on a deferral (`spec:protocol.roadmap-replaces-plans#rule.openFindings`) | the owner rules; an engineering session writes it | +| A reading that needs a new carrying Spec | a request in [07](07-graph-needs.md), or the corpus home in section 8 | an engineering session, on the owner's word | +| Drift between a Spec and its code, or between a concept document and the graph | recorded in the document that found it ([10](10-studio-baseline.md), [11](11-rup-roles-and-artifacts.md)) and raised as a pull-request comment on the lines; a code defect against settled intent stays a code finding | an engineering session | + +- Before proposing a change to a Spec others rest on, run design-change impact (recipe 30) over it. +- A proposal scopes Spec ids and entry addresses only. A finding that changes no Spec is not + dressed as one. +- A brief names the recipes its reading shows. A new recipe also needs a catalog entry in + [`docs/agent-surface/recipes.md`](../agent-surface/recipes.md), whose bodies a test runs as + written. +- Briefs and prompts stay in the session that used them (AGENTS.md). What lasts is the arc's + evidence, its description, the rows in 07 and the proposals. +- The path from a brief to a `ready` Spec is in [06](06-design-cycles.md#how-design-outputs-become-product). + +```sh +pnpm --silent sdp:q "$(cat dist/recipes/30-design-change-impact.js)" --params '{"specs":["spec:consumers.spec-studio.index-page"]}' --json +pnpm --silent sdp:q "$(cat dist/recipes/38-the-proposal-check.js)" --params proposal=@proposal.json --params base=@base-graph.json --json +pnpm --silent sdp:q "$(cat dist/recipes/49-the-proposal-memo.js)" --params proposal=@proposal.json --json +``` + +## 7. Opening and closing a cycle + +A cycle runs as one or more arcs. This section restates what AGENTS.md says about an arc: + +- **Opening.** The owner's instruction opens an arc and authorizes its commits and push; without + it, ask before committing. The first commit message states the owner's working rules, the base + and the arc's Pack. The draft pull request opens at the first coherent commit, normally the + scaffold, and repeats those rules with the branch, base, lanes and rulings. It is the arc's + record. +- **Working.** Commits are recovery boundaries, not workflow gates: commit each coherent unit after + its gate, and if a session must stop without a clean boundary, commit the work in progress saying + what is incomplete. A session resumes from the branch, its commits, the draft description and the + graph. Push only on the owner's explicit request; never use `git stash`. +- **Evidence.** Evidence no test or recipe carries is committed on the branch with its commands, + linked from the description at that commit, and removed before merge. Images, which `gh` cannot + attach, go on the branch with a short README naming the commands. +- **The description.** The story first, change lists after; a human view the arc moves shown at + base and head; + rulings in two tables, those the owner made and those delegated awaiting the owner's review; + numbers re-measured at close and marked; a try-it block; and a forward section that is recipe 55's + memo over `pack:roadmap`. The arc's intent is a Pack in the corpus, described with Pack design + (recipe 29) and the design diff (recipe 35) from the arc's base. +- **The roadmap.** Entries join or move only on the owner's word. + +This method adds two rules. A cycle closes on evidence, when its named tasks have recorded outcomes +on its named corpora and states, compared with the baseline; it never closes on a date. Until the +corpus home in section 8 exists, a design arc links and measures the Packs it reads, such as +`pack:spec-studio-v1`, and the design project never adds itself to the roadmap. + +## 8. Proposal: a corpus home for the design project + +A design Pack of `idea` captures, holding [06](06-design-cycles.md)'s long-horizon questions as keyed +open questions, is a proposal for an engineering session and the owner, not done and not something +a design session does; [07](07-graph-needs.md#a-corpus-home-for-these-needs-a-proposal) sets it out +with the case for and against. + +## 9. Accessibility baseline + +The baseline is Studio law already stated `ready` and implemented. Its verifier bindings say a +binding exists, not that an accessibility audit passed. + +| Need | Law | +|---|---| +| Keyboard | every link and control reachable in reading order, with focus shown (`spec:consumers.spec-studio.shell#rule.keyboard`); every control an element adds is a native button, link, select or input with a text label (`spec:consumers.spec-studio.page-elements#rule.nativeControls`); every page opens with a link that skips to the canvas (`spec:consumers.spec-studio.shell`) | +| Color | every meaning a color conveys is also in words (`spec:consumers.spec-studio.shell#rule.wordsBesideColor`); rung badges from a palette that stays distinct under color blindness (`spec:consumers.spec-studio.shell#rule.rungBadge`); the current page marked by `aria-current` and an underline (`spec:consumers.spec-studio.navigation#rule.currentPage`) | +| No script | every page but search reads in full (`spec:consumers.spec-studio.shell#rule.withoutScript`) | +| Reading width | prose no wider than about 80 characters; a wide table scrolls in its own box (`spec:consumers.spec-studio.shell#rule.lineLength`) | +| Diagrams | a text equivalent after each, named by the SVG as its description (`spec:consumers.spec-studio.diagrams#rule.textEquivalent`); a keyboard-accessible scroll region (`spec:consumers.spec-studio.diagrams#rule.panZoomOnly`) | +| Changes on screen | an element that changes what a page shows says so in a polite live region (`spec:consumers.spec-studio.page-elements#rule.liveCounts`) | +| Phone | the same pages serve a desktop and a phone (`spec:consumers.spec-studio.responsive`) | + +Sessions add keyboard-only, no-script, phone-width and screen-reader passes (section 4). No +automated accessibility audit of the generated pages runs today, and no Spec names a conformance +target: concept search (recipe 6) finds nothing for "WCAG". Which target applies, WCAG 2.2 AA being +one candidate, is a long-horizon question in [06](06-design-cycles.md), answered with the design +system. An automated audit, if one is added, is an engine test and never a corpus validator: checks +police conformance and honesty, never design quality. + +## Open method questions + +These are worked through over the cycles, not settled up front: + +- Do agent readers' results predict people's on the same tasks? +- Do the delivery-role tasks become job stories in [`jtbd-stories/`](../../jtbd-stories/README.md), + or stay design material? +- How are outside readers found, and recorded by delivery role without exposing who they are? +- Does any prototype earn a lasting home after its arc? diff --git a/docs/design/10-studio-baseline.md b/docs/design/10-studio-baseline.md new file mode 100644 index 00000000..441bdc7d --- /dev/null +++ b/docs/design/10-studio-baseline.md @@ -0,0 +1,244 @@ +# 10 — Studio baseline + +A page-by-page reading of today's Spec Studio, taken from one pull-request preview and read as a +prototype: what each page is for, whom it serves, what works and what does not. It is the +page-reading half of cycle 0 ([06](06-design-cycles.md)); the per-task outcomes that +[09](09-design-method.md) section 1 records have not been taken yet. This is design material, not +intended truth; where it differs from a Studio Spec under `spec:consumers.spec-studio`, the Spec +wins. + +## The preview this baseline reads + +- **Page set:** [the Studio preview of pull request #34](https://libar-dev.github.io/software-delivery-protocol/preview/34/index.html). +- **Basis, from its `stamp.json`:** corpus commit `35f1094d` (`35f1094dae742a673226fcb97580b887ef0c4ad1`), + GitHub's merge of the pull request's head `6062075` into its base `480ded4`, with the same tree as + the merge commit `f990bded` on `main`; engine `sdp 0.0.0` built from that commit; graph schema + `0.12.0`. The build was given a base graph (the pull request's base) and CI run records, so the + Diff and Runs pages exist. +- **Re-measured, not inherited.** `src/` and `specs/` are unchanged between the stamped commit and + `53804437`, so each statement below about the corpus was re-derived from the live graph: each + page's carrying Spec and rule through `g.specContext` and `g.resolveEntryAddress`, and corpus + shape through recipes 1, 17, 20, 24, 33, 43, 46, 51 and 53. Re-run them rather than trusting this + page; counts are left to the queries on purpose. +- **Not read yet:** slice pages (`spec:consumers.spec-studio.slice-page`), the Pack export and print + (`spec:consumers.spec-studio.export`), the phone layout (`spec:consumers.spec-studio.responsive`), + the composing panel's scripted behavior and the memo it hands off + (`spec:consumers.spec-studio.intent-panel`), and watch mode + (`spec:consumers.spec-studio.publisher.watch`). They are the next pages to read the same way. + +## How to read the table + +- **Stated purpose** paraphrases the carrying Spec's Intent outcome; the Spec id is where the + exact words live. +- **Roles** are the personas of [01](01-roles-and-perspectives.md), shortened: TPM (technical + product manager), decider (readiness author / question decider), architect, engineer, tester, + leader (engineering leader / project lead / auditor), PR reviewer and newcomer. "Persona" is a provisional design term + ([README](README.md)); the JTBD stories avoid personas on purpose, so each persona here is paired + with a job rather than a profile. +- **Problems** are UX and information-architecture problems. Visual style is out of scope until + the design system arrives. + +## Page by page + +| Page | Stated purpose (carrying Spec) | Job and roles served | What works | Main problems | +|---|---|---|---|---| +| [Index](https://libar-dev.github.io/software-delivery-protocol/preview/34/index.html), the landing | Say where the corpus stands, route by task, list every Pack with its members, narrow every Spec by coordinates and bindings (`spec:consumers.spec-studio.index-page`); the landing is the Packs lens (`spec:consumers.spec-studio.lenses.packs#rule.landing`) | Orientation, then a way into a Pack or a narrowed list. Leader (summary, findings), PR reviewer and TPM (Packs, "Start here"), decider (question counts, queue route), engineer and tester (binding filters); newcomer weakly | Summary sentences answer "where does it stand" fast, with explicit zero states; "Start here" routes are phrased as jobs; filters cover every coordinate, bindings, Pack and epic; Pack members sit in closed native disclosures and every row reads without script | No default narrowing: every Spec is one unpaginated row, about half of them examples interleaved by id, nearly all reading the same "ready · floor ready"; summary counts link nowhere; never names the project or says what the Studio is; the subtitle "from the reader" is engine vocabulary; Pack disclosures add weight and duplication, not visual length | +| [Search](https://libar-dev.github.io/software-delivery-protocol/preview/34/search.html) | Find a Spec, a Pack, a keyed entry or the code bound at a file by a remembered word, from any page, with no request (`spec:consumers.spec-studio.search`); one matcher with `findByConcept` (`#rule.oneMatcher`) | Jump by a word, key or file path. Engineer (files, code units), PR reviewer (coined keys, entry hits), architect, tester; newcomer only with a known word; decider weakly | The term lives in the link, so a search is shareable; coined keys and full paths land exactly; code units carry file and line, a source link and their `satisfies` target; every query says which fields it searched and why each card matched | Ranking buries the defining Spec (for "readiness floor", `spec:validation.readiness-floor` comes after examples and code units); a spaced phrase misses a hyphenated id; an entry address finds no entry, only Specs whose prose quotes it (search does not resolve addresses); short words flood with no facets; code-unit and anchor cards link nowhere; entry labels are internal paths (`rules[11]`); the embedded index makes it by far the heaviest page | +| [Glossary](https://libar-dev.github.io/software-delivery-protocol/preview/34/glossary.html) | Find any term a Spec defines, read it, open the Spec and entry that define it (`spec:consumers.spec-studio.glossary-page`); it renders no glossary document and picks neither of two definitions (`#rule.noGlossaryDocument`, `#rule.sameWordTwice`) | Look up a Model-section term. Newcomer partly, PR reviewer and decider (definitions side by side), architect (role vocabulary) | Small, scannable, with a letter index; a word two Specs define shows both, side by side; keyed terms deep-link and copy their term address | The Studio's own words (floor, rung, finding, deferral, decider, entry address, implementation binding, verifier binding) are absent, because no Model section defines them; no route to the ratified [`CONTEXT.md`](../../CONTEXT.md); most terms link to the top of a long Spec page; the defining Spec's stated rung is not shown, so a `scoped` definition reads like a `ready` one; "index" means an engine role here and the landing page elsewhere | +| [Capabilities](https://libar-dev.github.io/software-delivery-protocol/preview/34/capabilities.html) | Read an epic overview, its refinement structure and evidence, and narrow the index to its descendants, for a reviewer choosing a Spec or Pack (`spec:consumers.spec-studio.capability-map-page`, recipe 52) | How big a capability is and how it breaks down. TPM, architect, PR reviewer, newcomer; leader partly | Compact epic cards; stated rung and floor side by side on every row; rollups state their scope and refuse to sum overlapping epics; text equivalents carry every node and edge without script; "Show these Specs" narrows the index | Cards show size, not progress; binding rollups count examples and decisions in the denominator, so a mostly bound capability reads as mostly unbound; question and below-ready counts link nowhere; each epic appears four ways (drawing, its text, Mermaid source, refinement text); empty-question lines and zero kind buckets repeat on almost every row | +| [Architecture](https://libar-dev.github.io/software-delivery-protocol/preview/34/architecture.html) | See the components the code realizes and those the design plans, by bounded context and layer, with what each uses and holds (`spec:consumers.spec-studio.lenses.architecture`, with `spec:consumers.spec-studio.lenses.architecture.unit-register`) | The structure the component anchors record. Architect, engineer, newcomer (orientation to `src/`), PR reviewer; TPM only through "Designed, not built" | The uses matrix: complete, readable without script and in print; Satisfies and References kept apart; omissions shown (no component, role not stated, outside component); stable component ids; the claim word on every structural edge | With every component in the same context (recipe 17 lists each component's context), the context-by-layer grid has little to group; the text equivalent drops layer and context; "Significant units" is a bare id list; long member lists, mostly "References: None.", with no filter; anchors in test files read as orphaned engine code; no link to tests, readiness or source folder; "Designed, not built" is empty (recipe 43), so its acceptance task cannot be exercised here | +| [Tests](https://libar-dev.github.io/software-delivery-protocol/preview/34/tests.html) | For every Spec, whether a verifier is bound, which keyed rules an example exercises, which example-space values no example binds (`spec:consumers.spec-studio.lenses.tests`); bindings only, never a verdict (`#rule.bindingsOnly`) | Verification posture per non-example Spec, with file-grain run evidence. Tester, engineer, PR reviewer, leader; decider (rules no example exercises) | One line per Spec; binding existence kept apart from CI outcomes; filters match a tester's questions; rows deep-link to the verification panel; uncovered values link to the unbound example | Decision records make up most of the "without a verifier binding" rows, and there is no kind filter; "exercised" is never explained, so an example that declares no `exercises` reads as untested rules; file-wide run counts sit beside one Spec; no gap-first order; run lines repeat the runs page without linking it | +| [Evidence](https://libar-dev.github.io/software-delivery-protocol/preview/34/evidence.html) | Show which kinds of runtime evidence the Studio could show, and that none is tracked until the graph records it (`spec:consumers.spec-studio.lenses.evidence`), decided by the binding, never liveness decision (MD-7) | Say plainly what is not tracked and what would bring it in. Leader, TPM, newcomer | Short, unambiguous, invents nothing; keeping the page in the navigation makes the absence visible | A dead end: no link to runtime observation's design home (`spec:observation.runtime-overlay`, stated `idea`), to the deciding record or to the runs page (run records stay out of this lens by `#rule.runsElsewhere`, but the reader gets no route to them); "a Spec that designs this source" does not say whether one exists | +| [Runs](https://libar-dev.github.io/software-delivery-protocol/preview/34/runs.html) | Read, from a link, the test runs the build was given, the anchored test files each joins and the records that join none, each labelled external evidence (`spec:consumers.spec-studio.runs-page`); a commit is never called fresh or stale (`#rule.commitShown`) | CI results joined to test files and the Specs those anchors verify. Tester, engineer, PR reviewer (does the run match the preview?), leader | Strong honesty framing; each joined file names its test anchors and links the Specs they verify; unjoined records stay with their reason; test names read as behavior sentences | Runs are told apart only by position and times; one long, fully expanded list with no file index, per-file counts or result filter, so a failure would be hard to find; the share of records joining no anchor is never stated; unjoined rows show absolute CI paths; file headings never become source links; full commit hashes compared by eye | +| [Roadmap](https://libar-dev.github.io/software-delivery-protocol/preview/34/roadmap.html) | Show each roadmap in priority order with what to design, to state, to build and what is built, and what each entry lacks, for the owner choosing next work and a reviewer with a link (`spec:consumers.spec-studio.roadmap-page`, recipes 53 and 55) | What the next work needs, in the owner's order, plus a forward section to paste. Decider first, TPM, PR reviewer, engineer ("Build now" is the only page naming buildable Specs), leader partly | The need board answers design, state or build at a glance; the legend defines "To state" and "Built" in plain sentences; "Waiting on the owner" joins questions to entries; the copyable memo serves the pull-request convention; reads in full without script | Cards never say why an entry matters (its purpose sits inside the collapsed memo); deferred questions and their triggers appear only as raw Markdown in the memo; "nothing blocks" sits above "Blocked by" with no word on which rung each means; a question whose provisional reading records the owner's answer still reads as blocking; ids and titles mixed on one card | +| [Owner queue](https://libar-dev.github.io/software-delivery-protocol/preview/34/queue.html) | Every statement the floor allows, in the order that holds, and every open question only the owner settles, blocking first (`spec:consumers.spec-studio.owner-queue`, recipe 46 with decider `owner`) | Statements a person can make now, and the owner's questions. Decider first, TPM, PR reviewer | Answers its acceptance task directly ("can be made now"); statement rows lead with titles; provisional readings make long questions actionable; addresses link and copy | Deferral is erased: no word, no trigger, so parked questions read as blocking work; a counted question with no decider is never listed; delegated questions have no queue anywhere, though recipe 46 takes any decider; question rows show addresses, not titles; a waiting statement can invite work on a Spec whose blocking question is parked on a trigger; "round", "rests on" and "floor allows" go unexplained | +| [Open questions](https://libar-dev.github.io/software-delivery-protocol/preview/34/questions.html) | Every open question of the corpus on one page, linked to the entries it names (`spec:consumers.spec-studio.registers#rule.questionsPage`, recipe 20) | The register of unsettled design, with decider, provisional reading and trigger. Decider first, architect, PR reviewer, newcomer, TPM | The only page where deferrals, triggers and deciders all appear, so the long-horizon design agenda lives here; blocking first; "Links" point at the exact rule in question; deferral and decider filters with script | Questions open now and deferrals parked on a trigger are interleaved by id; "Decider: delegated" names nobody, and a question with no decider carries no note; no link to the roadmap entry a question blocks; no age, by design (`spec:consumers.spec-studio.shell#rule.noRecentEdits`), so long-open questions cannot show as stale; the questions open now are framed as a residue ("blocking without a trigger") | +| [Decisions](https://libar-dev.github.io/software-delivery-protocol/preview/34/decisions.html) | One row per decision: title, id, stated rung, supersession, refinement with reasons, the Specs it shapes, its questions (`spec:consumers.spec-studio.registers#rule.decisionsPage`, recipe 31) | Decision records and how they connect. Architect (what shapes what), newcomer (titles summarise the rulings), PR reviewer, leader | Titles are claim sentences, so the list alone summarises the rulings; refinement reasons make carve-outs legible; "Shapes" gives each ruling's reach | Most labelled lines read "None" (the row design requires them), burying the refinements that matter; no registry name or lookup key, so a reader holding a registry key such as "MD-22" cannot find it (few decision Specs mention one; the registry is [`DECISIONS.md`](../concept/DECISIONS.md)); id-slug order reads unsorted; no grouping by area; no rationale shown; every row reads `ready`, so the rung says nothing here | +| [Pinned declarations](https://libar-dev.github.io/software-delivery-protocol/preview/34/declarations.html) | The pinned declarations, each with the source lines that cite it, where a reader finds the test that checks one (`spec:consumers.spec-studio.registers#rule.declarationsPage`, recipes 24 and 51) | In principle, a signature and the test line that checks it; here, a catalogue of signatures. Engineer, tester, architect, PR reviewer | One place for every pinned signature, grouped by owning Spec and linked to its entry; declarations render as code | Almost every row reads "no citation recorded" (compare recipe 51's `citedDeclarations` with recipe 24's total), and the summary never says so; unlabelled, that reads as "untested", though a citation is `inferred` and confers nothing; a citation shows file and line, not the line's words (on the roadmap as `spec:consumers.spec-studio.cited-line-text`); machine keys as headings; no in-page index | +| [Design backlog](https://libar-dev.github.io/software-delivery-protocol/preview/34/backlog.html) (nav "Backlog") | The Specs designed and not yet built (`spec:consumers.spec-studio.registers#rule.backlogPage`, recipe 33) | Designed, unbuilt work. Engineer, TPM, architect, all as intended readers | Honest and small: the recipe's empty answer and its exclusions, unpadded | Empty, since no Spec states `defined`, while the build backlog (recipe 1) is not empty and no page renders it; a reader looking for buildable work reads "None." and stops, with no route onward; the bare label "Backlog" is a word `CONTEXT.md` lists to avoid; the vault offers both backlogs (`spec:consumers.obsidian-vault.bases`) | +| [Design diff](https://libar-dev.github.io/software-delivery-protocol/preview/34/diff.html) | What changed in the design between the base graph the build was given and the graph it built, down to each entry (`spec:consumers.spec-studio.diff-page`); confers nothing (`#rule.confersNothing`) | What a pull request changes in the design. PR reviewer first, decider, leader | An honest null result: a docs-and-tests pull request shows no design change, with the base named; Specs, Pack order and bindings kept apart; linked from "Start here" | The base label is doubled ("the base graph base 480ded4"); the built graph has no commit on the page, only in the scripted stamp as a full merge-commit hash; the pull request is never named; every empty section keeps its heading where one sentence would do; "Diagnostics" unexplained | +| Pack page ([`pack:spec-studio-v1`](https://libar-dev.github.io/software-delivery-protocol/preview/34/packs/spec-studio-v1.html), [`pack:roadmap`](https://libar-dev.github.io/software-delivery-protocol/preview/34/packs/roadmap.html)) | Where a Pack's design stands, member by member in reading order, on one page a reviewer scans and opens where needed (`spec:consumers.spec-studio.pack-page`); never presents a rung as approved (`#rule.holds`) | Review a Pack as one design. PR reviewer, architect, decider, engineer, leader; TPM on the roadmap Pack | Summary sentences answer the review's first questions; closed member cards carry rung, floor, questions and bindings on one line; decisions linked with their rung; the boundary shows what the set rests on and what rests on it; the roadmap Pack lists each blocking question with decider and provisional reading | Binding totals count examples and decisions without saying so; a maturity map whose members all share one cell still prints the member list and its Mermaid source; the "joined members" column changes direction between the boundary tables; the roadmap Pack and the Roadmap lens use different words for the same entry and the Pack page never links back; the Pack titled "Spec Studio" gets the product's own browser title | +| Spec page ([the Studio root](https://libar-dev.github.io/software-delivery-protocol/preview/34/specs/consumers.spec-studio.html), [an `idea` story](https://libar-dev.github.io/software-delivery-protocol/preview/34/specs/consumers.ai-assisted-reading.html), [a `ready` example](https://libar-dev.github.io/software-delivery-protocol/preview/34/specs/consumers.readiness-planner.decision-first.html)) | Everything the graph holds about one Spec on one page, in panels a person opens and closes (`spec:consumers.spec-studio.spec-page`, with `spec:consumers.spec-studio.spec-page.core` and `spec:consumers.spec-studio.verification-panels`) | Understand one Spec: intent, rules, acceptance, verifiers and runs, realizing code, shaping decisions, impact. Every role; the newcomer best through Intent | Intent (actor, problem, outcome) opens in plain language; keyed rules carry addresses and copy actions; decision text inline; an open question reads as a complete decision brief with compose actions; an example leads with its Given/When/Then; fixed "not tracked" labels; an over-budget diagram says so and falls back to text | Every panel opens by default (`spec:consumers.spec-studio.spec-page#rule.panelOrder`) and relations are restated in several forms; impact to any depth has no ranking or summary; panels that do not apply to an example still render; an example's "implementation binding: none" carries no posture note; run evidence shows the whole test file without marking this Spec's rows; exercised rule keys are text, not links; a floor clause names the per-kind evidence table without linking `spec:validation.kind-evidence` or saying what to add | + +## Across pages + +### The honesty language is the asset to keep + +Every page keeps the epistemic line: the stated rung as a badge with the floor reached beside it +in words (`spec:consumers.spec-studio.shell#rule.rungBadge`); "implementation binding +present/none" instead of `implemented`; claim words on edges; "not tracked" for observation, +attestations, deployments and bills of materials; "external run evidence … from test files"; +explicit "None." for every absence. A redesign should reuse this wording whole. Its cost shows at +corpus scale: the same reassuring phrase repeats on almost every row. + +### Arrival and wayfinding + +- The top navigation lists every lens and register as an equal entry + (`spec:consumers.spec-studio.navigation#rule.topEntries`), with jargon labels ("Queue", + "Declarations", "Evidence") and labels shorter than their page headings ("Backlog" for "Design + backlog"). Nothing says which to open first. +- "Start here" is the best idea in the Studio, but it is partial by rule: the index's own task + routes plus roadmap, queue, architecture and diff + (`spec:consumers.spec-studio.index-page#rule.taskRoutes`, + `spec:consumers.spec-studio.navigation#rule.indexRoutes`). Capabilities, Tests, Evidence, Runs, + Questions, Decisions, Declarations, the design backlog and the Glossary have no task route. +- Lenses do not link to each other: tests to runs, architecture to tests, evidence to runs, the + roadmap Pack page to the Roadmap lens. +- The rail lists Packs on every page and comes before the page heading. On a Spec page it lists + every member of every Pack the Spec belongs to (`spec:consumers.spec-studio.shell#ui.leftRail`). + The self-hosting Pack holds the whole corpus, so every Spec page leads with the whole corpus as + links before its own content. This is the largest findability problem, and it is a design + question for the shell Spec, not a rendering defect. +- Index and search do not hand off: the index has facets and no text term, search has a text term + and no facets, and summary counts are not links into filters. + +### Unranked lists that repeat themselves + +Lists come in id or recipe order everywhere, so the few real signals (a stated rung below its +floor, a ready Spec without a verifier, a skipped test, a question open now) sit among long runs of +identical "ready · floor ready · present" rows. Several pages show the same thing in several forms: +drawing, text equivalent, Mermaid source and a table. Mermaid source and renderer notes are shown +to every reader. + +### Postures that aggregate views do not apply + +About half of the corpus is example Specs, and decision records are a sizeable group too. Under +the example realization posture (MD-24) and the decision readiness posture (MD-26) neither is build +work, and decisions are left out of verifier-gap signals while keeping an explicit count. Aggregate +views ignore this: the index, the capability rollups, the tests summary and Pack page totals count +them in the denominator, and their "none" reads as a gap. The Pack page explains decisions ("a decision +never needs a verifier binding"); nothing explains examples. + +### One concept, several numbers and words + +- **Questions** are counted differently on the index, the questions page, the owner queue, the + roadmap and the roadmap Pack page (all questions, blocking ones, the owner's, the roadmap's). Each + is right in its scope, and none says which scope it counts. +- **"State"** means two things. On the roadmap, "to state" means only a person's `ready` statement + stands before the entry; in the queue, a statement is any rung the floor allows. The same entry, + `spec:protocol.delivery-record-cleanup`, is "To design" on the roadmap and "can be made now" in + the queue (recipes 53 and 46). +- **"Nothing blocks"** (the stated next rung, per `CONTEXT.md`) sits beside a blocking question that + holds a higher rung, with no word on which rung each statement is about. +- **Findings** show the corpus total in the rail and the page's own scope in the header, side by + side and unlabelled. +- **Names** mix: Packs by title in the rail and by id in filters and rows; kinds as raw literals on + Pack cards and as named coordinates on Spec pages; ids on question and decision surfaces, titles + on statement rows. + +### The long-horizon agenda is hard to see + +Most blocking questions are deferrals the owner parked on a trigger (recipe 20 separates +`deferrals` from `holds`). Only the questions page shows the deferral and its trigger. The queue +drops both, and the roadmap keeps them inside its copyable memo, so parked questions read as work +waiting now. Delegated questions have no queue, and the token names nobody. No page can show how +long a question has been open, by design: git holds history +(`spec:consumers.spec-studio.shell#rule.noRecentEdits`; the history row in [07](07-graph-needs.md)). +For design questions that will be answered over months, this is the gap that matters most. + +### The basis needs the script + +The build writes no stamp into its pages +(`spec:consumers.spec-studio.sharing#rule.buildWritesNoStamp`), and the stamp line appears only when +the script loads it (`spec:consumers.spec-studio.shell#ui.stampLine`). Without script, or through +`file://`, no page states what it projects. With script, the line shows a full merge-commit hash +twice and the engine version `0.0.0`, with no pull-request number and no base. The runs page then +asks the reader to compare full hashes by eye. This is the material for the basis line proposed in +[04](04-reading-model-and-ia.md), a provisional term. + +### Engine and agent vocabulary on human pages + +Recipe numbers open several page ledes, unlinked, and no page read here links the recipe +catalogue. Clause ids (`no-blocking-open-questions`), "node", "unit edges", "not enumerable", +"distinct descendants" and camelCase relation names reach readers unexplained. The glossary cannot +help: by `spec:consumers.spec-studio.glossary-page#rule.noGlossaryDocument` it lists only +Model-section terms, and the Studio's own vocabulary lives in `CONTEXT.md`, which no page read here +links. + +### The composing panel and the page without script + +The composing panel sits on every page (`spec:consumers.spec-studio.intent-panel#rule.everyPage`), +including pages that offer no composing action, where its hint points at actions that are not +there. Without script every page but search reads in full +(`spec:consumers.spec-studio.shell#rule.withoutScript`); filters hide, but their "N of N shown" +counters stay, with no control beside them. + +### The Studio's own design record is split + +`pack:spec-studio-v1` is the first-version record of the Studio. Its framing cites a lineage +document and says "its four lenses", while its member `spec:consumers.spec-studio.lenses` is titled +"Five lenses read the graph as Packs, capabilities, architecture, tests and evidence". The Studio +Specs added later (roadmap page, slice page, capability map page, diagram kinds) sit in +`pack:roadmaps-and-slices-v1`. No single Pack page presents the Studio as it ships. A design +session records this and edits no Pack: regrouping the Studio's Specs, like a corpus home for the +design project, is a proposal for an engineering session and the owner. + +## Role coverage + +The job stories below are illustrative design material, not entries of `jtbd-stories/`; +[01](01-roles-and-perspectives.md) links each persona to its job-story ids. + +| Persona | Job | Best page today | What is missing | +|---|---|---|---| +| Technical product manager | When I survey a capability, I want to see how far its intent stands, so I can decide where to invest | Capabilities, Roadmap | progress rather than size; one line on where a capability stands | +| Readiness author / question decider | When statements and questions wait on me, I want them in the order that frees most, so I can settle them first | Owner queue, Open questions, Roadmap | decide-now apart from parked-until-trigger; delegated questions anywhere | +| Software architect | When a change touches structure, I want components, uses and the decisions that shape them, so I can judge its reach | Architecture, Decisions | links from components to tests and readiness; decisions findable by registry name | +| Engineer / implementer | When I pick work, I want the buildable Specs and their bound code, so I can start | Roadmap "Build now", Search | a build-backlog page (recipe 1) | +| Tester / QA | When I check verification, I want the real gaps first, so I can close them | Tests, Runs | gap-first order; decisions out of the gap count; failures findable in run lists | +| Engineering leader / project lead / auditor | When I report, I want a picture nobody wrote by hand, so I can trust it | Index summary, Evidence | change over time (git holds it, by design); who owns what (no graph value, by design) | +| Pull-request reviewer | When I open a preview link, I want to know what changed and on which commits, so I can review it | Design diff, Pack page | the pull request and both commits named in words on the page | +| Newcomer | When I meet the project, I want to know what it is and what its words mean, so I can find my way | Spec page Intent, decision titles | a landing that names the project and the Studio; a glossary covering the Studio's own words | + +## Drift the repository answers + +These are technical disagreements between a Studio Spec and its code or wiring, answered from the +repository rather than by design. They are recorded for an engineering session, which fixes the +stale side deliberately; this document changes nothing. + +1. The top navigation's Packs entry should link to the index's Packs section + (`spec:consumers.spec-studio.shell#ui.topNavigation`); the page frame + (`src/projections/studio/pages/frame.ts`) links the top of the index. +2. A finding with a file and no line never becomes a source link, because the source mark in + `src/projections/studio/pages/html.ts` needs both, although the source template's `{line}` is + optional (`spec:consumers.spec-studio.sharing#design.sourceTemplate`). +3. Count wording: index rows read "N open, M blocking questions" as two totals with a broken plural + (`index-page.ts`), and plurals break at one elsewhere ("1 verifiers", "1 unit edges"). +4. A Pack titled "Spec Studio" gets the product's own browser title, from the title rule in + `frame.ts`. +5. The diff page doubles its base label: the preview workflow passes `base ` + (`.github/workflows/studio-preview.yml`) and the page writes "the base graph" before it. +6. Joined test-file headings on the runs page carry a copy action and no source mark (`run-rows.ts`), + so they never link, even with a stamp. + +## What this baseline feeds + +- **The design cycles.** It gives [06](06-design-cycles.md)'s question "which current Studio pages + are retired, merged or kept" a page-by-page starting point, and the jobs in the tables are the + tasks cycle prototypes are measured against. +- **The AI reading trigger.** `spec:consumers.ai-assisted-reading#question.aiPresentationBoundary` + (stated `idea`, owner, deferred) opens when "the UX design pass measures that assistant selection + or a generated explanation helps a named review task". The jobs above are candidate named review + tasks. How such a measurement is recorded is an open question in + [06](06-design-cycles.md#ai-assisted-reading). +- **Graph needs** this baseline found (who acts on a `delegated` question, a route from a + decision's registry name to its Spec, question age) are logged in [07](07-graph-needs.md#log). +- **A long-horizon research backlog**, to be worked across design cycles rather than settled now: + - What a landing needs to orient a newcomer and route by role, and what it drops from today's + census-first index. + - Whether "decide now" and "parked until a trigger" become separate readings wherever questions + appear, and where delegated questions surface. + - What search ranks first (the defining Spec, the entry or the code), and whether entry addresses + and registry names become search terms. + - How a count states its scope, so one concept never shows different numbers unexplained. + - How the rail and panel defaults should behave when one Pack holds the whole corpus, and per kind. + - Which pages stay pages, which become parts of role homes (a provisional term), and which merge: + the roadmap Pack page and the Roadmap lens, the evidence lens and runs, the two backlogs. + + These questions are carried in [06](06-design-cycles.md#design-questions-for-the-long-horizon). + + A decision on any of these lands as a Studio Spec change through the authoring workflow, and the + Spec wins. The shipped projections stay frozen (MD-32) for the Design Review, census, Mermaid and + Gherkin; the Studio is not among them. +- **Commercial surfaces.** The page set read here is the open-source static Studio. A commercial + Studio (desktop app, web app, CI/CD surface) is under consideration and exploratory + ([04](04-reading-model-and-ia.md)); this baseline is its starting point too. diff --git a/docs/design/11-rup-roles-and-artifacts.md b/docs/design/11-rup-roles-and-artifacts.md new file mode 100644 index 00000000..f6558939 --- /dev/null +++ b/docs/design/11-rup-roles-and-artifacts.md @@ -0,0 +1,322 @@ +# 11 — RUP roles and artifacts + +This document maps the Rational Unified Process onto the Protocol's one graph: for each RUP role, the +questions it keeps asking and the readings that answer them, and for each RUP artifact, whether it +becomes a regenerable reading of the graph or is refused. It is design material, not intended +truth: where it disagrees with a Spec, the Spec wins. + +**How it was checked.** The recipe mapping was spot-checked, not exhaustively verified. Recipes 1, +2, 3, 4, 7, 8, 9, 10, 11, 13, 17, 20, 23, 24, 25, 26, 27, 28, 29, 31, 32, 34, 37, 39, 41, 43, 44, +46, 47, 51, 52, 53, 54 and 55 were run at commit `53804437` through `pnpm --silent sdp:q`, and each +answered the kind of question it is mapped to here. The Studio's recipe set was read from its +source. Every entry address cited below resolves under address resolution (recipe 25). RUP role and +artifact names come from the standard RUP role and artifact sets; the repository holds no RUP +catalogue, and names vary between RUP editions. + +## Disciplines are filters, never phases + +The Protocol adopts the established delivery nouns and rejects the process gates +([adopt the nouns, reject the gates, MD-2](../../specs/decisions/adopt-the-nouns.sdp.md)). Its +concept document on consumers and projections maps the classic disciplines onto the graph "as +filters rather than phases" +([`docs/concept/06`](../concept/06-consumers-and-projections.md), section 6). The carrying term is +**discipline** in [`spec:consumers.projections-model`](../../specs/consumers/projections-model.sdp.md): +"A filter that selects or groups Specs by kind or section; it is not a phase to pass through." +Phase, iteration and milestone are descriptive words a roadmap's framing may use, "never an entry +field, a date, a gate or an enforced sequence" +([`spec:consumers.projections-model.roadmap-views`](../../specs/consumers/projections-model.roadmap-views.sdp.md)). + +So every RUP role below maps to a **selection and an arrangement** over the same graph, never to a +stage it must pass. RUP's hump chart keeps its rows (disciplines) and loses its columns (phases as +gates); [01](01-roles-and-perspectives.md#the-rup-frame) has the discipline-to-selection table. + +The concept document maps seven disciplines. Implementation and Environment appear only in design +material ([01](01-roles-and-perspectives.md#the-rup-frame)), which is not intended truth; see +[Drift this mapping found](#drift-this-mapping-found). + +## Words in this document + +- **RUP role** always means a role in RUP's sense. The ratified word **role** names something else: + the one-token architectural pattern on a code anchor (the architectural-annotation ruling, + MD-38), which recipe 28 lists. This document never uses bare "role" for a person. +- **persona** is a provisional design term ([README](README.md#words-used-here)): the person we + design for. Each RUP role here is a candidate persona, and the tier column pairs it with the + persona in [01](01-roles-and-perspectives.md) it would fold into. The job stories in + [`jtbd-stories/`](../../jtbd-stories/README.md) deliberately avoid personas; where a RUP role has + matching job stories, the questions column names them (for example JS-G1). +- **lens** names one of the Studio's graph views; **perspective** names a reader's concern a Pack + is read from (recipe 37); **discipline** is the kind-or-section filter. They are not synonyms. +- The artifact **fit** labels in the second catalogue are provisional design terms, defined + there. + +## How to read the catalogues + +- Numbers in parentheses are recipes in the [catalogue](../agent-surface/recipes.md). Run one as + shipped: `pnpm --silent sdp:q "$(cat dist/recipes/NN-.js)" --params '{...}' --json`. +- **Current reading** names a Studio page, a frozen projection (the shipped-projections decision, + MD-32) or "CLI only" when no page runs the recipe. [10](10-studio-baseline.md) describes the + current page set. +- **Tier** follows [01](01-roles-and-perspectives.md): 1 for the core delivery personas (the first + cycles' focus), 2 extended, 3 niche and specialised, 4 ultra-specialised. Tiers are suggestions for the + design cycles, not rulings, and no lower tier is ruled out. +- Counts are never quoted. Where a gap depends on how much material exists, the cell names the + recipe or query that measures it. + +## Catalogue 1 — RUP roles by discipline + +### Business Modeling + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Business-Process Analyst | Which terms and business rules govern this capability? Does one word mean two things across Packs? | Model terms and term addresses; `rule` Specs and keyed rules; the `workflow` kind; 6, 23, 41, 28 | glossary, search, vault term notes | no context-to-term reading; the glossary lists terms alphabetically, one row per defining Spec, with no Pack or context grouping; above-epic altitude is deferred, so a business use case has no coordinate of its own | 2 · business / domain analyst | +| Business Designer | Which entities does the domain state? Which behaviors touch this term? How does one business use case realize? | `model` sections (terms with definitions, not typed entities); `refines`, `dependsOn`, `constrainedBy`; 19, 54, 22, 25 | `model` Spec pages, glossary | no entity, attribute or worker structure; term use is found by substring search unless authors write term addresses; people are not in the graph | 3 | +| Business Architect (later editions) | Which bounded contexts make up the domain? Which epics span which contexts? Which decisions shape the structure? | `context` on component anchors; component designs; 17, 32, 43, 28, 52, 18 | capabilities and architecture pages, read separately | nothing joins capabilities to contexts; the Protocol's own corpus anchors every component in the same context and states no planned component design (recipes 28 and 43 derive both), so this needs an adopter corpus | 3 | +| Business-Model Reviewer | Is the vocabulary coherent across this Pack? Is a term defined twice? Do domain Specs leave blocking questions? | perspective filter (37) with `select: { kinds: ["model"] }`; the glossary's same-word-twice rule; 20, 22 | glossary, Pack pages; perspectives CLI only | the Studio takes no perspective input; no Pack-level vocabulary reading; judging content stays human | 3 | + +### Requirements + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| System Analyst | Which capabilities exist and how far is each refined? What blocks one, and who decides? What changed since the last pass? Where next? (JS-A6, JS-E3, JS-F1) | `behavior` Specs, epics and refinement; 52, 53, 20, 54, 35, 11, 19 | capabilities, roadmap, questions and slice pages; diff page with a base graph | readings sit one collection at a time, with no home for "where does intent stand"; actors are free-text Intent lines, never a selectable value | 1 · technical product manager | +| Requirements Specifier | Which keyed rules does no example exercise? Which values does no example bind? What stands before the stated next rung? Do my mentions resolve? | 34, 44, 9, 7, 11, 22, 48, 23; authoring through the `sdp-authoring` skill | Spec page verification panels, tests page | 9, 7 and 11 have no page (divergence shows only in the frozen census); no cross-Spec author worklist; views never write (`spec:consumers.edit-model`) | 2 · requirements specifier | +| Requirements Reviewer | Can `ready` be stated for this Spec or Pack? Which blocking questions hold it? Does the floor agree with the stated rung? What does it rest on? | 29, 54, 21, 30, 46, 9, 20 | Pack pages with the maturity map, Spec pages, queue page, frozen Design Review | validators never record or require review approval ([`spec:consumers.design-review`](../../specs/consumers/design-review.sdp.md)), and that a review happened is never a graph fact; the "review a Pack for readiness" flow is missing | 1 · readiness author / question decider | +| User-Interface Designer | Which UI entries describe this screen, and which behavior do they serve? Which have no example or bound unit? What changed? | keyed `ui` entries (`spec:#ui.`); 23, 25, 35 | UI panel on Spec pages | no visual artifacts or design-tool links; no register of UI entries; an example exercises rule keys only, never a UI entry; product designers are a later audience | 3 | + +### Analysis & Design + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Software Architect | Which components exist, by context and layer, and how do they use each other? Planned against realized? Which dependencies cross a forbidden pair? What does a change reach? (JS-G1, JS-G5) | 17, 12, 13, 14, 32, 42, 43, 28, 18, 31, 40, 30; significance annotated where realized (MD-38) | architecture and decisions pages, scoped-architecture drawings, frozen Mermaid view | 32, 42, 18 and 40 CLI only; the Studio has no changeset input; planned-beside-built is empty on the Protocol's own pages (43); no deployment view | 1 · software architect | +| Designer | What does this design pin? Which Specs rest on it? Which source lines cite a declaration? Which features read together? | `design` entries, 24, 51, 41, 27, 54, 30, 36, 39 | declarations, Spec and slice pages | the cited line's words wait on a roadmap entry (`spec:consumers.spec-studio.cited-line-text`); 41, 27 and 39 CLI only, so the step where a design thins once code carries it has no page | 2 | +| Database Designer | Which Specs define stored data or storage keys? Which contracts fix a stored shape? What breaks if a schema changes? | `model` and `contract` Specs; 41, 24, 4 | Spec pages, declarations page | no persistence or schema concept (concept search finds no Spec about data design); migrations have no reading | 3 | +| Capsule Designer | Which units run concurrently, over what protocol? Which timing constraints hold? | only indirect: free `role` tokens on code anchors (28), `contract` Specs, constraint targets | none | no concurrency, port or timing model; any reading would be corpus data; timing waits on the deferred `observed` fact | 4 | +| Architecture Reviewer | Are forbidden layer directions and isolated contexts honoured? Which planned components are unrealized? Which decisions shape this, and is any superseded? Which NFRs constrain it? | 42 as a corpus rule under `sdp validate --rules`; 32, 43, 18; 37 with its `bindings` selector | architecture and decisions pages; walk findings CLI only | no architecture review reading; NFR material is thin in the Protocol's own corpus; the Studio cannot apply a team's perspective, such as a security one | 2 | +| Design Reviewer | Where does each member of this Pack stand? What changed since the last pass? Which code answers to the design? Can the Pack be stated `ready`? | 29, 5, 54, 35, 27, 36, 37, 38, 49; the Pack design page (MD-39) | Pack and slice pages, diff page with a base graph, frozen Design Review, composing panel, vault iteration | the best-served RUP role; lacks the "review a Pack for readiness" flow, a perspective selector, and a page for 27 | 1 · readiness author / question decider | + +### Implementation + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Implementer | What next? What does this Spec guarantee, and who verifies it? What does my diff reach, and what can the graph not see? Is code ahead of intent? What do I hand my agent? (JS-G1, JS-G2, JS-E2) | 1, 3, 4, 2, 36, 21, 51; `g.byFile`, `g.blastRadius` | Spec pages; roadmap page (to build, drift); mainly the agent surface (`sdp q`) | no page runs 1 or 2, and the "Backlog" navigation entry is the design backlog (33); no changeset landing | 1 · engineer / implementer | +| Integrator | In what order do components depend on each other? Which components does a change reach? Did the integrated build pass? | 13, 17, 26, 4; 45, never a verdict | architecture page; runs page with run records | build and integration belong to CI; `dependsOn` is design dependency, never build order, and scheduling phrases are never authored (the planning-truths decision, MD-33); a component order could derive from anchored `uses`, but no reader has asked | 3 | +| Code Reviewer | Which Specs does a pull request touch; is a binding new or broken? Does each anchor honestly `satisfies` or only `references`? Do cited addresses resolve? Which load-bearing files lack an anchor? | 4, 22, 51, 25, 27, 40, 2 | none takes a changeset; the diff page shows design change only, with a base graph | the pull-request change narrative (design diff, blast radius, queue movement) is derivable but not built; code findings stay pull-request comments, outside the graph | 2 · pull-request reviewer | + +### Test + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Test Manager | How far does verification reach? Which ready Specs have no verifier? Are declared verifiers enabled? What did the last supplied run report? | 8, 10, 34, 44, 45 over the `has-verifier` fact | tests page, runs page with run records, index findings | no per-Pack test-evaluation reading; 10 has no page; evidence joins at file grain and is never a verdict; freshness is a Spec stated `idea` | 2 | +| Test Analyst | Which rules have no example? Which outcome classes or slot values lack a witness? Which behaviors have no example space? Which questions leave outcomes unspecified? (JS-G2, JS-G4) | 34, 44, oracles (`unspecified` is a first-class answer), 20 | tests page, rule-coverage rows on Spec pages | no example-space explorer; no outcome-class coverage per space; a test idea is an `example` at `idea`, visible only through 11, CLI only | 1 · Tester / QA | +| Test Designer | Which oracle models which space? Which examples bind which points? Is every example backed by a resolving test anchor? Where are tests anchored? | test and oracle anchors, step contracts, example spaces and oracles; 10, 44 | tests page, frozen Gherkin-shaped view, Spec pages | no matrix reading of a space; no oracle register; test environment and data are outside the graph | 2 | +| Tester | Which tests verify this Spec? Which examples does my test file bind? What did this run report for files bound to it? Which Specs does a failing file reach? | 3, `g.byFile`, 45, 4 | Spec verification panels, runs page with run records, Gherkin view | evidence joins at test-file grain; defects have no graph home; no reading leads from a failing file to the Specs at risk | 1 · Tester / QA | + +### Deployment + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Deployment Manager | What does this release contain? Is this Spec live? Are NFR targets met? What is in the bill of materials? | `observed` is designed and deferred (`spec:observation.runtime-overlay`, stated `idea`, held by `#observationIdentity`); a release is a git-tag projection | evidence page, where every source reads "not tracked" | everything, by design, until a reader is named: release and baseline views wait on `#releaseReader` | 3 · release or deployment manager | +| Course Developer | In what order should a newcomer read this capability? Which examples teach a behavior best? | 52, 54, Model terms, examples with expected outcomes, the Pack export | glossary, capabilities page, Pack export | no ordered tour; an outside reader waits on `#namedOutsideReader`; concept search finds no onboarding or training material | 4 | +| Technical Writer | What is the current reference for this interface? Which Specs describe outward behavior? What changed for users since the last release? | the reference projection, stated `idea` (`#namedOutsideReader` blocks; `#referenceSource` asks what would feed it); 24, 39, 35, the Pack export | Pack export; every page prints as a document; glossary | no reference projection until an outside reader is named; no release notes while release views are deferred | 3 | +| Graphic Artist | Which screens need artwork, and in which states? | none; `ui` entries are text | none | out of scope until the UI library and design system arrive; product designers are a later audience | 4 | + +### Configuration & Change Management + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Configuration Manager | Which commit and engine does this reading project? What changed between two commits? What does a baseline contain? Can I rebuild the graph at an old commit? (JS-C4) | git is the event log; 35 against a supplied base graph; the stamp; engine provenance (`sdp --version`) | diff page with a base graph; the stamp in the Studio shell | no status accounting over history, because no projection reads git yet; baseline views wait on `#releaseReader`; the stamp is not explained in words | 2 · change / configuration manager | +| Change Control Manager | Which change proposals exist, against which base? Is each scope moved, unresolved or incomparable? What does a design change reach? | the change proposal (`schemas/sdp-proposal-1.schema.json`); 38, 49, 30, 35, 48 | composing panel, diff page, memos on the pull request | by law a proposal carries no status, approval or verdict ([`spec:consumers.intent-composition.proposal`](../../specs/consumers/intent-composition.proposal.sdp.md)), so there is no change-request register or board disposition; open proposals live in pull requests, an outside input | 2 · change / configuration manager | + +### Project Management + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Project Manager | What comes next, and does each entry need design, a statement or building? What waits on a person? Where does each capability stand? What is at risk? | 53 and 55 over `pack:roadmap` (a roadmap states advisory priority, MD-46); 46, 52, 1, 33, 11, 20 | roadmap, queue and capabilities pages; the roadmap memo in pull-request descriptions | several needs are refused by law (dates, status, gates, percent complete, scheduling phrases); actually missing: people and ownership, a risk list beyond blocking questions, a time series | 1 · engineering leader / project lead / auditor | +| Project Reviewer (Management Reviewer in earlier editions) | Can I trust this picture without hand-authored status? Do stated readiness and realization agree? Which decisions shape the work? What does the corpus say it does not know? | the census; 11, 7, 31, 53, 2, 8 | frozen census, index findings, roadmap and decisions pages | milestone review as a gate is refused; baseline approval is a signed git tag outside the model; an honest leader reading combining readiness, realization and decisions is missing | 2 · shares the tier-1 leader's reading | + +### Environment + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Process Engineer | Which Protocol capabilities does this corpus use, and where could each apply? Which corpus rules should run? How do agents enter work? What does an upgrade change? | 47, 48, 50; rules files (25, 26, 42, 50, 51); the upgrade kit reports and proposes, never edits; work shapes are neither phases nor a required sequence | CLI only; the `sdp-sessions` and `sdp-authoring` skills; the upgrade guide | no adoption board; Environment is missing from the concept document; an authored development case would be the process state the adopt-the-nouns decision (MD-2) refuses | 2 · process engineer / adoption lead | +| Tool Specialist | Which engine and commit built this? How do I wire `sdp` into CI, the vault and previews? Which recipe answers which task? | engine provenance, the adopter on-ramp, validate watch, the vault, 47, the reading skill's recipe task table | README, skills, recipe catalogue; the stamp | tool guidance is hand-written prose; no page shows the recipes, inputs or capabilities a page set used | 3 | +| System Administrator | Where is this preview hosted, and which build is it? Did publishing run? | publishing is a CI step, never the build (`spec:consumers.spec-studio.sharing#rule.publishingStep`); the stamp; engine provenance | the stamp | infrastructure is outside the graph by design | 4 | + +### Additional RUP roles (across disciplines) + +| RUP role | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Stakeholder | Where, honestly, does the capability I care about stand? What does the behavior do for these inputs? Can I send a change request without learning the repository? (JS-E3) | 52, 53, the Pack export, example spaces with oracles, stamped previews | a preview link, Pack export, composing panel, phone layout | no short sponsor-level account, and one must not become a progress score; no example-space explorer; discussion lives in the pull request | 2 · stakeholder in a review; sponsor | +| Any Role | Where is this term, Spec or file? What does this address point at? What does this reading project, and is it current? How do I hand a change to an agent? | 6, 23, 25; `g.findByConcept`, `g.byFile`, `g.blastRadius`; the stamp; the composing panel | search, glossary, Spec and Pack pages, navigation, composing panel | the shared base every role home builds on; missing arrival by question, role or changeset, a basis line (provisional term), and object pages for questions and decisions | 1 · shared base | +| Technical Reviewer | What does this artifact say, and what does it rest on? What changed since I last read it? How do I return findings so they are applied? | the change proposal; 38, 49, 35, 36 | object pages, composing panel, diff page | findings travel as proposals or pull-request comments and never enter the graph; no page reads returned proposals | 2 · pull-request reviewer | +| Review Coordinator | Which reviews are due, and who reviews what? Which findings remain open? | 46 by decider; the question fields `decider`, `links`, `provisional`, `trigger` | queue page | reviewer assignment is impossible because no node has an owner; review records are refused by law; scheduling is refused (the planning-truths decision, MD-33); the honest reading is a decider's queue | 3 | + +### Protocol-native (not a RUP role) + +| Persona | Recurring questions | What the graph holds | Current reading | Gap | Tier | +|---|---|---|---|---|---| +| Readiness author / question decider | Which statements can I make now, and in what order? Which of my questions hold other Specs? What stands before the stated next rung? Does the floor agree with what I would state? (JS-E4) | 46, 9, 29, 7, 21, 20, 31 | queue page, Pack pages with the maturity map, frozen Design Review | promotion preflight (9) has no page; the queue selects by decider token, not by person; the "review a Pack for readiness" flow is a first-cycle brief ([06](06-design-cycles.md)) | 1 · readiness author / question decider | + +It combines RUP's stakeholder sign-off, requirements and design review, and project-review approval, +with no gate: a readiness author states readiness by editing a carrier, and the decider a question +names settles it. + +### Tiers at a glance + +| Tier | RUP roles | +|---|---| +| 1 | System Analyst, Requirements Reviewer, Software Architect, Design Reviewer, Implementer, Test Analyst, Tester, Project Manager, Any Role, and the Protocol-native readiness author / question decider | +| 2 | Business-Process Analyst, Requirements Specifier, Designer, Architecture Reviewer, Code Reviewer, Test Manager, Test Designer, Configuration Manager, Change Control Manager, Project Reviewer, Process Engineer, Stakeholder, Technical Reviewer | +| 3 | Business Designer, Business Architect, Business-Model Reviewer, User-Interface Designer, Database Designer, Integrator, Deployment Manager, Technical Writer, Tool Specialist, Review Coordinator | +| 4 | Capsule Designer, Course Developer, Graphic Artist, System Administrator | + +Two placements depart from [01](01-roles-and-perspectives.md). The Project Reviewer sits at tier 2 +because its milestone form is refused, while its honest reading is the tier-1 leader's. The Test +Analyst sits at tier 1 because rule and example-space coverage are the Tester / QA persona's core +questions. + +Non-human readers are not RUP roles and have no rows. The coding agent reads through `sdp q`, the +recipes and context bundles. CI runs the checks and builds the Studio preview, whose roadmap page +shows recipe 55's memo; a pull request's forward section is rendered by its author +([01](01-roles-and-perspectives.md#non-human-readers)). Every human reading should hand the same +scope to an agent. + +## Catalogue 2 — RUP artifacts as projections + +In RUP each artifact is a document someone writes and keeps current. Here, an artifact that states +intended system truth becomes a **reading of the one graph**: a pure, regenerable function of it, +never a second source of truth (the projection law, `spec:consumers.projections-model`). Nobody +keeps it current, because it is rebuilt from the Specs each time. + +An artifact that carries **process state** (schedule, approval, assignment, or the fact that a +review happened) is refused. The governing rubric in [`CONTEXT.md`](../../CONTEXT.md) says: +"Reject process state-machine / lifecycle gating (sprint/ticket FSM, mandatory phase gates). Adopt +the process nouns, not the process gates." Where the information is honest, the table names the +reading that re-derives it. + +| Fit (provisional) | Meaning | +|---|---| +| projection-available | a recipe or page derives it today | +| projection-possible | the graph holds the material; a carrying Spec plus a recipe or page would derive it, with no model change | +| partly-modelled | some of its content has a graph home; the rest has none | +| not-modelled | no graph material; deferred behind an owner question or out of scope | +| rejected | carries process state the rubric refuses; a derived substitute is named where one exists | + +| Discipline | RUP artifact | Fit | How it would be derived, or what replaces it | +|---|---|---|---| +| Business Modeling | Business Use-Case Model | partly-modelled | `workflow` and `behavior` Specs with Intent actor, problem and outcome, scoped by a Pack or a perspective (37), read through the capability map (52). No descriptor separates business from system use cases, and actors are free text. A business scope would be a Pack or a perspective, never a new kind (one primitive, named coordinates, MD-4) | +| | Business Object / Domain Model | partly-modelled | `model` Specs' terms and term addresses, through the glossary page, 23 and 6. Terms carry definitions, not attributes, associations or multiplicity | +| | Business Rules | projection-possible | `rule` Specs plus keyed rules (`spec:#rule.`), with rule coverage (34). No corpus-wide register exists: 34 refuses without a Spec or Pack scope, and a rule may stay inline or be promoted to its own Spec, so a register must read both | +| Requirements | Vision | projection-possible | Intent of epic Specs, the capability map (52) as the feature tree, `constraint` Specs, Pack framing and the roadmap (53). Stakeholders and market position are not modelled; the Protocol's own vision is still a hand-written concept document | +| | Glossary | projection-available | the Studio glossary page, the vault's term notes, 23 and 6. The page renders no separate glossary document and shows a word defined twice side by side. `CONTEXT.md` stays hand-authored, and no check compares it with the projected terms | +| | Stakeholder Requests | partly-modelled | `idea`-rung captures (`spec:consumers.graph-first-planning`), open questions (20), change proposals (38, 49). There is no stakeholder entity; a proposal carries no proposer and no status; tracker items stay in the tracker | +| | Use-Case Model | projection-available | `behavior` Specs refined epic to feature to story, read by the capability map (52), with a Design Review and Studio page per Spec; flows on `workflow` Specs; examples as scenarios. An actor-to-use-case diagram is only possible, because actors are free text | +| | Supplementary Specification (NFRs) | projection-possible | `constraint` Specs (statement, flavor, target, how it is measured) linked by `constrainedBy`, grouped by flavor. No recipe or page lists them yet; the NFR board in [05](05-specialised-and-ai-readings.md) is a candidate. Attainment waits on the deferred `observed` fact | +| | Requirements Management Plan | rejected | The typed half is the meta-model as code (the executable meta-model, MD-1), whose taxonomy the census projects; project policy becomes corpus rules under `sdp validate --rules`. The control half (approval, change boards, status attributes) is the gating the rubric refuses | +| | Requirements Attributes | partly-modelled | kind, altitude, stated and derived readiness, delivery facts, question fields, Pack membership, a place on a roadmap, Intent risk. "Status" is an alias to avoid; priority is advisory, with no date or gate (a roadmap states advisory priority, MD-46); there is no owner; target release waits on `#releaseReader` | +| | Software Requirements Specification | projection-available | the Pack export: one self-contained file holding a Pack page and its members in authored order; every page prints as a document; the design slice (54) reads a Pack as one design. Its scope is a Pack, not a template; the export holds no time or commit, so a version comes from the stamp or git | +| | Requirements traceability | projection-available | 3, 4, 18, 27, 30, and the requirement-trace drawing, which keeps claims apart (`spec:consumers.spec-studio.diagram-kinds.requirement-trace#rule.claimsApart`). `has-verifier` means a binding exists, not that a test passed; `implemented` never travels through refinement | +| Analysis & Design | Software Architecture Document | partly-modelled | logical and implementation views from 17, 32, 28, 43, 42 and the architecture page; decisions from 31, 18 and the decisions page; the use-case view from 52; a scoped-architecture drawing per Pack or slice. Process and deployment views have no material, and the architecture lens draws no port, external system or runtime layer | +| | Design Model | partly-modelled | open Design and UI entries, pinned declarations (24, with citing lines from 51), `contract` Specs, component designs (43), and anchored code units with `role`, `memberOf` and `uses`. Open sections stay open bags under the typing law, so classes and interactions are not typed | +| | Analysis Model | rejected | Its content is enriched in place on the same Spec, and a corpus-owned `role` can name a pattern. A separate model later transformed into another is the migration principle P4 forbids (one primitive, named coordinates, MD-4). This refuses an artifact type, not a workflow | +| | Use-Case Realization | partly-modelled | the units that satisfy or reference a behavior (3, 27), the requirement-trace and scoped-architecture drawings. Which units realize a use case is derivable; how they interact is not, because `uses` is static | +| | Data Model | partly-modelled | `model` terms, declarations that pin a type or table, the key-family register (41). There is no entity, key or relationship schema | +| | Interface specification / API reference | partly-modelled | `contract` Specs, pinned declarations (24), `api:` anchors. The reference projection is stated `idea` and held by `#namedOutsideReader` | +| | UI Prototype / Storyboard / Navigation Map | partly-modelled | keyed `ui` entries on Spec pages. There is no navigation structure, and Specs reference design artifacts, never own them | +| | Deployment Model | not-modelled | nearest material: the `infrastructure` layer value on a component. Deployments read "not tracked" (`spec:consumers.spec-studio.lenses.evidence#rule.notTracked`) | +| Implementation | Implementation Model | projection-available | code units from `impl:`, `api:` and `component:` anchors with `memberOf`, `uses`, `satisfies` and `references`; 12, 13, 14, 17; the census structural section; `g.byFile`. Curated and sparse by design; import structure is the separate inferred impact graph, and the curation report (40) ranks files the anchors miss | +| | Integration Build Plan | rejected | Substitute: the build backlog (1), each roadmap entry's need (53), dependency footing (21), dependency cycles (26), the statement queue's rounds (46). Planning truths live in ruled graph homes (MD-33): scheduling phrases are never authored, and no recipe or plan document "authorizes, blocks, or sequences delivery work" (`spec:consumers.graph-first-planning`) | +| Test | Test Plan | partly-modelled | Verification sections (mode and criteria), example spaces and `verifies`; the tests lens; 8, 10, 34, 44. The verification mode is authored posture, never the derived enabled verifier; environment and resources are not modelled; a test schedule or phase gate is refused | +| | Test Idea List | projection-available | 34, 44 and the honesty gaps (8), filtered in the tests lens. These are informative absences, never a gate; unkeyed rules are counted apart | +| | Test Case | projection-available | `example` Specs, one bound point each (point-per-example, MD-17), with a given-when-then fence and `verifies` naming the rule keys exercised; the Gherkin-shaped view; verification panels; 3, 10 | +| | Test Script / Test Data | projection-available | step and space contracts derived per example (`spec:extraction.executable-contracts`); bound points are the data and the oracle gives the expected outcome. The script itself is ordinary test code bound by a test anchor, never a document | +| | Test Results / Test Log | projection-available (named input) | run evidence (45) over supplied CTRF reports, shown on the runs page, in the tests lens and on Spec pages. Run records are never graph data, join at file grain, and are never a verdict (`spec:observation.run-evidence#rule.graphUntouched`) | +| | Test Evaluation Summary | projection-available (measures only) | the sentences that open the tests lens, counted from the recipes (`spec:consumers.spec-studio.lenses.tests#rule.testsSummary`); 10. The measures are projected; the evaluation stays a human act | +| Deployment | Deployment Plan | not-modelled | none. A rollout schedule would also fall under the refusal of recorded work order (the planning-truths decision, MD-33) | +| | Release Notes | projection-possible | the design diff (35) with the previous release's graph as its base; known issues from the question register (20). Release views wait on `#releaseReader`, whose trigger is the first published release | +| | Bill of Materials | not-modelled | nearest material: engine provenance and the stamp, which is never graph data. Bills of materials read "not tracked" | +| | End-User Support / Training Material | not-modelled | nearest designed reader: the `idea`-rung reference projection. The Protocol is not a replacement for adjacent tools | +| Configuration & Change Management | Change Request | partly-modelled (named input) | the change proposal against a base commit, checked by 38 and rendered by 49; the composing panel gathers scoped intent. No status, approval, verdict or proposer; code defects stay pull-request comments; a change-request lifecycle is refused | +| | Configuration Management Plan | rejected | git is the configuration-management system and the event log; a baseline is a signed git tag, and approval stays outside the model | +| | Configuration Audit Findings | projection-available | the validation report (`report`, both check families); 2, 7, 8, 22, 25, 40; the census findings; the `--check-clean` regenerability checks. "Deterministically validated," never "provably correct"; a physical audit of a release baseline waits on release views | +| Project Management | Software Development Plan | rejected | Substitute: a roadmap Pack read by 53, rendered by 55 and shown on the roadmap page; a Pack per body of work; `trigger` lines on deferred questions. Priority "carries no date, no dependency, no status and no gate" ([`spec:decisions.roadmap-priority`](../../specs/decisions/roadmap-priority.sdp.md)) | +| | Iteration Plan | rejected | Substitute: the arc's Pack and its draft pull request; 29, 54, 55. The Protocol "adds no plan file and no review file" (the roadmap and the pull request over plan and review files, MD-47) | +| | Status Assessment | rejected | Substitute: each roadmap entry's need (53), capability map totals (52), readiness divergence in the census, 11, 46. Authoring a delivery fact is an honesty violation, readiness is never status, and the map states no percent complete | +| | Iteration Assessment | rejected | Substitute: the design diff (35) from the arc's base, plus the pull request description. The diff "never records that a pass happened" (`spec:consumers.design-diff`) | +| | Risk List | projection-possible | aggregate the repeatable Intent `risk` entries; the register built today is the blocking questions (20). No recipe or page aggregates risks; probability, impact, mitigation and owner are not modelled, and a risk status would be the refused status machine | +| | Business Case | partly-modelled | Intent value, problem and outcome on epics; capability map totals. Cost, return and funding are not modelled, and no Spec rules on whether estimates would ever be admitted | +| | Review Record | rejected | Substitute: the review context on Design Review and Studio pages; findings as change proposals with a memo (49) on the pull request; an open finding becomes an open question. That a review happened is never a graph fact | +| | Issues List | projection-available | the open-question register (20) and the questions page, with the blocking flag, decider, provisional reading, trigger and links. Questions with no decider are counted apart (`spec:consumers.readiness-planner#rule.undecided`); an issue not tied to a Spec belongs in the tracker | +| | Work Order | rejected | Substitute: scoped intent from the composing panel, or a context bundle (36), handed to an agent. No recipe authorizes work; access control stays in git and CI | +| | Project Measurements | projection-available | census counts and findings, capability adoption (47), and the totals of 52, 53 and each recipe. No score or quota; trends would need a projection that reads git, which is not built | +| Environment | Development Case | rejected | Descriptive substitute: capability adoption (47); advisory work shapes in the `sdp-sessions` skill. Mandatory artifact sets contradict "never a quota of artifacts to produce" (principle P4's corollary) and the refusal of workflow gating | +| | Project-Specific Guidelines | partly-modelled | a checkable guideline as a `constraint` Spec plus a corpus rule under `sdp validate --rules` (42, 25, 26, 50, 51); prose guidance stays in skills and docs. Corpus findings stand outside the two check families | + +### The pattern + +1. **Artifacts that state intended system truth** (requirements, use cases, rules, NFRs, design, + tests, traceability) are projections of Specs: available today, or possible without a model + change. +2. **Artifacts that carry process state** (development and iteration plans, status and iteration + assessments, review records, work orders, the integration build plan, the configuration + management plan, the development case, the control half of the requirements management plan) + are refused by the governing rubric. Their honest information is re-derived instead, through + the roadmap (53, 55), the census, the design diff (35) and the statement queue (46). +3. **Runtime, deployment and release evidence** is not modelled yet. It waits behind owner + questions already in the corpus. + +Some artifacts are views of a **named input** beside the graph, not pure projections: test results +(run records), change requests (a proposal document), and release notes or an iteration assessment +(a base graph). [`CONTEXT.md`](../../CONTEXT.md) admits such an input only when it is identified +apart from the graph and never answers in its name, and the Studio accepts exactly the base graph +and run records (`spec:consumers.spec-studio#rule.namedInputs`). + +Any new RUP-shaped reading meets four constraints. The four shipped projections stay frozen (the +shipped-projections decision, MD-32), so it is a recipe, a Studio page or a new projection Spec, +never a reshaping of the Design Review, census, Mermaid or Gherkin view. Deterministic derivation +keeps dates and commits off pages; those come from the stamp or git. Sinks rank agents first, human +views second, document exports last. And the growth valve is a recipe: a join freezes into the +reader only at the second-caller bar. + +## Long-horizon research backlog + +The repository answers the technical mapping above. The design questions the RUP roles raise will be +answered over many months of iterative design cycles ([06](06-design-cycles.md), +[08](08-what-the-repo-settles.md)). They are research threads, not owner to-dos to settle now. + +- **Owner questions already in the corpus** hold the not-modelled and deferred artifacts: + `spec:consumers.projections-model.roadmap-views#question.releaseReader` (release notes, release + and baseline views; trigger: the first published release), + `spec:observation.runtime-overlay#question.observationIdentity` (deployment model and plan, NFR + attainment, a process view), `spec:consumers.reference-projection#question.namedOutsideReader` + and its non-blocking `#question.referenceSource` (API reference, end-user material), and + `spec:consumers.ai-assisted-reading#question.aiPresentationBoundary` (any assistant-written + narrative, such as a status summary). MCP integration stays designed-in and deferred (the + MCP-deferred decision, D6). +- **Questions no Spec rules on**: whether stakeholder entities, a business-versus-system use-case + scope, cost or effort estimates, risk probability and impact, people and ownership, or readings + derived from git history will ever enter the model. People and history already sit in the + [graph needs log](07-graph-needs.md). +- **Cheapest projection-possible readings**, needing no model change, only a carrying Spec plus a + recipe or page: a risk list, an NFR board, a business-rules register across the corpus, a vision + reading, and an actor catalogue from Intent actor lines. Each would need its carrying Spec + authored in an engineering session; a design session only records the need. +- **Test bed.** The Protocol's own corpus is thin for Business Modeling, NFRs and planned + architecture, so readings for those RUP roles need an adopter corpus or the worked example + (`examples/checkout-v1`). + +The design questions here are carried in +[06](06-design-cycles.md#design-questions-for-the-long-horizon); the owner questions above stay in +the corpus. + +## Drift this mapping found + +Recorded for an engineering session to resolve; this document does not settle any of it. + +- The concept document on consumers and projections maps seven disciplines in section 6 and omits + Implementation and Environment. Their mappings exist only in design material. +- The same document lists the Spec Studio under surfaces "designed and not built", yet + `spec:consumers.spec-studio` states `ready` and carries `implemented` and `has-verifier`. +- It calls the capability map "designed-for, unbuilt", yet `spec:consumers.capability-map` carries + `implemented` (recipe 52, the capabilities page). +- It calls the roadmap views deferred, yet the roadmap reading is built (`spec:consumers.roadmap`); + only the release and baseline views remain deferred. diff --git a/docs/design/12-analogous-products.md b/docs/design/12-analogous-products.md new file mode 100644 index 00000000..a3f55262 --- /dev/null +++ b/docs/design/12-analogous-products.md @@ -0,0 +1,252 @@ +# 12 — Analogous products + +This document condenses a survey of products that work on problems next to the Protocol's, from +developer portals and architecture as code to requirements tools, living documentation and AI +spec-driven development, into what each one teaches the design of the Protocol's readings. It is +design material, not intended truth: where it touches what a projection does, the carrying Specs +win on conflict. + +**About the product facts.** They were gathered from public pages (vendor documentation, blogs, +community threads and a few third-party reviews) and may change. Products in this space are renamed, +acquired, repositioned or shut down often, and several below already have been. Each category ends +with its sources; check a product again before relying on a detail. + +**About the Protocol claims.** Every statement about what the Protocol does was checked against the +graph; the queries are listed in [the last section](#how-the-protocol-claims-were-checked). The +design words the [README](README.md#words-used-here) marks provisional (reading, persona, role home, +object page, basis line) keep that status here. Every lesson is a candidate for the design pass, +not a commitment. + +## How to read the tables + +Each product gets one row: + +- **Where truth lives:** the product's source of truth and how its views are derived from it. +- **Role-specific views:** who gets which view, and whether the views are designed or configured. +- **Lesson:** one idea worth carrying over, put into Protocol terms. Anti-patterns are folded into + the lessons and into the [cross-cutting lessons](#cross-cutting-lessons). + +## Developer portals and architecture as code + +| Product | Where truth lives | Role-specific views | Lesson for the Protocol | +|---|---|---|---| +| **Backstage** (software catalog, TechDocs, catalog graph) | Hand-written YAML descriptors in each repository, ingested into a database. Relations are derived by processors, never authored. TechDocs is Markdown built to static HTML in CI. The served catalog lags the repository and names no commit. | By entity kind, not by role: each kind gets a page assembled in code from plugin cards. Leader views come only from plugins. | Put a Spec's own findings and absences in a fixed, unconditional region of every reading of it. Backstage has an orphan banner and a processing-error panel, but they appear only where someone wired them in. | +| **Tech Insights and Soundcheck** (scorecards for Backstage) | Time-stamped facts collected on a schedule, beside checks declared in configuration that judge those facts. | Owners get a scorecard tab. Leaders get a group picker, summary tiles, a compliance table and drill-down to teams "needing attention". | Borrow the drill-down (scope picker, tiles, table, pre-filtered list) without the compliance percentage. Navigate the graph's own hierarchy (roadmap entry, Pack, Spec), show counts of named kinds, and make each count open the list behind it. | +| **Port** | The vendor's database. Its schema can be edited in the UI, through infrastructure as code, or by asking an assistant in natural language. Derived values are typed as derived (mirror, aggregation, calculation). | A personal home ("my entities"), private and shared pages, and a column per scorecard rule in every catalog table. | Give every table of Specs automatic columns for delivery facts and findings, mark each cell with its claim or its outside input, and never total the columns into a percentage. | +| **Cortex** | YAML descriptors, edited in the UI or owned by Git, chosen per entity type. In one documented mode the UI silently overrides Git. A query language evaluates scorecard rules. | A "my work" homepage of failing rules with due dates, catalogs per type, leader metrics, and an MCP server for assistants. | Every finding and every absent cell should carry what produced it: the edge, entry address, source line and recipe. Cortex puts the failing value inside the rule's message, so the reason sits in the finding. | +| **OpsLevel** | A SaaS catalog with optional repository YAML. Checks form a rubric of categories by levels, and a service's level is computed. | A Maturity Report answers the service owner's "why this level, and what comes next". Leaders get roll-ups; campaigns push standards. | Base the readiness author's "what stands before the stated next rung" reading on this layout: the four rungs as columns, the stated rung beside the floor reached, and under each rung the unmet floor clauses with their locations. Replace OpsLevel's "Fix This" with composing scoped intent, so the view stays read-only. | +| **Structurizr** | A plain-text DSL workspace in the repository: one model, many views, documentation and decision records. CI validates and exports it. | By C4 level: system context for non-technical readers, containers and components for engineers, deployment for operations. Filtered views by tag, and question-driven overlays it calls perspectives. Its own docs say the as-code approach shuts out people who do not write code. | Build role readings as selections over a few shared readings (Pack, Spec, architecture, roadmap), so a Spec reads the same in every role and only selection and emphasis change. A lighter export must say what it left out: Structurizr's static site drops documentation and decisions without saying so. | +| **LikeC4** | A typed DSL in the repository. Views are predicates over the model. An MCP tool returns an element together with the views it appears in. | Views scoped to an element with click-through drill-down, a landing page curated by tags, and embeddable views. | Keep each role reading's selection as reviewable text, the way a perspective (recipe 37) is corpus data. Show on each Spec which readings include it, so a Spec no reading selects becomes a visible absence. | +| **IcePanel** | A shared model in the vendor's service; drafts fork it for future-state design. Links from model objects to repositories were polled, then withdrawn as too fragile. | C4 zoom levels, tag groups that highlight, pin, focus or hide objects, step-through flows, and share links. | Put a count of findings and absences in the header of every reading, scoped to what that reading shows (IcePanel's inaccuracy count is "contextual to what you're looking at"). Count named kinds, not one score, and link the count to the list. | +| **arc42 and docToolchain** | Prose chapters and diagrams as code in the repository, reviewed in pull requests and published by CI. Drift is caught by review habits, not derivation. | A field-tested table mapping stakeholders to the sections they need (arc42 FAQ B-15): managers, product owners, developers, operators, testers, neighbouring teams, and lately an LLM agent. | Seed the role-by-reading matrix from that table, translated into graph material (a tester to verifier bindings, example-space coverage and rule coverage; management to roadmap entries, decisions and constraints). Then refine it the arc42 way: show each role a cheap generated reading of a real Pack and revise from feedback. | + +**Sources.** + +- **Backstage:** [descriptor format](https://backstage.io/docs/features/software-catalog/descriptor-format/) · [life of an entity](https://backstage.io/docs/features/software-catalog/life-of-an-entity/) · [TechDocs architecture](https://backstage.io/docs/features/techdocs/architecture/) · [catalog plugin integration](https://backstage.io/docs/plugins/integrating-plugin-into-software-catalog/) · [catalog graph](https://backstage.io/api/next/modules/_backstage_plugin-catalog-graph.html) · third party: [the catalog maintenance trap](https://riftmap.dev/blog/the-catalog-maintenance-trap/), [technical disadvantages](https://www.port.io/blog/what-are-the-technical-disadvantages-of-backstage) +- **Tech Insights and Soundcheck:** [Roadie: Tech Insights](https://roadie.io/backstage/plugins/tech-insights/) · [Soundcheck Tech Insights](https://backstage.spotify.com/docs/plugins/soundcheck/core-concepts/tech-insights) · [Soundcheck plugin](https://backstage.spotify.com/partners/spotify/plugin/soundcheck) +- **Port:** [data model](https://docs.port.io/context-lake/data-model/configure-data-model/) · [standards concepts](https://docs.port.io/governance/standards-and-compliance/concepts-and-structure/) · [standards overview](https://docs.port.io/governance/standards-and-compliance/overview/) · [calculation properties](https://docs.port.io/context-lake/data-model/setup-blueprint/properties/calculation-property/) · [dashboards](https://docs.port.io/interface-builder/port-interface/dashboards/overview/) · [private pages](https://docs.port.io/interface-builder/port-interface/page/private-pages/) +- **Cortex:** [quickstart](https://docs.cortex.io/get-started/quickstart) · [GitOps](https://docs.cortex.io/configure/gitops) · [scorecards as code](https://docs.cortex.io/standardize/scorecards/scorecards-as-code) · [CQL](https://docs.cortex.io/standardize/cql) · [homepage](https://docs.cortex.io/streamline/homepage) · [creating scorecards](https://docs.cortex.io/standardize/scorecards/create) · [Jira integration](https://docs.cortex.io/ingesting-data-into-cortex/integrations/jira) · [GitHub integration](https://docs.cortex.io/ingesting-data-into-cortex/integrations/github) +- **OpsLevel:** [maturity report](https://docs.opslevel.com/docs/maturity-report) · [categories and levels](https://docs.opslevel.com/docs/categories-and-levels) · [introduction](https://docs.opslevel.com/docs/introducing-opslevel) · [setting up a rubric](https://www.opslevel.com/resources/how-to-set-up-your-service-maturity-rubric) +- **Structurizr:** [as code](https://docs.structurizr.com/as-code) · [AI](https://docs.structurizr.com/ai) · [perspectives](https://docs.structurizr.com/dsl/cookbook/perspectives-static/) · [filtered views](https://docs.structurizr.com/dsl/cookbook/filtered-view/) · [DSL language](https://docs.structurizr.com/dsl/language) · [workspace inspections](https://docs.structurizr.com/workspaces/inspections) · [inspect](https://docs.structurizr.com/inspect) · [static site export](https://docs.structurizr.com/export/static-site) · [decisions](https://docs.structurizr.com/server/decisions) +- **LikeC4:** [home](https://likec4.dev/) · [views](https://likec4.dev/dsl/views/) · [predicates](https://likec4.dev/dsl/views/predicates/) · [dynamic views](https://likec4.dev/dsl/views/dynamic/) · [deployment views](https://likec4.dev/dsl/deployment/views/) · [configuration](https://likec4.dev/dsl/config/) · [AI tools](https://likec4.dev/tooling/ai-tools/) +- **IcePanel:** [glossary](https://docs.icepanel.io/other-information/glossary) · [diagramming](https://docs.icepanel.io/core-features/diagramming) · [drafts](https://docs.icepanel.io/future-state-design/drafts) · [drafts announcement](https://icepanel.io/blog/new-drafts-design-future-states-of-software-architecture) · [linking to reality](https://docs.icepanel.io/integrations/linking-to-reality) · [accuracy score](https://docs.icepanel.io/integrations/accuracy-score) · [perspective tags](https://docs.icepanel.io/visual-storytelling/perspective-tags) · [recommendations](https://docs.icepanel.io/core-features/recommendation) · [getting started](https://docs.icepanel.io/getting-started) +- **arc42 and docToolchain:** [FAQ B-15](https://faq.arc42.org/questions/B-15/) · [FAQ A-5](https://faq.arc42.org/questions/A-5/) · [arc42 after the 12 chapters](https://blog.hompus.nl/2026/02/25/arc42-after-the-12-chapters/) · [docToolchain arc42 example](https://examples.arc42.org/systems/doctoolchain-v4/01-introduction-and-goals/) · [what is docToolchain](https://doctoolchain.org/docToolchain/v2.0.x/10_about/20_what-is-doctoolchain.html) · [arc42 in practice](https://leanpub.com/read/arc42inpractice/chapter-iii) + +## Requirements, ALM and living documentation + +Jira and Linear are included as a contrast: they hold process state, not delivery intent. + +| Product | Where truth lives | Role-specific views | Lesson for the Protocol | +|---|---|---|---| +| **IBM DOORS Next** | A server database of typed artifacts in modules, with typed links. Every reading happens inside a configuration: a working stream or a frozen baseline. Link validity is computed from the content at both ends of a link, and people then mark links valid or invalid. | No designed role homes: saved views, a link explorer, configuration compare reports and dashboards built by admins. | Derive "the other end of this relation changed since the base" from the design diff (recipe 35), with a worst-case summary on the Spec's page. Acknowledgement is an ordinary carrier edit that git records, never a "mark valid" button. The always-present configuration menu supports a basis line at the top of every reading. | +| **Jama Connect** | An item database plus an admin-defined model of the relationships expected between item types. Coverage and gaps are computed against that model. Reviews are versioned snapshots. | A trace view for engineers and QA; a trace explorer for leads and auditors in which each metric opens a filtered list; a review centre with moderator, reviewer and approver roles and e-signature. | Copy the drill from aggregate to filtered list, never the single trace score. Show "expected relation absent" per relation kind with its scope stated in the reading: the gap signal expects a verifier only on a Spec stated `ready`. Comparing review rounds maps onto reading a Pack at a proposal's base against head. | +| **Siemens Polarion** (LiveDocs) | Work items with full revision history. LiveDocs show them as Word-like documents in which every paragraph is an item; collections pin items at a revision for a release. | Authors and reviewers in LiveDocs, engineers in tracker tables, managers and QA in report pages that admins build, compliance through baselined collections. | The strongest reviewer reading is document-shaped over typed items: a Pack read top to bottom like a specification, each block a linked Spec carrying readiness, claim and delivery facts inline. The Protocol avoids Polarion's confusion over two homes for one item only while documents stay readings. | +| **PTC Codebeamer** | Tracker items joined by links that can mark a downstream item "suspect" when an upstream item changes. Reviews are snapshots. | A configurable traceability browser with presets that admins save, a review hub with moderators and reviewers, and suspect badges that open the upstream diff. | Encode a reading's selection in its link, so a reviewer can paste an exact reading into a pull request with no server; the Studio already routes one filter this way (the capability map's epic filter). Open a review against a proposal base with what moved since it (recipe 38). An impact indicator should open the actual content diff. | +| **SpecFlow+ LivingDoc** (end of life) | Gherkin feature files. A closed-source generator rendered an HTML report or an Azure DevOps tab, with or without test results. It reached end of life with no direct substitute. | One view with a switch: product owners read scenarios without results, testers read pass and fail. | Keep intent readings complete without run evidence, and treat CTRF run reports as an optional, named overlay on the same reading. Keep the self-contained Pack export open and stable: people who lost LivingDoc asked for exactly a single offline file. | +| **Cucumber reporting** | Feature files plus one canonical event stream from which every report format is derived. A hosted service shares a run's report by URL and deletes it after about a day unless an account keeps it. | Essentially none: one run-centred report for everyone, with plugins adding overviews. | Confirms "one model, many formatters", but the Protocol's centre is intent stamped at a commit, with run evidence a named input. Any "publish and share" in a commercial Studio must give durable, stamped links, never expiring ones. | +| **Serenity BDD** | Feature files or tests, arranged in a requirements hierarchy taken from folders or from `@Epic`, `@Feature` and `@Story` tags, merged with outcomes at each build. | A requirements-first report aimed at the whole team, including auditors, with the most important detail first. | Keep the requirements-first, layered reading, but split Serenity's single "pending" into separate absences: no verifier bound, verifier bound but no run evidence supplied, run evidence failing, example-space value unbound, readiness stated below `ready`. | +| **adr-tools** | Numbered Markdown decision records in the repository. Supersession is written into both files; a generated graph shows filing order and declared links. Status is edited by hand. | None: a list, a generated table of contents and a graph image. | A decision-trail reading should show what each decision shaped: follow `decidedBy` to the Specs and on to code annotated as architecturally significant (the architectural-annotation decision, MD-38), and show supersession both ways, as the decision register (recipe 31) already lists it. | +| **Log4brains** | Decision records in the repository, built into a static site by CI, with dates and authors taken from git and a live preview while writing. Planned links from code to decisions never shipped. | One site for everyone: a timeline by month, search, status badges and package labels. | Its unmet demand, code linked to decisions and a decision backlog, is material the graph already holds: anchors, decision Specs, and open questions with a `decider`. A read-only decision timeline could pair git dates with those relations. `sdp studio --watch` is the Protocol's live preview and can be presented to authors as such. | +| **Jira** (contrast) | A work-item database whose status moves through configured workflows guarded by conditions and validators; some transitions fire on repository events. Requirements live in descriptions and linked pages. | Strong role surfaces over one store (boards, backlogs, dashboards, saved queries, service queues), all configured by users or admins. | Stay a membrane: link to tickets, never mirror their states or show one as a delivery fact. Saved, shareable queries are a precedent for named, shareable readings backed by recipes. A binding is not a verdict, and a leader reading must say so. | +| **Linear** (contrast) | Issues, projects and initiatives in the vendor's database. Project health (on track, at risk, off track) is written by leads when reminded, with derived progress attached when it moved. | Engineers work in issues and cycles, leads write updates, leaders read rolled-up initiatives pushed to an inbox and chat. | Put authored narrative and derived facts side by side and visibly apart: the reasons the author writes around the roadmap memo (recipe 55) next to the need the graph derives for each entry. Never merge the two into a health colour. Leading with what changed since the reader's base is a good attention pattern for role homes. | + +**Sources.** + +- **DOORS Next:** [link validity](https://jazz.net/blog/index.php/2015/11/12/link-validity-coming-in-clm-version-6-0-1/comment-page-1/) · [managing baselines](https://www.sodiuswillert.com/en/blog/best-practices-for-managing-baselines-with-ibm-doors-next) · [configuration management](https://www.ibm.com/docs/en/engineering-lifecycle-management-suite/doors-next/7.1.0?topic=overview-configuration-management) · [overview](https://www.ibm.com/docs/en/engineering-lifecycle-management-suite/doors-next/7.2.0?topic=overview-doors-next) · [linking techniques](https://softacus.com/blog/articles/dng/linking-techniques-in-doors-next) · [artifacts not used in a module](https://jazz.net/forum/questions/266509/is-it-possible-to-list-report-the-doors-next-artifacts-not-used-in-a-module) +- **Jama Connect:** [trace view](https://help2.jamasoftware.com/ah/en/manage-content/coverage-and-traceability/trace-view.html) · [live trace explorer recap](https://www.jamasoftware.com/blog/webinar-recap-improve-traceability-and-enhance-coverage-with-live-trace-explorer/) · [live trace explorer](https://help.jamasoftware.com/en/manage-content/coverage-and-traceability/live-trace-explorer---beta.html) · [review center](https://www.jamasoftware.com/blog/jama-connect-features-in-five-review-center/) · [relationship rules](https://help.jamasoftware.com/ah/en/administration/organization-administrator/managing-relationships/set-up-relationship-rules.html) · [features](https://help.jamasoftware.com/ah/en/getting-to-know-jama-connect-features.html) · third party: [review](https://aqua-cloud.io/jama-connect-review-features-pricing/) +- **Polarion:** [requirements](https://www.siemens.com/en-us/products/polarion/requirements/) · [collections](https://blogs.sw.siemens.com/polarion/whats-new-in-polarion-collections/) · [document API](https://python-polarion.readthedocs.io/en/latest/document.html) · [LiveDoc community](https://community.sw.siemens.com/s/topic/0TO4O000000Ni0QWAS/livedoc) · [document traceability thread](https://community.sw.siemens.com/s/question/0D5KZ000005HqD80AK/document-work-items-traceability) · [baseline links thread](https://stackoverflow.com/questions/75321958/polarion-document-baseline-with-links-in-description-field) · [document macros](https://polarion.code.blog/2022/02/17/working-with-document-macros/) +- **Codebeamer:** [suspected links](https://support.ptc.com/help/codebeamer/r2.1/en/codebeamer/user_guide/ug_suspected_links.html) · [traceability browser](https://support.ptc.com/help/codebeamer/r2.1/en/codebeamer/user_guide/12450789.html) · [associations](https://support.ptc.com/help/codebeamer/r2.1/en/codebeamer/user_guide/2016061.html) · [reviews](https://support.ptc.com/help/codebeamer/r3.1/de/codebeamer/cbx_user_guide/review_hub/cbx_reviews_in_codebeamer.html) · [review hub how-to](https://www.ptc.com/en/resources/alm-on-demand/how-to-review-hub) +- **SpecFlow+ LivingDoc:** [teamwork with LivingDoc](https://automationpanda.com/2021/02/09/improving-teamwork-with-specflow-livingdoc/) · [end-of-life announcement](https://reqnroll.net/news/2025/01/specflow-end-of-life-has-been-announced/) · [Reqnroll discussion](https://github.com/orgs/reqnroll/discussions/196) +- **Cucumber:** [reporting](https://cucumber.io/docs/cucumber/reporting/) · [reports terms](https://reports.cucumber.io/terms) · [cucumber-reporting](https://github.com/damianszczepanik/cucumber-reporting) · [Jenkins plugin](https://plugins.jenkins.io/cucumber-reports/) +- **Serenity BDD:** [living documentation](https://serenity-bdd.github.io/docs/reporting/living_documentation) · [reports](https://serenity-bdd.github.io/docs/reporting/the_serenity_reports) · [Serenity/JS reporter](https://serenity-js.org/handbook/reporting/serenity-bdd-reporter/) · [Serenity/JS discussion](https://github.com/orgs/serenity-js/discussions/2869) · [living documentation, not just test reports](https://johnfergusonsmart.com/living-documentation-not-just-test-reports/) +- **adr-tools:** [repository](https://github.com/npryce/adr-tools) · [graph generator](https://raw.githubusercontent.com/npryce/adr-tools/master/src/_adr_generate_graph) +- **Log4brains:** [repository](https://github.com/thomvaill/log4brains) · [its own decisions](https://thomvaill.github.io/log4brains/adr/) · [Jamstack listing](https://jamstack.org/generators/log4brains/) +- **Jira:** [advanced workflows](https://support.atlassian.com/jira-cloud-administration/docs/configure-advanced-issue-workflows/) · [conditions and validators](https://confluence.atlassian.com/spaces/SERVICEDESKSERVER/pages/1044784442/Conditions+and+validators) +- **Linear:** [write issues, not user stories](https://linear.app/method/write-issues-not-user-stories) · [initiative and project updates](https://linear.app/docs/initiative-and-project-updates) · [the Linear Method](https://linear.app/method) + +## AI spec-driven development and code intelligence + +| Product | Where truth lives | Role-specific views | Lesson for the Protocol | +|---|---|---|---| +| **AWS Kiro** | A folder per feature in the repository with requirements, design and tasks files, each generated from the one before with an approval at every step; the agent writes task progress back into the tasks file. Steering files hold standing project memory. A review on martinfowler.com found the specs are not kept up after their task. | None by role: everyone reads the same three files. Review aids include comments on exact passages sent to the agent, and a requirements analysis that names the requirements involved and offers fixes. | Use Kiro's finding card for honesty findings and open questions: the Specs involved, a plain reason, and three ways out (change the intent, the code or the verifier), each becoming scoped intent. Kiro's "dismiss as intentional" lives in the UI; the Protocol's equivalent must be a visible, authored edit in the repository. | +| **GitHub Spec Kit** | A constitution file plus a numbered folder per feature (spec, plan, tasks, research, contracts, checklists). Teams choose whether finished specs freeze, stay living or flow back. Its analysis is read-only, and its converge step only appends tasks and never rewrites intent to match code. | None visual; roles are implied by commands. Checklists belong to the reviewer, and the implementing agent may not tick them. | Converge's contract matches the Protocol's drift rule. Give Pack readings the same two outcomes: no drift (an empty drift alarm, recipe 2, and no open honesty finding), or a list ordered by severity with the scoped intent each item needs. Avoid Spec Kit's file sprawl: show plan- and task-like views as readings over one Spec enriched in place. | +| **Tessl** | Began as spec-as-source (one spec per generated code file), then repositioned as a registry of agent context (rules and skills) scored by reviews and evals, with LLM-judged verifiers kept in the repository. | Administrative roles; organisation-wide context and findings views for platform leads. | "Candidate until committed": anything AI-drafted that a reading shows is labelled with its model and source commit until it travels through git and the checks, as the provisional answer in `spec:consumers.ai-assisted-reading` proposes. Every finding names the check that produced it, so a judgement is never mistaken for a deterministic fact. | +| **GitHub Copilot Workspace** (shut down) | A session started from an issue: an editable "current state / desired state" spec, a file-by-file plan and an editable diff. Nothing persisted in the repository; the pull request was the durable record. It was folded into the coding agent. | The developer drives; reviewers got a read-only link to the session from each pull request. | Lay out an engineer's or architect's Spec reading as desired (authored intent) against current (delivery facts, bindings, inferred structure), with the gap shown as named absences. Make the stamped pull-request preview the default way into review: because it is stamped, it cannot become the stale snapshot that Workspace's shared links became. | +| **Cursor** (rules, plan mode) | Code is the truth. Rules in the repository (plus team rules in the vendor dashboard) and agent-written plans are context. A rule applies always, by the agent's judgement, by file pattern or on mention. | Developers only; admins manage team rules. | Borrow the rule-application vocabulary for a reading's hand-off to an agent: what is always included (the Spec, its blocking questions, the stamp), what is included because of scope, and what was left out. The context bundle (recipe 36) already states its scope and what it left out. | +| **Claude Code** (instruction files, plan mode) | The repository: committed instruction files load by directory, while personal memory and plans stay outside it. Guidance is kept apart from enforcement (permissions and hooks). | None visual; `/context` shows exactly what the agent received. | Copy `/context` into every reading and hand-off: list which Specs and graph facts were included, at which commit. A curator reading could flag prose that quotes facts the graph derives (counts, readiness), which the handbook ([AGENTS.md](../../AGENTS.md)) already treats as drift. | +| **Sourcegraph** | Code across all repositories; Sourcegraph is an index derived from it. Navigation results are precise (from compiler indexes) or search-based. Batch changes reconcile code hosts to a declarative spec; insights turn search queries into time series. | The clearest role split surveyed: engineers (search, navigation), migration owners (batch changes with preview and burndown), leaders (insights dashboards), agents (context APIs). | Leaders accept progress derived from the repository rather than from tickets when two rules hold: the recipe behind every number is visible, and stated readiness, floor reached, realization and verifier coverage stay separate series, never one "% done". Show each edge's claim on its own row, as Sourcegraph keeps precise and search-based results apart. | +| **CodeSee** (now GitKraken Codemaps) | Code. Maps were generated from file dependencies; human notes and tours were stored in the vendor's service and disappeared with the product. | Developers got dependency maps, reviewers a map per pull request, newcomers tours, leaders an ownership legend that names files needing an owner. | Scope every diagram to a question: a reviewer's default diagram is the blast radius of a change or a Pack's boundary at a commit, with a complete text equivalent. Keep any human arrangement (a tour order, a saved selection) as data in the repository, as perspectives already are, so it outlives the tool that renders it. | +| **Swimm** | Prose written in Swimm's editor with typed references to code (snippets, names, paths) that sync automatically. A pull-request check marks affected documents "potentially out of date" and can block the merge. Its homepage now leads with modernisation services. | Developers read documents in the IDE beside the code they reference; newcomers get playlists; reviewers get the check. | Beside each binding, show whether its anchor still resolves at the stamped commit, and name an unresolving binding as its own absence (it confers no delivery fact, and referential integrity reports it). Offer people the reverse lookup from a source file to its Specs that `g.byFile` already gives agents. Never rewrite anything silently. | +| **Mintlify** | MDX in git, rendered as a site with previews. A background agent drafts documentation updates from code and connected tools and always opens a pull request. Agents read the same content as llms.txt, Markdown pages and MCP. | Readers get the site, AI tools get agent formats, documentation owners get a suggestions inbox with diff stats and preview links. | Give every Studio page an agent twin: a per-page "copy as scoped context" (Markdown, graph addresses, stamp) and a site index for agents, so a reading and an `sdp q` answer are visibly the same content. AI-drafted changes arrive only as change proposals against a named base. | +| **Docusaurus** | Markdown in a docs folder; tagging a version copies the folder. Banners mark unreleased and unmaintained versions, "edit this page" links to the source file, and last-update data comes from git. | None by role; the axes are version and locale. | Keep the version banner but derive it from the stamp: which commit the reading projects and where that commit stands (main, a preview against its base, an older stamp). An "open at source" link per entry could build on the location table and the stamp's source template, keeping the rule that a view never writes. | +| **OpenSpec** | Current specs in one folder. Each change is a folder with a proposal, a design, tasks and delta specs (added, modified, removed), merged into current truth when archived. | None by role; a reviewer reads the change folder. | Lead a readiness author's review with the delta (clauses added, changed and removed, readiness moves) against the base (recipes 35 and 38), with the whole Spec one disclosure away. No archive step is needed: the merged commit is the new truth. | + +**Sources.** + +- **Kiro:** [specs](https://kiro.dev/docs/specs/) · [feature specs](https://kiro.dev/docs/specs/feature-specs/) · [analyze requirements](https://kiro.dev/docs/specs/analyze-requirements/) · [correctness](https://kiro.dev/docs/specs/correctness/) · [best practices](https://kiro.dev/docs/specs/best-practices/) · third party: [Böckeler, understanding spec-driven development tools](https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html) +- **Spec Kit:** [repository](https://github.com/github/spec-kit) · [agentic SDD](https://github.github.io/spec-kit/reference/agentic-sdd.html) · [evolving specs](https://github.github.io/spec-kit/how-to/evolving-specs.html) · [spec persistence](https://github.com/github/spec-kit/blob/main/docs/how-to/spec-persistence.md) · [spec-driven.md](https://github.com/github/spec-kit/blob/main/spec-driven.md) · [discussion 152](https://github.com/github/spec-kit/discussions/152) +- **Tessl:** [core concepts](https://docs.tessl.io/introduction-to-tessl/core-concepts.md) · [verifiers](https://docs.tessl.io/codifying-and-enforcing/verifiers-overview.md) · [llms.txt](https://docs.tessl.io/llms.txt) · [from code-centric to spec-centric](https://tessl.io/blog/from-code-centric-to-spec-centric) · third party: [review](https://codemyspec.com/blog/tessl-review), [Böckeler](https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html) +- **Copilot Workspace:** [project page](https://githubnext.com/projects/copilot-workspace/) · [user manual: changes](https://github.com/githubnext/copilot-workspace-user-manual/blob/main/changes.md) · [sunset notice](https://gh.io/copilot-workspace-sunset) +- **Cursor:** [rules](https://cursor.com/docs/rules) · [plan mode](https://cursor.com/blog/plan-mode) · [forum: plans outside the plans folder](https://forum.cursor.com/t/153896) +- **Claude Code:** [memory](https://code.claude.com/docs/en/memory) · [best practices](https://code.claude.com/docs/en/best-practices) · [permission modes](https://code.claude.com/docs/en/permission-modes) · [debug your configuration](https://code.claude.com/docs/en/debug-your-config) · [large codebases](https://code.claude.com/docs/en/large-codebases) +- **Sourcegraph:** [code navigation](https://sourcegraph.com/docs/code-navigation) · [navigation features](https://sourcegraph.com/docs/code-navigation/features) · [batch changes](https://sourcegraph.com/docs/batch-changes) · [batch changes FAQ](https://sourcegraph.com/docs/batch-changes/faq) · [code insights](https://sourcegraph.com/code-insights) · [insights announcement](https://sourcegraph.com/blog/announcing-code-insights) · [Sourcegraph and Amp](https://sourcegraph.com/blog/why-sourcegraph-and-amp-are-becoming-independent-companies) · third party: [Unblocked vs Cody](https://getunblocked.com/blog/unblocked-vs-sourcegraph-cody/) +- **CodeSee and Codemaps:** [acquisition](https://gitkraken.com/blog/gitkraken-launches-devex-platform-acquires-codesee) · [dependency mapping](https://gitkraken.com/features/code-dependency-mapping) · [marketplace listing](https://marketplace.visualstudio.com/items?itemName=codesee.maps) · third party: [alternatives](https://repowise.dev/blog/comparisons/codesee-alternatives-codebase-maps) +- **Swimm:** [code-coupled documentation](https://docs.swimm.io/new-to-swimm/benefits-of-code-coupled-documentation) · [auto-sync](https://docs.swimm.io/features/keep-docs-updated-with-auto-sync/) · [documentation in CI](https://swimm.io/learn/code-documentation/reasons-continuous-integration-documentation-is-a-must) · [homepage](https://swimm.io/) · third party: [alternative](https://repowise.dev/compare/swimm-alternative) +- **Mintlify:** [Autopilot docs](https://www.mintlify.com/docs/autopilot) · [Autopilot announcement](https://www.mintlify.com/blog/autopilot) · [llms.txt](https://www.mintlify.com/docs/ai/llmstxt) · [contextual menu](https://www.mintlify.com/docs/ai/contextual-menu) · [AI-native](https://www.mintlify.com/docs/ai-native) · third party: [review](https://documentation.ai/blog/mintlify-review) +- **Docusaurus:** [versioning](https://docusaurus.io/docs/versioning) · [docs plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs) +- **OpenSpec:** [repository](https://github.com/Fission-AI/OpenSpec) · [concepts](https://github.com/Fission-AI/OpenSpec/blob/main/docs/concepts.md) + +## Cross-cutting lessons + +| Lesson | Seen in | What it asks of the readings | +|---|---|---| +| **Where truth lives predicts who is reached.** | Repository-first tools (Structurizr, LikeC4, arc42, adr-tools) keep one truth but lose people who do not write code. Interface-first tools (Port, Cortex, IcePanel, the ALM suites) reach everyone but end with split truth. Products that kept truth in a session or a vendor's store (Copilot Workspace, CodeSee, Tessl's first framework) were shut down or repositioned; repository artifacts and indexes derived from them lasted. | Repository-only truth with strong readings for people who never open the repository: the gap this design pass exists to fill. Borrow principles rather than features from this set, since the features keep changing. | +| **Explain the state; do not score it.** | OpsLevel's Maturity Report, Cortex's failing values in messages, Kiro's finding card, Spec Kit's analysis ("fix them at the source"). Single scores hide distinctions: Jama's trace score depends on filters the reader cannot see, Serenity's "pending" covers several absences, Soundcheck ranks teams by compliance percentage. | Show the ladder, the stated rung beside the floor reached, and the located unmet clauses; send each fix to the Spec that owns it. No progress score ([PRODUCT.md](../../PRODUCT.md)). | +| **Role readings are selections over shared readings.** | Structurizr's filtered views and overlays, IcePanel's highlight, pin, focus and hide, LikeC4's predicates. Elsewhere, role views are left to admins: saved views, presets, dashboards, saved queries. | Role homes over the same object pages, so a Spec reads the same for every role. Role readings that are designed, not configured, would be new in every category surveyed. | +| **Keep facts, judgements and certainty apart.** | Tech Insights (facts apart from checks), Port (derived values typed as derived), Sourcegraph (precise apart from search-based), Swimm (synced apart from "potentially out of date"), Tessl (linters apart from LLM verifiers), Kiro (property tests as "evidence ... not a proof"). | Claims, stated readiness, floor reached, delivery facts and findings stay visibly and structurally distinct, never merged into one cell; every finding names its check. | +| **Honesty signals belong where the reader is looking.** | IcePanel's inaccuracy count, scoped to the open diagram; Backstage's orphan and error banners, which vanish when nobody wires them in. | A reading-scoped count of findings and absences in every reading's header, unconditional. | +| **Readers must know which version they are reading.** | DOORS Next's configuration menu, Polarion's revisions, Docusaurus's banners. The reverse: Backstage's lagging catalog, scorecards polled on a schedule, Copilot Workspace's stale shared snapshots. | The basis line (corpus commit, engine, base, supplied inputs) at the top of every reading, as prominent as DOORS Next makes its configuration (a candidate: today a `file://` page and a Pack export show no stamp, so an always-present line needs a "not stamped" state or a change to `ready` rules; [08](08-what-the-repo-settles.md#4-view-state-and-commercial-surfaces)). | +| **Change impact is the most valued and most resented feature.** | DOORS Next moved from timestamps to content; Codebeamer's suspect badge opens the diff. Both make people clear suspects by hand, which turns into noise in large projects. | Derive "changed since the base" per relation from the design diff, open the content diff on click, and route acknowledgement through a carrier edit and git. | +| **Review works in rounds over a base, delta first.** | Jama's review versions, Codebeamer's "restart for changed items only", OpenSpec's deltas. Böckeler: an effective spec-driven tool needs "a very good spec review experience"; Spec Kit's many files per spec were "tedious to review". | A Studio review reading opened against a proposal base leads with what moved (recipe 38); Design Review itself stays frozen under the shipped-projections decision (MD-32). Readings are built for review: delta first, finding cards, scoped diagrams, the whole Spec behind disclosure. | +| **Reviewers want document order over item identity.** | Polarion's LiveDocs, DOORS Next modules, Serenity's layered narrative. | A Pack reads top to bottom like a specification while every block stays a linked Spec, and the document never becomes a second place to edit. | +| **Living documentation fails when it centres on test runs or is closed.** | LivingDoc's end of life, Cucumber's expiring report links, Serenity showing nothing before tests run. | Intent readings complete without run evidence; run evidence an optional, named overlay pinned to its commit; the Pack export open, stable and self-contained. | +| **Every human view needs an agent twin, and every hand-off states its scope.** | Mintlify's agent formats and per-page copy, Claude Code's `/context`, Cursor's rule-application modes, LikeC4's "which views include this element". | Each reading hands an agent the same scope (the context bundle's parameters), saying what was included, why, and what was left out, at which commit. | +| **AI-drafted changes travel as proposals.** | Mintlify's agent pull requests, Tessl's candidate verifiers ("isn't part of your repository's policy until you ... commit it"), Spec Kit's append-only converge, Copilot Workspace's pull request. | Confirms that a view never writes: AI output is a labelled candidate until it passes through a change proposal, git and the checks. | +| **Authored status is the common weakness.** | ADR status text, Jira transitions, Linear health, review approvals and suspect clearing in ALM tools, task checkboxes in Kiro, Spec Kit and OpenSpec. Sourcegraph shows leaders accept derived progress when the query behind it is visible. | Where an authored judgement is legitimate (the reason for a roadmap entry's place, a decision's rationale), show it as attributed narrative beside derived facts, never as a fact. | +| **Scope diagrams to a question.** | CodeSee's per-pull-request maps outlived its whole-repository maps; Copilot Workspace listed the files before showing the diff. | Default diagrams answer one question (a blast radius, a Pack's boundary) and carry a text equivalent; human arrangements live in the repository. | +| **Ceremony must scale with the problem.** | Kiro added a one-pass mode to skip its own approvals; Spec Kit recast its phases as independent entry points. | With no gates to pass, readings should scale from one Spec to a Pack to the roadmap without adding steps. | +| **Seed role design from field evidence, then iterate with samples.** | arc42's stakeholder table and its advice to show each stakeholder cheap examples and incorporate their feedback. | Fits a long design pass with cheap, regenerable readings better than an information architecture fixed up front ([09](09-design-method.md)). | +| **Regulated buyers expect audit packages.** | Word and Excel trace exports, signed review records, baselines named after release gates. | An auditor reading probably needs a printable, single-file evidence set keyed to a commit; the Pack export and print-as-document are the starting point. | + +## Positioning + +### What none of them do, and the Protocol does + +| The Protocol's difference | Nearest analogue | Carried by | +|---|---|---| +| One primitive for ideas, use cases, NFRs, decisions, contracts and examples, in one typed graph read across Packs and the roadmap | Per-feature folders (Kiro, Spec Kit, OpenSpec); separate stores for catalog, docs, decisions, diagrams and scorecards (portals); admin-configured item types (ALM suites) | `spec:model.core-model`; one primitive, named coordinates (MD-4) | +| A claim (`declared`, `anchored`, `inferred`) on every node and edge, never collapsed | Sourcegraph's precise and search-based tiers, for code references only; Port types how a value is derived, not how certain it is | `spec:extraction.claim-taxonomy` | +| Delivery facts derived from bindings, stated readiness shown beside a derived floor, and `implemented ∧ ¬ready` as a drift alarm | Checkboxes in task files; hand-set lifecycle and ADR status; maturity levels that apply only to running services | `spec:extraction.delivery-facts`, `spec:validation.readiness-floor`, recipe 2 | +| No workflow gates; the roadmap is advisory order, and the graph reads each entry's need afresh, with no dates | Kiro's phase approvals, Spec Kit's checklist gate, Swimm's blocking check, Cortex initiatives with deadlines, ALM workflow states | `spec:validation.two-check-families`; a roadmap states advisory priority (MD-46); `spec:consumers.roadmap` | +| Deterministic readings stamped with their commit, regenerable at any commit, with a preview per pull request | Eventually consistent live stores (Backstage, polled scorecards, IcePanel); Docusaurus copies folders; Copilot Workspace's shared snapshots went stale | `spec:consumers.spec-studio.sharing` | +| Change proposals against a named base, checked by a recipe, with a design diff from that base; the only write affordance is scoped intent | IcePanel's drafts, Port's interface and chat edits and OpsLevel's "Fix This" write from the view; OpenSpec has deltas but no check against a base | `spec:consumers.intent-composition.proposal`, `spec:consumers.spec-studio.intent-panel`, recipes 35 and 38 | +| Checks police conformance and honesty, never content quality or workflow | Tessl's LLM verifiers, Kiro's requirements analysis, Spec Kit's checklists, Structurizr's completeness inspections, IcePanel's recommendation score | `spec:validation.two-check-families` | +| Agents script the whole typed graph instead of calling a fixed set of verbs or reading Markdown files | MCP servers with fixed tools (Structurizr, LikeC4, Port, Cortex); REST and OSLC integration APIs in ALM suites | `spec:consumers.agent-surface`; the agent front door (MD-22) | +| All delivery intent as text in the repository, git as the event log, every human view a projection | Log4brains and LivingDoc do this for one artifact type; ALM suites hold truth on a server; Jira and Linear hold process state | `spec:consumers.projections-model` | + +### What they do that the Protocol does not (yet) + +Each row keeps the option open and labels it: **declined** (ruled out by design; the job may still +be served another way), **deferred** (designed in, not built), or **open** (no ruling; a candidate +for the research backlog). + +| Capability in analogues | Seen in | The Protocol today | Stance | +|---|---|---|---| +| People and ownership: teams, "my work", drill-down by organisation | Backstage, Port, Cortex, Soundcheck | The graph has four node types, none for people; only an open question names a `decider` | open; already logged in [07](07-graph-needs.md#log) | +| Time and trends: fact history, burndown, question age | Tech Insights, Soundcheck, Sourcegraph | The graph is one commit and the design diff compares two; the Studio refuses trend and timeline drawings until a ruled history input exists (`spec:consumers.spec-studio.diagram-kinds`) | open; already logged in 07 | +| Runtime and operations data: deployments, incidents, CI history | Portals | `observed` is never computed (`spec:extraction.delivery-facts`); `spec:observation.runtime-overlay` is at `idea`; a build reads one supplied set of run reports | deferred; already logged in 07 | +| Per-relation change impact ("suspect" links, link validity) | DOORS Next, Codebeamer, Jama | The design diff reports changed relation targets per Spec, but no reading says "the other end of this relation changed since the base"; concept search finds no Spec for the idea | open; the most transferable gap, and it must be derived, never authored; logged in [07](07-graph-needs.md#log) | +| Formal review records: roles, rounds, per-item verdicts, e-signature | Jama, Codebeamer, Polarion | Review travels as change proposals and pull-request discussion; that a Design Review happened is never a graph fact | declined as graph truth; how auditors are served stays open | +| Trace matrices exported to Word, Excel or ReqIF | ALM suites | A Pack exports as one self-contained HTML file, and every page prints as a document (`spec:consumers.spec-studio.export`) | open | +| Variant and product-line management | DOORS Next, Polarion | No Spec carries the idea | open | +| Rich in-place authoring for people who do not write code | Polarion LiveDocs, IcePanel, Port | The only write affordance is scoped intent, applied by an agent through git | declined by design; a trade-off to explain, not to close | +| Notifications and cadence: inbox, chat updates | Linear, Codebeamer, Mintlify | Readings wait to be opened; concept search finds no Spec for notifications | open; a candidate for a commercial surface | +| Interactive canvases: C4 zoom, manual layout, step-through flows, tours | Structurizr, LikeC4, IcePanel, CodeSee, Swimm | Diagrams laid out from graph values with text equivalents (`spec:consumers.spec-studio.diagrams`); no drill-down canvas or tour reading | open | +| Collaboration inside the tool: comments, "this looks wrong" flags, private drafts | IcePanel, Port, Kiro, Mintlify | Discussion goes to pull requests; the composing panel keeps gathered intents only in the browser | open; a candidate for a commercial surface, as product state, never delivery truth | +| Presence in the IDE and lookup from code to intent | Kiro, Cursor, Swimm | `g.byFile` gives agents the reverse lookup; Studio pages write no editor link; the vault is the nearest surface for people | open | +| AI that questions a spec for ambiguity, explains it or drafts changes | Kiro, Spec Kit, Copilot Workspace | `spec:consumers.ai-assisted-reading` is at `idea`, with a blocking question whose decider is the owner | open; see [the AI ladder](05-specialised-and-ai-readings.md#the-ai-ladder) | +| Executing plans and generating tests from requirements | Kiro, Spec Kit, Copilot Workspace | Execution is left to outside agents and read back through bindings; verifiers and example spaces are bound, not generated | declined for the core; open for tooling around it | +| An MCP server for apps and assistants | Structurizr, LikeC4, Port, Cortex, Mintlify | Designed in and deferred until a concrete caller sets its boundary (the MCP-deferred decision, `spec:decisions.mcp-deferred`) | deferred | +| Views across many repositories or a whole organisation | Sourcegraph, Tessl, OpenSpec | One graph per repository root, at one commit | open; a candidate for a commercial surface | +| Self-service actions and scaffolding | Backstage templates, Port and Cortex actions | None, and no stated intent beyond composing scoped intent | open | +| Ready-made shapes for bug fixes and idea triage | Kiro (current, expected and unchanged behaviour), Spec Kit (verified, partial, failed; go, needs clarification, kill) | Expressible as corpus perspectives or Specs; no ready-made reading | open | + +## What this means for a commercial Studio (exploratory) + +The core is and stays open source and free. A commercial Studio is under consideration as a web +app, a desktop app and a CI/CD surface ([04, section 5](04-reading-model-and-ia.md#5-surfaces)); +nothing here decides its scope. The survey suggests where such surfaces would earn their keep and +where they would break the Protocol's rules: + +- **Where the analogues' paid value sits:** people and ownership, notifications, comments and + review threads, saved and private readings, history and trends, views across an organisation. + Each is product state, not delivery truth. +- **What to avoid:** Cortex's mode in which the interface silently overrides Git, Port's schema + edits by chat, CodeSee's notes lost with the vendor, Cucumber's links that expire. In a commercial + surface, delivery truth stays in the repository, shared links stay durable and stamped, and any + human arrangement worth keeping can be exported to the repository. +- **What lasted:** repository artifacts and indexes derived from them. A commercial Studio that is + one more projection of the same graph inherits that durability. + +## Candidate needs for the graph-needs log + +Two needs this survey found, "the other end of this relation changed since the base" and which +readings select a Spec, are logged in [07](07-graph-needs.md#log) beside ownership, history, run +history and runtime observation. A third candidate, a link from each entry to its carrier line, is +already met: a Spec page shows each keyed entry's recorded line +(`spec:consumers.spec-studio.spec-page.core#rule.entryIds`), and a loaded stamp's source template +links every recorded file and line a page shows (`spec:consumers.spec-studio.sharing#rule.sourceLinks`). + +## Questions for the research backlog + +These are design questions for many cycles of work with real readers, not owner decisions to +settle now. Each pairs a persona or role from [01](01-roles-and-perspectives.md) with a job. + +1. Does an explanation-first "what stands before the stated next rung" reading help a readiness + author or decider decide faster than today's Pack page? +2. Can a leader reading built from counts of named kinds, with drill-down and no percentage, earn a + leader's trust? What do leaders do when no single number is offered? +3. Will an auditor accept stamped readings, a Pack export and git history in place of a signed + review record, or does a commit-keyed evidence set need a reading of its own? +4. Does a derived "changed since the base" indicator give reviewers the value of suspect links without + their noise? +5. Does a reading-scoped count of findings and absences in every header help, or does it become + noise the way suspect links did? +6. Which personas need intent where they write code (the IDE, the vault) rather than in the Studio? +7. Which habits from the analogues (comments, notifications, private drafts) belong in a commercial + surface, and can each stay product state without becoming delivery truth? + +These questions are carried in [06](06-design-cycles.md#design-questions-for-the-long-horizon). + +## How the Protocol claims were checked + +Every Protocol statement above was checked with `pnpm --silent sdp:q` at commit `53804437`. Re-run +the queries rather than trusting this page as the corpus changes. + +- **Carrying Specs:** `g.specs()` filtered to each cited id, returning kind, stated readiness and + delivery facts; `g.specContext(id)` for the wording of the Studio's sharing, lenses, composing + panel, diagram kinds and export Specs, delivery facts, the two check families, perspectives, the + context bundle, the MCP-deferred decision and AI-assisted reading. +- **Entry addresses:** `g.resolveEntryAddress` on `spec:consumers.agent-surface#rule.entryAdapters`, + `spec:consumers.roadmap#rule.entryNeed` and `spec:consumers.spec-studio#rule.namedInputs`. +- **No people in the graph:** `[...new Set(graph.nodes.map((n) => n.nodeType))]` returns the four + node types. +- **The gap signal's scope:** the message of an `honesty/gaps` finding in `report.findings`. +- **Absences:** `g.findByConcept` for "notification", "suspect", "product line", "ReqIF", "VS Code" + and "language server" returns nothing; "trend" returns only the diagram-kinds refusal. +- **Roadmap needs:** `recipes(53, { pack: "pack:roadmap" })`. +- **Reverse lookup:** `g.byFile` on a Studio source file returns the Specs bound there. +- **Recipe contracts:** the catalog in + [`docs/agent-surface/recipes.md`](../agent-surface/recipes.md) for recipes 2, 31, 35, 36, 37, 38, + 53 and 55; recipe 55 confirms that the author, not the memo, supplies the reason for an entry's + place. diff --git a/docs/design/README.md b/docs/design/README.md new file mode 100644 index 00000000..d628e84d --- /dev/null +++ b/docs/design/README.md @@ -0,0 +1,142 @@ +# Design foundation + +Working material for the Protocol's UX and information-architecture design. It sits between +[`PRODUCT.md`](../../PRODUCT.md), the product record for this design work (users, purpose, +constraints; design material, not intended truth), and the surface briefs that later design passes +write for individual readings. + +**Status.** This is design-pass material, not intended truth, and it confers nothing on the corpus. +When a design here would change what the Studio or a new reading does, the change reaches the +product as a Spec change through the authoring workflow, made in an engineering session; a change +to a `ready` Spec travels as a change proposal. The Spec wins. The Design Review, census, Mermaid +and Gherkin projections stay frozen under the shipped-projections decision (MD-32): reshaping one +of them needs a decision record that refines or supersedes that decision, never a follow-up work +item. The seed design in [`docs/lineage/v0-design/`](../lineage/v0-design/README.md) is context, +not law. + +**Design sessions never edit graph inputs.** They leave carriers, Packs, anchors and everything +else the graph is derived from alone. What they find the graph lacking is logged in +[07](07-graph-needs.md) for an engineering session and the owner to weigh. The corpus does not yet +record this design project: no Pack or roadmap entry carries it. A corpus home for it is a proposal +for an engineering session and the owner, set out in +[07](07-graph-needs.md#a-corpus-home-for-these-needs-a-proposal); a design session does not author it. + +**Scope.** UX, information architecture, task flows and option space. The Studio and new readings +come first. The other readings people use stay in the option space: CLI output (finding messages, +the default print of `sdp q`), the vault, and the roadmap and proposal memos (recipes 55 and 49). +Which of them the cycles take up is itself a design question. The frozen projections above are out +of scope unless a decision record reopens one. + +**No visual style.** An existing UI library and design system will be introduced later and will be +binding; until then this material stays at UX and IA level. One constraint already applies: the +decision that the Studio is built from custom elements, not a framework (MD-42). A CSS-level design +system or framework-free custom elements fit it; a framework-based component library would need a +decision that refines or supersedes it. + +**Open source first.** The core is and stays open source and free. The read-only Studio ships in +the open-source package, and its Spec leaves room for hosted review, shared comments and hosted +previews under `@libar-ai/` (`spec:consumers.spec-studio`). A commercial Studio, possibly a desktop +app, a web app and a CI/CD surface, is under consideration: exploratory, labelled as such wherever +it appears, and kept in the option space. + +**Time horizon.** Technical questions are answered from the repository; +[08](08-what-the-repo-settles.md) collects those answers. Design questions form a long-horizon +research backlog, worked through over at least six months of iterative cycles +([06](06-design-cycles.md), [09](09-design-method.md)). They are not owner to-dos to settle now. + +## Working method: the graph first + +This repository is self-hosted: its own delivery intent is a corpus, and the derived graph is how it +is explored. Every design session, and every agent a design session briefs, works in this order: + +1. **Load the reading skill** (`.agents/skills/sdp-agent-surface/`) before any question about the corpus. +2. **Ask the graph** through `pnpm --silent sdp:q` and the shipped recipes: the entry adapters for + a word, a file or a changeset (`findByConcept`, `byFile`, `blastRadius`); `specContext`, + `packContext` and `resolveEntryAddress` for one Spec, Pack or entry; recipes for recurring + questions. Compose ad-hoc bodies freely; there is no verb per question. +3. **Read a carrier last**, and only for its exact wording, at the location the graph returned. + +Text search over the carriers is not a research method here: it bypasses the claims, the derived +facts and the blind spots the graph reports. Sources outside the corpus (`CONTEXT.md`, the concept +documents, the recipe catalog, the lineage) may be read directly; concept search (recipe 6) finds +where a concept lives. A design claim about the Protocol is checked by a query, and the query +belongs in the claim's evidence. Counts are derived, never quoted: a document names the query or +recipe that derives a number instead of writing the number down. The same rule shapes the product: +people should enter the readings the way agents enter the graph +([04](04-reading-model-and-ia.md#2-how-people-arrive)). + +## Contents + +| Document | Question it answers | +|---|---| +| [`PRODUCT.md`](../../PRODUCT.md), the product record | Whom the readings serve, what they are for, and the constraints every design keeps | +| [01 — Roles and perspectives](01-roles-and-perspectives.md) | Who reads the graph, in which situation, for which job: core delivery roles first, then extended, niche, ultra-specialised and non-human readers | +| [02 — The seed's experience, mapped to now](02-seed-experience-map.md) | What the pre-code seed design imagined for people, what became of each idea, and the design opportunity each leaves | +| [03 — Reading material](03-reading-material.md) | What a reading can draw on: what the graph holds, what the recipes already answer, what named inputs supply, and what the graph does not hold | +| [04 — Reading model and information architecture](04-reading-model-and-ia.md) | What a reading is made of, how people arrive, how readings fit together, and which surfaces carry them | +| [05 — Specialised and AI-powered readings](05-specialised-and-ai-readings.md) | The wider option space: readings for narrow roles, and a ladder of AI roles with their trust boundaries | +| [06 — Design cycles](06-design-cycles.md) | How the work runs in cycles, which briefs to shape first, and the long-horizon design questions the cycles work through | +| [07 — Graph needs](07-graph-needs.md) | What design work finds the graph lacking, logged for engineering sessions and the owner, since design sessions never edit graph inputs | +| [08 — What the repository settles](08-what-the-repo-settles.md) | Which technical questions the repository already answers for design, with the Specs and queries that carry each answer | +| [09 — Design method](09-design-method.md) | How design work is done and judged: task sets, readers, what counts as success, prototypes, and how a session is recorded | +| [10 — Studio baseline](10-studio-baseline.md) | What today's Studio gives its readers, recorded at a pinned commit as the point every later cycle compares against; so far the page-reading half of cycle 0, with no task outcomes recorded yet | +| [11 — RUP roles and artifacts](11-rup-roles-and-artifacts.md) | How the roles and artifacts of the Rational Unified Process (RUP) map onto what the graph holds and the readings it could carry | +| [12 — Analogous products](12-analogous-products.md) | What comparable products do for the same jobs, and what each teaches the design, as evidence rather than template | + +Suggested reading order: `PRODUCT.md`, this README, 01, 02, 08, 03, 10, 04, 05, 11, 12, 09, 06, +07. 02 and 08 come early: the seed design was written before any code, and much of its human +experience is not in today's Studio; 08 shows which questions need no design work because the +repository already answers them. The catalogue in 01 keeps the whole range of readers in view: the first +cycles focus on core delivery roles, and that is a focus, not a limit. + +**Numbers in these documents.** A linked two-digit number (such as [08](08-what-the-repo-settles.md)) +is one of these documents. "(N)" in a material column, or "recipe N", is a recipe in the +[catalog](../agent-surface/recipes.md). "seed NN §x" points into the seed design +([`docs/lineage/v0-design/`](../lineage/v0-design/README.md)), and "concept NN" into +[`docs/concept/`](../concept/README.md). "Tier N" is a persona tier in 01, "cycle N" a design cycle +in 06, and A0–A7 are the steps of 05's AI ladder. JS-xN (shortened to xN in 01's tables) is a +[job story](../../jtbd-stories/README.md) id. MD-n and D1–D6 are entries of the decision registry +([`DECISIONS.md`](../concept/DECISIONS.md)), always given beside the decision's name. + +## Words used here + +The ratified language in [`CONTEXT.md`](../../CONTEXT.md) is binding: use its terms, and never use +as current usage a word it lists as an alias to avoid. These words do specific work in this design +and must not blur: + +- **perspective** (ratified): a reader's concern a Pack is read from, such as the domain model, + operations or the runtime platform. It is corpus data a recipe takes as a parameter (the + perspective filter, recipe 37) to select and order a Pack's members, leaving each member's + content whole. The corpus owns its perspectives; the Protocol ships none. +- **discipline** (an adopted delivery noun): a filter that selects or groups Specs by kind or + section. It is never a phase to pass through. +- **lens** (the Studio's name, not a glossary term): one of the Studio's graph views, today Packs, + capabilities, architecture, tests and evidence (`spec:consumers.spec-studio.lenses`). The owner + ruled the split in `spec:consumers.review-perspectives`, and `CONTEXT.md` lists "lens" as an alias + to avoid for perspective, so a lens never names a reader's concern. +- **role** (ratified): the one-token value on a code anchor naming the architectural pattern its + unit plays (the architectural-annotation ruling, MD-38). People are never "roles" bare here; see + *delivery role* below. +- **decider** (ratified, as an open-question field): who answers an open question. It is also a + value in this corpus's anchor role vocabulary, so it never names a persona. + +Design terms this foundation introduces are **provisional**: design-material words, not ratified +and not for labels, Specs or the glossary unless the owner rules them in. Their status: + +| Provisional term | Meaning here | Status | +|---|---|---| +| **reading** | what a person or agent takes from the graph for one question, whatever carries it: a page, a projection's output, a recipe's answer | **Keep as a design-prose word**, with this one meaning across these documents. The corpus already uses it informally the same way ("a design slice is a reading and not an artifact", `spec:consumers.design-slice`). Do not confuse it with fixed phrases: reading order (`spec:consumers.roadmap`), a question's provisional reading, the reading skill, and the context bundle's reading material (03's title uses that phrase in its plain sense). Where precision matters, use the exact noun: projection, page, page set, recipe answer. | +| **persona** | a design-research description of a person in a delivery role: situation, jobs, first questions | **Keep as a design-material word**, by the owner's choice. `CONTEXT.md` does not reject it, and the concept vision speaks of multi-persona consumption, but the [job stories](../../jtbd-stories/README.md) deliberately bind to no persona because the Protocol's readers are heterogeneous. So a persona is paired with job stories (When / I want / so I can) for its jobs; a Spec names whom it serves through its Intent `actor`; and a persona never becomes a label, a Spec term or a perspective. | +| **delivery role** | the people sense of role: analyst, architect, tester, product manager and the rest | **Always qualified.** Bare `role` is the ratified anchor token above. | +| **role home** | the landing reading a delivery role opens first, composed from shared readings | **Avoid as a name; the idea stays a candidate.** It builds on the ratified `role`, and the graph cannot select by person. Today's nearest names are the index, the Studio's default landing page (`spec:consumers.spec-studio.lenses`), and selection by concern, which is a perspective. A replacement name is open; documents that still use this one mean the idea above. | +| **object page** | the one canonical reading of a single thing (a Spec, Pack, decision, question, component) | **Prefer the Studio's own pattern**: Spec page, Pack page, slice page, "*thing* page". Decision records already have Spec pages. Some candidates contradict `ready` Studio rules and reach the product only as change proposals against them: a page per code unit (the page set holds none, `spec:consumers.spec-studio.spec-page#rule.sourceText`), one canonical page per Pack (a Pack has a Pack page and a slice page by design, `spec:consumers.spec-studio#rule.staticPageSet`), and pages for unkeyed open questions (only a keyed question has an address, `spec:model.open-question-keys`). | +| **basis line** | a statement on a reading of what it projects: corpus commit, engine and named inputs | **Avoid as a name; the need stays a design question.** The existing element is the stamp line (`spec:consumers.spec-studio.shell#ui.stampLine`), showing the corpus commit, engine and build time that `stamp.json` names, and each page that shows an input names it (`spec:consumers.spec-studio.data.inputs#rule.inputNaming`). Neither is always present: the build writes no stamp (`spec:consumers.spec-studio.sharing#rule.buildWritesNoStamp`), a page opened through `file://` shows none (`spec:consumers.spec-studio.shell#rule.stamp`), a later build removes it, a Pack export leaves the stamp line out, and vault notes name no commit. Making it always present would change `ready` rules and bears on the determinism constraint (`spec:extraction.determinism`). "Basis" also collides with *base* (the base graph, `--base`) and with the settled basis a `ready` statement rests on (`spec:validation.typed-dependency-floor`). Documents that still use this name mean the need above. | +| **other coinages** | task flow, claim cue, absence word, agent hand-off and jump ([04](04-reading-model-and-ia.md)); cycle ([06](06-design-cycles.md)); graph need ([07](07-graph-needs.md)); the AI ladder's step names A0–A7 ([05](05-specialised-and-ai-readings.md#the-ai-ladder)); the artifact fit labels ([11](11-rup-roles-and-artifacts.md#catalogue-2--rup-artifacts-as-projections)) | **Design prose only.** Each is flagged where it first appears and means only what that document says. | + +Any other word these documents coin is provisional in the same way: flagged where it first +appears and added to the last row above. A coinage that duplicates an existing name gives way to it: the Studio's composing panel +(`spec:consumers.spec-studio.intent-panel`) needs no second name. A provisional term becomes shared +vocabulary only through the governing rubric in `CONTEXT.md` (adopt the established delivery noun, +coin a word only for a genuine differentiator, and pass both naming tests). A shipped Studio name +then lands through a carrying Spec and a `CONTEXT.md` row, as perspective did: engineering-session +work, which design sessions record as a need in [07](07-graph-needs.md).