@zalom/plastic 2.0.0-alpha.2 → 2.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/agents/plastic-enforcer.md +3 -1
  2. package/agents/plastic-executor.md +9 -3
  3. package/hooks/hooks.json +12 -0
  4. package/hooks/message-display +134 -0
  5. package/hooks/statusline +4 -27
  6. package/package.json +2 -2
  7. package/scripts/agent-report +8 -2
  8. package/scripts/dashboard.rb +297 -18
  9. package/scripts/doctor.rb +652 -5
  10. package/scripts/end-intent +219 -0
  11. package/scripts/hook-capture +25 -113
  12. package/scripts/hook-message-display +81 -0
  13. package/scripts/hook-record +12 -4
  14. package/scripts/hook-session-start +23 -1
  15. package/scripts/index-projection +74 -0
  16. package/scripts/intent-screen +77 -0
  17. package/scripts/lib/action_graph_shim.rb +277 -0
  18. package/scripts/lib/arm.rb +26 -1
  19. package/scripts/lib/atomic_write.rb +31 -0
  20. package/scripts/lib/core_integrity.rb +71 -0
  21. package/scripts/lib/dashboard_screen.rb +40 -0
  22. package/scripts/lib/day_summary.rb +7 -2
  23. package/scripts/lib/doctor_core.rb +101 -5
  24. package/scripts/lib/doctor_session_ledger.rb +52 -0
  25. package/scripts/lib/graph_edges.rb +121 -0
  26. package/scripts/lib/graph_file.rb +246 -0
  27. package/scripts/lib/graph_tree.rb +98 -0
  28. package/scripts/lib/guarded_append.rb +155 -0
  29. package/scripts/lib/hook_registry.rb +14 -0
  30. package/scripts/lib/hook_replay.rb +211 -0
  31. package/scripts/lib/index_projection.rb +201 -0
  32. package/scripts/lib/installer_core.rb +131 -4
  33. package/scripts/lib/intent_screen.rb +309 -0
  34. package/scripts/lib/intent_screen_ansi.rb +262 -0
  35. package/scripts/lib/message_display.rb +586 -0
  36. package/scripts/lib/node_file.rb +214 -0
  37. package/scripts/lib/node_ids.rb +99 -0
  38. package/scripts/lib/node_ledger.rb +377 -0
  39. package/scripts/lib/node_packet.rb +886 -0
  40. package/scripts/lib/node_return.rb +199 -0
  41. package/scripts/lib/node_worktree.rb +337 -0
  42. package/scripts/lib/outcome_report.rb +440 -0
  43. package/scripts/lib/packet_wrapper.rb +132 -0
  44. package/scripts/lib/ready_set.rb +462 -0
  45. package/scripts/lib/release_guard.rb +16 -0
  46. package/scripts/lib/report_screen.rb +1967 -0
  47. package/scripts/lib/roadmap_graph.rb +210 -0
  48. package/scripts/lib/roadmap_migration.rb +95 -0
  49. package/scripts/lib/roadmap_queue.rb +155 -5
  50. package/scripts/lib/roadmap_render.rb +150 -0
  51. package/scripts/lib/roadmap_savepoint.rb +62 -12
  52. package/scripts/lib/runner_absorb.rb +620 -0
  53. package/scripts/lib/runner_answer.rb +206 -0
  54. package/scripts/lib/runner_core.rb +194 -0
  55. package/scripts/lib/runner_dispatch.rb +482 -0
  56. package/scripts/lib/runner_policy.rb +142 -0
  57. package/scripts/lib/runner_proposals.rb +254 -0
  58. package/scripts/lib/runner_rewind.rb +201 -0
  59. package/scripts/lib/runner_sweep.rb +231 -0
  60. package/scripts/lib/savepoint.rb +149 -12
  61. package/scripts/lib/screen_paint.rb +555 -0
  62. package/scripts/lib/screens/dashboard.rb +20 -0
  63. package/scripts/lib/screens/plan.rb +18 -0
  64. package/scripts/lib/screens/roadmap.rb +15 -0
  65. package/scripts/lib/session_git.rb +49 -18
  66. package/scripts/lib/session_ledger.rb +128 -0
  67. package/scripts/lib/verify_intent.rb +33 -0
  68. package/scripts/lib/work_graph_validator.rb +201 -0
  69. package/scripts/node-packet +92 -0
  70. package/scripts/node-transition +291 -0
  71. package/scripts/outcome-report +74 -0
  72. package/scripts/plastic-lock +8 -1
  73. package/scripts/ready-set +126 -0
  74. package/scripts/release-check +118 -0
  75. package/scripts/report-screen +281 -0
  76. package/scripts/roadmap-graph +119 -0
  77. package/scripts/roadmap-savepoint +7 -0
  78. package/scripts/runner +392 -0
  79. package/scripts/savepoint-note +69 -0
  80. package/scripts/spawn-preamble +9 -2
  81. package/scripts/validate-work-graph +39 -0
  82. package/scripts/verify-intent +2 -1
  83. package/skills/auto/SKILL.md +24 -17
  84. package/skills/auto/references/human-report-contract.md +136 -54
  85. package/skills/conventions/references/locks-and-worktrees.md +12 -0
  86. package/skills/dashboard/SKILL.md +13 -2
  87. package/skills/dashboard/templates/dashboard-global.md +1 -1
  88. package/skills/dashboard/templates/dashboard-project.md +2 -2
  89. package/skills/doctor/SKILL.md +10 -4
  90. package/skills/intent-continuing/SKILL.md +51 -41
  91. package/skills/intent-continuing/references/board-fill.md +9 -0
  92. package/skills/intent-continuing/references/boarding-matrix.md +6 -5
  93. package/skills/intent-continuing/references/context-management.md +1 -1
  94. package/skills/intent-ending/SKILL.md +36 -16
  95. package/skills/intent-executing/SKILL.md +17 -5
  96. package/skills/intent-executing/implementer-prompt.md +6 -1
  97. package/skills/intent-speccing/SKILL.md +7 -4
  98. package/skills/releasing/SKILL.md +39 -0
  99. package/skills/releasing/references/promotion-and-tagging.md +10 -6
  100. package/skills/releasing/references/release-lines.md +1 -1
  101. package/skills/roadmap/SKILL.md +26 -0
  102. package/skills/roadmap/references/file-format.md +10 -0
  103. package/templates/dashboard-screen.md +22 -0
  104. package/templates/display-fixture.md +21 -0
  105. package/templates/graph.md +16 -0
  106. package/templates/intent-screen.md +17 -0
  107. package/templates/node-decision.md +11 -0
  108. package/templates/node-research.md +11 -0
  109. package/templates/node-verify.md +13 -0
  110. package/templates/node-work.md +22 -0
  111. package/templates/outcome.md +19 -1
  112. package/templates/report-plan.md +15 -0
  113. package/templates/report-roadmap-delivered.md +10 -0
  114. package/templates/report-roadmap-plan.md +9 -0
  115. package/templates/report-roadmap-state.md +9 -0
  116. package/templates/report-state.md +11 -0
  117. package/templates/roadmap.md +13 -0
@@ -51,21 +51,39 @@ on disk is what the record becomes, so before the call:
51
51
  reported gap that lands verbatim in the backfilled `## Follow-ups`.
52
52
  2. Confirm every acceptance criterion in spec.md is verifiable (tests pass,
53
53
  or the manual check described in its HOW line was actually run).
54
- 3. Decide what you have to say. A spec.md, plan.md, action file, or outcome.md
55
- left as the scaffold placeholder is written from the record by
56
- `scripts/end-intent` (the intent file's `## Intent`, `### Decisions`, and
57
- `## Insights`, the checklist, the diff on the intent's own worktree). A
58
- file you wrote, even under a still-present sentinel, is never touched.
59
- Write outcome.md yourself when the summary deserves more than the
60
- `--outcome-summary` line; otherwise let the backfill carry it.
54
+ 3. Decide what you have to say. For an intent with a `graph.md`, `outcome.md` is
55
+ GENERATED by `scripts/end-intent` itself, through `scripts/lib/outcome_report.rb`
56
+ (`scripts/outcome-report` is its standalone CLI, useful for checking the
57
+ generated text before the close): `## Delivered`, `## Verification`,
58
+ `## Graph diff`, and `## Findings` are read straight from `graph.md`, `nodes/`,
59
+ and the ledger every time, never hand-typed. `## Summary`, `## Needs you`, and
60
+ `## Follow-ups`, and every frontmatter key but `disposition`, are preserved
61
+ byte for byte when you author them and generated as plain facts otherwise, so
62
+ writing a summary yourself still works exactly as before. For an intent with
63
+ no `graph.md`, or when the generated text would be refused by the close's own
64
+ gates, a spec.md, plan.md, action file, or outcome.md left as the scaffold
65
+ placeholder is written from the record by `scripts/end-intent` (the intent
66
+ file's `## Intent`, `### Decisions`, and `## Insights`, the checklist, the
67
+ diff on the intent's own worktree). A file you wrote, even under a
68
+ still-present sentinel, is never touched.
61
69
 
62
70
  ### Step 1-5. Run `scripts/end-intent`
63
71
 
64
- Author outcome.md yourself when it deserves prose: copy `templates/outcome.md`,
65
- set the frontmatter to `disposition: delivered` or `disposition: abandoned`, and
66
- fill `## Summary`, `## Delivered`, `## Verification`, `## Follow-ups`. On
67
- abandon, `## Summary` states the abandonment reason and the trail (see Pivot
68
- below). A placeholder outcome.md is backfilled from the record instead, with the
72
+ Author outcome.md yourself when the summary deserves more prose than the generator's
73
+ plain facts: copy `templates/outcome.md`, set the frontmatter to `disposition: delivered`
74
+ or `disposition: abandoned`, and fill `## Summary`, `## Delivered`, `## Verification`,
75
+ `## Follow-ups`. `## Delivered` is a `| Row | What |` table: one row per thing delivered,
76
+ in plain wording a reader recognizes, not a method name or an implementation summary
77
+ (that detail belongs in `## Summary`). Each row's label must appear as a standalone token
78
+ in an action-file heading (or a node-file heading, for an intent whose graph replaces
79
+ actions/ with nodes/) that owns the matrix table (`### S1 - ...` or
80
+ `## n1 failure-mode matrix` with a table beneath it proves that row; a table-less
81
+ heading naming the label is skipped); that heading's matrix rows become the row's
82
+ Proven-by cell on `report-screen delivered`'s post-delivery screen. `## Needs you` is
83
+ the literal None or a `| N | What | Why |` table. On abandon, `## Summary` states the
84
+ abandonment reason and the trail (see Pivot below). An intent with a `graph.md` and no
85
+ hand-written outcome.md gets one generated instead (Step 0.3 above); a placeholder
86
+ outcome.md on an intent with no `graph.md` is backfilled from the record, with the
69
87
  close's disposition and the `--outcome-summary` line as its summary. Also author
70
88
  the rich INDEX entry note now (a short line in the store's existing
71
89
  Completed/Abandoned convention: mode, what shipped or why it was
@@ -138,11 +156,13 @@ ruby ~/.plastic/scripts/qmd-sync reindex --store <store-root> --async
138
156
  No-op when QMD is absent. Runs in the background so it never blocks the
139
157
  turn.
140
158
 
141
- ### Step 7. EM-to-CTO report
159
+ ### Step 7. Print `delivered`
142
160
 
143
- Brief the human like an engineering manager to a CTO: impact and risk first,
144
- in plain language, the decision left to them (merge, release, or accept).
145
- See `outcome.md` for the details; do not restate it verbatim.
161
+ Print `ruby ~/.plastic/scripts/report-screen delivered <intent_dir>` as the first characters
162
+ of the reply: nothing before it, no fence, or the hook cannot paint it. Asked, Delivered (with
163
+ its Proven-by column), Evidence, and Needs you come straight from the record - the EM-to-CTO
164
+ report, impact and risk first, in plain language, with the decision left to the human (merge,
165
+ release, or accept). See `outcome.md` for the details; do not restate it verbatim.
146
166
 
147
167
  ## Abandoned is the same procedure
148
168
 
@@ -61,6 +61,10 @@ Run Step 0 (Sync Worktree First) before this step.
61
61
 
62
62
  Dispatch ONE executor subagent and give it the whole delivery: every task's full text from `plan.md` (pasted in, never a file reference), every action file with its failure-mode matrix, the checklist items it must tick, the project context from CLAUDE.md, the active intent context from `{ID}--{slug}.md`, and the worktree path. In auto mode this is the `plastic-executor` agent; elsewhere use the `implementer-prompt.md` template. The executor writes the matrix's tests and commits them red, implements the consolidated action in order, ticks each item as it lands (see `## Tick-as-you-land`), and drives the test suite green.
63
63
 
64
+ After each commit lands (the red commit and every commit after it), append a `Commit` line to the savepoint ledger: `ruby ~/.plastic/scripts/savepoint-note <intent_dir> --kind Commit --text "<sha> <what it proves>"` (intent 317, D17). This is what feeds `report-screen delay`; a commit with no line is a gap the delay report cannot explain.
65
+
66
+ Print `ruby ~/.plastic/scripts/report-screen state <intent_dir> --changed "<what just landed>"` as the first characters of the reply, nothing before it, no fence, right after the red commit and again once the suite goes green (intent 331f).
67
+
64
68
  Read its response by code:
65
69
  - DONE or DONE_WITH_CONCERNS → proceed to Step 3.
66
70
  - NEEDS_CONTEXT → provide the missing context, re-dispatch the executor.
@@ -69,6 +73,10 @@ Read its response by code:
69
73
  ### Step 3: Review by Risk
70
74
  Apply the auto skill's risk rule to the executor's return and the diff: a matrix row no test could prove, a diff touching a hook, the lock, the worktree code, the installer, or a release file, a DONE_WITH_CONCERNS or a deviation from the matrix, or an owner-facing surface no test pins. When a rule fires, dispatch the post-execution reviewer with `code-quality-reviewer-prompt.md` (a separate agent with fresh context, never the maker); if it returns changes, re-dispatch the executor to fix them, then run the suite once more. When no rule fires, the green suite is the review.
71
75
 
76
+ Whenever a review verdict returns - the plan review before code, or the post-execution review above - the lead appends a `Review` line: `ruby ~/.plastic/scripts/savepoint-note <intent_dir> --kind Review --text "<verdict, what changed>"` (intent 317, D17). This is the other half of what `report-screen delay` reads.
77
+
78
+ **The D19 heading convention.** An action file's `## Delivered` row (in `outcome.md`) is proven by the first `actions/ACTION_N.md` OR `nodes/*.md` heading that carries that row's label as a standalone token AND owns the matrix table (322 D1r, 334 D10r) - `### Row A -` with a table beneath it proves row A, `### S1 -` proves row S1, `## n1 failure-mode matrix` proves row n1; a heading that only names the label, with no table under it, is skipped. Readers check `actions/` first, then `nodes/` (334 D15r). Write action-file or node-file section headings so the label they prove is unambiguous (never a substring another label could also match, like `A` inside `AB`); `report-screen delivered`'s Proven-by column renders `not recorded` when no heading owns a matching table and no matrix row cell carries the label either.
79
+
72
80
  ### Step 4: Update Intent and Complete
73
81
  Capture observations in `## Insights`. When ALL checklist items are checked:
74
82
 
@@ -102,11 +110,15 @@ Capture observations in `## Insights`. When ALL checklist items are checked:
102
110
 
103
111
  ## Tick-as-you-land
104
112
 
105
- As each task lands, in the same edit: move its checklist item from `## In
106
- Progress` to `## Completed` in `checklist.md`, and add one `## Session Log`
107
- row (Date, Items Completed, Notes). Do not batch several tasks' worth of
108
- checklist updates into one later edit; tick the moment the task is verified,
109
- before moving to the next task.
113
+ A tick is two edits, made together: mark the item's box `[x]`, and move its
114
+ checklist item from `## In Progress` to `## Completed` in `checklist.md`;
115
+ then add one `## Session Log` row (Date, Items Completed, Notes). The box is
116
+ the half the state screen's Progress bar reads: `IntentScreen::ITEM_RE` and
117
+ `progress_fields` count `[x]`, not which section the line sits in, so a line
118
+ moved to `## Completed` with its box left unmarked still reads as zero
119
+ progress. Do not batch several tasks' worth of checklist updates into one
120
+ later edit; tick the moment the task is verified, before moving to the next
121
+ task.
110
122
 
111
123
  ## Verify before every owner review
112
124
 
@@ -20,12 +20,17 @@ You are implementing a specific task from a plan. You have been given the full t
20
20
  2. Implement exactly what the task specifies — nothing more, nothing less.
21
21
  3. Write tests first when the task includes test steps (TDD).
22
22
  4. Follow the file paths specified in the task exactly.
23
- 5. Commit after each logical unit of work.
23
+ 5. Commit after each logical unit of work, and in the same step tick the checklist item that
24
+ unit lands: mark its box `[x]` and move the line to `## Completed`, then append the
25
+ savepoint `Commit` line
26
+ (`scripts/savepoint-note <intent_dir> --kind Commit --text "<sha> <what it proves>"`). A
27
+ commit without its tick is incomplete.
24
28
  6. When done, self-review against this checklist:
25
29
  - [ ] All steps in the task are completed
26
30
  - [ ] Tests pass
27
31
  - [ ] Code is clean and follows project conventions
28
32
  - [ ] No unrelated changes
33
+ - [ ] Every landed unit's checklist item is ticked
29
34
 
30
35
  ## Report Format
31
36
 
@@ -111,10 +111,13 @@ When the rulings are enough to build from:
111
111
  rulings say more than the record already does.
112
112
  3. **Self-verify.** Read `references/self-verify-checklist.md` before presenting; fix any
113
113
  failing check and re-verify from the top.
114
- 4. **Present and hand off.** Present `spec.md` and the action files. Then offer the routes:
115
- run it now inline when the work is small enough for direct mode; hand to `plastic-auto`
116
- when the owner says auto and the checklist above passes (all decisions resolved, scope
117
- bounded, dependencies named, success criteria defined); or keep thinking.
114
+ 4. **Present and hand off.** Print `ruby ~/.plastic/scripts/report-screen plan <intent_dir>` as
115
+ the first characters of the reply: nothing before it, no fence, or the hook cannot paint it.
116
+ It carries Asked, Decisions, Steps, Mode, Reviewer, then the Steps and Risks tables, filled
117
+ from `spec.md` and the action files just written, never restated by eye. Then offer the
118
+ routes: run it now inline when the work is small enough for direct mode; hand to
119
+ `plastic-auto` when the owner says auto and the checklist above passes (all decisions
120
+ resolved, scope bounded, dependencies named, success criteria defined); or keep thinking.
118
121
 
119
122
  Report, in this order: which files were written (`spec.md` new or rewritten, the action
120
123
  files), the count of acceptance criteria, which `## Insights` rulings superseded an earlier
@@ -206,6 +206,45 @@ The dist-tag is derived from the version string in `package.json`:
206
206
  - Contains `-beta` → `--tag beta`
207
207
  - No pre-release suffix → no `--tag` flag (publishes to `latest`)
208
208
 
209
+ #### `npm_publish_workflow`
210
+
211
+ The tag pushed in step 6 starts the project's publish workflow (GitHub Actions, keyed on the
212
+ workflow file `publish.yml`) instead of a local `npm publish`. The workflow runs with a
213
+ short-lived, per-run OIDC credential, so no npm token exists in this session or on this
214
+ machine.
215
+
216
+ 1. **Confirm a run exists for the tag.** A tag cut from a ref that does not carry the
217
+ workflow starts no run at all, and silence would read as success:
218
+
219
+ ```bash
220
+ gh run list --workflow publish.yml --limit 5
221
+ ```
222
+
223
+ 2. **Follow the run.**
224
+
225
+ ```bash
226
+ gh run watch <run-id>
227
+ ```
228
+
229
+ 3. **Verify the registry, not just the run.** The release is not done until the new version
230
+ shows up on the expected channel:
231
+
232
+ ```bash
233
+ npm view <package> dist-tags
234
+ ```
235
+
236
+ The dist-tag is derived from the version string in `package.json`, the same rule
237
+ `ReleaseGuard.dist_tag` implements:
238
+
239
+ | Version contains | dist-tag |
240
+ | --- | --- |
241
+ | `-alpha` | `alpha` |
242
+ | `-beta` | `beta` |
243
+ | no pre-release suffix | `latest` |
244
+
245
+ Do not run `npm whoami` on this path. npm documents that `whoami` does not reflect OIDC
246
+ authentication, so on a workflow-published project it can only mislead.
247
+
209
248
  #### Other values
210
249
 
211
250
  If `on_green` contains an action not listed above, log it:
@@ -34,18 +34,22 @@ cleared is a no-op.
34
34
  ## Promotion
35
35
 
36
36
  Promotion is not a CLI flag; there is no `--promote` command. It is a set of steps the
37
- agent performs during the releasing workflow, reusing the normal release mechanics
38
- (version bump, tag, `npm publish` with the channel's dist-tag, GitHub release):
37
+ agent performs during the releasing workflow, reusing the normal release mechanics (version
38
+ bump, tag, GitHub release). For a project on the `npm_publish_workflow` post-push action,
39
+ the tag push itself starts the publish; there is no local publish command to run.
39
40
 
40
41
  ```bash
41
- # Promote alpha → beta: set version files from -alpha.N to -beta.1, commit, tag, then
42
- npm publish --access public --tag beta
42
+ # Promote alpha → beta: set version files from -alpha.N to -beta.1, commit, tag, push.
43
+ # The publish workflow reads the new version and publishes to the beta dist-tag.
43
44
 
44
45
  # Promote beta → stable: strip the pre-release suffix (e.g., 1.0.0-beta.3 → 1.0.0),
45
- # commit, tag, then
46
- npm publish --access public # no --tag flag publishes to latest
46
+ # commit, tag, push. The publish workflow reads the new version and publishes to latest.
47
47
  ```
48
48
 
49
+ A project still on the `npm_publish` action (publishing locally from the session) runs
50
+ `npm publish --access public --tag <channel>` at this point instead, per that action's own
51
+ section in SKILL.md.
52
+
49
53
  **Promotion rules:**
50
54
  - Linear only: alpha → beta → stable. Cannot skip channels.
51
55
  - Version files are bumped and committed as in a normal release.
@@ -78,7 +78,7 @@ re-deriving this decision.
78
78
  of 1.1.0, versioned `1.2.0-beta.1` (`c48601a`). There is nothing left to execute on the git side;
79
79
  this playbook describes what happens next, not a pending action.
80
80
 
81
- **Preconditions**, both required before any npm publish of `1.2.0-beta.1`:
81
+ **Preconditions**, both required before any publish of `1.2.0-beta.1`:
82
82
 
83
83
  - (a) One documentation pass over beta-line skills and docs for the hybrid savepoint contract:
84
84
  on beta, only the terminal Done bookend still writes a live `savepoint.md`; every other
@@ -43,10 +43,36 @@ See `references/file-format.md` for the exact entry-line shape, status vocabular
43
43
  format, and a worked example. See `references/operations.md` for step-by-step mechanics of each
44
44
  verb above.
45
45
 
46
+ ## Graph (intent 337)
47
+
48
+ A roadmap may carry an optional `## Graph` section - the same `needs` edge grammar as an
49
+ intent's own `graph.md` (`- <id> needs <id> <id>`, or `- <id> needs nothing` for a root). When
50
+ present, batches are computed from it (`roadmap-graph check`/`render`), not hand-ordered; the
51
+ template scaffolds a fenced example so a new roadmap starts with the section already in place.
52
+ Three verbs, all `--dry-run`-able:
53
+
54
+ | Verb | What it does |
55
+ |------|--------------|
56
+ | `roadmap-graph check <roadmap.md>` | Prints the computed batches, the ready set, and any dangling id (a graph names it, no batch lists it); exits 1 on a cyclic graph or a dangling id. |
57
+ | `roadmap-graph render <roadmap.md>` | Writes `## Tree` (a box-drawing render of the graph) and regroups the batch/wave section from the computed batches, entry lines carried over verbatim. |
58
+ | `roadmap-graph migrate <roadmap.md>` | Derives a conservative `## Graph` for a graphless roadmap from its existing batch order (batch N needs every entry of batch N-1); never overwrites an existing graph. |
59
+
60
+ A roadmap with no `## Graph` section keeps working exactly as before (wave-order dispatch); the
61
+ graph is additive, never required.
62
+
46
63
  Read `../plastic-conventions/references/roadmaps.md` for the roadmap file format, batch
47
64
  semantics, and the status-mirror rule that this skill's own file-format reference builds on. This
48
65
  path resolves relative to this skill's own installed directory.
49
66
 
67
+ ## Reports (intent 331f)
68
+
69
+ Each verb prints its report screen as the first characters of the reply: nothing before it, no
70
+ fence, or the hook cannot paint it.
71
+
72
+ - Create prints `ruby ~/.plastic/scripts/report-screen roadmap <roadmap.md> plan`.
73
+ - Read / consume prints `ruby ~/.plastic/scripts/report-screen roadmap <roadmap.md> state`.
74
+ - Close / archive prints `ruby ~/.plastic/scripts/report-screen roadmap <roadmap.md> delivered`.
75
+
50
76
  ## Notes
51
77
 
52
78
  - File location and the four-section shape are identical across tiers; do not invent a different
@@ -96,6 +96,16 @@ The ledger is derived and rebuildable (`ruby ~/.plastic/scripts/roadmap-savepoin
96
96
  roadmaps/{slug}.md`, reconstructing it from `## Log`), never a status source: `INDEX.md` stays the
97
97
  single writer of intent status, exactly as for the roadmap file itself.
98
98
 
99
+ ## Screens read this format (intent 331c)
100
+
101
+ `report-screen roadmap <roadmap.md> plan|state|delivered` reads exactly the shapes above and
102
+ nothing else: `## Goal`'s first sentence, the `## Batches` (or legacy `## Waves`) grouping and its
103
+ entries (through `RoadmapQueue`'s own reconciled reader - INDEX still wins), and the events from
104
+ the savepoint ledger, falling back to `## Log` classified through the same keyword vocabulary when
105
+ no ledger file exists (an archived roadmap moved before intent 134 shipped, `manual-first.md`
106
+ among them). A screen never invents a status, a time, or a merge sha the file, `INDEX.md`, or the
107
+ ledger did not already carry - the same `not recorded` floor the intent screens use.
108
+
99
109
  ## Worked example
100
110
 
101
111
  ```
@@ -0,0 +1,22 @@
1
+ ## ▶ {{scope}} · dashboard
2
+
3
+ | | | |
4
+ | --- | --- | --- |
5
+ | **Active** | {{active}} | intents |
6
+ | **In delivery** | {{in_delivery}} | with a fresh lock |
7
+ | **Delivered** | {{delivered}} | in the last 7 days |
8
+ | **Roadmap** | {{roadmap}} | frontier batch |
9
+ | **Sessions** | {{sessions}} | alive |
10
+ | **Changed** | {{changed}} | newest savepoint |
11
+
12
+ **Where we are**
13
+
14
+ | Graph ID | Intent | Stage | Progress | Lead |
15
+ | --- | --- | --- | --- | --- |
16
+ {{where_we_are.rows}}
17
+
18
+ **Where we go next**
19
+
20
+ | Rank | Graph ID | Intent | Reason |
21
+ | --- | --- | --- | --- |
22
+ {{where_we_go_next.rows}}
@@ -0,0 +1,21 @@
1
+ <!-- Doctor's display self-test fixture (intent 331e). Replayed through the
2
+ installed MessageDisplay hook by `display_hook_paints` to prove painting
3
+ still works; this is NOT a report-screen scaffold (no {{...}} mustache
4
+ placeholders) and ships no data of its own. -->
5
+
6
+ ## ▶ 331e · Doctor display check
7
+
8
+ | | | |
9
+ | --- | --- | --- |
10
+ | **Store** | project:plastic | the plastic project store |
11
+ | **Status** | Active | listed under ## Active in INDEX.md |
12
+ | **Stage** | Exec | What, Why, How, Exec delivered; the work is open |
13
+ | **Progress** | ██████████░░░░░░░░░░ 3 / 6 | 3 steps open |
14
+
15
+ **Steps**
16
+
17
+ | Step | Status | What |
18
+ | --- | --- | --- |
19
+ | S1 | done | Tests red |
20
+ | S2 | done | check_display_registration in doctor_core.rb |
21
+ | S3 | open | The three full-run checks in doctor.rb |
@@ -0,0 +1,16 @@
1
+ # Graph: <intent name>
2
+
3
+ ## Goal
4
+ <What this intent's graph delivers once every node reaches done.>
5
+
6
+ ## Decisions
7
+ - D1 <first ruling made while building this graph>
8
+
9
+ ## Graph
10
+ Edges, `needs` only; the head needs the tail done. The literal target `nothing` declares a root.
11
+ - n1 needs nothing
12
+
13
+ ## Status
14
+ | Node | State | Detail |
15
+ | --- | --- | --- |
16
+ | n1 | planned | |
@@ -0,0 +1,17 @@
1
+ ## ▶ {{id}} · {{name}}
2
+
3
+ | | | |
4
+ | --- | --- | --- |
5
+ | **Store** | {{store}} | {{store.note}} |
6
+ | **Status** | {{status}} | {{status.note}} |
7
+ | **Stage** | {{stage}} | {{stage.note}} |
8
+ | **Savepoint** | {{savepoint}} | {{savepoint.note}} |
9
+ | **Progress** | {{progress.bar}} {{progress.done}} / {{progress.total}} | {{progress.note}} |
10
+ | **Next** | {{next}} | {{next.note}} |
11
+ | **Insight** | {{insight}} | {{insight.note}} |
12
+
13
+ **Steps**
14
+
15
+ | Step | Status | Detail |
16
+ | --- | --- | --- |
17
+ {{steps.rows}}
@@ -0,0 +1,11 @@
1
+ ---
2
+ node: d1
3
+ kind: decision
4
+ files: []
5
+ budget: 20000
6
+ ---
7
+ # d1 - <the decision to make>
8
+
9
+ ## Question
10
+ <The question needing an owner ruling, framed so a yes/no answer or a pick
11
+ from a short list settles it.>
@@ -0,0 +1,11 @@
1
+ ---
2
+ node: r1
3
+ kind: research
4
+ files: []
5
+ budget: 60000
6
+ ---
7
+ # r1 - <what to find out>
8
+
9
+ ## Deposit
10
+ <Where the finding lands: a resources/ file, an artifact URL, or a ruling
11
+ recorded in the intent's ## Decisions.>
@@ -0,0 +1,13 @@
1
+ ---
2
+ node: v1
3
+ kind: verify
4
+ files: []
5
+ budget: 40000
6
+ ---
7
+ # v1 - <what this node verifies>
8
+
9
+ <What this node checks, and why it gates the work nodes it needs.>
10
+
11
+ ## Criteria
12
+ - <acceptance criterion one>
13
+ - <acceptance criterion two>
@@ -0,0 +1,22 @@
1
+ ---
2
+ node: n1
3
+ kind: work
4
+ files: [path/to/file.rb, test/path_to_file_test.rb]
5
+ budget: 100000
6
+ ---
7
+ # n1 - <one-line description of what this node builds>
8
+
9
+ <Why this node exists and what it changes, in a sentence or two.>
10
+
11
+ ## n1 failure-mode matrix
12
+ | Operation | Failure mode | Test |
13
+ | --- | --- | --- |
14
+ | <operation> | <what goes wrong without this code, and its consequence> | `some_test#test_name` |
15
+
16
+ ## Steps
17
+ 1. Red: the matrix's tests above, committed before any code.
18
+ 2. Write the code that makes them pass.
19
+ 3. Green, then the whole suite at its baseline.
20
+
21
+ ## Proven by
22
+ (filled at close from the ledger: commit, suite counts, review verdict)
@@ -7,10 +7,28 @@ disposition: delivered|abandoned
7
7
  (what was delivered)
8
8
 
9
9
  ## Delivered
10
- - ...
10
+ <!-- One row per thing delivered, in plain wording a reader recognizes, not
11
+ an implementation summary; the technical detail belongs in ## Summary. Each
12
+ row's label must appear as a standalone token in an actions/*.md OR
13
+ nodes/*.md heading that owns the matrix table (for example "### S1 - ..."
14
+ with a table beneath it proves row S1, or "## n1 failure-mode matrix" proves
15
+ row n1); that heading's matrix rows become the row's Proven-by cell on the
16
+ delivered screen (intent 317 D19, 317a, 322 D1r, 334 D10r). Readers resolve
17
+ actions/ first, then nodes/ (334 D15r). A label with no owning heading falls
18
+ back to a matrix row cell that carries it, when one under a heading named
19
+ "matrix" exists (322 D3r). -->
20
+ | Row | What |
21
+ | --- | --- |
22
+ | S1 | ... |
11
23
 
12
24
  ## Verification
13
25
  - <acceptance criterion> — verified by ... → result
14
26
 
27
+ ## Needs you
28
+ <!-- The literal None, or a table shaped | N | What | Why | with one row per
29
+ open owner action. Prose is tolerated by the reader but renders as a single
30
+ untyped row - write the table. -->
31
+ None
32
+
15
33
  ## Follow-ups
16
34
  None
@@ -0,0 +1,15 @@
1
+ ## ▶ {{id}} · {{name}} · plan
2
+
3
+ | | | |
4
+ | --- | --- | --- |
5
+ {{fields.rows}}
6
+
7
+ **Steps**
8
+
9
+ | Step | Action | Detail |
10
+ | --- | --- | --- |
11
+ {{steps.rows}}
12
+
13
+ **Risks**
14
+
15
+ {{risks.block}}
@@ -0,0 +1,10 @@
1
+ ## ✔ {{slug}} · roadmap · delivered
2
+ {{meta}}
3
+
4
+ **Delivered**
5
+
6
+ {{delivered.table}}
7
+
8
+ **Log**
9
+
10
+ {{log.table}}
@@ -0,0 +1,9 @@
1
+ ## ▶ {{slug}} · roadmap · plan
2
+
3
+ | | | |
4
+ | --- | --- | --- |
5
+ {{fields.rows}}
6
+
7
+ **Batches**
8
+
9
+ {{entries.table}}{{tree}}
@@ -0,0 +1,9 @@
1
+ ## ▶ {{slug}} · roadmap
2
+
3
+ | | | |
4
+ | --- | --- | --- |
5
+ {{fields.rows}}
6
+
7
+ **Batches**
8
+
9
+ {{entries.table}}
@@ -0,0 +1,11 @@
1
+ ## ▶ {{id}} · {{name}}
2
+
3
+ | | | |
4
+ | --- | --- | --- |
5
+ {{fields.rows}}
6
+
7
+ **Steps**
8
+
9
+ | Step | Status | Detail |
10
+ | --- | --- | --- |
11
+ {{steps.rows}}
@@ -9,6 +9,19 @@ roadmap's goal is reached, move this file from `roadmaps/{slug}.md` to
9
9
  (a checkable prose condition — one or a few sentences a human or coordinator reads to decide the
10
10
  roadmap is done. Not an executable checker.)
11
11
 
12
+ ## Graph
13
+ Edges, `needs` only; the head needs the tail done. The literal target `nothing` declares a root
14
+ (an entry needing nothing). Batches below are computed from these edges, not hand-ordered; run
15
+ `roadmap-graph check <this file>` to see the computed batches and `roadmap-graph render <this
16
+ file>` to write them back, or `roadmap-graph migrate <this file>` on an existing graphless
17
+ roadmap to derive edges from its current batch order instead of hand-writing them here.
18
+
19
+ Grammar (fenced below so this example is never read as a real edge):
20
+ ```
21
+ - <intent-id> needs nothing
22
+ - <intent-id> needs <intent-id>
23
+ ```
24
+
12
25
  ## Batches
13
26
  Entries in a batch are parallel-safe; batches run top to bottom. The checkbox is checked once an
14
27
  entry is delivered, unchecked otherwise; the trailing token after the em-dash is the precise