@zalom/plastic 2.0.0-alpha.27 → 2.0.0-alpha.29

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 (207) hide show
  1. package/PLASTIC.md +13 -139
  2. package/README.md +345 -133
  3. package/agents/plastic-enforcer.md +9 -10
  4. package/agents/plastic-executor.md +1 -1
  5. package/bin/crap +4 -0
  6. package/bin/lib/context_budget.rb +35 -1
  7. package/bin/lib/skill_census.rb +839 -0
  8. package/bin/plastic +6 -0
  9. package/bin/plastic-skill-census +114 -0
  10. package/bin/verify-change +345 -0
  11. package/deprecations.yml +1 -1
  12. package/{skills/agent-advisor/references → docs/help}/advisor-protocol.md +4 -7
  13. package/{skills/auto/references → docs/help}/agent-architecture.md +7 -7
  14. package/{skills/conventions/references → docs/help}/completion-and-done.md +1 -1
  15. package/{skills/auto/references → docs/help}/human-report-contract.md +17 -19
  16. package/{skills/conventions/references → docs/help}/roadmaps.md +2 -2
  17. package/{skills/tutorial/references → docs/help}/track-1-guided.md +8 -8
  18. package/{skills/tutorial/references → docs/help}/track-2-auto.md +5 -5
  19. package/{skills/tutorial/references → docs/help}/track-3-projects-and-roadmaps.md +24 -17
  20. package/package.json +3 -2
  21. package/scripts/append-ledger +2 -1
  22. package/scripts/dashboard.rb +10 -9
  23. package/scripts/day-summary +2 -1
  24. package/scripts/doctor.rb +48 -42
  25. package/scripts/end-intent +2 -8
  26. package/scripts/file-session-intent +2 -1
  27. package/scripts/hook-capture +4 -3
  28. package/scripts/hook-close +2 -1
  29. package/scripts/hook-record +3 -2
  30. package/scripts/hook-savepoint +3 -2
  31. package/scripts/hook-session-start +5 -4
  32. package/scripts/hook-stop +2 -1
  33. package/scripts/insight-append +1 -2
  34. package/scripts/install.rb +3 -1
  35. package/scripts/lib/active_delivery.rb +1 -1
  36. package/scripts/lib/arm.rb +2 -1
  37. package/scripts/lib/backup.rb +65 -0
  38. package/scripts/lib/cli/command.rb +85 -0
  39. package/scripts/lib/cli/commands/auto.rb +18 -0
  40. package/scripts/lib/cli/commands/auto_brief.rb +44 -0
  41. package/scripts/lib/cli/commands/auto_lock.rb +60 -0
  42. package/scripts/lib/cli/commands/auto_report.rb +50 -0
  43. package/scripts/lib/cli/commands/auto_take.rb +25 -0
  44. package/scripts/lib/cli/commands/backup.rb +43 -0
  45. package/scripts/lib/cli/commands/checkout.rb +25 -0
  46. package/scripts/lib/cli/commands/continue.rb +66 -0
  47. package/scripts/lib/cli/commands/doctor.rb +20 -0
  48. package/scripts/lib/cli/commands/feedback.rb +40 -0
  49. package/scripts/lib/cli/commands/help.rb +69 -0
  50. package/scripts/lib/cli/commands/hook.rb +32 -0
  51. package/scripts/lib/cli/commands/index.rb +23 -0
  52. package/scripts/lib/cli/commands/install.rb +21 -0
  53. package/scripts/lib/cli/commands/installer_verb.rb +37 -0
  54. package/scripts/lib/cli/commands/intent.rb +19 -0
  55. package/scripts/lib/cli/commands/intent_answer.rb +37 -0
  56. package/scripts/lib/cli/commands/intent_command.rb +53 -0
  57. package/scripts/lib/cli/commands/intent_end.rb +61 -0
  58. package/scripts/lib/cli/commands/intent_new.rb +62 -0
  59. package/scripts/lib/cli/commands/intent_note.rb +43 -0
  60. package/scripts/lib/cli/commands/intent_rule.rb +36 -0
  61. package/scripts/lib/cli/commands/intent_show.rb +25 -0
  62. package/scripts/lib/cli/commands/intent_spec.rb +44 -0
  63. package/scripts/lib/cli/commands/intent_step.rb +43 -0
  64. package/scripts/lib/cli/commands/intent_verify.rb +26 -0
  65. package/scripts/lib/cli/commands/migrate.rb +16 -0
  66. package/scripts/lib/cli/commands/migrate_stores.rb +31 -0
  67. package/scripts/lib/cli/commands/next.rb +49 -0
  68. package/scripts/lib/cli/commands/project.rb +19 -0
  69. package/scripts/lib/cli/commands/project_links.rb +42 -0
  70. package/scripts/lib/cli/commands/project_list.rb +20 -0
  71. package/scripts/lib/cli/commands/project_new.rb +72 -0
  72. package/scripts/lib/cli/commands/query.rb +31 -0
  73. package/scripts/lib/cli/commands/render.rb +25 -0
  74. package/scripts/lib/cli/commands/roadmap.rb +19 -0
  75. package/scripts/lib/cli/commands/roadmap_check.rb +44 -0
  76. package/scripts/lib/cli/commands/roadmap_log.rb +54 -0
  77. package/scripts/lib/cli/commands/roadmap_next.rb +34 -0
  78. package/scripts/lib/cli/commands/roadmap_show.rb +45 -0
  79. package/scripts/lib/cli/commands/rollback.rb +20 -0
  80. package/scripts/lib/cli/commands/search.rb +60 -0
  81. package/scripts/lib/cli/commands/session.rb +18 -0
  82. package/scripts/lib/cli/commands/session_commit.rb +42 -0
  83. package/scripts/lib/cli/commands/session_handoff.rb +34 -0
  84. package/scripts/lib/cli/commands/session_summary.rb +35 -0
  85. package/scripts/lib/cli/commands/status.rb +68 -0
  86. package/scripts/lib/cli/commands/subcommand_list.rb +36 -0
  87. package/scripts/lib/cli/commands/sync.rb +46 -0
  88. package/scripts/lib/cli/commands/uninstall.rb +20 -0
  89. package/scripts/lib/cli/commands/update.rb +20 -0
  90. package/scripts/lib/cli/commands/version.rb +53 -0
  91. package/scripts/lib/cli/frontier.rb +84 -0
  92. package/scripts/lib/cli/legacy.rb +50 -0
  93. package/scripts/lib/cli/output.rb +102 -0
  94. package/scripts/lib/cli/scope.rb +127 -0
  95. package/scripts/lib/cli/table.rb +64 -0
  96. package/scripts/lib/cli.rb +94 -0
  97. package/scripts/lib/compact_instructions.rb +8 -0
  98. package/scripts/lib/day_summary.rb +4 -3
  99. package/scripts/lib/doctor_core.rb +7 -32
  100. package/scripts/lib/doctor_session_ledger.rb +2 -1
  101. package/scripts/lib/feedback_report.rb +1 -1
  102. package/scripts/lib/graph_measure_models.rb +3 -1
  103. package/scripts/lib/index_entry.rb +9 -0
  104. package/scripts/lib/installer_core.rb +73 -19
  105. package/scripts/lib/intent_screen.rb +3 -3
  106. package/scripts/lib/lock.rb +2 -2
  107. package/scripts/lib/node_input.rb +3 -2
  108. package/scripts/lib/preflight.rb +4 -6
  109. package/scripts/lib/project_config.rb +2 -1
  110. package/scripts/lib/project_validator.rb +3 -2
  111. package/scripts/lib/qmd_sync.rb +8 -7
  112. package/scripts/lib/reference_archive.rb +45 -0
  113. package/scripts/lib/release_guard.rb +2 -0
  114. package/scripts/lib/report_screen.rb +4 -3
  115. package/scripts/lib/rlm/corpus.rb +13 -0
  116. package/scripts/lib/rlm/probe.rb +29 -0
  117. package/scripts/lib/rlm/query.rb +22 -0
  118. package/scripts/lib/roadmap_queue.rb +2 -2
  119. package/scripts/lib/roadmap_savepoint.rb +1 -1
  120. package/scripts/lib/runner_absorb.rb +3 -2
  121. package/scripts/lib/search_index.rb +55 -0
  122. package/scripts/lib/session_git.rb +4 -3
  123. package/scripts/lib/sqlite.rb +22 -0
  124. package/scripts/lib/store_discovery.rb +7 -6
  125. package/scripts/lib/store_layout.rb +54 -0
  126. package/scripts/lib/store_provisioning.rb +2 -1
  127. package/scripts/lib/store_sync.rb +85 -0
  128. package/scripts/lib/stores_move.rb +93 -0
  129. package/scripts/lib/verify_intent.rb +2 -7
  130. package/scripts/lib/version_number.rb +48 -0
  131. package/scripts/lib/work_graph.rb +59 -0
  132. package/scripts/lib/worktree.rb +3 -8
  133. package/scripts/lib/worktree_sweep.rb +3 -2
  134. package/scripts/link-suggest +2 -1
  135. package/scripts/migrate-to-global +1 -1
  136. package/scripts/new-intent +3 -12
  137. package/scripts/plastic-lock +3 -2
  138. package/scripts/promote-session-item +3 -2
  139. package/scripts/release-check +10 -5
  140. package/scripts/report-screen +1 -1
  141. package/scripts/session-commit +2 -1
  142. package/scripts/spawn-preamble +2 -2
  143. package/scripts/update.rb +25 -4
  144. package/scripts/write-handoff +2 -1
  145. package/templates/agents.md +6 -6
  146. package/templates/render.css +10 -0
  147. package/bin/plastic.js +0 -70
  148. package/skills/agent-advisor/SKILL.md +0 -84
  149. package/skills/auto/SKILL.md +0 -297
  150. package/skills/auto/evals/evals.json +0 -255
  151. package/skills/auto/references/end-tail.md +0 -64
  152. package/skills/conventions/SKILL.md +0 -29
  153. package/skills/dashboard/SKILL.md +0 -180
  154. package/skills/dashboard/evals/evals.json +0 -38
  155. package/skills/dashboard/references/classification.md +0 -22
  156. package/skills/dashboard/templates/dashboard-global.md +0 -20
  157. package/skills/dashboard/templates/dashboard-project.md +0 -19
  158. package/skills/direct/SKILL.md +0 -66
  159. package/skills/direct/references/request-signals.md +0 -59
  160. package/skills/doctor/SKILL.md +0 -305
  161. package/skills/doctor/report.md +0 -102
  162. package/skills/feedback/SKILL.md +0 -98
  163. package/skills/feedback/references/transport-and-privacy.md +0 -65
  164. package/skills/feedback/report.md +0 -36
  165. package/skills/install/SKILL.md +0 -215
  166. package/skills/intent-continuing/SKILL.md +0 -156
  167. package/skills/intent-continuing/references/board-fill.md +0 -52
  168. package/skills/intent-continuing/references/boarding-matrix.md +0 -35
  169. package/skills/intent-continuing/references/context-management.md +0 -28
  170. package/skills/intent-continuing/references/liveness-ranking.md +0 -57
  171. package/skills/intent-creating/SKILL.md +0 -89
  172. package/skills/intent-creating/evals/evals.json +0 -72
  173. package/skills/intent-creating/references/lifecycle.md +0 -81
  174. package/skills/intent-creating/references/wikilinks.md +0 -8
  175. package/skills/intent-ending/SKILL.md +0 -182
  176. package/skills/intent-ending/evals/evals.json +0 -74
  177. package/skills/intent-executing/SKILL.md +0 -87
  178. package/skills/intent-executing/evals/evals.json +0 -66
  179. package/skills/intent-executing/implementer-prompt.md +0 -47
  180. package/skills/intent-executing/spec-reviewer-prompt.md +0 -27
  181. package/skills/intent-speccing/SKILL.md +0 -136
  182. package/skills/intent-speccing/evals/evals.json +0 -126
  183. package/skills/intent-speccing/references/design-principles.md +0 -44
  184. package/skills/intent-speccing/references/per-section-fill-rules.md +0 -92
  185. package/skills/intent-speccing/references/self-verify-checklist.md +0 -37
  186. package/skills/project-creating/SKILL.md +0 -162
  187. package/skills/project-creating/references/hubs-projects.md +0 -55
  188. package/skills/project-creating/references/project-scaffolding.md +0 -97
  189. package/skills/releasing/SKILL.md +0 -376
  190. package/skills/releasing/references/deprecations.md +0 -60
  191. package/skills/releasing/references/promotion-and-tagging.md +0 -70
  192. package/skills/releasing/references/release-lines.md +0 -105
  193. package/skills/roadmap/SKILL.md +0 -90
  194. package/skills/roadmap/references/file-format.md +0 -134
  195. package/skills/roadmap/references/operations.md +0 -112
  196. package/skills/rollback/SKILL.md +0 -91
  197. package/skills/tutorial/SKILL.md +0 -66
  198. package/skills/tutorial/evals/evals.json +0 -186
  199. package/skills/uninstall/SKILL.md +0 -75
  200. package/skills/update/SKILL.md +0 -126
  201. /package/{skills/auto/references → docs/help}/agent-report-contract.md +0 -0
  202. /package/{skills/intent-executing → docs/help}/code-quality-reviewer-prompt.md +0 -0
  203. /package/{skills/conventions/references → docs/help}/knowledge-graph.md +0 -0
  204. /package/{skills/conventions/references → docs/help}/lifecycle-and-savepoints.md +0 -0
  205. /package/{skills/conventions/references → docs/help}/locks-and-worktrees.md +0 -0
  206. /package/{skills/conventions/references → docs/help}/maintenance-and-revisions.md +0 -0
  207. /package/{skills/intent-executing → docs/help}/plan-reviewer-prompt.md +0 -0
@@ -1,305 +0,0 @@
1
- ---
2
- name: plastic-doctor
3
- description: Use when diagnosing Plastic installation health, after updates, or when something seems broken. Runs checks and reports findings with fix options.
4
- user-invocable: true
5
- ---
6
-
7
- # Doctor: Plastic Health Check
8
-
9
- ## Scopes
10
-
11
- Doctor has three scopes. Pick the right one for the situation:
12
-
13
- | Scope | Flag | When it runs | States |
14
- |-------|------|--------------|--------|
15
- | Core check | `--core` | SessionStart hook (automatic), also available on demand | Binary: pass or error |
16
- | Store check | `--store [global\|<slug>]` | Dashboard load, the project route of `plastic-intent-continuing` | Three-state: pass / warn / fail |
17
- | Full check | (no flag) | After every update (automatic), or `/plastic-doctor` | Three-state: pass / warn / fail |
18
-
19
- ### `--core` (binary, operational-readiness only)
20
-
21
- Checks ONLY that Plastic is loaded and ready for work: agent registration (skills,
22
- subagents, hooks/harnesses present and registered), core files (manifest-backed
23
- presence/hash checks, excluding `agent_model_drift`, which is a non-boot
24
- config-honoring check, never run at core), manifest sync (global + agent manifest
25
- SHA256), every registered project's path resolving to a real, existing directory,
26
- and the global store being reachable (`INDEX.md` present; no orphan/ghost content
27
- scanning). Result is binary: exit 0 on pass, non-zero on error. It never produces
28
- warnings, and it never scans store content.
29
-
30
- It checks two install manifests as part of core files and manifest sync:
31
-
32
- - `~/.plastic/manifest.json` (global manifest, covers PLASTIC.md and global scripts)
33
- - `~/.claude/plastic/manifest.json` (agent-side manifest, covers agent scripts and hooks)
34
-
35
- Each manifest maps a file path to its SHA256.
36
-
37
- **On failure**, the report states this guided route, in order:
38
-
39
- 1. Offer fixes in the `/plastic-doctor` conversation (the Fix all / Select individually /
40
- Skip router from Steps 4-5 below); doctor itself only reports, and each chosen repair
41
- is dispatched to the maintenance tool or skill that owns it.
42
- 2. If that does not resolve it, roll back to the last known-good version via
43
- `plastic-rollback` (restores from the local, append-only `versions.json` ledger of
44
- versions actually run).
45
- 3. Optionally report the issue via the feedback command (`scripts/feedback-report`,
46
- backing the `plastic-feedback` skill), which composes a local report plus a
47
- prefilled GitHub issue URL and never holds a credential or contacts GitHub
48
- directly.
49
-
50
- ### `--store [global|<slug>]`
51
-
52
- Checks the operations Plastic itself depends on in one store: QMD search reachability (scoped
53
- to that store's own collection; global uses `plastic-global`, a project slug uses
54
- `plastic-<slug>`), sources/chain resolution, cross-store resolution, INDEX parsing, links
55
- projection, done signals (including `backfilled_complete`: a terminal intent still missing a
56
- real spec.md, plan.md, or action file), and, for the global store only, the session ledger
57
- (`orphaned_session_tmp`: a `.tmp/<session>/` directory whose heartbeat is older than 24
58
- hours; `day_ledger_shape`: a `.sessions/` entry that is not a `YYYYMMDD` day directory with
59
- its `<day>.md`). A project slug also checks tool readiness (Serena, Enola): each is a pass whether
60
- present or absent, present naming it available, absent noting it as an optional integration
61
- never installed by doctor. Scope options:
62
-
63
- - No argument (`:all`): checks all stores (global and all project stores), QMD reachability
64
- unscoped across every collection.
65
- - `global`: checks only the global store, QMD scoped to `plastic-global`, no tool-readiness
66
- checks (code-navigation tools have no meaning against the global store).
67
- - A project slug (e.g. `--store plastic`): checks only that project's store, QMD scoped to
68
- `plastic-<slug>`, plus Serena/Enola readiness for that project.
69
-
70
- Produces three-state results (pass / warn / fail) and is run per-scope at dashboard load time:
71
- the global board uses `--store global`, a project board uses `--store <slug>`. **This IS the
72
- load-time full project check** named by 219's doctrine: no separate mechanism exists or is
73
- needed, since a project slug's scan already carries every per-project finding scoped to that
74
- project alone.
75
-
76
- ### Full doctor (no flag)
77
-
78
- Runs the install-wide surface: agent registration, core files (including config-honoring
79
- drift), manifest sync is core-only and not part of this run, deprecation checks, config-ask
80
- checks, install-integrity checks, skill-lint (advisory), QMD reachability (unscoped, every
81
- collection), the global store's own conventions/done-signals content, and the `display`
82
- category (intent 331e): `display_hook_registered` (also runs at `--core`), `display_hook_paints`
83
- (replays the shipped display fixture through the installed MessageDisplay hook and expects a
84
- painted screen back, a pass when a known defeater like `NO_COLOR` is active, never a fail),
85
- `display_not_defeated` (warns per active defeater and always names the undetectable verbose
86
- transcript view), and `display_surfaces_documented` (the harness-adapters doc still names every
87
- surface class). **Never carries a per-project finding**; that is `--store <slug>`'s job (see
88
- above). This is what `/plastic-doctor` invokes, and it also runs automatically after every
89
- `plastic-update` (informational, does not block or revert the update).
90
-
91
- ## When to Use
92
-
93
- - User invokes `/plastic-doctor` (full check)
94
- - After `plastic-update` completes (automatically, full check)
95
- - When hooks aren't firing, skills aren't loading, or something seems broken
96
- - When the user says "check plastic", "diagnose", "what's wrong with plastic"
97
-
98
- ## Procedure
99
-
100
- ### Step 1: Run the diagnostic script
101
-
102
- ```bash
103
- ruby ~/.plastic/scripts/doctor.rb --agent claude
104
- ```
105
-
106
- Replace `claude` with the current agent type if known (`codex`, `hermes`).
107
-
108
- Parse the JSON output from stdout. The script is read-only and never modifies
109
- files. Errors go to stderr.
110
-
111
- Exit codes indicate check results, not script failure:
112
- - `0`: all checks passed
113
- - `1`: warnings found
114
- - `2`: failures found
115
-
116
- All three exit codes mean the script ran successfully. Do not treat non-zero
117
- as an error.
118
-
119
- ### Step 2: Determine overall status
120
-
121
- Read the `status` field from the JSON root:
122
-
123
- | Status | Meaning |
124
- |--------|---------|
125
- | `pass` | Everything is healthy |
126
- | `warn` | Warnings found but Plastic works normally |
127
- | `fail` | Blocking issues that prevent Plastic from operating |
128
-
129
- ### Step 3: Fill the report template
130
-
131
- Read `report.md` from the same directory as this SKILL.md
132
- (`~/.plastic/skills/doctor/report.md` at runtime, or the plugin source
133
- `skills/doctor/report.md` during development).
134
-
135
- Group checks by category. For each category, list the checks with their
136
- status icon and message. If a check has `details`, list them as sub-items.
137
-
138
- Present the filled template to the user.
139
-
140
- ### Step 4: Offer fixes (if applicable)
141
-
142
- If any checks have `fixable: true` AND status is not `pass`:
143
-
144
- 1. Group fixable items by category
145
- 2. Show what each fix would do (from `fix_hint`)
146
- 3. Ask the user: **"Fix all / Select individually / Skip"**
147
-
148
- If no fixable issues exist, skip this step.
149
-
150
- This "Fix all / Select individually / Skip" prompt IS the router the spec calls
151
- `doctor --fix-all` (intent 197): doctor itself never mutates anything (see Step 5's table and
152
- "Important Notes" below); "Fix all" means "dispatch every fixable finding to the maintenance
153
- tool or skill that owns that class of repair," one row per fix_hint pattern.
154
-
155
- ### Step 5: Apply fixes
156
-
157
- Use the `fix_hint` value to determine the correct action:
158
-
159
- | Fix hint pattern | Agent action |
160
- |---|---|
161
- | "chmod +x on the listed files" | Run `chmod +x` on each file listed in `details` |
162
- | "Create missing directory" | Run `mkdir -p` on the path |
163
- | "Create INDEX.md with required sections" | Write INDEX.md with the 5 sections: Active, Future, Clusters, Abandoned, Completed |
164
- | "Add missing entries to INDEX.md" | Add orphaned intents to the appropriate INDEX.md section |
165
- | "Remove stale references from INDEX.md" | Edit INDEX.md to remove ghost references |
166
- | "Inject the missing required frontmatter field(s)" | Edit the intent's `{ID}--{slug}.md` frontmatter to add the missing key (e.g. `chain: []`) without touching other keys |
167
- | "Run: provision-project-store {slug}" | Run `provision-project-store <slug>` (see Provisioning a project store below) to create the missing store |
168
- | "Re-run installer" | Run `npx -y @zalom/plastic@<channel> install --claude` (or `--codex`/`--hermes`/`--all` for that agent; channel: -alpha->@alpha, -beta->@beta, else @latest) |
169
- | "Run the Plastic installer to bootstrap the store" | Run `npx -y @zalom/plastic@<channel> install --claude` (or `--codex`/`--hermes`/`--all`; channel: -alpha->@alpha, -beta->@beta, else @latest) to restore the global store's plastic_home directory or INDEX.md |
170
- | "Relocate ... revisions.md ..." | Relocate the flagged section or ref into the intent's `revisions.md` via move-and-record (one dated, `[rule: <tag>]`-tagged entry per item), per plastic-conventions > references/maintenance-and-revisions.md. For a missing required section, restore or reproject it instead. |
171
- | "Write the missing documents from the record via `scaffold-intent backfill ...`" | Run `ruby ~/.plastic/scripts/scaffold-intent backfill --store <store> --id <id> --disposition <delivered\|abandoned>` for each listed intent; it fills only missing or placeholder files and never touches real content |
172
- | "Remove each listed .tmp/<session>/ directory after confirming that session is gone" | For each listed directory, confirm no live session uses it (a live session rewrites its heartbeat on every prompt and edit), then remove that directory by hand; never remove an unlisted one |
173
- | "For a day directory missing its <day>.md, run `file-session-intent --day <day> ...`" | Run `ruby ~/.plastic/scripts/file-session-intent --day <day> --carry-to <today> --store <store>` for the named day; rename or remove an entry that is not a `YYYYMMDD` day directory |
174
- | "Run scripts/project-links ... PRESERVES ... --drop-unbacked-links" | Run `ruby ~/.plastic/scripts/maintenance-run --tool project-links --intent <id> --apply` for the one flagged id (never run bare `project-links` against a real store outside the rare owner-approved batch exception, D2) |
175
- | "Re-run the Plastic installer to repair the hook registration ... (plastic-install --repair)" (`display_hook_registered`) | Run `npx -y @zalom/plastic@<channel> install --reinstall --claude` (the `plastic-install` skill's repair mode), then re-run doctor |
176
-
177
- For fixes the agent cannot handle automatically, explain what the user needs
178
- to do manually. The `revisions.md` remedy is curator-applied (a move-and-record
179
- relocation, not a mechanical edit) and stays human-gated by the Step 4
180
- Fix / Select / Skip prompt.
181
-
182
- Read `../plastic-conventions/references/maintenance-and-revisions.md` for WORK versus
183
- MAINTENANCE, the `revisions.md` move-and-record contract, and the violation-tag catalog behind
184
- the `revisions.md` remedy above.
185
-
186
- ### Step 6: Verify
187
-
188
- After applying fixes, re-run the diagnostic script:
189
-
190
- ```bash
191
- ruby ~/.plastic/scripts/doctor.rb --agent claude
192
- ```
193
-
194
- Show the updated results.
195
-
196
- - If all checks pass: announce success.
197
- - If issues remain: explain what is still wrong and what the user can do.
198
-
199
- ## Post-Update Mode
200
-
201
- When invoked from `plastic-update` (not directly by the user):
202
-
203
- 1. Run the diagnostic script as in Step 1.
204
- 2. If all checks pass, show a single line: **"Health check: all clear."**
205
- 3. If issues are found: show the full report (Steps 3-6).
206
-
207
- This keeps the update flow clean when nothing is wrong.
208
-
209
- ## Important Notes
210
-
211
- - The script is **read-only**. It inspects but never modifies files.
212
- All fixes are performed by the agent using standard tools.
213
- - The script outputs JSON to stdout. Any diagnostic errors go to stderr.
214
- - Non-zero exit codes mean "issues found", not "script crashed".
215
- Always parse stdout regardless of exit code.
216
-
217
- ## Doctor-Exclusions: Known-Exempt Findings
218
-
219
- Some `savepoint_operational` findings can never legitimately close (a terminal intent with no
220
- real `outcome.md` has no disposition to echo, and doctor never invents one), so each store
221
- carries a `doctor-exclusions` file, sibling to that store's `INDEX.md`, recording
222
- knowingly-exempt `(intent_id, rule)` pairs. Format: one `rule_name id id id` line per rule,
223
- blank lines and `#` comments ignored. v1 honors exactly one rule, `savepoint_operational`.
224
-
225
- **Reading the count.** When any exclusion applies, the `savepoint_operational` check's message
226
- includes the count and the file's path, e.g. `"... (3 excluded via ~/.plastic/doctor-exclusions)"`.
227
- A malformed line in the file forces the check to `warn` with the parse error in `details`, even
228
- when zero real gaps remain, so a broken file is never silently permissive.
229
-
230
- **Both surfaces, one line.** A registration is honored by the store-wide `savepoint_operational`
231
- check and by the per-intent `doctor.rb --intent <id>` run, which reports the same missing
232
- `savepoint.md` under the check name `intent_savepoint_truthful`. Register the id once. The
233
- per-intent run honors it only for an intent that is terminal in `INDEX.md`, and never suppresses
234
- a phantom-savepoint-line finding.
235
-
236
- **Hand-editing.** The file is plain text; add a line (or append ids to an existing rule line) and
237
- save. No installer step, no reindex, and no `revisions.md` entry is required or written.
238
-
239
- **Populating it in bulk.** Run the maintenance tool, dry-run first:
240
-
241
- ```bash
242
- ruby ~/.plastic/scripts/maintenance-run --tool register-exclusions
243
- ```
244
-
245
- This computes every current `savepoint_operational` violation across all stores (or one store
246
- via `--store <key>`), through doctor's own finding function, and prints what it would register
247
- without writing anything. Review the output, then re-run with `--apply` to write the file(s) and
248
- land one scoped git commit. It unions with any existing hand-added ids (never drops one) and
249
- skips, rather than aborts on, any intent dir holding a fresh delivery lock.
250
-
251
- **Dead-row notice.** A registered row can go dead (gap repaired, id mistyped, or the intent
252
- directory gone). When any row is dead, the message adds a second suffix next to the exclusion
253
- count naming the count, the file, and the prune command - purely informational, status and exit
254
- code unchanged. Prune it the same way, dry-run first: register-exclusions --prune [--apply]. It
255
- removes exactly the dead rows through the same writer and commit, but holds back an id whose
256
- intent dir carries a fresh lock or has not gone terminal yet (nothing to suppress there yet),
257
- naming both as kept.
258
-
259
- ## Locks (auto teams only)
260
-
261
- Locks exist for auto teams: a `delivery.lock` file in the intent directory names the owning
262
- session, and the `record` hook refreshes its mtime on every edit (the lease heartbeat; stale
263
- means older than the TTL). Direct work takes no lock. When a lock reads held by a session
264
- that is gone, when work resumes after a crash, reboot, or `/tmp` wipe, or when the user says
265
- "fix the lock", "who holds the lock", or "reclaim the lock", use the CLI (intent 304 merged
266
- the former locking skill here):
267
-
268
- | Verb | What it does | When |
269
- |---|---|---|
270
- | `who` | Owner, heartbeat, claims, delegates, from durable files only | Safe inspection; needs `--intent-dir` |
271
- | `status` | Lock file, freshness, the derived worktree, whether this session is delivering the intent, claims | Always safe; run first |
272
- | `fix` | Idempotent repair from disk truth for this session; never touches a fresh foreign lock | Interrupted work, corrupt state, `/tmp` wiped |
273
- | `release` | The owner clears the lock | Ending or abandoning an auto delivery |
274
- | `reclaim` | Explicit takeover of a stale lock; appends an audit line to `savepoint.md` | The owner is gone and the lease expired |
275
- | `delegate` | The owner registers a subagent session, or marks it `finished` or `failed` | Auto-team orchestration |
276
-
277
- ```
278
- ruby ~/.plastic/scripts/plastic-lock status --intent-dir <store>/<id>--<slug>
279
- ruby ~/.plastic/scripts/plastic-lock who --intent-dir <store>/<id>--<slug>
280
- ruby ~/.plastic/scripts/plastic-lock fix --intent-dir <store>/<id>--<slug>
281
- ruby ~/.plastic/scripts/plastic-lock reclaim --intent-dir <store>/<id>--<slug>
282
- ```
283
-
284
- `fix` exits non-zero when another session holds a fresh lock: back off, `status` shows the
285
- owner. `reclaim` refuses a fresh lock; every takeover is audited. The lock file's mtime is the
286
- sole freshness truth. Never delete a lock file by hand. Read
287
- `../plastic-conventions/references/locks-and-worktrees.md` when a lock question goes beyond
288
- these verbs (claims, worktrees, the station ledger).
289
-
290
- ## Provisioning a project store
291
-
292
- When a project is registered in `~/.plastic/projects.yml` but has no store on disk (doctor
293
- reports `project_store_dir`), provision it (intent 304 merged the former provisioning skill
294
- here). The slug is the project's key under `projects`; an unregistered slug exits non-zero and
295
- creates nothing, and this procedure never edits `projects.yml`.
296
-
297
- ```bash
298
- ruby ~/.plastic/scripts/provision-project-store <slug>
299
- ruby ~/.plastic/scripts/qmd-sync register --store ~/.plastic/projects/<slug>/store
300
- ```
301
-
302
- The provisioner is pure filesystem and idempotent: it creates
303
- `~/.plastic/projects/<slug>/store/` with `.gitkeep`, writes `INDEX.md` and `project.yml` only
304
- when missing, and never clobbers. The QMD registration is a separate, optional step that
305
- no-ops when QMD is absent. New projects are provisioned by `plastic-project-creating`, not here.
@@ -1,102 +0,0 @@
1
- # Plastic Doctor Report
2
-
3
- <!-- =======================================================================
4
- AGENT INSTRUCTIONS -- How to fill this template
5
- =========================================================================
6
- 1. Run the doctor script. It outputs JSON with check results.
7
- 2. Replace every {{placeholder}} below with the corresponding JSON value.
8
- 3. For the category sections: the template shows ONE example section.
9
- Repeat that pattern for each unique category in the checks array.
10
- The scope determines which categories appear:
11
- --core scope: agent_registration, core_files (binary pass/error only)
12
- --store scope: global_store, conventions, project_stores
13
- full (no flag): all six categories below
14
- The six known categories and their display names are:
15
- global_store -> "Global Store"
16
- conventions -> "Conventions"
17
- agent_registration -> "Agent Registration"
18
- core_files -> "Core Files"
19
- project_stores -> "Project Stores"
20
- deprecations -> "Deprecations"
21
- done_signals -> "Completion Signals"
22
- session_ledger -> "Session Ledger" (global store only)
23
- 4. For each check within a category, emit one line with the status icon
24
- and the check message. If the check has non-empty details, list them
25
- as indented sub-items.
26
- 5. The "Fixable Issues" section should ONLY appear if at least one check
27
- has fixable=true AND status is not "pass". Omit the entire section
28
- otherwise.
29
- 6. Status icons (plain text, no emoji):
30
- pass -> [PASS]
31
- warn -> [WARN]
32
- fail -> [FAIL]
33
- 7. The overall status icon in the header uses the same mapping.
34
- 8. After filling, remove all HTML comments -- they are instructions only.
35
- ======================================================================= -->
36
-
37
- ## {{overall_status_icon}} Overall: {{status}} -- Plastic v{{version}}
38
-
39
- Checked at: {{timestamp}}
40
-
41
- ### Summary
42
-
43
- {{pass}} passed, {{warn}} warnings, {{fail}} failed -- {{total}} checks total
44
-
45
- ---
46
-
47
- <!-- =====================================================================
48
- CATEGORY SECTIONS
49
- ======================================================================
50
- Repeat the block below ONCE PER CATEGORY present in the checks array.
51
- Group checks by their "category" field. Use the display name mapping
52
- above for the heading. Within each category, list every check as a
53
- single line: status icon + message. If a check has non-empty "details",
54
- list each detail as an indented bullet beneath.
55
-
56
- Example category section (for agent_registration with two checks):
57
- ===================================================================== -->
58
-
59
- ### Agent Registration
60
-
61
- - [PASS] Claude Code adapter registered
62
- - [FAIL] 2 hook scripts not executable
63
- - ~/.claude/hooks/plastic-session-start
64
- - ~/.claude/hooks/plastic-record
65
-
66
- <!-- =====================================================================
67
- Repeat the above pattern for each category found in the checks array.
68
- Only include categories that have at least one check.
69
- Order categories as they appear in the checks array.
70
- ===================================================================== -->
71
-
72
- ---
73
-
74
- <!-- =====================================================================
75
- FIXABLE ISSUES SECTION
76
- ======================================================================
77
- Include this section ONLY if one or more checks have fixable=true AND
78
- status is "warn" or "fail". If no fixable issues exist, omit everything
79
- from the "Fixable Issues" heading through the end of the horizontal
80
- rule that follows the table.
81
-
82
- For each fixable check that is not "pass", emit one table row:
83
- | status_icon | check_message | fix_hint |
84
- ===================================================================== -->
85
-
86
- ### Fixable Issues
87
-
88
- | Status | Issue | Fix |
89
- |--------|-------|-----|
90
- | [FAIL] | 2 hook scripts not executable | chmod +x on the listed files |
91
-
92
- <!-- =====================================================================
93
- Repeat one row per fixable non-pass check.
94
- ===================================================================== -->
95
-
96
- ---
97
-
98
- <!-- =====================================================================
99
- FOOTER -- always include this line exactly as written.
100
- ===================================================================== -->
101
-
102
- Doctor only reports; it never fixes anything itself. Ask me to fix these issues and I will offer Fix all / Select individually / Skip, then route each chosen repair through the tool that owns it.
@@ -1,98 +0,0 @@
1
- ---
2
- name: plastic-feedback
3
- description: Use when the user hits a Plastic quirk, bug, or feature idea in a project and wants to report it back to the Plastic project. Builds a sanitized report file and a prefilled GitHub issue URL the user reviews and submits. Only the user sends.
4
- disable-model-invocation: true
5
- user-invocable: true
6
- ---
7
-
8
- # Plastic Feedback
9
-
10
- Turn a described Plastic problem into a local report file and a prefilled GitHub
11
- issue URL. The script does the mechanics (redaction, naming, URL building); the
12
- user alone opens the URL and submits it. This skill has no send step, by design.
13
-
14
- Because `disable-model-invocation` hides this skill's description from your own
15
- context, you cannot discover it by browsing available skills mid-task. If the
16
- user hits a Plastic quirk, bug, or missing feature, offer to run
17
- `/plastic-feedback` yourself; do not wait for the user to ask for it by name.
18
-
19
- ## Procedure
20
-
21
- ### 1. Gather the narrative
22
-
23
- Ask the user for:
24
- - What happened (the observed behavior).
25
- - The root cause, if they already know it.
26
- - The expected behavior.
27
-
28
- Keep it to about one page. Do not pad it with speculation; a short, accurate
29
- report beats a long, padded one.
30
-
31
- ### 2. Obfuscate before it leaves this session
32
-
33
- Before filling the template, strip anything that identifies the user's project
34
- or its content:
35
- - Remove project names, directory paths, and file names specific to the user's
36
- codebase.
37
- - Turn any Plastic intent names into their bare numeric or slug ids (drop the
38
- descriptive title if it leaks project context).
39
- - Keep only Plastic's own operational content: what Plastic did, what it should
40
- have done, which command or hook was involved.
41
-
42
- Read `references/transport-and-privacy.md` before filling the template, for the
43
- full obfuscation checklist and the reasoning behind it.
44
-
45
- ### 3. Fill the report template
46
-
47
- Read `report.md` from this skill's directory (`~/.plastic/skills/feedback/report.md`
48
- at runtime, or the plugin source `skills/feedback/report.md` during development).
49
- Fill every placeholder except `{{plastic_version}}`, which the script fills.
50
- Assemble the final markdown body from the filled template.
51
-
52
- ### 4. Run the script
53
-
54
- ```bash
55
- ruby ~/.plastic/scripts/feedback-report --title "<short title>"
56
- ```
57
-
58
- Pipe the filled body on STDIN. Parse the JSON on stdout:
59
-
60
- | Key | Meaning |
61
- |---|---|
62
- | `report_path` | Local file the full, uncapped report was written to |
63
- | `url` | Prefilled GitHub new-issue URL |
64
- | `encoded_url_bytes` | Byte length of the encoded URL |
65
- | `truncated` | Whether the URL body is a capped page-one, not the full report |
66
- | `page_break_note` | The end-marker text appended when `truncated` is true, else null |
67
-
68
- The script only ever writes a local file and prints a URL. It has no network
69
- call, no token, and no way to open a browser or submit anything on its own.
70
-
71
- ### 5. Present the result
72
-
73
- Show the user:
74
- - The local file path (`report_path`).
75
- - A short preview of the report.
76
- - The URL.
77
-
78
- If `truncated` is true, tell the user plainly: the URL carries page one of the
79
- report, and the full report is in the local file at `report_path`. They can
80
- paste more from the local file into the opened issue if they want.
81
-
82
- Then tell them, in these words or close to them: open the URL, review it, drag
83
- a screenshot onto the form if they have one, and submit it under their own
84
- GitHub account. Or, if they would rather edit first, copy the local file
85
- contents into a new issue themselves.
86
-
87
- ### 6. Never submit
88
-
89
- State plainly that this skill has no send step: it never posts to GitHub, never
90
- runs `gh issue create`, and never opens a browser on the user's behalf. The user
91
- is the only one who can submit the report.
92
-
93
- ## Gotchas
94
-
95
- - If the described report is long, the script may hand back `truncated: true`.
96
- This is expected, not an error: the local file always holds the full text.
97
- - Do not try to route around the missing send step (no `gh` call, no API POST).
98
- The absence of a send path is the point of this skill, not a gap to fill.
@@ -1,65 +0,0 @@
1
- # Transport and Privacy
2
-
3
- Read this before filling `report.md` and before presenting the URL to the user.
4
-
5
- ## Obfuscation checklist (do this before filling the template)
6
-
7
- Run through this list on the narrative gathered from the user, before it goes
8
- into `report.md`:
9
-
10
- - Strip project names. Refer to "the project" or "a consumer project", never
11
- the user's actual project name.
12
- - Strip file paths and directory names specific to the user's codebase.
13
- - Turn Plastic intent names into their bare ids. Drop the descriptive title if
14
- it names project content (an intent title like "Fix the checkout flow" leaks
15
- what the user is building; "intent 42" does not).
16
- - Keep only Plastic's own operational content: which command, hook, or skill
17
- ran, what it did, what it should have done instead.
18
- - Before presenting the URL, re-read the filled report once and confirm none
19
- of the above slipped back in.
20
-
21
- ## Mechanical redaction (what the script also strips)
22
-
23
- `scripts/lib/feedback_report.rb` redacts these patterns to `[REDACTED]` before
24
- the report ever touches disk, as a second, mechanical layer under the
25
- obfuscation above:
26
-
27
- | Secret kind | Pattern shape |
28
- |---|---|
29
- | GitHub tokens | `ghp_`, `gho_`, `ghs_`, `ghr_`, `ghu_`, `github_pat_` prefixes |
30
- | Anthropic/OpenAI keys | `sk-ant-...`, `sk-...` |
31
- | AWS access key id | `AKIA...` |
32
- | Bearer tokens | `Bearer <token>` |
33
- | Slack tokens | `xoxb-`, `xoxa-`, `xoxp-`, `xoxr-`, `xoxs-` prefixes |
34
- | Google API keys | `AIza...` |
35
- | PEM private key blocks | `-----BEGIN ... PRIVATE KEY----- ... -----END ... PRIVATE KEY-----` |
36
- | Key/value assignments | `api_key = ...`, `secret: ...`, `token = ...`, `password: ...` (value only) |
37
-
38
- Treat this list as a safety net, not the primary defense. The mechanical
39
- patterns catch a specific, known shape; the obfuscation pass above is what
40
- catches project-identifying context a regex cannot recognize.
41
-
42
- ## Why a prefilled URL, and not something else
43
-
44
- The report is sent by opening a prefilled `https://github.com/zalom/plastic/issues/new`
45
- URL in the user's own browser. Submission happens in an authenticated session
46
- that belongs to the user, not to the agent or the script. Nothing in this
47
- skill or in `feedback-report` can complete that submission on its own: there
48
- is no send method, no token, and no network call anywhere in the code path.
49
-
50
- Other transports were considered and rejected:
51
-
52
- - **`gh issue create`**: the CLI can send on its own; only `--web` is
53
- browser-submitted, and the plain form cannot be guaranteed not to send
54
- directly. It also assumes `gh` auth, which a consumer-project user may not
55
- have.
56
- - **An API POST with a token**: the agent could send it, and the token itself
57
- becomes a credential worth stealing.
58
- - **An anonymous POST endpoint**: still agent-reachable, with no built-in spam
59
- resistance, and it needs server infrastructure this project does not run.
60
- - **Email or `git send-email`**: the CLI sends the message, review is opt-in
61
- rather than forced, and it needs a working mail transport most machines do
62
- not have configured.
63
-
64
- Only the prefilled-URL approach makes "the agent cannot send" a structural
65
- fact instead of a rule the agent could break by taking a shortcut.
@@ -1,36 +0,0 @@
1
- # Plastic feedback: {{title}}
2
-
3
- <!-- =======================================================================
4
- AGENT INSTRUCTIONS -- How to fill this template
5
- =========================================================================
6
- 1. Replace every {{placeholder}} below with real content gathered from the
7
- user, except {{plastic_version}}: leave that token exactly as written,
8
- the feedback-report script fills it from the installed VERSION file.
9
- 2. Obfuscate first (see references/transport-and-privacy.md): strip project
10
- names, file paths, and anything else that identifies the user's
11
- codebase. Keep only Plastic's own operational content.
12
- 3. Keep the report to about one page. Use tables or short lists where they
13
- make the report clearer than prose.
14
- 4. Delete this entire HTML comment block before piping the body into
15
- feedback-report. It is fill instructions only, not report content.
16
- ======================================================================= -->
17
-
18
- ## Environment
19
-
20
- | Field | Value |
21
- |---|---|
22
- | Plastic version | {{plastic_version}} |
23
- | Agent | {{agent_name}} |
24
- | OS | {{os}} |
25
-
26
- ## What happened
27
-
28
- {{what_happened}}
29
-
30
- ## Root cause (if known)
31
-
32
- {{root_cause_or_not_known}}
33
-
34
- ## Expected behavior
35
-
36
- {{expected_behavior}}