@naswerks/engineering-loop 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +9 -3
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +37 -0
- package/package.json +1 -1
- package/references/docs-workflow.md +1 -1
- package/references/engineering-loop.md +3 -2
- package/skills/init/SKILL.md +36 -11
- package/skills/init/scripts/doctor.mjs +22 -4
- package/skills/spec-child/SKILL.md +13 -5
- package/skills/spec-parent/SKILL.md +15 -10
- package/skills/spec-review/SKILL.md +6 -3
- package/skills/spec-seat/SKILL.md +13 -7
- package/templates/docs/_meta/doc-index.md +18 -12
- package/templates/docs/infrastructure/background-work.md +8 -6
- package/templates/docs/patterns/backend-patterns.md +1 -1
- package/templates/docs/patterns/{vertical-slice-anatomy.md → code-organization.md} +18 -14
- package/templates/docs/patterns/design-tokens.md +62 -0
- package/templates/docs/patterns/frontend-patterns.md +1 -1
- package/templates/docs/patterns/long-running-workflows.md +63 -0
- package/templates/docs/patterns/state-management.md +1 -1
- package/templates/docs/patterns/testing.md +1 -1
- package/templates/docs/patterns/ui-style-guide.md +9 -8
- package/templates/docs/readme-patterns.md +2 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "engineering-loop",
|
|
3
|
-
"owner": {
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "naswerks"
|
|
5
|
+
},
|
|
4
6
|
"metadata": {
|
|
5
7
|
"description": "The engineering loop as a Claude Code plugin: docs-* (knowledge), spec-* (execution), init."
|
|
6
8
|
},
|
|
@@ -8,8 +10,12 @@
|
|
|
8
10
|
{
|
|
9
11
|
"name": "naswerks",
|
|
10
12
|
"description": "The engineering loop: docs-* knowledge loop, spec-* execution loop, and init for a fresh repository.",
|
|
11
|
-
"version": "0.1
|
|
12
|
-
"source":
|
|
13
|
+
"version": "0.2.1",
|
|
14
|
+
"source": {
|
|
15
|
+
"source": "npm",
|
|
16
|
+
"package": "@naswerks/engineering-loop",
|
|
17
|
+
"version": "0.2.1"
|
|
18
|
+
}
|
|
13
19
|
}
|
|
14
20
|
]
|
|
15
21
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "naswerks",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "The engineering loop: a knowledge loop (docs-*) and an execution loop (spec-*) for repositories driven by hosted agent sessions, plus init to make a repository ready for both.",
|
|
5
5
|
"author": { "name": "naswerks" },
|
|
6
6
|
"license": "MIT",
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,43 @@ version is the one in `package.json` and `.claude-plugin/plugin.json`, which mus
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.2.1] - 2026-09-20
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- `spec-seat`'s fallback for a `verify-staged` that is not on PATH names the pack root as `${CLAUDE_PLUGIN_ROOT}`
|
|
13
|
+
(substituted under Claude Code), with the folder two levels above the skill as the reading elsewhere — a
|
|
14
|
+
seat in a fresh worktree no longer has to locate the pack before it can take a staging receipt.
|
|
15
|
+
|
|
16
|
+
## [0.2.0] - 2026-09-20
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- The reading floor every seat reads is four documents plus the `_meta` trio: `patterns/code-organization.md`
|
|
21
|
+
(was `vertical-slice-anatomy.md` — it describes the layout a repository actually has and presumes no
|
|
22
|
+
pattern), `backend-patterns.md`, `frontend-patterns.md`, `testing.md`. `codegen.md` leaves the floor.
|
|
23
|
+
- The standard set a role reads on top of the floor is seven documents, each drafted by `init` only when the
|
|
24
|
+
repository shows the concern and each carrying a `doc-index.md` row either way: `codegen`,
|
|
25
|
+
`state-management`, `ui-style-guide`, `design-tokens` (the token authority, split out of the style guide),
|
|
26
|
+
`long-running-workflows` (split out of `background-work`), `realtime-events`, `background-work`.
|
|
27
|
+
`spec-child` names them by path and says an absent one has a row saying `not detected`.
|
|
28
|
+
- `docs/_meta/doc-index.md` § Role reading lists is the repository's reserved space: `Doc | what it gives
|
|
29
|
+
the seat | backend | frontend | mixed`. `spec-parent` copies a role's rows into every seed's `EXTRA DOCS`
|
|
30
|
+
line, so a team's own documents reach a seat as paths in its prompt rather than as an index to consult.
|
|
31
|
+
- `spec-pipeline` sizes every spec for one session before context compacts, with no target count;
|
|
32
|
+
`engineering-loop.md` says the same in place of a session range.
|
|
33
|
+
- `init doctor` fails a standard document that is absent without its `not detected` row, and any
|
|
34
|
+
Role-reading-lists row whose path does not exist.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- Templates `code-organization.md`, `design-tokens.md`, `long-running-workflows.md`.
|
|
39
|
+
|
|
40
|
+
### Removed
|
|
41
|
+
|
|
42
|
+
- The snapshot-stub pattern for the standard names: a repository names its documents with the standard
|
|
43
|
+
names directly; no pointer documents.
|
|
44
|
+
|
|
8
45
|
## [0.1.0] - 2026-09-20
|
|
9
46
|
|
|
10
47
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naswerks/engineering-loop",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "The engineering loop as a Claude Code plugin: a knowledge loop (docs-*), an execution loop (spec-*), and init for a fresh repository. The package root is the plugin root.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- naswerks-loop: version=0.1
|
|
1
|
+
<!-- naswerks-loop: version=0.2.1 -->
|
|
2
2
|
# The Engineering Loop — flow, seats, skills, and the ceremony
|
|
3
3
|
|
|
4
4
|
> The quick intro to how work gets built with this loop: the two loops (`docs-*` knowledge, `spec-*`
|
|
@@ -170,7 +170,8 @@ diff.
|
|
|
170
170
|
seat's own commit, so left alone it hands the NEXT seat a dirty tree. Goto 1.
|
|
171
171
|
|
|
172
172
|
**Hard rules:** no commit/push without the relayed call; explicit staging, never `git add -A`, verified
|
|
173
|
-
with `verify-staged`; codegen only through the command `patterns/codegen.md` names
|
|
173
|
+
with `verify-staged`; codegen only through the command `patterns/codegen.md` names (when the repo has
|
|
174
|
+
one); component files as
|
|
174
175
|
`patterns/frontend-patterns.md` states; additive-only, never amend pushed commits; parallel sessions only
|
|
175
176
|
when specs share no files — commits sequence regardless; seats run the pipeline's declared default model
|
|
176
177
|
(allowlist-exact, set at creation), and an investigation-heavy seat may warrant a reasoning-heavier one.
|
package/skills/init/SKILL.md
CHANGED
|
@@ -37,10 +37,16 @@ docs/
|
|
|
37
37
|
_meta/doc-index.md the menu, written LAST — every doc that exists + three repo slots:
|
|
38
38
|
## Role reading lists · ## Apps and their build commands · ## The evidence tools
|
|
39
39
|
research/ working/ archive/ guides/ patterns/ infrastructure/ features/ each with a README.md
|
|
40
|
-
patterns/
|
|
41
|
-
patterns/
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
patterns/code-organization.md patterns/backend-patterns.md
|
|
41
|
+
patterns/frontend-patterns.md patterns/testing.md the floor — always drafted; a repo
|
|
42
|
+
with no server side or no client side
|
|
43
|
+
gets an honest "not detected" doc
|
|
44
|
+
patterns/codegen.md patterns/state-management.md patterns/ui-style-guide.md
|
|
45
|
+
patterns/design-tokens.md patterns/long-running-workflows.md
|
|
46
|
+
infrastructure/realtime-events.md infrastructure/background-work.md
|
|
47
|
+
the standard set — drafted ONLY when
|
|
48
|
+
the scan finds the concern; every one
|
|
49
|
+
gets a doc-index row either way
|
|
44
50
|
CLAUDE.md the Start-here stanza appended (created with only the stanza if absent)
|
|
45
51
|
AGENTS.md the same stanza, only when the file already exists
|
|
46
52
|
.claude/settings.json the plugin pin merged in (never clobbers existing keys)
|
|
@@ -49,6 +55,19 @@ AGENTS.md the same stanza, only when the file already e
|
|
|
49
55
|
Eight folders, and the set is closed. Anything else already under `docs/` is left alone and reported as
|
|
50
56
|
"outside the loop's shape — not touched" — never an error, never a queue entry.
|
|
51
57
|
|
|
58
|
+
**The standard set is shaped by what an engineering team usually has, and a team that lacks one of them
|
|
59
|
+
is told so, not handed a placeholder.** A concern the scan finds no evidence for is NOT drafted; its
|
|
60
|
+
`doc-index.md` § Role reading lists row says `not detected — no {library/mechanism} found`, and the
|
|
61
|
+
report lists it under "not in this codebase". A seat that later meets the absent path reads that row and
|
|
62
|
+
moves on. The floor four are the exception: every repository can answer "where the code lives", "how
|
|
63
|
+
the server side is built", "how the client side is built" and "how tests run" — even when the answer to
|
|
64
|
+
one of them is "no client side here" — so those are always written.
|
|
65
|
+
|
|
66
|
+
**The reserved space.** § Role reading lists in `doc-index.md` is the repository's own table: one row
|
|
67
|
+
per doc a role should read, standard or not. The coordinator copies a role's rows into every seat's
|
|
68
|
+
`EXTRA DOCS` line, so a team's own docs reach a seat as paths in its prompt. `init` seeds the standard
|
|
69
|
+
rows; the team adds its own, and can add a role column if its seats have kinds the loop does not ship.
|
|
70
|
+
|
|
52
71
|
**Every template lives at the pack root under `templates/`** (`templates/docs/patterns/*.md`,
|
|
53
72
|
`templates/docs/infrastructure/*.md`, `templates/docs/_meta/doc-index.md`, `templates/docs/readme-*.md`,
|
|
54
73
|
`templates/claude-md-stanza.md`, `templates/settings-pin.json`). Under Claude Code the pack root is
|
|
@@ -91,9 +110,13 @@ not. `init` never overwrites, never reorders, never deletes.
|
|
|
91
110
|
the only file init writes into a folder that already exists.
|
|
92
111
|
2. `docs/_meta/docs-workflow.md` and `docs/_meta/engineering-loop.md` — byte copies of the pack's
|
|
93
112
|
`references/*` (their first line is the version stamp; copy it with the file).
|
|
94
|
-
3. The
|
|
95
|
-
|
|
96
|
-
|
|
113
|
+
3. The four floor drafts (`code-organization`, `backend-patterns`, `frontend-patterns`, `testing`) from
|
|
114
|
+
`templates/docs/patterns/*.md`, filled as below.
|
|
115
|
+
4. The standard-set drafts — `codegen`, `state-management`, `ui-style-guide`, `design-tokens`,
|
|
116
|
+
`long-running-workflows`, `realtime-events`, `background-work` — only where pass 3 found the concern.
|
|
117
|
+
Evidence per concern: a `generated/` folder or codegen config; a state library; a UI library; a tokens
|
|
118
|
+
file or token layer; a saga / workflow / state-machine mechanism; a realtime library on either side; a
|
|
119
|
+
queue, worker or scheduler.
|
|
97
120
|
5. `docs/_meta/doc-index.md` from its template, LAST, listing every doc that now exists under the four
|
|
98
121
|
living folders (drafted or repo-owned), the three repo slots filled from the scan.
|
|
99
122
|
6. The Start-here stanza (`templates/claude-md-stanza.md`) appended to `CLAUDE.md` (created if absent)
|
|
@@ -138,8 +161,9 @@ FAIL, so a CI job or a control plane can call it.
|
|
|
138
161
|
| each of the eight folders | missing | README missing | present |
|
|
139
162
|
| `_meta/docs-workflow.md`, `_meta/engineering-loop.md` | missing, or no stamp on line 1 | stamp behind the pack's version | stamp equals it |
|
|
140
163
|
| `_meta/doc-index.md` and its three slot sections | missing | a slot carries only the absent-line | filled |
|
|
141
|
-
| the
|
|
142
|
-
| the
|
|
164
|
+
| the four floor docs | missing | `status=draft`, or an `<!-- init: -->` left in | `status=current` |
|
|
165
|
+
| the seven standard docs | absent AND no doc-index row saying `not detected` | `status=draft` when present; absent with its row | present and current, or absent with its row |
|
|
166
|
+
| every path a § Role reading lists row names | the row's path does not exist | — | resolves |
|
|
143
167
|
| `CLAUDE.md` / `AGENTS.md` stanza · `.claude/settings.json` pin | — | missing | present |
|
|
144
168
|
| `verify-staged` | — | not on PATH (the row carries the fallback) | resolvable |
|
|
145
169
|
| every `docs/research/*/00-ignition-brief.md` | the five problems the control plane's parser emits (no `## The kick`; the kick has no blockquote; no `## The sequence`; the sequence holds no table; a row names no kind from `coordinator build fixit review retro witness docs-process`), or a spec a row names is missing from disk | — | clean |
|
|
@@ -157,7 +181,8 @@ state: the owner promotes each draft to `status=current` as they confirm it, sec
|
|
|
157
181
|
|
|
158
182
|
- `init` is the front door of the pack; `docs-status` is the pulse after it. Run `docs-status` once the
|
|
159
183
|
drafts are promoted to see the queue the way a session will.
|
|
160
|
-
- The floor
|
|
161
|
-
|
|
184
|
+
- The floor four are always drafted, even in a repository with no frontend — the reading floor must
|
|
185
|
+
RESOLVE for every seat kind, and "No frontend detected — fill this in" is an honest doc. The standard
|
|
186
|
+
seven are drafted only on evidence; their absence is recorded, never papered over.
|
|
162
187
|
- Counterpart skills: `spec-seat` (reads the floor), `spec-child` (reads the role rows), `spec-pipeline`
|
|
163
188
|
(writes the brief `doctor` checks), `docs-write` / `docs-process` (the queue `doctor` reads).
|
|
@@ -56,13 +56,20 @@ for (const name of ['docs-workflow.md', 'engineering-loop.md']) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// ── 4. the reading floor and the conditional docs ───────────────────────────────────────────────
|
|
59
|
-
const FLOOR = ['patterns/
|
|
60
|
-
const
|
|
59
|
+
const FLOOR = ['patterns/code-organization.md', 'patterns/backend-patterns.md', 'patterns/frontend-patterns.md', 'patterns/testing.md'];
|
|
60
|
+
const STANDARD = ['patterns/codegen.md', 'patterns/state-management.md', 'patterns/ui-style-guide.md', 'patterns/design-tokens.md', 'patterns/long-running-workflows.md', 'infrastructure/realtime-events.md', 'infrastructure/background-work.md'];
|
|
61
|
+
const roleRows = (() => { const t = read(join(repo, 'docs', '_meta', 'doc-index.md')); return t === null ? null : sectionOf(t, '## Role reading lists'); })();
|
|
61
62
|
for (const d of FLOOR) docRow(d, true);
|
|
62
|
-
for (const d of
|
|
63
|
+
for (const d of STANDARD) docRow(d, false);
|
|
63
64
|
function docRow(relPath, required) {
|
|
64
65
|
const text = read(join(repo, 'docs', relPath));
|
|
65
|
-
if (text === null) {
|
|
66
|
+
if (text === null) {
|
|
67
|
+
if (required) { row('FAIL', `docs/${relPath}`, 'missing'); return; }
|
|
68
|
+
const rowText = roleRows === null ? null : roleRows.split('\n').find((l) => l.includes(relPath));
|
|
69
|
+
if (rowText && /not detected/i.test(rowText)) row('ok', `docs/${relPath}`, 'absent, and doc-index says why (not detected)');
|
|
70
|
+
else row('FAIL', `docs/${relPath}`, 'absent with no doc-index row saying it was not detected — a seat meeting this path has no answer');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
66
73
|
const meta = /<!-- meta:[^>]*status=([a-z]+)/.exec(text);
|
|
67
74
|
if (!meta) row('DEGRADE', `docs/${relPath}`, 'no <!-- meta --> line');
|
|
68
75
|
else if (meta[1] === 'draft') row('DEGRADE', `docs/${relPath}`, 'status=draft — scanned, not decided');
|
|
@@ -70,6 +77,17 @@ function docRow(relPath, required) {
|
|
|
70
77
|
if (/<!-- init:/.test(text)) row('DEGRADE', `docs/${relPath}`, 'an <!-- init: --> instruction was left in the file');
|
|
71
78
|
}
|
|
72
79
|
|
|
80
|
+
// ── 4b. every path a Role reading lists row names resolves ─────────────────────────────────────
|
|
81
|
+
if (roleRows !== null) {
|
|
82
|
+
for (const line of roleRows.split('\n').filter((l) => l.trim().startsWith('|') && !/^\|\s*-/.test(l.trim()) && !/^\|\s*Doc\s*\|/i.test(l.trim()))) {
|
|
83
|
+
for (const m of line.matchAll(/`((?:patterns|infrastructure|guides|features)\/[A-Za-z0-9_.-]+\.md)`|\]\((?:\.\.\/)?((?:patterns|infrastructure|guides|features)\/[A-Za-z0-9_.-]+\.md)\)/g)) {
|
|
84
|
+
const p = m[1] || m[2];
|
|
85
|
+
if (/not detected/i.test(line)) continue;
|
|
86
|
+
row(existsSync(join(repo, 'docs', p)) ? 'ok' : 'FAIL', `doc-index row: docs/${p}`, existsSync(join(repo, 'docs', p)) ? '' : 'the row names a path that does not exist');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
73
91
|
// ── 5. CLAUDE.md / AGENTS.md stanza, settings pin ───────────────────────────────────────────────
|
|
74
92
|
for (const name of ['CLAUDE.md', 'AGENTS.md']) {
|
|
75
93
|
const text = read(join(repo, name));
|
|
@@ -34,16 +34,24 @@ apply** (`spec-seat`, Step 0). This list is for a build seat working from a spec
|
|
|
34
34
|
|
|
35
35
|
## Role — the adds, on top of spec-seat's Step 0 floor
|
|
36
36
|
|
|
37
|
+
The loop's standard docs, by path. **Read every one that exists for your role.** One that is absent was
|
|
38
|
+
not detected by `init` — `docs/_meta/doc-index.md` § Role reading lists carries a row saying so — and is
|
|
39
|
+
not a missing-file finding. `patterns/codegen.md` is read by any seat that touches a generated folder.
|
|
40
|
+
|
|
37
41
|
| Role | Adds |
|
|
38
42
|
|---|---|
|
|
39
|
-
| **frontend** | `patterns/state-management.md` · `patterns/ui-style-guide.md` · `infrastructure/realtime-events.md` (the poke/refetch concept trips sessions up — read it even for "pure UI" work) ·
|
|
40
|
-
| **backend** | `infrastructure/realtime-events.md` (the poke/refetch concept trips sessions up — read it even for "pure API" work) · `infrastructure/background-work.md` as the task warrants ·
|
|
41
|
-
| **mixed** | **NOT every set by default** — read the adds for the surfaces your spec ACTUALLY touches, decided at recon once you have read the spec. **This is the default role and it covers every surface with no role of its own** — a
|
|
43
|
+
| **frontend** | `patterns/state-management.md` · `patterns/ui-style-guide.md` · `patterns/design-tokens.md` · `infrastructure/realtime-events.md` (the poke/refetch concept trips sessions up — read it even for "pure UI" work) · `patterns/codegen.md` when the client consumes generated types |
|
|
44
|
+
| **backend** | `infrastructure/realtime-events.md` (the poke/refetch concept trips sessions up — read it even for "pure API" work) · `infrastructure/background-work.md` · `patterns/long-running-workflows.md` as the task warrants · `patterns/codegen.md` when the server side emits generated code |
|
|
45
|
+
| **mixed** | **NOT every set by default** — read the adds for the surfaces your spec ACTUALLY touches, decided at recon once you have read the spec. **This is the default role and it covers every surface with no role of its own** — a CLI, a sidecar, a worker project; docs work needs nothing beyond the Step 0 floor |
|
|
46
|
+
|
|
47
|
+
**This repository's own docs reach you as paths too, not as an index to consult:** the coordinator copies
|
|
48
|
+
your role's rows from `docs/_meta/doc-index.md` § Role reading lists into your prompt's `EXTRA DOCS` line.
|
|
49
|
+
Read those the same way. If your prompt carries no `EXTRA DOCS` line, read that section yourself once and
|
|
50
|
+
say in your PLAN TLDR which rows you took.
|
|
42
51
|
|
|
43
52
|
A role is *which docs does this build session read* — nothing else. Jobs are SEAT KINDS, not roles:
|
|
44
53
|
`docs-process` is a session type of its own, and a spec that touches a surface with no role of its own is
|
|
45
|
-
`mixed` with that surface's
|
|
46
|
-
that concern is not in this repo yet, and there is nothing to read for it.
|
|
54
|
+
`mixed` with that surface's rows.
|
|
47
55
|
|
|
48
56
|
## Recon — the build seat's first act
|
|
49
57
|
|
|
@@ -32,13 +32,14 @@ hand-testing what shipped. Everything else that a human does hand-cranked, you d
|
|
|
32
32
|
|
|
33
33
|
## Read first
|
|
34
34
|
|
|
35
|
-
**Step 0 — the same floor every seat reads, all
|
|
36
|
-
from the context they build in. A coordinator that has not
|
|
37
|
-
that has not read `codegen.md`
|
|
35
|
+
**Step 0 — the same floor every seat reads, all seven, plus every standard doc this repository has.**
|
|
36
|
+
You verify every seat's work, so you start from the context they build in. A coordinator that has not
|
|
37
|
+
read `testing.md` cannot judge a receipt; one that has not read `codegen.md` (when the repo has one)
|
|
38
|
+
cannot spot a hand-written generated file.
|
|
38
39
|
|
|
39
40
|
`_meta/doc-index.md` · `_meta/docs-workflow.md` · `_meta/engineering-loop.md` ·
|
|
40
|
-
`patterns/
|
|
41
|
-
`patterns/testing.md`
|
|
41
|
+
`patterns/code-organization.md` · `patterns/backend-patterns.md` · `patterns/frontend-patterns.md` ·
|
|
42
|
+
`patterns/testing.md` — then every doc `doc-index.md` § Role reading lists carries a path for.
|
|
42
43
|
|
|
43
44
|
**Step 1 — the effort**, in order:
|
|
44
45
|
|
|
@@ -113,9 +114,12 @@ read the board and answer on first receipt rather than spending a round-trip.
|
|
|
113
114
|
defect even when it works: there are then two sources for one contract and only one of them gets
|
|
114
115
|
corrected.
|
|
115
116
|
|
|
116
|
-
**Pick the docs:** the
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
**Pick the docs:** the floor and the loop's standard docs are settled (`spec-seat`'s Step 0 +
|
|
118
|
+
`spec-child`'s role table). **This repository's own docs are yours to seed, by path, every time:** copy
|
|
119
|
+
the seat's role rows from `docs/_meta/doc-index.md` § Role reading lists into the prompt's `EXTRA DOCS`
|
|
120
|
+
line — a seat follows a path in its prompt and does not reliably follow an index. Then add the extras
|
|
121
|
+
the task itself warrants. When in doubt, seed the doc: a seat reading one extra doc is cheaper than a
|
|
122
|
+
seat guessing.
|
|
119
123
|
|
|
120
124
|
**The seed-retirement rule:** each new seed restates ONLY what OVERRIDES a default (every seat
|
|
121
125
|
re-acquires the defaults from the skill + umbrella from scratch) and DROPS what merely confirms them.
|
|
@@ -368,7 +372,7 @@ so read them as run-time obligations, not close-out ones:
|
|
|
368
372
|
branch-deletion backstop. The fence fires on the commands a careful seat runs to PROVE its work.
|
|
369
373
|
- Seats never edit `project-status.md` or memory files; never run `docs-write` unprompted; respect the
|
|
370
374
|
umbrella's out-of-scope list; codegen only through the command `patterns/codegen.md` § Running codegen
|
|
371
|
-
names; component files laid out as `patterns/frontend-patterns.md` § Component files states. Run the
|
|
375
|
+
names (when the repo has one); component files laid out as `patterns/frontend-patterns.md` § Component files states. Run the
|
|
372
376
|
suite lanes SERIALLY.
|
|
373
377
|
- Cross-slice changes (touching a shipped spec's files) need your explicit approval and get recorded as
|
|
374
378
|
a departure. Additive-only; never amend pushed commits.
|
|
@@ -440,7 +444,8 @@ Pipeline context: {umbrella path} (settled decisions — don't relitigate) + {pr
|
|
|
440
444
|
(READ-ONLY, coordinator-owned — prior rows, deferred findings, and process incidents are your contract).
|
|
441
445
|
|
|
442
446
|
EXTRA DOCS for this task (beyond your role's floor — read them):
|
|
443
|
-
{
|
|
447
|
+
{this repository's rows for the role, copied from doc-index.md § Role reading lists, by path}
|
|
448
|
+
{the coordinator's task-specific picks}
|
|
444
449
|
|
|
445
450
|
PRIOR SPECS ARE SHIPPED at {hash} — build against their ACTUAL shapes:
|
|
446
451
|
{bullet the real endpoints, contracts, helpers-to-reuse, caveats, and coordinator-adopted requirements
|
|
@@ -102,9 +102,12 @@ other; an identity or authorization plane that is trustworthy per-slice and forg
|
|
|
102
102
|
ordinary correctness: null and error paths, concurrency, data loss, exception swallowing.
|
|
103
103
|
|
|
104
104
|
**Lens 2 — the patterns, and the language.** Read the diff against `patterns/backend-patterns.md`,
|
|
105
|
-
`patterns/frontend-patterns.md`, `patterns/
|
|
106
|
-
`patterns/codegen.md`
|
|
107
|
-
|
|
105
|
+
`patterns/frontend-patterns.md`, `patterns/code-organization.md`, `patterns/testing.md`, and every
|
|
106
|
+
standard doc the repository has (`patterns/codegen.md`, `patterns/state-management.md`,
|
|
107
|
+
`patterns/ui-style-guide.md`, `patterns/design-tokens.md`, `infrastructure/realtime-events.md`,
|
|
108
|
+
`infrastructure/background-work.md`, `patterns/long-running-workflows.md` — those that exist) plus the
|
|
109
|
+
rows in `docs/_meta/doc-index.md` § Role reading lists — and against ordinary good practice in the
|
|
110
|
+
language, which no pattern doc covers exhaustively.
|
|
108
111
|
|
|
109
112
|
**A pattern break is not automatically a defect.** There are legitimate reasons to depart. Your job is
|
|
110
113
|
that **every departure is IDENTIFIED and its reason stated** — an intentional break with a recorded reason
|
|
@@ -61,20 +61,24 @@ Then recon the tree: `git rev-parse HEAD`, `git status --porcelain`, `git branch
|
|
|
61
61
|
|
|
62
62
|
| Doc | What it gives you |
|
|
63
63
|
|---|---|
|
|
64
|
-
| `patterns/
|
|
64
|
+
| `patterns/code-organization.md` | where the code lives and where a new piece goes, every stack the repo has |
|
|
65
65
|
| `patterns/backend-patterns.md` | how the server side is built here |
|
|
66
66
|
| `patterns/frontend-patterns.md` | how the client side is built here |
|
|
67
67
|
| `patterns/testing.md` | how to write and RUN the suites — including the run protocol |
|
|
68
|
-
| `patterns/codegen.md` | what is generated and how; never hand-write a generated folder |
|
|
69
68
|
|
|
70
69
|
**That is the default set, required regardless of role** —
|
|
71
70
|
`docs/_meta/doc-index.md` · `docs/_meta/docs-workflow.md` · `docs/_meta/engineering-loop.md` ·
|
|
72
|
-
`patterns/
|
|
73
|
-
`patterns/testing.md`
|
|
71
|
+
`patterns/code-organization.md` · `patterns/backend-patterns.md` · `patterns/frontend-patterns.md` ·
|
|
72
|
+
`patterns/testing.md`
|
|
74
73
|
<!-- A control plane may read this line + list as its preset hint (it looks for "default set" and "role" on
|
|
75
74
|
one line, then collects the backticked paths until a blank line). Keep the phrase and the list
|
|
76
75
|
contiguous, or the hint silently empties. -->
|
|
77
76
|
|
|
77
|
+
**On top of the floor, your job skill names the loop's standard docs for your role by path, and your
|
|
78
|
+
prompt's `EXTRA DOCS` line names this repository's own.** Read every one that exists. A standard doc that
|
|
79
|
+
is absent was not detected by `init` — `docs/_meta/doc-index.md` § Role reading lists carries a row
|
|
80
|
+
saying so — and is not a missing-file finding.
|
|
81
|
+
|
|
78
82
|
A doc marked `status=draft` in its meta line was scanned by `init`, not decided by the repo's owners —
|
|
79
83
|
read it as the starting point it is, and treat a rule it states without a cited source as a question for
|
|
80
84
|
your PLAN TLDR, not a law.
|
|
@@ -348,7 +352,9 @@ doorbell with no follow-through**; if you receive one bare, retry anyway and say
|
|
|
348
352
|
exit 0 and NO output, and `git status` cannot show the loss** (an ignored file is neither staged nor
|
|
349
353
|
dirty, so status looks *cleaner* after it — a `bin/` rule can eat a composition root, a `*.log` rule a
|
|
350
354
|
folder of receipts). Run `verify-staged {your explicit staging list}` — one command, gate-legal (not on
|
|
351
|
-
PATH: `node
|
|
355
|
+
PATH: `node ${CLAUDE_PLUGIN_ROOT}/bin/verify-staged.mjs {list}` — under Claude Code that variable is the
|
|
356
|
+
pack root, the folder this skill loaded from; in another harness it is the folder holding
|
|
357
|
+
`.claude-plugin/plugin.json`, two levels above this SKILL.md; `--from-file` takes the list from a file,
|
|
352
358
|
`--against head` checks after the commit). Exit 0 is your staging receipt; non-zero names every missing
|
|
353
359
|
file and the `.gitignore` rule that ate it, and is a **stop-the-line finding**: do not commit, do not
|
|
354
360
|
`git add -f`, do not touch `.gitignore` — rename the artifact off the pattern (receipts stage as `.txt`,
|
|
@@ -365,8 +371,8 @@ doorbell with no follow-through**; if you receive one bare, retry anyway and say
|
|
|
365
371
|
echo text — the deny layer matches text, not parsed verbs.
|
|
366
372
|
- Prefer native read/glob/grep tools for reads; a shell read flows with its row like any other
|
|
367
373
|
non-boundary call.
|
|
368
|
-
- **Codegen only through the command `patterns/codegen.md` § Running codegen names**
|
|
369
|
-
generated folder.
|
|
374
|
+
- **Codegen only through the command `patterns/codegen.md` § Running codegen names** (when the repo has
|
|
375
|
+
one) — never hand-write a generated folder.
|
|
370
376
|
- **Never improvise a qualifying path in.** If a push parks and the remedy you can think of is touching a
|
|
371
377
|
`docs/working/` file or the tracker to satisfy a predicate, that is fabricating a receipt. Raise a
|
|
372
378
|
`## MID-BUILD QUESTION` and price the options; do not execute it and do not invent a way around it.
|
|
@@ -21,12 +21,11 @@
|
|
|
21
21
|
|
|
22
22
|
| Doc | When to read |
|
|
23
23
|
|-----|-------------|
|
|
24
|
-
| [
|
|
24
|
+
| [code-organization](../patterns/code-organization.md) | **Where the code lives and where a new piece goes** — the folder shape as it is, per stack, and the add-a-feature checklist |
|
|
25
25
|
| [backend-patterns](../patterns/backend-patterns.md) | **How the server side is built here** — data layer, API layer, write paths, registration |
|
|
26
26
|
| [frontend-patterns](../patterns/frontend-patterns.md) | **How the client side is built here** — architecture rules, component kinds and files, state, styling |
|
|
27
27
|
| [testing](../patterns/testing.md) | **How to write and RUN the suites** — the lanes and their exact commands, the run protocol, what to test where, the controls discipline |
|
|
28
|
-
|
|
29
|
-
<!-- init: add rows for state-management and ui-style-guide when they were drafted. -->
|
|
28
|
+
<!-- init: add rows for codegen, state-management, ui-style-guide, design-tokens and long-running-workflows when they were drafted; the hook for each ends "(draft — scanned, not decided)". -->
|
|
30
29
|
|
|
31
30
|
## Infrastructure — what runs UNDER THE HOOD
|
|
32
31
|
|
|
@@ -49,15 +48,22 @@
|
|
|
49
48
|
|
|
50
49
|
## Role reading lists
|
|
51
50
|
|
|
52
|
-
The
|
|
53
|
-
names the
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
60
|
-
<!--
|
|
51
|
+
The docs a build seat reads on top of the floor every seat reads (`spec-seat` Step 0). The `spec-child`
|
|
52
|
+
skill names the loop's standard docs by path; this table is the repository's reserved space — one row per
|
|
53
|
+
doc, saying which roles read it. The coordinator copies a role's rows into every seat's seed as
|
|
54
|
+
`EXTRA DOCS`, so a seat sees paths, not this index. Add a row for any doc of your own a role should read;
|
|
55
|
+
add a role column if your seats have kinds the loop does not ship.
|
|
56
|
+
|
|
57
|
+
| Doc | What it gives the seat | backend | frontend | mixed |
|
|
58
|
+
|---|---|---|---|---|
|
|
59
|
+
<!-- init: one row per standard doc the scan found evidence for and drafted (codegen, state-management,
|
|
60
|
+
ui-style-guide, design-tokens, realtime-events, background-work, long-running-workflows), with the
|
|
61
|
+
roles that read it marked `x` (realtime-events: backend + frontend; state-management, ui-style-guide,
|
|
62
|
+
design-tokens: frontend; background-work, long-running-workflows: backend; codegen: any seat that
|
|
63
|
+
touches a generated folder). One row per standard doc NOT drafted, in the form
|
|
64
|
+
"| `patterns/state-management.md` | not detected — no state library found | | | |" so a seat that
|
|
65
|
+
meets the absent path knows why. `mixed` reads the rows for the surfaces its spec touches. -->
|
|
66
|
+
<!-- repo rows go here: a doc this repository has that the loop's standard set does not name -->
|
|
61
67
|
|
|
62
68
|
## Apps and their build commands
|
|
63
69
|
|
|
@@ -32,11 +32,13 @@
|
|
|
32
32
|
|
|
33
33
|
## Long-running workflows
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
Snapshot — multi-stage work (stages, per-item progress, exactly-once transitions) is the authority of
|
|
36
|
+
[long-running-workflows](../patterns/long-running-workflows.md) when the repo has one; this page is the
|
|
37
|
+
transport it runs on.
|
|
38
|
+
|
|
39
|
+
<!-- init: fill — one sentence naming the workflow mechanism (from long-running-workflows.md when drafted).
|
|
40
|
+
absent — "No multi-stage workflow detected — every background job here is single-stage; fill this in
|
|
41
|
+
when one appears." -->
|
|
40
42
|
|
|
41
43
|
## Gotchas
|
|
42
44
|
|
|
@@ -50,4 +52,4 @@
|
|
|
50
52
|
|------|---------|
|
|
51
53
|
|
|
52
54
|
## Lineage
|
|
53
|
-
- **Related** — [backend-patterns](../patterns/backend-patterns.md) · [realtime-events](realtime-events.md)
|
|
55
|
+
- **Related** — [backend-patterns](../patterns/backend-patterns.md) · [realtime-events](realtime-events.md) · [long-running-workflows](../patterns/long-running-workflows.md)
|
|
@@ -93,4 +93,4 @@
|
|
|
93
93
|
absent — "| (none detected) | fill this in: the base entity, the data context, the composition root |" -->
|
|
94
94
|
|
|
95
95
|
## Lineage
|
|
96
|
-
- **Related** — [
|
|
96
|
+
- **Related** — [code-organization](code-organization.md) · [testing](testing.md) · [codegen](codegen.md)
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Code Organization
|
|
2
2
|
|
|
3
|
-
> Where
|
|
3
|
+
> Where the code lives and where a new piece goes — the folder shape this repository actually uses, per
|
|
4
|
+
> stack, and the checklist for adding a feature to it. Last verified {today}.
|
|
4
5
|
<!-- meta: type=pattern; status=draft; verified={today}; lineage=0 -->
|
|
5
6
|
<!-- naswerks-loop: draft; scanned={files} -->
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## The shape
|
|
10
11
|
|
|
11
12
|
<!-- init: scan — the folder layout two deep for every stack (Features/, src/app/, apps/*, packages/*,
|
|
12
|
-
cmd/, internal/, lib/), and ONE existing feature
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
cmd/, internal/, lib/, a layered src/{Domain,Application,Infrastructure}), and ONE existing feature or
|
|
14
|
+
module per stack.
|
|
15
|
+
fill — name the organization as it IS (vertical slices, layers, packages in a monorepo, a flat
|
|
16
|
+
module tree — whatever the folders say), then one ASCII tree per stack showing a REAL feature/module
|
|
17
|
+
as it exists, side by side when there are two, with a comment per folder saying what goes there; then
|
|
18
|
+
one sentence per stack on what lives OUTSIDE a feature (shared infrastructure, cross-cutting code).
|
|
19
|
+
Do not describe a pattern the folders do not show.
|
|
20
|
+
absent — "No code layout detected — fill this in: where a feature's or module's files go, per
|
|
21
|
+
stack, as a tree copied from a real one." -->
|
|
18
22
|
|
|
19
23
|
```
|
|
20
24
|
{stack A} {stack B, if any}
|
|
@@ -25,22 +29,22 @@
|
|
|
25
29
|
## The kinds of file, and their roles
|
|
26
30
|
|
|
27
31
|
<!-- init: scan — the kinds the trees above show (endpoint / model / query / service; page / component /
|
|
28
|
-
store; command / handler).
|
|
32
|
+
store; command / handler; a module's public surface).
|
|
29
33
|
fill — a table `Kind | Role | Where | Owns` with one row per kind.
|
|
30
34
|
absent — "No kinds detected — fill this in: each kind of file a feature holds, and what it owns." -->
|
|
31
35
|
|
|
32
36
|
| Kind | Role | Where | Owns |
|
|
33
37
|
|------|------|-------|------|
|
|
34
38
|
|
|
35
|
-
## Checklist:
|
|
39
|
+
## Checklist: adding a feature
|
|
36
40
|
|
|
37
41
|
<!-- init: scan — the trees above, the registration points (composition root, router, module list), the
|
|
38
42
|
test conventions in patterns/testing.md § What to test where.
|
|
39
43
|
fill — an ordered `- [ ]` checklist per stack: create X in {path} (one line on what it must extend
|
|
40
44
|
or implement), register it in {file}, add the route/handler in {file}, add the tests the testing doc
|
|
41
45
|
names for each kind, run the build. Each item is a real path.
|
|
42
|
-
absent — "- [ ] No
|
|
43
|
-
|
|
46
|
+
absent — "- [ ] No layout detected — fill this in: the ordered steps that add a feature, each naming
|
|
47
|
+
its file." -->
|
|
44
48
|
|
|
45
49
|
### {stack A}
|
|
46
50
|
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
## Gotchas
|
|
54
58
|
|
|
55
59
|
<!-- init: scan — CONTRIBUTING.md, CLAUDE.md, AGENTS.md, lint rules that fire on layout (import
|
|
56
|
-
boundaries, dependency-cruiser, ArchUnit-style rules).
|
|
60
|
+
boundaries, dependency-cruiser, ArchUnit-style rules, banned-symbol lists).
|
|
57
61
|
fill — one `### Gotcha:` per written-down layout rule, citing its source file.
|
|
58
62
|
absent — "No layout gotchas written down yet — fill this in the first time one bites." -->
|
|
59
63
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Design Tokens
|
|
2
|
+
|
|
3
|
+
> The token authority: which colour, spacing and typography tokens exist, what each means, and how
|
|
4
|
+
> component CSS consumes them. Component usage (which class for which job) lives in
|
|
5
|
+
> [ui-style-guide](ui-style-guide.md). Last verified {today}.
|
|
6
|
+
<!-- meta: type=pattern; status=draft; verified={today}; lineage=0 -->
|
|
7
|
+
<!-- naswerks-loop: draft; scanned={files} -->
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
<!-- init: scan — a tokens/theme file (a CSS file defining --* custom properties, a tailwind/daisyui
|
|
14
|
+
theme block, a design-system package), the global stylesheet, how themes are switched.
|
|
15
|
+
fill — two to four sentences: the token system, the library that emits it, how a theme is selected.
|
|
16
|
+
absent — this doc is only drafted when a tokens file or a UI library with a token layer is found. -->
|
|
17
|
+
|
|
18
|
+
## Token reference
|
|
19
|
+
|
|
20
|
+
<!-- init: fill — one table per family (`Token | CSS variable | Purpose | When to use`): brand, base /
|
|
21
|
+
surface, status; each row read from the tokens file, never invented.
|
|
22
|
+
absent — "No token definitions found — fill this in." -->
|
|
23
|
+
|
|
24
|
+
### Brand
|
|
25
|
+
|
|
26
|
+
| Token | CSS variable | Purpose | When to use |
|
|
27
|
+
|-------|-------------|---------|-------------|
|
|
28
|
+
|
|
29
|
+
### Base / surface
|
|
30
|
+
|
|
31
|
+
| Token | CSS variable | Purpose | When to use |
|
|
32
|
+
|-------|-------------|---------|-------------|
|
|
33
|
+
|
|
34
|
+
### Status
|
|
35
|
+
|
|
36
|
+
| Token | CSS variable | Purpose | When to use |
|
|
37
|
+
|-------|-------------|---------|-------------|
|
|
38
|
+
|
|
39
|
+
## Consuming tokens in component CSS
|
|
40
|
+
|
|
41
|
+
<!-- init: scan — how existing component styles reference tokens (var(--…), a theme() helper, a mixin).
|
|
42
|
+
fill — the ONE rule in this repo's form ("use `var(--…)` directly; express opacity with `color-mix`;
|
|
43
|
+
never a literal colour"), a fenced example copied from a real stylesheet, and the dead forms to grep for
|
|
44
|
+
if the library moved majors.
|
|
45
|
+
absent — "No token consumption found in component styles — fill this in." -->
|
|
46
|
+
|
|
47
|
+
## Rules
|
|
48
|
+
|
|
49
|
+
<!-- init: scan — a style lint, a stylesheet rule spec, a CONTRIBUTING note.
|
|
50
|
+
fill — bold-lead imperative bullets, each citing its source when written down; the loop supplies one:
|
|
51
|
+
"**A stylesheet never names a colour** — every value is a token or a mix over one, so a skin or a dark
|
|
52
|
+
mode needs no per-component work."
|
|
53
|
+
absent — the one loop-supplied bullet, then "- No further token rules found written down — fill this
|
|
54
|
+
in." -->
|
|
55
|
+
|
|
56
|
+
## Key Files
|
|
57
|
+
|
|
58
|
+
| File | Purpose |
|
|
59
|
+
|------|---------|
|
|
60
|
+
|
|
61
|
+
## Lineage
|
|
62
|
+
- **Related** — [ui-style-guide](ui-style-guide.md) · [frontend-patterns](frontend-patterns.md)
|
|
@@ -89,4 +89,4 @@
|
|
|
89
89
|
absent — "| (none detected) | fill this in: the app config, the routes, the shared components |" -->
|
|
90
90
|
|
|
91
91
|
## Lineage
|
|
92
|
-
- **Related** — [
|
|
92
|
+
- **Related** — [code-organization](code-organization.md) · [testing](testing.md) · [codegen](codegen.md) · [backend-patterns](backend-patterns.md)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Long-Running Workflows
|
|
2
|
+
|
|
3
|
+
> How multi-stage work is orchestrated in this repository: the stages, per-item progress, exactly-once
|
|
4
|
+
> transitions, and how progress reaches the client. The transport it runs on is
|
|
5
|
+
> [background-work](../infrastructure/background-work.md). Last verified {today}.
|
|
6
|
+
<!-- meta: type=pattern; status=draft; verified={today}; lineage=0 -->
|
|
7
|
+
<!-- naswerks-loop: draft; scanned={files} -->
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
<!-- init: scan — a saga / orchestration / workflow / state-machine base class or library (a saga
|
|
14
|
+
framework, a durable-functions style runtime, a job with named stages), the entities that record
|
|
15
|
+
stage state.
|
|
16
|
+
fill — two to four sentences: what a workflow is here, what guarantees it makes, and which features
|
|
17
|
+
use it.
|
|
18
|
+
absent — this doc is only drafted when a multi-stage workflow mechanism is found. -->
|
|
19
|
+
|
|
20
|
+
## The shape
|
|
21
|
+
|
|
22
|
+
<!-- init: fill — an ASCII diagram of one REAL workflow (trigger, stages, the transition that starts the
|
|
23
|
+
next stage, completion), then the base classes / tables that hold it.
|
|
24
|
+
absent — "No workflow found to diagram — fill this in with the first one." -->
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
{trigger} -> stage 1 -> stage 2 -> ... -> complete
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Exactly-once transitions
|
|
31
|
+
|
|
32
|
+
<!-- init: scan — the code that decides a stage is done (a TryComplete, a row lock, a compare-and-set, an
|
|
33
|
+
idempotency key).
|
|
34
|
+
fill — what guarantees a stage transition happens once, with the real symbol named; what happens on a
|
|
35
|
+
retry; who owns the transition.
|
|
36
|
+
absent — "No transition guard found — fill this in: how a stage completes exactly once under
|
|
37
|
+
concurrency." -->
|
|
38
|
+
|
|
39
|
+
## Per-item progress and failure
|
|
40
|
+
|
|
41
|
+
<!-- init: fill — how an item starts, completes and fails inside a stage; what a stuck item looks like and
|
|
42
|
+
who reaps it; how progress is reported (an event, a poke, a row).
|
|
43
|
+
absent — "No per-item tracking found — fill this in." -->
|
|
44
|
+
|
|
45
|
+
## Creating a new workflow — checklist
|
|
46
|
+
|
|
47
|
+
<!-- init: fill — an ordered `- [ ]` list: the base class to extend, the stage events or handlers to add,
|
|
48
|
+
the registration, the tests the testing doc names (the concurrency test especially).
|
|
49
|
+
absent — "- [ ] No workflow mechanism detected — fill this in when one appears." -->
|
|
50
|
+
|
|
51
|
+
## Rules
|
|
52
|
+
|
|
53
|
+
<!-- init: scan — comments on the base class, CONTRIBUTING notes.
|
|
54
|
+
fill — bold-lead imperative bullets citing their source.
|
|
55
|
+
absent — "- No workflow rules found written down — fill this in." -->
|
|
56
|
+
|
|
57
|
+
## Key Files
|
|
58
|
+
|
|
59
|
+
| File | Purpose |
|
|
60
|
+
|------|---------|
|
|
61
|
+
|
|
62
|
+
## Lineage
|
|
63
|
+
- **Related** — [background-work](../infrastructure/background-work.md) · [backend-patterns](backend-patterns.md) · [testing](testing.md)
|
|
@@ -100,4 +100,4 @@ A test that cannot go red is a green light with a test's name on it. For every p
|
|
|
100
100
|
absent — "| (none detected) | fill this in: the runner config, the shared fixtures, the CI workflow |" -->
|
|
101
101
|
|
|
102
102
|
## Lineage
|
|
103
|
-
- **Related** — [backend-patterns](backend-patterns.md) · [frontend-patterns](frontend-patterns.md) · [
|
|
103
|
+
- **Related** — [backend-patterns](backend-patterns.md) · [frontend-patterns](frontend-patterns.md) · [code-organization](code-organization.md)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# UI Style Guide
|
|
2
2
|
|
|
3
3
|
> Which class or component to reach for, for which job, and the composition rules that keep screens
|
|
4
|
-
> consistent
|
|
4
|
+
> consistent. The tokens themselves are the authority of [design-tokens](design-tokens.md). Last verified {today}.
|
|
5
5
|
<!-- meta: type=pattern; status=draft; verified={today}; lineage=0 -->
|
|
6
6
|
<!-- naswerks-loop: draft; scanned={files} -->
|
|
7
7
|
|
|
@@ -52,12 +52,13 @@ Every data-driven page handles four states: **loading**, **error**, **empty**, *
|
|
|
52
52
|
|
|
53
53
|
## Tokens
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
Snapshot — the token authority is [design-tokens](design-tokens.md): which tokens exist, what each
|
|
56
|
+
means, and the one rule for consuming them in component CSS. This page names the class for the job; that
|
|
57
|
+
page names the value behind the class.
|
|
58
|
+
|
|
59
|
+
<!-- init: fill — one sentence naming the token family this UI library exposes (from design-tokens.md when
|
|
60
|
+
drafted). absent — "No design tokens detected — the classes above are the whole vocabulary; fill this in
|
|
61
|
+
if a token layer appears." -->
|
|
61
62
|
|
|
62
63
|
## Forms
|
|
63
64
|
|
|
@@ -73,4 +74,4 @@ Every data-driven page handles four states: **loading**, **error**, **empty**, *
|
|
|
73
74
|
|---------|-------|
|
|
74
75
|
|
|
75
76
|
## Lineage
|
|
76
|
-
- **Related** — [frontend-patterns](frontend-patterns.md)
|
|
77
|
+
- **Related** — [frontend-patterns](frontend-patterns.md) · [design-tokens](design-tokens.md)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Conventions to FOLLOW when writing code. Prescriptive: truth is by decision, so a mismatch between a
|
|
4
4
|
pattern doc and the code is usually a code problem to flag, not a doc to rewrite. Every seat reads the
|
|
5
|
-
floor (`
|
|
6
|
-
|
|
5
|
+
floor (`code-organization`, `backend-patterns`, `frontend-patterns`, `testing`) before it writes a
|
|
6
|
+
line, and its role's docs on top of it; a doc marked `status=draft` was scanned by `init`, not decided — promote it as
|
|
7
7
|
you confirm each section.
|
|
8
8
|
|
|
9
9
|
A README in this folder is never a queue entry.
|