@zalom/plastic 1.3.0 → 1.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/PLASTIC-reference.md +8 -6
- package/PLASTIC.md +52 -14
- package/hooks/hooks.json +5 -0
- package/hooks/links-gate +3 -0
- package/package.json +1 -1
- package/scripts/codex-hook +122 -8
- package/scripts/dashboard.rb +323 -71
- package/scripts/doctor.rb +393 -58
- package/scripts/end-intent +347 -43
- package/scripts/hook-links-gate +74 -0
- package/scripts/hook-lock-gate +8 -3
- package/scripts/install.rb +51 -6
- package/scripts/lib/bridge.rb +105 -27
- package/scripts/lib/config_asks.rb +110 -0
- package/scripts/lib/graph_rebuild.rb +30 -6
- package/scripts/lib/hook_registry.rb +34 -3
- package/scripts/lib/installer_core.rb +70 -13
- package/scripts/lib/intent_validator.rb +38 -10
- package/scripts/lib/links_gate.rb +140 -0
- package/scripts/lib/links_projection.rb +71 -12
- package/scripts/lib/lock.rb +186 -11
- package/scripts/lib/power_tools.rb +57 -14
- package/scripts/lib/project_validator.rb +113 -0
- package/scripts/lib/qmd_hook.rb +12 -8
- package/scripts/lib/restore_intent_v1.rb +154 -0
- package/scripts/lib/roadmap_queue.rb +1 -1
- package/scripts/lib/roadmap_savepoint.rb +38 -10
- package/scripts/lib/store_discovery.rb +77 -0
- package/scripts/lib/store_provisioning.rb +21 -12
- package/scripts/new-intent +10 -12
- package/scripts/plastic-lock +76 -9
- package/scripts/project-links +132 -35
- package/scripts/provision-project-store +18 -5
- package/scripts/read-config +1 -0
- package/scripts/rebuild-graph +42 -17
- package/scripts/restore-intent-v1 +288 -0
- package/scripts/roadmap-next +9 -2
- package/scripts/roadmap-savepoint +9 -1
- package/scripts/update.rb +50 -1
- package/scripts/validate-intent +3 -1
- package/scripts/validate-project +53 -0
- package/scripts/write-config +105 -0
- package/skills/auto/SKILL.md +45 -16
- package/skills/auto/references/agent-architecture.md +7 -0
- package/skills/auto/references/end-tail.md +27 -13
- package/skills/dashboard/SKILL.md +48 -25
- package/skills/dashboard/evals/evals.json +4 -4
- package/skills/dashboard/templates/dashboard-global.md +3 -5
- package/skills/dashboard/templates/dashboard-project.md +6 -18
- package/skills/install/SKILL.md +4 -4
- package/skills/intent-creating/SKILL.md +5 -0
- package/skills/intent-ending/SKILL.md +49 -36
- package/skills/intent-locking/SKILL.md +20 -2
- package/skills/intent-starting/SKILL.md +6 -4
- package/skills/project-continuing/SKILL.md +10 -0
- package/skills/project-continuing/evals/evals.json +3 -3
- package/skills/project-continuing/references/board-fill.md +13 -11
- package/skills/project-creating/SKILL.md +29 -1
- package/skills/releasing/SKILL.md +37 -19
- package/skills/roadmap/SKILL.md +9 -7
- package/skills/roadmap/references/file-format.md +14 -10
- package/skills/roadmap/references/operations.md +22 -18
- package/skills/roadmap-continuing/SKILL.md +5 -5
- package/skills/roadmap-continuing/evals/evals.json +3 -3
- package/skills/roadmap-continuing/references/liveness-ranking.md +6 -5
- package/skills/tutorial/SKILL.md +4 -4
- package/skills/tutorial/references/track-1-guided.md +2 -1
- package/skills/tutorial/references/track-2-auto.md +2 -1
- package/skills/tutorial/references/track-3-projects-and-roadmaps.md +12 -11
- package/skills/update/SKILL.md +30 -17
- package/templates/roadmap.md +8 -8
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
"id": 8, "scope": "behavior", "set": "validation",
|
|
74
|
-
"prompt": "Does the skill carry the intent-
|
|
75
|
-
"expected_output": "A 'Coordination' section records that intent
|
|
74
|
+
"prompt": "Does the skill carry the intent-202 coordination note (project board short by default)?",
|
|
75
|
+
"expected_output": "A 'Coordination' section records that intent 202 has landed: the Recently-worked and raw Future tables are gone, replaced by a prose summary (built in dashboard.rb) and an honest-totals footer; Active is capped at 3 (lifecycle-stage descending, D2) and Next-work at 5; conversational paging re-invokes dashboard.rb --data with --limit-active/--limit-next/--all (no state on disk); --plain prints the full uncapped plain-text board. The rule-name citations and the dashboard.rb project <slug> --data -> dashboard-project.md path still resolve.",
|
|
76
76
|
"files": ["skills/project-continuing/SKILL.md"],
|
|
77
77
|
"assertions": [
|
|
78
|
-
{ "type": "convention", "check": "'
|
|
78
|
+
{ "type": "convention", "check": "'202' present with the landed coordination note describing the new shape, caps, paging flags, and --plain", "observed": "present: 'Intent 202 has landed' paragraph with the described content", "result": "pass" }
|
|
79
79
|
]
|
|
80
80
|
},
|
|
81
81
|
{
|
|
@@ -7,20 +7,22 @@ would otherwise bloat the SKILL.md body.
|
|
|
7
7
|
## Fill rules (owned by plastic-dashboard, summarized here for convenience)
|
|
8
8
|
|
|
9
9
|
- `{{a.b.count}}` -> the integer (e.g. `counts.active` is that count).
|
|
10
|
-
- `{{<list>.rows}}` -> the
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- `recently_worked` -> `| id | what | state | scope |` (global), `| id | what | state |` (project)
|
|
10
|
+
- `{{<list>.rows}}` -> the two intent lists (`active`, `next_work`) render as Markdown table
|
|
11
|
+
rows. The template hard-codes each table's header and separator; the placeholder becomes one
|
|
12
|
+
data row per entry, in that table's fixed column order, cells dropped verbatim from the
|
|
13
|
+
payload (cells arrive pipe-escaped and whitespace-normalized; do not re-escape or
|
|
14
|
+
re-truncate). Column order per table:
|
|
16
15
|
- `next_work` -> `| id | what | value | disposition | flags_label |`
|
|
17
|
-
- `active` -> `| id | what | stage
|
|
18
|
-
Overflow entry (empty `id`, `what` = `+N more`) -> `+N more` in the Id column, other cells blank.
|
|
16
|
+
- `active` -> `| id | what | stage |`
|
|
19
17
|
Empty list -> one full-width row with `_(none)_` in the Id column, other cells blank, matching
|
|
20
|
-
that table's column count
|
|
21
|
-
|
|
18
|
+
that table's column count. Neither list carries an overflow "+N more" row (intent 202): the
|
|
19
|
+
true pool size rides on the payload (`active_total`/`next_total`, shown as
|
|
20
|
+
`active_shown`/`next_shown`), stated in prose by `{{footer}}` instead. Never emit `<br>`.
|
|
22
21
|
- `{{projects.lines}}` (global board) -> the project rollup stays prose, one line per project.
|
|
23
|
-
- Scalars (`{{date}}`, `{{slug}}`, `{{
|
|
22
|
+
- Scalars (`{{date}}`, `{{slug}}`, `{{summary}}`, `{{footer}}`) -> substitute verbatim.
|
|
23
|
+
`summary` (the 2-3 sentence "what was delivered most recently") and `footer` (the
|
|
24
|
+
honest-totals + how-to-see-everything line) are finished prose built in `dashboard.rb`,
|
|
25
|
+
replacing the old recently-worked table and the raw future table respectively.
|
|
24
26
|
|
|
25
27
|
No re-sorting, no re-summarizing, no hand-written prose replacing a line the payload already
|
|
26
28
|
supplies. Same store state produces a byte-identical payload regardless of model.
|
|
@@ -122,7 +122,35 @@ ruby ~/.plastic/scripts/qmd-sync register --store ~/.plastic/projects/<slug>/sto
|
|
|
122
122
|
`qmd-sync` no-ops when QMD is absent, so run it unconditionally. This adds the
|
|
123
123
|
`plastic-<slug>` collection and indexes it.
|
|
124
124
|
|
|
125
|
-
### 12.
|
|
125
|
+
### 12. Self-Check with validate-project
|
|
126
|
+
|
|
127
|
+
Before announcing, verify the spawn actually landed everything it claims to
|
|
128
|
+
have created. Run:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
ruby ~/.plastic/scripts/validate-project <slug>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If this exits 0, proceed to step 13. If it exits non-zero, STOP: do not
|
|
135
|
+
proceed to Announce. Read the `missing:` and error lines it printed to
|
|
136
|
+
stderr, fix the named gap(s), for example:
|
|
137
|
+
|
|
138
|
+
- missing `project.yml` or `INDEX.md` or `store/`: re-run
|
|
139
|
+
`ruby ~/.plastic/scripts/provision-project-store <slug>` (step 7), then
|
|
140
|
+
re-check
|
|
141
|
+
- missing project-root `AGENTS.md`: repeat step 4 (populate AGENTS.md at the
|
|
142
|
+
project root, not `~/.plastic/projects/<slug>/`)
|
|
143
|
+
- project directory missing on disk: repeat step 2
|
|
144
|
+
- not registered in projects.yml: repeat step 6
|
|
145
|
+
|
|
146
|
+
Re-run `validate-project <slug>` after each fix until it exits 0. Only a
|
|
147
|
+
project spawn that passes this self-check moves on to be announced as
|
|
148
|
+
created. A spawn that never verifies itself is exactly the bug this step
|
|
149
|
+
exists to close (intent 190; the intent-26 spawn shipped with no
|
|
150
|
+
`project.yml` and no root `AGENTS.md`, caught only weeks later by a doctor
|
|
151
|
+
sweep).
|
|
152
|
+
|
|
153
|
+
### 13. Announce
|
|
126
154
|
|
|
127
155
|
Log in `## Insights` of each founding intent:
|
|
128
156
|
> "Project `<slug>` created at `<path>`. Tactical mirror: `project-<slug>:1` (autonomous)"
|
|
@@ -21,8 +21,8 @@ Project configuration drives the workflow - no hardcoded assumptions.
|
|
|
21
21
|
- [ ] Push to remote with tags
|
|
22
22
|
- [ ] Run post-push actions (GitHub release, npm publish, etc.)
|
|
23
23
|
- [ ] Verify release sync (npm dist-tag, GitHub "Latest", git tag all show the new version)
|
|
24
|
-
- [ ] Complete active intent
|
|
25
24
|
- [ ] Clean up the intent's worktrees (merge-then-remove)
|
|
25
|
+
- [ ] Complete active intent
|
|
26
26
|
|
|
27
27
|
## Workflow
|
|
28
28
|
|
|
@@ -232,25 +232,19 @@ If the GitHub "Latest" badge is on an older tag (the common drift), fix it witho
|
|
|
232
232
|
gh release edit <tag-name> --latest
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
### 8.
|
|
236
|
-
|
|
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.
|
|
238
|
-
|
|
239
|
-
1. Read `~/.plastic/INDEX.md` (or the project's INDEX.md) - find active intent(s) related to this release.
|
|
240
|
-
2. For each active intent being delivered:
|
|
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).
|
|
250
|
-
|
|
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.
|
|
235
|
+
### 8. Clean Up the Intent's Worktrees (merge-then-remove)
|
|
252
236
|
|
|
253
|
-
|
|
237
|
+
This step now runs BEFORE step 9's `end-intent` call (intent 188, D7): `scripts/end-intent`
|
|
238
|
+
gained its own step 5 that disarms (releases the worktree, clears `delivery.lock`) as part
|
|
239
|
+
of every close. Its plain-remove shape does not merge, so if `end-intent` ran first on a
|
|
240
|
+
release, its step 5 would remove the worktree WITHOUT merging the code branch first,
|
|
241
|
+
stranding the integrated work (`Worktree.finish` returns early once the worktree block it
|
|
242
|
+
needs is gone, per `worktree.rb`'s own "no-op if nothing was provisioned" contract).
|
|
243
|
+
Running this merge-then-remove step first means the worktree is already gone by the time
|
|
244
|
+
step 9 runs, so `end-intent`'s own disarm becomes a harmless no-op for the worktree
|
|
245
|
+
(nothing left to remove), while for the FIRST time on this path it also clears the delivery
|
|
246
|
+
lock correctly (G5): before intent 188 this path left the lock stranded, exactly the class
|
|
247
|
+
of bug closed by the End-tail enforcement work.
|
|
254
248
|
|
|
255
249
|
This is the release branch of `plastic-intent-ending`'s Step 5 disarm (`merge: true`), not a
|
|
256
250
|
separate concern: a release is the merge-then-remove path for the intent's worktrees (intent
|
|
@@ -272,6 +266,30 @@ prune` in the affected repo if you hit a stale reference. For why this is the on
|
|
|
272
266
|
merge-vs-remove policy lands on merge, and the fail-open/idempotent guarantees of `finish`,
|
|
273
267
|
read `references/promotion-and-tagging.md`.
|
|
274
268
|
|
|
269
|
+
### 9. Complete Active Intent
|
|
270
|
+
|
|
271
|
+
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, AND disarm since intent 188) is `plastic-intent-ending`'s job, not this skill's: run its backing script rather than restating that prose here.
|
|
272
|
+
|
|
273
|
+
1. Read `~/.plastic/INDEX.md` (or the project's INDEX.md) - find active intent(s) related to this release.
|
|
274
|
+
2. For each active intent being delivered:
|
|
275
|
+
a. Write a real `outcome.md` (never leave the scaffold placeholder), `disposition: delivered`, referencing the release tag.
|
|
276
|
+
b. Update `## Insights` with final observations.
|
|
277
|
+
c. Run the mechanical close (`scripts/end-intent`'s steps 1-5): 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, commits the store, and disarms (releases the worktree - already gone from step 8 above - and clears `delivery.lock`), all in one call:
|
|
278
|
+
```bash
|
|
279
|
+
ruby ~/.plastic/scripts/end-intent --store <store_path> --id <ID> --disposition delivered \
|
|
280
|
+
--session "$CLAUDE_CODE_SESSION_ID" \
|
|
281
|
+
--outcome-summary "delivered in <tag-name>: <one-line summary>" \
|
|
282
|
+
--index-note "<tag-name>, <mode/tier>; <what shipped>; <suite result>"
|
|
283
|
+
```
|
|
284
|
+
A non-zero exit needs attention: 4 means a live foreign session holds the lock (back
|
|
285
|
+
off), 5 means the code worktree is still dirty (should not happen here, since step 8
|
|
286
|
+
already removed it; investigate before overriding with `--discard-worktree-changes`),
|
|
287
|
+
3 means disarm ran but the lock is still present (run `/plastic-doctor check the lock
|
|
288
|
+
status`).
|
|
289
|
+
d. Update clusters to show `_(completed)_` (the store-curating skill's job on its next pass).
|
|
290
|
+
|
|
291
|
+
**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.
|
|
292
|
+
|
|
275
293
|
## Release lines and channels
|
|
276
294
|
|
|
277
295
|
Two lanes get code to a release, on top of the workflow above.
|
package/skills/roadmap/SKILL.md
CHANGED
|
@@ -13,10 +13,12 @@ to a release (completion-side, `CHANGELOG.md`). It lives at `roadmaps/{slug}.md`
|
|
|
13
13
|
project's `INDEX.md` and `project.yml`). It never sits inside `store/`, which holds intent
|
|
14
14
|
directories, not project artifacts.
|
|
15
15
|
|
|
16
|
-
A roadmap file has four parts: a title/meta header, `## Goal` (prose), `##
|
|
17
|
-
inside a
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
A roadmap file has four parts: a title/meta header, `## Goal` (prose), `## Batches` (ordered;
|
|
17
|
+
entries inside a batch are parallel-safe, batches run sequentially), and an append-only dated
|
|
18
|
+
`## Log`. A roadmap written before owner ruling 145 may instead use the legacy `## Waves` heading;
|
|
19
|
+
reading accepts both, but every new roadmap is scaffolded with `## Batches`, and an existing
|
|
20
|
+
roadmap file's heading is never renamed to migrate it. Each batch entry mirrors that intent's
|
|
21
|
+
status in `INDEX.md` (`queued`/`delivering`/`delivered`/`abandoned`/`blocked`).
|
|
20
22
|
|
|
21
23
|
**`INDEX.md` is the single writer of intent status; on any conflict INDEX wins and the roadmap
|
|
22
24
|
entry is corrected to match.**
|
|
@@ -31,9 +33,9 @@ Read/Edit-only.
|
|
|
31
33
|
| Verb | When | Mechanics |
|
|
32
34
|
|------|------|-----------|
|
|
33
35
|
| Create | user wants to start a new roadmap / plan a delivery batch | `references/operations.md#create` |
|
|
34
|
-
| Add / reorder entries | user wants to add intents to a
|
|
36
|
+
| Add / reorder entries | user wants to add intents to a batch or resequence batches | `references/operations.md#add--reorder-entries` |
|
|
35
37
|
| Sync status mirror | an entry's status may be stale against INDEX | `references/operations.md#sync-status-mirror` |
|
|
36
|
-
| Append log line | a roadmap event just happened (created,
|
|
38
|
+
| Append log line | a roadmap event just happened (created, batch done, closed) | `references/operations.md#append-a-log-line` |
|
|
37
39
|
| Read / consume | a human or a coordinator needs the roadmap's current state | `references/operations.md#read--consume` |
|
|
38
40
|
| Close / archive | the roadmap's `## Goal` is reached | `references/operations.md#close--archive` |
|
|
39
41
|
|
|
@@ -47,7 +49,7 @@ verb above.
|
|
|
47
49
|
layout per project. The general rule: `roadmaps/` is a sibling of `INDEX.md`, wherever `INDEX.md`
|
|
48
50
|
lives.
|
|
49
51
|
- `## Goal` is a checkable prose condition read by a human or agent, not an executable checker.
|
|
50
|
-
-
|
|
52
|
+
- Batch entries render as checkboxes (`- [x] ... — delivered` / `- [ ] ... — <status>`); a human
|
|
51
53
|
reading cold should see shipped/running/next within a minute. `## Log` lines are one-sentence,
|
|
52
54
|
EM-to-CTO-voice, dated, and link each entry-intent's `outcome.md` (lossless-by-reference).
|
|
53
55
|
- Additive: this skill introduces no gate, lock, or hook, and does not change `INDEX.md`'s section
|
|
@@ -21,15 +21,19 @@ it in the same Close/archive step.
|
|
|
21
21
|
roadmap delivers and which tier (project or global) it lives in.
|
|
22
22
|
2. **`## Goal`** — a checkable prose condition: one or a few sentences a human or coordinator reads
|
|
23
23
|
to decide the roadmap is done. Not an executable checker, not a list of tasks.
|
|
24
|
-
3. **`##
|
|
25
|
-
parallel-safe (can be dispatched together);
|
|
26
|
-
not start until
|
|
24
|
+
3. **`## Batches`** — ordered batches (`### Batch 1`, `### Batch 2`, ...). Entries inside a batch
|
|
25
|
+
are parallel-safe (can be dispatched together); batches run top to bottom, sequentially (batch 2
|
|
26
|
+
does not start until batch 1's entries are no longer `queued`/`delivering`). A roadmap written
|
|
27
|
+
before owner ruling 145 may instead use `## Waves` / `### Wave N`; both headings are accepted
|
|
28
|
+
when reading, but every new roadmap is scaffolded with `## Batches`, and an existing roadmap
|
|
29
|
+
file's heading is never renamed to migrate it.
|
|
27
30
|
4. **`## Log`** — append-only, dated, one line per event. Newest entry at the bottom. Never edit or
|
|
28
31
|
remove an existing log line.
|
|
29
32
|
|
|
30
33
|
## Entry line shape
|
|
31
34
|
|
|
32
|
-
One line per intent, inside its wave,
|
|
35
|
+
One line per intent, inside its batch (or wave, on a roadmap still using the legacy heading), as a
|
|
36
|
+
Markdown checkbox:
|
|
33
37
|
|
|
34
38
|
```
|
|
35
39
|
- [x] <intent-id> <title> — delivered
|
|
@@ -80,8 +84,8 @@ Line shape, one event per line, append-only, newest at the bottom:
|
|
|
80
84
|
|
|
81
85
|
Two-space fields, mirroring the intent-dir cycle-step ledger (`savepoint.md`). The controlled event
|
|
82
86
|
vocabulary: `created`, `dispatched`, `parked`, `merged`, `release`, `handoff`, `closed`, and
|
|
83
|
-
optionally `added`, `reordered`, `wave`. The `(event, detail)` pair is the idempotency key,
|
|
84
|
-
re-appending the same pair is a no-op.
|
|
87
|
+
optionally `added`, `reordered`, `wave`, `batch`. The `(event, detail)` pair is the idempotency key,
|
|
88
|
+
so re-appending the same pair is a no-op.
|
|
85
89
|
|
|
86
90
|
`## Log` and the ledger record the same events in two voices: the Log is the dated, one-sentence,
|
|
87
91
|
EM-to-CTO-plain-language record a human reads cold; the ledger is the terse, machine-timestamped,
|
|
@@ -102,16 +106,16 @@ Delivery-side collection of intents that close out the pre-1.0 hardening pass, p
|
|
|
102
106
|
## Goal
|
|
103
107
|
All intents below are delivered, the suite is green, and a 1.0.0 release is cut.
|
|
104
108
|
|
|
105
|
-
##
|
|
106
|
-
Entries in a
|
|
109
|
+
## Batches
|
|
110
|
+
Entries in a batch are parallel-safe; batches run top to bottom. The checkbox tracks delivered/not;
|
|
107
111
|
the token after the em-dash carries the precise mirrored status (queued | delivering | delivered |
|
|
108
112
|
abandoned | blocked); INDEX wins on any conflict.
|
|
109
113
|
|
|
110
|
-
###
|
|
114
|
+
### Batch 1
|
|
111
115
|
- [x] 121 Fix bash gate redirect parsing — delivered
|
|
112
116
|
- [ ] 130 Proportional cycle tiers — delivering
|
|
113
117
|
|
|
114
|
-
###
|
|
118
|
+
### Batch 2
|
|
115
119
|
- [x] 124 Roadmap feature — delivered
|
|
116
120
|
|
|
117
121
|
## Log
|
|
@@ -16,7 +16,7 @@ next" in under a minute, just from this one file.
|
|
|
16
16
|
3. Copy `templates/roadmap.md` to `roadmaps/{slug}.md`.
|
|
17
17
|
4. Fill the header (`# Roadmap: <title>` + the one-line meta) and write a real `## Goal` prose
|
|
18
18
|
condition.
|
|
19
|
-
5. Add at least one `##
|
|
19
|
+
5. Add at least one `## Batches` batch with real entries (see Add / reorder below), each entry's
|
|
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.
|
|
@@ -28,18 +28,20 @@ next" in under a minute, just from this one file.
|
|
|
28
28
|
|
|
29
29
|
## Add / reorder entries
|
|
30
30
|
|
|
31
|
-
- **Add**: append an entry line (`- <intent-id> <title> — <status>`) to the target
|
|
31
|
+
- **Add**: append an entry line (`- <intent-id> <title> — <status>`) to the target batch. Pick the
|
|
32
32
|
intent's title and status straight from `INDEX.md`.
|
|
33
|
-
- **New
|
|
34
|
-
every earlier
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
- **New batch**: add a new `### Batch N` heading after the last batch; entries in it are gated
|
|
34
|
+
behind every earlier batch's entries leaving `queued`/`delivering`. A roadmap still on the legacy
|
|
35
|
+
`## Waves` heading keeps using `### Wave N` for a new entry; never migrate an existing roadmap's
|
|
36
|
+
heading to add one.
|
|
37
|
+
- **Reorder**: move an entry line to a different batch, or move a `### Batch` (or, on a legacy
|
|
38
|
+
roadmap, `### Wave`) heading (with its entries) earlier or later. Reordering never changes an
|
|
39
|
+
entry's status; it only changes when the entry is eligible to run.
|
|
38
40
|
- After any add/reorder, append a `## Log` line describing the change (e.g.
|
|
39
|
-
`- <YYYY-MM-DD HH:MM UTC> added 132 to
|
|
41
|
+
`- <YYYY-MM-DD HH:MM UTC> added 132 to batch 2`).
|
|
40
42
|
- Append the ledger event (derived, idempotent, safe to re-run; never writes INDEX or roadmap
|
|
41
43
|
status): `ruby ~/.plastic/scripts/roadmap-savepoint append --roadmap roadmaps/<slug>.md --event
|
|
42
|
-
added --detail "<id> to
|
|
44
|
+
added --detail "<id> to batch N"` for an add, or `--event reordered` for a reorder (describe the
|
|
43
45
|
move in `<detail>`).
|
|
44
46
|
- Refresh the QMD index for this roadmap (no-op when QMD is absent), in the background so it
|
|
45
47
|
never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <roadmaps-dir> --async`.
|
|
@@ -70,7 +72,7 @@ next" in under a minute, just from this one file.
|
|
|
70
72
|
edit or delete an existing line (append-only).
|
|
71
73
|
- Every line is plain language a non-expert can read, never a codename or a raw `field -> value`.
|
|
72
74
|
A delivery event follows the EM-to-CTO one-line shape with an `outcome.md` link (see
|
|
73
|
-
`file-format.md`); bookkeeping events (created, an intent added to a
|
|
75
|
+
`file-format.md`); bookkeeping events (created, an intent added to a batch, a batch completed, a
|
|
74
76
|
roadmap closed) are short dated plain-language lines.
|
|
75
77
|
- Append the matching ledger event (derived, idempotent, never writes INDEX or roadmap status):
|
|
76
78
|
when the line records a release cut, `ruby ~/.plastic/scripts/roadmap-savepoint append --roadmap
|
|
@@ -81,14 +83,16 @@ next" in under a minute, just from this one file.
|
|
|
81
83
|
|
|
82
84
|
## Read / consume
|
|
83
85
|
|
|
84
|
-
- A human reading the file gets the current picture directly: `## Goal` for the target, `##
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
`outcome.md` for
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
`
|
|
91
|
-
|
|
86
|
+
- A human reading the file gets the current picture directly: `## Goal` for the target, `## Batches`
|
|
87
|
+
(or, on a roadmap still using the legacy `## Waves` heading, that section instead) for what is
|
|
88
|
+
queued/delivering/delivered per batch (checkboxes give the shipped/not-shipped view at a glance),
|
|
89
|
+
`## Log` for a one-line, plain-language history with a link into each intent's `outcome.md` for
|
|
90
|
+
detail.
|
|
91
|
+
- A future coordinator (for example, an auto-mode dispatcher) reads the grouping section
|
|
92
|
+
(`## Batches`, or legacy `## Waves`) top to bottom: a batch is eligible to dispatch once every
|
|
93
|
+
entry in the previous batch is no longer `queued`/`delivering`; within an eligible batch, entries
|
|
94
|
+
still `queued` are parallel-dispatchable. Always re-sync against `INDEX.md` before dispatch
|
|
95
|
+
decisions, since INDEX is the source of truth.
|
|
92
96
|
|
|
93
97
|
## Close / archive
|
|
94
98
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: plastic-roadmap-continuing
|
|
3
3
|
description: >-
|
|
4
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
|
|
5
|
+
asks "where is the roadmap", or wants to resume the batch that was shipping, including an
|
|
6
6
|
indirect ask that never names a roadmap directly (for example "where did that batch of
|
|
7
7
|
intents land"). This is the roadmap route of plastic-continuing: it finds the tier's
|
|
8
8
|
mid-flight roadmap, presents its state, then asks how to proceed exactly once.
|
|
@@ -27,7 +27,7 @@ roadmap handoff had to be resumed by hand, carried as a free-prose note in `171`
|
|
|
27
27
|
2. For each candidate, also read its paired ledger `roadmaps/<slug>.savepoint.md` when present
|
|
28
28
|
(see `plastic-roadmap`'s `references/file-format.md#savepoint-ledger`): its last line(s) are a
|
|
29
29
|
cheaper, precise last-event signal (for example `dispatched 134` or `merged 172`), read
|
|
30
|
-
alongside the existing `## Waves
|
|
30
|
+
alongside the existing `## Batches` (or legacy `## Waves`) / `## Log` judgment. The ledger is read-only here, a derived
|
|
31
31
|
signal, never a new status field; INDEX.md stays the sole status writer.
|
|
32
32
|
3. Rank liveness by calling the shared reader in which mode (one implementation across the
|
|
33
33
|
auto loop and this skill):
|
|
@@ -47,7 +47,7 @@ roadmap handoff had to be resumed by hand, carried as a free-prose note in `171`
|
|
|
47
47
|
|
|
48
48
|
## Present state
|
|
49
49
|
|
|
50
|
-
Present the chosen roadmap's `## Goal`, the current
|
|
50
|
+
Present the chosen roadmap's `## Goal`, the current batch with each entry's mirrored status, the
|
|
51
51
|
ledger's newest line(s) (the last mechanized event) alongside the newest `## Log` line, before any
|
|
52
52
|
ask, so the coordinator sees the machine last-event at a glance.
|
|
53
53
|
|
|
@@ -56,7 +56,7 @@ ask, so the coordinator sees the machine last-event at a glance.
|
|
|
56
56
|
Ask "auto or guided?" exactly once, after presenting state, mirroring
|
|
57
57
|
`plastic-intent-starting`'s single-ask contract:
|
|
58
58
|
- **guided** -> continue step by step with the user.
|
|
59
|
-
- **auto** -> hand off to `plastic-auto` to drive the next
|
|
59
|
+
- **auto** -> hand off to `plastic-auto` to drive the next batch or entry.
|
|
60
60
|
|
|
61
61
|
Never re-ask. No new roadmap or INDEX status field is invented anywhere in this flow.
|
|
62
62
|
|
|
@@ -78,7 +78,7 @@ This skill is a reader, not a writer, of `roadmaps/<slug>.savepoint.md`. The coo
|
|
|
78
78
|
~/.plastic/scripts/roadmap-savepoint append` at their own dispatch, merge, park, handoff, and
|
|
79
79
|
release points, the same events `plastic-roadmap`'s verbs append at their closing steps. A
|
|
80
80
|
resuming coordinator therefore both reads the ledger here and writes to it as it drives the next
|
|
81
|
-
|
|
81
|
+
batch or entry.
|
|
82
82
|
|
|
83
83
|
## References
|
|
84
84
|
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"id": 4, "scope": "behavior", "set": "train",
|
|
38
|
-
"prompt": "Does the skill rank liveness correctly when a
|
|
39
|
-
"expected_output": "A roadmap with any delivering/blocked
|
|
38
|
+
"prompt": "Does the skill rank liveness correctly when a batch entry is delivering or blocked?",
|
|
39
|
+
"expected_output": "A roadmap with any delivering/blocked batch entry wins the ranking outright over every other candidate.",
|
|
40
40
|
"files": ["skills/roadmap-continuing/references/liveness-ranking.md"],
|
|
41
41
|
"assertions": [
|
|
42
42
|
{ "type": "convention", "check": "delivering/blocked-wins rule documented as step 2 of the algorithm", "observed": "present", "result": "pass" }
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
{
|
|
55
55
|
"id": 6, "scope": "behavior", "set": "train",
|
|
56
56
|
"prompt": "Does the skill present the roadmap state before asking?",
|
|
57
|
-
"expected_output": "The '## Present state' section (Goal, current
|
|
57
|
+
"expected_output": "The '## Present state' section (Goal, current batch, newest Log line) runs before the '## Ask once' section.",
|
|
58
58
|
"files": ["skills/roadmap-continuing/SKILL.md"],
|
|
59
59
|
"assertions": [
|
|
60
60
|
{ "type": "convention", "check": "Present state precedes Ask once in document order", "observed": "present", "result": "pass" }
|
|
@@ -19,8 +19,9 @@ tier's live `roadmaps/*.md` files (excluding `roadmaps/archived/`), by `RoadmapQ
|
|
|
19
19
|
|
|
20
20
|
1. **Enumerate.** List every `roadmaps/*.md` at the tier (project or global), skipping
|
|
21
21
|
`roadmaps/archived/`.
|
|
22
|
-
2. **Delivering/blocked wins outright.** If any candidate roadmap has at least one
|
|
23
|
-
entry whose mirrored status token is `delivering` or
|
|
22
|
+
2. **Delivering/blocked wins outright.** If any candidate roadmap has at least one grouping-section
|
|
23
|
+
entry (`## Batches`, or legacy `## Waves`) whose mirrored status token is `delivering` or
|
|
24
|
+
`blocked`, it is in flight right now.
|
|
24
25
|
That candidate wins the ranking immediately; skip the rest of the ranking for it.
|
|
25
26
|
3. **Otherwise, newest `## Log` entry wins.** Among the remaining candidates (none have a
|
|
26
27
|
`delivering`/`blocked` entry), read each file's last `## Log` line (append-only, newest at
|
|
@@ -42,8 +43,8 @@ tier's live `roadmaps/*.md` files (excluding `roadmaps/archived/`), by `RoadmapQ
|
|
|
42
43
|
|
|
43
44
|
Before this skill existed, nothing resumed a mid-flight roadmap automatically. The `171`
|
|
44
45
|
(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
|
|
46
|
-
`## Log` and reconstructed where the batch stood. This ranking, now a deterministic reader
|
|
46
|
+
HANDOFF" note written into `171`'s own `## Insights`, because nothing read the grouping section
|
|
47
|
+
(`## Batches`/legacy `## Waves`) + `## Log` and reconstructed where the batch stood. This ranking, now a deterministic reader
|
|
47
48
|
rather than a by-eye judgment, is the mechanism that replaces that hand-carried note.
|
|
48
49
|
|
|
49
50
|
## Grammar pointer (do not duplicate)
|
|
@@ -52,5 +53,5 @@ The roadmap file's four sections, entry line shape, and status vocabulary
|
|
|
52
53
|
(`queued|delivering|delivered|abandoned|blocked`) are owned by `plastic-roadmap`:
|
|
53
54
|
`skills/roadmap/references/file-format.md` for the shape, and
|
|
54
55
|
`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
|
+
coordinator) is meant to walk `## Batches` (or legacy `## Waves`) and `## Log`. This page assumes that grammar and adds
|
|
56
57
|
only the liveness-ranking judgment on top of it.
|
package/skills/tutorial/SKILL.md
CHANGED
|
@@ -59,7 +59,7 @@ remember where they left off.
|
|
|
59
59
|
|
|
60
60
|
## Before any track
|
|
61
61
|
|
|
62
|
-
Every track opens with the same two checks: run `/plastic-update` first
|
|
63
|
-
matches what is actually installed, and work in a sandbox (a
|
|
64
|
-
intent) so nothing real is touched by mistake. Each reference
|
|
65
|
-
skip it even if the user seems experienced.
|
|
62
|
+
Every track opens with the same two checks: run `/plastic-update` first (`$plastic-update` on
|
|
63
|
+
Codex), so the walkthrough matches what is actually installed, and work in a sandbox (a
|
|
64
|
+
throwaway repo, or a global-store intent) so nothing real is touched by mistake. Each reference
|
|
65
|
+
restates this briefly; do not skip it even if the user seems experienced.
|
|
@@ -9,7 +9,8 @@ end to end: a piece of work moved through What, Why, How, and Exec, with a finis
|
|
|
9
9
|
|
|
10
10
|
## Before you start
|
|
11
11
|
|
|
12
|
-
Run `/plastic-update` first, so the commands below match what is
|
|
12
|
+
Run `/plastic-update` first (`$plastic-update` on Codex), so the commands below match what is
|
|
13
|
+
actually installed.
|
|
13
14
|
|
|
14
15
|
Work in a sandbox: this track always creates a global-store intent; the throwaway repo below
|
|
15
16
|
is never registered as a Plastic project. Pick a throwaway git repository if you have one
|
|
@@ -9,7 +9,8 @@ agent end to end, and pausing and resuming that delivery will feel familiar.
|
|
|
9
9
|
|
|
10
10
|
## Before you start
|
|
11
11
|
|
|
12
|
-
Run `/plastic-update` first, so the commands below match what is
|
|
12
|
+
Run `/plastic-update` first (`$plastic-update` on Codex), so the commands below match what is
|
|
13
|
+
actually installed.
|
|
13
14
|
|
|
14
15
|
Work in a sandbox: a throwaway git repository, or a global-store intent. Nothing in this
|
|
15
16
|
track touches a real project.
|
|
@@ -9,7 +9,8 @@ will exist with more than one intent inside it and a roadmap file describing the
|
|
|
9
9
|
|
|
10
10
|
## Before you start
|
|
11
11
|
|
|
12
|
-
Run `/plastic-update` first, so the commands below match what is
|
|
12
|
+
Run `/plastic-update` first (`$plastic-update` on Codex), so the commands below match what is
|
|
13
|
+
actually installed.
|
|
13
14
|
|
|
14
15
|
Work in a sandbox: this whole track is a walked example. It creates a real project directory
|
|
15
16
|
and a real roadmap file on disk, but the project is a throwaway one made for learning, not
|
|
@@ -56,16 +57,16 @@ in the global store.
|
|
|
56
57
|
Type `/plastic-roadmap`.
|
|
57
58
|
|
|
58
59
|
Teach the roadmap file shape exactly: a title and short meta header, a `## Goal` section in
|
|
59
|
-
prose describing what "done" looks like for the whole batch, a `##
|
|
60
|
-
ordered list of groups of intents; intents inside one
|
|
61
|
-
|
|
60
|
+
prose describing what "done" looks like for the whole batch, a `## Batches` section (an
|
|
61
|
+
ordered list of groups of intents; intents inside one batch are safe to run in parallel,
|
|
62
|
+
batches themselves run one after another), and an append-only, dated `## Log`. `INDEX.md`
|
|
62
63
|
stays the single source of truth for each intent's status; the roadmap only mirrors it.
|
|
63
64
|
|
|
64
65
|
Artifact: a new `roadmaps/<slug>.md` file, sitting next to the project's `INDEX.md`, listing
|
|
65
|
-
the two or more intents from station 3 across one or more
|
|
66
|
+
the two or more intents from station 3 across one or more batches.
|
|
66
67
|
|
|
67
|
-
Checkpoint: name which of the two intents from station 3 share a
|
|
68
|
-
parallel) and which one, if any, sits in a later
|
|
68
|
+
Checkpoint: name which of the two intents from station 3 share a batch (so they run in
|
|
69
|
+
parallel) and which one, if any, sits in a later batch (so it waits).
|
|
69
70
|
|
|
70
71
|
### 5. Drive delivery with /goal
|
|
71
72
|
|
|
@@ -74,18 +75,18 @@ and Claude keeps working, turn after turn, until a fast checker model confirms f
|
|
|
74
75
|
Claude has actually reported that the condition holds; `/goal` never reads files on its own,
|
|
75
76
|
so the condition has to name a check Claude's own output can prove.
|
|
76
77
|
|
|
77
|
-
Turn the roadmap's `## Goal` and current `##
|
|
78
|
+
Turn the roadmap's `## Goal` and current `## Batches` into that condition, for example:
|
|
78
79
|
|
|
79
|
-
`/goal every intent in
|
|
80
|
+
`/goal every intent in batch 1 of roadmaps/<slug>.md shows Completed in INDEX.md, and the test
|
|
80
81
|
suite is green`
|
|
81
82
|
|
|
82
|
-
Claude then works through the
|
|
83
|
+
Claude then works through the batch itself, one intent at a time, and stops on its own once the
|
|
83
84
|
checker agrees the condition holds. Run `/goal` with no argument at any point to see how long
|
|
84
85
|
it has run and how many turns it has spent; run `/goal clear` to stop it before that.
|
|
85
86
|
|
|
86
87
|
On a harness without `/goal`, just tell the agent to deliver the roadmap in auto mode instead.
|
|
87
88
|
|
|
88
|
-
Checkpoint: point at the exact file (`roadmaps/<slug>.md`) whose `## Goal` and `##
|
|
89
|
+
Checkpoint: point at the exact file (`roadmaps/<slug>.md`) whose `## Goal` and `## Batches`
|
|
89
90
|
sections you turned into the condition above.
|
|
90
91
|
|
|
91
92
|
### 6. Merge discipline and releases
|
package/skills/update/SKILL.md
CHANGED
|
@@ -57,22 +57,35 @@ unavailable. The command prints the transition (`vX -> vY`) or "already up to da
|
|
|
57
57
|
a post-update doctor summary, and records the move in the append-only
|
|
58
58
|
`~/.plastic/versions.json` ledger.
|
|
59
59
|
|
|
60
|
-
### Step 2:
|
|
61
|
-
|
|
62
|
-
If
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
### Step 2: Relay any pending config question(s) the update printed
|
|
61
|
+
|
|
62
|
+
If `update`'s own output (Step 1) printed a "Config question(s) introduced by
|
|
63
|
+
this update" block, relay each question to the user exactly as printed
|
|
64
|
+
(question, options, and the `write-config` command for each option). Do not
|
|
65
|
+
invent or hardcode a specific question here: it comes from the CLI's fresh
|
|
66
|
+
output (`config_asks.yml`, read by code that just synced from the new version),
|
|
67
|
+
never from this skill file, which is always one release behind and cannot know
|
|
68
|
+
what a future release will ask.
|
|
69
|
+
|
|
70
|
+
Once the user picks an option, run the printed `write-config` command for that
|
|
71
|
+
option, for example:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
ruby ~/.plastic/scripts/write-config advisor.claude.default plastic-faux-advisor
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If they say "not now" / want to keep the default, run the printed dismissal
|
|
78
|
+
command instead, for example:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
ruby ~/.plastic/scripts/write-config config_asks_dismissed --push advisor-default
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If `update` printed nothing under that heading, skip this step silently - there
|
|
85
|
+
is nothing pending. A question already answered or dismissed is never re-asked
|
|
86
|
+
(both the CLI print and the doctor check verify this before showing anything),
|
|
87
|
+
and a pending question missed here still shows up as a `config_asks` warn on
|
|
88
|
+
the next `/plastic-doctor` run, so nothing is silently lost.
|
|
76
89
|
|
|
77
90
|
### Step 3: Relay the result, announce convention changes
|
|
78
91
|
|
|
@@ -98,6 +111,6 @@ report and offer to fix. If it already reads clean, do not re-run doctor.
|
|
|
98
111
|
### Step 5: Commit + clear update cache
|
|
99
112
|
|
|
100
113
|
```bash
|
|
101
|
-
cd ~/.plastic && git add PLASTIC.md scripts/ AGENTS.md VERSION versions.json 2>/dev/null && git commit -m "chore: update Plastic to $(cat ~/.plastic/VERSION)" --allow-empty
|
|
114
|
+
cd ~/.plastic && git add PLASTIC.md scripts/ AGENTS.md VERSION versions.json deprecations.yml config_asks.yml 2>/dev/null && git commit -m "chore: update Plastic to $(cat ~/.plastic/VERSION)" --allow-empty
|
|
102
115
|
rm -f ~/.plastic/.cache/update-check.json
|
|
103
116
|
```
|