@naswerks/engineering-loop 0.2.1 → 0.5.0

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.
Files changed (35) hide show
  1. package/.claude-plugin/marketplace.json +2 -6
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +94 -0
  4. package/README.md +49 -11
  5. package/package.json +1 -1
  6. package/references/docs-workflow.md +119 -10
  7. package/references/engineering-loop.md +27 -2
  8. package/skills/docs-audit-feature/SKILL.md +24 -20
  9. package/skills/docs-audit-full/SKILL.md +17 -9
  10. package/skills/docs-backlog/SKILL.md +6 -3
  11. package/skills/docs-process/SKILL.md +67 -66
  12. package/skills/docs-status/SKILL.md +25 -15
  13. package/skills/docs-write/SKILL.md +9 -6
  14. package/skills/init/SKILL.md +88 -22
  15. package/skills/init/scripts/doctor.mjs +131 -18
  16. package/skills/init/scripts/owned.mjs +96 -0
  17. package/skills/init/scripts/refresh.mjs +129 -0
  18. package/skills/spec-child/SKILL.md +1 -1
  19. package/skills/spec-parent/SKILL.md +20 -9
  20. package/skills/spec-pipeline/SKILL.md +23 -13
  21. package/skills/spec-retro/SKILL.md +5 -2
  22. package/skills/spec-review/SKILL.md +10 -6
  23. package/skills/spec-seat/SKILL.md +11 -6
  24. package/templates/docs/_meta/doc-index.md +7 -1
  25. package/templates/docs/infrastructure/background-work.md +1 -1
  26. package/templates/docs/infrastructure/realtime-events.md +1 -1
  27. package/templates/docs/patterns/backend-patterns.md +1 -1
  28. package/templates/docs/patterns/code-organization.md +1 -1
  29. package/templates/docs/patterns/codegen.md +1 -1
  30. package/templates/docs/patterns/design-tokens.md +1 -1
  31. package/templates/docs/patterns/frontend-patterns.md +1 -1
  32. package/templates/docs/patterns/long-running-workflows.md +1 -1
  33. package/templates/docs/patterns/state-management.md +1 -1
  34. package/templates/docs/patterns/testing.md +1 -1
  35. package/templates/docs/patterns/ui-style-guide.md +1 -1
@@ -10,12 +10,8 @@
10
10
  {
11
11
  "name": "naswerks",
12
12
  "description": "The engineering loop: docs-* knowledge loop, spec-* execution loop, and init for a fresh repository.",
13
- "version": "0.2.1",
14
- "source": {
15
- "source": "npm",
16
- "package": "@naswerks/engineering-loop",
17
- "version": "0.2.1"
18
- }
13
+ "version": "0.5.0",
14
+ "source": "./"
19
15
  }
20
16
  ]
21
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naswerks",
3
- "version": "0.2.1",
3
+ "version": "0.5.0",
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,100 @@ version is the one in `package.json` and `.claude-plugin/plugin.json`, which mus
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.5.0] - 2026-09-24
9
+
10
+ ### Added
11
+
12
+ - **The menu declares its shape.** `docs/_meta/doc-index.md` carries `<!-- naswerks-loop: menu=all -->` (it
13
+ lists every living doc: the repository has no other index; the default, and what a menu with no such line
14
+ means) or `<!-- naswerks-loop: menu=curated; index={path} -->` (the repository already indexes every doc in
15
+ `{path}`; the menu lists the docs its seats read). `docs-workflow.md` § The repository-owned sections
16
+ explains both, and the loop's standard for a doc on a curated menu: a header at a decided status and a
17
+ `## Key Files` section. `init` writes `menu=curated` when its scan finds an index the repository already
18
+ keeps; `docs-process` registers a new doc where the shape says; `docs-status` and `docs-audit-full` flag a
19
+ menu that has drifted; `init doctor` reads the shape, FAILs a doc the menu names that does not exist,
20
+ flags a living doc an all-menu misses, and holds every doc a curated menu names to the standard.
21
+ `pins/menu.test.mjs` holds both shapes.
22
+
23
+ ### Changed
24
+
25
+ - The map's Doc metadata row no longer asks whether the menu is kept by hand; the menu's shape line says
26
+ what the menu is.
27
+ - `docs-workflow.md` § The repository-owned sections no longer says which words this repository writes for
28
+ the loop's states; that is § Doc metadata's to say, so a repository that pastes the section verbatim no
29
+ longer inherits a line that is untrue for it.
30
+ - README: taking a new release is `claude plugin update`; the pins and the release path read as they are.
31
+
32
+ ## [0.4.0] - 2026-09-23
33
+
34
+ ### Changed
35
+
36
+ - **The two method documents state one way of running the loop, opinionated on purpose, and name the four
37
+ places a repository replaces with its own.** Each is a whole section whose heading ends
38
+ `(repository-owned)`: in `docs-workflow.md`, The archive convention, Doc metadata and Templates; in
39
+ `engineering-loop.md`, This repository's rails. One grep lists them and nothing else:
40
+ `rg -n '^#+ .*\(repository-owned\)' docs/_meta/`. The heading is the contract: a repository keeps it and
41
+ replaces the body in its `docs/_meta/` copy, in its own words. The loop's own preferences stay stated
42
+ concretely in the references: the `<!-- meta -->` header and its Obsidian interop, `## Lineage`, the
43
+ topic folders under `archive/{topic}/`, flat and split.
44
+ - `docs-workflow.md` gains § The repository-owned sections: what the skills read from each section, where
45
+ the two documents echo it in passing, the loop's four states (`draft`, `wip`, `current`, `shipped`) and
46
+ who writes each, what silence in a section means, how to replace one (filing a pipeline as one package
47
+ into a home the repository already has among the examples), and what the version stamp means.
48
+ - `engineering-loop.md` § This repository's rails is six items, each an absent-line until the repository
49
+ fills it: Policy, Gates a commit passes, Before a PR, Where a PR goes, Staging, Skills a seat meets here.
50
+ They add to the Hard rules and never subtract. The POLICY row of where-a-rule-lives points at the rails'
51
+ policy document, and in hosted mode at the control plane's suffix.
52
+ - **The skills name the section and the concept, never the value.** A header is written at the word for a
53
+ loop state, "the verified date" is wherever § Doc metadata keeps it, an effort files into "the archive
54
+ home" § The archive convention names, and the base branch and the PR route come from the rails. Every
55
+ skill that needs a format carries the same line near its top, "Find the format first", with the grep.
56
+ `docs-process` holds the filing procedure only; the shapes and the link repairs are the archive
57
+ convention's. `spec-review` and `spec-pipeline` diff against the rails' base branch; `spec-parent` and
58
+ `spec-retro` open the PR where and how the rails say.
59
+ - The templates keep the loop's own header; their init instruction drops the blockquote date where
60
+ § Doc metadata keeps none. `init` writes the Start-here stanza's and the folder READMEs' echo lines in the
61
+ copy's words when the copy has replaced the section they echo, and drafts § This repository's rails from
62
+ the scan.
63
+ - `init doctor` reads a doc's status from either header form unaided, the loop's meta line or a
64
+ frontmatter `status:` key, needing only the word `draft`; reads the version stamp after a leading
65
+ frontmatter block; and reports each repository-owned heading (unmarked or missing: DEGRADE) and each
66
+ rails item (missing, or still its absent-line: DEGRADE). It never grades the loop text or the content of
67
+ a repository-owned section.
68
+ - The marketplace entry sources the plugin from this repository (`./`) instead of the npm package at a
69
+ pinned version. `claude plugin install naswerks@engineering-loop` no longer depends on a registry that
70
+ can lag a tag; npm remains the runner lane (`npm i -g @naswerks/engineering-loop`). A pin keeps it so.
71
+ - The release workflow names the remedy when a publish is refused: the package has no trusted publisher
72
+ linked on npmjs.com for this repository and `release.yml`.
73
+
74
+ ### Added
75
+
76
+ - `init refresh` (`skills/init/scripts/refresh.mjs`): brings a repository's copies of the method documents
77
+ up to this pack by writing only their repository-owned sections and the stamp. A dry run by default, one
78
+ row per section (kept, heading marked, added, item added, stamp); `--write` applies exactly those rows. It
79
+ never touches the loop text, never deletes, never reorders, keeps every line's own ending, and a second
80
+ run writes nothing.
81
+ - `skills/init/scripts/owned.mjs`: the one list of repository-owned sections the doctor, refresh and the
82
+ pins share.
83
+ - Pins: a census that no skill spells the loop's own header or archive destination; the one-grep pin
84
+ (exactly four marked headings, equal to `owned.mjs`, no partial marker); section citations by exact
85
+ heading only; the loop states a skill names; the find-format line; `pins/preferences.test.mjs`, which
86
+ keeps the loop's own preferences in the references; `pins/refresh.test.mjs`.
87
+
88
+ ### Fixed
89
+
90
+ - `docs-audit-full` named `docs-write` as the skill that files a finished working doc; it is
91
+ `docs-process`.
92
+ - `spec-review` wrote its report at a status no loop state names; it writes the word for `shipped`.
93
+
94
+ ## [0.2.2] - 2026-09-21
95
+
96
+ ### Changed
97
+
98
+ - `spec-child`'s `mixed` row names where its reading list lives — the rows for those surfaces in
99
+ `docs/_meta/doc-index.md` § Role reading lists — so the default role is no longer the one role told to
100
+ read "the adds for the surfaces your spec touches" without a path to them.
101
+
8
102
  ## [0.2.1] - 2026-09-20
9
103
 
10
104
  ### Changed
package/README.md CHANGED
@@ -5,8 +5,9 @@ living documentation true, and an **execution loop** (`spec-*`) that turns an ap
5
5
  pipeline of agent sessions with a coordinator, build seats, a review seat and a retrospective. `init`
6
6
  makes a fresh repository ready for both.
7
7
 
8
- The package root is the plugin root: `.claude-plugin/` and `skills/` sit at the top, so one artifact serves
9
- a person's CLI, a hosted runner, and a repository's pin.
8
+ The package root is the plugin root: `.claude-plugin/` and `skills/` sit at the top, so the same tree serves
9
+ a person's CLI (through the marketplace, from this repository), a hosted runner (through npm), and a
10
+ repository's pin.
10
11
 
11
12
  ## Install
12
13
 
@@ -17,6 +18,11 @@ claude plugin marketplace add naswerks/engineering-loop
17
18
  claude plugin install naswerks@engineering-loop
18
19
  ```
19
20
 
21
+ The marketplace is this repository, and the plugin is sourced from it: no registry sits between you and a
22
+ release. Plugins load at session start, so start a new session (or run `/reload-plugins`) after installing.
23
+ To pick up a new release later: `claude plugin marketplace update engineering-loop`, then
24
+ `claude plugin update naswerks@engineering-loop` (an install over an existing install does nothing).
25
+
20
26
  Skills are namespaced by the plugin: `/naswerks:docs-write`, `/naswerks:spec-pipeline`, `/naswerks:init`.
21
27
 
22
28
  **On a runner** (sessions started through the Agent SDK load a plugin only from a local path):
@@ -32,6 +38,27 @@ then point the runner at `$(npm root -g)/@naswerks/engineering-loop` — with pe
32
38
  structure the skills read, the two method documents, a `CLAUDE.md` pointer and the plugin pin in
33
39
  `.claude/settings.json`. A team member still installs the plugin once per machine; the pin enables it.
34
40
 
41
+ **In a repository that already has a docs convention** (frontmatter on every file, a pre-commit
42
+ validator, an indexer): the two method documents state one way of running the loop, opinionated on
43
+ purpose, and mark the four sections that are yours to replace — the header every doc carries, where a
44
+ finished effort is filed, the templates' header lines, the rails a commit passes. Keep each heading and
45
+ rewrite its body in your `docs/_meta/` copies, in your own words; `docs-workflow.md` § The repository-owned
46
+ sections lists what each must answer. One grep lists the four:
47
+
48
+ ```
49
+ rg -n '^#+ .*\(repository-owned\)' docs/_meta/
50
+ ```
51
+
52
+ If the repository already keeps an index of every doc, declare the loop's menu curated — put
53
+ `<!-- naswerks-loop: menu=curated; index=docs/INDEX.md -->` (your index's path) in `docs/_meta/doc-index.md`
54
+ — and the menu lists only the docs your seats read, each held to the loop's standard; every other doc stays
55
+ in your own index. A repository with no index of its own keeps the default, a menu of every living doc.
56
+
57
+ Every skill names the section it needs and never states the format itself, so the pack stays generic and
58
+ your conventions live in your repository. **Taking a newer pack:** `/naswerks:init refresh` writes only
59
+ those four sections and the version stamp into your copies — a dry run first, then `--write` on your word —
60
+ and never touches the rest of the text.
61
+
35
62
  ## What is in the box
36
63
 
37
64
  | Skill | Loop | One line |
@@ -49,9 +76,10 @@ structure the skills read, the two method documents, a `CLAUDE.md` pointer and t
49
76
  | `spec-retro` | spec | the coordinator's close-out audit |
50
77
  | `spec-witness` | spec | a read-only verifier |
51
78
  | `spec-ignite` | spec | the ignition copilot for a hosted run |
52
- | `init` | — | make a repository ready for both loops |
79
+ | `init` | — | make a repository ready for both loops; `init doctor` checks one, `init refresh` takes a newer pack's repository-owned sections |
53
80
 
54
- `references/` carries the two method documents a repository copies into `docs/_meta/`;
81
+ `references/` carries the two method documents a repository copies into `docs/_meta/` and then
82
+ rewrites where they say (repository-owned);
55
83
  `bin/verify-staged` is the staging receipt the seats run between `git add` and `git commit`. A
56
84
  marketplace install puts nothing on PATH: `npm i -g @naswerks/engineering-loop` does, and the skills
57
85
  carry the fallback `node <pack root>/bin/verify-staged.mjs`.
@@ -62,16 +90,26 @@ or the child may resolve `docs/` paths against the parent session's workspace.
62
90
 
63
91
  ## Does it work
64
92
 
65
- `npm test` runs the pins: one version across the package, the plugin manifest and the marketplace
66
- entry; every skill directory carries a `SKILL.md` named for its folder; no byte-order marks; the
67
- method documents carry the version stamp; the vocabulary censuses. `node bin/verify-staged.mjs
68
- --self-test` drives the receipt against a throwaway repository and reports each case.
93
+ `npm test` runs the pins: one version across the package, the plugin manifest, the marketplace entry and
94
+ both method documents' stamps; every skill directory carries a `SKILL.md` named for its folder; no
95
+ byte-order marks; the vocabulary and content censuses; no skill states a format a repository owns, and
96
+ every skill that needs one carries the same find-format line; exactly four repository-owned sections, found
97
+ by the one grep; the loop's own preferences stay stated in the method documents; the menu's two shapes; `init refresh` leaves
98
+ every line outside those sections byte for byte. `node bin/verify-staged.mjs --self-test` drives the
99
+ receipt against a throwaway repository and reports each case.
69
100
 
70
101
  ## Releasing
71
102
 
72
- The version lives in `package.json` and `.claude-plugin/plugin.json` (they must agree). A `v*` tag
73
- runs the pins and publishes to npm through trusted publishing; the GitHub release notes are the
74
- CHANGELOG section for that version.
103
+ The version lives in `package.json`, `.claude-plugin/plugin.json` and `.claude-plugin/marketplace.json`
104
+ (they must agree), in both method documents' stamps, and in a CHANGELOG section. The marketplace serves
105
+ the plugin from this repository at whatever `main` holds, so a CLI install never waits on npm; npm is the
106
+ runner lane.
107
+
108
+ To release: push the release commit to `main`, publish it to npm from the repository root (`npm login`,
109
+ then `npm publish --access public`), then push its `v*` tag. The tag's workflow runs the pins, finds the
110
+ version already on the registry and skips its own publish, and creates the GitHub release from the
111
+ CHANGELOG section. With a trusted publisher linked on npmjs.com for this repository and `release.yml`,
112
+ pushing the tag alone publishes; the workflow prints that remedy when a publish is refused.
75
113
 
76
114
  ## License
77
115
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naswerks/engineering-loop",
3
- "version": "0.2.1",
3
+ "version": "0.5.0",
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.2.1 -->
1
+ <!-- naswerks-loop: version=0.5.0 -->
2
2
  # Docs Workflow
3
3
 
4
4
  > How knowledge flows through `docs/`: the loop, the folder rules, the templates, and the `docs-*` skills.
@@ -40,10 +40,10 @@ narrative. That's also why it's a separate session, not the tail of the implemen
40
40
 
41
41
  | Folder | What it holds | Lifecycle |
42
42
  |--------|---------------|-----------|
43
- | `_meta/` | This system — `doc-index` (the menu) + `docs-workflow` (this file) | Maintained as the system evolves |
43
+ | `_meta/` | This system — `doc-index` (the menu) + `docs-workflow` (this file) + `engineering-loop` (the seats and the ceremony) | Maintained as the system evolves; the sections marked **(repository-owned)** are rewritten by each repository to its own conventions |
44
44
  | `research/` | The running tab of ideas to do, not yet built. The folder is the queue. | Created by `docs-backlog`; stays through the build, then **archived with its working doc(s)** by `docs-process` |
45
45
  | `working/` | Active + finished-but-unprocessed session docs (one effort may chain several). The folder is the queue. | **Leaves via `docs-process`** — research + the whole chain archived together once the living docs are patched |
46
- | `archive/` | Completed/abandoned session docs, grouped into **topic** folders | Write-once. Frozen history — never edit archived docs |
46
+ | `archive/` | Completed/abandoned session docs, grouped into **topic** folders (or the home "The archive convention" below names for them) | Write-once. Frozen history — never edit archived docs |
47
47
  | `guides/` | How to ADD a new thing — step-by-step walkthroughs | Living — patched by `docs-process` |
48
48
  | `patterns/` | Conventions to FOLLOW when writing code | Living — patched by `docs-process` |
49
49
  | `infrastructure/` | What runs under the hood (technologies/plumbing) | Living — patched by `docs-process` |
@@ -62,7 +62,105 @@ is usually a code problem to flag, not a doc to rewrite (unless the rule itself
62
62
 
63
63
  ---
64
64
 
65
- ## The archive convention
65
+ ## The repository-owned sections
66
+
67
+ This file and [engineering-loop](engineering-loop.md) state one way of running the loop, and they are
68
+ opinionated on purpose. Where a repository's conventions differ, they differ in four places only — the
69
+ sections whose heading ends **(repository-owned)**. Each one declares this repository's preference for one
70
+ thing; another repository **keeps the heading and replaces the body** in its `docs/_meta/` copy, in its own
71
+ words. Every other section is the loop and reads the same everywhere. One grep lists the four, with their
72
+ line numbers; each runs to the next `## ` heading:
73
+
74
+ ```
75
+ rg -n '^#+ .*\(repository-owned\)' docs/_meta/
76
+ ```
77
+
78
+ **The skills read these sections and never restate them.** A skill names the section and the thing it
79
+ needs from it — *the header § Doc metadata prescribes*, *the archive home § The archive convention names*,
80
+ *the base branch § This repository's rails names* — and takes the value from this repository's copy. What
81
+ each section answers, and where the two method docs echo the preference in passing (the lines a repository
82
+ that replaces the section rewrites alongside it):
83
+
84
+ | Section | What the skills read from it | Also echoed in |
85
+ |---------|------------------------------|----------------|
86
+ | **The archive convention** (this file) | the archive home for each kind of effort (hand-cranked, spec pipeline, follow-on round) and for audit reports · the shape inside it · what a working doc's `## Archive` line says, and whether an umbrella carries an `Archive:` line · the links a move repairs · what is frozen once filed | The Loop (the diagram and its prose) · Folders (`research/`, `working/`, `archive/`) · "Living docs vs session docs" · the skills table (`docs-process`) · Conventions (incident receipts, archived docs) · `engineering-loop.md` "The loop at a glance" |
87
+ | **Doc metadata** (this file) | the header — its form and its place · the sweep: one command, one line per doc · the word for each loop state (below) · where the verified date lives, and the rule that moves it · whether `## Lineage` stays · the gates a doc passes, and the folders they exempt | the skills table (`docs-status`) · Conventions (the machine layer; dates in the header) · `engineering-loop.md`'s own header line and its `## Lineage` |
88
+ | **Templates** (this file) | each template's header lines, at the state its writer names | — |
89
+ | **This repository's rails** (`engineering-loop.md`) | the policy document, and how a seat reaches it · the gates a commit passes · the suite before a PR · the base branch, the PR target, the branch names and how a PR is opened · the staging rule · the repository's own skills a seat meets | the POLICY row of "Where a rule lives" · the Hard rules, which the rails add to and never subtract from |
90
+
91
+ **The loop's states.** The skills speak in four states, and § Doc metadata says which word this repository
92
+ writes for each.
93
+
94
+ | State | Written by | Means |
95
+ |-------|------------|-------|
96
+ | `draft` | `init`, `spec-pipeline`, `docs-backlog` | scanned or authored, not yet decided or verified |
97
+ | `wip` | `docs-write` mid-effort, the pipeline's tracker | in progress |
98
+ | `current` | `docs-process` for a doc it creates, `docs-audit-feature` | describes the code as it is |
99
+ | `shipped` | `docs-write` for an effort's last session, `spec-review`'s report | finished — frozen once filed |
100
+
101
+ *Stale* is a date, not a state: `docs-status` computes it from the verified date, and no seat writes it.
102
+
103
+ **The menu.** `doc-index.md` is the menu the seats read, and the whole file is the repository's: `init` writes
104
+ it once and never again. A line near its top says which of two shapes it has, and one grep reads it:
105
+ `rg -n 'naswerks-loop: menu=' docs/_meta/doc-index.md`.
106
+
107
+ | Shape line | The menu lists | A new living doc goes |
108
+ |------------|----------------|-----------------------|
109
+ | `<!-- naswerks-loop: menu=all -->` | every living doc — the repository has no other index | onto the menu |
110
+ | `<!-- naswerks-loop: menu=curated; index={path} -->` | the docs this repository's seats read; `{path}` indexes every doc | into `{path}`, the way that index is kept, and onto the menu only when it meets the loop's standard and a seat should read it |
111
+
112
+ **The loop's standard for a doc on a curated menu:** it exists, it carries the header § Doc metadata
113
+ prescribes at a decided status (not the word for `draft`), and it has a `## Key Files` section. `init doctor`
114
+ checks exactly that, for every doc a curated menu names.
115
+
116
+ **Silence.** A section that says nothing about an item leaves the loop's default: a menu with no shape line
117
+ lists every living doc (`menu=all`), no gate runs on a commit, the base branch is the remote's
118
+ default (`git symbolic-ref refs/remotes/origin/HEAD`), and a seat with no PR route asks the human once and
119
+ suggests recording the answer in the rails. Any other unanswered item is a question for the human, never a
120
+ guess.
121
+
122
+ ### Replacing a section
123
+
124
+ Keep what the skills need to find, change the words to yours:
125
+ - **The header and how to sweep it.** Name the fields (a status, a verified date, a type) and where they
126
+ live, and give the one command `docs-status` runs to list every doc's status in one line each. For the
127
+ loop's own header that command is `rg -o '<!-- meta:.*-->' docs/`; for a frontmatter convention it is a
128
+ grep over the keys.
129
+ - **The status words.** Say which word of yours a seat writes for each loop state above, in one line — *"a
130
+ seat that would write `current` or `shipped` writes `stable`; `wip` and `draft` are `draft`"*. `draft` is
131
+ the one word `init doctor` looks for, in either header form.
132
+ - **What the verified date means.** It moves only when a doc is checked against code in that run, whatever
133
+ it is called; state the rule in your words so the anti-fabrication rule survives the rename.
134
+ - **Whether `## Lineage` stays.** It is the footer that carries Idea, Spec, Built and Related; a repository
135
+ whose own tooling derives that graph may drop it and say so.
136
+ - **Your gates.** Name the validator or index a commit must pass, and which of the loop's folders it
137
+ exempts. The loop's session folders (`research/`, `working/`, `archive/`) hold breadcrumbs, not living
138
+ docs, and are the usual exemption.
139
+ - **Your archive home.** A repository whose living docs already have a home for an effort's history (a
140
+ feature's own folder, say) may file a spec pipeline **as one package** into that home: nothing is
141
+ re-sorted, every file keeps its name and its place, `sessions/` rides along untouched, and the effort's
142
+ working docs join the package under `implementation/`, with the tracker still the "read me first" at its
143
+ root. When where a pipeline files depends on something only its authoring session knows, say so —
144
+ `spec-pipeline` then records the resolved path in the umbrella's blockquote as an `Archive:` line.
145
+ - **Your rails.** Fill each item of `engineering-loop.md` § This repository's rails from what the
146
+ repository already wrote down — a policy document, hooks, CI, a pull-request template.
147
+ - **Your menu.** A repository that already indexes its docs declares its menu curated and names that index:
148
+ the menu then lists only the docs its seats read, each meeting the loop's standard, and every other doc
149
+ stays in the repository's own index, kept the way it already is.
150
+
151
+ **The version stamp** on line 1 names the pack version whose repository-owned sections this copy carries.
152
+ The loop text around them is this repository's copy from whenever it was taken: `init doctor` never grades
153
+ it, and `init refresh` never touches it — refresh adds a section or a rails item a newer pack reads, and
154
+ restamps.
155
+
156
+ ---
157
+
158
+ ## The archive convention (repository-owned)
159
+
160
+ > **Repository-owned.** This section says where a finished effort is filed and in what shape. A
161
+ > repository whose living docs already have a home for an effort's history rewrites it in its
162
+ > `docs/_meta/` copy; every skill that files a doc reads this copy, never its own text.
163
+ > [The repository-owned sections](#the-repository-owned-sections) lists what it must answer.
66
164
 
67
165
  A multi-session effort becomes a **topic folder** under `archive/` (e.g. `archive/{topic}/`).
68
166
  Docs are **not numbered** — they use descriptive names and chain via a header link:
@@ -113,8 +211,7 @@ one** (via `spec-pipeline`). The trigger for the layout is simply *"does this ef
113
211
  record, not the convention.
114
212
  ```
115
213
 
116
- **Follow-on pipelines (multi-round families).** *(Renamed at the v2 cutover — this section was
117
- `Follow-on chains`; skills citing the old heading mean this one.)* A second (third, …) spec pipeline that continues an
214
+ **Follow-on pipelines (multi-round families).** A second (third, …) spec pipeline that continues an
118
215
  already-archived effort gets its **own sibling topic folder**, never filed inside the frozen one.
119
216
  Rules: (a) name the new topic `{family-prefix}-{subtopic}` so the family groups
120
217
  alphabetically; (b) each folder keeps the full split shape (own `project-status.md` at root); (c) the
@@ -137,7 +234,14 @@ report sits beside the docs it audits. The cross-cutting `health-report-{date}.m
137
234
 
138
235
  ---
139
236
 
140
- ## Doc metadata (header + lineage)
237
+ ## Doc metadata (repository-owned)
238
+
239
+ > **Repository-owned.** This section prescribes the machine header every doc the loop writes carries.
240
+ > What follows is the loop's own header. A repository whose docs already carry a metadata convention
241
+ > (YAML frontmatter with its own keys and status words, a validator, an indexer) rewrites this section
242
+ > and the templates below in its `docs/_meta/` copy to say that convention, in one voice; every skill
243
+ > that writes a doc takes the header from this copy. [The repository-owned sections](#the-repository-owned-sections)
244
+ > lists what it must answer.
141
245
 
142
246
  Two additive machine layers wrap a doc's unchanged human content: an invisible **header meta-comment**
143
247
  (greppable status/identity) and a visible **`## Lineage` footer** (the clickable provenance breadcrumb).
@@ -219,7 +323,10 @@ Obsidian; don't imitate it.
219
323
 
220
324
  ---
221
325
 
222
- ## Templates
326
+ ## Templates (repository-owned)
327
+
328
+ > **Repository-owned.** A repository that rewrote "Doc metadata" rewrites each template's header lines
329
+ > here to match; the sections beneath them are the loop's and stay.
223
330
 
224
331
  ### Session / working doc (created during a session, archived by `docs-write`)
225
332
 
@@ -355,7 +462,9 @@ spec set *is* the design history.
355
462
  **`spec-*` = the execution loop** (how big work gets built: graduate a plan, a coordinator seat,
356
463
  build seats). They hand off at both ends: research docs feed `spec-pipeline`; every build session
357
464
  closes with `docs-write`; `docs-process` compiles the results back into living docs. A seat prompt
358
- never restates a rule a skill holds — the prompt points, the skill holds it.
465
+ never restates a rule a skill holds — the prompt points, the skill holds it. And a skill never restates
466
+ what this file's repository-owned sections hold: the header a doc carries and where an effort is filed
467
+ come from this copy, so a repository changes them once, here.
359
468
 
360
469
  | Skill | When | What it does |
361
470
  |-------|------|-------------|
@@ -411,7 +520,7 @@ never restates a rule a skill holds — the prompt points, the skill holds it.
411
520
  the actual source. For prescriptive docs (`patterns/`, `guides/`) the doc is the decided rule — check
412
521
  that code conforms to it instead (see "Two kinds of living doc" above).
413
522
  - **Every living / spec / working doc carries the machine layer** — a one-line `<!-- meta: … -->` header
414
- below the blockquote + a `## Lineage` footer (see "Doc metadata (header + lineage)" above). The meta
523
+ below the blockquote + a `## Lineage` footer (see "Doc metadata (repository-owned)" above). The meta
415
524
  `verified` date moves with the blockquote's `Last verified` and obeys the same anti-fabrication rule:
416
525
  only stamp it for a doc actually checked against code this run.
417
526
  - **Don't edit archived docs** — stale references there are historical record.
@@ -1,4 +1,4 @@
1
- <!-- naswerks-loop: version=0.2.1 -->
1
+ <!-- naswerks-loop: version=0.5.0 -->
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-*`
@@ -77,6 +77,31 @@ effort wants a review row and a docs-process row, and writes them into the row t
77
77
  learns the shape by reading its own sequence, and nothing needs a toggle. A pipeline can be plain,
78
78
  `+review`, `+review +process`, or `+process`.
79
79
 
80
+ **Sections marked (repository-owned), here and in `docs-workflow.md`, are this repository's.** They say
81
+ how a doc's header is written, where a finished effort is filed, and which rails a commit passes here.
82
+ Every other section is the loop and reads the same in every repository. The coordinator and every seat
83
+ read both documents at Step 0, so a repository's conventions reach them without a line in any prompt,
84
+ and a skill that writes or files a doc takes those two facts from `docs-workflow.md`, never from its
85
+ own text. One grep lists every such section — `rg -n '^#+ .*\(repository-owned\)' docs/_meta/` — and
86
+ `docs-workflow.md` § The repository-owned sections lists what each answers and where it is echoed.
87
+
88
+ ## This repository's rails (repository-owned)
89
+
90
+ What a commit and a PR pass here, beyond the loop. These add to the Hard rules below; they never subtract.
91
+
92
+ - **Policy.** No policy document recorded — fill this in: the document every seat is bound by, and how a
93
+ seat reaches it.
94
+ - **Gates a commit passes.** No commit gates recorded — fill this in: the hooks and checks a commit must
95
+ pass, and what each validates.
96
+ - **Before a PR.** No pre-PR suite recorded — fill this in: the suite that runs before a PR, and where its
97
+ commands live.
98
+ - **Where a PR goes.** No PR route recorded — fill this in: the base branch, the host, the branch names,
99
+ and how a PR is opened.
100
+ - **Staging.** No staging rule recorded — fill this in: anything stricter than the Hard rules' explicit
101
+ paths and `verify-staged`.
102
+ - **Skills a seat meets here.** No repository skills recorded — fill this in: the repository's own skills
103
+ a seat invokes by name, and when.
104
+
80
105
  ## Two loops — both hand-crankable
81
106
 
82
107
  - **`docs-*` is the knowledge loop** and runs standalone, forever: small/everyday efforts are
@@ -128,7 +153,7 @@ The thing that keeps prompts and skills from drifting apart:
128
153
 
129
154
  | Kind | Home | Why there |
130
155
  |---|---|---|
131
- | **POLICY** | the un-skippable system-prompt suffix the control plane supplies at open | cannot be skipped, present on every turn |
156
+ | **POLICY** | the policy document § This repository's rails names — and, hosted, the un-skippable system-prompt suffix the control plane supplies at open | cannot be skipped, present on every turn |
132
157
  | **PROCEDURE — shared** | `spec-seat` | the contract for ANY seat the coordinator arms: blackboard, question lane, parked-call discriminator, verdicts, BELIEFS sha, git shapes, six-section FINAL TLDR, close-out order |
133
158
  | **PROCEDURE — per job** | `spec-child` · `spec-review` · `docs-process` | what THIS seat does. The job skill **refines** the seat contract and never contradicts it; a genuine conflict is a finding, not a fork |
134
159
  | **TASK** | the seed prompt + the pipeline's `00-ignition-brief.md` | per-run; dies with the run |
@@ -10,6 +10,8 @@ docs, or a whole folder — in `docs/features/`, `docs/infrastructure/`, or `doc
10
10
  the one audit skill for "does this doc still match the code"; it produces both the **audit report**
11
11
  and the **corrected living doc**.
12
12
 
13
+ **Find the format first.** This repository writes its formats (the doc header and status words, where an effort is filed, its rails) in the sections `rg -n '^#+ .*\(repository-owned\)' docs/_meta/` lists; read the one a step names before that step writes. This skill names the section, never the format.
14
+
13
15
  > **The system:** `docs/_meta/doc-index.md` (the menu of living docs) + `docs/_meta/docs-workflow.md`
14
16
  > (the loop, folders, templates) explain how the docs are organized. Skim them if you need to place a
15
17
  > doc or find its siblings.
@@ -30,28 +32,29 @@ writes across docs. End with a one-line-per-doc summary (stale-count / added-cou
30
32
  1. **Read the living doc** (`docs/features/{x}.md`, `docs/infrastructure/{x}.md`, or
31
33
  `docs/patterns/{x}.md`).
32
34
 
33
- 2. **Read the corresponding code** — the backend `Features/{Feature}/` slice and matching frontend
34
- feature folder for feature docs; the relevant subsystem for infrastructure/pattern docs. Confirm
35
- entities, endpoints, stores, routes, services, config, key files.
35
+ 2. **Read the corresponding code** — the feature's code on each side, wherever
36
+ `docs/patterns/code-organization.md` says a feature lives, for feature docs; the relevant subsystem for
37
+ infrastructure/pattern docs. Confirm entities, endpoints, stores, routes, services, config, key files.
36
38
 
37
39
  3. **Check against conventions** — cross-check the doc's claims against `docs/patterns/` (and
38
40
  `docs/infrastructure/` where relevant) so the doc matches how things are actually built.
39
41
 
40
- 4. **Report findings** — write a short audit report to `docs/archive/audit/{group}/{doc-name}-audit.md`,
41
- where `{group}` mirrors the living doc's folder (`guides/`, `patterns/`, `infrastructure/`, or
42
- `features/`; create the subfolder if absent). Date in header: what was accurate, what was stale,
42
+ 4. **Report findings** — write a short audit report where `docs/_meta/docs-workflow.md` § The archive
43
+ convention (repository-owned) files audit reports, named for the doc it audits and grouped the way that
44
+ section groups them (create the folder if absent). Date in header: what was accurate, what was stale,
43
45
  what's undocumented, and any **code risks / bugs / tech-debt** you noticed against the source.
44
- (The master `health-report-*.md` from `docs-audit-full` stays at the `audit/` root — it's cross-cutting.)
45
-
46
- 5. **Update the living doc** with the corrections and bump its "Last verified" date — **and refresh the
47
- `<!-- meta: … -->` line in lockstep** (`verified` = today, update `status`, recompute `lineage=N`). This is
48
- allowed here only because you just did the full doc-vs-code pass; the meta `verified` obeys the same
49
- anti-fabrication rule as the blockquote date (the two always move together). **Verify the `## Lineage`
50
- footer** — check every link resolves; flag any dead breadcrumb into `## Open Issues` (or the audit report)
51
- and recompute `lineage=N` to match. **Soft-check `Spec` / `Built` symmetry** — for a spec-driven feature, a
46
+ (The master health report from `docs-audit-full` sits where that section puts it — it's cross-cutting.)
47
+
48
+ 5. **Update the living doc** with the corrections and set its verified date to today — **every place
49
+ `docs/_meta/docs-workflow.md` § Doc metadata (repository-owned) keeps that date moves in lockstep**, along
50
+ with its status and any field the header derives. This is allowed here only because you just did the full
51
+ doc-vs-code pass; the verified date obeys the anti-fabrication rule below. **Verify the `## Lineage`
52
+ footer** (where that section keeps it) — check every link resolves; flag any dead breadcrumb into
53
+ `## Open Issues` (or the audit report) and recompute any field the header derives from it. **Soft-check
54
+ `Spec` / `Built` symmetry** — for a spec-driven feature, a
52
55
  `Built` session whose per-slice spec is absent from `Spec` (or vice-versa) is usually an under-scoped row;
53
56
  note it and complete it *unless* the doc is deliberately scoped tighter than the effort (judgment, not a hard
54
- fail — see the Lineage rules in `docs-workflow.md`). **Reconcile its `## Open Issues` section** — add any real, code-verified
57
+ fail — the `## Lineage` rules § Doc metadata (repository-owned) gives). **Reconcile its `## Open Issues` section** — add any real, code-verified
55
58
  risk/bug/tech-debt you found (dated, with `file:line`), and remove any listed issue the code now resolves.
56
59
  (The archived report is the history; `## Open Issues` is the live signal `docs-status` reads.)
57
60
 
@@ -65,8 +68,8 @@ is missed:
65
68
  - **Both exist**: run the per-doc audit above.
66
69
 
67
70
  For `docs/features/`, the folder (one doc per feature) IS the inventory — there is no separate
68
- catalog. Build the real list from `Features/` + the frontend feature folders/routes via actual
69
- `ls`/`find` output in this run, then diff.
71
+ catalog. Build the real list from where `docs/patterns/code-organization.md` says features live — each
72
+ side, routes included — via actual `ls`/`find` output in this run, then diff.
70
73
 
71
74
  ## Anti-fabrication rule
72
75
 
@@ -76,10 +79,11 @@ catalog. Build the real list from `Features/` + the frontend feature folders/rou
76
79
  - **Every claim traces to a file you opened in this run** — entity names, endpoints, routes, key
77
80
  files, line references. No identifiers or dates from memory. When listing a folder, build the
78
81
  feature/doc lists from real `ls`/`find` output, not memory.
79
- - Only stamp **"Last verified: <today>"** on a doc you actually checked against code in this run.
82
+ - Only stamp **the verified date** (today) on a doc you actually checked against code in this run.
80
83
  Stamping a date you didn't verify is the exact failure this rule exists to prevent.
81
- - The `<!-- meta: verified=… -->` date is bound by the **same** rule and always equals the blockquote's
82
- `Last verified` — refresh `verified` / `status` / `lineage=N` only after the full doc-vs-code pass this run.
84
+ - Every place § Doc metadata (repository-owned) keeps that date, whatever it calls it, is bound by the
85
+ **same** rule and moves together — refresh it, the status and any derived field only after the full
86
+ doc-vs-code pass this run.
83
87
 
84
88
  ## Notes
85
89
  - **Descriptive docs (`infrastructure/`, `features/`):** code is truth — where doc and code disagree,
@@ -8,13 +8,20 @@ description: Master health check across all docs — staleness/age scan, convent
8
8
  A deep-clean sweep. Does NOT re-audit every feature in depth — it produces the prioritized plan of
9
9
  what to audit next.
10
10
 
11
+ **Find the format first.** This repository writes its formats (the doc header and status words, where an effort is filed, its rails) in the sections `rg -n '^#+ .*\(repository-owned\)' docs/_meta/` lists; read the one a step names before that step writes. This skill names the section, never the format.
12
+
11
13
  ## Steps
12
14
 
13
- 1. **Freshness scan** — read "Last verified" dates across all living docs (`guides/ patterns/
14
- infrastructure/ features/`). Flag anything older than ~14 days; sort oldest-first.
15
+ 1. **Freshness scan** — read the verified dates across all living docs (`guides/ patterns/
16
+ infrastructure/ features/`), wherever `docs/_meta/docs-workflow.md` § Doc metadata (repository-owned)
17
+ says that date lives (its sweep command reads them all at once). Flag anything older than ~14 days; sort
18
+ oldest-first.
15
19
 
16
20
  2. **Feature completeness** — quick `docs/features/` folder pass (per `docs-audit-feature`'s
17
- folder mode): any features in code with no doc, or docs whose feature is gone.
21
+ folder mode): any features in code with no doc, or docs whose feature is gone. Then the menu against its
22
+ shape line (`rg -n 'naswerks-loop: menu=' docs/_meta/doc-index.md`; none means `menu=all`): on
23
+ `menu=all`, living docs it does not name; on `menu=curated`, docs it names that fall short of the loop's
24
+ standard (`docs/_meta/docs-workflow.md` § The repository-owned sections).
18
25
 
19
26
  3. **Convention spot-check** — sample 2-3 source files per major convention against the
20
27
  `docs/patterns/` docs; note drift.
@@ -23,14 +30,15 @@ what to audit next.
23
30
  graduated/removed) and ideas worth surfacing.
24
31
 
25
32
  5. **Working/archive sanity** — note any docs lingering in `docs/working/` that look done (should be
26
- filed via `docs-write`), and confirm `archive/` topic folders are intact.
33
+ filed via `docs-process`), and confirm the filed efforts are intact where § The archive convention
34
+ (repository-owned) puts them.
27
35
 
28
- 6. **Read the previous report first.** Before writing anything, find the most recent
29
- `docs/archive/audit/health-report-*.md` and read it in full. The new report continues from it:
30
- note what was flagged last time and is now fixed, what's still outstanding, and anything that
31
- regressed. If there is **no** prior report, say so — this run is the baseline.
36
+ 6. **Read the previous report first.** Before writing anything, find the most recent health report —
37
+ where § The archive convention (repository-owned) files audit reports — and read it in full. The new
38
+ report continues from it: note what was flagged last time and is now fixed, what's still outstanding,
39
+ and anything that regressed. If there is **no** prior report, say so — this run is the baseline.
32
40
 
33
- 7. **Produce a health report** at `docs/archive/audit/health-report-{date}.md` with a prioritized,
41
+ 7. **Produce a health report** — `health-report-{date}.md`, beside the previous one — with a prioritized,
34
42
  actionable list (which `docs-audit-feature` runs, which docs to re-verify, which research to clear).
35
43
  Open with a **"Since last report"** section that diffs against the report from step 6 (or marks this
36
44
  as the baseline if none existed).
@@ -7,6 +7,8 @@ description: Capture an idea, improvement, or future-state design as a research
7
7
 
8
8
  Capture ideas as research docs. `docs/research/` is the idea inbox — the folder itself is the queue.
9
9
 
10
+ **Find the format first.** This repository writes its formats (the doc header and status words, where an effort is filed, its rails) in the sections `rg -n '^#+ .*\(repository-owned\)' docs/_meta/` lists; read the one a step names before that step writes. This skill names the section, never the format.
11
+
10
12
  ## Steps
11
13
 
12
14
  1. **Scan existing research titles** in `docs/research/` — quick check for an obvious duplicate or a
@@ -14,7 +16,8 @@ Capture ideas as research docs. `docs/research/` is the idea inbox — the folde
14
16
 
15
17
  2. **For each idea, create a research doc** at `docs/research/{topic}.md` using the research-doc
16
18
  template in `docs/_meta/docs-workflow.md`: Current State, Desired End State, Design Options /
17
- Recommendation, Open Questions. Capture the idea while it's fresh — verify "Current State" against
19
+ Recommendation, Open Questions. Its header is the one that file's § Doc metadata (repository-owned)
20
+ prescribes, at the word for `draft`. Capture the idea while it's fresh — verify "Current State" against
18
21
  code if quick, otherwise note it's unverified.
19
22
 
20
23
  **The research doc must be self-contained.** It's the durable jump-off point; assume everything else
@@ -37,5 +40,5 @@ Capture ideas as research docs. `docs/research/` is the idea inbox — the folde
37
40
  - When an idea is later picked up and built, link it via the session doc's **Source** field. The
38
41
  research doc **stays in `research/` through the build** (it's the running tab, and a build may span
39
42
  several sessions / working docs). When the effort finishes, `docs-process` archives the research doc
40
- **alongside its working doc(s)** in the same `archive/{topic}/` folder — research and the work that
41
- delivered it are filed together, not deleted.
43
+ **alongside its working doc(s)** in the same archive home (`docs-workflow.md` § The archive convention
44
+ (repository-owned)) — research and the work that delivered it are filed together, not deleted.