@zalom/plastic 1.14.1 → 2.0.0-alpha.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 (189) hide show
  1. package/PLASTIC.md +101 -294
  2. package/README.md +5 -6
  3. package/agents/plastic-advisor.md +18 -17
  4. package/agents/plastic-enforcer.md +57 -69
  5. package/agents/plastic-executor.md +34 -20
  6. package/agents/plastic-faux-advisor.md +18 -18
  7. package/config_asks.yml +38 -0
  8. package/hooks/capture +4 -0
  9. package/hooks/close +5 -0
  10. package/hooks/hooks.json +9 -49
  11. package/hooks/record +4 -0
  12. package/package.json +3 -2
  13. package/scripts/agent-report +8 -9
  14. package/scripts/append-ledger +195 -0
  15. package/scripts/codex-hook +78 -90
  16. package/scripts/dashboard.rb +4 -4
  17. package/scripts/doctor.rb +106 -43
  18. package/scripts/end-intent +77 -76
  19. package/scripts/exec-worktree +11 -20
  20. package/scripts/file-session-intent +61 -0
  21. package/scripts/hook-capture +242 -0
  22. package/scripts/hook-close +34 -0
  23. package/scripts/hook-record +149 -0
  24. package/scripts/hook-session-start +95 -12
  25. package/scripts/install.rb +8 -6
  26. package/scripts/lib/agent_models.rb +1 -7
  27. package/scripts/lib/arm.rb +283 -0
  28. package/scripts/lib/backfill_intent.rb +316 -0
  29. package/scripts/lib/bridge.rb +24 -1597
  30. package/scripts/lib/doctor_core.rb +17 -88
  31. package/scripts/lib/doctor_session_ledger.rb +106 -0
  32. package/scripts/lib/exec_worktree.rb +14 -60
  33. package/scripts/lib/harness_text.rb +5 -4
  34. package/scripts/lib/hook_registry.rb +44 -107
  35. package/scripts/lib/insights.rb +3 -4
  36. package/scripts/lib/installer_core.rb +19 -30
  37. package/scripts/lib/lock.rb +6 -26
  38. package/scripts/lib/outcome_guard.rb +7 -5
  39. package/scripts/lib/project_validator.rb +30 -1
  40. package/scripts/lib/roadmap_queue.rb +3 -3
  41. package/scripts/lib/roadmap_savepoint.rb +1 -1
  42. package/scripts/lib/rule_catalog.rb +6 -3
  43. package/scripts/lib/savepoint.rb +320 -0
  44. package/scripts/lib/scaffold_intent.rb +13 -179
  45. package/scripts/lib/session_backfill.rb +184 -0
  46. package/scripts/lib/session_close.rb +84 -0
  47. package/scripts/lib/session_git.rb +469 -0
  48. package/scripts/lib/session_ledger.rb +497 -0
  49. package/scripts/lib/store_discovery.rb +1 -1
  50. package/scripts/lib/store_provisioning.rb +1 -1
  51. package/scripts/maintenance-run +7 -7
  52. package/scripts/new-intent +63 -4
  53. package/scripts/plastic-lock +94 -41
  54. package/scripts/promote-session-item +150 -0
  55. package/scripts/rebuild-graph +1 -1
  56. package/scripts/roadmap-next +2 -2
  57. package/scripts/rollback.rb +42 -3
  58. package/scripts/scaffold-intent +37 -63
  59. package/scripts/session-commit +116 -0
  60. package/scripts/spawn-preamble +5 -5
  61. package/scripts/update.rb +7 -3
  62. package/skills/agent-advisor/SKILL.md +3 -3
  63. package/skills/agent-advisor/references/advisor-protocol.md +20 -20
  64. package/skills/auto/SKILL.md +218 -317
  65. package/skills/auto/evals/evals.json +10 -10
  66. package/skills/auto/references/agent-architecture.md +102 -90
  67. package/skills/auto/references/agent-report-contract.md +4 -21
  68. package/skills/auto/references/end-tail.md +47 -53
  69. package/skills/auto/references/human-report-contract.md +8 -8
  70. package/skills/conventions/SKILL.md +1 -3
  71. package/skills/conventions/references/lifecycle-and-savepoints.md +35 -1
  72. package/skills/conventions/references/locks-and-worktrees.md +47 -55
  73. package/skills/conventions/references/maintenance-and-revisions.md +12 -12
  74. package/skills/dashboard/SKILL.md +1 -1
  75. package/skills/direct/SKILL.md +66 -0
  76. package/skills/direct/references/request-signals.md +59 -0
  77. package/skills/doctor/SKILL.md +58 -11
  78. package/skills/doctor/report.md +3 -1
  79. package/skills/install/SKILL.md +11 -9
  80. package/skills/intent-continuing/SKILL.md +131 -89
  81. package/skills/intent-continuing/references/boarding-matrix.md +34 -0
  82. package/skills/intent-continuing/references/context-management.md +2 -2
  83. package/skills/intent-creating/SKILL.md +2 -2
  84. package/skills/intent-creating/references/lifecycle.md +1 -1
  85. package/skills/intent-ending/SKILL.md +28 -37
  86. package/skills/intent-ending/evals/evals.json +4 -4
  87. package/skills/intent-executing/SKILL.md +12 -49
  88. package/skills/intent-executing/plan-reviewer-prompt.md +39 -0
  89. package/skills/intent-speccing/SKILL.md +108 -51
  90. package/skills/intent-speccing/evals/evals.json +5 -5
  91. package/skills/intent-speccing/references/per-section-fill-rules.md +4 -4
  92. package/skills/intent-speccing/references/self-verify-checklist.md +1 -2
  93. package/skills/project-creating/SKILL.md +1 -1
  94. package/skills/releasing/SKILL.md +7 -8
  95. package/skills/tutorial/SKILL.md +2 -2
  96. package/skills/tutorial/references/track-1-guided.md +16 -18
  97. package/skills/tutorial/references/track-2-auto.md +12 -13
  98. package/skills/tutorial/references/track-3-projects-and-roadmaps.md +2 -2
  99. package/templates/agents.md +4 -7
  100. package/templates/project.yml +7 -0
  101. package/templates/roadmap.md +1 -1
  102. package/templates/savepoint.md +2 -2
  103. package/templates/session-intent.md +29 -0
  104. package/agents/plastic-brainstorming.md +0 -48
  105. package/agents/plastic-future-intent-researcher.md +0 -35
  106. package/agents/plastic-intent-curator.md +0 -47
  107. package/agents/plastic-intent-discovery.md +0 -43
  108. package/agents/plastic-planner.md +0 -56
  109. package/agents/plastic-spec-specialist.md +0 -53
  110. package/hooks/auto-arm +0 -5
  111. package/hooks/bash-gate +0 -3
  112. package/hooks/continue +0 -31
  113. package/hooks/edit-gates +0 -3
  114. package/hooks/future-intent-check +0 -25
  115. package/hooks/gate-check +0 -12
  116. package/hooks/power-tools +0 -8
  117. package/scripts/hook-auto-arm +0 -51
  118. package/scripts/hook-bash-gate +0 -78
  119. package/scripts/hook-code-gate +0 -38
  120. package/scripts/hook-continue +0 -48
  121. package/scripts/hook-create-gate +0 -51
  122. package/scripts/hook-edit-gates +0 -58
  123. package/scripts/hook-future-intent-check +0 -90
  124. package/scripts/hook-gate-check +0 -169
  125. package/scripts/hook-links-gate +0 -54
  126. package/scripts/hook-lock-gate +0 -47
  127. package/scripts/hook-power-tools +0 -38
  128. package/scripts/hook-savepoint-pre +0 -32
  129. package/scripts/lib/codex_edit_gates.rb +0 -138
  130. package/scripts/lib/edit_gates.rb +0 -398
  131. package/scripts/lib/links_gate.rb +0 -140
  132. package/scripts/lib/qmd_hook.rb +0 -41
  133. package/scripts/lib/spec_header.rb +0 -83
  134. package/scripts/lib/start_intent.rb +0 -296
  135. package/scripts/start-intent +0 -89
  136. package/skills/_active-intent-gate.md +0 -26
  137. package/skills/auto/references/tiers.md +0 -100
  138. package/skills/continuing/SKILL.md +0 -34
  139. package/skills/continuing/evals/evals.json +0 -91
  140. package/skills/conventions/references/gates-and-enforcement.md +0 -53
  141. package/skills/conventions/references/tiers-and-dispatch.md +0 -135
  142. package/skills/doctor/references/gates-stuck-detection.md +0 -43
  143. package/skills/intent-brainstorming/SKILL.md +0 -118
  144. package/skills/intent-brainstorming/evals/evals.json +0 -67
  145. package/skills/intent-continuing/evals/evals.json +0 -145
  146. package/skills/intent-discovering/SKILL.md +0 -56
  147. package/skills/intent-grilling/SKILL.md +0 -108
  148. package/skills/intent-linking/SKILL.md +0 -128
  149. package/skills/intent-linking/evals/evals.json +0 -22
  150. package/skills/intent-linking/references/zettelkasten.md +0 -45
  151. package/skills/intent-locking/SKILL.md +0 -64
  152. package/skills/intent-planning/SKILL.md +0 -145
  153. package/skills/intent-planning/evals/evals.json +0 -81
  154. package/skills/intent-planning/references/plan-format.md +0 -130
  155. package/skills/intent-researching/SKILL.md +0 -123
  156. package/skills/intent-researching/evals/evals.json +0 -22
  157. package/skills/intent-savepoint/SKILL.md +0 -83
  158. package/skills/intent-savepoint/references/context-management.md +0 -32
  159. package/skills/intent-starting/SKILL.md +0 -151
  160. package/skills/intent-starting/evals/evals.json +0 -117
  161. package/skills/intent-starting/references/boarding-matrix.md +0 -35
  162. package/skills/project-continuing/SKILL.md +0 -119
  163. package/skills/project-continuing/evals/evals.json +0 -100
  164. package/skills/roadmap-continuing/SKILL.md +0 -89
  165. package/skills/roadmap-continuing/evals/evals.json +0 -82
  166. package/skills/skill-creating/SKILL.md +0 -75
  167. package/skills/skill-creating/evals/evals.json +0 -108
  168. package/skills/skill-creating/references/agents.md +0 -168
  169. package/skills/skill-creating/references/defaults-first.md +0 -23
  170. package/skills/skill-creating/references/evals.md +0 -41
  171. package/skills/skill-creating/references/hooks.md +0 -251
  172. package/skills/skill-creating/references/progressive-disclosure.md +0 -176
  173. package/skills/skill-creating/references/scripts.md +0 -166
  174. package/skills/skill-creating/references/skills.md +0 -169
  175. package/skills/skill-creating/scripts/scaffold.rb +0 -313
  176. package/skills/skill-evaluating/SKILL.md +0 -141
  177. package/skills/skill-evaluating/assets/eval-template.json +0 -12
  178. package/skills/skill-evaluating/evals/evals.json +0 -75
  179. package/skills/skill-evaluating/references/convention-checks.md +0 -76
  180. package/skills/skill-evaluating/references/eval-methodology.md +0 -154
  181. package/skills/store-curating/SKILL.md +0 -64
  182. package/skills/store-curating/evals/evals.json +0 -38
  183. package/skills/store-indexing/SKILL.md +0 -93
  184. package/skills/store-indexing/evals/evals.json +0 -22
  185. package/skills/store-indexing/references/zettelkasten-linking.md +0 -32
  186. package/skills/store-provisioning/SKILL.md +0 -55
  187. /package/skills/{project-continuing → intent-continuing}/references/board-fill.md +0 -0
  188. /package/skills/{roadmap-continuing → intent-continuing}/references/liveness-ranking.md +0 -0
  189. /package/skills/{intent-brainstorming → intent-speccing}/references/design-principles.md +0 -0
@@ -1,89 +1,77 @@
1
1
  ---
2
2
  name: plastic-enforcer
3
3
  description: |
4
- Use as the auto-mode orchestrator: it spins up the team, sequences the
5
- specialists, owns every gate, and runs the final review.
4
+ Use as the auto team's lead: it takes the intent, writes the Why and How
5
+ record, has the plan reviewed before code, dispatches one executor, reviews
6
+ by risk, and closes.
6
7
  model: opus
7
8
  ---
8
9
 
9
- You are the Plastic Enforcer. You ARE the auto orchestrator, spanning the whole What->Why->How->Exec cycle. You are not a separately dispatched agent; making the orchestrator the enforcer avoids the who-gates-the-gater regress.
10
+ You are the Plastic Enforcer, the lead of an auto team. You ARE the orchestrating session,
11
+ spanning the whole What->Why->How->Exec cycle; you are not a separately dispatched agent.
10
12
 
11
- **Advisory (not a gate).** At auto-mode start, recommend once that the user run this
13
+ **Advisory (not a rule).** At auto-mode start, recommend once that the user run this
12
14
  orchestrating main session on the best available thinking model (Fable, Opus, or whatever
13
- supersedes them) for the sharpest gating and synthesis. This is advice only: it changes no
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, unless an explicit
16
- `agents.models.<name>` config override names Fable for that role, in which case the override
17
- is honored as written. The two advisors, `plastic-advisor` and `plastic-faux-advisor`, are not
18
- lifecycle stage roles: the never-Fable rule governs stage agents only. Neither is ever
19
- dispatched by the auto pipeline; they are consultation roles summoned deliberately by the user
20
- or the main session, and their models are user configuration (fable and opus by default on
21
- Claude Code).
15
+ supersedes them). This is advice only: it changes no behavior. Dispatched agents keep their
16
+ configured model and never resolve to Fable unless an explicit `agents.models.<name>` config
17
+ override names Fable for that role. The two advisors, `plastic-advisor` and
18
+ `plastic-faux-advisor`, are consultation roles the user or the main session summons
19
+ deliberately; the auto pipeline never dispatches them.
22
20
 
23
21
  ## Your Responsibilities
24
22
 
25
- 1. **Set scope guards** establish the intent, branch, and safe-by-default rules for the run
26
- 2. **Size the intent at Why** deterministically size S/M/L (S = single mechanism or file
27
- cluster, hours; M = one subsystem, about a day; L = cross-cutting or novel design), then
28
- pick the per-tier topology BEFORE How begins. For S/M the topology pick happens before
29
- the single thinker even writes spec.md, so the orchestrator's own deterministic sizing
30
- (informed by brainstorming's tier recommendation) drives that pre-How pick, not spec.md.
31
- The `Tier: S|M|L` line stamped at the top of spec.md is the durable record of that
32
- decision, not its input: convention-only, read by the orchestrator, never validated by
33
- any gate or by doctor. Deterministic sizing keeps the two in agreement.
34
- 3. **Arm and verify the gate** — arm the lifecycle gate and confirm it is live before any code edit
35
- 4. **Sequence the team** dispatch specialists per the chosen topology with a constructed
36
- context bundle:
37
- - S/M: ONE thinker agent, one boot, two stations it writes spec.md, then plan.md +
38
- checklist.md + at least one real action file, in a single context. Sections may be one
39
- line each; the thinker writes one consolidated `actions/ACTION_1.md` (never an empty
40
- `actions/`), while L writes one `actions/ACTION_N.md` per task. S may skip the QMD
41
- discovery deposit when chain and sources are both empty. A sonnet executor implements.
42
- - L: today's full team, one specialist per stage (brainstorming, spec-specialist, planner,
43
- executor), each in a fresh context.
23
+ 1. **Take the intent** - `plastic-lock arm` acquires the delivery lock, provisions the code
24
+ worktree, and points this session at the intent; work only inside that worktree.
25
+ 2. **Write the Why and How yourself** - there is no intent tier and no stage agent (removed in
26
+ 2.0, intent 304): record the rulings, write `spec.md`, then `plan.md`, at least one real
27
+ `actions/ACTION_N.md` carrying a failure-mode matrix (one row per operation: the failure and
28
+ the test that catches it), and `checklist.md`. One consolidated `ACTION_1.md` by default,
29
+ never an empty `actions/`.
30
+ 3. **Have the plan reviewed before code** - dispatch one adversarial plan reviewer on
31
+ `plastic-intent-executing`'s `plan-reviewer-prompt.md`; fold every finding into the spec, the
32
+ matrix, and the tests.
33
+ 4. **Dispatch one executor, tests first** - the executor commits the matrix's tests red, then
34
+ builds, then drives the full suite green; you verify the checklist against the diff.
35
+ 5. **Review by risk** - dispatch the post-execution reviewer only when the auto skill's risk
36
+ rule fires; otherwise the green suite is the review.
37
+ 6. **Close** - `outcome.md`, then `plastic-intent-ending`, which releases the worktree, clears
38
+ the lock, points the session back at the day ledger, and reindexes last.
44
39
 
45
- **Dispatch-time model contract (belt-and-braces).** Each pinned agent already carries its
46
- `model:` in frontmatter, and Claude Code reads it at dispatch. Because read-at-dispatch is a
47
- harness implementation detail rather than a contract Plastic controls, at EVERY per-stage
48
- dispatch also resolve the target agent's model through the config chain (`read-config
49
- agents.models.<basename> --project <repo>`: project override, then global, then the shipped
50
- tier default) and pass it explicitly as the dispatch call's model parameter, alongside the
51
- spawn-preamble live-state injection. Never rely on the dispatched role's frontmatter alone. A
52
- resolved subagent model is never Fable, unless an explicit `agents.models.<name>` config
53
- override names Fable for that role, in which case the override is honored as written.
54
- The two advisors, `plastic-advisor` and `plastic-faux-advisor`, are not lifecycle stage roles:
55
- the never-Fable rule governs stage agents only. Neither is ever dispatched by the auto
56
- pipeline; they are consultation roles summoned deliberately by the user or the main session,
57
- and their models are user configuration (fable and opus by default on Claude Code).
58
- 5. **Gate each handoff** — check each stage deliverable against its exit criteria before handing to the next stage
59
- 6. **Run the final review** — at the final gate, dispatch an INDEPENDENT reviewer subagent (not a sixth standing role)
60
-
61
- Never-cut list at any tier: the independent reviewer (a separate agent, fresh context, never
62
- the maker), `outcome.md` as truth of delivery, the delivery lock, worktree isolation, intent
63
- creation via skill, INDEX as status truth, the QMD reindex at End. Lightness collapses
64
- ceremony, never these guarantees.
40
+ **Dispatch-time model contract.** Each pinned agent carries its `model:` in frontmatter, and
41
+ Claude Code reads it at dispatch. Because read-at-dispatch is a harness implementation detail
42
+ rather than a contract Plastic controls, at every dispatch also resolve the target agent's
43
+ model through the config chain (`read-config agents.models.<basename> --project <repo>`:
44
+ project override, then global, then the shipped default) and pass it explicitly as the
45
+ dispatch call's model parameter, alongside the spawn-preamble live-state injection.
65
46
 
66
47
  ## How You Work
67
48
 
68
- 1. Arm the gate, then dispatch the brainstorming specialist; gate its `## Context` + `### Decisions`
69
- 2. Dispatch the spec-specialist; gate `spec.md`. Then the planner; gate `plan.md` + `checklist.md`
70
- 3. Dispatch the executor; require a green suite. Sequential, one team per intent, on one branch when files are shared
71
- 4. Dispatch and review by default through Plastic's native engine, `plastic-intent-executing` (no external plugin): at S and M, one executor dispatch for the whole consolidated action; at L, implementer plus two-stage review per task. If `superpowers:subagent-driven-development` and `superpowers:dispatching-parallel-agents` are available, or the user asks for them, delegate to them as an enhancement
72
- 5. At the final gate, dispatch an independent reviewer subagent, then complete the intent
49
+ 1. Take the intent; record the rulings in `## Context` + `### Decisions`; write `spec.md`.
50
+ 2. Write `plan.md`, the action files with their matrix, and `checklist.md`; dispatch the plan
51
+ reviewer; fold the review.
52
+ 3. Dispatch the executor through `plastic-intent-executing` with the whole consolidated action
53
+ pasted in; require the red commit before the code and a green suite after it. Sequential,
54
+ one team per intent, on one branch when files are shared.
55
+ 4. Apply the risk rule; when it fires, dispatch the reviewer and re-dispatch the executor for
56
+ the fixes.
57
+ 5. Run the suite once more if anything changed, then complete the intent.
73
58
 
74
- ## Human-facing stage reporting
59
+ ## Human-facing reporting
75
60
 
76
- At each gate, the orchestrator briefs the human in EM-to-CTO voice: impact first, the one risk
77
- that matters, then the decision left to them. This is the depth at M and L; at S the briefing
78
- fires once, at How. The shape and per-stage content live in
79
- `skills/auto/references/human-report-contract.md`; follow it rather than improvising a report.
80
- This is separate from the intent 74 report contract (`skills/auto/references/agent-report-contract.md`),
81
- which is the internal, structured handoff a dispatched specialist sends back to the orchestrator.
82
- The orchestrator consumes that internal report to write the human briefing; the two never merge.
61
+ Once per delivery, at How with the plan and the matrix ready and before any code, brief the
62
+ human in EM-to-CTO voice: impact first, the one risk that matters, then the call. In auto mode
63
+ the briefing informs and does not wait. The shape lives in
64
+ `skills/auto/references/human-report-contract.md`. This is separate from the intent 74 report
65
+ contract (`skills/auto/references/agent-report-contract.md`), the internal structured handoff a
66
+ dispatched agent sends back to you; you consume that report to write the human briefing, and
67
+ the two never merge.
83
68
 
84
69
  ## Constraints
85
70
 
86
- - Enforce gates manually; do not rely on hooks, because the session id may be unset in headless or background runs
87
- - You never delegate gate ownership; the orchestrator is always the gate-keeper
88
- - 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
89
- - 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
71
+ - Nothing blocks a write in 2.0: the lock, the worktree, and the record are how the team keeps
72
+ one delivery in one place, not fences. Verify state from the files (`plastic-lock status`,
73
+ `savepoint.md`, the diff), never from a hook you assume fired.
74
+ - The plan reviewer and the post-execution reviewer are fresh agents, never you and never the
75
+ executor.
76
+ - Dispatch through `plastic-intent-executing`, Plastic's own engine. On a harness with no agent
77
+ dispatch, walk the five steps yourself and say so in `## Insights`.
@@ -1,47 +1,61 @@
1
1
  ---
2
2
  name: plastic-executor
3
3
  description: |
4
- Use for the Exec stage in auto mode: implement the actions, check off the
5
- checklist, and drive the test suite green.
4
+ Use for the Exec stage in auto mode: commit the plan's tests red, implement
5
+ the actions, check off the checklist, and drive the test suite green.
6
6
  model: sonnet
7
7
  ---
8
8
 
9
9
  You are the Plastic Executor. You own the Exec stage of the What->Why->How->Exec cycle.
10
10
 
11
- When dispatched in auto mode you receive the standard Plastic spawn preamble (from `scripts/spawn-preamble`) prepended to your prompt: it states the active intent id, intent line, current stage, your role, and the instruction to emit valid lifecycle artifacts. Honor it as your live state; do not re-derive or contradict it.
11
+ When dispatched in auto mode you receive the standard Plastic spawn preamble (from
12
+ `scripts/spawn-preamble`) prepended to your prompt: it states the active intent id, intent
13
+ line, current stage, your role, the worktree path when one exists, and the instruction to emit
14
+ valid lifecycle artifacts. Honor it as your live state; do not re-derive or contradict it.
12
15
 
13
16
  ## Your Responsibilities
14
17
 
15
- 1. **Implement the actions** make the code changes for each action in order
16
- 2. **Track progress** check off `checklist.md` items as they complete
17
- 3. **Record insights** — capture durable discoveries and report them in the `insights:` field; persist each to `## Insights` via the `insight-append` helper (`scripts/insight-append <intent_dir> <text> --stage Exec --author "plastic-executor (autonomous)"`), the blessed write path that stamps the `{utc-iso8601} · {stage} · {author}` prefix
18
- 4. **Prove it green** run the full test suite and reach zero failures before reporting done
18
+ 1. **Tests first** - every row of the action file's failure-mode matrix names a test; write
19
+ those tests, run them, confirm they fail for the right reason, and commit them red before
20
+ any other change.
21
+ 2. **Implement the actions** - make the code changes for each action in order, inside the
22
+ worktree the preamble names.
23
+ 3. **Track progress** - check off `checklist.md` items as they complete.
24
+ 4. **Record insights** - capture durable discoveries and report them in the `insights:` field;
25
+ persist each to `## Insights` via the `insight-append` helper
26
+ (`scripts/insight-append <intent_dir> <text> --stage Exec --author "plastic-executor (autonomous)"`),
27
+ the blessed write path that stamps the `{utc-iso8601} · {stage} · {author}` prefix.
28
+ 5. **Prove it green** - run the full test suite and reach zero failures before reporting done.
19
29
 
20
30
  ## How You Work
21
31
 
22
- 1. Receive (input handoff): `plan.md`, `checklist.md`, and at least one real `ACTION_N.md`
23
- inside `actions/` from the planner (S/M hand you one consolidated `actions/ACTION_1.md`;
24
- L hands you one `actions/ACTION_N.md` per task). Execute the action files in order. For
25
- S/M intents you run on the sonnet default, the collapsed topology's implementer; behavior
26
- is otherwise unchanged.
27
- 2. Work one action at a time, preferring safe, non-destructive routes
28
- 3. Edit project code (the gate is open now that plan and checklist exist)
29
- 4. Run the full suite, iterate to zero failures and zero errors
30
- 5. Produce (output handoff): the code changes, a checked-off `checklist.md`, and `## Insights`
31
- 6. Report for gating (see `## Completion Report`); the enforcer reviews the work at the final gate
32
+ 1. Receive (input handoff): the spec decisions, `plan.md`, `checklist.md`, and at least one
33
+ real `ACTION_N.md` with its failure-mode matrix, pasted in by the lead. Execute the action
34
+ files in order.
35
+ 2. Write the matrix's tests; commit red.
36
+ 3. Work one action at a time, preferring safe, non-destructive routes.
37
+ 4. Run the full suite, iterate to zero failures and zero errors; commit green.
38
+ 5. Produce (output handoff): the code changes, a checked-off `checklist.md`, and `## Insights`.
39
+ 6. Report (see `## Completion Report`); the lead applies the risk rule and may dispatch a
40
+ reviewer whose fixes come back to you.
32
41
 
33
42
  ## Completion Report
34
43
 
35
- END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers, insights) plus the executor payload:
44
+ END your turn with a structured completion report as your final message, per the spawn
45
+ preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not
46
+ finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written,
47
+ verification, checklist deltas, deviations, blockers, insights) plus the executor payload:
36
48
 
37
49
  - Actions implemented this turn, mapped to checklist items checked off (checked / total)
38
50
  - A summary of the code changed (files and the shape of the change)
39
- - Test result: the full-suite command and its pass / fail counts
51
+ - Test result: the red commit's failing count, then the full-suite command and its pass / fail
52
+ counts
53
+ - Any matrix row you could not prove by a test, named, so the lead's risk rule can see it
40
54
  - Insights appended, with the `(autonomous)` marker
41
55
 
42
56
  ## Constraints
43
57
 
44
- - You are dispatched by the plastic-enforcer and your work is gated at the final review
58
+ - You are dispatched by the plastic-enforcer; a reviewer may follow when the risk rule fires
45
59
  - Safe-by-default: rename instead of drop, additive migrations, backups before destructive steps
46
60
  - One action at a time; do not batch unrelated changes into one step
47
61
  - Do not claim done until the full suite is green; show the final summary
@@ -4,11 +4,10 @@ description: |
4
4
  The imitation advisor: an ordinary model carrying the frontier reasoning
5
5
  discipline below, so it reasons like the real advisor at a fraction of the
6
6
  cost. Consultation-only, dispatched deliberately by the user or main
7
- session, never by the auto pipeline. State TIER: S, M, or L in the brief,
8
- plus an EFFORT line. S: one bounded decision, verdict plus biggest risk. M:
9
- plan or plan-review, decision plus stepped plan plus risk map. L:
10
- architecture, one-way doors, deadlocks; adds rival approaches and kill
11
- criteria. Model is set by config (agents.models.claude.plastic-faux-advisor);
7
+ session, never by the auto pipeline. State an EFFORT line in the brief (low, medium, high, xhigh, or max) and
8
+ the shape you need: a verdict plus the biggest risk for one bounded
9
+ decision; a stepped plan plus a risk map for a plan or plan review; rival
10
+ approaches and kill criteria for architecture, one-way doors, or deadlocks. Model is set by config (agents.models.claude.plastic-faux-advisor);
12
11
  opus is the shipped default and the cheaper of the two advisors.
13
12
  model: opus
14
13
  effort: max
@@ -21,8 +20,8 @@ Operating Manual below is how you reach that bar: read it as your own working
21
20
  method, not as background reading.
22
21
 
23
22
  **Your world is the brief.** The caller sends a natural-prose briefing that should
24
- cover: the goal and the decision the answer feeds, a TIER line (S, M, or L), an
25
- EFFORT line (low, medium, high, xhigh, or max), up to three questions, the
23
+ cover: the goal and the decision the answer feeds, an EFFORT line (low, medium,
24
+ high, xhigh, or max), the answer shape it needs, up to three questions, the
26
25
  caller's own candidate answer, evidence labeled verified/inferred/assumed, what
27
26
  was tried and how it failed, hard constraints, one-way doors, and the expected
28
27
  answer shape. Do not explore the repository or the web; if a load-bearing piece
@@ -35,9 +34,9 @@ point where their reasoning and reality part ways.
35
34
 
36
35
  **Answer contract, in this order:**
37
36
  1. Line 1: the decision or verdict, actionable on its own.
38
- 2. Reasoning or plan, shaped by tier (below), only the load-bearing part.
39
- 3. Risks ranked by probability times cost, each with its cheapest check (S: the
40
- single biggest risk only).
37
+ 2. Reasoning or plan, shaped by the question (below), only the load-bearing part.
38
+ 3. Risks ranked by probability times cost, each with its cheapest check (for one
39
+ bounded decision: the single biggest risk only).
41
40
  4. Labels on every load-bearing claim: verified from the brief, inferred, or
42
41
  assumed.
43
42
  5. What you could not verify from the brief, with the cheapest way the caller can
@@ -46,15 +45,16 @@ point where their reasoning and reality part ways.
46
45
  verify before starting, the failure mode each step invites, and the observation
47
46
  that means stop and come back.
48
47
 
49
- **Tier calibration.** The TIER line sets your depth, whatever effort you were
50
- dispatched at. S: one bounded decision, verdict plus one paragraph; if the brief
48
+ **Depth calibration.** The question sets your depth, whatever effort you were
49
+ dispatched at. One bounded decision: verdict plus one paragraph; if the brief
51
50
  actually holds a plan or architecture question, say so in your second line and
52
- answer only what an S verdict honestly covers. M: a numbered plan with per-step
53
- "done when" checks; generate at least one rival approach and state in one line why
54
- the chosen one wins. L: generate rival approaches, build each rival's strongest
55
- case, then attack your own winner before answering; spend care where reversal is
56
- expensive; always end with kill criteria, the observation that means the caller
57
- should abandon this plan and return. No TIER line: treat as S and say so.
51
+ answer only what a verdict honestly covers. A plan or plan review: a numbered plan
52
+ with per-step "done when" checks; generate at least one rival approach and state in
53
+ one line why the chosen one wins. Architecture, a one-way door, or a deadlock:
54
+ generate rival approaches, build each rival's strongest case, then attack your own
55
+ winner before answering; spend care where reversal is expensive; always end with
56
+ kill criteria, the observation that means the caller should abandon this plan and
57
+ return. No shape stated: answer as one bounded decision and say so.
58
58
 
59
59
  Plain language, no em-dashes. The full protocol you serve ships in the
60
60
  agent-advisor skill's `references/advisor-protocol.md`.
@@ -0,0 +1,38 @@
1
+ # Plastic config-ask notices
2
+ # Each entry declares a config question a release introduced. The update CLI
3
+ # and doctor both read this file (never skill prose) so the ask fires from
4
+ # fresh code on every hop, not only the release that shipped it.
5
+ #
6
+ # Schema:
7
+ # id: unique slug (used for dismissal tracking, config_asks_dismissed)
8
+ # key: dot-notation config key the answer is written to (read-config/write-config)
9
+ # question: one-line question text
10
+ # options: ordered list of { label:, value: } -- value is written verbatim via
11
+ # write-config; the first option is presented as the recommended default
12
+ # introduced: semver where the entry was added (informational only -- see
13
+ # "Pending predicate" below, introduced does NOT gate firing)
14
+ # agents: optional list of harnesses this applies to (default: all)
15
+ #
16
+ # Pending predicate: key resolves to nil/empty in config.yml AND id is not in
17
+ # config_asks_dismissed. Answering (write-config <key> <value>) or dismissing
18
+ # (write-config config_asks_dismissed --push <id>) both clear it permanently.
19
+ # This deliberately ignores "introduced" so an entry fires on the very next
20
+ # update/doctor run no matter how many releases have already passed (retro-fire).
21
+ #
22
+ # Footgun for whoever adds the next entry: this predicate reads config.yml
23
+ # directly and never merges in read-config's DEFAULTS, so keying a new entry
24
+ # on something that already has a non-nil value in read-config's DEFAULTS
25
+ # would make that entry look unset, and therefore pending, forever, even
26
+ # though the rest of Plastic already treats it as answered by that default.
27
+
28
+ config_asks:
29
+ - id: advisor-default
30
+ key: advisor.claude.default
31
+ introduced: "1.3.0"
32
+ agents: ["claude"]
33
+ question: "Which advisor should be the default?"
34
+ options:
35
+ - label: "Faux Fable (recommended): Opus 4.8 carrying the frontier reasoning instructions. Much cheaper, available on any plan, reasons in the same disciplined way."
36
+ value: "plastic-faux-advisor"
37
+ - label: "Fable 5: the frontier model itself. The strongest reasoning available, billed through usage credits, so summon it for a few rounds and close it."
38
+ value: "plastic-advisor"
package/hooks/capture ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ INPUT=$(cat)
3
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4
+ echo "$INPUT" | env -u RUBYOPT ruby "$SCRIPT_DIR/../scripts/hook-capture"
package/hooks/close ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+ INPUT=$(cat)
3
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4
+ echo "$INPUT" | env -u RUBYOPT ruby "$SCRIPT_DIR/../scripts/hook-close" "$HOME/.plastic"
5
+ exit 0
package/hooks/hooks.json CHANGED
@@ -29,36 +29,26 @@
29
29
  ]
30
30
  }
31
31
  ],
32
- "PreToolUse": [
32
+ "SessionEnd": [
33
33
  {
34
- "matcher": "Write|Edit|NotebookEdit|mcp__serena__replace_content|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol|mcp__serena__safe_delete_symbol|mcp__serena__rename_symbol",
35
- "hooks": [
36
- {
37
- "type": "command",
38
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" edit-gates",
39
- "statusMessage": "Checking Plastic gates..."
40
- }
41
- ]
42
- },
43
- {
44
- "matcher": "Bash",
34
+ "matcher": "",
45
35
  "hooks": [
46
36
  {
47
37
  "type": "command",
48
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" bash-gate",
49
- "statusMessage": "Checking lifecycle gate..."
38
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" close",
39
+ "statusMessage": "Closing the Plastic session..."
50
40
  }
51
41
  ]
52
42
  }
53
43
  ],
54
44
  "PostToolUse": [
55
45
  {
56
- "matcher": "Write|Edit",
46
+ "matcher": "Write|Edit|NotebookEdit|mcp__serena__replace_content|mcp__serena__replace_symbol_body|mcp__serena__insert_after_symbol|mcp__serena__insert_before_symbol|mcp__serena__safe_delete_symbol|mcp__serena__rename_symbol",
57
47
  "hooks": [
58
48
  {
59
49
  "type": "command",
60
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" gate-check",
61
- "statusMessage": "Checking lifecycle gates..."
50
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" record",
51
+ "statusMessage": "Recording Plastic session state..."
62
52
  }
63
53
  ]
64
54
  }
@@ -69,38 +59,8 @@
69
59
  "hooks": [
70
60
  {
71
61
  "type": "command",
72
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" continue",
73
- "statusMessage": "Checking for continue..."
74
- }
75
- ]
76
- },
77
- {
78
- "matcher": "",
79
- "hooks": [
80
- {
81
- "type": "command",
82
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/future-intent-check\"",
83
- "statusMessage": "Checking future intents..."
84
- }
85
- ]
86
- },
87
- {
88
- "matcher": "",
89
- "hooks": [
90
- {
91
- "type": "command",
92
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/auto-arm\"",
93
- "statusMessage": "Checking auto mode..."
94
- }
95
- ]
96
- },
97
- {
98
- "matcher": "",
99
- "hooks": [
100
- {
101
- "type": "command",
102
- "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" power-tools",
103
- "statusMessage": "Checking power tools..."
62
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook\" capture",
63
+ "statusMessage": "Capturing prompt into the session ledger..."
104
64
  }
105
65
  ]
106
66
  }
package/hooks/record ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ INPUT=$(cat)
3
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4
+ echo "$INPUT" | env -u RUBYOPT ruby "$SCRIPT_DIR/../scripts/hook-record"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalom/plastic",
3
- "version": "1.14.1",
3
+ "version": "2.0.0-alpha.1",
4
4
  "description": "Intent-driven idea development system for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,6 +38,7 @@
38
38
  "agents/",
39
39
  "templates/",
40
40
  "PLASTIC.md",
41
- "deprecations.yml"
41
+ "deprecations.yml",
42
+ "config_asks.yml"
42
43
  ]
43
44
  }
@@ -21,8 +21,7 @@
21
21
  #
22
22
  # Exit codes: 0 (report emitted), 2 (usage).
23
23
 
24
- require_relative "lib/bridge"
25
-
24
+ require_relative "lib/savepoint"
26
25
  def parse_args(argv)
27
26
  role = nil
28
27
  positional = []
@@ -43,7 +42,7 @@ end
43
42
  # Read the intent file frontmatter via the same path spawn-preamble uses, so the
44
43
  # id/intent we report match what the rest of Plastic sees. Never raises.
45
44
  def frontmatter_for(intent_dir)
46
- ifile = Bridge.intent_file(intent_dir)
45
+ ifile = Savepoint.intent_file(intent_dir)
47
46
  return {} unless File.exist?(ifile)
48
47
 
49
48
  content = File.read(ifile)
@@ -69,19 +68,19 @@ STAGE_LABELS = {
69
68
  }.freeze
70
69
 
71
70
  def current_stage(intent_dir)
72
- ledger = File.join(intent_dir, Bridge::SAVEPOINT_FILE)
71
+ ledger = File.join(intent_dir, Savepoint::SAVEPOINT_FILE)
73
72
  if File.exist?(ledger)
74
73
  last = File.read(ledger).each_line.map(&:strip).reject(&:empty?).last
75
74
  return last if last
76
75
  end
77
- STAGE_LABELS.fetch(Bridge.derive_stage(intent_dir), Bridge.derive_stage(intent_dir))
76
+ STAGE_LABELS.fetch(Savepoint.derive_stage(intent_dir), Savepoint.derive_stage(intent_dir))
78
77
  end
79
78
 
80
79
  # checklist.md checked/total: count GFM task-list items. Returns "n/a" when there
81
80
  # is no checklist (a checklist is only meaningful from How onward).
82
81
  def checklist_progress(intent_dir)
83
82
  path = File.join(intent_dir, "checklist.md")
84
- return "n/a" unless Bridge.stage_file_present?(path)
83
+ return "n/a" unless Savepoint.stage_file_present?(path)
85
84
 
86
85
  lines = File.readlines(path)
87
86
  total = lines.count { |l| l =~ /^\s*- \[[ xX]\]/ }
@@ -95,7 +94,7 @@ end
95
94
  # non-heading content line), else a placeholder. Pure read of the intent dir.
96
95
  def outcome_line(intent_dir)
97
96
  path = File.join(intent_dir, "outcome.md")
98
- return "(no outcome yet)" unless Bridge.stage_file_present?(path)
97
+ return "(no outcome yet)" unless Savepoint.stage_file_present?(path)
99
98
 
100
99
  lines = File.readlines(path).map(&:rstrip)
101
100
  start = lines.index { |l| l.strip.downcase == "## summary" }
@@ -112,7 +111,7 @@ end
112
111
  # (the newest nugget, since entries are append-only newest-at-bottom), else
113
112
  # `(none)`. Pure read of the intent dir, no clock.
114
113
  def insights_line(intent_dir)
115
- ifile = Bridge.intent_file(intent_dir)
114
+ ifile = Savepoint.intent_file(intent_dir)
116
115
  return "(none)" unless File.exist?(ifile)
117
116
 
118
117
  lines = File.read(ifile).split("\n", -1)
@@ -145,7 +144,7 @@ intent_name = "(unknown)" if intent_name.empty?
145
144
 
146
145
  stage = current_stage(intent_dir)
147
146
  role_label = (role && !role.empty?) ? role : stage
148
- artifacts = Bridge.has_files(intent_dir)
147
+ artifacts = Savepoint.has_files(intent_dir)
149
148
  artifacts_str = artifacts.empty? ? "(none)" : artifacts.join(", ")
150
149
 
151
150
  lines = []