@zalom/plastic 1.1.0 → 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.md +4 -2
- package/README.md +3 -3
- package/agents/plastic-enforcer.md +5 -2
- package/agents/plastic-future-intent-researcher.md +1 -1
- 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 +136 -5
- package/scripts/hook-continue +3 -3
- package/scripts/install.rb +2 -1
- package/scripts/lib/bridge.rb +81 -0
- package/scripts/lib/dashboard_banner.rb +8 -9
- package/scripts/lib/installer_core.rb +10 -3
- 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/worktree.rb +21 -0
- package/scripts/new-intent +1 -0
- package/scripts/read-config +3 -3
- package/scripts/roadmap-next +44 -0
- package/scripts/roadmap-savepoint +64 -0
- package/skills/auto/SKILL.md +22 -4
- package/skills/continuing/SKILL.md +34 -0
- package/skills/continuing/evals/evals.json +91 -0
- package/skills/dashboard/SKILL.md +17 -14
- 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 +1 -1
- package/skills/install/SKILL.md +10 -10
- package/skills/intent-continuing/SKILL.md +26 -68
- package/skills/intent-continuing/evals/evals.json +26 -26
- package/skills/intent-continuing/references/context-management.md +15 -19
- package/skills/intent-savepoint/SKILL.md +12 -0
- package/skills/intent-starting/evals/evals.json +1 -1
- 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/releasing/SKILL.md +48 -0
- 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/skill-evaluating/evals/evals.json +1 -1
- package/skills/tutorial/references/track-2-auto.md +1 -1
- package/skills/uninstall/SKILL.md +2 -2
- package/skills/update/SKILL.md +2 -2
- package/templates/config.yml +2 -1
- package/templates/index.md +4 -1
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.
|
|
@@ -72,7 +72,7 @@ line.
|
|
|
72
72
|
|
|
73
73
|
### 5. Continue and where-was-I after time away
|
|
74
74
|
|
|
75
|
-
Type `/plastic-
|
|
75
|
+
Type `/plastic-continuing`.
|
|
76
76
|
|
|
77
77
|
Artifact: the current state, presented and then the session stops. If a specific intent is
|
|
78
78
|
named, the agent reads its stage and savepoint and resumes exactly there, rather than
|
|
@@ -14,7 +14,7 @@ underlying uninstaller and adds reporting + verification.
|
|
|
14
14
|
|
|
15
15
|
If Plastic is installed, derive `<channel>` from `~/.plastic/VERSION`: a version containing
|
|
16
16
|
`-alpha` means `@alpha`, `-beta` means `@beta`, otherwise `@latest`. If not installed,
|
|
17
|
-
default to `@
|
|
17
|
+
default to `@latest`. The user can always override with `--alpha` / `--beta` / `--latest`.
|
|
18
18
|
|
|
19
19
|
## Procedure
|
|
20
20
|
|
|
@@ -74,5 +74,5 @@ Delete it too?
|
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
- **Keep:** "Your data is at ~/.plastic/. Re-install anytime with
|
|
77
|
-
`npx -y @zalom/plastic@
|
|
77
|
+
`npx -y @zalom/plastic@latest install --claude` (or your channel)."
|
|
78
78
|
- **Delete:** run `rm -rf ~/.plastic/` and confirm.
|
package/skills/update/SKILL.md
CHANGED
|
@@ -22,7 +22,7 @@ clean no-op. You do not compute the target yourself, the script does.
|
|
|
22
22
|
|
|
23
23
|
If Plastic is installed, derive `<channel>` from `~/.plastic/VERSION`: a version containing
|
|
24
24
|
`-alpha` means `@alpha`, `-beta` means `@beta`, otherwise `@latest`. If not installed
|
|
25
|
-
(first install), default to `@
|
|
25
|
+
(first install), default to `@latest`. The user can always override with
|
|
26
26
|
`--alpha` / `--beta` / `--latest`.
|
|
27
27
|
|
|
28
28
|
## Flags
|
|
@@ -40,7 +40,7 @@ confirmed. To roll **back** to a previously-installed version, use `plastic-roll
|
|
|
40
40
|
## Prerequisites
|
|
41
41
|
|
|
42
42
|
Plastic must be installed (`~/.plastic/VERSION` present). If not, run `plastic-install`
|
|
43
|
-
first (or `npx -y @zalom/plastic@
|
|
43
|
+
first (or `npx -y @zalom/plastic@latest install --claude` directly).
|
|
44
44
|
|
|
45
45
|
## Procedure
|
|
46
46
|
|
package/templates/config.yml
CHANGED
|
@@ -14,7 +14,8 @@ architect:
|
|
|
14
14
|
|
|
15
15
|
# Per-agent model override (intent 116). Uncomment and set to a Claude Code
|
|
16
16
|
# alias (opus, sonnet, haiku) to override the shipped tier for one agent. With
|
|
17
|
-
# no entry, the shipped default applies
|
|
17
|
+
# no entry, the shipped default applies and never resolves to Fable; naming
|
|
18
|
+
# Fable here is an explicit, sanctioned override, honored as written.
|
|
18
19
|
# agents:
|
|
19
20
|
# models:
|
|
20
21
|
# plastic-executor: sonnet
|
package/templates/index.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
# Index
|
|
2
2
|
|
|
3
3
|
## Active
|
|
4
|
+
<!-- Line shape: `- [ID — Title](path)`. The em-dash (U+2014, not a plain hyphen)
|
|
5
|
+
between id and title is load-bearing: Bridge.intent_active? matches only that
|
|
6
|
+
shape, and a plain hyphen there fails the lock gate open (see docs/internals.md). -->
|
|
4
7
|
(no active intents)
|
|
5
8
|
|
|
6
9
|
## Future
|
|
7
10
|
(no future intents)
|
|
8
11
|
|
|
9
12
|
## Clusters
|
|
10
|
-
(clusters emerge as intents accumulate
|
|
13
|
+
(clusters emerge as intents accumulate; add headings when 3+ intents share a topic)
|
|
11
14
|
|
|
12
15
|
## Completed
|
|
13
16
|
(links preserved, never deleted)
|