@zalom/plastic 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/PLASTIC-reference.md +11 -11
  2. package/PLASTIC.md +11 -9
  3. package/README.md +48 -1
  4. package/agents/plastic-enforcer.md +8 -5
  5. package/agents/plastic-future-intent-researcher.md +1 -1
  6. package/agents/plastic-intent-curator.md +9 -10
  7. package/agents/plastic-spec-specialist.md +9 -6
  8. package/bin/plastic.js +2 -2
  9. package/hooks/check-update +1 -1
  10. package/hooks/continue +1 -1
  11. package/package.json +1 -1
  12. package/scripts/dashboard.rb +29 -24
  13. package/scripts/doctor.rb +188 -9
  14. package/scripts/end-intent +330 -0
  15. package/scripts/hook-code-gate +1 -1
  16. package/scripts/hook-continue +2 -2
  17. package/scripts/hook-create-gate +2 -2
  18. package/scripts/hook-session-start +1 -1
  19. package/scripts/install.rb +2 -1
  20. package/scripts/lib/bridge.rb +116 -3
  21. package/scripts/lib/dashboard_banner.rb +8 -9
  22. package/scripts/lib/installer_core.rb +17 -8
  23. package/scripts/lib/legacy_bookend_amnesty.rb +35 -0
  24. package/scripts/lib/release_guard.rb +62 -0
  25. package/scripts/lib/roadmap_queue.rb +285 -0
  26. package/scripts/lib/roadmap_savepoint.rb +213 -0
  27. package/scripts/lib/store_provisioning.rb +1 -1
  28. package/scripts/lib/worktree.rb +21 -0
  29. package/scripts/new-intent +2 -1
  30. package/scripts/read-config +3 -3
  31. package/scripts/roadmap-next +44 -0
  32. package/scripts/roadmap-savepoint +64 -0
  33. package/scripts/{versions.rb → rollback.rb} +33 -41
  34. package/scripts/update.rb +1 -1
  35. package/skills/_active-intent-gate.md +1 -1
  36. package/skills/_decision-tables.md +50 -0
  37. package/skills/auto/SKILL.md +69 -68
  38. package/skills/auto/evals/evals.json +4 -4
  39. package/skills/auto/references/agent-architecture.md +2 -2
  40. package/skills/continuing/SKILL.md +23 -130
  41. package/skills/continuing/evals/evals.json +26 -80
  42. package/skills/dashboard/SKILL.md +18 -15
  43. package/skills/dashboard/references/classification.md +3 -3
  44. package/skills/dashboard/templates/dashboard-global.md +8 -23
  45. package/skills/dashboard/templates/dashboard-project.md +7 -26
  46. package/skills/doctor/SKILL.md +3 -3
  47. package/skills/install/SKILL.md +10 -10
  48. package/skills/{brainstorming → intent-brainstorming}/SKILL.md +43 -45
  49. package/skills/intent-brainstorming/evals/evals.json +67 -0
  50. package/skills/{brainstorming → intent-brainstorming}/references/design-principles.md +12 -17
  51. package/skills/intent-continuing/SKILL.md +99 -0
  52. package/skills/intent-continuing/evals/evals.json +145 -0
  53. package/skills/intent-continuing/references/context-management.md +28 -0
  54. package/skills/{creating-intent → intent-creating}/SKILL.md +3 -3
  55. package/skills/{creating-intent → intent-creating}/evals/evals.json +1 -1
  56. package/skills/{intent-discovery → intent-discovering}/SKILL.md +1 -1
  57. package/skills/intent-ending/SKILL.md +151 -0
  58. package/skills/intent-ending/evals/evals.json +74 -0
  59. package/skills/{executing-plan → intent-executing}/SKILL.md +75 -15
  60. package/skills/intent-executing/evals/evals.json +66 -0
  61. package/skills/{brainstorming-grill-me → intent-grilling}/SKILL.md +4 -4
  62. package/skills/{linking-intents → intent-linking}/SKILL.md +1 -1
  63. package/skills/{linking-intents → intent-linking}/evals/evals.json +1 -1
  64. package/skills/{lock → intent-locking}/SKILL.md +1 -1
  65. package/skills/{writing-plans → intent-planning}/SKILL.md +48 -20
  66. package/skills/intent-planning/evals/evals.json +66 -0
  67. package/skills/{writing-plans → intent-planning}/references/plan-format.md +31 -7
  68. package/skills/{research → intent-researching}/SKILL.md +2 -2
  69. package/skills/{research → intent-researching}/evals/evals.json +1 -1
  70. package/skills/{savepoint → intent-savepoint}/SKILL.md +13 -1
  71. package/skills/intent-speccing/SKILL.md +69 -0
  72. package/skills/intent-speccing/evals/evals.json +126 -0
  73. package/skills/intent-speccing/references/per-section-fill-rules.md +92 -0
  74. package/skills/intent-speccing/references/self-verify-checklist.md +38 -0
  75. package/skills/intent-starting/SKILL.md +2 -2
  76. package/skills/intent-starting/evals/evals.json +2 -2
  77. package/skills/project-continuing/SKILL.md +104 -0
  78. package/skills/project-continuing/evals/evals.json +100 -0
  79. package/skills/project-continuing/references/board-fill.md +33 -0
  80. package/skills/{creating-project → project-creating}/SKILL.md +2 -2
  81. package/skills/releasing/SKILL.md +66 -14
  82. package/skills/releasing/references/release-lines.md +105 -0
  83. package/skills/roadmap/SKILL.md +7 -1
  84. package/skills/roadmap/references/file-format.md +30 -1
  85. package/skills/roadmap/references/operations.md +26 -6
  86. package/skills/roadmap-continuing/SKILL.md +85 -0
  87. package/skills/roadmap-continuing/evals/evals.json +82 -0
  88. package/skills/roadmap-continuing/references/liveness-ranking.md +56 -0
  89. package/skills/{versions → rollback}/SKILL.md +30 -20
  90. package/skills/{creating-skills → skill-creating}/SKILL.md +2 -2
  91. package/skills/{creating-skills → skill-creating}/evals/evals.json +5 -5
  92. package/skills/{creating-skills → skill-creating}/references/progressive-disclosure.md +2 -2
  93. package/skills/{evaluating-skills → skill-evaluating}/SKILL.md +1 -1
  94. package/skills/{evaluating-skills → skill-evaluating}/evals/evals.json +3 -3
  95. package/skills/{intent-curator → store-curating}/SKILL.md +6 -7
  96. package/skills/{intent-curator → store-curating}/evals/evals.json +1 -1
  97. package/skills/{managing-index → store-indexing}/SKILL.md +6 -7
  98. package/skills/{managing-index → store-indexing}/evals/evals.json +1 -1
  99. package/skills/{add-project-store → store-provisioning}/SKILL.md +2 -2
  100. package/skills/tutorial/SKILL.md +65 -0
  101. package/skills/tutorial/evals/evals.json +186 -0
  102. package/skills/tutorial/references/track-1-guided.md +123 -0
  103. package/skills/tutorial/references/track-2-auto.md +95 -0
  104. package/skills/tutorial/references/track-3-projects-and-roadmaps.md +110 -0
  105. package/skills/uninstall/SKILL.md +2 -2
  106. package/skills/update/SKILL.md +3 -3
  107. package/templates/agents.md +7 -7
  108. package/templates/config.yml +2 -1
  109. package/templates/index.md +4 -1
  110. package/skills/brainstorming/evals/evals.json +0 -22
  111. package/skills/savepoint/references/context-management.md +0 -32
  112. /package/skills/{creating-intent → intent-creating}/references/lifecycle.md +0 -0
  113. /package/skills/{creating-intent → intent-creating}/references/wikilinks.md +0 -0
  114. /package/skills/{executing-plan → intent-executing}/code-quality-reviewer-prompt.md +0 -0
  115. /package/skills/{executing-plan → intent-executing}/implementer-prompt.md +0 -0
  116. /package/skills/{executing-plan → intent-executing}/spec-reviewer-prompt.md +0 -0
  117. /package/skills/{linking-intents → intent-linking}/references/zettelkasten.md +0 -0
  118. /package/skills/{continuing → intent-savepoint}/references/context-management.md +0 -0
  119. /package/skills/{creating-project → project-creating}/references/hubs-projects.md +0 -0
  120. /package/skills/{creating-project → project-creating}/references/project-scaffolding.md +0 -0
  121. /package/skills/{creating-skills → skill-creating}/references/agents.md +0 -0
  122. /package/skills/{creating-skills → skill-creating}/references/evals.md +0 -0
  123. /package/skills/{creating-skills → skill-creating}/references/hooks.md +0 -0
  124. /package/skills/{creating-skills → skill-creating}/references/scripts.md +0 -0
  125. /package/skills/{creating-skills → skill-creating}/references/skills.md +0 -0
  126. /package/skills/{creating-skills → skill-creating}/scripts/scaffold.rb +0 -0
  127. /package/skills/{evaluating-skills → skill-evaluating}/assets/eval-template.json +0 -0
  128. /package/skills/{evaluating-skills → skill-evaluating}/references/convention-checks.md +0 -0
  129. /package/skills/{evaluating-skills → skill-evaluating}/references/eval-methodology.md +0 -0
  130. /package/skills/{managing-index → store-indexing}/references/zettelkasten-linking.md +0 -0
@@ -115,19 +115,19 @@ Detailed conventions live inside the skills that use them, not in this file.
115
115
 
116
116
  | Topic | Skill | References in skill |
117
117
  |-------|-------|-------------------|
118
- | Creating intents, lifecycle | `plastic-creating-intent` | lifecycle, wikilinks |
119
- | Brainstorming, spec writing | `plastic-brainstorming` | — |
120
- | Planning, actions | `plastic-writing-plans` | — |
121
- | Execution, delivery | `plastic-executing-plan` | — |
118
+ | Creating intents, lifecycle | `plastic-intent-creating` | lifecycle, wikilinks |
119
+ | Brainstorming, spec writing | `plastic-intent-brainstorming` | — |
120
+ | Planning, actions | `plastic-intent-planning` | — |
121
+ | Execution, delivery | `plastic-intent-executing` | — |
122
122
  | Autonomous delivery | `plastic-auto` | agent architecture |
123
- | Save/restore state | `plastic-savepoint`, `plastic-continuing` | context management |
124
- | Knowledge graph, linking | `plastic-linking-intents` | zettelkasten, wikilinks |
125
- | Projects, hubs | `plastic-creating-project` | hubs, project stores |
126
- | Provision a project store | `plastic-add-project-store` | project stores |
127
- | Index maintenance | `plastic-managing-index` | — |
123
+ | Save/restore state | `plastic-intent-savepoint`, `plastic-intent-continuing` | context management |
124
+ | Knowledge graph, linking | `plastic-intent-linking` | zettelkasten, wikilinks |
125
+ | Projects, hubs | `plastic-project-creating` | hubs, project stores |
126
+ | Provision a project store | `plastic-store-provisioning` | project stores |
127
+ | Index maintenance | `plastic-store-indexing` | — |
128
128
  | Releases, deprecations | `plastic-releasing` | deprecation process |
129
129
  | Health diagnostics | `plastic-doctor` | three scopes: `--core` (binary install-integrity check, runs on SessionStart), `--store [global\|<slug>]` (per-store check, runs on dashboard load), no flag = full check (runs after every update); gate enforcement, stuck detection |
130
- | Authoring skills, agents, hooks | `plastic-creating-skills` | progressive disclosure, agentskills.io spec |
131
- | Evaluating skills, evals | `plastic-evaluating-skills` | eval methodology, convention checks |
130
+ | Authoring skills, agents, hooks | `plastic-skill-creating` | progressive disclosure, agentskills.io spec |
131
+ | Evaluating skills, evals | `plastic-skill-evaluating` | eval methodology, convention checks |
132
132
  | Create, order, and consume a roadmap of intents | `plastic-roadmap` | file format, operations |
133
133
 
package/PLASTIC.md CHANGED
@@ -93,10 +93,10 @@ tags: [plastic, architecture]
93
93
 
94
94
  | Stage | Section | Deliverable | Detail |
95
95
  |-------|---------|-------------|--------|
96
- | **What** | `## Intent` | `{ID}--{slug}.md` | `plastic-creating-intent` |
97
- | **Why** | `## Context` + Decisions | `spec.md` | `plastic-brainstorming` |
98
- | **How** | Planning | `plan.md` + `actions/` + `checklist.md` | `plastic-writing-plans` |
99
- | **Exec** | Execution | `outcome.md` | `plastic-executing-plan` |
96
+ | **What** | `## Intent` | `{ID}--{slug}.md` | `plastic-intent-creating` |
97
+ | **Why** | `## Context` + Decisions | `spec.md` | `plastic-intent-brainstorming` |
98
+ | **How** | Planning | `plan.md` + `actions/` + `checklist.md` | `plastic-intent-planning` |
99
+ | **Exec** | Execution | `outcome.md` | `plastic-intent-executing` |
100
100
 
101
101
  `## Insights` is the append-only log of durable discoveries captured throughout ALL stages.
102
102
  An insight is a discovery worth keeping for later reads: novel, or old but newly relevant,
@@ -167,8 +167,10 @@ and Exec, spins up the team above, and works the dashboard's dispatchable queue.
167
167
  `human_only` (intents that need a person); auto mode consumes the former.
168
168
 
169
169
  **Model contract.** Every agent in `agents/*.md` pins an explicit Claude Code model alias in
170
- its own frontmatter: `opus`, `sonnet`, or `haiku`. Never `inherit`, never Fable. Aliases track
171
- "latest per tier" so no Plastic release is required to advance a tier. The tier by role:
170
+ its own frontmatter: `opus`, `sonnet`, or `haiku`. Never `inherit`, never Fable by default,
171
+ unless an explicit `agents.models.<name>` config override names Fable for that role, in which
172
+ case the override is honored as written. Aliases track "latest per tier" so no Plastic release
173
+ is required to advance a tier. The tier by role:
172
174
  `plastic-enforcer`, `plastic-brainstorming`, `plastic-planner` are `opus`;
173
175
  `plastic-spec-specialist`, `plastic-executor`, `plastic-intent-curator`,
174
176
  `plastic-future-intent-researcher`, `plastic-intent-discovery` are `sonnet`.
@@ -237,7 +239,7 @@ Beyond the lifecycle agents, Plastic ships thin skills for day-to-day operation:
237
239
  for its three scopes (`--core` for the boot integrity check, `--store` per store on dashboard
238
240
  load, and the full no-flag walk after an update).
239
241
  - **Lifecycle skills** (`plastic-install`, `plastic-update`, `plastic-uninstall`,
240
- `plastic-versions`, intent 55) are thin wrappers over a single pinned
242
+ `plastic-rollback`, intent 55) are thin wrappers over a single pinned
241
243
  `npx -y @zalom/plastic@<channel> <verb>` call: initialize or repair an install, advance a
242
244
  channel, remove Plastic, and step the local versions ledger.
243
245
 
@@ -327,7 +329,7 @@ A Zettelkasten structure note, not a table of contents. Clusters by meaning.
327
329
 
328
330
  Sections: `## Active`, `## Future`, `## Clusters`, `## Abandoned`, `## Completed`.
329
331
 
330
- For index maintenance, use `plastic-managing-index`.
332
+ For index maintenance, use `plastic-store-indexing`.
331
333
 
332
334
  One-line entry convention. Each index entry is ONE line: `- [<id> <terse title>](<dir>) <tags>`.
333
335
  The title is the title, not a summary: aim for about 80 characters, no multi-sentence
@@ -350,7 +352,7 @@ ALL work flows through intents.
350
352
  3. On completion, capture observations in `## Insights`.
351
353
  4. When done, write `outcome.md` + `## Outcome` summary. Update INDEX.md.
352
354
  5. Researches are intents. No separate folder.
353
- 6. Intents are created only via `plastic-creating-intent`. Never hand-author an intent file. The skill self-verifies the written intent with `scripts/validate-intent` before announcing or committing, so every intent is born complete. `--intent` text is escaped for double quotes and backslashes before it lands in frontmatter, so free-form text is safe to pass as-is, and a reciprocal `chain:` append preserves the target intent's existing flow- or block-style entries.
355
+ 6. Intents are created only via `plastic-intent-creating`. Never hand-author an intent file. The skill self-verifies the written intent with `scripts/validate-intent` before announcing or committing, so every intent is born complete. `--intent` text is escaped for double quotes and backslashes before it lands in frontmatter, so free-form text is safe to pass as-is, and a reciprocal `chain:` append preserves the target intent's existing flow- or block-style entries.
354
356
 
355
357
  ## House Style (self-check)
356
358
 
package/README.md CHANGED
@@ -99,6 +99,53 @@ Plastic delivers all work through successive stages ->
99
99
  | How | What is the plan? | Plan and checklist | plan.md, checklist.md, actions/ACTION_1.md ... ACTION_N.md |
100
100
  | Exec | What was actually delivered? | Outcome | outcome.md |
101
101
 
102
+ ## How to use Plastic
103
+
104
+ Plastic organizes all work as intents. Each intent is one directory, and it carries the same
105
+ small set of files at every stage.
106
+
107
+ **The intent directory**
108
+
109
+ | File | What it holds |
110
+ | ---- | -------------- |
111
+ | `{id}--slug.md` | The intent itself: intent line, context, decisions |
112
+ | `spec.md` | The Why, consolidated into one contract for the plan |
113
+ | `plan.md`, `checklist.md`, `actions/` | The How: the plan and its execution registry |
114
+ | `outcome.md` | The Exec record: what actually shipped |
115
+
116
+ See [`docs/architecture.md`](docs/architecture.md) for the full store layout, and
117
+ [reading a delivered intent](docs/guides/reading-a-delivered-intent.md) for how to read a
118
+ finished one fast.
119
+
120
+ **From idea to delivery, one line per stage**
121
+
122
+ | Stage | What happens |
123
+ | ----- | ------------- |
124
+ | What | Describe the idea in plain words; Plastic scaffolds the intent |
125
+ | Why | Explore it, one ruling at a time, then consolidate into `spec.md` |
126
+ | How | Turn `spec.md` into `plan.md` and `checklist.md` |
127
+ | Exec | Build the change, verify it, tick the checklist |
128
+ | Done | `outcome.md` records what shipped; the index moves the intent to Completed |
129
+
130
+ Walk this once in
131
+ [your first intent in 10 minutes](docs/guides/your-first-intent-in-10-minutes.md), or run
132
+ `plastic-tutorial` for an interactive, hands-on walkthrough of three different ways to work.
133
+
134
+ **Commands, by family**
135
+
136
+ | Family | Commands |
137
+ | ------ | -------- |
138
+ | Mode | `plastic-tutorial`, `plastic-auto` |
139
+ | Intent | `plastic-continuing`, `plastic-intent-creating`, `plastic-intent-starting`, `plastic-intent-brainstorming`, `plastic-intent-grilling`, `plastic-intent-speccing`, `plastic-intent-planning`, `plastic-intent-executing`, `plastic-intent-ending`, `plastic-intent-continuing`, `plastic-intent-researching` |
140
+ | Project and delivery | `plastic-project-creating`, `plastic-project-continuing`, `plastic-roadmap`, `plastic-roadmap-continuing`, `plastic-releasing` |
141
+ | Skill | `plastic-skill-creating`, `plastic-skill-evaluating` |
142
+ | Product | `plastic-install`, `plastic-update`, `plastic-uninstall`, `plastic-rollback`, `plastic-doctor`, `plastic-humanizer` |
143
+
144
+ See [`docs/guides/index.md`](docs/guides/index.md) for task-oriented walkthroughs.
145
+
146
+ The agent helps most at Why and How: turning a rough idea into rulings, and rulings into a
147
+ plan a machine can build from exactly. Read
148
+ [pick your mode](docs/guides/pick-your-mode.md) to decide how much of that to hand over.
102
149
 
103
150
  ## Compatibility and ownership
104
151
 
@@ -118,7 +165,7 @@ Plastic is developed through Plastic.
118
165
  The roadmap, intent history, plans, decisions, and outcomes
119
166
  behind releases are part of the repository, not a hidden process.
120
167
 
121
- See the current [roadmap](ROADMAP.md) and [changelog](CHANGELOG.md).
168
+ [changelog](CHANGELOG.md).
122
169
 
123
170
  ## Documentation
124
171
 
@@ -12,7 +12,9 @@ You are the Plastic Enforcer. You ARE the auto orchestrator, spanning the whole
12
12
  orchestrating main session on the best available thinking model (Fable, Opus, or whatever
13
13
  supersedes them) for the sharpest gating and synthesis. This is advice only: it changes no
14
14
  behavior and blocks nothing if ignored. It concerns the human's MAIN session; dispatched
15
- subagents keep their pinned tier and never resolve to Fable.
15
+ subagents keep their pinned tier and never resolve to Fable, unless an explicit
16
+ `agents.models.<name>` config override names Fable for that role, in which case the override
17
+ is honored as written.
16
18
 
17
19
  ## Your Responsibilities
18
20
 
@@ -42,7 +44,8 @@ dispatch also resolve the target agent's model through the config chain (`read-c
42
44
  agents.models.<basename> --project <repo>`: project override, then global, then the shipped
43
45
  tier default) and pass it explicitly as the dispatch call's model parameter, alongside the
44
46
  spawn-preamble live-state injection. Never rely on the dispatched role's frontmatter alone. A
45
- resolved subagent model is never Fable.
47
+ resolved subagent model is never Fable, unless an explicit `agents.models.<name>` config
48
+ override names Fable for that role, in which case the override is honored as written.
46
49
  5. **Gate each handoff** — check each stage deliverable against its exit criteria before handing to the next stage
47
50
  6. **Run the final review** — at the final gate, dispatch an INDEPENDENT reviewer subagent (not a sixth standing role)
48
51
 
@@ -56,7 +59,7 @@ ceremony, never these guarantees.
56
59
  1. Arm the gate, then dispatch the brainstorming specialist; gate its `## Context` + `### Decisions`
57
60
  2. Dispatch the spec-specialist; gate `spec.md`. Then the planner; gate `plan.md` + `checklist.md`
58
61
  3. Dispatch the executor; require a green suite. Sequential, one team per intent, on one branch when files are shared
59
- 4. Dispatch and review by default through Plastic's native engine, `plastic-executing-plan` (implementer plus two-stage review, no external plugin). If `superpowers:subagent-driven-development` and `superpowers:dispatching-parallel-agents` are available, or the user asks for them, delegate to them as an enhancement
62
+ 4. Dispatch and review by default through Plastic's native engine, `plastic-intent-executing` (implementer plus two-stage review, no external plugin). If `superpowers:subagent-driven-development` and `superpowers:dispatching-parallel-agents` are available, or the user asks for them, delegate to them as an enhancement
60
63
  5. At the final gate, dispatch an independent reviewer subagent, then complete the intent
61
64
 
62
65
  ## Human-facing stage reporting
@@ -72,5 +75,5 @@ The orchestrator consumes that internal report to write the human briefing; the
72
75
 
73
76
  - Enforce gates manually; do not rely on hooks, because the session id may be unset in headless or background runs
74
77
  - You never delegate gate ownership; the orchestrator is always the gate-keeper
75
- - Roles are thin handoff contracts, not an execution engine; dispatch through `plastic-executing-plan` by default, and through the superpowers skills only when they are available or the user prefers them
76
- - Fall back by case: if the harness supports subagents but superpowers is absent, use the native `plastic-executing-plan` engine; if the harness has no subagent dispatch at all, fall back to a single agent walking the full cycle
78
+ - Roles are thin handoff contracts, not an execution engine; dispatch through `plastic-intent-executing` by default, and through the superpowers skills only when they are available or the user prefers them
79
+ - Fall back by case: if the harness supports subagents but superpowers is absent, use the native `plastic-intent-executing` engine; if the harness has no subagent dispatch at all, fall back to a single agent walking the full cycle
@@ -31,4 +31,4 @@ You are the Plastic Future Intent Researcher. Your role is to pick up parked fut
31
31
  - You never modify `## Insights` or `## Outcome` sections — those belong to the worker
32
32
  - You use Read, WebSearch, WebFetch, and Bash (read-only grep/find) for research
33
33
  - You never change status fields — status is convention-derived from INDEX.md placement
34
- - When dispatching any sub-agent, resolve its model via `read-config agents.models.<basename> --project <repo>` and pass it explicitly at dispatch, never relying on inherited frontmatter; a resolved subagent model is never Fable
34
+ - When dispatching any sub-agent, resolve its model via `read-config agents.models.<basename> --project <repo>` and pass it explicitly at dispatch, never relying on inherited frontmatter; a resolved subagent model is never Fable, unless an explicit `agents.models.<name>` config override names Fable for that role, in which case the override is honored as written
@@ -10,11 +10,11 @@ You are the Plastic Intent Curator. Your role is to maintain the health and navi
10
10
 
11
11
  ## Your Responsibilities
12
12
 
13
- 1. **Intent lifecycle management** move intents between Active/Future/Completed/Abandoned in INDEX.md, fill in `## Outcome` sections (including the abandonment rationale when an intent is abandoned)
14
- 2. **INDEX.md maintenance** keep Active/Future/Clusters/Completed/Abandoned sections accurate and well-organized
15
- 3. **Link discovery** suggest connections between intents that share topics but aren't linked
16
- 4. **Cluster management** create new clusters when 3+ unlinked intents share tags, merge or rename clusters as topics evolve
17
- 5. **Orphan detection** flag intents with no links and no cluster membership
13
+ 1. **Intent lifecycle management** - move intents between Active/Future/Completed/Abandoned in INDEX.md, fill in `## Outcome` sections (including the abandonment rationale when an intent is abandoned)
14
+ 2. **INDEX.md maintenance** - keep Active/Future/Clusters/Completed/Abandoned sections accurate and well-organized
15
+ 3. **Link discovery** - suggest connections between intents that share topics but aren't linked
16
+ 4. **Cluster management** - create new clusters when 3+ unlinked intents share tags, merge or rename clusters as topics evolve
17
+ 5. **Orphan detection** - flag intents with no links and no cluster membership
18
18
  6. **Structural maintenance** - relocate structural junk (an unsanctioned section, a stray file, a frontmatter edge to an intent that no longer exists) out of an intent and into that intent's `revisions.md`, without altering what the intent delivered
19
19
 
20
20
  ## How You Work
@@ -24,17 +24,16 @@ You are the Plastic Intent Curator. Your role is to maintain the health and navi
24
24
  2. Read `~/.plastic/INDEX.md` (or project INDEX.md) to understand current organization
25
25
  3. Compare: are there intents not in any cluster? Missing from Active/Completed/Abandoned? Status mismatches?
26
26
  4. Make targeted edits to INDEX.md and intent frontmatter/links
27
- 5. On a terminal-state transition (Completed OR Abandoned), run the closing acts in the canonical End-tail order (see PLASTIC.md `## Delivery Isolation and the Single-Owner Lock`):
27
+ 5. On a terminal-state transition (Completed OR Abandoned), do these things:
28
28
  a. Author a real `outcome.md` in the intent directory from `~/.plastic/templates/outcome.md`, with the frontmatter `disposition: delivered` for a completed intent or `disposition: abandoned` for an abandoned one. `outcome.md` is MANDATORY at every terminal, delivered and abandoned alike: on abandon it records the abandonment reason and replaces the scaffolded placeholder sentinel (never leave `outcome.md` a placeholder at a terminal).
29
- b. Stamp the terminal savepoint bookend (intent 81) recording the disposition. Idempotent.
30
- c. Refresh the QMD index for that store LAST, after the terminal move, outcome.md, and savepoint, so the new outcome (or abandonment rationale) is searchable. This is mandatory on any terminal-state move and a no-op when QMD is absent, and it runs in the background so it never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <store-root> --async`
29
+ b. Call `plastic-intent-ending` for the terminal-transition close (INDEX move, savepoint `Done` bookend, store commit, disarm, and the QMD reindex last): `ruby ~/.plastic/scripts/end-intent --store <store> --id <id> --disposition delivered|abandoned`, then follow that skill's own disarm and reindex steps. Never restate the INDEX/savepoint/reindex one-liners here.
31
30
  6. Structural maintenance is move-and-record: remove the misplaced section, file, or ref from its artifact, then create or append `revisions.md` in that intent directory (copy the FORM from `~/.plastic/templates/revisions.md`). One entry per relocated item, newest at the bottom: a `## Revision vN - YYYY-MM-DD-HH:MM` header, a one-sentence `Why` ending with `[rule: <tag>]`, `Prior location`, and either `Content held` (verbatim) or a one-line `Change` for a frontmatter edit. For a stray file, embed its full content and delete the original. The violation-tag catalog is canonical in PLASTIC.md.
32
31
  7. Report what you changed
33
32
 
34
33
  ## Constraints
35
34
 
36
35
  - You only edit `~/.plastic/INDEX.md` (or project INDEX.md) and `~/.plastic/store/*/ID--slug.md` (or project store) files
37
- - You never create new intents that's the creating-intent skill's job
38
- - You never modify `## Insights`, `## Context`, or `## Outcome` content sections those belong to the worker. Relocating a whole misplaced block out of an intent and into `revisions.md` verbatim is structural maintenance, not authoring: maintenance moves an item out unchanged, it never rewords what stays, so the two rules do not conflict.
36
+ - You never create new intents - that's the intent-creating skill's job
37
+ - You never modify `## Insights`, `## Context`, or `## Outcome` content sections - those belong to the worker. Relocating a whole misplaced block out of an intent and into `revisions.md` verbatim is structural maintenance, not authoring: maintenance moves an item out unchanged, it never rewords what stays, so the two rules do not conflict.
39
38
  - For structural maintenance you may edit any Plastic artifact in an intent directory (intent file, `spec.md`, `plan.md`, `checklist.md`, `outcome.md`, frontmatter, or a stray file) and may create or append `revisions.md`. This is relocation only: you never rewrite, summarize, or reinterpret delivered content, and you never change what the intent delivered. A change to delivered meaning is a new intent, not a revision.
40
39
  - For discovery, put QMD first when available (`qmd-sync search`), then fall back to Read and grep/find; use Edit for targeted changes
@@ -12,18 +12,21 @@ When dispatched in auto mode you receive the standard Plastic spawn preamble (fr
12
12
 
13
13
  ## Your Responsibilities
14
14
 
15
- 1. **Consolidate the Why** turn the enriched `## Context` and `### Decisions` into one spec
16
- 2. **Follow the template** produce `spec.md` with Problem, Goals, Non-Goals, Approach, Decisions, Acceptance Criteria
17
- 3. **Stamp the tier** write a `Tier: S|M|L` line as the TOP line of spec.md, above the `#
15
+ 1. **Consolidate the Why**: turn the enriched `## Context` and `### Decisions` into one spec
16
+ 2. **Follow the template**: produce `spec.md` with all 8 sections in template order: Problem, Goals,
17
+ Non-Goals, Approach, Alternatives Considered, Decisions, Acceptance Criteria, Open Questions.
18
+ The shared fill method for each section is `skills/intent-speccing/references/per-section-fill-rules.md`;
19
+ read it when filling the template, it is the single owner of the method, do not fork it here.
20
+ 3. **Stamp the tier**: write a `Tier: S|M|L` line as the TOP line of spec.md, above the `#
18
21
  Spec:` heading, taking the value from the orchestrator's sizing / the brainstorming
19
22
  recommendation. This line is convention-only: read by the orchestrator, never validated by
20
23
  any gate or by doctor. It is an extra top line, not a template field, so no template changes.
21
- 4. **Accept collapsed sections at S/M** a spec.md whose Problem, Goals, Non-Goals, Approach,
24
+ 4. **Accept collapsed sections at S/M**: a spec.md whose Problem, Goals, Non-Goals, Approach,
22
25
  Decisions, or Acceptance Criteria sections are a single line each is still a complete
23
26
  spec.md under the same-structure invariant; do not pad it. The gates check file existence
24
27
  and realness, not artifact depth, so a collapsed-but-real spec passes.
25
- 5. **Make it the contract** the spec is what the planner and executor build against
26
- 6. **Hand off** leave a complete `spec.md` ready for the planner
28
+ 5. **Make it the contract**: the spec is what the planner and executor build against
29
+ 6. **Hand off**: leave a complete `spec.md` ready for the planner
27
30
 
28
31
  ## How You Work
29
32
 
package/bin/plastic.js CHANGED
@@ -6,7 +6,7 @@
6
6
  // npx @zalom/plastic install [flags]
7
7
  // npx @zalom/plastic update [flags]
8
8
  // npx @zalom/plastic uninstall [flags]
9
- // npx @zalom/plastic versions [flags]
9
+ // npx @zalom/plastic rollback [flags]
10
10
  //
11
11
  // Back-compat: a bare `--uninstall` (no subcommand) routes to uninstall with a deprecation
12
12
  // warning; no subcommand at all defaults to install (legacy behaviour, one release).
@@ -15,7 +15,7 @@ import { execFileSync } from 'node:child_process'
15
15
  import { resolve } from 'node:path'
16
16
  import { existsSync } from 'node:fs'
17
17
 
18
- const VERBS = ['install', 'update', 'uninstall', 'versions']
18
+ const VERBS = ['install', 'update', 'uninstall', 'rollback']
19
19
  const packageRoot = new URL('..', import.meta.url).pathname
20
20
  const argv = process.argv.slice(2)
21
21
 
@@ -5,7 +5,7 @@
5
5
  # upgrade target instead of blindly trusting the `latest` tag.
6
6
 
7
7
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
- PLASTIC_HOME="$HOME/.plastic"
8
+ PLASTIC_HOME="${PLASTIC_HOME:-$HOME/.plastic}"
9
9
  CACHE_DIR="$PLASTIC_HOME/.cache"
10
10
  CACHE_FILE="$CACHE_DIR/update-check.json"
11
11
  VERSION_FILE="$PLASTIC_HOME/VERSION"
package/hooks/continue CHANGED
@@ -23,7 +23,7 @@ if echo "$MESSAGE" | grep -iq '\bcontinue\b'; then
23
23
  {
24
24
  "hookSpecificOutput": {
25
25
  "hookEventName": "UserPromptSubmit",
26
- "additionalContext": "PLASTIC CONTINUE The user wants to resume previous work.\n\nRead ~/.plastic/INDEX.md and follow the continuing skill workflow."
26
+ "additionalContext": "PLASTIC CONTINUE: The user wants to resume previous work.\n\nRead ~/.plastic/INDEX.md and follow the plastic-continuing skill workflow."
27
27
  }
28
28
  }
29
29
  HOOKJSON
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalom/plastic",
3
- "version": "1.0.3",
3
+ "version": "1.1.1",
4
4
  "description": "Intent-driven idea development system for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@ def today
33
33
  end
34
34
 
35
35
  # A generic "about a month" threshold, not tuned to any one store's item count.
36
- # Deliberately independent from plastic-continuing's separate stale_threshold_days
36
+ # Deliberately independent from plastic-project-continuing's separate stale_threshold_days
37
37
  # config: that one is a proactive boot-time triage nudge, this is a board annotation.
38
38
  # Unifying the two is a follow-up, not this intent.
39
39
  STALE_DAYS = 30
@@ -355,10 +355,7 @@ LIFECYCLE_GLYPH = { "what" => "○", "why" => "◔", "how" => "◑", "exec" => "
355
355
  DISPOSITION_GLYPH = { "drive" => "▸", "defer" => "⇢", "research" => "⊙", "triage" => "⚑" }.freeze
356
356
  LEGEND = "legend ○ What ◔ Why ◑ How ◕ Exec ● Done │ ▸drive ⇢defer ⊙research ⚑triage │ ⇡unblocked"
357
357
 
358
- # Markdown board glyphs (intent 37). Quadrant signatures + per-line bullets.
359
- QUADRANT_BULLET = {
360
- "quick_win" => "⚡", "next_big" => "★", "defer" => "→", "triage" => "⚑",
361
- }.freeze
358
+ # Markdown board glyphs (intent 37). Status signature for the project active/future lists.
362
359
  STATUS_GLYPH = { "active" => "◑", "completed" => "●", "future" => "○" }.freeze
363
360
 
364
361
  # ---------------------------------------------------------------------------
@@ -375,10 +372,10 @@ end
375
372
  CELL_CAP = 6
376
373
 
377
374
  # Markdown-board caps (Task 5, D6/D7): the ASCII renderer already caps via CELL_CAP/
378
- # cap_cell, but the Markdown board's matrix_data quadrants and the project board's
375
+ # cap_cell, but the Markdown board's next_work list and the project board's
379
376
  # active/future lists had no cap and no per-line truncation, so a large store printed
380
377
  # hundreds of full-length lines. These two constants fix that on the Markdown side only.
381
- MATRIX_DATA_CAP = 8
378
+ NEXT_WORK_CAP = 8
382
379
  INTENT_LINE_MAX_CHARS = 120
383
380
 
384
381
  def matrix(records, scope_tag: false)
@@ -584,31 +581,39 @@ def intent_line(rec, bullet)
584
581
  scope: rec[:scope], line: "#{bullet} #{rec[:id]} #{text}#{note}".rstrip }
585
582
  end
586
583
 
587
- # Cap a raw record list to MATRIX_DATA_CAP entries, then map to intent_line-shaped
584
+ # Cap a raw record list to NEXT_WORK_CAP entries, then map to intent_line-shaped
588
585
  # hashes, appending a plain "+N more" line (no id, not a real record) when truncated.
589
586
  # Caps the record list first so the "+N more" entry never goes through intent_line.
590
587
  def cap_lines(list, bullet)
591
- capped = list.first(MATRIX_DATA_CAP)
588
+ capped = list.first(NEXT_WORK_CAP)
592
589
  lines = capped.map { |r| intent_line(r, bullet) }
593
- if list.size > MATRIX_DATA_CAP
590
+ if list.size > NEXT_WORK_CAP
594
591
  lines << { id: "", intent: "", created: "", bullet: bullet, scope: "",
595
- line: "#{bullet} +#{list.size - MATRIX_DATA_CAP} more" }
592
+ line: "#{bullet} +#{list.size - NEXT_WORK_CAP} more" }
596
593
  end
597
594
  lines
598
595
  end
599
596
 
600
- def matrix_data(records)
601
- cells = { "quick_win" => [], "next_big" => [], "defer" => [], "triage" => [] }
602
- research = []
603
- records.each do |r|
604
- if %w[research exploration].include?(r[:type]) then research << r
605
- else cells[r[:quadrant]] << r end
597
+ # Flat, rank-ordered "most-valuable next work" list (intent 149). Replaces the
598
+ # quadrant-keyed matrix_data with a single list ranked by the same rank_key every
599
+ # other ordering uses, capped at NEXT_WORK_CAP with a trailing "+N more" marker
600
+ # when the pool overflows. No grid glyph on the line; the prose surface supplies
601
+ # its own bullet.
602
+ def next_work(records)
603
+ ranked = records.sort_by { |r| rank_key(r) }
604
+ capped = ranked.first(NEXT_WORK_CAP)
605
+ lines = capped.map do |r|
606
+ text = r[:intent].to_s
607
+ text = "#{text[0, INTENT_LINE_MAX_CHARS]}…" if text.length > INTENT_LINE_MAX_CHARS
608
+ { id: r[:id], intent: r[:intent], scope: r[:scope], lifecycle: r[:lifecycle],
609
+ value: r[:value].to_s, disposition: r[:disposition], flags: r[:flags],
610
+ line: "#{r[:id]} #{text}" }
606
611
  end
607
- by_created_desc = ->(list) { list.sort_by { |r| invert_ts(r[:created]) } }
608
- out = {}
609
- cells.each { |q, list| out[q] = cap_lines(by_created_desc.call(list), QUADRANT_BULLET[q]) }
610
- out["research"] = cap_lines(by_created_desc.call(research), "🔬")
611
- out
612
+ if ranked.size > NEXT_WORK_CAP
613
+ lines << { id: "", intent: "", scope: "", lifecycle: "", value: "", disposition: "",
614
+ flags: [], line: "+#{ranked.size - NEXT_WORK_CAP} more" }
615
+ end
616
+ lines
612
617
  end
613
618
 
614
619
  def short_description(scope)
@@ -654,7 +659,7 @@ def render_data_global(records)
654
659
  { mode: "global", date: today.to_s,
655
660
  store_health: store_health(:global),
656
661
  recently_worked: recently_worked(records),
657
- matrix: matrix_data(matrix_pool),
662
+ next_work: next_work(matrix_pool),
658
663
  counts: counts_of(global),
659
664
  projects: projs,
660
665
  project_totals: {
@@ -671,7 +676,7 @@ def render_data_project(records, slug)
671
676
  store_health: store_health(slug),
672
677
  description: short_description(scope),
673
678
  recently_worked: recently_worked(records, project_scope: scope),
674
- matrix: matrix_data(matrix_pool),
679
+ next_work: next_work(matrix_pool),
675
680
  counts: counts_of(scoped),
676
681
  active: cap_lines(scoped.select { |r| r[:status] == "active" }
677
682
  .sort_by { |r| invert_ts(r[:last_accessed_at]) }, STATUS_GLYPH["active"]),