projectstore-claude 0.29.1 → 0.29.3

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 (57) hide show
  1. package/README.md +2 -1
  2. package/node_modules/projectstore/.claude-plugin/marketplace.json +1 -1
  3. package/node_modules/projectstore/.claude-plugin/plugin.json +2 -1
  4. package/node_modules/projectstore/README.md +37 -9
  5. package/node_modules/projectstore/commands/bar.md +30 -0
  6. package/node_modules/projectstore/commands/bind.md +14 -7
  7. package/node_modules/projectstore/commands/scaffold.md +24 -16
  8. package/node_modules/projectstore/commands/status.md +1 -1
  9. package/node_modules/projectstore/commands/statusline.md +1 -1
  10. package/node_modules/projectstore/docs/alongside.md +167 -0
  11. package/node_modules/projectstore/docs/extending.md +17 -3
  12. package/node_modules/projectstore/docs/getting-started.md +18 -9
  13. package/node_modules/projectstore/docs/harnesses.md +1 -1
  14. package/node_modules/projectstore/docs/how-it-works.md +7 -0
  15. package/node_modules/projectstore/harnesses/claude-code.json +18 -3
  16. package/node_modules/projectstore/harnesses/codex.json +12 -1
  17. package/node_modules/projectstore/hooks/band-state.d.ts +44 -0
  18. package/node_modules/projectstore/hooks/band.tsx +594 -0
  19. package/node_modules/projectstore/hooks/hooks.json +1 -0
  20. package/node_modules/projectstore/hooks/session-start.mjs +6 -2
  21. package/node_modules/projectstore/package.json +2 -1
  22. package/node_modules/projectstore/scaffold/headings.json +8 -0
  23. package/node_modules/projectstore/scripts/band-shared.mjs +329 -0
  24. package/node_modules/projectstore/scripts/band.mjs +156 -0
  25. package/node_modules/projectstore/scripts/binding.mjs +157 -17
  26. package/node_modules/projectstore/scripts/build-adapters.mjs +26 -7
  27. package/node_modules/projectstore/scripts/cli.mjs +549 -180
  28. package/node_modules/projectstore/scripts/convergence.mjs +468 -0
  29. package/node_modules/projectstore/scripts/doctor-report.mjs +185 -0
  30. package/node_modules/projectstore/scripts/doctor.mjs +80 -62
  31. package/node_modules/projectstore/scripts/fetch-shell.mjs +283 -0
  32. package/node_modules/projectstore/scripts/harness.mjs +178 -7
  33. package/node_modules/projectstore/scripts/install-harness.mjs +1571 -257
  34. package/node_modules/projectstore/scripts/kanban.mjs +4 -20
  35. package/node_modules/projectstore/scripts/lib.mjs +269 -58
  36. package/node_modules/projectstore/scripts/portable-registration.mjs +68 -16
  37. package/node_modules/projectstore/scripts/query.mjs +83 -12
  38. package/node_modules/projectstore/scripts/run-host.mjs +94 -0
  39. package/node_modules/projectstore/scripts/scaffold.mjs +183 -0
  40. package/node_modules/projectstore/scripts/stages.mjs +80 -0
  41. package/node_modules/projectstore/scripts/statusline.mjs +25 -2
  42. package/node_modules/projectstore/scripts/surfaces.mjs +78 -13
  43. package/node_modules/projectstore/scripts/term.mjs +729 -39
  44. package/node_modules/projectstore/scripts/version-guard.mjs +5 -0
  45. package/node_modules/projectstore/templates/de/strings.json +63 -1
  46. package/node_modules/projectstore/templates/de/vault-readme.md.tmpl +13 -0
  47. package/node_modules/projectstore/templates/en/strings.json +63 -1
  48. package/node_modules/projectstore/templates/en/vault-readme.md.tmpl +13 -0
  49. package/node_modules/projectstore/templates/es/strings.json +63 -1
  50. package/node_modules/projectstore/templates/es/vault-readme.md.tmpl +13 -0
  51. package/node_modules/projectstore/templates/fr/strings.json +63 -1
  52. package/node_modules/projectstore/templates/fr/vault-readme.md.tmpl +13 -0
  53. package/node_modules/projectstore/templates/ru/strings.json +63 -1
  54. package/node_modules/projectstore/templates/ru/vault-readme.md.tmpl +13 -0
  55. package/node_modules/projectstore/templates/zh/strings.json +63 -1
  56. package/node_modules/projectstore/templates/zh/vault-readme.md.tmpl +13 -0
  57. package/package.json +2 -2
package/README.md CHANGED
@@ -6,11 +6,12 @@ The Claude Code installer for [projectstore](https://www.npmjs.com/package/proje
6
6
  npx projectstore-claude install --project "$PWD"
7
7
  ```
8
8
 
9
- It registers the plugin for that checkout at the host's local scope. It prints its plan first — every write and every host command, verbatim — and at a terminal asks `Apply N changes? [Y/n]` before anything runs; then each step as it runs, and what to do next. Without a terminal (a script, CI, an agent's tool) naming the shell is the confirmation; `--json` never asks. Restart Claude Code afterwards.
9
+ It registers the plugin for that checkout at the host's local scope. It prints its plan first — every write and every host command, verbatim — and at a terminal asks `◆ Apply N changes? [Y/n]` before anything runs; then each step as it runs, and what to do next. Without a terminal (a script, CI, an agent's tool) naming the shell is the confirmation; `--json` never asks. Restart Claude Code afterwards.
10
10
 
11
11
  - See before you write: `npx projectstore-claude plan --project "$PWD"` prints the same plan and writes nothing; `--verbose` adds every row's reasoning; `npx projectstore-claude <verb> --help` lists a verb's options with examples.
12
12
 
13
13
  - Upgrade, or pin: `npx projectstore-claude@<version> upgrade --project "$PWD"` — the version you name is the version you run.
14
+ - Behind a registry mirror: if `npx` answers `could not determine executable to run`, the mirror's index knows only the reserved `0.0.1` placeholder — name the version, and if needed the public registry: `npx --registry https://registry.npmjs.org projectstore-claude@<version> install --project "$PWD"`.
14
15
  - Uninstall: `npx projectstore-claude uninstall --project "$PWD"` — forgets the registration for that checkout and nothing else; your vault is plain markdown and stays yours.
15
16
  - `doctor`, `status`, `search` and the other read verbs pass through unchanged: `npx projectstore-claude doctor --json`.
16
17
 
@@ -12,7 +12,7 @@
12
12
  "name": "projectstore",
13
13
  "displayName": "projectstore",
14
14
  "description": "📚 Your agent runs the project through a verified loop: task → artifact (ADR · spec · epic · story) → adversarial critic → backlog → planner → reviewer → done. Plain markdown in an Obsidian-friendly vault, every write approved by you — and any model can pick the project up tomorrow.",
15
- "version": "0.29.1",
15
+ "version": "0.29.3",
16
16
  "author": {
17
17
  "name": "Evgenii Konev",
18
18
  "email": "ekonev@smartandpoint.com",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "projectstore",
3
3
  "displayName": "projectstore",
4
- "version": "0.29.1",
4
+ "version": "0.29.3",
5
5
  "description": "Your agent runs the project through a verified loop: task → artifact (ADR / spec / epic / story) → adversarial critic → backlog → planner → reviewer → done. Plain markdown in git — any model can pick the project up tomorrow.",
6
6
  "author": {
7
7
  "name": "Evgenii Konev @ SmartAndPoint",
@@ -11,6 +11,7 @@
11
11
  "homepage": "https://github.com/SmartAndPoint/ProjectStore",
12
12
  "repository": "https://github.com/SmartAndPoint/ProjectStore",
13
13
  "license": "MIT",
14
+ "types": "./hooks/band-state.d.ts",
14
15
  "keywords": [
15
16
  "project-management",
16
17
  "adr",
@@ -1,6 +1,6 @@
1
1
  # ProjectStore
2
2
 
3
- > Not a memory plugin. ProjectStore is how your AI agent runs the *project* — decisions, specs, epics, stories and a kanban board as plain markdown in git — so the next agent, the next model, or you in six months know exactly **why** everything is the way it is.
3
+ > Not agent memory, not a per-feature spec pipeline. Memory helps one agent recall; a feature spec plans one change. ProjectStore keeps the project's record — what was decided, what is in flight, what was checked — as reviewed markdown in git, readable by any agent and anyone with the repo.
4
4
 
5
5
  [![release](https://img.shields.io/github/v/release/SmartAndPoint/ProjectStore?label=release)](https://github.com/SmartAndPoint/ProjectStore/releases) [![license](https://img.shields.io/github/license/SmartAndPoint/ProjectStore?label=license)](./LICENSE) [![Star on GitHub](https://img.shields.io/badge/%E2%AD%90-star_us-yellow?logo=github)](https://github.com/SmartAndPoint/ProjectStore/stargazers)
6
6
 
@@ -14,6 +14,21 @@ Agents write code fast. They re-decide settled questions even faster: every fres
14
14
 
15
15
  The fix is not a smarter agent. It is a loop with verification in it.
16
16
 
17
+ ## Where it fits
18
+
19
+ **Not agent memory. Not a spec pipeline. The project's record.** Three kinds of tools sit next to a coding agent. Each answers a different question.
20
+
21
+ | Kind of tool | The question it answers | What it keeps | Examples |
22
+ |---|---|---|---|
23
+ | **Agent memory** | What does this agent recall? | Notes the model keeps from its sessions, for an agent, a user or a machine. | Mem0, Zep, Codex and Claude Code memory |
24
+ | **Instruction files** | How should an agent behave here? | Standing rules for an agent, kept in the repository. | `CLAUDE.md`, `AGENTS.md`, rules, steering files |
25
+ | **Spec-driven tools** | How do we build this change? | A spec, a plan and tasks for one feature. | Spec Kit, Kiro, OpenSpec, BMAD |
26
+ | **ProjectStore** | What has the project decided, what is in flight, and was it checked? | Decisions, specs and work items with a status, a date and links, in git. A person approves each before ProjectStore writes it; a fresh-context critic reviews it by rule. | — |
27
+
28
+ Keep your agent's memory for you and your machine, and the project in the vault.
29
+
30
+ Decision logs, validators, session-start orientation and independent review each exist elsewhere. What ProjectStore adds is all of them over one linked record. Tool by tool, with sources: [`docs/alongside.md`](./docs/alongside.md).
31
+
17
32
  ## The loop
18
33
 
19
34
  The thing that makes agentic coding work — the loop Claude Code's own creator keeps pointing at — is *gather context, act, verify, repeat*. ProjectStore runs that loop one level up: over the project, not just the code.
@@ -27,10 +42,10 @@ The thing that makes agentic coding work — the loop Claude Code's own creator
27
42
  2. **A fresh-context critic attacks the artifact.** Expect *revise* — on this repo it has yet to pass anything on the first try, and that is the point.
28
43
  3. The fixed artifact lands in the **backlog**; the kanban regenerates itself.
29
44
  4. An agent picks up a story. A **planner** reads how earlier epics actually landed in the code and says where this change belongs.
30
- 5. A **reviewer** matches the diff against the story's acceptance criteria — per criterion, with evidence — before anything gets called done.
45
+ 5. By rule, a **reviewer** matches the diff against the story's acceptance criteria — per criterion, with evidence — before anything gets called done.
31
46
  6. **Done.** Board, link graph and code map regenerate. The next session starts oriented instead of guessing.
32
47
 
33
- Mechanisms hold this together, not discipline: an agent that starts coding with no story open gets nudged, artifacts are not final before review, and a deterministic `doctor` checks the mechanical consistency with zero AI involved. Every *verify* step is a separate fresh-context agent with no stake in the draft it is judging.
48
+ Mechanisms hold this together, not discipline: an agent that starts coding with no story open gets nudged; an artifact that needs review carries `review_status: pending` until a critic pass is applied, so "not yet reviewed" is a state the tools can read rather than something someone must remember; and a deterministic `doctor` checks the mechanical consistency with zero AI involved. Every *verify* step is a separate fresh-context agent with no stake in the draft it is judging.
34
49
 
35
50
  We build ProjectStore with ProjectStore. The feature that names your session went through exactly this loop — including a critic pass that killed the design's central claim, and a reviewer pass that caught a bug which would have shipped the feature silently dead for every real user.
36
51
 
@@ -56,6 +71,8 @@ Six months later, *"why Postgres?"* has an answer with a date and the alternativ
56
71
 
57
72
  ![projectstore status line: the 📚 epic › story line sitting above an existing oh-my-claudecode HUD](docs/images/statusline-hud.png)
58
73
 
74
+ In Claude Code a band above the prompt goes further (experimental): the session's epic with its goal and how far it is, the story in hand, and the ProjectStore agent at work — `critic · opus 5.5 · reviews «…»` — on the model its own requests name. While it draws, the status line steps aside; `/projectstore:bar off` hides it, `/projectstore:bar status` says why it is not there.
75
+
59
76
  Open the vault in [Obsidian](https://obsidian.md) and you get the graph view and the board for free. Don't use Obsidian? Everything renders on GitHub and in any editor.
60
77
 
61
78
  ## Install — one message
@@ -94,19 +111,27 @@ Contributors: `git clone` this repo, then `claude --plugin-dir ./ProjectStore`.
94
111
  npx projectstore-claude install --project "$PWD"
95
112
  ```
96
113
 
97
- The same tree is published to npm as [`projectstore`](https://www.npmjs.com/package/projectstore) — one source package carrying every harness's manifest — and `projectstore-claude` is its Claude Code shell: the core pinned at the same version and bundled inside, the harness fixed, so the one command has the same shape on every harness. It registers the plugin with Claude Code: it writes a small local marketplace of its own under your Claude home, then drives `claude plugin marketplace add` / `plugin install` **at local scope**, so the registration lands in this checkout's `.claude/settings.local.json` and nowhere else. It prints its plan first — every file it writes and every host command, verbatim — and at a terminal asks `Apply N changes? [Y/n]`; then it shows each step as it runs and what to do next. Without a terminal (a script, CI, an agent's tool) naming the harness is the confirmation. `plan` prints the same plan and writes nothing; `--verbose` adds every row's reasoning; `npx projectstore-claude <verb> --help` lists a verb's options with examples. Restart Claude Code afterwards. A git-marketplace copy already enabled for the checkout is silenced there (not globally) so the plugin does not load twice; `uninstall` turns it back on. Pin or upgrade with `npx projectstore-claude@<version> upgrade --project "$PWD"` — the version you name is the version you run. The core's low-level form, `npx projectstore <verb> --harness claude-code …`, is exactly what the shell runs. bun works the same on the packed bin.
114
+ The same tree is published to npm as [`projectstore`](https://www.npmjs.com/package/projectstore) — one source package carrying every harness's manifest — and `projectstore-claude` is its Claude Code shell: the core pinned at the same version and bundled inside, the harness fixed, so the one command has the same shape on every harness. It registers the plugin with Claude Code: it writes a small local marketplace of its own under your Claude home, then drives `claude plugin marketplace add` / `plugin install` **at local scope**, so the registration lands in this checkout's `.claude/settings.local.json` and nowhere else. It prints its plan first — every file it writes and every host command, verbatim — and at a terminal asks `◆ Apply N changes? [Y/n]`; then it shows each step as it runs and what to do next. Without a terminal (a script, CI, an agent's tool) naming the harness is the confirmation. `plan` prints the same plan and writes nothing; `--verbose` adds every row's reasoning; `npx projectstore-claude <verb> --help` lists a verb's options with examples. Restart Claude Code afterwards. A git-marketplace copy already enabled for the checkout is silenced there (not globally) so the plugin does not load twice; `uninstall` turns it back on. Pin or upgrade with `npx projectstore-claude@<version> upgrade --project "$PWD"` — the version you name is the version you run. The core's low-level form, `npx projectstore <verb> --harness claude-code …`, is exactly what the shell runs. bun works the same on the packed bin.
98
115
 
99
116
  **Codex has its own shell with the same one-command shape:**
100
117
  `npx projectstore-codex install --project "$PWD"`. It carries a Codex
101
118
  plugin manifest, namespaced workflow and role skills, lifecycle hooks, and
102
119
  the exact bundled core. It stages a stable marketplace under `CODEX_HOME`,
103
120
  drives `codex plugin marketplace add` and `codex plugin add`, then reads the
104
- installation back and verifies its version and payload digest. Restart Codex,
121
+ installation back and verifies its version and payload digest. Before it
122
+ changes anything it asks Codex for that read-back (`codex plugin list --json`),
123
+ so a Codex too old to answer stops the registration before it changes anything
124
+ and tells you to upgrade Codex. Restart Codex,
105
125
  approve the hooks, and run `$projectstore-bind <vault-path>`. For later
106
126
  releases, `npx projectstore-codex@<version> upgrade --project "$PWD"`. Because
107
127
  Codex's plugin registry is user-global, ordinary uninstall removes only the
108
128
  project's agents block; `uninstall --global` is the explicit machine-wide
109
- removal. Codex is **experimental** until a live session has exercised every
129
+ removal. If `npx` answers `could not determine executable to run`, your
130
+ registry (often a company mirror) serves a stale index that knows only the
131
+ reserved `0.0.1` placeholder: name the version, and if that is not enough, the
132
+ public registry: `npx --registry https://registry.npmjs.org
133
+ projectstore-codex@<version> install --project "$PWD"` (the same holds for
134
+ `projectstore-claude`). Codex is **experimental** until a live session has exercised every
110
135
  surface it installs; [`docs/harnesses.md`](./docs/harnesses.md) says what has
111
136
  been measured and what has not. From a checkout, the same npx path runs against
112
137
  a built tarball:
@@ -124,6 +149,8 @@ npx projectstore install --harness claude-code # the low-level form the shell
124
149
  npx projectstore reconcile --write --only kanban
125
150
  ```
126
151
 
152
+ At a terminal the bin's output is coloured; a pipe gets the same layout as plain text. `NO_COLOR=1` turns the colour off, and `PROJECTSTORE_ASCII=1` draws every glyph in ASCII — for a terminal that draws ambiguous-width characters wide (`TERM=dumb` does both).
153
+
127
154
  Reads too — the same facts the agents get over MCP:
128
155
 
129
156
  ```
@@ -140,11 +167,12 @@ The same eight reads are an MCP server. The plugin registers it through its own
140
167
  npx projectstore mcp --project "$PWD"
141
168
  ```
142
169
 
143
- Binding, too — naming the vault is the confirmation, and changing it needs `--rebind`:
170
+ Binding, too — naming the vault is the confirmation, and changing it needs `--rebind`. `init` creates a whole vault in one step, with no `mkdir` first: the directory, its git repository, the layout's folders and their README indexes; `scaffold --write` adds the folders to a vault that was bound without them:
144
171
 
145
172
  ```
146
173
  npx projectstore bind ~/vaults/my-project
147
174
  npx projectstore init ~/vaults/new-project --language ru
175
+ npx projectstore scaffold --write
148
176
  ```
149
177
 
150
178
  `projectstore-claude`, `projectstore-codex` and `projectstore-opencode` are this package's per-harness shells — the core pinned and bundled, the harness fixed. The Claude Code and Codex shells are published at the core's version; Codex stays labelled experimental until a live run has exercised every surface it installs ([`docs/harnesses.md`](./docs/harnesses.md)). The opencode shell publishes after its plugin root is rendered. The other `projectstore-*` names are reserved placeholders pointing back here. One source package, one version, N tarballs.
@@ -255,7 +283,7 @@ And they are the exit door. The vault is plain markdown in git — no server, no
255
283
 
256
284
  ## Fact sheet
257
285
 
258
- **20 commands** · **6 agents** — critic, planner, reviewer, librarian, archaeologist (the advisors: read-only, fresh-context) and clerk (the sole write-capable one — it executes approved writes, post-gate, and composes nothing) · **6 languages** — en, ru, es, de, fr, zh · zero runtime dependencies
286
+ **21 commands** · **6 agents** — critic, planner, reviewer, librarian, archaeologist (the advisors: read-only, fresh-context) and clerk (the sole write-capable one — it executes approved writes, post-gate, and composes nothing) · **6 languages** — en, ru, es, de, fr, zh · zero runtime dependencies
259
287
 
260
288
  The deep dive — real session files, measured payloads, how every mechanism works and where its limits are: [docs/how-it-works.md](./docs/how-it-works.md).
261
289
 
@@ -269,7 +297,7 @@ The deep dive — real session files, measured payloads, how every mechanism wor
269
297
 
270
298
  ## Uninstalling
271
299
 
272
- `/plugin uninstall projectstore@SmartAndPoint` for a Claude git-marketplace install; `npx projectstore-claude uninstall --project "$PWD"` for its npm registration. For Codex, `npx projectstore-codex uninstall --project "$PWD"` removes only project-owned wiring; add `--global` only to remove the user-global Codex plugin and marketplace. Your vault is yours — plain markdown, untouched. One leftover of a host-managed plugin path can be the agents block in `CLAUDE.md`/`AGENTS.md`; remove it with the harness's agents unregister skill, or delete everything between `<!-- projectstore:agents … -->` and `<!-- /projectstore:agents -->` by hand. `uninstall` leaves a block that lives in `AGENTS.md`, because that file is read by other coding agents too, and removes the `CLAUDE.md` import when that file holds nothing else; `uninstall --surface agents_block` removes the block as well.
300
+ `/plugin uninstall projectstore@SmartAndPoint` for a Claude git-marketplace install; `npx projectstore-claude uninstall --project "$PWD"` for its npm registration. For Codex, `npx projectstore-codex uninstall --project "$PWD"` removes only project-owned wiring; add `--global` only to remove the user-global Codex plugin and marketplace. Your vault is yours — plain markdown, untouched. One leftover of a host-managed plugin path can be the agents block in `CLAUDE.md`/`AGENTS.md`; remove it with the harness's agents unregister skill, or delete everything between `<!-- projectstore:agents … -->` and `<!-- /projectstore:agents -->` by hand. A one-harness `uninstall` leaves a block that lives in `AGENTS.md`, because that file is read by other coding agents too. Claude Code's then removes the `CLAUDE.md` import when that file holds nothing else; Codex's keeps it, so Claude Code still sees the block. `uninstall --surface agents_block` removes the block as well. A bare core `npx projectstore uninstall --project "$PWD"`, with no `--harness`, covers every harness the project uses — each one whose own directory (`.claude/`, `.codex/`) or `.projectstore/state/<id>/` is there. Once every harness that can read the block's file is among them (for `AGENTS.md`, Claude Code and Codex), the block goes too, and the `CLAUDE.md` import with it unless your own text keeps both files.
273
301
 
274
302
  ## Extending
275
303
 
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: The band above the prompt — this session's epic, its progress, its story and its ProjectStore agents. Switch it on or off, pin an epic for sessions with none, or ask why it is not drawing.
3
+ argument-hint: "on | off | status | epic [<ID>]"
4
+ ---
5
+
6
+ You are managing the band above the prompt through the core's `band` verb. The band is drawn by the plugin's hooks module; it shows this session's epic (from this session's own state), how far that epic is, its goal, this session's story and the ProjectStore agent at work. While it draws, the status line gives way to it, and it comes back within 30 s of the band stopping. Never edit `.projectstore/projectstore.json` yourself: the verb is the one writer of its `band` keys, and writes atomically.
7
+
8
+ Read `$ARGUMENTS`: `on`, `off`, `status`, `epic <ID>`, or `epic` alone (releases the pin). Nothing, or anything else, is `status`.
9
+
10
+ ## status — read-only
11
+
12
+ ```bash
13
+ node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" band status --project "${CLAUDE_PROJECT_DIR}"
14
+ ```
15
+
16
+ Relay its lines. Exit 3: the project is not bound — tell the user to run `/projectstore:bind <vault-path>` and stop. When it says the band is not drawing, the reason is one of: switched off; this session has no epic and none is pinned; the pinned epic no longer exists; the module is not drawing (the host has modules switched off, an older Claude Code, or a crashed module — the status line keeps its own line then); a harness without a band.
17
+
18
+ ## on, off, epic
19
+
20
+ 1. **Ask** via AskUserQuestion, naming the change — "Switch the band off?", "Switch the band on?", "Pin the band to `<ID>` for sessions with no epic of their own?", or "Release the pinned epic?" — **Yes** / **No**. On **No**, stop: nothing is written.
21
+
22
+ 2. **Write**, on **Yes**:
23
+
24
+ ```bash
25
+ node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" band <on|off|epic> [<ID>] --json --project "${CLAUDE_PROJECT_DIR}"
26
+ ```
27
+
28
+ The question above is the confirmation; `--json` never asks again. Report `result.band` and whether `result.wrote`. Exit 1 is a refusal — an unknown epic id (the message names the existing ones), or a binding that is not valid JSON: relay it. The band follows within a few seconds; no restart.
29
+
30
+ A pin shows only in a session that has no epic of its own: a session working on an epic always shows that one.
@@ -20,7 +20,7 @@ Steps:
20
20
  - If absent otherwise: proceed to step 1 (fresh bind).
21
21
  - If present **and** `--inherit` was passed: print "Already bound to `<path>`." and stop. Do not fall through to the rebind comparison below — with `--inherit` there is no new path to compare, and the comparison would render an empty "proposed" side and offer to replace the binding. A no-op command must not reach a destructive option.
22
22
  - If present, let the verb compare — run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" bind "<vault-path>" [--layout <name>] [--language <code>] --json` **without** `--rebind` (pass the user's flags, so the proposed side of the diff is what a rebind would write) (the vault is normalised on both sides: `~`, relative, trailing slash, symlinks):
23
- - `result.state` is `"same"` (exit 0, nothing written): print "Already bound to `<path>`. Re-run `/projectstore:scaffold` if you need to (re)create the layout, or `/projectstore:status` to inspect it." and stop. If `result.ignored` names `layout` or `language`, say the flag was ignored — a change of layout or language is not a rebind.
23
+ - `result.state` is `"same"` (exit 0, nothing written): print "Already bound to `<path>`." Then run step 7's `scaffold --json` check: when a row reads `create`, add "`/projectstore:scaffold` creates the layout's missing folders and READMEs"; otherwise suggest `/projectstore:status`. Stop. If `result.ignored` names `layout` or `language`, say the flag was ignored — a change of layout or language is not a rebind.
24
24
  - a refusal with code `UNREADABLE` (the config exists but is not valid JSON): relay it and stop — nothing is overwritten; the user fixes or removes the file first.
25
25
  - `result.state` is `"different"` (exit 1, a `REBIND` refusal, nothing written — **the refusal is the diff**, and `result.kept_keys` lists what a rebind keeps): show the user a one-block diff built from the existing config and the refusal:
26
26
  ```
@@ -48,12 +48,13 @@ Steps:
48
48
 
49
49
  It prints `{state, worktree, mainCheckout, vaultPath}` and writes nothing.
50
50
  - `state` is **not** `inheritable` → say why in one line (not a worktree, its parent is unbound too, or git could not answer) and fall through to step 1, which needs a vault path; if none was given, ask for one.
51
- - `state` is `inheritable` → read the parent's `<mainCheckout>/.projectstore/projectstore.json` (or, in a checkout not yet migrated, the legacy `<mainCheckout>/.claude/projectstore.json`), show it **verbatim as a code block**, and ask via AskUserQuestion: "Adopt the binding of `<mainCheckout>` (vault `<vaultPath>`)?" — Yes / No.
52
- - On **Yes**: Write that JSON verbatim to `<project>/.projectstore/projectstore.json`, **and write `<project>/.projectstore/.gitignore` beside it** with the two lines `projectstore.json` and `state/` under a comment saying they are machine-local (the verb writes them itself on every other path; this one bypasses the verb, and without them the worktree commits an absolute vault path into the index it shares with its parent). If that file already exists, add any missing line and leave the rest — it is line-merged. Then **jump straight to step 10** (the summary). Steps 1–9 and 11–12 are decisions the parent already made and the copied config already carries — layout, language, statusline, agent models, auto-update. Do not re-ask them, and do not scaffold: the vault exists and is shared.
51
+ - `state` is `inheritable` → read the parent's `<mainCheckout>/.projectstore/projectstore.json` (or, in a checkout not yet migrated, the legacy `<mainCheckout>/.claude/projectstore.json`), show it **verbatim as a code block** — but for a `channel_switch` key, which is left out (below) — and ask via AskUserQuestion: "Adopt the binding of `<mainCheckout>` (vault `<vaultPath>`)?" — Yes / No.
52
+ - On **Yes**: Write that JSON verbatim, without `channel_switch`, to `<project>/.projectstore/projectstore.json`, **and write `<project>/.projectstore/.gitignore` beside it** with the two lines `projectstore.json` and `state/` under a comment saying they are machine-local (the verb writes them itself on every other path; this one bypasses the verb, and without them the worktree commits an absolute vault path into the index it shares with its parent). If that file already exists, add any missing line and leave the rest — it is line-merged. Then **jump straight to step 10** (the summary). Steps 1–9 and 11–12 are decisions the parent already made and the copied config already carries — layout, language, statusline, agent models, auto-update. Do not re-ask them, and do not scaffold: the vault exists and is shared.
53
53
  - Copy the **binding only** (`projectstore.json`). Never copy `.projectstore/state/` — per-session state belonging to the other checkout — and never `harness/`: the overlays are committed and arrive from git.
54
+ - **Never copy `channel_switch`.** It records that the parent checkout was switched to the npm install — a machine-local fact of that checkout, not of the binding it shares. Every other key is copied verbatim.
54
55
  - Do not add a provenance key to the config. The parent is resolvable from git at any time; a key would be a second source of truth for the same fact.
55
56
 
56
- 1. **Validate the vault path** read-only first: `ls -d "<path>"` (the verb has no dry run — running it on a fresh project would write the config before step 4's approval). If it does not exist, ask the user (via AskUserQuestion) whether to create it; on Yes, step 5 runs `init` instead of `bind` (it creates the directory and binds; the layout's folders remain `/projectstore:scaffold`'s). Never `mkdir` it yourself.
57
+ 1. **Validate the vault path** read-only first: `ls -A "<path>"` (the verb has no dry run — running it on a fresh project would write the config before step 4's approval). If it does not exist, or exists and is empty, ask the user (via AskUserQuestion) whether to create the vault there; on Yes, step 5 runs `init` instead of `bind`. `init` creates the whole vault and binds: the directory (unless it is there and empty), its git repository with no commit, and the layout's folders and READMEs. Never `mkdir` it yourself. A directory that already holds files is bound with `bind`; `init` would bind it too, but never scaffolds or `git init`s inside it.
57
58
  2. **Detect existing layout**: list immediate subdirectories. If you see `adr/`, `epics/`, `concepts/`, `research/` — the vault already uses an engineering-like layout; suggest `engineering`. Otherwise use the user's choice or `engineering` default.
58
59
  3. **Build the config** as JSON:
59
60
 
@@ -80,15 +81,21 @@ Steps:
80
81
  node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" bind "<vault-path>" [--layout <name>] [--language <code>] [--rebind]
81
82
  ```
82
83
 
83
- `init "<vault-path>" …` instead when step 1 chose to create the vault; `--rebind` only when step 0 ended on **Replace bind**. Naming the vault is the verb's confirmation (there is no `--yes`); the interview's AskUserQuestion in step 4 is the in-session gate. Print the verb's output. A non-zero exit is a refusal or a usage error — relay it and stop. Steps 11 and 12 below `Edit` the file this step wrote; keep them after it.
84
+ `init "<vault-path>" …` instead when step 1 chose to create the vault — it creates the whole vault, so step 7 has nothing to offer after it; `--rebind` only when step 0 ended on **Replace bind**. Naming the vault is the verb's confirmation (there is no `--yes`); the interview's AskUserQuestion in step 4 is the in-session gate. Print the verb's output. A non-zero exit is a refusal or a usage error — relay it and stop — except an `init` whose output reports `git init failed` or `Scaffold failed`: the binding is written, so relay the remedy line it prints and continue. Steps 11 and 12 below `Edit` the file this step wrote; keep them after it.
84
85
 
85
86
  6. **Check `.gitignore`**: read `<project>/.gitignore` if it exists. Our own files are self-ignored inside `.projectstore/` — the verb writes that `.gitignore` itself, carrying `projectstore.json` and `state/`, with `harness/` committed on purpose (the layout ADR); on the inherit path of step 0a, which bypasses the verb, you wrote both by hand. Unless `.claude/` is ignored wholesale, the one machine-specific entry left is the host's `.claude/settings.local.json`. If it is missing, offer (AskUserQuestion) to append it. If the user declines, skip silently.
86
87
 
87
- 7. **Offer scaffold**: if the vault is empty or missing layout folders, ask: "Vault is empty/incomplete. Run `/projectstore:scaffold` to create the layout? [Yes / No]". If yes, invoke `/projectstore:scaffold` immediately (just describe; do not assume execution).
88
+ 7. **Offer scaffold** — after `bind` only; a vault `init` made is already scaffolded. Ask the core, which writes nothing here:
89
+
90
+ ```bash
91
+ node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" scaffold --json --project "${CLAUDE_PROJECT_DIR}"
92
+ ```
93
+
94
+ Offer only when some `result.rows[]` entry has `action: "create"` — a layout folder or a README is missing. Ask via AskUserQuestion: "The vault is missing N of the layout's folders and READMEs (listed). Create them? Existing files are never rewritten." — **Yes** / **No**. On **Yes**, run `node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" scaffold --write --json --project "${CLAUDE_PROJECT_DIR}"` and report `result.created`. No `create` row: say nothing and continue.
88
95
 
89
96
  7.5. **Vault policy** (v0.14, ADR-007 — vault-side, survives clones): check `<vault>/.projectstore.json`.
90
97
  - If it already exists with a `spec_policy` key — respect it, print the current policy, do not re-ask.
91
- - **New bind into an empty/fresh vault**: ask via AskUserQuestion — "Enable spec-first policy for this vault (every story must be covered by a spec; doctor enforces it)?" with options **Yes, `spec_policy: required` (Recommended)** / **Not yet, `optional`**. Second question: "Enable lifecycle gates (plan/close sections + evidence checks on stories)?" — **Yes, `lifecycle_gates: on` (Recommended)** / **Off for now**.
98
+ - **New bind into a vault with no artifacts** (a vault `init` just made counts: its folders and README indexes are not artifacts): ask via AskUserQuestion — "Enable spec-first policy for this vault (every story must be covered by a spec; doctor enforces it)?" with options **Yes, `spec_policy: required` (Recommended)** / **Not yet, `optional`**. Second question: "Enable lifecycle gates (plan/close sections + evidence checks on stories)?" — **Yes, `lifecycle_gates: on` (Recommended)** / **Off for now**.
92
99
  - **Bind to an existing vault with artifacts**: default to `spec_policy: optional`, `lifecycle_gates: off` and say doctor will suggest enabling once specs appear. Do not impose the gate on an existing backlog.
93
100
  - On any choice, write `<vault>/.projectstore.json` (vault ROOT — deliberately not inside `<vault>/.projectstore/`, whose .gitignore would keep the policy out of git):
94
101
 
@@ -1,23 +1,31 @@
1
1
  ---
2
2
  description: Scaffold the bound vault with the layout's folder structure and README index files.
3
- argument-hint: [layout-name]
3
+ argument-hint: ""
4
4
  ---
5
5
 
6
- You are creating the folder structure of the projectstore layout inside the bound vault.
6
+ You are creating the bound vault's layout folders and their README indexes through the core's `scaffold` verb. The layout and the language are the binding's; the folder names, the descriptions and every README come from the plugin's templates in that language, so a vault scaffolded here is byte-identical to one `init` made. Never create a folder or write a README yourself, and take no layout argument: `bind --rebind` changes the layout.
7
7
 
8
8
  Steps:
9
9
 
10
- 1. **Read config**: `cat .projectstore/projectstore.json`. If missing, tell user to run `/projectstore:bind <path>` and stop.
11
- 2. **Determine layout**: use `$ARGUMENTS` if provided, else `config.layout`.
12
- 3. **Load layout spec**: `cat "${CLAUDE_PLUGIN_ROOT}/scaffold/layouts/<layout>.json"`. Parse it.
13
- 4. **Show plan**: list every folder that will be created and which folders already exist. Mark new ones with `(create)`, existing with `(exists)`.
14
- 5. **Ask approval** via AskUserQuestion: "Create the missing folders and READMEs? [Yes / Skip READMEs / No]".
15
- 6. **Execute**:
16
- - For each folder in `layout.folders`:
17
- - Create directory via `mkdir -p <vault>/<folder.path>`.
18
- - If `folder.readme === true` and `<vault>/<folder.path>/README.md` does not exist:
19
- - Read template: `cat "${CLAUDE_PLUGIN_ROOT}/templates/<lang>/folder-readme.md.tmpl"`.
20
- - Substitute `{{folder_name}}` and `{{folder_description}}` based on the folder kind.
21
- - Write the README via Write tool.
22
- - Also create a top-level `<vault>/README.md` if missing — a simple index pointing to each folder.
23
- 7. **Print result**: tree of newly created files and a one-line "next step" suggestion.
10
+ 1. **Plan** — nothing is written:
11
+
12
+ ```bash
13
+ node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" scaffold --project "${CLAUDE_PROJECT_DIR}"
14
+ ```
15
+
16
+ It prints one row per folder, per folder README and for the vault's own `README.md`, each `create` or `exists`.
17
+ - Exit 3: the project is not bound — tell the user to run `/projectstore:bind <vault-path>` and stop.
18
+ - Exit 1: a refusal — the bound vault directory is missing, the binding's language lacks a template or a folder string, or a folder's path is a file. Relay the message and stop.
19
+ - No `create` row: say the vault already has every folder and README the layout declares, and stop.
20
+
21
+ 2. **Ask** via AskUserQuestion, showing the plan's `create` rows: "Create these folders and READMEs in the vault? Existing files are never rewritten." — **Yes** / **No**. On **No**, stop: nothing is written.
22
+
23
+ 3. **Write**, on **Yes**:
24
+
25
+ ```bash
26
+ node "${CLAUDE_PLUGIN_ROOT}/bin/projectstore.mjs" scaffold --write --json --project "${CLAUDE_PROJECT_DIR}"
27
+ ```
28
+
29
+ The question above is the confirmation; `--json` never asks again. Report `result.created`, and how many rows `result.exists` left as they were. A non-zero exit is an error: relay it.
30
+
31
+ 4. **Next**: the folder indexes fill as artifacts are created; `/projectstore:reconcile` regenerates the board and the other derived views when you want them.
@@ -22,6 +22,6 @@ Steps:
22
22
 
23
23
  5. **Active sessions** from `result.sessions`: `active` is the count within the last 30 minutes; `entries[]` (capped at 5) carry `id`, `project_root`, `started_at`, `last_active` — print them as a compact table. From inside a slash command you cannot tell which entry is the current session (Claude's `session_id` reaches hooks, not commands); the user can match by `project_root` and timestamps. If `active` is greater than 1: warn "⚠️ Coordinate via /projectstore:search before creating new artifacts to avoid topic collisions (identity is the slug — ADR-010; the draft's `collision` field catches clashes at creation time)."
24
24
 
25
- 6. Suggest the next command from what you saw: `stories.total` is 0 → "Vault looks empty — try `/projectstore:scaffold`"; any view stale or missing → "Stale views — try `/projectstore:reconcile`"; something in progress → name it and suggest `/projectstore:story` to continue.
25
+ 6. Suggest the next command from what you saw: `stories.total` is 0 → "No stories yet — `/projectstore:epic <ID> "<title>"` opens the first epic" (a vault `init` made has its folders; `/projectstore:scaffold` is for one bound without them, and its plan says which are missing); any view stale or missing → "Stale views — try `/projectstore:reconcile`"; something in progress → name it and suggest `/projectstore:story` to continue.
26
26
 
27
27
  What this command no longer does, and why: the former `ls`/`find -mtime -7` walk of recently touched files is gone — its failure mode is a false "nothing changed" (an iCloud download or a git checkout resets mtimes), the opposite of the views' `stale` flag, whose false positive only costs a reconcile. The in-progress list and the views' freshness answer the same question from artifact facts. The former layout-folder check (`ls` the vault, mark missing folders) is `doctor --vault`'s job and `orientation`'s skeleton shows the folders that exist; it is not repeated here.
@@ -3,7 +3,7 @@ description: Enable/disable the projectstore status line (current epic & story i
3
3
  argument-hint: "on | off | status"
4
4
  ---
5
5
 
6
- You are toggling the projectstore status line for THIS project. When enabled, `install-harness.mjs` points the project's `.claude/settings.local.json` at a launcher it writes at `.projectstore/state/claude-code/statusline.mjs`. That path carries no version, so it never goes stale: the launcher resolves the *currently installed* plugin on every render, and an update is reflected on the spot instead of one restart later. (A dev checkout or `--plugin-dir` root is wired straight to its `scripts/statusline.mjs` — those paths have no version to drift.) The line renders `[PS#<version>] 📚 <epic> › <story> (<status>)` **composed above** any existing HUD (e.g. oh-my-claudecode), never replacing it.
6
+ You are toggling the projectstore status line for THIS project. When enabled, `install-harness.mjs` points the project's `.claude/settings.local.json` at a launcher it writes at `.projectstore/state/claude-code/statusline.mjs`. That path carries no version, so it never goes stale: the launcher resolves the *currently installed* plugin on every render, and an update is reflected on the spot instead of one restart later. (A dev checkout or `--plugin-dir` root is wired straight to its `scripts/statusline.mjs` — those paths have no version to drift.) The line renders `[PS#<version>] 📚 <epic> › <story> (<status>)` **composed above** any existing HUD (e.g. oh-my-claudecode), never replacing it. While this session's band above the prompt is drawing (`/projectstore:bar`), the line gives way to it — your base HUD stays — and it comes back within 30 s of the band stopping.
7
7
 
8
8
  Resolution is **per-session with zero cross-session and zero vault reads** (ADR-006): the 📚 segment comes from this session's pointer (`.projectstore/state/sessions/<session_id>.json`, maintained by the PreToolUse hook); a fresh session shows an explicit localized cold-start line ("No epic or story in this session yet" / «Эпик и стори ещё не в работе в этой сессии») — never a silent blank; a corrupt pointer shows an error-marked string. Strings localize via `templates/<lang>/strings.json` (en fallback). The version badge is controlled by `statusline.show_version` (default true).
9
9
 
@@ -0,0 +1,167 @@
1
+ # ProjectStore beside agent memory and spec-driven tools
2
+
3
+ People who meet ProjectStore compare it with what they already run next to a coding agent: a
4
+ memory plugin, an instruction file, a spec-driven tool. This page says what each of those keeps,
5
+ what ProjectStore keeps instead, and which parts of ProjectStore exist elsewhere. The README and
6
+ the site name three kinds of tools; the first table here has four kinds, because agent memory kept
7
+ in the repository gets its own column.
8
+
9
+ The claims about other tools come from their own documentation, repositories and release notes,
10
+ **read on 2026-10-09**. Tools move fast; if a cell below is wrong or out of date,
11
+ [open an issue](https://github.com/SmartAndPoint/ProjectStore/issues/new?title=docs%2Falongside.md%3A+a+wrong+cell)
12
+ and name the cell and your source.
13
+
14
+ ## The question each kind of tool answers
15
+
16
+ | | Agent memory | Instruction files | Agent notes in the repository | Spec-driven tools | ProjectStore |
17
+ |---|---|---|---|---|---|
18
+ | **Examples** | Mem0, Zep, claude-mem, Codex memories, Claude Code auto memory | `CLAUDE.md`, `AGENTS.md`, rules, Kiro steering | Cline Memory Bank, Serena memories, Basic Memory, Letta | Spec Kit, Kiro specs, OpenSpec, BMAD | |
19
+ | **One entry is** | a fact or an observation | a rule | a note the agent keeps | a change: spec, plan, tasks | a decision, a spec or a work item, with a status, a date and links |
20
+ | **Written by** | the model, automatically | a person, or the agent on request | the agent, sometimes reviewed in pull requests | the agent; phase approval in Kiro and Tessl, a clear yes in OpenSpec's Explore, write previews in one BMAD skill | the agent drafts; a person approves the full text; a fresh-context critic reviews it by rule |
21
+ | **Lives in** | a hosted or local index (vector, graph, SQLite), or machine-local files | the code repository | the code repository, or a memory repository | the code repository; OpenSpec Stores (beta) in a planning repository | a folder kept in git, usually its own repository |
22
+ | **Read by** | the model, by retrieval | the model, at session start or when a file pattern or request matches | the model, on demand | the model and the team, during the feature | Claude Code sessions from the start (Codex: experimental); any agent through the CLI and MCP; people in pull requests and Obsidian |
23
+ | **Scope** | an agent, a user or a machine | the project | the project | a feature, plus a constitution or steering | the project, across features and harnesses |
24
+ | **Changes by** | expiry, invalidation, pruning | rewriting | rewriting, git history | per feature: discarded, or merged into living specs | supersede with reasons; status changes with evidence; `doctor` and `reconcile` |
25
+ | **Answers** | "What does this agent recall?" | "How should an agent behave here?" | "What has this agent learned about the project?" | "How do we build this change?" | "What has the project decided, what is in flight, and was it checked?" |
26
+
27
+ ## Why ProjectStore is not agent memory
28
+
29
+ 1. **Nothing is written because it was said.** A memory system writes when the model notices
30
+ something. A vault artifact is written through a ProjectStore command, after a person approved
31
+ its path and full text. The skill that watches the conversation only suggests a command.
32
+ 2. **Nothing is read by similarity.** Agents navigate: folder indexes, the link graph grepped by
33
+ path, the kanban, then the artifact. `search` is a literal substring search. What an agent read
34
+ is a file a person can open.
35
+
36
+ The price: an agent must know a word, a title or a path. Nothing finds a note that says the
37
+ same thing in other words.
38
+ 3. **Nothing belongs to an agent, a user or a machine.** The vault travels through git to whoever
39
+ has the repository. Claude Code and Codex read it through ProjectStore's commands; any other
40
+ agent can read it through the CLI or the MCP read surface. Codex memories and Claude Code auto
41
+ memory are per machine; Mem0's are per user or agent.
42
+ 4. **It can be wrong in a way that is reviewed.** A memory that turned false is expired, pruned or
43
+ invalidated. A decision that turned false is superseded by a newer ADR that says why, and the
44
+ chain stays.
45
+ 5. **What survives `/compact` is paths into the record, not knowledge from the session.** In
46
+ Claude Code, the SessionStart hook runs after compaction too. It hands back a navigation
47
+ skeleton of the vault plus the vault paths the session touched: the session's own activity log,
48
+ machine-local and git-ignored, resolved against the vault. Nothing the conversation said is
49
+ stored. Codex runs the same hook in its experimental shell, but what it reports after
50
+ compaction has not been measured.
51
+
52
+ **The overlap.** ProjectStore keeps a little session state on the machine — a per-session pointer
53
+ and the last 50 activity entries — for orientation, never committed. It is not knowledge, and
54
+ deleting it changes nothing in the vault.
55
+
56
+ **Where the data goes.** A memory tool stores what it derives from conversations, and some ship it
57
+ off the machine (Mem0's platform, claude-mem's optional cloud sync). The vault holds only text a
58
+ person approved. What reaches the model provider still depends on your harness and its
59
+ permissions.
60
+
61
+ ## Memory and the vault, side by side
62
+
63
+ They are not rivals. Use both, each for its own thing:
64
+
65
+ - **Memory for the person and the machine:** how you like to work, your environment's quirks,
66
+ corrections you gave the agent.
67
+ - **The vault for the project:** what was decided and why, what is in flight, what was checked.
68
+
69
+ The vendors say the same about their own memory. Codex: "Keep required team guidance in AGENTS.md
70
+ or checked-in documentation. Treat memories as a helpful recall layer, not as the only source for
71
+ rules that must always apply." Claude Code's auto memory skips what your `CLAUDE.md` already says.
72
+
73
+ The rule needs upkeep, because memory fills up on its own. When a memory states a project decision
74
+ or an idea the team should see, move it into the vault as an artifact, and let the memory keep only
75
+ a pointer to it.
76
+
77
+ ## The ingredients, tool by tool
78
+
79
+ Every ingredient of ProjectStore's loop exists somewhere else. This matrix shows where. "Core"
80
+ means without extensions; "?" means the documentation we read says nothing either way.
81
+
82
+ | Tool | Decision record with status and supersede | Person approves the full text before a write | Fresh-context review of planning artifacts | Fresh-context review of the diff against acceptance criteria | Orientation from the record at session start | Consistency checks with no model | Read surface for any agent |
83
+ |---|---|---|---|---|---|---|---|
84
+ | Spec Kit 1.1, core | no | no (a convention between phases) | no (in-context `/speckit.analyze` and `/speckit.checklist` only) | no | no | ? | commands for about forty agents |
85
+ | Spec Kit with community extensions | `adrkit`: MADR records with `status`, `adr accept`, superseded retrieval (pinned below 1.1.0) | no, before a write. `plan-review-gate` requires spec and plan merged by PR before tasks; `spec-validate` adds approval state as "a hard gate before /speckit.implement" | `red-team`, `critique`, `multi-model-review` | `maqa`, a QA workflow (fresh context unstated) | the official `agent-context` extension keeps a static block in `CLAUDE.md`/`AGENTS.md`; `memory`, `dubsar` (resume) | ? (`speckit-utils` "validate project health", `sync`; model use unverified) | same |
86
+ | Kiro | no | yes, per phase (Quick Spec skips the gates) | ? | ? | steering, always included | ? | Kiro only |
87
+ | OpenSpec 1.14 | a section per change; the archive keeps history | Explore only: waits for "a clear yes" | ? | ? | marker blocks in `CLAUDE.md`/`AGENTS.md`; no session hook | **yes**: `openspec validate` | many tools |
88
+ | BMAD 6.12.1 | spine `AD-n`: IDs can be retired, never reused; append-only rationale; no supersede chain documented | the project-context skill shows every write first | **yes**: reviewer gates on PRD, spine, UX | fresh subagent lenses (edge cases, verification gaps); the edge-case lens reads the spec's acceptance as claims, not per criterion | its `AGENTS.md` block (project-context skill); no SessionStart hook found | **yes**: `sprint_plan.py validate` | installer for several agents |
89
+ | Beads 1.3.1 | no: issues, not decisions (`bd supersede` marks an issue superseded by a newer one) | no | no | no | **yes**: `bd prime` through SessionStart hooks (Claude Code, Gemini CLI, Codex) | **yes**: `bd doctor`, `bd lint` (missing sections), `bd orphans` (referenced in commits, still open) | CLI with JSON; Dolt in git, JSONL export |
90
+ | Letta, Serena | no | no | no | no | Letta loads memory-root files into the system prompt every turn | no | Serena: any MCP client |
91
+ | Mem0, claude-mem | no | no | no | no | claude-mem injects memory at session start | no | many harnesses |
92
+ | ProjectStore 0.29.2 | **yes**: ADR status, `superseded_by` | **yes**, through its commands | a standing rule for every kind (critic) | a standing rule (reviewer), per criterion with evidence | **yes** in Claude Code; Codex experimental | **yes**: `doctor`, `reconcile`, regenerated views | CLI and MCP; Claude Code and Codex shells |
93
+
94
+ **What it shows.** No single column is ProjectStore's alone:
95
+ - `adrkit` keeps decision status and supersession;
96
+ - OpenSpec, BMAD and Beads validate artifacts without a model;
97
+ - Beads injects ready work at session start;
98
+ - BMAD reviews plans and diffs in fresh contexts.
99
+
100
+ What none of the tools above documents is all of them over one record: decisions, specs and work
101
+ items in one linked graph with a lifecycle, where the same `doctor` checks the links between them
102
+ and down to code, the same views regenerate from them, one critic rule covers every kind, and each
103
+ session's starting map is computed from that record.
104
+
105
+ **The nearest composition is Spec Kit with extensions.** Read cell by cell, it covers three of the
106
+ four ingredients listed above — decision status (`adrkit`), fresh-context review (`red-team`,
107
+ `critique`, `multi-model-review`), session-start orientation (`agent-context`, `memory`, `dubsar`) —
108
+ and has a "?" on the fourth, checks with no model. But it spreads across three stores — `adrkit`'s
109
+ ADRs, `specs/`, and an issue tracker through `maqa` — and documents no links between them and no
110
+ check that reads across them. `adrkit`'s catalog entry also pins Spec Kit below 1.1.0, the current
111
+ core.
112
+
113
+ **Review is a rule, not a lock**, in ProjectStore and in BMAD alike. Both are only as good as their
114
+ being followed. In ProjectStore, ADRs, specs, epics and research notes carry `review_status:
115
+ pending` until a critic pass is applied, so "not yet reviewed" is a state the tools can read;
116
+ stories are checked instead by the reviewer, against their diff. Nothing stops a person from
117
+ accepting an ADR before the critic pass.
118
+
119
+ **When this table is re-read:** when BMAD ships its next release, when OpenSpec Stores leave beta,
120
+ or when a Spec Kit extension joins decision records to review — each of those could change a cell.
121
+
122
+ **Sources, read on 2026-10-09:**
123
+ - Spec Kit: [repository](https://github.com/github/spec-kit) — releases 1.0.0 (2026-08-21) and
124
+ 1.1.0 (2026-10-02), `docs/concepts/spec-persistence.md`, `docs/reference/integrations.md`,
125
+ `extensions/catalog.community.json`; [adrkit](https://github.com/mbeacom/adrkit).
126
+ - Kiro: [specs](https://kiro.dev/docs/specs/), [best practices](https://kiro.dev/docs/specs/best-practices/),
127
+ [steering](https://kiro.dev/docs/steering/).
128
+ - OpenSpec: [repository](https://github.com/Fission-AI/OpenSpec) — releases, `docs/concepts.md`,
129
+ `docs/cli.md`, `docs/installation.md`, `docs/stores-beta/user-guide.md`.
130
+ - BMAD-METHOD: [repository](https://github.com/bmad-code-org/BMAD-METHOD) — release 6.12.1
131
+ (2026-10-04), `src/bmm-skills/plan/bmad-architecture/references/reviewer-gate.md`,
132
+ `src/bmm-skills/plan/bmad-sprint-planning/references/validate.md`.
133
+ - Beads: [repository](https://github.com/gastownhall/beads) — release 1.3.1 (2026-09-30),
134
+ `docs/cli-reference/`.
135
+ - Letta: [context repositories](https://www.letta.com/blog/context-repositories),
136
+ [MemFS](https://docs.letta.com/concepts/memfs). Serena:
137
+ [memories](https://oraios.github.io/serena/02-usage/045_memories.html).
138
+ - Zep / Graphiti: [concepts](https://help.getzep.com/concepts),
139
+ [Graphiti](https://github.com/getzep/graphiti). Cline: [Memory Bank](https://docs.cline.bot/best-practices/memory-bank).
140
+ Basic Memory: [repository](https://github.com/basicmachines-co/basic-memory). Tessl:
141
+ [overview](https://docs.tessl.io/overview/readme.md),
142
+ [spec-driven development tile](https://github.com/tesslio/spec-driven-development-tile).
143
+ - Mem0: [how it works](https://docs.mem0.ai/core-concepts/how-it-works),
144
+ [memory expiration](https://docs.mem0.ai/platform/features/memory-expiration),
145
+ [OpenMemory's removal](https://github.com/mem0ai/mem0/pull/6530). claude-mem:
146
+ [repository](https://github.com/thedotmack/claude-mem).
147
+ - Claude Code: [memory](https://code.claude.com/docs/en/memory). Codex:
148
+ [memories](https://learn.chatgpt.com/docs/customization/memories),
149
+ [AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md).
150
+ - ProjectStore: this repository.
151
+
152
+ ## What the checks cost
153
+
154
+ The critic and reviewer runs are model calls, and they are not free. On this repository, where
155
+ every change goes through the full loop, vault work measures 22.5% of total spend; on a typical
156
+ project, budget 10–15% of a weekly limit. The number is the price of the critic and reviewer
157
+ runs, not of storing files. See
158
+ [What it costs — measured, not promised](../README.md#what-it-costs--measured-not-promised).
159
+
160
+ ## Spec-driven tools
161
+
162
+ Running ProjectStore beside a spec-driven tool such as Spec Kit, Kiro or OpenSpec is a design that
163
+ has not been tried. The idea is that the spec-driven tool would own one feature's spec, plan and
164
+ tasks, while ProjectStore keeps the decisions, the backlog and the checks around them. Whether the
165
+ two tools' agent instructions, entry points and acceptance criteria stay out of each other's way is
166
+ an open question, and so is how ProjectStore's spec-first policy should be set beside them. A trial
167
+ and a decision on that policy are proposed; until they land, this page recommends no setting.
@@ -4,8 +4,8 @@
4
4
 
5
5
  Since v0.14 the kind machinery is layout-driven: `draft.mjs` builds ANY kind
6
6
  declared in the layout, and doctor's template check follows the layout instead
7
- of a hardcoded list. A new kind needs **five touch points** — note that **all
8
- five live inside the plugin installation**, not in your vault (there is no
7
+ of a hardcoded list. A new kind needs **six touch points** — note that **all
8
+ six live inside the plugin installation**, not in your vault (there is no
9
9
  vault-side layout or template override):
10
10
 
11
11
  1. **Layout folder entry** — `scaffold/layouts/<name>.json` → `folders`:
@@ -56,6 +56,16 @@ vault-side layout or template override):
56
56
  `collision`/`warnings` fields and updates an index, `commands/spec.md`
57
57
  for one with status transitions.
58
58
 
59
+ 6. **Folder strings** — `templates/<lang>/strings.json` → `folders.<kind>`,
60
+ a `name` and a one-line `description`, in **every** bundled language's
61
+ file. `scaffold` (and `init`) render the folder's README and its row in
62
+ the vault's top-level README from them, and refuse a layout whose folder
63
+ kind has no string in the bound language, naming the kind and the
64
+ language; doctor warns about the same gap. Every folder kind needs one,
65
+ with or without a command (`diagram` too). Keep the description to 160
66
+ characters with no `|`: the SessionStart skeleton shows it as the
67
+ folder's Purpose cell. Machine tokens such as `stories/` stay as they are.
68
+
59
69
  If the kind introduces **new section headings or inline keywords** that
60
70
  deterministic checks must recognize (doctor, reconcile, story-section),
61
71
  register a form per bundled language (en, ru, es, de, fr, zh) in
@@ -108,7 +118,11 @@ Frontmatter keys **and their values** stay English (`status: planned` is
108
118
  machine-read; only prose and table labels get translated). Then register the
109
119
  language's heading/keyword/index-column forms in `scaffold/headings.json`, and
110
120
  add the locale to `LOCALES` in `tests/locales.test.mjs` so the suite actually
111
- runs over it. `templates/<lang>/strings.json` localizes the statusline only.
121
+ runs over it. `templates/<lang>/strings.json` localizes the statusline and the
122
+ folder names and descriptions `scaffold` writes into the READMEs
123
+ (`folders.<kind>`, one per kind the layout declares — touch point 6 above),
124
+ and `vault-readme.md.tmpl` is the vault's top-level README. There is no English
125
+ fallback for either: a language that lacks one is refused by `scaffold`.
112
126
 
113
127
  Skipping the registry does not produce one clean error — it degrades *unevenly*,
114
128
  which is why the spec exists: an unregistered index header raises a doctor