@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.
- package/agents/plastic-enforcer.md +3 -1
- package/agents/plastic-executor.md +9 -3
- package/hooks/hooks.json +12 -0
- package/hooks/message-display +134 -0
- package/hooks/statusline +4 -27
- package/package.json +2 -2
- package/scripts/agent-report +8 -2
- package/scripts/dashboard.rb +297 -18
- package/scripts/doctor.rb +652 -5
- package/scripts/end-intent +219 -0
- package/scripts/hook-capture +25 -113
- package/scripts/hook-message-display +81 -0
- package/scripts/hook-record +12 -4
- package/scripts/hook-session-start +23 -1
- package/scripts/index-projection +74 -0
- package/scripts/intent-screen +77 -0
- package/scripts/lib/action_graph_shim.rb +277 -0
- package/scripts/lib/arm.rb +26 -1
- package/scripts/lib/atomic_write.rb +31 -0
- package/scripts/lib/core_integrity.rb +71 -0
- package/scripts/lib/dashboard_screen.rb +40 -0
- package/scripts/lib/day_summary.rb +7 -2
- package/scripts/lib/doctor_core.rb +101 -5
- package/scripts/lib/doctor_session_ledger.rb +52 -0
- package/scripts/lib/graph_edges.rb +121 -0
- package/scripts/lib/graph_file.rb +246 -0
- package/scripts/lib/graph_tree.rb +98 -0
- package/scripts/lib/guarded_append.rb +155 -0
- package/scripts/lib/hook_registry.rb +14 -0
- package/scripts/lib/hook_replay.rb +211 -0
- package/scripts/lib/index_projection.rb +201 -0
- package/scripts/lib/installer_core.rb +131 -4
- package/scripts/lib/intent_screen.rb +309 -0
- package/scripts/lib/intent_screen_ansi.rb +262 -0
- package/scripts/lib/message_display.rb +586 -0
- package/scripts/lib/node_file.rb +214 -0
- package/scripts/lib/node_ids.rb +99 -0
- package/scripts/lib/node_ledger.rb +377 -0
- package/scripts/lib/node_packet.rb +886 -0
- package/scripts/lib/node_return.rb +199 -0
- package/scripts/lib/node_worktree.rb +337 -0
- package/scripts/lib/outcome_report.rb +440 -0
- package/scripts/lib/packet_wrapper.rb +132 -0
- package/scripts/lib/ready_set.rb +462 -0
- package/scripts/lib/release_guard.rb +16 -0
- package/scripts/lib/report_screen.rb +1967 -0
- package/scripts/lib/roadmap_graph.rb +210 -0
- package/scripts/lib/roadmap_migration.rb +95 -0
- package/scripts/lib/roadmap_queue.rb +155 -5
- package/scripts/lib/roadmap_render.rb +150 -0
- package/scripts/lib/roadmap_savepoint.rb +62 -12
- package/scripts/lib/runner_absorb.rb +620 -0
- package/scripts/lib/runner_answer.rb +206 -0
- package/scripts/lib/runner_core.rb +194 -0
- package/scripts/lib/runner_dispatch.rb +482 -0
- package/scripts/lib/runner_policy.rb +142 -0
- package/scripts/lib/runner_proposals.rb +254 -0
- package/scripts/lib/runner_rewind.rb +201 -0
- package/scripts/lib/runner_sweep.rb +231 -0
- package/scripts/lib/savepoint.rb +149 -12
- package/scripts/lib/screen_paint.rb +555 -0
- package/scripts/lib/screens/dashboard.rb +20 -0
- package/scripts/lib/screens/plan.rb +18 -0
- package/scripts/lib/screens/roadmap.rb +15 -0
- package/scripts/lib/session_git.rb +49 -18
- package/scripts/lib/session_ledger.rb +128 -0
- package/scripts/lib/verify_intent.rb +33 -0
- package/scripts/lib/work_graph_validator.rb +201 -0
- package/scripts/node-packet +92 -0
- package/scripts/node-transition +291 -0
- package/scripts/outcome-report +74 -0
- package/scripts/plastic-lock +8 -1
- package/scripts/ready-set +126 -0
- package/scripts/release-check +118 -0
- package/scripts/report-screen +281 -0
- package/scripts/roadmap-graph +119 -0
- package/scripts/roadmap-savepoint +7 -0
- package/scripts/runner +392 -0
- package/scripts/savepoint-note +69 -0
- package/scripts/spawn-preamble +9 -2
- package/scripts/validate-work-graph +39 -0
- package/scripts/verify-intent +2 -1
- package/skills/auto/SKILL.md +24 -17
- package/skills/auto/references/human-report-contract.md +136 -54
- package/skills/conventions/references/locks-and-worktrees.md +12 -0
- package/skills/dashboard/SKILL.md +13 -2
- package/skills/dashboard/templates/dashboard-global.md +1 -1
- package/skills/dashboard/templates/dashboard-project.md +2 -2
- package/skills/doctor/SKILL.md +10 -4
- package/skills/intent-continuing/SKILL.md +51 -41
- package/skills/intent-continuing/references/board-fill.md +9 -0
- package/skills/intent-continuing/references/boarding-matrix.md +6 -5
- package/skills/intent-continuing/references/context-management.md +1 -1
- package/skills/intent-ending/SKILL.md +36 -16
- package/skills/intent-executing/SKILL.md +17 -5
- package/skills/intent-executing/implementer-prompt.md +6 -1
- package/skills/intent-speccing/SKILL.md +7 -4
- package/skills/releasing/SKILL.md +39 -0
- package/skills/releasing/references/promotion-and-tagging.md +10 -6
- package/skills/releasing/references/release-lines.md +1 -1
- package/skills/roadmap/SKILL.md +26 -0
- package/skills/roadmap/references/file-format.md +10 -0
- package/templates/dashboard-screen.md +22 -0
- package/templates/display-fixture.md +21 -0
- package/templates/graph.md +16 -0
- package/templates/intent-screen.md +17 -0
- package/templates/node-decision.md +11 -0
- package/templates/node-research.md +11 -0
- package/templates/node-verify.md +13 -0
- package/templates/node-work.md +22 -0
- package/templates/outcome.md +19 -1
- package/templates/report-plan.md +15 -0
- package/templates/report-roadmap-delivered.md +10 -0
- package/templates/report-roadmap-plan.md +9 -0
- package/templates/report-roadmap-state.md +9 -0
- package/templates/report-state.md +11 -0
- package/templates/roadmap.md +13 -0
|
@@ -1,72 +1,154 @@
|
|
|
1
|
-
# Human Report Contract (
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
# Human Report Contract (the report screens, intent 317)
|
|
2
|
+
|
|
3
|
+
D15: the prose EM-to-CTO briefing this doc used to define is retired. The orchestrator now
|
|
4
|
+
prints one of these report screens, filled from the record by `scripts/report-screen`, never
|
|
5
|
+
written by eye:
|
|
6
|
+
|
|
7
|
+
- **`report-screen plan <intent_dir>`** - the pre-delivery report (intent 331b), printed once
|
|
8
|
+
at the How boundary, before the executor is dispatched: Asked, Decisions, Steps, Mode,
|
|
9
|
+
Reviewer, then the Steps table (Step, Action, What) and the Risks table.
|
|
10
|
+
- **`report-screen state <intent_dir> [--changed "<text>"]`** - the mid-delivery report. One
|
|
11
|
+
intent's field table (Store, Status, Stage, Savepoint, Progress, Next, Insight) plus a
|
|
12
|
+
`Changed` row naming what caused the print, and its Steps table.
|
|
13
|
+
- **`report-screen state --all <store_root>`** - the roster across every in-delivery intent,
|
|
14
|
+
most recently changed first, then one collapsed block (Stage, Next, Changed, first three
|
|
15
|
+
open steps) per intent.
|
|
16
|
+
- **`report-screen delivered <intent_dir>`** - the post-delivery report, printed once at close:
|
|
17
|
+
Asked, Delivered (with a Proven-by column), Evidence, Needs you.
|
|
18
|
+
- **`report-screen delay <intent_dir>`** - printed only on request ("why did X take so long"):
|
|
19
|
+
the delivery as a timeline plus the derived `Where the time went` line.
|
|
20
|
+
- **`report-screen session <tier_root>`** - the answer to an UNNAMED status ask ("where are we
|
|
21
|
+
with delivery", "what is the status"): one `delivered` screen per intent this session
|
|
22
|
+
completed, oldest first, then the `state --all` roster. Intent 330's ruling: a status ask
|
|
23
|
+
answers with what actually shipped, not the in-flight roster alone.
|
|
24
|
+
- **`dashboard.rb continue|project <slug> --screen`** - the dashboard screen (intent 331d):
|
|
25
|
+
Active, In delivery, Delivered, Roadmap, Sessions, Changed, then the Where-we-are and
|
|
26
|
+
Where-we-go-next tables. A separate script from the other four (`dashboard.rb`, not
|
|
27
|
+
`report-screen`), since it aggregates across a whole store or project rather than one
|
|
28
|
+
intent; it prints on `continue` and on loading a project, not as a delivery trigger.
|
|
29
|
+
|
|
30
|
+
## Binding table (intent 331f)
|
|
31
|
+
|
|
32
|
+
Every skill that shows state names its own report verb, one row per skill and trigger. Each
|
|
33
|
+
bound skill's file carries the SAME rule next to its verb: print the screen as the first
|
|
34
|
+
characters of the reply, nothing before it, no fence, or the hook cannot paint it.
|
|
35
|
+
|
|
36
|
+
| Skill | Trigger | Verb |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `plastic-intent-continuing` | project route (continue, load project) | `dashboard.rb ... --screen` |
|
|
39
|
+
| `plastic-intent-continuing` | a named intent | `report-screen state` |
|
|
40
|
+
| `plastic-intent-continuing` | "where are we" (a status ask) | `report-screen session` |
|
|
41
|
+
| `plastic-intent-continuing` | "why so long" | `report-screen delay` |
|
|
42
|
+
| `plastic-intent-continuing` | a roadmap route | `report-screen roadmap ... state` |
|
|
43
|
+
| `plastic-auto` | the How boundary, before the executor | `report-screen plan` |
|
|
44
|
+
| `plastic-auto` | each of the five triggers | `report-screen state` |
|
|
45
|
+
| `plastic-auto` | close | `report-screen delivered` |
|
|
46
|
+
| `plastic-intent-ending` | the close | `report-screen delivered` |
|
|
47
|
+
| `plastic-intent-speccing` | the action files are written | `report-screen plan` |
|
|
48
|
+
| `plastic-roadmap` | create | `report-screen roadmap ... plan` |
|
|
49
|
+
| `plastic-roadmap` | read | `report-screen roadmap ... state` |
|
|
50
|
+
| `plastic-roadmap` | close | `report-screen roadmap ... delivered` |
|
|
51
|
+
| `plastic-dashboard` | any invocation | `dashboard.rb ... --screen` |
|
|
52
|
+
| `plastic-intent-executing` | after the red commit, and after the suite | `report-screen state` |
|
|
53
|
+
|
|
54
|
+
## A roadmap's own three reports (intent 331c)
|
|
55
|
+
|
|
56
|
+
A roadmap gets the same pre-, in-, and post-delivery shape as an intent, through
|
|
57
|
+
`report-screen roadmap <roadmap.md> plan|state|delivered [--ansi] [--store-root <dir>]`:
|
|
58
|
+
|
|
59
|
+
- **`roadmap plan`** - the pre-delivery report: the Goal's first sentence, the batch (or legacy
|
|
60
|
+
wave) count and intent count, the batch order, and when the roadmap was created; then the
|
|
61
|
+
full entries table.
|
|
62
|
+
- **`roadmap state`** - the in-delivery report: Goal, a Progress bar over intents delivered of
|
|
63
|
+
intents total (never batches), the frontier batch, who is delivering it and their lead, the
|
|
64
|
+
next queued entry, and the last ledger event; then the entries table with each entry's own
|
|
65
|
+
checklist progress and lead.
|
|
66
|
+
- **`roadmap delivered`** - the post-delivery report: a meta line (closed time, or `in progress`
|
|
67
|
+
when the goal is not yet reached; intent count; duration) directly under the title, the
|
|
68
|
+
delivered table with each entry's merge sha, and the `## Log` table.
|
|
69
|
+
|
|
70
|
+
Every cell traces to the roadmap file, `INDEX.md` (which always wins on status), the roadmap's
|
|
71
|
+
own savepoint ledger, or (falling back when no ledger file exists) the roadmap's `## Log` -
|
|
72
|
+
never a second parser: `RoadmapQueue`'s own public `roadmap` reader supplies every entry.
|
|
73
|
+
|
|
74
|
+
## The five triggers for `state`
|
|
75
|
+
|
|
76
|
+
Print `state` (one intent, or `--all` for the roster) on any of these; a checklist tick alone,
|
|
77
|
+
an executor's intermediate commit, or an agent going idle is NOT one of them:
|
|
78
|
+
|
|
79
|
+
| Trigger | Scope |
|
|
80
|
+
|---|---|
|
|
81
|
+
| A savepoint line lands (a stage boundary: Why, How, Exec started, outcome written, Done) | that intent |
|
|
82
|
+
| A review verdict returns (plan review or post-execution review), naming what it changed | that intent |
|
|
83
|
+
| A blocker or needs-input is logged | that intent |
|
|
84
|
+
| A merge or a release lands | that intent |
|
|
85
|
+
| The owner asks ("where are we", "state of X", "continue X") | all in delivery, or the one named |
|
|
86
|
+
|
|
87
|
+
`delivered` prints exactly once, at Completion. `delay` prints only when the owner asks why a
|
|
88
|
+
delivery took long.
|
|
89
|
+
|
|
90
|
+
Every verb prints the same plain Markdown on every harness (owner ruling 2026-08-31); where a
|
|
91
|
+
harness can paint it (Claude Code, through 316a's message-display hook), it substitutes a
|
|
92
|
+
painted rendering of that same output, never a different one, and no skill or script branches
|
|
93
|
+
on harness name to decide.
|
|
32
94
|
|
|
33
95
|
## Depth for small work
|
|
34
96
|
|
|
35
|
-
For small work in auto mode the
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
still ends with `outcome.md` plus one owner report.
|
|
97
|
+
For small work in auto mode, only the How-boundary `plan` screen prints mid-flight (intent
|
|
98
|
+
331f moved this print off `state`, since there is no separate briefing per stage any more).
|
|
99
|
+
Larger work prints `state` at every trigger in the table above. This is a
|
|
100
|
+
depth cut, not a different report: the screen's shape never changes, only how often it fires.
|
|
101
|
+
A delivery still ends with `outcome.md` plus one `delivered` screen.
|
|
41
102
|
|
|
42
103
|
## One report per audience
|
|
43
104
|
|
|
44
|
-
A delivery produces exactly two artifacts: `outcome.md` (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
105
|
+
A delivery produces exactly two artifacts: `outcome.md` (generated by `scripts/end-intent`
|
|
106
|
+
from `graph.md`, `nodes/`, and the ledger when the intent has one, intent 339; hand-authored
|
|
107
|
+
by `plastic-intent-ending` otherwise) and one `delivered` screen at the End stage. No stage or skill restates a delivery already
|
|
108
|
+
written to `outcome.md`; point at it instead. Skills do not open with a banner that names the
|
|
109
|
+
skill or restates the intent id and name the owner just typed. Announce only what the reader
|
|
110
|
+
cannot already know: an error, a result, a choice with its reason, or a handoff.
|
|
49
111
|
|
|
50
112
|
## Boundary vs intent 74
|
|
51
113
|
|
|
52
114
|
Intent 74's report contract (`references/agent-report-contract.md`) is the INTERNAL,
|
|
53
115
|
machine-checked handoff from a dispatched specialist back to the orchestrator: a structured
|
|
54
|
-
envelope plus a per-role payload. This contract is the OUTWARD
|
|
55
|
-
|
|
56
|
-
|
|
116
|
+
envelope plus a per-role payload. This contract is the OUTWARD screen shown to the owner.
|
|
117
|
+
Different direction, different audience, different form. The orchestrator reads the intent 74
|
|
118
|
+
report and reflects it into the record (savepoint, outcome.md) that `report-screen` then
|
|
119
|
+
renders. The two never merge.
|
|
57
120
|
|
|
58
121
|
## Brevity: point, don't repeat
|
|
59
122
|
|
|
60
|
-
Surface rules are owned by the `writing-style` skill. This contract does not restate them
|
|
61
|
-
|
|
62
|
-
|
|
123
|
+
Surface rules are owned by the `writing-style` skill. This contract does not restate them. Its
|
|
124
|
+
job is naming which screen prints when, not the wording inside it - `report-screen` derives
|
|
125
|
+
every cell from the record (D14), so there is no prose left to style here.
|
|
63
126
|
|
|
64
127
|
## Emission: guided vs auto
|
|
65
128
|
|
|
66
|
-
In guided mode,
|
|
67
|
-
|
|
129
|
+
In guided mode, `state` prints at each stage boundary and the human decides before the next
|
|
130
|
+
stage starts.
|
|
131
|
+
|
|
132
|
+
In auto mode, `state` prints at every trigger for larger work; for small work only the How
|
|
133
|
+
boundary's `plan` screen prints (see `## Depth for small work` above). The orchestrator takes
|
|
134
|
+
the go-ahead itself and moves on, except at the existing hard stops (destructive action without
|
|
135
|
+
a safe alternative, project-path confirm).
|
|
136
|
+
|
|
137
|
+
## Column vocabulary (D5, intent 331f)
|
|
138
|
+
|
|
139
|
+
Owner ruling 2026-09-05 11:05 UTC: "What" is never a column name, because What is a stage, not
|
|
140
|
+
a value. The id column reads `Graph ID`; the title column reads `Intent`. Every Steps table
|
|
141
|
+
reads `Step | Status | Detail` (the plan screen's own Steps table reads
|
|
142
|
+
`Step | Action | Detail`); every Risks table reads `N | Risk`; the Delivered/Evidence/Needs-you
|
|
143
|
+
tables on the `delivered` screen read `Row | Detail | Proven by`, `Kind | Detail | Source`, and
|
|
144
|
+
`N | Need | Reason`. The plan screen's Asked row prints the intent title before its first
|
|
145
|
+
colon, never the whole intent line. This applies to every screen the family prints: `state`,
|
|
146
|
+
`roster`, `session`, `delivered`, `delay`, `plan`, `roadmap` (`plan`/`state`/`delivered`), and
|
|
147
|
+
`dashboard`. `outcome.md`'s own `| Row | What |` heading is an AUTHORING convention inside the
|
|
148
|
+
file a human writes, never a rendered header, and stays unchanged.
|
|
149
|
+
|
|
150
|
+
## Width bound (D7, intent 331f)
|
|
68
151
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
the existing hard stops (destructive action without a safe alternative, project-path confirm).
|
|
152
|
+
No rendered row passes 115 visible columns. A long cell (the roadmap Goal, an intent title, an
|
|
153
|
+
Asked line) truncates on a word boundary with a single ellipsis; `ReportScreen.fit_screen`
|
|
154
|
+
shrinks a table's widest column first, floor 8, before it ever truncates a whole row.
|
|
@@ -103,3 +103,15 @@ what gets written down.
|
|
|
103
103
|
| Exec | code on the intent branch, checklist checked off | heartbeat; code edits confined to the provisioned worktree; delegates write under the owner's lock | checklist boxes; savepoint milestones; the day-ledger line promotes when a project file lands |
|
|
104
104
|
| End (done) | mandatory `outcome.md` (`disposition: delivered\|abandoned`), INDEX moves to Completed or Abandoned | ordered End tail: verify, merge and remove worktrees, disarm clears `delivery.lock`, then the pointer is purge-eligible, and the QMD reindex runs LAST (after purge); `end-intent` backfills a placeholder `outcome.md` from the record and its structure check reports (never refuses) | savepoint `Done delivered` (or `abandoned`); takeover audits, if any, remain in savepoint.md |
|
|
105
105
|
| Maintenance (Future, Terminal, or Active-with-a-stale-or-no-lock) | `revisions.md` move-and-record entries | detects (never acquires) `delivery.lock`; defers and reports while the target's lock is FRESH (`Lock.fresh?`); a stale or absent lock is not-active, maintenance proceeds | append-only, rule-tagged `revisions.md` entry written in the same operation as the change, or the change is refused; lands via a fresh branch off store main merged back as one closed op, never `git add -A` |
|
|
106
|
+
|
|
107
|
+
## The write guard is not residue
|
|
108
|
+
|
|
109
|
+
`<type>.write.lock` (usually `delivery.write.lock`) is a deliberate sibling
|
|
110
|
+
inode used only for `flock`: no owner, no timestamp, no content, and it is
|
|
111
|
+
NEVER unlinked - deleting it while a writer holds the flock hands the next
|
|
112
|
+
writer a fresh inode at the same path, so two writers hold "the" guard at
|
|
113
|
+
once (see `scripts/lib/lock.rb`, the write-guard comment). A zero-byte
|
|
114
|
+
`*.write.lock` in a completed intent directory is by design; no cleaner may
|
|
115
|
+
sweep it, and it is already inside the store's `*.lock` gitignore rule.
|
|
116
|
+
(Intent 317a, A2: a review misread it as stale residue and nearly shipped
|
|
117
|
+
the sweep.)
|
|
@@ -7,7 +7,8 @@ user-invocable: false
|
|
|
7
7
|
# Dashboard — Plastic Work Cockpit
|
|
8
8
|
|
|
9
9
|
A deterministic overview of the intent store(s). It answers three questions at a glance:
|
|
10
|
-
**where we are** (recently worked
|
|
10
|
+
**where we are** (recently worked; `Graph ID | Intent | Stage | Progress | Lead`),
|
|
11
|
+
**where we go next** (the most-valuable next work; `Rank | Graph ID | Intent | Reason`), and
|
|
11
12
|
**how to conduct it** (a disposition per intent). The human-facing surface is **Markdown**,
|
|
12
13
|
because the user's UI renders Markdown natively but collapses raw tool-call stdout.
|
|
13
14
|
|
|
@@ -22,6 +23,16 @@ state → byte-identical payload, regardless of model. Do NOT hand-summarize int
|
|
|
22
23
|
- `plastic-intent-continuing` lands on the board on a bare resume
|
|
23
24
|
- `plastic-auto` reads `--json` to choose the next dispatchable intent
|
|
24
25
|
|
|
26
|
+
## The screen surface (intent 331d/331f)
|
|
27
|
+
|
|
28
|
+
`dashboard.rb project <slug> --screen` (or `continue --screen` for the global board) is the
|
|
29
|
+
default surface on every invocation: print it as the first characters of the reply, nothing
|
|
30
|
+
before it, no fence, or the hook cannot paint it. It carries a title, six fields (Active, In
|
|
31
|
+
delivery, Delivered, Roadmap, Sessions, Changed), then the Where-we-are and Where-we-go-next
|
|
32
|
+
tables, its own grammar and painted form standing in for the filled Markdown template below.
|
|
33
|
+
`plastic-intent-continuing`'s project route prints it this way. The Markdown board (Step 1-4
|
|
34
|
+
below) stays available as the deeper prose surface a reader can ask for.
|
|
35
|
+
|
|
25
36
|
## Procedure (the Markdown board — default human surface)
|
|
26
37
|
|
|
27
38
|
### Step 1 — Get the data payload
|
|
@@ -70,7 +81,7 @@ Fill mechanically, no rewriting, no re-sorting:
|
|
|
70
81
|
re-truncate, or reword them. Never emit `<br>`.
|
|
71
82
|
- `next_work` → `| {id} | {what} | {value} | {disposition} | {flags_label} |`
|
|
72
83
|
- `active` → `| {id} | {what} | {stage} | {worker} | {activity} |`
|
|
73
|
-
Empty list → one full-width row with `_(none)_` in the
|
|
84
|
+
Empty list → one full-width row with `_(none)_` in the Graph ID column and every other cell blank,
|
|
74
85
|
matching that table's column count (e.g. `| _(none)_ | | | | |` for the 5-column next_work
|
|
75
86
|
table, `| _(none)_ | | | |` for the 5-column active table). Neither list carries an overflow
|
|
76
87
|
"+N more" row anymore (D5, intent 202): the true pool size rides on the payload as
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
**Active**
|
|
6
6
|
|
|
7
|
-
|
|
|
7
|
+
| Graph ID | Intent | Stage | Worker | Activity |
|
|
8
8
|
| --- | --- | --- | --- | --- |
|
|
9
9
|
{{active.rows}}
|
|
10
10
|
|
|
11
11
|
**Most-valuable next work**
|
|
12
12
|
|
|
13
|
-
|
|
|
13
|
+
| Graph ID | Intent | Value | Disposition | Flags |
|
|
14
14
|
| --- | --- | --- | --- | --- |
|
|
15
15
|
{{next_work.rows}}
|
|
16
16
|
|
package/skills/doctor/SKILL.md
CHANGED
|
@@ -78,10 +78,15 @@ project alone.
|
|
|
78
78
|
Runs the install-wide surface: agent registration, core files (including config-honoring
|
|
79
79
|
drift), manifest sync is core-only and not part of this run, deprecation checks, config-ask
|
|
80
80
|
checks, install-integrity checks, skill-lint (advisory), QMD reachability (unscoped, every
|
|
81
|
-
collection),
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
collection), the global store's own conventions/done-signals content, and the `display`
|
|
82
|
+
category (intent 331e): `display_hook_registered` (also runs at `--core`), `display_hook_paints`
|
|
83
|
+
(replays the shipped display fixture through the installed MessageDisplay hook and expects a
|
|
84
|
+
painted screen back, a pass when a known defeater like `NO_COLOR` is active, never a fail),
|
|
85
|
+
`display_not_defeated` (warns per active defeater and always names the undetectable verbose
|
|
86
|
+
transcript view), and `display_surfaces_documented` (the harness-adapters doc still names every
|
|
87
|
+
surface class). **Never carries a per-project finding**; that is `--store <slug>`'s job (see
|
|
88
|
+
above). This is what `/plastic-doctor` invokes, and it also runs automatically after every
|
|
89
|
+
`plastic-update` (informational, does not block or revert the update).
|
|
85
90
|
|
|
86
91
|
## When to Use
|
|
87
92
|
|
|
@@ -167,6 +172,7 @@ Use the `fix_hint` value to determine the correct action:
|
|
|
167
172
|
| "Remove each listed .tmp/<session>/ directory after confirming that session is gone" | For each listed directory, confirm no live session uses it (a live session rewrites its heartbeat on every prompt and edit), then remove that directory by hand; never remove an unlisted one |
|
|
168
173
|
| "For a day directory missing its <day>.md, run `file-session-intent --day <day> ...`" | Run `ruby ~/.plastic/scripts/file-session-intent --day <day> --carry-to <today> --store <store>` for the named day; rename or remove an entry that is not a `YYYYMMDD` day directory |
|
|
169
174
|
| "Run scripts/project-links ... PRESERVES ... --drop-unbacked-links" | Run `ruby ~/.plastic/scripts/maintenance-run --tool project-links --intent <id> --apply` for the one flagged id (never run bare `project-links` against a real store outside the rare owner-approved batch exception, D2) |
|
|
175
|
+
| "Re-run the Plastic installer to repair the hook registration ... (plastic-install --repair)" (`display_hook_registered`) | Run `npx -y @zalom/plastic@<channel> install --reinstall --claude` (the `plastic-install` skill's repair mode), then re-run doctor |
|
|
170
176
|
|
|
171
177
|
For fixes the agent cannot handle automatically, explain what the user needs
|
|
172
178
|
to do manually. The `revisions.md` remedy is curator-applied (a move-and-record
|
|
@@ -5,7 +5,7 @@ description: >-
|
|
|
5
5
|
where we left off", "where was I", "what should I work on", names a specific intent to
|
|
6
6
|
resume (by id or description, or `--intent {id}`), or names a roadmap or delivery batch to
|
|
7
7
|
resume (`--roadmap {slug}`, "where is the roadmap", "where did that batch land"). Presents
|
|
8
|
-
state and resumes at the last delivered
|
|
8
|
+
state and resumes at the last delivered stage; it never asks auto or guided, never boots
|
|
9
9
|
(the SessionStart hook owns boot), and never drives work autonomously (plastic-auto does).
|
|
10
10
|
Absorbs the former continuing, project-continuing, and roadmap-continuing skills and the
|
|
11
11
|
read half of the former intent-starting skill (intent 304).
|
|
@@ -45,32 +45,29 @@ specific intent or roadmap named.").
|
|
|
45
45
|
|
|
46
46
|
## Project route: land on the board
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Priority order on the board: active intents first, then project context (governing plus
|
|
60
|
-
tactical intents in a registered project), then stale future intents for triage, then fresh
|
|
61
|
-
future intents as next work. A future intent older than `stale_threshold_days` (default 3) is
|
|
62
|
-
surfaced for triage without action: activate, abandon, or leave. Activating moves it to
|
|
48
|
+
Print `ruby ~/.plastic/scripts/dashboard.rb project <slug> --screen` (or `continue --screen`
|
|
49
|
+
for the global fallback) as the first characters of the reply: nothing before it, no fence, or
|
|
50
|
+
the hook cannot paint it (intent 331d/331f). It carries a title, six fields (Active, In
|
|
51
|
+
delivery, Delivered, Roadmap, Sessions, Changed), then the Where-we-are and Where-we-go-next
|
|
52
|
+
tables. The board load runs the scoped store check (`doctor --store <scope>`); its result
|
|
53
|
+
rides in the payload as `store_health` and prints as one line of data, never a blocker.
|
|
54
|
+
|
|
55
|
+
Priority order on the underlying data: active intents first, then project context (governing
|
|
56
|
+
plus tactical intents in a registered project), then stale future intents for triage, then
|
|
57
|
+
fresh future intents as next work. A future intent older than `stale_threshold_days` (default
|
|
58
|
+
3) is surfaced for triage without action: activate, abandon, or leave. Activating moves it to
|
|
63
59
|
`## Active` in `INDEX.md` and auto-commits. The board's ranked next-work order is computed by
|
|
64
60
|
`dashboard.rb`; cite the rule names only (Effort, Value, Flags, Override, Caps) and read
|
|
65
61
|
`plastic-dashboard`'s `references/classification.md` for their definitions.
|
|
66
62
|
|
|
67
63
|
When the tier root (the directory holding `INDEX.md`) has a mid-flight roadmap
|
|
68
64
|
(`ruby ~/.plastic/scripts/roadmap-next --roadmaps-dir <root>/roadmaps` reports a `state`
|
|
69
|
-
other than `none`), say so in one line and offer the roadmap route; the
|
|
65
|
+
other than `none`), say so in one line and offer the roadmap route; the screen still presents
|
|
70
66
|
project state and stops.
|
|
71
67
|
|
|
72
68
|
Then stop: "here is the state, what next?". Do not start executing work. When the user names
|
|
73
|
-
an intent, take the intent route.
|
|
69
|
+
an intent, take the intent route. Read `references/board-fill.md` only when the reader asks
|
|
70
|
+
for the deeper prose board (`plastic-dashboard`'s Markdown surface still exists for that ask).
|
|
74
71
|
|
|
75
72
|
## Intent route: resume one intent from its ledger
|
|
76
73
|
|
|
@@ -79,19 +76,20 @@ QMD-first when the intent is named by description: run
|
|
|
79
76
|
authoritative intent file. The command is a no-op when QMD is absent; fall back to
|
|
80
77
|
`INDEX.md`.
|
|
81
78
|
|
|
82
|
-
If the intent is terminal (`## Completed` or `## Abandoned` in `INDEX.md`):
|
|
83
|
-
|
|
79
|
+
If the intent is terminal (`## Completed` or `## Abandoned` in `INDEX.md`): print the
|
|
80
|
+
intent screen (Status shows the terminal section, Next is empty), summarize its
|
|
81
|
+
`outcome.md`, and ask what is next; never reopen it.
|
|
84
82
|
|
|
85
83
|
For a live intent's directory:
|
|
86
84
|
|
|
87
85
|
1. **Read `savepoint.md` first.** It is a deterministic, append-only ledger, one line per
|
|
88
|
-
event, newest at the bottom: `{utc-iso8601} {Stage} {milestone}`. Classify the
|
|
86
|
+
event, newest at the bottom: `{utc-iso8601} {Stage} {milestone}`. Classify the stage
|
|
89
87
|
from the last line alone (the table in `references/boarding-matrix.md`, read when
|
|
90
88
|
classifying), then verify only that line's artifact is real (sentinel-aware:
|
|
91
89
|
`Savepoint.stage_file_present?`). Do not re-probe every lifecycle file.
|
|
92
|
-
2. **
|
|
90
|
+
2. **Stale ledger.** When the last line disagrees with the files on disk, rebuild the ledger from
|
|
93
91
|
disk and note the correction. A rebuilt ledger is the file-landing skeleton, which still
|
|
94
|
-
pins the
|
|
92
|
+
pins the stage:
|
|
95
93
|
```bash
|
|
96
94
|
ruby -r ~/.plastic/scripts/lib/savepoint -e 'Savepoint.rebuild_savepoint("<intent_dir>")'
|
|
97
95
|
```
|
|
@@ -99,21 +97,32 @@ For a live intent's directory:
|
|
|
99
97
|
else the newest prior day) is the prior session's own account of where things stand; read
|
|
100
98
|
it after the ledger, never instead of it.
|
|
101
99
|
4. **Derive the next step:** the first unchecked item in `checklist.md` when it exists, else
|
|
102
|
-
the next thing the
|
|
100
|
+
the next thing the stage needs (see the matrix). The newest `## Insights` entry supplies
|
|
103
101
|
the human-readable context; an entry marked `(autonomous)` means an auto team was
|
|
104
102
|
delivering it, so say so and offer to hand back to `plastic-auto`.
|
|
105
|
-
5. **
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
`
|
|
103
|
+
5. **Print the report screen as the first thing in the reply, then continue at that stage.**
|
|
104
|
+
The screen must open the message with nothing before it. On Claude Code, a fail-open
|
|
105
|
+
`MessageDisplay` hook recognizes a reply that opens this way and substitutes a styled ANSI
|
|
106
|
+
rendering for it there; the transcript and every other harness keep exactly this plain
|
|
107
|
+
form. For "where are we" on one named intent, run
|
|
108
|
+
`ruby ~/.plastic/scripts/report-screen state <intent_dir>` and print its output as it is:
|
|
109
|
+
the title, the field table, the `Changed` row, and the Steps table come from the record,
|
|
110
|
+
never by eye. For "where are we" with no intent named, run
|
|
111
|
+
`ruby ~/.plastic/scripts/report-screen session <tier_root> --session <this session's id>`
|
|
112
|
+
(intent 330; pass the id your harness gives you, or the screen widens to the whole day and
|
|
113
|
+
says so): it prints one
|
|
114
|
+
`delivered` screen per intent this session actually completed, oldest first, then the same
|
|
115
|
+
roster `report-screen state --all <store_root>` prints on its own - `state --all` stays the
|
|
116
|
+
right call when only the in-flight roster is wanted, with nothing delivered above it. Route
|
|
117
|
+
"why did X take so long" to `ruby ~/.plastic/scripts/report-screen delay <intent_dir>`
|
|
118
|
+
instead - every verb prints the same plain screen on any harness, painted only where the
|
|
119
|
+
harness supports it, with no branching on harness name. Under the `state` screen
|
|
120
|
+
write **What this means** as two to four bullets in plain words (what the intent is for,
|
|
121
|
+
what has landed, what is left, any defect named by step), then close with **needs input:**
|
|
122
|
+
naming the first open step. Then continue the work in the
|
|
123
|
+
session's current mode. In auto mode the running team already holds the delivery lock; if a
|
|
124
|
+
lock is held by a session that is gone, the `plastic-doctor` skill's lock section repairs or
|
|
125
|
+
reclaims it.
|
|
117
126
|
|
|
118
127
|
## Roadmap route: resume the mid-flight roadmap
|
|
119
128
|
|
|
@@ -127,10 +136,11 @@ For a live intent's directory:
|
|
|
127
136
|
`delivering` or `blocked` entry wins, else the newest ledger or `## Log` timestamp.
|
|
128
137
|
`roadmaps/<slug>.savepoint.md` is a derived signal read here, never a status field;
|
|
129
138
|
`INDEX.md` stays the sole status writer.
|
|
130
|
-
2. **
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
139
|
+
2. **Print state.** Print `ruby ~/.plastic/scripts/report-screen roadmap <roadmap.md> state` as
|
|
140
|
+
the first characters of the reply: nothing before it, no fence, or the hook cannot paint it.
|
|
141
|
+
It carries Goal, Progress, Frontier, Delivering, Next, and Changed, then the entries table -
|
|
142
|
+
never hand-typed. Read `../plastic-conventions/references/roadmaps.md` for the file format
|
|
143
|
+
and the status-mirror rule when a roadmap file needs interpreting.
|
|
134
144
|
3. Then continue with the next dispatchable entry in the session's mode: direct work on it,
|
|
135
145
|
or `plastic-auto` when the owner says auto. The coordinator that drives a batch appends
|
|
136
146
|
to `roadmaps/<slug>.savepoint.md` at its dispatch, merge, park, and handoff points with
|
|
@@ -141,6 +151,6 @@ For a live intent's directory:
|
|
|
141
151
|
| Trigger | Read |
|
|
142
152
|
|---|---|
|
|
143
153
|
| Filling the board on the project route | `references/board-fill.md` |
|
|
144
|
-
| Classifying the
|
|
154
|
+
| Classifying the stage from the ledger's last line | `references/boarding-matrix.md` |
|
|
145
155
|
| Explaining why one roadmap ranked above another | `references/liveness-ranking.md` |
|
|
146
156
|
| Saving or restoring context across a long session, or debugging a resume | `references/context-management.md` |
|
|
@@ -41,3 +41,12 @@ The project route's default target is the project board. When no project is load
|
|
|
41
41
|
case where this route is reached without a registered project in scope), fall back to the
|
|
42
42
|
global board payload (`dashboard.rb continue --data`) rather than failing. This mirrors the
|
|
43
43
|
router's D6 default: a bare "continue" always lands somewhere useful.
|
|
44
|
+
|
|
45
|
+
## The screen surface (intent 331d)
|
|
46
|
+
|
|
47
|
+
`dashboard.rb project <slug> --screen` (or `continue --screen`) prints the identical state -
|
|
48
|
+
Active, In delivery, Delivered, Roadmap, Sessions, Changed, then the Where-we-are and
|
|
49
|
+
Where-we-go-next tables - as a screen with its own grammar instead of a filled Markdown
|
|
50
|
+
template. It replaces this fill mechanism once intent 331f wires the project route to print
|
|
51
|
+
it first, the way the intent route already prints the intent screen first today; until then,
|
|
52
|
+
this page's fill rules stay the route's own surface.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Boarding matrix: which
|
|
1
|
+
# Boarding matrix: which stage a resume lands at
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The stage is derived from `savepoint.md`'s last line plus the real artifacts on disk.
|
|
4
4
|
Classify from the last line alone, then verify only that line's artifact is real
|
|
5
|
-
(sentinel-aware).
|
|
5
|
+
(sentinel-aware). When the ledger is stale, rebuild it from disk and note it.
|
|
6
6
|
|
|
7
7
|
| savepoint last line | latest delivered | lands at | continue with |
|
|
8
8
|
|---|---|---|---|
|
|
@@ -10,11 +10,12 @@ Classify from the last line alone, then verify only that line's artifact is real
|
|
|
10
10
|
| `Why started` (spec still sentinel) | What | **Why** | continue the conversation; rulings land as insights |
|
|
11
11
|
| `Why spec.md created` | Why | **How** | the action files, `plan.md`, `checklist.md` |
|
|
12
12
|
| `How started` / `How plan.md created` | (How in progress) | **How** | finish `plan.md` and `checklist.md` |
|
|
13
|
-
| `How checklist.md created` / `Exec started` | How | **Exec** | do the work,
|
|
13
|
+
| `How checklist.md created` / `Exec started` | How | **Exec** | do the work, check off the checklist |
|
|
14
14
|
| `Exec outcome.md created` | Exec | **ready to complete** | the ending procedure (`plastic-intent-ending`) |
|
|
15
15
|
| `Done delivered` / `Done abandoned` | terminal | **report only** | immutable; ask what is next |
|
|
16
|
+
| A node or `Intent` transition line (`n1 running ...`, `Intent needs_decision ...`) | Exec | **Exec** | a graph delivery is in progress; read node status through `NodeLedger.status`, never re-derive it by eye |
|
|
16
17
|
|
|
17
|
-
## Per-
|
|
18
|
+
## Per-stage behaviour (what "continue" means)
|
|
18
19
|
|
|
19
20
|
- **Why**: continue the conversation, or run the work directly when the request is already
|
|
20
21
|
clear; every ruling is recorded as it lands.
|
|
@@ -19,7 +19,7 @@ step looks stale):
|
|
|
19
19
|
(see `SKILL.md`'s `## Conditional Ledger-Resume` for the full state table).
|
|
20
20
|
2. Confirm the artifact that line implies (`plan.md`, `checklist.md`, `outcome.md`, ...) is
|
|
21
21
|
present and non-empty on disk.
|
|
22
|
-
3. If the two disagree, the ledger
|
|
22
|
+
3. If the two disagree, the ledger is stale: rebuild it rather than hand-editing:
|
|
23
23
|
`ruby -r ~/.plastic/scripts/lib/savepoint -e 'Savepoint.rebuild_savepoint("<intent_dir>")'`
|
|
24
24
|
4. Re-read the rebuilt last line and re-derive the next step from `checklist.md`'s first
|
|
25
25
|
unchecked item.
|