@zalom/plastic 1.1.0 → 1.1.2

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 (63) hide show
  1. package/PLASTIC.md +12 -9
  2. package/README.md +3 -3
  3. package/agents/plastic-enforcer.md +8 -4
  4. package/agents/plastic-executor.md +5 -5
  5. package/agents/plastic-future-intent-researcher.md +1 -1
  6. package/agents/plastic-planner.md +15 -11
  7. package/hooks/check-update +1 -1
  8. package/hooks/continue +1 -1
  9. package/package.json +1 -1
  10. package/scripts/dashboard.rb +29 -24
  11. package/scripts/doctor.rb +180 -5
  12. package/scripts/hook-continue +3 -3
  13. package/scripts/install.rb +2 -1
  14. package/scripts/lib/bridge.rb +114 -11
  15. package/scripts/lib/dashboard_banner.rb +8 -9
  16. package/scripts/lib/installer_core.rb +12 -3
  17. package/scripts/lib/legacy_bookend_amnesty.rb +35 -0
  18. package/scripts/lib/release_guard.rb +62 -0
  19. package/scripts/lib/roadmap_queue.rb +285 -0
  20. package/scripts/lib/roadmap_savepoint.rb +213 -0
  21. package/scripts/lib/skill_lint.rb +304 -0
  22. package/scripts/lib/worktree.rb +21 -0
  23. package/scripts/new-intent +1 -0
  24. package/scripts/read-config +3 -3
  25. package/scripts/roadmap-next +44 -0
  26. package/scripts/roadmap-savepoint +64 -0
  27. package/scripts/skill-lint +50 -0
  28. package/skills/auto/SKILL.md +32 -11
  29. package/skills/auto/references/tiers.md +4 -3
  30. package/skills/continuing/SKILL.md +34 -0
  31. package/skills/continuing/evals/evals.json +91 -0
  32. package/skills/dashboard/SKILL.md +17 -14
  33. package/skills/dashboard/references/classification.md +3 -3
  34. package/skills/dashboard/templates/dashboard-global.md +8 -23
  35. package/skills/dashboard/templates/dashboard-project.md +7 -26
  36. package/skills/doctor/SKILL.md +1 -1
  37. package/skills/install/SKILL.md +10 -10
  38. package/skills/intent-continuing/SKILL.md +26 -68
  39. package/skills/intent-continuing/evals/evals.json +26 -26
  40. package/skills/intent-continuing/references/context-management.md +15 -19
  41. package/skills/intent-planning/SKILL.md +11 -11
  42. package/skills/intent-planning/evals/evals.json +20 -5
  43. package/skills/intent-planning/references/plan-format.md +9 -5
  44. package/skills/intent-savepoint/SKILL.md +12 -0
  45. package/skills/intent-starting/evals/evals.json +1 -1
  46. package/skills/project-continuing/SKILL.md +104 -0
  47. package/skills/project-continuing/evals/evals.json +100 -0
  48. package/skills/project-continuing/references/board-fill.md +33 -0
  49. package/skills/releasing/SKILL.md +48 -0
  50. package/skills/releasing/references/release-lines.md +105 -0
  51. package/skills/roadmap/SKILL.md +7 -1
  52. package/skills/roadmap/references/file-format.md +30 -1
  53. package/skills/roadmap/references/operations.md +26 -6
  54. package/skills/roadmap-continuing/SKILL.md +85 -0
  55. package/skills/roadmap-continuing/evals/evals.json +82 -0
  56. package/skills/roadmap-continuing/references/liveness-ranking.md +56 -0
  57. package/skills/skill-evaluating/evals/evals.json +1 -1
  58. package/skills/tutorial/references/track-1-guided.md +5 -4
  59. package/skills/tutorial/references/track-2-auto.md +1 -1
  60. package/skills/uninstall/SKILL.md +2 -2
  61. package/skills/update/SKILL.md +2 -2
  62. package/templates/config.yml +2 -1
  63. package/templates/index.md +4 -1
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ # frozen_string_literal: true
4
+
5
+ # roadmap-savepoint - deterministic CLI over RoadmapSavepoint (intent 134).
6
+ #
7
+ # The plastic-roadmap skill verbs and the coordinator flows call this instead of hand-writing
8
+ # ledger lines. append is idempotent on the (event, detail) pair; rebuild is the one operation
9
+ # allowed to overwrite the ledger, reconstructing it from the roadmap's own `## Log`.
10
+ #
11
+ # Usage:
12
+ # roadmap-savepoint append --roadmap <path> --event <event> --detail "<text>"
13
+ # roadmap-savepoint rebuild --roadmap <path>
14
+ #
15
+ # Exits non-zero with a usage line on stderr for an unknown verb or a missing required flag.
16
+
17
+ require_relative "lib/roadmap_savepoint"
18
+
19
+ def opt(args, name)
20
+ (i = args.index(name)) && args[i + 1]
21
+ end
22
+
23
+ def usage
24
+ warn "Usage: roadmap-savepoint append --roadmap <path> --event <event> --detail \"<text>\""
25
+ warn " roadmap-savepoint rebuild --roadmap <path>"
26
+ end
27
+
28
+ verb = ARGV.shift
29
+
30
+ case verb
31
+ when "append"
32
+ roadmap = opt(ARGV, "--roadmap")
33
+ event = opt(ARGV, "--event")
34
+ detail = opt(ARGV, "--detail")
35
+ if roadmap.nil? || event.nil? || detail.nil?
36
+ warn "append: pass --roadmap <path> --event <event> --detail \"<text>\""
37
+ usage
38
+ exit 2
39
+ end
40
+ begin
41
+ wrote = RoadmapSavepoint.append(roadmap, event, detail)
42
+ puts wrote ? "appended #{event} #{detail}" : "no-op (already recorded): #{event} #{detail}"
43
+ exit 0
44
+ rescue ArgumentError => e
45
+ warn "append: #{e.message}"
46
+ exit 2
47
+ end
48
+
49
+ when "rebuild"
50
+ roadmap = opt(ARGV, "--roadmap")
51
+ if roadmap.nil?
52
+ warn "rebuild: pass --roadmap <path>"
53
+ usage
54
+ exit 2
55
+ end
56
+ count = RoadmapSavepoint.rebuild(roadmap)
57
+ puts "rebuilt #{count} line#{count == 1 ? '' : 's'}"
58
+ exit 0
59
+
60
+ else
61
+ warn "roadmap-savepoint: unknown verb #{verb.inspect}. Use append|rebuild."
62
+ usage
63
+ exit 2
64
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ # frozen_string_literal: true
4
+
5
+ # skill-lint: deterministic CLI over SkillLint (intent 85b).
6
+ #
7
+ # Runs the five structural skill checks (body-budget, frontmatter-validity,
8
+ # bare-pointer, orphan-files, references-depth) over a directory of Agent
9
+ # Skills and reports every violation. Mirrors `scripts/validate-intent`'s
10
+ # CLI-over-lib shape and exit-code contract.
11
+ #
12
+ # Usage:
13
+ # skill-lint [--skills-dir <path>]
14
+ #
15
+ # Exit codes: 0 (clean), 1 (violations found; reported on stderr), 2 (usage).
16
+ # --skills-dir defaults to the repo skills/ directory next to this script.
17
+
18
+ require_relative "lib/skill_lint"
19
+
20
+ def resolve_skills_dir(args)
21
+ if (i = args.index("--skills-dir"))
22
+ args[i + 1]
23
+ else
24
+ File.expand_path("../skills", __dir__)
25
+ end
26
+ end
27
+
28
+ if ARGV.any? { |a| a.start_with?("--") && a != "--skills-dir" }
29
+ warn "usage: skill-lint [--skills-dir <path>]"
30
+ exit 2
31
+ end
32
+
33
+ if ARGV.include?("--skills-dir") && ARGV[ARGV.index("--skills-dir") + 1].nil?
34
+ warn "usage: skill-lint [--skills-dir <path>]"
35
+ exit 2
36
+ end
37
+
38
+ dir = File.expand_path(resolve_skills_dir(ARGV))
39
+ result = SkillLint.new(skills_dir: dir).run
40
+
41
+ if result.ok?
42
+ puts "OK: #{dir}"
43
+ exit 0
44
+ end
45
+
46
+ warn "VIOLATIONS: #{dir}"
47
+ result.violations.each do |v|
48
+ warn "#{v[:check]} #{v[:skill]} #{v[:file]}:#{v[:line].nil? ? "-" : v[:line]} #{v[:message]}"
49
+ end
50
+ exit 1
@@ -15,7 +15,9 @@ Announce: "Taking over intent [ID] - [name] for autonomous delivery."
15
15
  orchestrating main session on the best available thinking model (Fable, Opus, or whatever
16
16
  supersedes them) for the sharpest gating and synthesis. This is advice only: it changes no
17
17
  behavior and blocks nothing if ignored. It concerns the human's MAIN session; dispatched
18
- subagents keep their pinned tier and never resolve to Fable.
18
+ subagents keep their pinned tier and never resolve to Fable, unless an explicit
19
+ `agents.models.<name>` config override names Fable for that role, in which case the override
20
+ is honored as written.
19
21
 
20
22
  ## Precondition
21
23
 
@@ -24,8 +26,22 @@ An active intent MUST exist in INDEX.md. If none exists, refuse: "No active inte
24
26
  If multiple active intents exist, ask the user which one to deliver (this is the only question auto asks).
25
27
 
26
28
  **Picking work when no intent is specified.** If the user says "auto" without naming an
27
- intent and none is active, consult the dashboard's machine-readable queue to choose the
28
- next dispatchable intent:
29
+ intent and none is active, consult the roadmap first (the primary planning surface), then
30
+ fall back to the dashboard queue. Read the tier's mid-flight roadmap:
31
+
32
+ ```bash
33
+ ruby ~/.plastic/scripts/roadmap-next --roadmaps-dir <tier>/roadmaps
34
+ ```
35
+
36
+ Branch on `state`:
37
+ - `dispatchable`: work its `dispatchable_queue` in `rank` order (the head is the next batch
38
+ entry). These are the current batch's `queued` intents, parallel-safe within the wave.
39
+ - `in_flight`: the frontier batch is still delivering. Report it and wait. Do NOT dispatch a
40
+ later batch and do NOT fall through to the dashboard, the roadmap is live.
41
+ - `none` or `exhausted`: no roadmap, or nothing left to dispatch. Fall back to the dashboard
42
+ queue below. (The global store has no roadmap, so it always reports `none` and falls back.)
43
+
44
+ Dashboard fallback:
29
45
 
30
46
  ```bash
31
47
  ruby ~/.plastic/scripts/dashboard.rb all --json
@@ -54,8 +70,10 @@ and artifact depth to that size. Extended walkthrough: `references/tiers.md`.
54
70
  every tier and in both modes. A three-line spec.md is still a spec.md, in the same
55
71
  place, under the same gate.
56
72
  3. **Per-tier topology.** S/M: one thinker agent, one boot, two stations, sonnet
57
- executor, `actions/` skipped; S may also skip the QMD discovery deposit when chain and
58
- sources are both empty. L: today's full team (`## Team Spin-Up` below).
73
+ executor; the thinker writes at least one real action file (one consolidated
74
+ `actions/ACTION_1.md`), never an empty `actions/`. S may also skip the QMD discovery
75
+ deposit when chain and sources are both empty. L: today's full team (`## Team Spin-Up`
76
+ below), one `actions/ACTION_N.md` per task.
59
77
  4. **Never-cut list**, any tier or mode: the independent reviewer (separate agent, fresh
60
78
  context, never the maker), `outcome.md` as truth of delivery, the delivery lock,
61
79
  worktree isolation, intent creation via skill, INDEX as status truth, the QMD reindex
@@ -108,7 +126,9 @@ Dispatch rule: sequential, one specialist per stage on one branch (the deliverab
108
126
 
109
127
  Spawn preamble (live-state injection): before dispatching any specialist, run `scripts/spawn-preamble <intent_dir> --role <role>` and PREPEND its output to that specialist's prompt. The preamble is a deterministic, filesystem-only snapshot of the active intent (id, intent line, current stage, and the provisioned code worktree path when one exists on disk) plus the honoring instruction, so every spawned agent boots with accurate live state instead of guessing. This is the authoritative L2 mechanism for harnesses whose sub-agents do not inherit a top-level session event (see `docs/reference/harness-adapters.md`).
110
128
 
111
- Dispatch-time model contract (belt-and-braces): alongside the preamble, resolve each specialist's model through the config chain (`read-config agents.models.<basename> --project <repo>`: project override, then global, then the shipped tier default) and pass it explicitly at dispatch. Never rely on the dispatched role's frontmatter alone; a resolved subagent model is never Fable.
129
+ Dispatch-time model contract (belt-and-braces): alongside the preamble, resolve each specialist's model through the config chain (`read-config agents.models.<basename> --project <repo>`: project override, then global, then the shipped tier default) and pass it explicitly at dispatch. Never rely on the dispatched role's frontmatter alone; a resolved subagent model is never Fable,
130
+ unless an explicit `agents.models.<name>` config override names Fable for that role, in which
131
+ case the override is honored as written.
112
132
 
113
133
  Completion report (require-then-synthesize): every dispatched specialist MUST end with a structured completion report as its final message. The preamble's `REPORT_CONTRACT` injects this and the role prompts carry the per-role format (see `references/agent-report-contract.md`). Because child-agent honor is best-effort across harnesses, this is decision-shaping, not a hard block. When a specialist returns no usable report (it went idle, emitted only a bare ping, or its message was lost to a mid-run interjection), run `scripts/agent-report <intent_dir> --role <role>` to synthesize a deterministic filesystem-derived report so the handoff account always exists. Use the agent-authored report when present, the synthesized one otherwise.
114
134
 
@@ -185,14 +205,15 @@ Then proceed to How.
185
205
 
186
206
  ## How Phase
187
207
 
188
- This is the L-tier shape (see `## Tiers` above); S/M skip step 3 and fold the checklist
189
- rationale into plan.md inline. The `actions/` directory itself is scaffolded empty at
190
- intent birth and persists at every tier; only writing `ACTION_N.md` files into it is L
191
- only (S/M leave the directory empty).
208
+ Every tier runs all four steps below (see `## Tiers` above). The `actions/` directory is
209
+ scaffolded (with a `.gitkeep`) at intent birth; the planner then writes at least one REAL
210
+ `ACTION_N.md` into it at every tier. The tier only changes step 3's granularity: S/M write
211
+ one consolidated `actions/ACTION_1.md`, L writes one `actions/ACTION_N.md` per task. A
212
+ `.gitkeep`-only or empty `actions/` fails the How gate.
192
213
 
193
214
  1. If `superpowers:writing-plans` is available as a skill, delegate plan creation to it. Tell it the plan saves to the active intent's directory (not `docs/superpowers/plans/`).
194
215
  2. Otherwise, write `plan.md` directly - implementation plan with numbered tasks
195
- 3. Write `ACTION_N.md` files into the existing `actions/` directory (one per task, self-contained) - L only
216
+ 3. Write at least one real `ACTION_N.md` into the existing `actions/` directory, self-contained (S/M: one consolidated `ACTION_1.md`; L: one per task)
196
217
  4. Write `checklist.md` - execution registry with checkboxes covering all actions
197
218
  5. Notify user (How briefing): brief per `references/human-report-contract.md`
198
219
  (State: the plan shape, task count and what it builds; Risk: the riskiest task or
@@ -30,9 +30,10 @@ the savepoint ledger.
30
30
  One thinker agent boots ONCE and stays in a single context for two stations:
31
31
 
32
32
  1. Station 1 — writes `spec.md` (collapsed sections allowed, one line each is valid).
33
- 2. Station 2 — writes `plan.md` + `checklist.md` in the SAME context (no reboot). plan.md
34
- carries the checklist rationale inline instead of separate `actions/ACTION_N.md` files.
35
- `actions/` is not created for S/M.
33
+ 2. Station 2 — writes `plan.md` + `checklist.md` + at least one real action file in the
34
+ SAME context (no reboot). At S/M the thinker consolidates the whole delivery into one
35
+ `actions/ACTION_1.md` (rather than one file per task); `actions/` is populated at every
36
+ tier, and a `.gitkeep`-only or empty `actions/` fails the How gate.
36
37
 
37
38
  Then a sonnet executor (a fresh dispatch, this is the one topology split that always
38
39
  happens) implements from plan.md + checklist.md, checks off items, appends `## Insights`,
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: plastic-continuing
3
+ description: >-
4
+ Use when the user says "continue", "resume", or "pick up where we left off", starts a new
5
+ session and wants to keep going, asks "what should I work on", or asks a where-was-I question
6
+ that never says "continue" (for example "where was I"). This is the front door for resuming
7
+ work: it dispatches to plastic-intent-continuing (a specific intent named to resume),
8
+ plastic-project-continuing (the default, general board landing), or
9
+ plastic-roadmap-continuing (a roadmap or delivery batch named to resume).
10
+ user-invocable: true
11
+ ---
12
+
13
+ # Continuing - the front door
14
+
15
+ `plastic-continuing` is the front door for resuming work (ruling 96: continuing routes,
16
+ starting does the lock plus resume plus work). It routes to exactly one of three skills and
17
+ does nothing else: no ledger-resume, no dashboard render, no roadmap read happens here.
18
+
19
+ ## Route
20
+
21
+ | Args / context | Route to |
22
+ |---|---|
23
+ | `--intent {id}`, or the user names one specific intent (by id or description) to resume | `plastic-intent-continuing` (intent route) |
24
+ | `--roadmap {slug}`, or the user asks to continue/resume a roadmap or delivery batch | `plastic-roadmap-continuing` (roadmap route) |
25
+ | bare "continue" / "resume" / no further target (default) | `plastic-project-continuing` (project route) |
26
+
27
+ ## Announce, then hand off
28
+
29
+ State the chosen route in one line before delegating (this is the router's own "present state
30
+ before any ask" - the router asks nothing itself). Example: "Routing to the project board (no
31
+ specific intent or roadmap named)."
32
+
33
+ Then hand off to the chosen skill. Do not inline any of the routed skill's own work here -
34
+ that belongs to the routes.
@@ -0,0 +1,91 @@
1
+ {
2
+ "skill_name": "plastic-continuing",
3
+ "notes": "Intent 158a1. New bare front-door router restored per intent 96 (D8). Scopes: description triggering (1-5) and routing behavior (6-9), the latter checked as convention against SKILL.md's routing table.",
4
+ "results": {
5
+ "triggering": { "cases": 5, "passed": 5, "run": "2026-07-10, one subagent per case" },
6
+ "behavior": { "cases": 4, "passed": 4, "evidence": "convention checks against skills/continuing/SKILL.md's routing table" }
7
+ },
8
+ "evals": [
9
+ {
10
+ "id": 1, "scope": "triggering", "set": "train",
11
+ "prompt": "continue",
12
+ "expected_output": "Activates plastic-continuing (the bare 'continue' keyword is the router's documented trigger).",
13
+ "files": [],
14
+ "assertions": [
15
+ { "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
16
+ ]
17
+ },
18
+ {
19
+ "id": 2, "scope": "triggering", "set": "train",
20
+ "prompt": "resume where we left off",
21
+ "expected_output": "Activates plastic-continuing.",
22
+ "files": [],
23
+ "assertions": [
24
+ { "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
25
+ ]
26
+ },
27
+ {
28
+ "id": 3, "scope": "triggering", "set": "validation",
29
+ "prompt": "pick up where we left off",
30
+ "expected_output": "Activates plastic-continuing.",
31
+ "files": [],
32
+ "assertions": [
33
+ { "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
34
+ ]
35
+ },
36
+ {
37
+ "id": 4, "scope": "triggering", "set": "validation",
38
+ "prompt": "where was I",
39
+ "expected_output": "Activates plastic-continuing (indirect trigger: a continue request that never says 'continue').",
40
+ "files": [],
41
+ "assertions": [
42
+ { "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
43
+ ]
44
+ },
45
+ {
46
+ "id": 5, "scope": "triggering", "set": "validation",
47
+ "prompt": "continue the for-loop in this function",
48
+ "expected_output": "Does NOT activate plastic-continuing. Near-miss: shares 'continue' but is a code-editing task.",
49
+ "files": [],
50
+ "assertions": [
51
+ { "type": "code", "check": "router CHOICE != plastic-continuing", "observed": "none", "result": "pass" }
52
+ ]
53
+ },
54
+ {
55
+ "id": 6, "scope": "behavior", "set": "train",
56
+ "prompt": "continue",
57
+ "expected_output": "Bare 'continue' with no further target dispatches to the project route (plastic-project-continuing), the routing table's default.",
58
+ "files": ["skills/continuing/SKILL.md"],
59
+ "assertions": [
60
+ { "type": "convention", "check": "routing table's default row maps bare continue/resume/no target to plastic-project-continuing", "observed": "present", "result": "pass" }
61
+ ]
62
+ },
63
+ {
64
+ "id": 7, "scope": "behavior", "set": "train",
65
+ "prompt": "continue --intent 4a",
66
+ "expected_output": "Dispatches to the intent route (plastic-intent-continuing).",
67
+ "files": ["skills/continuing/SKILL.md"],
68
+ "assertions": [
69
+ { "type": "convention", "check": "routing table maps --intent {id} to plastic-intent-continuing", "observed": "present", "result": "pass" }
70
+ ]
71
+ },
72
+ {
73
+ "id": 8, "scope": "behavior", "set": "validation",
74
+ "prompt": "resume the statusline-coloring intent",
75
+ "expected_output": "Dispatches to the intent route (plastic-intent-continuing): a specific intent named by description.",
76
+ "files": ["skills/continuing/SKILL.md"],
77
+ "assertions": [
78
+ { "type": "convention", "check": "routing table maps a named specific intent (by id or description) to plastic-intent-continuing", "observed": "present", "result": "pass" }
79
+ ]
80
+ },
81
+ {
82
+ "id": 9, "scope": "behavior", "set": "validation",
83
+ "prompt": "continue the consistency-dividend roadmap",
84
+ "expected_output": "Dispatches to the roadmap route (plastic-roadmap-continuing).",
85
+ "files": ["skills/continuing/SKILL.md"],
86
+ "assertions": [
87
+ { "type": "convention", "check": "routing table maps a named roadmap/delivery batch to plastic-roadmap-continuing", "observed": "present", "result": "pass" }
88
+ ]
89
+ }
90
+ ]
91
+ }
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: plastic-dashboard
3
- description: Use when the user wants an overview of intents, asks "where are we", "what's next", "what should I work on", "show the dashboard", or invokes /plastic-dashboard. Renders a deterministic Value×Effort work cockpit as Markdown across the global store and all projects, and emits a machine-readable queue that auto mode consumes.
3
+ description: Use when the user wants an overview of intents, asks "where are we", "what's next", "what should I work on", "show the dashboard", or invokes /plastic-dashboard. Renders the intent store(s) as Markdown prose, the global board as a narrative of work done, each project board as a short summary plus its most-valuable next work, and emits a machine-readable queue that auto mode consumes.
4
4
  user-invocable: false
5
5
  ---
6
6
 
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), **where we go next** (a Value×Effort matrix), and
10
+ **where we are** (recently worked), **where we go next** (the most-valuable next work), and
11
11
  **how to conduct it** (a disposition per intent). The human-facing surface is **Markdown**,
12
12
  because the user's UI renders Markdown natively but collapses raw tool-call stdout.
13
13
 
@@ -19,7 +19,7 @@ state → byte-identical payload, regardless of model. Do NOT hand-summarize int
19
19
 
20
20
  - User invokes `/plastic-dashboard`
21
21
  - User asks "where are we", "what's next", "what should I work on", "show me the intents"
22
- - `plastic-intent-continuing` lands on the board on resume
22
+ - `plastic-project-continuing` lands on the board on resume
23
23
  - `plastic-auto` reads `--json` to choose the next dispatchable intent
24
24
 
25
25
  ## Procedure (the Markdown board — default human surface)
@@ -34,9 +34,9 @@ ruby ~/.plastic/scripts/dashboard.rb [continue|project <slug>] --data
34
34
  - `project <slug>` → that **project** board payload (`mode: "project"`).
35
35
 
36
36
  The payload is read-only JSON. Global-board fields: `date`, `store_health`, `recently_worked`,
37
- `matrix` (`quick_win`/`next_big`/`defer`/`triage`/`research`, each a list of `{line, bullet, ...}`),
38
- `counts`, `projects`, `project_totals`. Project-board fields: `slug`, `store_health`,
39
- `description`, `recently_worked`, `matrix`, `counts`, `active`, `future`.
37
+ `next_work` (a flat, rank-ordered list of `{id, intent, scope, lifecycle, value, disposition,
38
+ flags, line}`), `counts`, `projects`, `project_totals`. Project-board fields: `slug`,
39
+ `store_health`, `description`, `recently_worked`, `next_work`, `counts`, `active`, `future`.
40
40
 
41
41
  Each board load runs the scoped store check (`doctor --store <scope>`): the global board runs
42
42
  `--store global` and a project board runs `--store <slug>`. The result rides in the payload as
@@ -51,13 +51,16 @@ Templates live in this skill's `templates/` directory:
51
51
  `~/.claude/skills/plastic-dashboard/templates/dashboard-global.md` and
52
52
  `dashboard-project.md`.
53
53
 
54
- Fill mechanically no rewriting, no re-sorting:
55
- - `{{a.b.count}}` → the integer (e.g. `matrix.quick_win.count` = that list's length).
54
+ Fill mechanically, no rewriting, no re-sorting:
55
+ - `{{a.b.count}}` → the integer (e.g. `counts.active` = that count).
56
56
  - `{{...lines}}` → join the list's `.line` strings with **real newlines** (one per line).
57
- These lines are already glyph-led (the glyph is the bullet — never add `-`, never emit
58
- `<br>`). If a matrix quadrant list is empty, render `_(none)_`.
57
+ These are ordinary prose lines, not glyph-led bullets: never add a Markdown `-` bullet,
58
+ never emit `<br>`. If a list is empty, render `_(none)_`.
59
+ - `next_work.lines` → the most-valuable next work, already ranked; each line reads
60
+ `"<id> <intent, truncated>"`. Use each entry's `disposition`/`flags` fields when the prose
61
+ needs to say why an item is next.
59
62
  - `projects.lines` → one line per project:
60
- `- **{slug}** {description} · active {active} · done {done} · future {future} · last accessed {last_accessed_at[0,10]}`.
63
+ `- **{slug}**: {description}, active {active}, done {done}, future {future}, last accessed {last_accessed_at[0,10]}`.
61
64
  - Scalars (`{{date}}`, `{{slug}}`, `{{description}}`) → substitute verbatim.
62
65
 
63
66
  ### Step 3 — Present it (mandatory, every invocation)
@@ -112,7 +115,7 @@ a raw terminal. The Markdown board (`--data` + template) is the surface for the
112
115
  ## How classification works (deterministic)
113
116
 
114
117
  The script computes Effort/Value/Flags/Override/Caps; the agent never re-derives them.
115
- To explain or debug a quadrant assignment, read `references/classification.md`.
118
+ To explain or debug a ranking or disposition, read `references/classification.md`.
116
119
 
117
120
  ## Eval
118
121
 
@@ -123,7 +126,7 @@ intentional change means the skill is broken.
123
126
 
124
127
  ## Notes
125
128
 
126
- - Quadrant lists are **not** Markdown `-` bullets the glyph is the bullet (the boards are
127
- UI-only and may evolve, so they need not be valid Markdown lists). Never emit `<br>`.
129
+ - Board lines are ordinary prose, not a rigid grid: the boards are UI-only and may evolve,
130
+ so they need not be valid Markdown lists. Never emit `<br>`.
128
131
  - Clusters (Zettelkasten grouping in INDEX.md) are intentionally not rendered.
129
132
  - Additive: changes no core lifecycle, gate, or cycle logic.
@@ -1,7 +1,7 @@
1
1
  # How Classification Works (Deterministic)
2
2
 
3
3
  The script (`dashboard.rb`) computes Effort/Value/Flags/Override/Caps deterministically;
4
- the agent never re-derives them. Read this to explain or debug a quadrant assignment.
4
+ the agent never re-derives them. Read this to explain or debug a ranking or disposition.
5
5
 
6
6
  - **Effort** — small for `research`/`exploration`/`bugfix`, for already-scoped intents
7
7
  (plan/checklist exists), or a **branch id** (folgezettel depth ≥ 2, e.g. `4a`, `12b3`); big
@@ -16,7 +16,7 @@ the agent never re-derives them. Read this to explain or debug a quadrant assign
16
16
  the staleness threshold. All three kept low-noise by design.
17
17
  - **Override** — a `value: high|low` frontmatter field always wins (pre-stamped data, never
18
18
  model judgment at render time).
19
- - **Caps** quadrant lists and the project board's `active`/`future` lists are capped at 8
20
- entries plus a trailing "+N more" line; each entry's text is truncated to 120 characters
19
+ - **Caps**: the next-work list and the project board's `active`/`future` lists are capped at
20
+ 8 entries plus a trailing "+N more" line; each entry's text is truncated to 120 characters
21
21
  with a trailing ellipsis. Applies to the Markdown board only (the ASCII renderer has its own
22
22
  separate `CELL_CAP`).
@@ -1,31 +1,16 @@
1
- # 🧩 Plastic · Global Board {{date}}
1
+ # 🧩 Plastic · Global Board, {{date}}
2
2
 
3
- **Recently worked** · last 24h
3
+ **Recently worked** (last 24h)
4
4
  {{recently_worked.lines}}
5
5
 
6
- ## Where we go next · Value × Effort *(global intents only)*
6
+ ## Where we are
7
7
 
8
- | | Small effort | Big effort |
9
- |---|---|---|
10
- | **High value** | ⚡ **Quick win** · {{matrix.quick_win.count}} | ★ **Next big thing** · {{matrix.next_big.count}} |
11
- | **Low value** | → **Defer (agent)** · {{matrix.defer.count}} | ⚑ **Triage** · {{matrix.triage.count}} |
8
+ {{counts.active}} intents active, {{counts.done}} done, {{counts.future}} queued for later.
12
9
 
13
- **⚡ Quick win** small effort, high value
14
- {{matrix.quick_win.lines}}
15
-
16
- **★ Next big thing** — big effort, high value
17
- {{matrix.next_big.lines}}
18
-
19
- **→ Defer (agent)** — small effort, low value
20
- {{matrix.defer.lines}}
21
-
22
- **⚑ Triage** — big effort, low value
23
- {{matrix.triage.lines}}
24
-
25
- 🔬 **Research → agent**
26
- {{matrix.research.lines}}
27
-
28
- ## Projects · active {{project_totals.active}} · done {{project_totals.done}} · future {{project_totals.future}}
10
+ ## Projects, active {{project_totals.active}}, done {{project_totals.done}}, future {{project_totals.future}}
29
11
  {{projects.lines}}
30
12
 
13
+ ## Most-valuable next work
14
+ {{next_work.lines}}
15
+
31
16
  **What would you like to work on next?** (type an **intent id**, a **project name**, or anything **new** you'd like to start)
@@ -1,33 +1,11 @@
1
- # 📦 {{slug}} · Project Board {{date}}
1
+ # 📦 {{slug}} · Project Board, {{date}}
2
2
 
3
3
  {{description}}
4
4
 
5
- **Recently worked** · last 24h
5
+ **Recently worked** (last active work, last 24h)
6
6
  {{recently_worked.lines}}
7
7
 
8
- ## Where we go next · Value × Effort
9
-
10
- | | Small effort | Big effort |
11
- |---|---|---|
12
- | **High value** | ⚡ **Quick win** · {{matrix.quick_win.count}} | ★ **Next big thing** · {{matrix.next_big.count}} |
13
- | **Low value** | → **Defer (agent)** · {{matrix.defer.count}} | ⚑ **Triage** · {{matrix.triage.count}} |
14
-
15
- **⚡ Quick win** — small effort, high value
16
- {{matrix.quick_win.lines}}
17
-
18
- **★ Next big thing** — big effort, high value
19
- {{matrix.next_big.lines}}
20
-
21
- **→ Defer (agent)** — small effort, low value
22
- {{matrix.defer.lines}}
23
-
24
- **⚑ Triage** — big effort, low value
25
- {{matrix.triage.lines}}
26
-
27
- 🔬 **Research → agent**
28
- {{matrix.research.lines}}
29
-
30
- ## Intents · active {{counts.active}} · done {{counts.done}} · future {{counts.future}}
8
+ ## Intents, active {{counts.active}}, done {{counts.done}}, future {{counts.future}}
31
9
 
32
10
  **Active**
33
11
  {{active.lines}}
@@ -35,6 +13,9 @@
35
13
  **Future**
36
14
  {{future.lines}}
37
15
 
38
- **Legend** · What ◔ Why ◑ How ◕ Exec ● Done · ⚡ quick win ★ big → defer ⚑ triage 🔬 research
16
+ ## Most-valuable next work
17
+ {{next_work.lines}}
18
+
19
+ **Legend** · ○ What ◔ Why ◑ How ◕ Exec ● Done
39
20
 
40
21
  **What would you like to work on next?** (type an **intent id**, or **global** to go back)
@@ -13,7 +13,7 @@ Doctor has three scopes. Pick the right one for the situation:
13
13
  | Scope | Flag | When it runs | States |
14
14
  |-------|------|--------------|--------|
15
15
  | Core check | `--core` | SessionStart hook (automatic), also available on demand | Binary: pass or error |
16
- | Store check | `--store [global\|<slug>]` | Dashboard load, `plastic-intent-continuing` | Three-state: pass / warn / fail |
16
+ | Store check | `--store [global\|<slug>]` | Dashboard load, `plastic-project-continuing` | Three-state: pass / warn / fail |
17
17
  | Full check | (no flag) | After every update (automatic), or `/plastic-doctor` | Three-state: pass / warn / fail |
18
18
 
19
19
  ### `--core` (binary, manifest-backed)
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: plastic-install
3
- description: 'Use when initializing Plastic globally (~/.plastic/) or locally in a project, or to re-install/repair a broken installation. Accepts channel flags (--alpha, --beta, --latest) to select release channel. First install defaults to --beta; reinstalls match the already-installed channel. Global install is recommended: it creates the global intent store as a git-backed repository. Local install creates .plastic/ in the current project for testing.'
3
+ description: 'Use when initializing Plastic globally (~/.plastic/) or locally in a project, or to re-install/repair a broken installation. Accepts channel flags (--alpha, --beta, --latest) to select release channel. First install defaults to --latest (stable); reinstalls match the already-installed channel. Global install is recommended: it creates the global intent store as a git-backed repository. Local install creates .plastic/ in the current project for testing.'
4
4
  user-invocable: true
5
5
  ---
6
6
 
7
7
  # Install Plastic
8
8
 
9
- > **Recommended path:** for a first install, run `npx -y @zalom/plastic@beta install --claude`
10
- > in your shell (or `bunx -y @zalom/plastic@beta install --claude` if you use Bun). This skill
9
+ > **Recommended path:** for a first install, run `npx -y @zalom/plastic@latest install --claude`
10
+ > in your shell (or `bunx -y @zalom/plastic@latest install --claude` if you use Bun). This skill
11
11
  > exists to **re-install or repair** an existing setup from inside the agent, and to
12
12
  > drive interactive global configuration. Whenever this skill performs an install or
13
13
  > re-install, it **runs `/plastic-doctor` afterward** and reports the result.
@@ -16,7 +16,7 @@ user-invocable: true
16
16
 
17
17
  If Plastic is installed, derive `<channel>` from `~/.plastic/VERSION`: a version containing
18
18
  `-alpha` means `@alpha`, `-beta` means `@beta`, otherwise `@latest`. If not installed
19
- (first install), default to `@beta`. The user can always override with
19
+ (first install), default to `@latest`. The user can always override with
20
20
  `--alpha` / `--beta` / `--latest`.
21
21
 
22
22
  ## Re-install / repair
@@ -35,18 +35,18 @@ Then **run `/plastic-doctor`** and report what it found.
35
35
 
36
36
  | Flag | Behavior |
37
37
  |------|----------|
38
- | `--latest` | Install from the stable channel |
39
- | `--beta` | Install from the beta channel (default on a first install) |
38
+ | `--latest` | Install from the stable channel (default on a first install) |
39
+ | `--beta` | Install from the beta channel |
40
40
  | `--alpha` | Install from the alpha channel |
41
41
 
42
42
  When invoked from within Claude Code (re-install or channel switch), the skill
43
43
  runs the appropriate npx command:
44
44
 
45
45
  ```bash
46
- # Stable
46
+ # Stable (default on a first install)
47
47
  npx -y @zalom/plastic@latest install --claude
48
48
 
49
- # Beta (default on a first install)
49
+ # Beta
50
50
  npx -y @zalom/plastic@beta install --claude
51
51
 
52
52
  # Alpha
@@ -68,10 +68,10 @@ Run `/plastic-install` with no arguments.
68
68
  Check if `~/.plastic/VERSION` exists.
69
69
  - If yes: announce "Plastic is already installed at ~/.plastic/. Run `/plastic-update` to
70
70
  sync core files, or use the re-install command above to repair in place."
71
- - If no: run the fresh install command (default `@beta`, or the channel the user named):
71
+ - If no: run the fresh install command (default `@latest`, or the channel the user named):
72
72
 
73
73
  ```bash
74
- npx -y @zalom/plastic@beta install --claude
74
+ npx -y @zalom/plastic@latest install --claude
75
75
  ```
76
76
 
77
77
  This single command, via `install.rb` (`bootstrap` + `distribute`), creates `store/`,