@zalom/plastic 1.0.3 → 1.1.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/PLASTIC-reference.md +11 -11
- package/PLASTIC.md +11 -9
- package/README.md +48 -1
- package/agents/plastic-enforcer.md +8 -5
- package/agents/plastic-future-intent-researcher.md +1 -1
- package/agents/plastic-intent-curator.md +9 -10
- package/agents/plastic-spec-specialist.md +9 -6
- package/bin/plastic.js +2 -2
- package/hooks/check-update +1 -1
- package/hooks/continue +1 -1
- package/package.json +1 -1
- package/scripts/dashboard.rb +29 -24
- package/scripts/doctor.rb +188 -9
- package/scripts/end-intent +330 -0
- package/scripts/hook-code-gate +1 -1
- package/scripts/hook-continue +2 -2
- package/scripts/hook-create-gate +2 -2
- package/scripts/hook-session-start +1 -1
- package/scripts/install.rb +2 -1
- package/scripts/lib/bridge.rb +116 -3
- package/scripts/lib/dashboard_banner.rb +8 -9
- package/scripts/lib/installer_core.rb +17 -8
- package/scripts/lib/legacy_bookend_amnesty.rb +35 -0
- package/scripts/lib/release_guard.rb +62 -0
- package/scripts/lib/roadmap_queue.rb +285 -0
- package/scripts/lib/roadmap_savepoint.rb +213 -0
- package/scripts/lib/store_provisioning.rb +1 -1
- package/scripts/lib/worktree.rb +21 -0
- package/scripts/new-intent +2 -1
- package/scripts/read-config +3 -3
- package/scripts/roadmap-next +44 -0
- package/scripts/roadmap-savepoint +64 -0
- package/scripts/{versions.rb → rollback.rb} +33 -41
- package/scripts/update.rb +1 -1
- package/skills/_active-intent-gate.md +1 -1
- package/skills/_decision-tables.md +50 -0
- package/skills/auto/SKILL.md +69 -68
- package/skills/auto/evals/evals.json +4 -4
- package/skills/auto/references/agent-architecture.md +2 -2
- package/skills/continuing/SKILL.md +23 -130
- package/skills/continuing/evals/evals.json +26 -80
- package/skills/dashboard/SKILL.md +18 -15
- package/skills/dashboard/references/classification.md +3 -3
- package/skills/dashboard/templates/dashboard-global.md +8 -23
- package/skills/dashboard/templates/dashboard-project.md +7 -26
- package/skills/doctor/SKILL.md +3 -3
- package/skills/install/SKILL.md +10 -10
- package/skills/{brainstorming → intent-brainstorming}/SKILL.md +43 -45
- package/skills/intent-brainstorming/evals/evals.json +67 -0
- package/skills/{brainstorming → intent-brainstorming}/references/design-principles.md +12 -17
- package/skills/intent-continuing/SKILL.md +99 -0
- package/skills/intent-continuing/evals/evals.json +145 -0
- package/skills/intent-continuing/references/context-management.md +28 -0
- package/skills/{creating-intent → intent-creating}/SKILL.md +3 -3
- package/skills/{creating-intent → intent-creating}/evals/evals.json +1 -1
- package/skills/{intent-discovery → intent-discovering}/SKILL.md +1 -1
- package/skills/intent-ending/SKILL.md +151 -0
- package/skills/intent-ending/evals/evals.json +74 -0
- package/skills/{executing-plan → intent-executing}/SKILL.md +75 -15
- package/skills/intent-executing/evals/evals.json +66 -0
- package/skills/{brainstorming-grill-me → intent-grilling}/SKILL.md +4 -4
- package/skills/{linking-intents → intent-linking}/SKILL.md +1 -1
- package/skills/{linking-intents → intent-linking}/evals/evals.json +1 -1
- package/skills/{lock → intent-locking}/SKILL.md +1 -1
- package/skills/{writing-plans → intent-planning}/SKILL.md +48 -20
- package/skills/intent-planning/evals/evals.json +66 -0
- package/skills/{writing-plans → intent-planning}/references/plan-format.md +31 -7
- package/skills/{research → intent-researching}/SKILL.md +2 -2
- package/skills/{research → intent-researching}/evals/evals.json +1 -1
- package/skills/{savepoint → intent-savepoint}/SKILL.md +13 -1
- package/skills/intent-speccing/SKILL.md +69 -0
- package/skills/intent-speccing/evals/evals.json +126 -0
- package/skills/intent-speccing/references/per-section-fill-rules.md +92 -0
- package/skills/intent-speccing/references/self-verify-checklist.md +38 -0
- package/skills/intent-starting/SKILL.md +2 -2
- package/skills/intent-starting/evals/evals.json +2 -2
- package/skills/project-continuing/SKILL.md +104 -0
- package/skills/project-continuing/evals/evals.json +100 -0
- package/skills/project-continuing/references/board-fill.md +33 -0
- package/skills/{creating-project → project-creating}/SKILL.md +2 -2
- package/skills/releasing/SKILL.md +66 -14
- package/skills/releasing/references/release-lines.md +105 -0
- package/skills/roadmap/SKILL.md +7 -1
- package/skills/roadmap/references/file-format.md +30 -1
- package/skills/roadmap/references/operations.md +26 -6
- package/skills/roadmap-continuing/SKILL.md +85 -0
- package/skills/roadmap-continuing/evals/evals.json +82 -0
- package/skills/roadmap-continuing/references/liveness-ranking.md +56 -0
- package/skills/{versions → rollback}/SKILL.md +30 -20
- package/skills/{creating-skills → skill-creating}/SKILL.md +2 -2
- package/skills/{creating-skills → skill-creating}/evals/evals.json +5 -5
- package/skills/{creating-skills → skill-creating}/references/progressive-disclosure.md +2 -2
- package/skills/{evaluating-skills → skill-evaluating}/SKILL.md +1 -1
- package/skills/{evaluating-skills → skill-evaluating}/evals/evals.json +3 -3
- package/skills/{intent-curator → store-curating}/SKILL.md +6 -7
- package/skills/{intent-curator → store-curating}/evals/evals.json +1 -1
- package/skills/{managing-index → store-indexing}/SKILL.md +6 -7
- package/skills/{managing-index → store-indexing}/evals/evals.json +1 -1
- package/skills/{add-project-store → store-provisioning}/SKILL.md +2 -2
- package/skills/tutorial/SKILL.md +65 -0
- package/skills/tutorial/evals/evals.json +186 -0
- package/skills/tutorial/references/track-1-guided.md +123 -0
- package/skills/tutorial/references/track-2-auto.md +95 -0
- package/skills/tutorial/references/track-3-projects-and-roadmaps.md +110 -0
- package/skills/uninstall/SKILL.md +2 -2
- package/skills/update/SKILL.md +3 -3
- package/templates/agents.md +7 -7
- package/templates/config.yml +2 -1
- package/templates/index.md +4 -1
- package/skills/brainstorming/evals/evals.json +0 -22
- package/skills/savepoint/references/context-management.md +0 -32
- /package/skills/{creating-intent → intent-creating}/references/lifecycle.md +0 -0
- /package/skills/{creating-intent → intent-creating}/references/wikilinks.md +0 -0
- /package/skills/{executing-plan → intent-executing}/code-quality-reviewer-prompt.md +0 -0
- /package/skills/{executing-plan → intent-executing}/implementer-prompt.md +0 -0
- /package/skills/{executing-plan → intent-executing}/spec-reviewer-prompt.md +0 -0
- /package/skills/{linking-intents → intent-linking}/references/zettelkasten.md +0 -0
- /package/skills/{continuing → intent-savepoint}/references/context-management.md +0 -0
- /package/skills/{creating-project → project-creating}/references/hubs-projects.md +0 -0
- /package/skills/{creating-project → project-creating}/references/project-scaffolding.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/agents.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/evals.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/hooks.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/scripts.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/skills.md +0 -0
- /package/skills/{creating-skills → skill-creating}/scripts/scaffold.rb +0 -0
- /package/skills/{evaluating-skills → skill-evaluating}/assets/eval-template.json +0 -0
- /package/skills/{evaluating-skills → skill-evaluating}/references/convention-checks.md +0 -0
- /package/skills/{evaluating-skills → skill-evaluating}/references/eval-methodology.md +0 -0
- /package/skills/{managing-index → store-indexing}/references/zettelkasten-linking.md +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: plastic-creating
|
|
2
|
+
name: plastic-project-creating
|
|
3
3
|
description: >-
|
|
4
4
|
Create a new project from an implementation intent. Sets up project directory,
|
|
5
5
|
git init, AGENTS.md with founding intent decisions, plastic-install --local,
|
|
@@ -79,7 +79,7 @@ writes `INDEX.md` and `project.yml` only if missing. It is idempotent, so it is
|
|
|
79
79
|
safe even when the tactical mirror in step 5 already created the store directory.
|
|
80
80
|
Do not create the store with an inline `mkdir`; the provisioner is the only place
|
|
81
81
|
a store is made. For a project that is already registered but store-less, use the
|
|
82
|
-
`plastic-
|
|
82
|
+
`plastic-store-provisioning` skill instead.
|
|
83
83
|
|
|
84
84
|
### 8. Mark Global Intent(s) Completed
|
|
85
85
|
|
|
@@ -15,6 +15,7 @@ Project configuration drives the workflow - no hardcoded assumptions.
|
|
|
15
15
|
- [ ] All tests pass (or verification skipped per config)
|
|
16
16
|
- [ ] Merge feature branch to main
|
|
17
17
|
- [ ] Bump version in configured version files
|
|
18
|
+
- [ ] Stable-cut guard passes (version files agree, no pre-release suffix; stable/latest cuts only)
|
|
18
19
|
- [ ] Commit version bump
|
|
19
20
|
- [ ] Create annotated tag
|
|
20
21
|
- [ ] Push to remote with tags
|
|
@@ -94,6 +95,25 @@ the full rationale and the already-merged-by-hand no-op case, read
|
|
|
94
95
|
|
|
95
96
|
### 4. Bump Version
|
|
96
97
|
|
|
98
|
+
**Stable-cut guard.** Before touching any version file for a stable (no pre-release suffix,
|
|
99
|
+
`latest`) cut, run the guard in `scripts/lib/release_guard.rb`:
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
require "./scripts/lib/release_guard"
|
|
103
|
+
result = ReleaseGuard.check(
|
|
104
|
+
package_json: "package.json",
|
|
105
|
+
plugin_json: ".claude-plugin/plugin.json",
|
|
106
|
+
marketplace_json: ".claude-plugin/marketplace.json",
|
|
107
|
+
stable: true
|
|
108
|
+
)
|
|
109
|
+
raise "release guard failed: #{result.mismatches} #{result.prerelease_suffix}" unless result.ok?
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If it reports a mismatch or a pre-release-suffix violation, stop and resolve it before bumping
|
|
113
|
+
any file. For a beta or alpha cut, pass `stable: false`; only version-file agreement is checked,
|
|
114
|
+
a pre-release suffix is expected. Read `references/release-lines.md` for the stable-line
|
|
115
|
+
guarantees this guard protects.
|
|
116
|
+
|
|
97
117
|
Determine which files to update from project.yml:
|
|
98
118
|
|
|
99
119
|
- If `release.version_files` is set: update ALL listed files (they must stay in sync).
|
|
@@ -214,26 +234,30 @@ gh release edit <tag-name> --latest
|
|
|
214
234
|
|
|
215
235
|
### 8. Complete Active Intent
|
|
216
236
|
|
|
217
|
-
A release IS a delivery. The active intent that drove this work must be completed as part of the release process. This is NOT optional.
|
|
237
|
+
A release IS a delivery. The active intent that drove this work must be completed as part of the release process. This is NOT optional. The mechanical close (outcome/INDEX/savepoint/commit) is `plastic-intent-ending`'s job, not this skill's: run its backing script rather than restating that prose here.
|
|
218
238
|
|
|
219
|
-
1. Read `~/.plastic/INDEX.md`
|
|
239
|
+
1. Read `~/.plastic/INDEX.md` (or the project's INDEX.md) - find active intent(s) related to this release.
|
|
220
240
|
2. For each active intent being delivered:
|
|
221
|
-
a. Write `outcome.md`
|
|
222
|
-
b.
|
|
223
|
-
c.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
241
|
+
a. Write a real `outcome.md` (never leave the scaffold placeholder), `disposition: delivered`, referencing the release tag.
|
|
242
|
+
b. Update `## Insights` with final observations.
|
|
243
|
+
c. Run the mechanical close (steps 1-4 of `plastic-intent-ending`): this stamps the intent file's `## Outcome` summary, moves the INDEX.md line to `## Completed` (dated today, with a rich entry description via `--index-note`), appends the savepoint `Done` bookend, and commits the store, all in one call:
|
|
244
|
+
```bash
|
|
245
|
+
ruby ~/.plastic/scripts/end-intent --store <store_path> --id <ID> --disposition delivered \
|
|
246
|
+
--outcome-summary "delivered in <tag-name>: <one-line summary>" \
|
|
247
|
+
--index-note "<tag-name>, <mode/tier>; <what shipped>; <suite result>"
|
|
248
|
+
```
|
|
249
|
+
d. Update clusters to show `_(completed)_` (the store-curating skill's job on its next pass).
|
|
227
250
|
|
|
228
251
|
**If no active intent exists for this release**, that itself is a problem - work happened outside the intent system. Log it and move on, but flag it.
|
|
229
252
|
|
|
230
253
|
### 9. Clean Up the Intent's Worktrees (merge-then-remove)
|
|
231
254
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
255
|
+
This is the release branch of `plastic-intent-ending`'s Step 5 disarm (`merge: true`), not a
|
|
256
|
+
separate concern: a release is the merge-then-remove path for the intent's worktrees (intent
|
|
257
|
+
73c3), so the intent's code branch is merged back into the default branch BEFORE the worktree
|
|
258
|
+
is removed. Drive it through `Worktree.finish` with `merge: true`, which merges the code
|
|
259
|
+
branch, then removes both worktrees (code + paired store), prunes both repos, and clears the
|
|
260
|
+
worktree block from the bridge:
|
|
237
261
|
|
|
238
262
|
```bash
|
|
239
263
|
ruby -r ~/.plastic/scripts/lib/worktree -r ~/.plastic/scripts/lib/bridge -e \
|
|
@@ -241,13 +265,39 @@ ruby -r ~/.plastic/scripts/lib/worktree -r ~/.plastic/scripts/lib/bridge -e \
|
|
|
241
265
|
```
|
|
242
266
|
|
|
243
267
|
(Uses `discover_bridge`, not a bare session-keyed `Bridge.read`, because a session can own more
|
|
244
|
-
than one live bridge now
|
|
268
|
+
than one live bridge now (intent 131) and `discover_bridge` resolves the right one for this cwd.)
|
|
245
269
|
|
|
246
270
|
Honor the worktree-cleanup rule: never leave an orphaned worktree, and run `git worktree
|
|
247
271
|
prune` in the affected repo if you hit a stale reference. For why this is the one place the
|
|
248
272
|
merge-vs-remove policy lands on merge, and the fail-open/idempotent guarantees of `finish`,
|
|
249
273
|
read `references/promotion-and-tagging.md`.
|
|
250
274
|
|
|
275
|
+
## Release lines and channels
|
|
276
|
+
|
|
277
|
+
Two lanes get code to a release, on top of the workflow above.
|
|
278
|
+
|
|
279
|
+
- **Default lane.** Branch, merge to main, cut stable, publish to npm `latest`. This is the
|
|
280
|
+
workflow in the steps above, unchanged. Use it for additive, suite-verifiable,
|
|
281
|
+
low-blast-radius work.
|
|
282
|
+
- **Beta-verified lane.** Branch, merge to `beta`, publish to the npm `beta` channel, verify in
|
|
283
|
+
real use, then merge to main and cut stable. Use it for work that changes operational
|
|
284
|
+
substrate, or carries data, migration, lock, or state-format risk, or that a hermetic suite
|
|
285
|
+
cannot fully validate on its own.
|
|
286
|
+
|
|
287
|
+
**Stable-line guarantees.** An external `latest` user can rely on:
|
|
288
|
+
|
|
289
|
+
- `main` is always green and releasable; no pending revert awaiting re-land sits on `main`.
|
|
290
|
+
- A stable release carries no pre-release suffix, publishes to `latest`, and the newest release
|
|
291
|
+
always carries the GitHub "Latest" badge.
|
|
292
|
+
- The three version files always agree, checked by `scripts/lib/release_guard.rb` (see Bump
|
|
293
|
+
Version above).
|
|
294
|
+
- A stable cut collects only intents that cleared their lane's verification bar.
|
|
295
|
+
- Channel semantics are fixed: `latest` is stable, `beta` is the verification line, `alpha` is
|
|
296
|
+
experimental.
|
|
297
|
+
|
|
298
|
+
Read `references/release-lines.md` for the full lane-routing detail, the version-line map, and
|
|
299
|
+
the intent-41 re-land playbook.
|
|
300
|
+
|
|
251
301
|
## Conventions
|
|
252
302
|
|
|
253
303
|
- **Annotated tags only** - `git tag -a`, never lightweight tags
|
|
@@ -262,6 +312,8 @@ read `references/promotion-and-tagging.md`.
|
|
|
262
312
|
|
|
263
313
|
## References
|
|
264
314
|
|
|
315
|
+
- Read `references/release-lines.md` for the two release lanes, the stable-line guarantees,
|
|
316
|
+
the version-line map, and the intent-41 re-land playbook before starting any release
|
|
265
317
|
- When promoting a pre-release across channels (`--promote beta`/`--promote stable`) or
|
|
266
318
|
tagging a historical release retroactively, read `references/promotion-and-tagging.md`
|
|
267
319
|
for the exact commands and rules first
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Release Lines and Channels
|
|
2
|
+
|
|
3
|
+
The two release lanes, the version-line map, and the intent-41 re-land playbook: the deep
|
|
4
|
+
material behind SKILL.md's "Release lines and channels" section.
|
|
5
|
+
|
|
6
|
+
## Table of Contents
|
|
7
|
+
|
|
8
|
+
- [The two lanes](#the-two-lanes)
|
|
9
|
+
- [Routing rule](#routing-rule)
|
|
10
|
+
- [Stable-line guarantees](#stable-line-guarantees)
|
|
11
|
+
- [Version-line map](#version-line-map)
|
|
12
|
+
- [Intent 41 re-land playbook](#intent-41-re-land-playbook)
|
|
13
|
+
|
|
14
|
+
## The two lanes
|
|
15
|
+
|
|
16
|
+
**Default lane.** Branch, merge to `main` with `--no-ff`, cut stable, publish to npm `latest`.
|
|
17
|
+
This is the workflow SKILL.md documents step by step. It is the path for additive,
|
|
18
|
+
suite-verifiable, low-blast-radius work: new skills, prose, deterministic scripts, anything a
|
|
19
|
+
green Minitest run can fully vouch for.
|
|
20
|
+
|
|
21
|
+
**Beta-verified lane.** Branch, merge to the `beta` branch, publish to the npm `beta` dist-tag,
|
|
22
|
+
verify in real use, then merge `beta` into `main` and cut stable. It sits on top of the existing
|
|
23
|
+
promotion mechanics (`--promote beta` / `--promote stable`, linear only, see
|
|
24
|
+
`promotion-and-tagging.md`); it names when to use them, not new machinery.
|
|
25
|
+
|
|
26
|
+
## Routing rule
|
|
27
|
+
|
|
28
|
+
Work rides the beta-verified lane when it changes operational substrate, carries data,
|
|
29
|
+
migration, lock, or state-format risk, or cannot be fully validated by a hermetic suite alone.
|
|
30
|
+
Everything else merges straight to main.
|
|
31
|
+
|
|
32
|
+
Intent 41's DB layer is the archetypal beta-lane case: it replaces the bridge, lock, and session
|
|
33
|
+
file formats with a new persistent SQLite substrate. A green suite proves the code correct; it
|
|
34
|
+
cannot prove the new substrate survives real, uncontrolled usage, so real-use verification on
|
|
35
|
+
beta comes first.
|
|
36
|
+
|
|
37
|
+
The manual-first roadmap's eight 1.1.0 intents (158a, 163, 161, 164, 165, 168, 166, 159) are all
|
|
38
|
+
default-lane: skill directory renames, prose rewrites, deterministic step scripts. Additive, and
|
|
39
|
+
fully suite-verified.
|
|
40
|
+
|
|
41
|
+
## Stable-line guarantees
|
|
42
|
+
|
|
43
|
+
What an external `latest` user can rely on:
|
|
44
|
+
|
|
45
|
+
1. `main` is always green and releasable. No pending revert awaiting re-land sits on `main`.
|
|
46
|
+
When something needs beta verification, it comes out of `main` the same day that need is
|
|
47
|
+
found (the 226023f precedent), never left half-landed.
|
|
48
|
+
2. A stable release carries no pre-release suffix, publishes to npm `latest`, and the newest
|
|
49
|
+
stable release always carries the GitHub "Latest" badge (`gh release create --latest` on
|
|
50
|
+
every cut).
|
|
51
|
+
3. The three repo version files (`package.json`, `.claude-plugin/plugin.json`,
|
|
52
|
+
`.claude-plugin/marketplace.json`) always agree. Checked mechanically by
|
|
53
|
+
`scripts/lib/release_guard.rb`.
|
|
54
|
+
4. A stable cut collects only intents that cleared their lane's bar: default-lane intents by a
|
|
55
|
+
green suite, beta-lane intents by suite green plus their lane's own verification (real-use
|
|
56
|
+
signal, owner sign-off).
|
|
57
|
+
5. Channel semantics are fixed: `latest` is stable and what an external user should run; `beta`
|
|
58
|
+
is the verification line, published but expected to move; `alpha` is experimental,
|
|
59
|
+
pre-verification.
|
|
60
|
+
|
|
61
|
+
## Version-line map
|
|
62
|
+
|
|
63
|
+
| Line | State | What lands here |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `1.1.x` | Current stable line (main) | Additive or low-risk work merged straight to main; interim stable cuts, including 171's wave-6 cut, stay in this line |
|
|
66
|
+
| `1.2.0-beta.1` | On beta (`9ec194b`, unpublished) | Intent 41's DB layer, restored over 1.1.0 by revert-of-revert (`c48601a` then `9ec194b`) |
|
|
67
|
+
| `1.2.0` | Reserved | The stable graduation of the DB layer, once beta verification passes; not claimed by any interim `1.1.x` cut |
|
|
68
|
+
|
|
69
|
+
A beta-graduated substrate change claims its reserved minor at the moment it actually merges to
|
|
70
|
+
main, not before. Nothing else on the `1.1.x` line is blocked waiting for `1.2.0`.
|
|
71
|
+
|
|
72
|
+
## Intent 41 re-land playbook
|
|
73
|
+
|
|
74
|
+
Written for the wave-6 cut intent (171) and any future reader to pick a version without
|
|
75
|
+
re-deriving this decision.
|
|
76
|
+
|
|
77
|
+
**Current state.** The revert-of-revert already sits on the `beta` branch at `9ec194b`, on top
|
|
78
|
+
of 1.1.0, versioned `1.2.0-beta.1` (`c48601a`). There is nothing left to execute on the git side;
|
|
79
|
+
this playbook describes what happens next, not a pending action.
|
|
80
|
+
|
|
81
|
+
**Preconditions**, both required before any npm publish of `1.2.0-beta.1`:
|
|
82
|
+
|
|
83
|
+
- (a) One documentation pass over beta-line skills and docs for the hybrid savepoint contract:
|
|
84
|
+
on beta, only the terminal Done bookend still writes a live `savepoint.md`; every other
|
|
85
|
+
milestone lives in `savepoint_events` plus a committed JSONL export. Beta-line prose that
|
|
86
|
+
still assumes an always-live ledger needs updating first, so a beta-line reader does not
|
|
87
|
+
mistake an empty ledger for a broken one.
|
|
88
|
+
- (b) The owner's manual verification of the DB layer in real use. This is a dogfood signal,
|
|
89
|
+
distinct from the independently-reviewed green suite that already exists on beta.
|
|
90
|
+
|
|
91
|
+
**Trigger**, owner-gated: the owner publishes `1.2.0-beta.1` to the npm `beta` dist-tag. This is
|
|
92
|
+
explicitly not this intent's, nor any agent's, call to make.
|
|
93
|
+
|
|
94
|
+
**Verification.** An external tester plus the owner verify the DB layer on the beta channel.
|
|
95
|
+
|
|
96
|
+
**Completion.** Once verified, `beta` merges into `main`, `1.2.0` is cut stable, and it publishes
|
|
97
|
+
to npm `latest`.
|
|
98
|
+
|
|
99
|
+
**Version mechanics.** `1.2.0` is reserved for this graduation. The `1.1.x` line stays the
|
|
100
|
+
stable line until `1.2.0` actually lands. `1.2.0-beta.1` graduates to `1.2.0` stable by dropping
|
|
101
|
+
the pre-release suffix; nothing else about the version number changes.
|
|
102
|
+
|
|
103
|
+
**Consumed by 171.** The wave-6 consistency-dividend cut stays in the `1.1.x` line. It does not
|
|
104
|
+
ride intent 41 and needs no further derivation: intent 41 keeps its own `1.2.0` line on beta,
|
|
105
|
+
independent of whatever `1.1.x` number 171 lands on.
|
package/skills/roadmap/SKILL.md
CHANGED
|
@@ -21,7 +21,10 @@ wave entry mirrors that intent's status in `INDEX.md` (`queued`/`delivering`/`de
|
|
|
21
21
|
**`INDEX.md` is the single writer of intent status; on any conflict INDEX wins and the roadmap
|
|
22
22
|
entry is corrected to match.**
|
|
23
23
|
|
|
24
|
-
The skill operates on the file directly via Read/Edit
|
|
24
|
+
The skill operates on the roadmap file directly via Read/Edit. The one deterministic helper it
|
|
25
|
+
uses is the savepoint ledger writer (`scripts/roadmap-savepoint`, `append`/`rebuild`); every verb's
|
|
26
|
+
closing step calls `append` after its Read/Edit, and the roadmap `.md` file itself stays
|
|
27
|
+
Read/Edit-only.
|
|
25
28
|
|
|
26
29
|
## Verbs
|
|
27
30
|
|
|
@@ -50,3 +53,6 @@ verb above.
|
|
|
50
53
|
- Additive: this skill introduces no gate, lock, or hook, and does not change `INDEX.md`'s section
|
|
51
54
|
list or the intent frontmatter schema.
|
|
52
55
|
- Closing a roadmap moves it to `roadmaps/archived/{slug}.md` so `roadmaps/` lists only live ones.
|
|
56
|
+
- Every verb also appends a machine ledger line to the roadmap's name-paired
|
|
57
|
+
`roadmaps/{slug}.savepoint.md`, the derived counterpart to the human `## Log`; see
|
|
58
|
+
`references/file-format.md` for its shape and location.
|
|
@@ -11,7 +11,9 @@ roadmap.
|
|
|
11
11
|
|
|
12
12
|
`roadmaps/` lists only live (open or in-flight) roadmaps. Once a roadmap's `## Goal` is reached,
|
|
13
13
|
its file moves to `roadmaps/archived/{slug}.md` (see Close/archive in `operations.md`); the
|
|
14
|
-
`archived/` subdirectory is scaffolded once, alongside `roadmaps/`, with a `.gitkeep`.
|
|
14
|
+
`archived/` subdirectory is scaffolded once, alongside `roadmaps/`, with a `.gitkeep`. Its
|
|
15
|
+
name-paired ledger, `roadmaps/{slug}.savepoint.md` (see Savepoint ledger below), moves alongside
|
|
16
|
+
it in the same Close/archive step.
|
|
15
17
|
|
|
16
18
|
## The four sections (in order)
|
|
17
19
|
|
|
@@ -63,6 +65,33 @@ that entry-intent's `outcome.md`:
|
|
|
63
65
|
The log line never restates `outcome.md` detail; it points at it (lossless-by-reference). This
|
|
64
66
|
complements, and does not replace, `INDEX.md`'s `## Completed` section or `CHANGELOG.md`.
|
|
65
67
|
|
|
68
|
+
## Savepoint ledger
|
|
69
|
+
|
|
70
|
+
`roadmaps/{slug}.savepoint.md` is the name-paired sibling of `roadmaps/{slug}.md`: the machine
|
|
71
|
+
counterpart to the human `## Log`, moving to `roadmaps/archived/{slug}.savepoint.md` alongside its
|
|
72
|
+
roadmap on close (see Close/archive). It is created lazily by the first `append` call; there is no
|
|
73
|
+
template to scaffold.
|
|
74
|
+
|
|
75
|
+
Line shape, one event per line, append-only, newest at the bottom:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
<UTC-iso8601> <event> <detail>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Two-space fields, mirroring the intent-dir cycle-step ledger (`savepoint.md`). The controlled event
|
|
82
|
+
vocabulary: `created`, `dispatched`, `parked`, `merged`, `release`, `handoff`, `closed`, and
|
|
83
|
+
optionally `added`, `reordered`, `wave`. The `(event, detail)` pair is the idempotency key, so
|
|
84
|
+
re-appending the same pair is a no-op.
|
|
85
|
+
|
|
86
|
+
`## Log` and the ledger record the same events in two voices: the Log is the dated, one-sentence,
|
|
87
|
+
EM-to-CTO-plain-language record a human reads cold; the ledger is the terse, machine-timestamped,
|
|
88
|
+
controlled-vocabulary record a coordinator reads at a glance. Both are append-only; neither edits
|
|
89
|
+
the other.
|
|
90
|
+
|
|
91
|
+
The ledger is derived and rebuildable (`ruby ~/.plastic/scripts/roadmap-savepoint rebuild --roadmap
|
|
92
|
+
roadmaps/{slug}.md`, reconstructing it from `## Log`), never a status source: `INDEX.md` stays the
|
|
93
|
+
single writer of intent status, exactly as for the roadmap file itself.
|
|
94
|
+
|
|
66
95
|
## Worked example
|
|
67
96
|
|
|
68
97
|
```
|
|
@@ -20,7 +20,10 @@ next" in under a minute, just from this one file.
|
|
|
20
20
|
status mirroring that intent's current `INDEX.md` status.
|
|
21
21
|
6. Append the first `## Log` line, a short `YYYY-MM-DD HH:MM UTC`-prefixed plain-language note
|
|
22
22
|
that the roadmap was created.
|
|
23
|
-
7.
|
|
23
|
+
7. Append the ledger event (derived, idempotent, safe to re-run; never writes INDEX or roadmap
|
|
24
|
+
status; creates `roadmaps/<slug>.savepoint.md` lazily): `ruby ~/.plastic/scripts/roadmap-savepoint
|
|
25
|
+
append --roadmap roadmaps/<slug>.md --event created --detail "<slug>: <title>"`.
|
|
26
|
+
8. Refresh the QMD index for this roadmap (no-op when QMD is absent), in the background so it
|
|
24
27
|
never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <roadmaps-dir> --async`.
|
|
25
28
|
|
|
26
29
|
## Add / reorder entries
|
|
@@ -34,6 +37,10 @@ next" in under a minute, just from this one file.
|
|
|
34
37
|
entry is eligible to run.
|
|
35
38
|
- After any add/reorder, append a `## Log` line describing the change (e.g.
|
|
36
39
|
`- <YYYY-MM-DD HH:MM UTC> added 132 to wave 2`).
|
|
40
|
+
- Append the ledger event (derived, idempotent, safe to re-run; never writes INDEX or roadmap
|
|
41
|
+
status): `ruby ~/.plastic/scripts/roadmap-savepoint append --roadmap roadmaps/<slug>.md --event
|
|
42
|
+
added --detail "<id> to wave N"` for an add, or `--event reordered` for a reorder (describe the
|
|
43
|
+
move in `<detail>`).
|
|
37
44
|
- Refresh the QMD index for this roadmap (no-op when QMD is absent), in the background so it
|
|
38
45
|
never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <roadmaps-dir> --async`.
|
|
39
46
|
|
|
@@ -49,7 +56,12 @@ next" in under a minute, just from this one file.
|
|
|
49
56
|
one-line EM-to-CTO entry described in `file-format.md` (date, what shipped and its impact in
|
|
50
57
|
plain language, then a link to that intent's `outcome.md`). For other transitions, write a
|
|
51
58
|
short dated plain-language line (no codenames, no jargon).
|
|
52
|
-
5.
|
|
59
|
+
5. Append the ledger event, only when the status token actually changed (derived, idempotent,
|
|
60
|
+
never writes INDEX or roadmap status): map the new status to its mechanized event (`delivered`
|
|
61
|
+
-> `merged`, `delivering` -> `dispatched`, `blocked`/`abandoned` -> `parked`), then `ruby
|
|
62
|
+
~/.plastic/scripts/roadmap-savepoint append --roadmap roadmaps/<slug>.md --event <event>
|
|
63
|
+
--detail "<intent-id>"` (add a sha in `<detail>` when one is known).
|
|
64
|
+
6. Refresh the QMD index for this roadmap (no-op when QMD is absent), in the background so it
|
|
53
65
|
never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <roadmaps-dir> --async`.
|
|
54
66
|
|
|
55
67
|
## Append a log line
|
|
@@ -60,6 +72,10 @@ next" in under a minute, just from this one file.
|
|
|
60
72
|
A delivery event follows the EM-to-CTO one-line shape with an `outcome.md` link (see
|
|
61
73
|
`file-format.md`); bookkeeping events (created, an intent added to a wave, a wave completed, a
|
|
62
74
|
roadmap closed) are short dated plain-language lines.
|
|
75
|
+
- Append the matching ledger event (derived, idempotent, never writes INDEX or roadmap status):
|
|
76
|
+
when the line records a release cut, `ruby ~/.plastic/scripts/roadmap-savepoint append --roadmap
|
|
77
|
+
roadmaps/<slug>.md --event release --detail "<version>"`; otherwise append the mechanized event
|
|
78
|
+
matching the bookkeeping line just written (see the per-verb event mapping on this page).
|
|
63
79
|
- Refresh the QMD index for this roadmap (no-op when QMD is absent), in the background so it
|
|
64
80
|
never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <roadmaps-dir> --async`.
|
|
65
81
|
|
|
@@ -80,9 +96,13 @@ next" in under a minute, just from this one file.
|
|
|
80
96
|
`abandoned` with a recorded reason, plus whatever else the goal states).
|
|
81
97
|
2. Create `roadmaps/archived/` beside `roadmaps/` (both siblings of `INDEX.md`) if it does not
|
|
82
98
|
exist yet.
|
|
83
|
-
3.
|
|
84
|
-
|
|
85
|
-
|
|
99
|
+
3. Append the ledger closed event, while the roadmap is still at its live path (derived,
|
|
100
|
+
idempotent, never writes INDEX or roadmap status): `ruby ~/.plastic/scripts/roadmap-savepoint
|
|
101
|
+
append --roadmap roadmaps/<slug>.md --event closed --detail "<slug>"`.
|
|
102
|
+
4. Move BOTH files: `roadmaps/{slug}.md` -> `roadmaps/archived/{slug}.md` AND
|
|
103
|
+
`roadmaps/{slug}.savepoint.md` -> `roadmaps/archived/{slug}.savepoint.md`. `roadmaps/` itself
|
|
104
|
+
then lists only live (open or in-flight) roadmaps.
|
|
105
|
+
5. Append the final `## Log` line before or as part of the move:
|
|
86
106
|
`- <YYYY-MM-DD HH:MM UTC> roadmap closed`.
|
|
87
|
-
|
|
107
|
+
6. Refresh the QMD index for this roadmap (no-op when QMD is absent), in the background so it
|
|
88
108
|
never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <roadmaps-dir> --async`.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-roadmap-continuing
|
|
3
|
+
description: >-
|
|
4
|
+
Use when the user wants to continue or resume a roadmap, pick up a mid-flight delivery batch,
|
|
5
|
+
asks "where is the roadmap", or wants to resume the wave that was shipping, including an
|
|
6
|
+
indirect ask that never names a roadmap directly (for example "where did that batch of
|
|
7
|
+
tickets land"). This is the roadmap route of plastic-continuing: it finds the tier's
|
|
8
|
+
mid-flight roadmap, presents its state, then asks how to proceed exactly once.
|
|
9
|
+
user-invocable: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Roadmap Continuing - resume the mid-flight roadmap
|
|
13
|
+
|
|
14
|
+
`plastic-roadmap-continuing` is the roadmap route of `plastic-continuing`. It finds the tier's
|
|
15
|
+
mid-flight roadmap, presents its state, then asks the user how to proceed, exactly once.
|
|
16
|
+
|
|
17
|
+
Before intent 158a1 there was no automated way to do this: the `171` (consistency-dividend)
|
|
18
|
+
roadmap handoff had to be resumed by hand, carried as a free-prose note in `171`'s own
|
|
19
|
+
`## Insights`. This skill closes that gap.
|
|
20
|
+
|
|
21
|
+
## Find the mid-flight roadmap
|
|
22
|
+
|
|
23
|
+
1. Determine the tier (project vs. global) and enumerate that tier's live `roadmaps/*.md`
|
|
24
|
+
(exclude `roadmaps/archived/`). Read via Read/glob, or `plastic-roadmap`'s Read/consume
|
|
25
|
+
verb. See `plastic-roadmap`'s `references/file-format.md` for the file grammar; do not
|
|
26
|
+
duplicate it here.
|
|
27
|
+
2. For each candidate, also read its paired ledger `roadmaps/<slug>.savepoint.md` when present
|
|
28
|
+
(see `plastic-roadmap`'s `references/file-format.md#savepoint-ledger`): its last line(s) are a
|
|
29
|
+
cheaper, precise last-event signal (for example `dispatched 134` or `merged 172`), read
|
|
30
|
+
alongside the existing `## Waves`/`## Log` judgment. The ledger is read-only here, a derived
|
|
31
|
+
signal, never a new status field; INDEX.md stays the sole status writer.
|
|
32
|
+
3. Rank liveness by calling the shared reader in which mode (one implementation across the
|
|
33
|
+
auto loop and this skill):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
ruby ~/.plastic/scripts/roadmap-next --roadmaps-dir <tier>/roadmaps --which
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Read `state` and the winning `roadmap`. When `state` is `tie`, `tie_candidates` lists the
|
|
40
|
+
equally-live roadmaps to present side by side; the single "auto or guided?" ask below
|
|
41
|
+
doubles as the resolution. `roadmap-next` liveness-ranks the same way this skill used to do
|
|
42
|
+
by eye (a `delivering` or `blocked` entry wins, else the newest ledger or `## Log`
|
|
43
|
+
timestamp), now deterministically. See `references/liveness-ranking.md` for the algorithm it
|
|
44
|
+
implements.
|
|
45
|
+
4. A genuine tie (two candidates equally live) is presented to the user and resolved by the
|
|
46
|
+
single ask below, not silently picked.
|
|
47
|
+
|
|
48
|
+
## Present state
|
|
49
|
+
|
|
50
|
+
Present the chosen roadmap's `## Goal`, the current wave with each entry's mirrored status, the
|
|
51
|
+
ledger's newest line(s) (the last mechanized event) alongside the newest `## Log` line, before any
|
|
52
|
+
ask, so the coordinator sees the machine last-event at a glance.
|
|
53
|
+
|
|
54
|
+
## Ask once
|
|
55
|
+
|
|
56
|
+
Ask "auto or guided?" exactly once, after presenting state, mirroring
|
|
57
|
+
`plastic-intent-starting`'s single-ask contract:
|
|
58
|
+
- **guided** -> continue step by step with the user.
|
|
59
|
+
- **auto** -> hand off to `plastic-auto` to drive the next wave or entry.
|
|
60
|
+
|
|
61
|
+
Never re-ask. No new roadmap or INDEX status field is invented anywhere in this flow.
|
|
62
|
+
|
|
63
|
+
## The shared reader
|
|
64
|
+
|
|
65
|
+
Liveness ranking and frontier selection live in one place, `scripts/lib/roadmap_queue.rb`
|
|
66
|
+
(intent 148), behind the `scripts/roadmap-next` CLI. This skill calls it in which mode rather
|
|
67
|
+
than ranking roadmaps in prose, so the auto loop (`plastic-auto`) and this skill share exactly
|
|
68
|
+
one implementation (no forked ranking logic). 158a1 originally added no script because the
|
|
69
|
+
benefit was marginal for a read-time judgment; the auto-loop consumer flipped that calculus by
|
|
70
|
+
making the ranking load-bearing and deterministic. The reader is read-only: it consumes the
|
|
71
|
+
roadmap `.md`, the 134 `<slug>.savepoint.md` ledger, and INDEX.md, and writes nothing. INDEX.md
|
|
72
|
+
stays the single status writer.
|
|
73
|
+
|
|
74
|
+
## Caller contract: who writes the ledger
|
|
75
|
+
|
|
76
|
+
This skill is a reader, not a writer, of `roadmaps/<slug>.savepoint.md`. The coordinator flows
|
|
77
|
+
(`plastic-auto`, the enforcer, and this skill's own resume-and-hand-off path) call `ruby
|
|
78
|
+
~/.plastic/scripts/roadmap-savepoint append` at their own dispatch, merge, park, handoff, and
|
|
79
|
+
release points, the same events `plastic-roadmap`'s verbs append at their closing steps. A
|
|
80
|
+
resuming coordinator therefore both reads the ledger here and writes to it as it drives the next
|
|
81
|
+
wave or entry.
|
|
82
|
+
|
|
83
|
+
## References
|
|
84
|
+
|
|
85
|
+
- `references/liveness-ranking.md` - the read-time ranking algorithm and the tie rule.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "plastic-roadmap-continuing",
|
|
3
|
+
"notes": "Intent 158a1. New roadmap route, closing the gap that forced the 171 (consistency-dividend) roadmap handoff to be resumed by hand. Scopes: description triggering (1-3) and behavior/convention compliance (4-8), the latter checked against SKILL.md.",
|
|
4
|
+
"results": {
|
|
5
|
+
"triggering": { "cases": 3, "passed": 3, "run": "2026-07-10, one subagent per case" },
|
|
6
|
+
"behavior": { "cases": 5, "passed": 5, "evidence": "convention checks against skills/roadmap-continuing/SKILL.md and references/liveness-ranking.md" }
|
|
7
|
+
},
|
|
8
|
+
"evals": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1, "scope": "triggering", "set": "train",
|
|
11
|
+
"prompt": "continue the roadmap",
|
|
12
|
+
"expected_output": "Activates plastic-roadmap-continuing.",
|
|
13
|
+
"files": [],
|
|
14
|
+
"assertions": [
|
|
15
|
+
{ "type": "code", "check": "router CHOICE == plastic-roadmap-continuing", "observed": "plastic-roadmap-continuing", "result": "pass" }
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 2, "scope": "triggering", "set": "train",
|
|
20
|
+
"prompt": "resume the delivery batch we were shipping",
|
|
21
|
+
"expected_output": "Activates plastic-roadmap-continuing.",
|
|
22
|
+
"files": [],
|
|
23
|
+
"assertions": [
|
|
24
|
+
{ "type": "code", "check": "router CHOICE == plastic-roadmap-continuing", "observed": "plastic-roadmap-continuing", "result": "pass" }
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": 3, "scope": "triggering", "set": "validation",
|
|
29
|
+
"prompt": "where did that batch of tickets land",
|
|
30
|
+
"expected_output": "Activates plastic-roadmap-continuing (indirect trigger: a roadmap-resume request that never names 'roadmap' or 'continue').",
|
|
31
|
+
"files": [],
|
|
32
|
+
"assertions": [
|
|
33
|
+
{ "type": "code", "check": "router CHOICE == plastic-roadmap-continuing", "observed": "plastic-roadmap-continuing", "result": "pass" }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": 4, "scope": "behavior", "set": "train",
|
|
38
|
+
"prompt": "Does the skill rank liveness correctly when a wave entry is delivering or blocked?",
|
|
39
|
+
"expected_output": "A roadmap with any delivering/blocked wave entry wins the ranking outright over every other candidate.",
|
|
40
|
+
"files": ["skills/roadmap-continuing/references/liveness-ranking.md"],
|
|
41
|
+
"assertions": [
|
|
42
|
+
{ "type": "convention", "check": "delivering/blocked-wins rule documented as step 2 of the algorithm", "observed": "present", "result": "pass" }
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": 5, "scope": "behavior", "set": "train",
|
|
47
|
+
"prompt": "Does the skill fall back to newest Log date when no candidate is delivering/blocked?",
|
|
48
|
+
"expected_output": "Among remaining candidates, the most recent ## Log entry timestamp wins.",
|
|
49
|
+
"files": ["skills/roadmap-continuing/references/liveness-ranking.md"],
|
|
50
|
+
"assertions": [
|
|
51
|
+
{ "type": "convention", "check": "newest-Log-date fallback documented as step 3", "observed": "present", "result": "pass" }
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": 6, "scope": "behavior", "set": "train",
|
|
56
|
+
"prompt": "Does the skill present the roadmap state before asking?",
|
|
57
|
+
"expected_output": "The '## Present state' section (Goal, current wave, newest Log line) runs before the '## Ask once' section.",
|
|
58
|
+
"files": ["skills/roadmap-continuing/SKILL.md"],
|
|
59
|
+
"assertions": [
|
|
60
|
+
{ "type": "convention", "check": "Present state precedes Ask once in document order", "observed": "present", "result": "pass" }
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": 7, "scope": "behavior", "set": "validation",
|
|
65
|
+
"prompt": "Does the skill ask 'auto or guided?' exactly once?",
|
|
66
|
+
"expected_output": "Exactly one ask, after presenting state; never re-asked.",
|
|
67
|
+
"files": ["skills/roadmap-continuing/SKILL.md"],
|
|
68
|
+
"assertions": [
|
|
69
|
+
{ "type": "convention", "check": "the literal phrase 'auto or guided' appears on exactly one line of SKILL.md", "observed": "one occurrence", "result": "pass" }
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": 8, "scope": "behavior", "set": "validation",
|
|
74
|
+
"prompt": "Does the skill invent a new roadmap or INDEX status field, or add a new script?",
|
|
75
|
+
"expected_output": "No. Liveness is computed at read time from existing files; INDEX.md stays the sole status writer; the enumeration/ranking is prose, not a helper script.",
|
|
76
|
+
"files": ["skills/roadmap-continuing/SKILL.md", "skills/roadmap-continuing/references/liveness-ranking.md"],
|
|
77
|
+
"assertions": [
|
|
78
|
+
{ "type": "convention", "check": "no new field or script introduced; 'No new script' section present", "observed": "present", "result": "pass" }
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Liveness Ranking (read time, no new field)
|
|
2
|
+
|
|
3
|
+
Depth reference for "Find the mid-flight roadmap" in `SKILL.md`. This is the full algorithm the
|
|
4
|
+
body summarizes. Since intent 148, this algorithm is IMPLEMENTED in
|
|
5
|
+
`scripts/lib/roadmap_queue.rb` behind the `scripts/roadmap-next` CLI; it is no longer a by-eye
|
|
6
|
+
procedure. This page documents what that reader does, and is the specification the reader
|
|
7
|
+
satisfies.
|
|
8
|
+
|
|
9
|
+
## Why read-time, not a stored field
|
|
10
|
+
|
|
11
|
+
INDEX.md stays the sole writer of intent status; the roadmap file mirrors it (see
|
|
12
|
+
`plastic-roadmap`'s `references/file-format.md`). Adding a "mid-flight" flag to the roadmap
|
|
13
|
+
file or to INDEX.md would create a second thing to keep in sync for a question that is cheap to
|
|
14
|
+
answer by reading what is already there. So liveness is computed fresh, every call, from the
|
|
15
|
+
tier's live `roadmaps/*.md` files (excluding `roadmaps/archived/`), by `RoadmapQueue` (intent
|
|
16
|
+
148) rather than by eye.
|
|
17
|
+
|
|
18
|
+
## The algorithm
|
|
19
|
+
|
|
20
|
+
1. **Enumerate.** List every `roadmaps/*.md` at the tier (project or global), skipping
|
|
21
|
+
`roadmaps/archived/`.
|
|
22
|
+
2. **Delivering/blocked wins outright.** If any candidate roadmap has at least one `## Waves`
|
|
23
|
+
entry whose mirrored status token is `delivering` or `blocked`, it is in flight right now.
|
|
24
|
+
That candidate wins the ranking immediately; skip the rest of the ranking for it.
|
|
25
|
+
3. **Otherwise, newest `## Log` entry wins.** Among the remaining candidates (none have a
|
|
26
|
+
`delivering`/`blocked` entry), read each file's last `## Log` line (append-only, newest at
|
|
27
|
+
the bottom) and rank by that line's `YYYY-MM-DD HH:MM UTC` timestamp. The most recent wins.
|
|
28
|
+
When a candidate's paired `roadmaps/<slug>.savepoint.md` (intent 134) is present, its last
|
|
29
|
+
line is a cheaper, machine-timestamped read of the same fact (the ledger is derived from `##
|
|
30
|
+
Log`, so the two should already agree); reading it first is an optimization, not a second
|
|
31
|
+
source of truth, so a missing or stale ledger never blocks falling back to `## Log` itself.
|
|
32
|
+
4. **Genuine tie -> present, do not silently pick.** If two or more candidates are equally live
|
|
33
|
+
(for example two roadmaps both idle with `## Log` entries on the same timestamp, or two both
|
|
34
|
+
showing `delivering` entries with no other signal to separate them), do not choose for the
|
|
35
|
+
user. Present both/all tied candidates' state side by side, then let the single "auto or
|
|
36
|
+
guided?" ask (asked once regardless of how many candidates were presented) double as the
|
|
37
|
+
resolution: the user's answer implicitly picks by naming which roadmap to continue, or the
|
|
38
|
+
agent asks a short one-line disambiguation immediately before that same single ask, never a
|
|
39
|
+
second separate prompt.
|
|
40
|
+
|
|
41
|
+
## What this closes
|
|
42
|
+
|
|
43
|
+
Before this skill existed, nothing resumed a mid-flight roadmap automatically. The `171`
|
|
44
|
+
(consistency-dividend) roadmap handoff had to be resumed by hand: a free-prose "SESSION
|
|
45
|
+
HANDOFF" note written into `171`'s own `## Insights`, because nothing read `## Waves` +
|
|
46
|
+
`## Log` and reconstructed where the batch stood. This ranking, now a deterministic reader
|
|
47
|
+
rather than a by-eye judgment, is the mechanism that replaces that hand-carried note.
|
|
48
|
+
|
|
49
|
+
## Grammar pointer (do not duplicate)
|
|
50
|
+
|
|
51
|
+
The roadmap file's four sections, entry line shape, and status vocabulary
|
|
52
|
+
(`queued|delivering|delivered|abandoned|blocked`) are owned by `plastic-roadmap`:
|
|
53
|
+
`skills/roadmap/references/file-format.md` for the shape, and
|
|
54
|
+
`skills/roadmap/references/operations.md#read--consume` for how a reader (human or
|
|
55
|
+
coordinator) is meant to walk `## Waves` and `## Log`. This page assumes that grammar and adds
|
|
56
|
+
only the liveness-ranking judgment on top of it.
|