@theglitchking/persistent-planning 3.1.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.documentation/INDEX.md +15 -7
- package/.documentation/REGISTRY.md +2 -2
- package/.documentation/agents/INDEX.md +2 -2
- package/.documentation/agents/REGISTRY.md +2 -2
- package/.documentation/api/INDEX.md +2 -2
- package/.documentation/api/REGISTRY.md +2 -2
- package/.documentation/architecture/INDEX.md +5 -3
- package/.documentation/architecture/REGISTRY.md +8 -4
- package/.documentation/architecture/lg-mode.md +16 -0
- package/.documentation/architecture/lg-plan-artifact-lifecycle.md +104 -0
- package/.documentation/architecture/skill-linking-and-reclaim.md +84 -0
- package/.documentation/backups/INDEX.md +2 -2
- package/.documentation/backups/REGISTRY.md +2 -2
- package/.documentation/database/INDEX.md +2 -2
- package/.documentation/database/REGISTRY.md +2 -2
- package/.documentation/devops/INDEX.md +2 -2
- package/.documentation/devops/REGISTRY.md +2 -2
- package/.documentation/features/INDEX.md +2 -2
- package/.documentation/features/REGISTRY.md +2 -2
- package/.documentation/plans/INDEX.md +2 -2
- package/.documentation/plans/REGISTRY.md +2 -2
- package/.documentation/procedures/INDEX.md +4 -3
- package/.documentation/procedures/REGISTRY.md +6 -4
- package/.documentation/procedures/plan-completion-and-archive.md +34 -0
- package/.documentation/procedures/plugin-update-delivery.md +106 -0
- package/.documentation/quickstart/INDEX.md +2 -2
- package/.documentation/quickstart/REGISTRY.md +2 -2
- package/.documentation/reference/INDEX.md +10 -3
- package/.documentation/reference/REGISTRY.md +8 -4
- package/.documentation/reference/mandatory-frontmatter.md +71 -0
- package/.documentation/reference/skill-version-marker.md +70 -0
- package/.documentation/security/INDEX.md +2 -2
- package/.documentation/security/REGISTRY.md +2 -2
- package/.documentation/standards/INDEX.md +2 -2
- package/.documentation/standards/REGISTRY.md +2 -2
- package/.documentation/standards/mandatory-closing-phases.md +21 -1
- package/.documentation/testing/INDEX.md +2 -2
- package/.documentation/testing/REGISTRY.md +2 -2
- package/.documentation/testing/test-suite.md +38 -0
- package/.documentation/troubleshooting/INDEX.md +8 -8
- package/.documentation/troubleshooting/REGISTRY.md +20 -5
- package/.documentation/troubleshooting/plan-never-reads-complete.md +109 -0
- package/.documentation/troubleshooting/stale-skill-dir-drift.md +115 -0
- package/.documentation/workflows/INDEX.md +2 -2
- package/.documentation/workflows/REGISTRY.md +2 -2
- package/CHANGELOG.md +176 -0
- package/bin/persistent-planning.js +56 -6
- package/hooks/session-start.js +157 -15
- package/package.json +1 -1
- package/scripts/archive-plan.sh +3 -6
- package/scripts/init-atom.sh +7 -0
- package/scripts/init-phase.sh +58 -6
- package/scripts/init-planning.sh +18 -6
- package/scripts/init-task.sh +7 -0
- package/scripts/lib/planning.sh +122 -0
- package/scripts/lib/skill-link.js +177 -0
- package/scripts/link-skills.js +38 -0
- package/scripts/plan-status.sh +85 -10
- package/skills/persistent-planning/SKILL.md +5 -2
- package/templates/lg/phase.md +7 -4
- package/templates/lg/task.md +3 -2
|
@@ -3,7 +3,7 @@ title: Procedures Registry
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [procedures]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Quick reference for procedures documentation
|
|
9
9
|
---
|
|
@@ -16,23 +16,25 @@ purpose: Quick reference for procedures documentation
|
|
|
16
16
|
|
|
17
17
|
| Metric | Value |
|
|
18
18
|
|--------|-------|
|
|
19
|
-
| Documents |
|
|
19
|
+
| Documents | 2 |
|
|
20
20
|
| Category | features |
|
|
21
21
|
| Load Priority | 6/10 |
|
|
22
22
|
|
|
23
23
|
## Active Documents
|
|
24
24
|
|
|
25
25
|
- [Plan Completion and Archive](plan-completion-and-archive.md)
|
|
26
|
+
- [Plugin update delivery — what actually runs, and when](plugin-update-delivery.md)
|
|
26
27
|
|
|
27
28
|
## Recently Updated
|
|
28
29
|
|
|
30
|
+
- [Plugin update delivery — what actually runs, and when](plugin-update-delivery.md) - 2026-09-04
|
|
29
31
|
- [Plan Completion and Archive](plan-completion-and-archive.md) - 2026-08-31
|
|
30
32
|
|
|
31
33
|
## By Status
|
|
32
34
|
|
|
33
35
|
| Status | Count |
|
|
34
36
|
|--------|-------|
|
|
35
|
-
| active |
|
|
37
|
+
| active | 2 |
|
|
36
38
|
| draft | 0 |
|
|
37
39
|
| deprecated | 0 |
|
|
38
40
|
| archived | 0 |
|
|
@@ -48,4 +50,4 @@ purpose: Quick reference for procedures documentation
|
|
|
48
50
|
|
|
49
51
|
---
|
|
50
52
|
|
|
51
|
-
*Last updated: 2026-
|
|
53
|
+
*Last updated: 2026-09-04*
|
|
@@ -149,3 +149,37 @@ untouched and the update check still works.
|
|
|
149
149
|
machine* got somewhere. Sharing it with every clone would grow the repository
|
|
150
150
|
with reasoning nobody reads. If a particular plan is worth keeping, promote its
|
|
151
151
|
findings into a real doc — which is what the mandatory documentation phase is for.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
## Completion also gates on mandatory tasks (3.3.0+)
|
|
155
|
+
|
|
156
|
+
"Every checkbox checked" is necessary but no longer sufficient. A plan containing any
|
|
157
|
+
task with `mandatory: true` whose `status:` is not `done` (or `archived`) reads
|
|
158
|
+
`in progress` however the boxes add up, and `archive-plan.sh` refuses it through the
|
|
159
|
+
same pre-flight — there is still exactly one implementation of the rule.
|
|
160
|
+
|
|
161
|
+
Plans with no `mandatory:` frontmatter are unaffected.
|
|
162
|
+
|
|
163
|
+
Symptoms and fixes: [Plan never reads complete](../troubleshooting/plan-never-reads-complete.md).
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
## What counts, and what does not (3.3.1+)
|
|
167
|
+
|
|
168
|
+
- **Checkboxes** are body content and are counted anywhere *except* inside a fenced code
|
|
169
|
+
block. A quoted example is documentation, not work. An unterminated fence swallows the
|
|
170
|
+
rest of the file — the safe direction, since ambiguous content is not counted as
|
|
171
|
+
outstanding.
|
|
172
|
+
- **`status:` and `mandatory:`** are frontmatter fields and are read *only* from the
|
|
173
|
+
leading `---` block. They are never matched in prose, tables or fenced examples, which
|
|
174
|
+
is stricter than fence-stripping alone.
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
## What is tracked (3.4.0+)
|
|
178
|
+
|
|
179
|
+
Active plans are committed; only `.planning/.archive/` is gitignored. v1.0.0 ignored the
|
|
180
|
+
whole `.planning/` tree, which contradicted this procedure, `CLAUDE.md`, and the archive
|
|
181
|
+
rationale itself — and in lg mode, chosen because a team exists, it guaranteed no
|
|
182
|
+
teammate ever received the plans.
|
|
183
|
+
|
|
184
|
+
Repos carrying the old blanket line keep it: the init scripts warn once and never rewrite
|
|
185
|
+
a user's `.gitignore`. Replace `.planning/` with `.planning/.archive/` to start sharing.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin update delivery — what actually runs, and when
|
|
3
|
+
tier: guide
|
|
4
|
+
domains:
|
|
5
|
+
- procedures
|
|
6
|
+
audience:
|
|
7
|
+
- developers
|
|
8
|
+
tags:
|
|
9
|
+
- migration
|
|
10
|
+
status: active
|
|
11
|
+
last_updated: '2026-09-04'
|
|
12
|
+
version: 1.0.0
|
|
13
|
+
purpose: What actually executes on each of the two distribution paths, why a marketplace
|
|
14
|
+
install never runs npm postinstall, and how to ship a fix that repairs existing installs.
|
|
15
|
+
estimated_read_time: 3 minutes
|
|
16
|
+
word_count: 539
|
|
17
|
+
last_validated: '2026-09-04'
|
|
18
|
+
backlinks: []
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Plugin update delivery — what actually runs, and when
|
|
22
|
+
|
|
23
|
+
This package ships down two paths. They execute **different code at different times**,
|
|
24
|
+
and a fix delivered through the wrong one reaches nobody. Read this before shipping any
|
|
25
|
+
change that has to repair or migrate an existing install.
|
|
26
|
+
|
|
27
|
+
## The two paths
|
|
28
|
+
|
|
29
|
+
| | npm package | Claude Code marketplace plugin |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Installed at | `node_modules/@theglitchking/persistent-planning` | `~/.claude/plugins/cache/persistent-planning-marketplace/persistent-planning/<version>/` |
|
|
32
|
+
| Runs `postinstall`? | **yes** | **no** |
|
|
33
|
+
| `node_modules` present? | yes | **no — the plugin cache has none** |
|
|
34
|
+
| Runtime resolved from | local `node_modules` | shared `~/.claude/plugins/npm-cache/node_modules/` |
|
|
35
|
+
| Runs every session | SessionStart hook | SessionStart hook |
|
|
36
|
+
|
|
37
|
+
## The constraint
|
|
38
|
+
|
|
39
|
+
**A marketplace install never runs npm postinstall.**
|
|
40
|
+
|
|
41
|
+
So `runPostinstall()` — and therefore the skill linker, the reclaim, and the version
|
|
42
|
+
marker — never execute on a marketplace update. A repair wired only into postinstall
|
|
43
|
+
ships to npm consumers and silently misses every marketplace consumer.
|
|
44
|
+
|
|
45
|
+
That is not a corner case. In issue #10 the broken population *was* the marketplace
|
|
46
|
+
consumers, precisely because they were the ones postinstall could never reach.
|
|
47
|
+
|
|
48
|
+
`runPostinstall()` also returns `null` when `INIT_CWD` equals the package root
|
|
49
|
+
(dev-in-place), which is why this repo has no `.claude/skills/persistent-planning` of
|
|
50
|
+
its own.
|
|
51
|
+
|
|
52
|
+
## The rule
|
|
53
|
+
|
|
54
|
+
> **Anything that must reach an existing install goes through the SessionStart hook.**
|
|
55
|
+
> It is the only code that runs every session in both shapes.
|
|
56
|
+
|
|
57
|
+
`hooks/session-start.js` `autoRepair()` is the reference implementation:
|
|
58
|
+
|
|
59
|
+
- **Fast path first.** Two `lstat`s settle the common "nothing to do" case before any
|
|
60
|
+
work happens. Never make a healthy install pay.
|
|
61
|
+
- **Once per plugin version.** Stamped as `repairedSkillsForVersion` in
|
|
62
|
+
`.claude/persistent-planning.json`. Stamped *regardless of outcome*, so a repair that
|
|
63
|
+
cannot succeed does not retry every session; a later release moves the version and
|
|
64
|
+
gets one fresh attempt.
|
|
65
|
+
- **Policy-gated.** `auto` repairs, `nudge` warns only, `off` does nothing. A user who
|
|
66
|
+
turned updates off did not consent to filesystem mutation.
|
|
67
|
+
- **Spawned, not imported.** The migration runs in a child process with a timeout, so a
|
|
68
|
+
failure is contained.
|
|
69
|
+
- **Fails open.** Every path is wrapped. A broken migration must never cost someone
|
|
70
|
+
their session start.
|
|
71
|
+
- **Never let a dependency be fatal.** Load the runtime with `await import()` in a
|
|
72
|
+
try/catch. A static import makes an unresolvable dependency fatal for the whole hook,
|
|
73
|
+
including the repair — the delivery path must survive what it is delivering a fix for
|
|
74
|
+
(#18). Only the update check genuinely needs the runtime.
|
|
75
|
+
- **Stamp on success, never on failure.** Marking a version done after a failed attempt
|
|
76
|
+
turns a transient problem into a permanent one: the repair never runs again, even once
|
|
77
|
+
the cause is gone. Retrying costs one spawn per session while genuinely drifted.
|
|
78
|
+
- **One stdout write.** The runtime owns the single `SessionStart` JSON response and
|
|
79
|
+
exposes no append hook; a second response line is invalid. Merge into the existing
|
|
80
|
+
intercept.
|
|
81
|
+
|
|
82
|
+
## Release checklist addendum
|
|
83
|
+
|
|
84
|
+
The version appears in **three** places that must match — `package.json`,
|
|
85
|
+
`.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json` (both `metadata.version`
|
|
86
|
+
and the plugin entry). See `CLAUDE.md`.
|
|
87
|
+
|
|
88
|
+
Two more things to verify for a migration release:
|
|
89
|
+
|
|
90
|
+
1. **The `files` array actually ships the new code.** v3.0.0 shipped broken because
|
|
91
|
+
`scripts/` and `templates/` were missing from it. Check with `npm pack --dry-run` and
|
|
92
|
+
grep the listing for the files you added.
|
|
93
|
+
2. **Test from a marketplace-shaped fixture** — no `node_modules`, no postinstall — not
|
|
94
|
+
from `npm install`. A test that passes under `npm install` proves nothing about the
|
|
95
|
+
population that is actually broken. `tests/run.sh` builds exactly this fixture.
|
|
96
|
+
|
|
97
|
+
If a fix depends on a new `@theglitchking/claude-plugin-runtime`, it needs a runtime
|
|
98
|
+
publish, a dependency-range bump here, and a coordinated rollout — marketplace consumers
|
|
99
|
+
resolve the runtime from a shared cache, not a vendored copy. Preferring a change that
|
|
100
|
+
keeps the runtime unchanged is usually worth real effort; the issue #10 reclaim is
|
|
101
|
+
deliberately ordered *before* the runtime's linker for that reason.
|
|
102
|
+
|
|
103
|
+
## Related
|
|
104
|
+
|
|
105
|
+
- [Skill linking and reclaim](../architecture/skill-linking-and-reclaim.md)
|
|
106
|
+
- [Stale skill directory](../troubleshooting/stale-skill-dir-drift.md)
|
|
@@ -3,7 +3,7 @@ title: Quickstart Documentation Index
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [quickstart]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Complete listing of quickstart documentation
|
|
9
9
|
---
|
|
@@ -39,4 +39,4 @@ This domain covers: quickstart, quick-start, getting-started, setup, install, in
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
*Last updated: 2026-
|
|
42
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Quickstart Registry
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [quickstart]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Quick reference for quickstart documentation
|
|
9
9
|
---
|
|
@@ -48,4 +48,4 @@ purpose: Quick reference for quickstart documentation
|
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
|
-
*Last updated: 2026-
|
|
51
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Reference Documentation Index
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [reference]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Complete listing of reference documentation
|
|
9
9
|
---
|
|
@@ -14,7 +14,7 @@ purpose: Complete listing of reference documentation
|
|
|
14
14
|
|
|
15
15
|
## Overview
|
|
16
16
|
|
|
17
|
-
- **Total Documents:**
|
|
17
|
+
- **Total Documents:** 3
|
|
18
18
|
- **Domain:** `reference/`
|
|
19
19
|
- **Category:** development
|
|
20
20
|
- **Load Priority:** 7/10
|
|
@@ -27,6 +27,13 @@ purpose: Complete listing of reference documentation
|
|
|
27
27
|
|----------|--------|---------|-------|
|
|
28
28
|
| [workspace.json schema](workspace-json.md) | active | 2026-05-07 | 358 |
|
|
29
29
|
|
|
30
|
+
### References
|
|
31
|
+
|
|
32
|
+
| Document | Status | Updated | Words |
|
|
33
|
+
|----------|--------|---------|-------|
|
|
34
|
+
| [`mandatory:` task frontmatter](mandatory-frontmatter.md) | active | 2026-09-04 | 270 |
|
|
35
|
+
| [Skill version marker (`.version`)](skill-version-marker.md) | active | 2026-09-04 | 295 |
|
|
36
|
+
|
|
30
37
|
## Keywords
|
|
31
38
|
|
|
32
39
|
This domain covers: schema, frontmatter, workspace.json, field, enum, cli, flags, reference, contract
|
|
@@ -39,4 +46,4 @@ This domain covers: schema, frontmatter, workspace.json, field, enum, cli, flags
|
|
|
39
46
|
|
|
40
47
|
---
|
|
41
48
|
|
|
42
|
-
*Last updated: 2026-
|
|
49
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Reference Registry
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [reference]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Quick reference for reference documentation
|
|
9
9
|
---
|
|
@@ -16,23 +16,27 @@ purpose: Quick reference for reference documentation
|
|
|
16
16
|
|
|
17
17
|
| Metric | Value |
|
|
18
18
|
|--------|-------|
|
|
19
|
-
| Documents |
|
|
19
|
+
| Documents | 3 |
|
|
20
20
|
| Category | development |
|
|
21
21
|
| Load Priority | 7/10 |
|
|
22
22
|
|
|
23
23
|
## Active Documents
|
|
24
24
|
|
|
25
|
+
- [`mandatory:` task frontmatter](mandatory-frontmatter.md)
|
|
26
|
+
- [Skill version marker (`.version`)](skill-version-marker.md)
|
|
25
27
|
- [workspace.json schema](workspace-json.md)
|
|
26
28
|
|
|
27
29
|
## Recently Updated
|
|
28
30
|
|
|
31
|
+
- [`mandatory:` task frontmatter](mandatory-frontmatter.md) - 2026-09-04
|
|
32
|
+
- [Skill version marker (`.version`)](skill-version-marker.md) - 2026-09-04
|
|
29
33
|
- [workspace.json schema](workspace-json.md) - 2026-05-07
|
|
30
34
|
|
|
31
35
|
## By Status
|
|
32
36
|
|
|
33
37
|
| Status | Count |
|
|
34
38
|
|--------|-------|
|
|
35
|
-
| active |
|
|
39
|
+
| active | 3 |
|
|
36
40
|
| draft | 0 |
|
|
37
41
|
| deprecated | 0 |
|
|
38
42
|
| archived | 0 |
|
|
@@ -48,4 +52,4 @@ purpose: Quick reference for reference documentation
|
|
|
48
52
|
|
|
49
53
|
---
|
|
50
54
|
|
|
51
|
-
*Last updated: 2026-
|
|
55
|
+
*Last updated: 2026-09-04*
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: '`mandatory:` task frontmatter'
|
|
3
|
+
tier: reference
|
|
4
|
+
domains:
|
|
5
|
+
- reference
|
|
6
|
+
audience:
|
|
7
|
+
- developers
|
|
8
|
+
tags: []
|
|
9
|
+
status: active
|
|
10
|
+
last_updated: '2026-09-04'
|
|
11
|
+
version: 1.0.0
|
|
12
|
+
purpose: >-
|
|
13
|
+
Contract for the mandatory: task frontmatter field — who sets it, what reads it, and
|
|
14
|
+
why absent must mean no enforcement for legacy plans.
|
|
15
|
+
estimated_read_time: 2 minutes
|
|
16
|
+
word_count: 270
|
|
17
|
+
last_validated: '2026-09-04'
|
|
18
|
+
backlinks: []
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# `mandatory:` task frontmatter
|
|
22
|
+
|
|
23
|
+
A boolean in an lg task's frontmatter marking it as one of the phase's mandatory
|
|
24
|
+
closing tasks. It is what turns "a phase cannot be done until both closers are done"
|
|
25
|
+
from a sentence in a template into something `plan-status.sh` enforces.
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
---
|
|
29
|
+
title: Validate success through comprehensive testing
|
|
30
|
+
plan_kind: task
|
|
31
|
+
status: draft
|
|
32
|
+
depends_on: []
|
|
33
|
+
parallelizable: false
|
|
34
|
+
mandatory: true
|
|
35
|
+
---
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Contract
|
|
39
|
+
|
|
40
|
+
| | |
|
|
41
|
+
|---|---|
|
|
42
|
+
| **Lives in** | `<phase>/<task>/task.md` frontmatter |
|
|
43
|
+
| **Default** | `false` — `templates/lg/task.md` ships it explicitly |
|
|
44
|
+
| **Set to `true` by** | `init-phase.sh`, on the two scaffolded closers only |
|
|
45
|
+
| **Read by** | `scripts/plan-status.sh` (`unfinished_mandatory()`) |
|
|
46
|
+
| **Effect** | a plan with any `mandatory: true` task whose `status` is neither `done` nor `archived` cannot read `COMPLETE`, however the checkboxes add up |
|
|
47
|
+
| **Absent means** | no enforcement — legacy behavior, exactly as before |
|
|
48
|
+
|
|
49
|
+
## Why absent must mean "no enforcement"
|
|
50
|
+
|
|
51
|
+
Plans created before 3.3.0 have no closer directories and no `mandatory:` frontmatter.
|
|
52
|
+
Treating absence as `true`, or inferring closers by title, would retroactively reopen
|
|
53
|
+
finished plans — worse than the bug this field fixes. The gate is strictly additive and
|
|
54
|
+
the test suite asserts a legacy plan still reads `COMPLETE`.
|
|
55
|
+
|
|
56
|
+
## Where it is enforced — once
|
|
57
|
+
|
|
58
|
+
`plan-status.sh` is the single implementation of "is this plan done?" per `CLAUDE.md`.
|
|
59
|
+
`archive-plan.sh` inherits the gate through its existing pre-flight call rather than
|
|
60
|
+
carrying a second copy of the rule, and `--complete` / `--nudge` — which the
|
|
61
|
+
SessionStart hook and `archive-plan.sh` consume — honour it too.
|
|
62
|
+
|
|
63
|
+
Ticking a checkbox is **not** sufficient for a mandatory task. The task's own `status:`
|
|
64
|
+
must be `done`. That distinction is the whole point: a closer that was ticked but never
|
|
65
|
+
performed is exactly the failure this guards.
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- [lg plan artifact lifecycle](../architecture/lg-plan-artifact-lifecycle.md)
|
|
70
|
+
- [Plan completion and archive](../procedures/plan-completion-and-archive.md)
|
|
71
|
+
- [Plan never reads complete](../troubleshooting/plan-never-reads-complete.md)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Skill version marker (`.version`)
|
|
3
|
+
tier: reference
|
|
4
|
+
domains:
|
|
5
|
+
- reference
|
|
6
|
+
audience:
|
|
7
|
+
- developers
|
|
8
|
+
tags: []
|
|
9
|
+
status: active
|
|
10
|
+
last_updated: '2026-09-04'
|
|
11
|
+
version: 1.0.0
|
|
12
|
+
purpose: >-
|
|
13
|
+
Contract for the .version marker written beside SKILL.md — who writes it, when it
|
|
14
|
+
is deliberately not written, and why it is the secondary drift signal.
|
|
15
|
+
estimated_read_time: 2 minutes
|
|
16
|
+
word_count: 295
|
|
17
|
+
last_validated: '2026-09-04'
|
|
18
|
+
backlinks: []
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# Skill version marker (`.version`)
|
|
22
|
+
|
|
23
|
+
A one-line file beside `SKILL.md` recording which package version a linked skill came
|
|
24
|
+
from. Written by `scripts/link-skills.js`, read by `scripts/lib/skill-link.js`.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
.claude/skills/persistent-planning/.version -> "3.2.0\n"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Contract
|
|
31
|
+
|
|
32
|
+
| | |
|
|
33
|
+
|---|---|
|
|
34
|
+
| **Path** | `.claude/skills/<skill-name>/.version` |
|
|
35
|
+
| **Contents** | the package's `version`, plus a trailing newline |
|
|
36
|
+
| **Written by** | `writeVersionMarkers()`, after the linker runs |
|
|
37
|
+
| **Read by** | `readSkillVersion(consumerRoot, name)` — returns the string, or `null` |
|
|
38
|
+
| **Written when** | the skill resolves to `symlink-ok` |
|
|
39
|
+
| **Never written when** | the destination is a real directory |
|
|
40
|
+
| **Absent means** | unknown — never "current" |
|
|
41
|
+
|
|
42
|
+
## Why only healthy symlinks are stamped
|
|
43
|
+
|
|
44
|
+
Stamping a real directory would write "3.2.0" into a frozen pre-3.1.0 copy and mark
|
|
45
|
+
stale code as current — defeating the check it exists to support. A real directory is
|
|
46
|
+
left unstamped precisely so it reads as unknown.
|
|
47
|
+
|
|
48
|
+
Because a healthy skill dir is a symlink into the package, the marker written through
|
|
49
|
+
it lands in the package and is correct for free.
|
|
50
|
+
|
|
51
|
+
## Why not `package.json`
|
|
52
|
+
|
|
53
|
+
A `package.json` inside a skill directory invites npm to treat that directory as a
|
|
54
|
+
package and changes module resolution underneath it. A plain `.version` file cannot.
|
|
55
|
+
`skills/*/.version` is gitignored so a local install cannot commit a stray marker.
|
|
56
|
+
|
|
57
|
+
## This is the secondary signal
|
|
58
|
+
|
|
59
|
+
The **primary** drift signal is structural: is `.claude/skills/<name>` a symlink into
|
|
60
|
+
this package? A real directory is always drift, because nothing in the current system
|
|
61
|
+
creates one. That check needs no marker and cannot itself go stale.
|
|
62
|
+
|
|
63
|
+
The marker answers the follow-up question — *how far behind is it* — and is the only
|
|
64
|
+
signal available on install shapes where a symlink is impossible (Windows without
|
|
65
|
+
developer mode, some CI checkouts). Treat a missing marker as unknown, never as fine.
|
|
66
|
+
|
|
67
|
+
## Related
|
|
68
|
+
|
|
69
|
+
- [Skill linking and reclaim](../architecture/skill-linking-and-reclaim.md)
|
|
70
|
+
- [Stale skill directory](../troubleshooting/stale-skill-dir-drift.md)
|
|
@@ -3,7 +3,7 @@ title: Security Documentation Index
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [security]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Complete listing of security documentation
|
|
9
9
|
---
|
|
@@ -40,4 +40,4 @@ This domain covers: security, auth, authentication, authorization, oauth, jwt, k
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
*Last updated: 2026-
|
|
43
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Security Registry
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [security]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Quick reference for security documentation
|
|
9
9
|
---
|
|
@@ -35,4 +35,4 @@ purpose: Quick reference for security documentation
|
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
-
*Last updated: 2026-
|
|
38
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Standards Documentation Index
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [standards]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Complete listing of standards documentation
|
|
9
9
|
---
|
|
@@ -40,4 +40,4 @@ This domain covers: standard, standards, convention, conventions, pattern, patte
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
*Last updated: 2026-
|
|
43
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Standards Registry
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [standards]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Quick reference for standards documentation
|
|
9
9
|
---
|
|
@@ -50,4 +50,4 @@ purpose: Quick reference for standards documentation
|
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
53
|
-
*Last updated: 2026-
|
|
53
|
+
*Last updated: 2026-09-04*
|
|
@@ -25,7 +25,7 @@ Every plan this plugin creates ends with the same two units of work, in the same
|
|
|
25
25
|
order, no exceptions:
|
|
26
26
|
|
|
27
27
|
1. **Validate success through comprehensive testing**
|
|
28
|
-
2. **Documentation pass — create / update / deprecate docs**
|
|
28
|
+
2. **Documentation pass — create / update / deprecate as many docs as needed to capture what was done, where it lives, how to troubleshoot it**
|
|
29
29
|
|
|
30
30
|
They are seeded into the templates so an agent never has to remember them, and
|
|
31
31
|
they are marked `MANDATORY` in the artifact itself so an agent re-reading the
|
|
@@ -123,3 +123,23 @@ npm test
|
|
|
123
123
|
| Closing phases are no longer last | Work appended below them | Move the new phases above the pair and renumber |
|
|
124
124
|
| `npm test` fails on "documentation phase is last" | A template edit added a checkbox after the pair, or reworded the pair | Restore the ordering in `scripts/init-planning.sh` / `templates/lg/phase.md` |
|
|
125
125
|
| Phase marked `done` with closing tasks unchecked | Skipped the gate | Not done — finish both, then mark the phase |
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## How they are enforced (3.3.0+)
|
|
129
|
+
|
|
130
|
+
In lg mode the two closers are no longer only checkbox lines. `init-phase.sh` scaffolds
|
|
131
|
+
each as a real task directory — `task.md` with `mandatory: true`, `notes.md`, `atoms/`,
|
|
132
|
+
and seeded atoms — so they are addressable artifacts like every other task.
|
|
133
|
+
|
|
134
|
+
Two mechanisms keep the rule true rather than advisory:
|
|
135
|
+
|
|
136
|
+
- **Ordering by construction.** `init-task.sh` inserts every new task *above* the first
|
|
137
|
+
MANDATORY entry, so the closers cannot be pushed out of last place by adding work.
|
|
138
|
+
- **Completion gated on status.** `plan-status.sh` refuses `COMPLETE` while any
|
|
139
|
+
`mandatory: true` task's own `status:` is not `done`. Ticking its checkbox is not
|
|
140
|
+
enough — a closer that was ticked but never performed is exactly the failure being
|
|
141
|
+
guarded.
|
|
142
|
+
|
|
143
|
+
Legacy plans without `mandatory:` frontmatter keep their previous behavior; the gate is
|
|
144
|
+
strictly additive. See [`mandatory:` frontmatter](../reference/mandatory-frontmatter.md)
|
|
145
|
+
and [lg plan artifact lifecycle](../architecture/lg-plan-artifact-lifecycle.md).
|
|
@@ -3,7 +3,7 @@ title: Testing Documentation Index
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [testing]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Complete listing of testing documentation
|
|
9
9
|
---
|
|
@@ -39,4 +39,4 @@ This domain covers: test, testing, tests, unit, unit-test, integration, integrat
|
|
|
39
39
|
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
*Last updated: 2026-
|
|
42
|
+
*Last updated: 2026-09-04*
|
|
@@ -3,7 +3,7 @@ title: Testing Registry
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [testing]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Quick reference for testing documentation
|
|
9
9
|
---
|
|
@@ -48,4 +48,4 @@ purpose: Quick reference for testing documentation
|
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
|
-
*Last updated: 2026-
|
|
51
|
+
*Last updated: 2026-09-04*
|
|
@@ -86,3 +86,41 @@ never failed is not known to test anything.
|
|
|
86
86
|
| Tests pass locally, lg mode broken for installed users | `templates/` or `scripts/` missing from the `files` array in `package.json` | Add them, verify with `npm pack` before publishing |
|
|
87
87
|
|
|
88
88
|
That last row is not hypothetical — it is exactly how v3.0.0 shipped broken.
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## The marketplace-shaped fixture
|
|
92
|
+
|
|
93
|
+
The skill-reclaim tests (issue #10) build a consumer workspace with **no
|
|
94
|
+
`node_modules`**, mirroring a Claude Code marketplace install — the shape that never
|
|
95
|
+
runs npm postinstall, and the shape that was actually broken. Driving the SessionStart
|
|
96
|
+
hook against it proves a repair lands with no `npm install` anywhere in the path.
|
|
97
|
+
|
|
98
|
+
A test that only passes under `npm install` proves nothing about that population. See
|
|
99
|
+
[Plugin update delivery](../procedures/plugin-update-delivery.md).
|
|
100
|
+
|
|
101
|
+
## Assert by diff, not by feature-grep
|
|
102
|
+
|
|
103
|
+
When checking that generated output matches a template, `diff` it. During triage of
|
|
104
|
+
issue #10 a keyword count (`phases: 6 | closers: 2`) reported two known-stale copies as
|
|
105
|
+
healthy; only `diff` exposed the 23-line gap, including an entirely missing
|
|
106
|
+
`## On Completion` block.
|
|
107
|
+
|
|
108
|
+
Likewise, assertions against the SessionStart payload parse it as JSON rather than
|
|
109
|
+
string-matching. The failure being guarded is an invalid second response line — a
|
|
110
|
+
substring check would pass on malformed output.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
## Assert after mutation, not at render
|
|
114
|
+
|
|
115
|
+
The ordering rule for the mandatory closers went unenforced for a long time while a
|
|
116
|
+
test claimed to cover it. That test asserted the order of two checkbox lines in a
|
|
117
|
+
*freshly rendered template* — which can never be wrong, because nothing had happened to
|
|
118
|
+
it yet.
|
|
119
|
+
|
|
120
|
+
Assertions about an invariant must mutate the plan first: create a phase, add several
|
|
121
|
+
tasks, then check the closers are still last. The issue #12 block does this throughout,
|
|
122
|
+
including against a hand-reordered, partially-checked, annotated list.
|
|
123
|
+
|
|
124
|
+
The same instinct applies elsewhere in this suite: verify generated output by `diff`
|
|
125
|
+
rather than keyword count, and parse the SessionStart payload as JSON rather than
|
|
126
|
+
string-matching it.
|
|
@@ -3,7 +3,7 @@ title: Troubleshooting Documentation Index
|
|
|
3
3
|
tier: reference
|
|
4
4
|
domains: [troubleshooting]
|
|
5
5
|
status: active
|
|
6
|
-
last_updated: '2026-
|
|
6
|
+
last_updated: '2026-09-04'
|
|
7
7
|
version: '1.0.0'
|
|
8
8
|
purpose: Complete listing of troubleshooting documentation
|
|
9
9
|
---
|
|
@@ -14,20 +14,20 @@ purpose: Complete listing of troubleshooting documentation
|
|
|
14
14
|
|
|
15
15
|
## Overview
|
|
16
16
|
|
|
17
|
-
- **Total Documents:**
|
|
17
|
+
- **Total Documents:** 2
|
|
18
18
|
- **Domain:** `troubleshooting/`
|
|
19
19
|
- **Category:** advanced
|
|
20
20
|
- **Load Priority:** 6/10
|
|
21
21
|
|
|
22
22
|
## Documents
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
### Guides
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
| Document | Status | Updated | Words |
|
|
27
|
+
|----------|--------|---------|-------|
|
|
28
|
+
| [A plan won't read COMPLETE](plan-never-reads-complete.md) | active | 2026-09-04 | 264 |
|
|
29
|
+
| [Stale skill directory — commands run frozen code](stale-skill-dir-drift.md) | active | 2026-09-04 | 403 |
|
|
27
30
|
|
|
28
|
-
1. Create a markdown file in this directory
|
|
29
|
-
2. Add YAML frontmatter with required metadata
|
|
30
|
-
3. Run `npx hit-em-with-the-docs integrate <file>`
|
|
31
31
|
## Keywords
|
|
32
32
|
|
|
33
33
|
This domain covers: troubleshooting, troubleshoot, debug, debugging, issue, issues, problem, problems, error, errors
|
|
@@ -40,4 +40,4 @@ This domain covers: troubleshooting, troubleshoot, debug, debugging, issue, issu
|
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
-
*Last updated: 2026-
|
|
43
|
+
*Last updated: 2026-09-04*
|