@zalom/plastic 2.0.0-alpha.9 → 2.0.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 (326) hide show
  1. package/PLASTIC.md +13 -136
  2. package/README.md +357 -133
  3. package/agents/plastic-enforcer.md +21 -16
  4. package/agents/plastic-executor.md +15 -4
  5. package/agents/plastic-node-research.md +30 -0
  6. package/agents/plastic-node-verify.md +28 -0
  7. package/agents/plastic-node-work.md +33 -0
  8. package/agents/{plastic-advisor.md → plastic-primary-advisor.md} +7 -9
  9. package/agents/{plastic-faux-advisor.md → plastic-secondary-advisor.md} +9 -12
  10. package/assets/plastic-logo.svg +1 -0
  11. package/bin/crap +4 -0
  12. package/bin/lib/context_budget.rb +43 -6
  13. package/bin/lib/skill_census.rb +839 -0
  14. package/bin/plastic +8 -0
  15. package/bin/plastic-skill-census +114 -0
  16. package/bin/test +24 -4
  17. package/bin/verify-change +345 -0
  18. package/config_asks.yml +4 -4
  19. package/deprecations.yml +1 -1
  20. package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +19 -24
  21. package/{skills/auto/references → docs/help}/agent-architecture.md +16 -14
  22. package/docs/help/completion-and-done.md +53 -0
  23. package/docs/help/human-report-contract.md +152 -0
  24. package/{skills/conventions/references → docs/help}/knowledge-graph.md +9 -0
  25. package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +11 -13
  26. package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +1 -1
  27. package/{skills/conventions/references → docs/help}/roadmaps.md +5 -4
  28. package/{skills/tutorial/references → docs/help}/track-1-guided.md +28 -47
  29. package/{skills/tutorial/references → docs/help}/track-2-auto.md +8 -8
  30. package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
  31. package/hooks/call-budget +4 -0
  32. package/hooks/hooks.json +24 -0
  33. package/hooks/message-display +55 -2
  34. package/hooks/session-start +5 -1
  35. package/hooks/statusline +32 -27
  36. package/hooks/stop +5 -0
  37. package/package.json +5 -3
  38. package/scripts/append-ledger +2 -1
  39. package/scripts/dashboard.rb +267 -16
  40. package/scripts/day-summary +2 -1
  41. package/scripts/doctor.rb +680 -39
  42. package/scripts/end-intent +378 -56
  43. package/scripts/exec-worktree +5 -5
  44. package/scripts/file-session-intent +2 -1
  45. package/scripts/graph-measure +249 -0
  46. package/scripts/hook-call-budget +222 -0
  47. package/scripts/hook-capture +24 -123
  48. package/scripts/hook-close +2 -1
  49. package/scripts/hook-message-display +7 -0
  50. package/scripts/hook-record +24 -16
  51. package/scripts/hook-savepoint +27 -3
  52. package/scripts/hook-session-start +359 -321
  53. package/scripts/hook-stop +58 -0
  54. package/scripts/index-projection +74 -0
  55. package/scripts/insight-append +17 -4
  56. package/scripts/install.rb +9 -7
  57. package/scripts/lib/action_graph_shim.rb +279 -0
  58. package/scripts/lib/active_delivery.rb +105 -0
  59. package/scripts/lib/agent_models.rb +63 -25
  60. package/scripts/lib/arm.rb +74 -91
  61. package/scripts/lib/atomic_write.rb +31 -0
  62. package/scripts/lib/backup.rb +65 -0
  63. package/scripts/lib/cli/command.rb +92 -0
  64. package/scripts/lib/cli/commands/auto.rb +18 -0
  65. package/scripts/lib/cli/commands/auto_brief.rb +44 -0
  66. package/scripts/lib/cli/commands/auto_lock.rb +111 -0
  67. package/scripts/lib/cli/commands/auto_report.rb +50 -0
  68. package/scripts/lib/cli/commands/auto_take.rb +68 -0
  69. package/scripts/lib/cli/commands/backup.rb +43 -0
  70. package/scripts/lib/cli/commands/checkout.rb +25 -0
  71. package/scripts/lib/cli/commands/continue.rb +66 -0
  72. package/scripts/lib/cli/commands/doctor.rb +81 -0
  73. package/scripts/lib/cli/commands/feedback.rb +40 -0
  74. package/scripts/lib/cli/commands/help.rb +69 -0
  75. package/scripts/lib/cli/commands/hook.rb +32 -0
  76. package/scripts/lib/cli/commands/index.rb +23 -0
  77. package/scripts/lib/cli/commands/install.rb +21 -0
  78. package/scripts/lib/cli/commands/installer_verb.rb +37 -0
  79. package/scripts/lib/cli/commands/intent.rb +19 -0
  80. package/scripts/lib/cli/commands/intent_answer.rb +37 -0
  81. package/scripts/lib/cli/commands/intent_command.rb +58 -0
  82. package/scripts/lib/cli/commands/intent_end.rb +75 -0
  83. package/scripts/lib/cli/commands/intent_new.rb +62 -0
  84. package/scripts/lib/cli/commands/intent_note.rb +43 -0
  85. package/scripts/lib/cli/commands/intent_rule.rb +36 -0
  86. package/scripts/lib/cli/commands/intent_show.rb +32 -0
  87. package/scripts/lib/cli/commands/intent_spec.rb +44 -0
  88. package/scripts/lib/cli/commands/intent_step.rb +79 -0
  89. package/scripts/lib/cli/commands/intent_verify.rb +26 -0
  90. package/scripts/lib/cli/commands/migrate.rb +16 -0
  91. package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
  92. package/scripts/lib/cli/commands/next.rb +54 -0
  93. package/scripts/lib/cli/commands/project.rb +19 -0
  94. package/scripts/lib/cli/commands/project_links.rb +46 -0
  95. package/scripts/lib/cli/commands/project_list.rb +20 -0
  96. package/scripts/lib/cli/commands/project_new.rb +95 -0
  97. package/scripts/lib/cli/commands/query.rb +31 -0
  98. package/scripts/lib/cli/commands/render.rb +35 -0
  99. package/scripts/lib/cli/commands/roadmap.rb +19 -0
  100. package/scripts/lib/cli/commands/roadmap_check.rb +54 -0
  101. package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
  102. package/scripts/lib/cli/commands/roadmap_migrate.rb +53 -0
  103. package/scripts/lib/cli/commands/roadmap_next.rb +77 -0
  104. package/scripts/lib/cli/commands/roadmap_show.rb +65 -0
  105. package/scripts/lib/cli/commands/rollback.rb +20 -0
  106. package/scripts/lib/cli/commands/search.rb +60 -0
  107. package/scripts/lib/cli/commands/session.rb +18 -0
  108. package/scripts/lib/cli/commands/session_commit.rb +42 -0
  109. package/scripts/lib/cli/commands/session_handoff.rb +34 -0
  110. package/scripts/lib/cli/commands/session_summary.rb +35 -0
  111. package/scripts/lib/cli/commands/status.rb +68 -0
  112. package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
  113. package/scripts/lib/cli/commands/sync.rb +55 -0
  114. package/scripts/lib/cli/commands/uninstall.rb +20 -0
  115. package/scripts/lib/cli/commands/update.rb +20 -0
  116. package/scripts/lib/cli/commands/version.rb +53 -0
  117. package/scripts/lib/cli/frontier.rb +86 -0
  118. package/scripts/lib/cli/intent_progress.rb +36 -0
  119. package/scripts/lib/cli/legacy.rb +80 -0
  120. package/scripts/lib/cli/output.rb +137 -0
  121. package/scripts/lib/cli/scope.rb +134 -0
  122. package/scripts/lib/cli/table.rb +65 -0
  123. package/scripts/lib/cli.rb +94 -0
  124. package/scripts/lib/codex_adapter.rb +198 -0
  125. package/scripts/lib/compact_instructions.rb +13 -5
  126. package/scripts/lib/core_integrity.rb +71 -0
  127. package/scripts/lib/dashboard_screen.rb +40 -0
  128. package/scripts/lib/data_boundary.rb +132 -0
  129. package/scripts/lib/day_summary.rb +23 -14
  130. package/scripts/lib/doctor_core.rb +114 -38
  131. package/scripts/lib/doctor_session_ledger.rb +5 -53
  132. package/scripts/lib/engine_permissions.rb +88 -0
  133. package/scripts/lib/exec_worktree.rb +24 -21
  134. package/scripts/lib/feedback_report.rb +1 -1
  135. package/scripts/lib/graph_edges.rb +137 -0
  136. package/scripts/lib/graph_file.rb +246 -0
  137. package/scripts/lib/graph_measure.rb +645 -0
  138. package/scripts/lib/graph_measure_budget.rb +409 -0
  139. package/scripts/lib/graph_measure_cohorts.rb +487 -0
  140. package/scripts/lib/graph_measure_models.rb +413 -0
  141. package/scripts/lib/graph_measure_report.rb +532 -0
  142. package/scripts/lib/graph_tree.rb +98 -0
  143. package/scripts/lib/guarded_append.rb +155 -0
  144. package/scripts/lib/handoff.rb +40 -13
  145. package/scripts/lib/harness_adapter.rb +184 -0
  146. package/scripts/lib/hook_registry.rb +27 -3
  147. package/scripts/lib/hook_replay.rb +235 -0
  148. package/scripts/lib/index_entry.rb +62 -0
  149. package/scripts/lib/index_projection.rb +201 -0
  150. package/scripts/lib/insights.rb +1 -1
  151. package/scripts/lib/installer_core.rb +543 -71
  152. package/scripts/lib/intent_screen.rb +4 -4
  153. package/scripts/lib/intent_screen_ansi.rb +73 -12
  154. package/scripts/lib/intent_validator.rb +2 -2
  155. package/scripts/lib/lock.rb +10 -11
  156. package/scripts/lib/message_display.rb +350 -54
  157. package/scripts/lib/meter_watch.rb +185 -0
  158. package/scripts/lib/node_file.rb +234 -0
  159. package/scripts/lib/node_ids.rb +99 -0
  160. package/scripts/lib/node_input.rb +921 -0
  161. package/scripts/lib/node_input_compatibility.rb +62 -0
  162. package/scripts/lib/node_ledger.rb +386 -0
  163. package/scripts/lib/node_progress.rb +153 -0
  164. package/scripts/lib/node_return.rb +204 -0
  165. package/scripts/lib/node_worktree.rb +337 -0
  166. package/scripts/lib/outcome_report.rb +440 -0
  167. package/scripts/lib/preflight.rb +4 -6
  168. package/scripts/lib/project_config.rb +46 -0
  169. package/scripts/lib/project_validator.rb +3 -2
  170. package/scripts/lib/qmd_sync.rb +8 -7
  171. package/scripts/lib/ready_set.rb +462 -0
  172. package/scripts/lib/reference_archive.rb +45 -0
  173. package/scripts/lib/release_guard.rb +18 -0
  174. package/scripts/lib/report_screen.rb +1371 -47
  175. package/scripts/lib/rlm/corpus.rb +13 -0
  176. package/scripts/lib/rlm/probe.rb +29 -0
  177. package/scripts/lib/rlm/query.rb +22 -0
  178. package/scripts/lib/roadmap_graph.rb +210 -0
  179. package/scripts/lib/roadmap_migration.rb +95 -0
  180. package/scripts/lib/roadmap_queue.rb +170 -12
  181. package/scripts/lib/roadmap_render.rb +150 -0
  182. package/scripts/lib/roadmap_savepoint.rb +64 -14
  183. package/scripts/lib/runner_absorb.rb +703 -0
  184. package/scripts/lib/runner_answer.rb +206 -0
  185. package/scripts/lib/runner_core.rb +194 -0
  186. package/scripts/lib/runner_dispatch.rb +526 -0
  187. package/scripts/lib/runner_policy.rb +191 -0
  188. package/scripts/lib/runner_proposals.rb +275 -0
  189. package/scripts/lib/runner_rewind.rb +201 -0
  190. package/scripts/lib/runner_sweep.rb +231 -0
  191. package/scripts/lib/runner_until_empty.rb +252 -0
  192. package/scripts/lib/runner_watch.rb +389 -0
  193. package/scripts/lib/savepoint.rb +141 -19
  194. package/scripts/lib/scaffold_intent.rb +6 -3
  195. package/scripts/lib/screen_paint.rb +365 -28
  196. package/scripts/lib/screens/dashboard.rb +20 -0
  197. package/scripts/lib/screens/plan.rb +18 -0
  198. package/scripts/lib/screens/roadmap.rb +15 -0
  199. package/scripts/lib/search_index.rb +55 -0
  200. package/scripts/lib/session_close.rb +30 -28
  201. package/scripts/lib/session_git.rb +67 -19
  202. package/scripts/lib/session_ledger.rb +48 -4
  203. package/scripts/lib/session_usage.rb +190 -0
  204. package/scripts/lib/sqlite.rb +22 -0
  205. package/scripts/lib/stop_gate.rb +95 -0
  206. package/scripts/lib/store_discovery.rb +7 -6
  207. package/scripts/lib/store_layout.rb +54 -0
  208. package/scripts/lib/store_provisioning.rb +2 -1
  209. package/scripts/lib/store_sync.rb +85 -0
  210. package/scripts/lib/stores_move.rb +93 -0
  211. package/scripts/lib/untouched_scaffold.rb +51 -0
  212. package/scripts/lib/verify_intent.rb +36 -8
  213. package/scripts/lib/version_number.rb +48 -0
  214. package/scripts/lib/work_graph.rb +59 -0
  215. package/scripts/lib/work_graph_validator.rb +201 -0
  216. package/scripts/lib/worktree.rb +27 -32
  217. package/scripts/lib/worktree_sweep.rb +6 -5
  218. package/scripts/link-suggest +2 -1
  219. package/scripts/meter-watch +57 -0
  220. package/scripts/migrate-to-global +1 -1
  221. package/scripts/new-intent +4 -13
  222. package/scripts/node-input +92 -0
  223. package/scripts/node-run +225 -0
  224. package/scripts/node-transition +291 -0
  225. package/scripts/outcome-report +74 -0
  226. package/scripts/plastic-lock +65 -60
  227. package/scripts/project-links +6 -21
  228. package/scripts/promote-session-item +3 -2
  229. package/scripts/read-config +53 -9
  230. package/scripts/ready-set +126 -0
  231. package/scripts/release-check +123 -0
  232. package/scripts/report-screen +177 -16
  233. package/scripts/roadmap-graph +125 -0
  234. package/scripts/roadmap-savepoint +7 -0
  235. package/scripts/rollback.rb +5 -1
  236. package/scripts/runner +581 -0
  237. package/scripts/savepoint-note +11 -9
  238. package/scripts/session-commit +2 -1
  239. package/scripts/session-usage +56 -0
  240. package/scripts/skill-lint +115 -6
  241. package/scripts/spawn-preamble +2 -2
  242. package/scripts/update.rb +31 -4
  243. package/scripts/validate-work-graph +39 -0
  244. package/scripts/verify-intent +3 -2
  245. package/scripts/write-handoff +2 -1
  246. package/templates/agents.md +7 -7
  247. package/templates/config.yml +16 -9
  248. package/templates/dashboard-screen.md +22 -0
  249. package/templates/display-fixture.md +21 -0
  250. package/templates/graph.md +16 -0
  251. package/templates/index.md +1 -1
  252. package/templates/intent-screen.md +1 -1
  253. package/templates/node-decision.md +11 -0
  254. package/templates/node-research.md +13 -0
  255. package/templates/node-verify.md +13 -0
  256. package/templates/node-work.md +22 -0
  257. package/templates/outcome.md +8 -3
  258. package/templates/project.yml +1 -1
  259. package/templates/render.css +10 -0
  260. package/templates/report-plan.md +15 -0
  261. package/templates/report-roadmap-delivered.md +10 -0
  262. package/templates/report-roadmap-plan.md +9 -0
  263. package/templates/report-roadmap-state.md +9 -0
  264. package/templates/report-state.md +1 -1
  265. package/templates/roadmap.md +13 -0
  266. package/bin/plastic.js +0 -70
  267. package/scripts/lib/bridge.rb +0 -116
  268. package/skills/agent-advisor/SKILL.md +0 -92
  269. package/skills/auto/SKILL.md +0 -296
  270. package/skills/auto/evals/evals.json +0 -255
  271. package/skills/auto/references/end-tail.md +0 -66
  272. package/skills/auto/references/human-report-contract.md +0 -78
  273. package/skills/conventions/SKILL.md +0 -29
  274. package/skills/conventions/references/completion-and-done.md +0 -43
  275. package/skills/dashboard/SKILL.md +0 -169
  276. package/skills/dashboard/evals/evals.json +0 -38
  277. package/skills/dashboard/references/classification.md +0 -22
  278. package/skills/dashboard/templates/dashboard-global.md +0 -20
  279. package/skills/dashboard/templates/dashboard-project.md +0 -19
  280. package/skills/direct/SKILL.md +0 -66
  281. package/skills/direct/references/request-signals.md +0 -59
  282. package/skills/doctor/SKILL.md +0 -299
  283. package/skills/doctor/report.md +0 -102
  284. package/skills/feedback/SKILL.md +0 -98
  285. package/skills/feedback/references/transport-and-privacy.md +0 -65
  286. package/skills/feedback/report.md +0 -36
  287. package/skills/install/SKILL.md +0 -217
  288. package/skills/intent-continuing/SKILL.md +0 -154
  289. package/skills/intent-continuing/references/board-fill.md +0 -43
  290. package/skills/intent-continuing/references/boarding-matrix.md +0 -34
  291. package/skills/intent-continuing/references/context-management.md +0 -28
  292. package/skills/intent-continuing/references/liveness-ranking.md +0 -57
  293. package/skills/intent-creating/SKILL.md +0 -164
  294. package/skills/intent-creating/evals/evals.json +0 -72
  295. package/skills/intent-creating/references/lifecycle.md +0 -81
  296. package/skills/intent-creating/references/wikilinks.md +0 -8
  297. package/skills/intent-ending/SKILL.md +0 -176
  298. package/skills/intent-ending/evals/evals.json +0 -74
  299. package/skills/intent-executing/SKILL.md +0 -170
  300. package/skills/intent-executing/evals/evals.json +0 -66
  301. package/skills/intent-executing/implementer-prompt.md +0 -42
  302. package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
  303. package/skills/intent-speccing/SKILL.md +0 -130
  304. package/skills/intent-speccing/evals/evals.json +0 -126
  305. package/skills/intent-speccing/references/design-principles.md +0 -44
  306. package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
  307. package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
  308. package/skills/project-creating/SKILL.md +0 -162
  309. package/skills/project-creating/references/hubs-projects.md +0 -55
  310. package/skills/project-creating/references/project-scaffolding.md +0 -97
  311. package/skills/releasing/SKILL.md +0 -337
  312. package/skills/releasing/references/deprecations.md +0 -60
  313. package/skills/releasing/references/promotion-and-tagging.md +0 -66
  314. package/skills/releasing/references/release-lines.md +0 -105
  315. package/skills/roadmap/SKILL.md +0 -64
  316. package/skills/roadmap/references/file-format.md +0 -124
  317. package/skills/roadmap/references/operations.md +0 -112
  318. package/skills/rollback/SKILL.md +0 -91
  319. package/skills/tutorial/SKILL.md +0 -65
  320. package/skills/tutorial/evals/evals.json +0 -186
  321. package/skills/uninstall/SKILL.md +0 -75
  322. package/skills/update/SKILL.md +0 -126
  323. /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
  324. /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
  325. /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
  326. /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
@@ -6,6 +6,6 @@
6
6
 
7
7
  **Steps**
8
8
 
9
- | Step | Status | What |
9
+ | Step | Status | Detail |
10
10
  | --- | --- | --- |
11
11
  {{steps.rows}}
@@ -9,6 +9,19 @@ roadmap's goal is reached, move this file from `roadmaps/{slug}.md` to
9
9
  (a checkable prose condition — one or a few sentences a human or coordinator reads to decide the
10
10
  roadmap is done. Not an executable checker.)
11
11
 
12
+ ## Graph
13
+ Edges, `needs` only; the head needs the tail done. The literal target `nothing` declares a root
14
+ (an entry needing nothing). Batches below are computed from these edges, not hand-ordered; run
15
+ `roadmap-graph check <this file>` to see the computed batches and `roadmap-graph render <this
16
+ file>` to write them back, or `roadmap-graph migrate <this file>` on an existing graphless
17
+ roadmap to derive edges from its current batch order instead of hand-writing them here.
18
+
19
+ Grammar (fenced below so this example is never read as a real edge):
20
+ ```
21
+ - <intent-id> needs nothing
22
+ - <intent-id> needs <intent-id>
23
+ ```
24
+
12
25
  ## Batches
13
26
  Entries in a batch are parallel-safe; batches run top to bottom. The checkbox is checked once an
14
27
  entry is delivered, unchecked otherwise; the trailing token after the em-dash is the precise
package/bin/plastic.js DELETED
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // Thin shim — npx entry point that dispatches a subcommand to the matching Ruby verb script.
4
- // All logic lives in scripts/<verb>.rb. JS is only the distribution + dispatch mechanism.
5
- //
6
- // npx @zalom/plastic install [flags]
7
- // npx @zalom/plastic update [flags]
8
- // npx @zalom/plastic uninstall [flags]
9
- // npx @zalom/plastic rollback [flags]
10
- //
11
- // Back-compat: a bare `--uninstall` (no subcommand) routes to uninstall with a deprecation
12
- // warning; no subcommand at all defaults to install (legacy behaviour, one release).
13
-
14
- import { execFileSync } from 'node:child_process'
15
- import { resolve } from 'node:path'
16
- import { existsSync } from 'node:fs'
17
-
18
- const VERBS = ['install', 'update', 'uninstall', 'rollback']
19
- const packageRoot = new URL('..', import.meta.url).pathname
20
- const argv = process.argv.slice(2)
21
-
22
- let verb
23
- let rest
24
-
25
- if (VERBS.includes(argv[0])) {
26
- verb = argv[0]
27
- rest = argv.slice(1)
28
- } else if (argv.includes('--uninstall')) {
29
- // Deprecated: `--uninstall` as a flag instead of the `uninstall` subcommand.
30
- console.error('! plastic: `--uninstall` is deprecated — use `npx @zalom/plastic uninstall`. (works for now)')
31
- verb = 'uninstall'
32
- rest = argv.filter((a) => a !== '--uninstall')
33
- } else {
34
- // No subcommand: legacy default to install (one release of grace).
35
- verb = 'install'
36
- rest = argv
37
- }
38
-
39
- const script = resolve(packageRoot, 'scripts', `${verb}.rb`)
40
-
41
- if (!existsSync(script)) {
42
- console.error(`Error: scripts/${verb}.rb not found in package.`)
43
- process.exit(1)
44
- }
45
-
46
- try {
47
- execFileSync('ruby', [script, ...rest], {
48
- stdio: 'inherit',
49
- // Clear RUBYOPT last, after the spread, so a global setting (for example --yjit)
50
- // cannot reach a ruby that does not know the flag. A machine with an old ruby
51
- // must get preflight's real message, not a crash.
52
- env: { ...process.env, PLASTIC_PACKAGE_ROOT: packageRoot, RUBYOPT: '' },
53
- })
54
- } catch (err) {
55
- if (err.status) process.exit(err.status)
56
- // We only get here when ruby could not be executed at all. A ruby that runs but is
57
- // too old exits with a status, handled on the line above, and prints its own real
58
- // message from scripts/lib/preflight.rb naming the version actually found.
59
- if (err.code === 'ENOENT') {
60
- console.error('Plastic needs Ruby 3.0.0 or newer to run its scripts (ruby was not found on PATH).')
61
- console.error('Install a pinned Ruby with mise:')
62
- console.error(' curl https://mise.run | sh # only if mise is not installed yet')
63
- console.error(' mise use --global ruby@3.3')
64
- console.error('Then re-run the Plastic installer.')
65
- } else {
66
- console.error(`Plastic could not run ruby: ${err.message}`)
67
- console.error('Check that `ruby -v` works in this shell, then re-run the Plastic installer.')
68
- }
69
- process.exit(1)
70
- }
@@ -1,116 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require "yaml"
5
- require_relative "lock"
6
-
7
- # Bridge - the shared helpers that outlived the /tmp bridge JSON.
8
- #
9
- # Until 2.0 this file cached a session's delivery state in
10
- # `<tmp>/plastic-<session>--<id>.json` (stage, worktree, lock, auto flag) and
11
- # arbitrated which bridge a gate hook should read. Ruling 6 of intent 296
12
- # retired that: the per-session pointer (`~/.plastic/store/.tmp/<session>/current`)
13
- # plus `delivery.lock` in the intent directory is the whole bridge, and
14
- # `scripts/lib/arm.rb` is how a team takes and gives back an intent (intent
15
- # 307). What stays here is the handful of pure helpers a dozen callers still
16
- # share: the INDEX entry matcher, the Active check, the id-from-dir parser,
17
- # the project config reader, `blank?`, and the skill-reference delegator.
18
- module Bridge
19
- # Single place a skill-reference string gets built (intent 201, D3). The
20
- # prefix table lives on Lock; this is a thin delegator so call sites read
21
- # Bridge.skill_ref.
22
- def self.skill_ref(name, harness: :claude)
23
- Lock.skill_ref(name, harness: harness)
24
- end
25
-
26
- def self.blank?(value)
27
- value.nil? || value.to_s.strip.empty?
28
- end
29
-
30
- # --- Shared INDEX entry matcher (intent 188, D12/D13) -----------------------
31
- #
32
- # ONE definition site for the "- [ID <sep> Title](link)" shape both
33
- # `intent_active?` (below) and `scripts/end-intent`'s own INDEX-move parser
34
- # depend on, so the two regexes can never drift apart. Accepts a real em dash
35
- # (U+2014) OR a plain hyphen as the id/title separator on READ; every WRITE
36
- # still emits the real em dash (D10). The separator is built from the
37
- # codepoint, not a literal byte, so this file stays em-dash free.
38
- EM_DASH = "\u2014".freeze
39
- INDEX_ENTRY_RE = /\A- \[(\S+)\s+(?:#{Regexp.escape(EM_DASH)}|-)\s+(.*?)\]\(([^)]+)\)/.freeze
40
-
41
- # Match `line` (already chomped) against the shared INDEX entry shape.
42
- # Returns a MatchData (captures: 1 = id, 2 = title, 3 = link) or nil.
43
- def self.index_entry_match(line)
44
- line.to_s.match(INDEX_ENTRY_RE)
45
- end
46
-
47
- # True iff the intent is Active in its store's INDEX.md, which lives at the
48
- # PARENT of the store/ dir. Non-raising: any failure (missing or unreadable
49
- # INDEX, bad arg) returns false. `index_active_ids` is a pure-data test
50
- # seam: when an Array of id strings is supplied, membership is checked
51
- # against it directly with no file read.
52
- def self.intent_active?(intent_id, store:, index_active_ids: nil)
53
- target = intent_id.to_s
54
- return index_active_ids.include?(target) if index_active_ids.is_a?(Array)
55
-
56
- index = File.join(File.dirname(store.to_s), "INDEX.md")
57
- return false unless File.exist?(index)
58
-
59
- in_active = false
60
- File.foreach(index) do |line|
61
- stripped = line.chomp
62
- if stripped == "## Active"
63
- in_active = true
64
- next
65
- end
66
- next unless in_active
67
- break if stripped.start_with?("## ") # next section ends the Active block
68
- m = index_entry_match(stripped)
69
- return true if m && m[1] == target
70
- end
71
- false
72
- rescue StandardError
73
- false
74
- end
75
-
76
- # --- Project config -------------------------------------------------------------
77
-
78
- PROJECT_CONFIG_DEFAULTS = {
79
- "governing_docs" => ["AGENTS.md"],
80
- "release" => {
81
- "on_complete" => "commit",
82
- },
83
- }.freeze
84
-
85
- def self.read_project_config(slug)
86
- path = File.join(Dir.home, ".plastic", "projects", slug, "project.yml")
87
- config = if File.exist?(path)
88
- YAML.safe_load(File.read(path)) || {}
89
- else
90
- {}
91
- end
92
-
93
- deep_merge(PROJECT_CONFIG_DEFAULTS, config)
94
- rescue => e
95
- $stderr.puts "Warning: failed to read project config for #{slug}: #{e.message}"
96
- PROJECT_CONFIG_DEFAULTS.dup
97
- end
98
-
99
- # "<id>" from a ".../store/<id>--<slug>" dir, else nil.
100
- def self.intent_id_from_dir(dir)
101
- base = File.basename(dir.to_s)
102
- base.include?("--") ? base.split("--", 2).first : nil
103
- end
104
-
105
- def self.deep_merge(base, overlay)
106
- result = base.dup
107
- overlay.each do |key, value|
108
- if value.is_a?(Hash) && result[key].is_a?(Hash)
109
- result[key] = deep_merge(result[key], value)
110
- else
111
- result[key] = value
112
- end
113
- end
114
- result
115
- end
116
- end
@@ -1,92 +0,0 @@
1
- ---
2
- name: plastic-agent-advisor
3
- description: >-
4
- Consult the advisor for expensive reasoning: one-way doors, plans, adversarial
5
- review of a plan or conclusion before an irreversible step, a deadlock after two
6
- failed attempts, or ranking several plausible options. Use when the user asks for
7
- a second opinion, a hard design decision, an architecture review, help breaking a
8
- deadlock, or says "ask the advisor". Also sets which advisor is the default when
9
- asked ("make Fable my advisor", "switch my advisor", "use the real advisor").
10
- user-invocable: true
11
- ---
12
-
13
- # Agent Advisor
14
-
15
- Plastic ships two consultation agents, never dispatched by the auto pipeline, summoned
16
- only when you decide the reasoning is worth buying:
17
-
18
- - **`plastic-advisor`** ("the real advisor"): the frontier model itself, expensive,
19
- billed through usage credits. Spawn it for a few rounds on the hardest problem, then
20
- close the session.
21
- - **`plastic-faux-advisor`** ("the imitation advisor"): an ordinary model carrying the
22
- same reasoning discipline inline in its own body, so it reasons the same disciplined
23
- way at a fraction of the cost. The cheaper default.
24
-
25
- ## When to consult (and when not to)
26
-
27
- Buy a consultation for: decisions with one-way doors (architecture, migration order,
28
- public contracts); turning a goal plus evidence into a step plan with checks;
29
- adversarial review of your plan or conclusion before an irreversible step; a deadlock
30
- after two failed attempts where you cannot say why; ranking several plausible options
31
- when the ordering decides where you spend the next day.
32
-
33
- Never buy a consultation for: anything a tool can answer (search, reading code, running
34
- tests, documentation), writing code at volume, confirming a decision you already made,
35
- style or naming a linter would settle, or anything reversible and cheap you have not
36
- tried first. The full buy/never-buy list, the effort table, and the entry test live in
37
- `references/advisor-protocol.md`; read it before writing a brief for the first time in
38
- a session.
39
-
40
- ## Routing: which advisor answers
41
-
42
- 1. Read the harness-scoped config: `advisor.claude.default`, the only advisor routing key
43
- the installer writes. If unset, use `plastic-advisor`, the shipped default.
44
- 2. If the user names which advisor they want ("ask the real one", "use Fable", "ask the
45
- cheap one"), honor that directly and dispatch `plastic-advisor` (the real advisor) or
46
- `plastic-faux-advisor` (the cheaper imitation) accordingly, overriding step 1 for this
47
- consultation only.
48
- 3. If `advisor.enabled` reads `false`, neither advisor agent nor this skill is
49
- installed; this step should not be reachable, but if it is, tell the user the
50
- advisor is disabled and point at "Setting the default" below.
51
- 4. Dispatch the resolved agent with a brief built per `references/advisor-protocol.md`
52
- section 4 (natural prose, the block is a completeness check, not a form to fill).
53
- State EFFORT and the answer shape explicitly; classify low and prove your way up,
54
- never open high "to be safe".
55
- 5. Consume the answer per the protocol's section 5: run the Operating Manual's
56
- five-question self-test on the advisor's plan before executing it. Advice is input,
57
- not authority; the plan is the advisor's, the outcome is yours.
58
-
59
- Read the resolved config value with:
60
-
61
- ```bash
62
- ruby ~/.plastic/scripts/read-config advisor.claude.default --project <repo>
63
- ```
64
-
65
- (Omit `--project` outside a registered project; falls back to the global value.)
66
-
67
- ## Setting the default advisor
68
-
69
- When asked to change the default ("make Fable my advisor", "switch my advisor", "use
70
- the cheaper one by default"), present the two options in plain language and write the
71
- choice:
72
-
73
- - **Faux Fable** (`plastic-faux-advisor`, recommended): an ordinary model carrying the
74
- frontier reasoning instructions. Much cheaper, available on any plan, reasons in the
75
- same disciplined way.
76
- - **Fable 5** (`plastic-advisor`): the frontier model itself. The strongest reasoning
77
- available, billed through usage credits, so summon it for a few rounds and close it.
78
-
79
- These are the same two options the installer offers at install and update time. Write
80
- the choice to `advisor.claude.default` in the global `~/.plastic/config.yml` (or the
81
- project's `.plastic_store/config.yml` when the user scopes the change to one project):
82
- read the file as YAML, set `advisor.claude.default` to the agent name (`plastic-advisor`
83
- or `plastic-faux-advisor`, never a model name or nickname), and write it back. Confirm
84
- the new default back to the user in one line.
85
-
86
- ## References
87
-
88
- - `references/advisor-protocol.md`: the full shipped Advisor Protocol (what to buy,
89
- effort and answer shape, the entry test, how to write a brief that earns its cost, the
90
- answer contract, session economics, anti-patterns). Read it before the first
91
- consultation in a session; the second consultation in the same advisor thread costs a
92
- fraction of the first, so keep follow-ups on one thread rather than opening a new one.
@@ -1,296 +0,0 @@
1
- ---
2
- name: plastic-auto
3
- description: >-
4
- Autonomous intent delivery - a background team takes a registered intent from How to Done.
5
- Use when user says "auto", "take it from here", "deliver this", or when a thinking
6
- conversation concludes and the user confirms autonomous execution. Requires an active intent
7
- in INDEX.md.
8
- user-invocable: true
9
- ---
10
-
11
- # Auto - Autonomous Intent Delivery
12
-
13
- Announce: "Taking over intent [ID] - [name] for autonomous delivery."
14
-
15
- **Advisory (not a rule).** At auto-mode start, recommend once that the user run this
16
- orchestrating main session on the best available thinking model (Fable, Opus, or whatever
17
- supersedes them). This is advice only: it changes no behavior. Dispatched agents keep their
18
- configured model and never resolve to Fable unless an explicit `agents.models.<name>` config
19
- override names Fable for that role. The two advisors, `plastic-advisor` and
20
- `plastic-faux-advisor`, are consultation roles the user or the main session summons
21
- deliberately; the auto pipeline never dispatches them.
22
-
23
- ## Precondition
24
-
25
- An active intent MUST exist in INDEX.md. If none exists, refuse: "No active intent found.
26
- Create one first with /plastic-intent-creating."
27
-
28
- If several active intents exist, ask the user which one to deliver (the one question auto asks
29
- at boarding, before delivery starts).
30
-
31
- **Picking work when no intent is specified.** If the user says "auto" without naming an intent
32
- and none is active, consult the roadmap first (the primary planning surface), then fall back to
33
- the dashboard queue:
34
-
35
- ```bash
36
- ruby ~/.plastic/scripts/roadmap-next --roadmaps-dir <tier>/roadmaps
37
- ```
38
-
39
- Branch on `state`: `dispatchable` means work its `dispatchable_queue` in `rank` order (the
40
- current batch's `queued` intents, parallel-safe within the batch); `in_flight` means the
41
- frontier batch is still delivering, report it and wait, never dispatch a later batch; `none` or
42
- `exhausted` means fall back to `ruby ~/.plastic/scripts/dashboard.rb all --json` and work its
43
- `dispatchable_queue` in `rank` order, leaving `human_only` and `next_big_thing` for the user.
44
-
45
- QMD-first (when available): when the user describes the work rather than naming an intent, run
46
- `ruby ~/.plastic/scripts/qmd-sync search "<terms>"` before scanning the store, then open the
47
- authoritative intent file for the hit you take over. The command is a no-op when QMD is absent.
48
-
49
- ## Take the intent (do this FIRST)
50
-
51
- Immediately after selecting the intent, take it for this session. One verb acquires the durable
52
- `delivery.lock` in the intent directory (stamped `run_mode: auto`), provisions the code worktree
53
- at `<repo>/.claude/worktrees/{id}--{slug}` on branch `plastic/{id}--{slug}`, and points this
54
- session at the intent (`~/.plastic/store/.tmp/<session>/current`), so the record hook writes
55
- savepoint lines and heartbeats for it instead of the day ledger:
56
-
57
- ```bash
58
- codex="${CODEX_THREAD_ID:-}"; claude="${CLAUDE_CODE_SESSION_ID:-}"
59
- ruby ~/.plastic/scripts/plastic-lock arm --intent-dir "<STORE>/<dir>" --mode auto \
60
- --agent plastic-enforcer \
61
- ${codex:+--harness codex --session "$codex" --thread "$codex"} \
62
- ${claude:+--harness claude --session "$claude"}
63
- ```
64
-
65
- Replace `<STORE>` (`~/.plastic/projects/<slug>/store` or `~/.plastic/store`) and `<dir>` (the
66
- `ID--slug` directory). The snippet trusts a nonblank `CODEX_THREAD_ID` as Codex, otherwise a
67
- nonblank `CLAUDE_CODE_SESSION_ID` as Claude, otherwise passes no identity and the verb keys the
68
- lock by a derived session key. Never guess identity from an absent runtime variable; an
69
- unknown harness or thread stays unknown. Exit 1 means the lock is held, stale, excluded, or
70
- corrupt; the message names the `plastic-doctor` verb that resolves it. Do not proceed as the
71
- owner after an exit 1.
72
-
73
- Read `../plastic-conventions/references/locks-and-worktrees.md` for what the lock and the
74
- worktree mean and the station table behind them. Code edits happen only inside the worktree.
75
-
76
- ## The shape (five steps, two agent boots)
77
-
78
- Every auto delivery runs the same shape, ruled by the owner on 2026-08-29. There is no intent
79
- tier and no stage agent; depth follows the work.
80
-
81
- | Step | Who | What lands |
82
- |---|---|---|
83
- | 1. The lead writes How | this session | `plan.md`, at least one `actions/ACTION_N.md` carrying a failure-mode matrix (one row per operation: the failure and the test that catches it), `checklist.md` |
84
- | 2. Adversarial plan review | boot 1, a fresh agent on `plan-reviewer-prompt.md` | a review file; the lead folds every finding into the spec, the matrix, and the tests |
85
- | 3. Execute, tests first | boot 2, `plastic-executor` | the red commit (the matrix's tests, failing), then the code, then a green suite |
86
- | 4. Review by risk | boot 3 only when risk calls for it (below) | a pass or a list of fixes the executor applies |
87
- | 5. One suite run, then close | this session | `outcome.md`, `end-intent`, the roadmap ledger |
88
-
89
- Two boots is the normal delivery; the third is the exception the risk rule names. The lead is
90
- this session (the `plastic-enforcer` role), never a dispatched agent.
91
-
92
- ## Team
93
-
94
- - **plastic-enforcer**: this session. Writes the Why and How record, dispatches, folds reviews,
95
- verifies, closes.
96
- - **plastic-executor**: one dispatch per intent, implements the consolidated action tests first,
97
- ticks the checklist, appends `## Insights`, drives the suite green.
98
- - **the plan reviewer**: one dispatch before code, from `plastic-intent-executing`'s
99
- `plan-reviewer-prompt.md`; a fresh agent, never the lead.
100
- - **the post-execution reviewer**: dispatched only by the risk rule, from
101
- `code-quality-reviewer-prompt.md`; a fresh agent, never the maker.
102
-
103
- Spawn preamble (live-state injection): before dispatching any agent, run
104
- `scripts/spawn-preamble <intent_dir> --role <role>` and PREPEND its output to the prompt. The
105
- preamble is a deterministic, filesystem-only snapshot of the intent (id, intent line, current
106
- stage, the worktree path when it exists) plus the honoring instruction and the report contract.
107
-
108
- Dispatch-time model contract: resolve each agent's model through the config chain
109
- (`read-config agents.models.<basename> --project <repo>`: project override, then global, then
110
- the shipped default) and pass it explicitly at dispatch; never rely on the role's frontmatter
111
- alone.
112
-
113
- Completion report (require, then synthesize): every dispatched agent MUST end with a structured
114
- completion report as its final message (`references/agent-report-contract.md`). When an agent
115
- returns no usable report, run `scripts/agent-report <intent_dir> --role <role>` to synthesize a
116
- deterministic filesystem-derived one, so the handoff account always exists.
117
-
118
- ### Delegation (agents writing under the owner's lock)
119
-
120
- This session owns the delivery lock. A dispatched agent runs in its own session, so register
121
- each one as a delegate before (or when) it needs to write into the intent dir:
122
-
123
- 1. Instruct each spawned agent to report its session id and runtime identity in its first
124
- message: `CODEX_THREAD_ID` for Codex, or `CLAUDE_CODE_SESSION_ID` for Claude. Use the
125
- agent's own identity when known; never infer a harness or model from missing context.
126
- 2. As the lock owner, run:
127
- `ruby ~/.plastic/scripts/plastic-lock delegate --intent-dir <intent-dir> --delegate <specialist-session-id> --harness <specialist-harness-when-known> --agent <role> --model <resolved-model-when-known> --thread <reported-CODEX_THREAD_ID-when-Codex>`
128
- Omit `--harness`, `--model`, or `--thread` when that value is unknown; `--agent <role>` is
129
- always known from the roster.
130
- 3. Immediately after the specialist returns, and before validating or dispatching
131
- the next handoff, classify the return and record its activity status as the owner:
132
- - `finished` means the specialist returned a usable completion report, whether
133
- agent-authored or synthesized through `scripts/agent-report`.
134
- - `failed` means the specialist returned blocked, errored, or without a usable
135
- completion report that can be synthesized.
136
- 4. Record the classification with exactly one of:
137
- ```bash
138
- ruby ~/.plastic/scripts/plastic-lock delegate --intent-dir <intent-dir> \
139
- --delegate <specialist-session-id> --status finished --harness <same-specialist-harness-when-known> \
140
- --agent <same-role> --model <same-resolved-model-when-known> --thread <same-CODEX_THREAD_ID-when-Codex>
141
- ruby ~/.plastic/scripts/plastic-lock delegate --intent-dir <intent-dir> \
142
- --delegate <specialist-session-id> --status failed --harness <same-specialist-harness-when-known> \
143
- --agent <same-role> --model <same-resolved-model-when-known> --thread <same-CODEX_THREAD_ID-when-Codex>
144
- ```
145
- Apply the same omission rule to unknown values on terminal status commands. A failed agent
146
- stops that handoff under the error procedure; never dispatch the next agent first.
147
-
148
- Only the owner can delegate. Delegates cannot re-delegate or release.
149
-
150
- Headless note: in a headless or background run the session id may be unset; the arm verb then
151
- keys the lock by a derived key and the record hook still writes the savepoint ledger from the
152
- written path. Verify the lock with `plastic-lock status` rather than assuming.
153
-
154
- Solo fallback: on a harness with no agent dispatch (Codex CLI today), this session walks the
155
- five steps itself: it still writes the matrix, still writes the tests first, and reviews its own
156
- plan against the matrix before code, saying so in `## Insights`.
157
-
158
- ## Stage-Aware Entry
159
-
160
- Read the active intent's `savepoint.md` FIRST: the last line classifies the stage, and you
161
- verify only that line's artifact before entering. Fall back to the filesystem probe when the
162
- ledger is missing (then rebuild it with `Savepoint.rebuild_savepoint`).
163
-
164
- | Ledger last line | Enter |
165
- |---|---|
166
- | `What {id}--{slug}.md` (born) or no spec | Why (write spec.md) |
167
- | `Why spec.md created` | How |
168
- | `How plan.md created` / `How checklist.md created` / `Exec started` | Exec (verify plan, matrix, checklist) |
169
- | `Exec outcome.md created` | Exec done; complete the intent |
170
- | `Done delivered|abandoned` | Terminal; do not resume |
171
-
172
- Filesystem fallback, in order: `checklist.md` with items checked means resume Exec from the
173
- first unchecked item; `plan.md` plus `checklist.md` means enter Exec; `spec.md` alone means
174
- enter How; `## Context` with content means complete Why; only `## Intent` means start Why.
175
-
176
- Announce which stage you are entering and why.
177
-
178
- ## Why (the lead)
179
-
180
- 1. Read `## Context` and `### Decisions`; assess the gaps.
181
- 2. Research yourself: code, docs, related intents through `## Links`, the web if needed. No
182
- questions to the human.
183
- 3. Decide: pick the best option per gap, record it in `## Context > ### Decisions` with the
184
- rationale, and log it in `## Insights` with the `(autonomous)` marker through
185
- `scripts/insight-append`.
186
- 4. Write `spec.md`.
187
-
188
- Then How.
189
-
190
- ## How (the lead), then the plan review
191
-
192
- 1. Write `plan.md`: numbered steps.
193
- 2. Write at least one real `actions/ACTION_N.md` (one consolidated `ACTION_1.md` by default;
194
- several only when the work splits into independent, parallel-safe actions). Each action
195
- carries the failure-mode matrix: one row per operation, the failure mode, and the test that
196
- catches it. A `.gitkeep`-only `actions/` is not a finished How.
197
- 3. Write `checklist.md` covering every action.
198
- 4. Dispatch the plan reviewer (boot 1) with `plastic-intent-executing`'s
199
- `plan-reviewer-prompt.md`, the spawn preamble, and the intent directory. Fold every finding
200
- into the spec, the matrix, and the tests; record what was dropped and why in the action
201
- file's review fold. A REVISE verdict is folded and not re-reviewed unless a finding changes
202
- a decision.
203
- 5. Print `ruby ~/.plastic/scripts/report-screen state <intent_dir> --changed "How written, plan review next"`
204
- (D15; see `references/human-report-contract.md` for the full trigger list). This replaces
205
- the old prose State/Risk/Call briefing at this boundary. In auto mode the screen informs;
206
- it does not wait.
207
-
208
- Then Exec.
209
-
210
- ## Exec (the executor)
211
-
212
- 1. Dispatch `plastic-executor` (boot 2) through `plastic-intent-executing` with the whole
213
- consolidated action pasted in: the spec decisions, the matrix, the checklist items, the
214
- worktree path from the preamble. Tests first: the executor commits the matrix's tests red,
215
- then builds, then drives the full suite green.
216
- 2. Read its return by code: DONE or DONE_WITH_CONCERNS proceeds; NEEDS_CONTEXT re-dispatches
217
- with the missing context; BLOCKED stops under the error procedure.
218
- 3. Tick the checklist as items land (the executor does this; verify it).
219
-
220
- ## Review by risk (boot 3, only when a rule fires)
221
-
222
- Dispatch the post-execution reviewer with `code-quality-reviewer-prompt.md` when any of these
223
- holds, each checkable from disk with no judgment; otherwise the green suite is the review:
224
-
225
- 1. `git diff --name-only <red-commit>..HEAD` touches a path on the risk list in
226
- `references/agent-architecture.md` (hooks, the lock, the arming module, the installer, a
227
- release file).
228
- 2. A row of any `actions/ACTION_N.md` failure-mode matrix names a test file that is not in that
229
- diff, or a test the green run did not execute.
230
- 3. The executor's completion report carries a status other than `delivered`, or a non-empty
231
- `deviations` or `blockers` field.
232
-
233
- The reviewer returns a pass or a list of fixes; the executor (re-dispatched) applies them, then
234
- the suite runs once more.
235
- ## Project Creation
236
-
237
- If the plan calls for creating a new project, determine the path from `~/.plastic/config.yml`
238
- `project_roots` or the intent context, confirm the path with the user (the one human
239
- interaction added mid-delivery), invoke `plastic-project-creating`, and continue from the
240
- project directory on the tactical intent.
241
-
242
- ## Permission Model - Safe-by-Default
243
-
244
- Prefer non-destructive routes: rename instead of drop, additive migrations plus backfill, move
245
- files instead of deleting them, feature flags off instead of removed code, a backup before a
246
- migration. When a destructive action on an existing project has no safe alternative, log it in
247
- `## Insights`, notify the user ("Blocked on destructive action: ..."), and STOP unless
248
- `--skip-permissions` was given, in which case log and proceed. During initial project creation
249
- every choice is non-destructive and the team has full autonomy.
250
-
251
- ## Completion
252
-
253
- Read `../plastic-conventions/references/completion-and-done.md` for what "intent done" means.
254
-
255
- 1. Verify every checklist item is checked and the suite is green once on the branch.
256
- 2. Write `outcome.md` from `~/.plastic/templates/outcome.md` with `disposition: delivered`,
257
- `## Delivered` as the labeled table whose row labels match the action-file headings (317a).
258
- 3. Release, if configured: match the working directory against `~/.plastic/projects.yml`, read
259
- `project.yml`'s `release` block, and act on `on_complete` (`commit`, `commit_and_push`,
260
- `manual`), `verify` (green proceeds; red follows `on_red`: `fix_and_retry` up to twice,
261
- `stop`, or `manual`), and `on_green` (delegate entirely to `plastic-releasing`).
262
- 4. Review `## Insights` for observations that should become future intents; create them through
263
- `plastic-intent-creating` and update `chain`.
264
- 5. Close through `plastic-intent-ending`, which runs `scripts/end-intent`: outcome, INDEX,
265
- savepoint, the store commit, and the disarm (the worktree released, `delivery.lock` cleared,
266
- the session pointer back on the day ledger), then the QMD reindex last and the single owner
267
- report. Pass `--session` and `--index-note`:
268
- ```bash
269
- ruby ~/.plastic/scripts/end-intent --store <store_path> --id <ID> --disposition delivered \
270
- --session "$CLAUDE_CODE_SESSION_ID" \
271
- --index-note "<what shipped>; <suite result>"
272
- ```
273
- Exit 4 means a live foreign session holds the lock; 5 means the worktree is dirty (commit
274
- first, or pass `--discard-worktree-changes` deliberately); 3 means the lock survived the
275
- disarm (`/plastic-doctor check the lock status`); 6 means the structure check refused. Never
276
- leave an orphaned worktree; run `git worktree prune` on a stale reference.
277
- 6. Print `ruby ~/.plastic/scripts/report-screen delivered <intent_dir>` once (D15): this is the
278
- owner report at End, replacing the old prose Done briefing.
279
-
280
- ## Error Handling
281
-
282
- If the team gets stuck (an unresolvable gap, a missing dependency, a suite that stays red):
283
- log the blocker in `## Insights`, make sure `savepoint.md` reflects the state, notify the user
284
- ("Blocked on intent [ID] - [name]: ..."), and STOP. Never work around a blocker in a way that
285
- leaves the project broken.
286
-
287
- ## References
288
-
289
- - Read `references/agent-architecture.md` for the team model, the risk list, the headless note,
290
- and the solo fallback when dispatching or when a harness has no agent dispatch.
291
- - Read `references/human-report-contract.md` for the three report screens and the five
292
- triggers before printing the How or Completion screen above.
293
- - Read `references/agent-report-contract.md` for the completion report format when reading a
294
- dispatched agent's return or synthesizing one.
295
- - Read `references/end-tail.md` for what `Arm.disarm` does at the End tail and why the reindex
296
- runs last, before closing an intent.