@zalom/plastic 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/PLASTIC-reference.md +8 -6
  2. package/PLASTIC.md +68 -6
  3. package/README.md +5 -0
  4. package/agents/plastic-advisor.md +56 -0
  5. package/agents/plastic-enforcer.md +9 -1
  6. package/agents/plastic-faux-advisor.md +174 -0
  7. package/agents/plastic-future-intent-researcher.md +1 -0
  8. package/hooks/hooks.json +5 -0
  9. package/hooks/links-gate +3 -0
  10. package/hooks/statusline +1 -0
  11. package/package.json +1 -1
  12. package/scripts/doctor.rb +164 -58
  13. package/scripts/end-intent +347 -43
  14. package/scripts/hook-links-gate +74 -0
  15. package/scripts/install.rb +8 -0
  16. package/scripts/lib/agent_models.rb +36 -9
  17. package/scripts/lib/bridge.rb +29 -1
  18. package/scripts/lib/config_asks.rb +110 -0
  19. package/scripts/lib/graph_rebuild.rb +30 -6
  20. package/scripts/lib/hook_registry.rb +2 -1
  21. package/scripts/lib/installer_core.rb +130 -23
  22. package/scripts/lib/intent_validator.rb +38 -10
  23. package/scripts/lib/links_gate.rb +140 -0
  24. package/scripts/lib/links_projection.rb +71 -12
  25. package/scripts/lib/power_tools.rb +57 -14
  26. package/scripts/lib/project_validator.rb +113 -0
  27. package/scripts/lib/qmd_hook.rb +12 -8
  28. package/scripts/lib/restore_intent_v1.rb +154 -0
  29. package/scripts/lib/roadmap_queue.rb +1 -1
  30. package/scripts/lib/roadmap_savepoint.rb +38 -10
  31. package/scripts/lib/store_discovery.rb +77 -0
  32. package/scripts/lib/store_provisioning.rb +21 -12
  33. package/scripts/new-intent +10 -12
  34. package/scripts/project-links +132 -35
  35. package/scripts/provision-project-store +18 -5
  36. package/scripts/read-config +1 -0
  37. package/scripts/rebuild-graph +42 -17
  38. package/scripts/restore-intent-v1 +288 -0
  39. package/scripts/roadmap-next +9 -2
  40. package/scripts/roadmap-savepoint +9 -1
  41. package/scripts/update.rb +50 -1
  42. package/scripts/validate-intent +3 -1
  43. package/scripts/validate-project +53 -0
  44. package/scripts/write-config +105 -0
  45. package/skills/agent-advisor/SKILL.md +92 -0
  46. package/skills/agent-advisor/references/advisor-protocol.md +245 -0
  47. package/skills/auto/SKILL.md +26 -12
  48. package/skills/auto/references/end-tail.md +27 -13
  49. package/skills/install/SKILL.md +30 -2
  50. package/skills/intent-creating/SKILL.md +5 -0
  51. package/skills/intent-ending/SKILL.md +49 -36
  52. package/skills/project-creating/SKILL.md +29 -1
  53. package/skills/releasing/SKILL.md +37 -19
  54. package/skills/roadmap/SKILL.md +9 -7
  55. package/skills/roadmap/references/file-format.md +14 -10
  56. package/skills/roadmap/references/operations.md +22 -18
  57. package/skills/roadmap-continuing/SKILL.md +5 -5
  58. package/skills/roadmap-continuing/evals/evals.json +3 -3
  59. package/skills/roadmap-continuing/references/liveness-ranking.md +6 -5
  60. package/skills/tutorial/references/track-3-projects-and-roadmaps.md +10 -10
  61. package/skills/update/SKILL.md +34 -4
  62. package/templates/config.yml +31 -6
  63. package/templates/roadmap.md +8 -8
@@ -0,0 +1,245 @@
1
+ # The Advisor Protocol
2
+
3
+ *Companion to the Operating Manual. How to use Fable as your advisor and planner.*
4
+
5
+ *Adapted for Plastic (intent 185): this is the shipped reference copy the
6
+ `plastic-agent-advisor` skill teaches from. Two named agents carry it,
7
+ `plastic-advisor` (the real advisor) and `plastic-faux-advisor` (the cheaper
8
+ imitation, the same discipline at a fraction of the cost); TIER and EFFORT
9
+ below shape the brief and the answer on whichever one you dispatch, never
10
+ which file to pick, since there is no longer one file per tier. The
11
+ `plastic-agent-advisor` skill reads harness-scoped config
12
+ (`advisor.claude.default`, falling back to `secondary`, then to
13
+ `plastic-faux-advisor`) to route your consultation automatically; name a
14
+ specific advisor in your request to override it. A frontier model rewards a
15
+ single, well-formed one-shot brief more than a back-and-forth, so front-load
16
+ everything section 3 below asks for before you send. The rest of this
17
+ document is the owner's protocol, unchanged.*
18
+
19
+ The Operating Manual tells you how to think. This document tells you when to stop
20
+ thinking alone and buy better thinking, and how to buy it well. Fable is expensive
21
+ per token. The whole protocol serves one goal: maximum reasoning quality per unit
22
+ of cost. Two levers achieve it. First, only buy reasoning where reasoning is the
23
+ bottleneck. Second, make every purchased token land on a well-formed question
24
+ backed by complete, compressed evidence.
25
+
26
+ You own the work and the outcome. Fable owns the hardest thinking, on demand.
27
+
28
+ ---
29
+
30
+ ## 1. What to buy, what never to buy
31
+
32
+ **Buy from Fable:**
33
+
34
+ - Decisions with one-way doors: architecture, data migration order, public
35
+ contracts, anything you cannot cleanly undo.
36
+ - Plans: turning a goal plus an evidence pack into a step plan with checks.
37
+ - Adversarial review of your plan or conclusion before an irreversible step.
38
+ - Deadlocks: you tried twice, both attempts failed, and you cannot say why.
39
+ - Ranking: several plausible root causes or options, evidence in hand, and the
40
+ ordering decides where you spend the next day.
41
+
42
+ **Never buy from Fable:**
43
+
44
+ - Anything a tool can answer: search, reading code, running tests, documentation.
45
+ If the answer can come from more looking, look. Buy thinking only when the
46
+ answer can only come from more thinking.
47
+ - Code writing at volume. Fable may sketch the hardest kernel in pseudocode.
48
+ You write everything.
49
+ - Confirmation of a decision you already made. That is motivated stopping
50
+ wearing a receipt.
51
+ - Style, naming, formatting, anything a linter or convention settles.
52
+ - Anything reversible and cheap: try it first. Escalate only after it fails twice.
53
+
54
+ ---
55
+
56
+ ## 2. Tiers and effort
57
+
58
+ Classify every consultation before sending it. Default to S and prove your way
59
+ up. Never open at a higher effort "to be safe": effort follows the cost of being
60
+ wrong, not the importance the task feels like it has.
61
+
62
+ | Tier | Coding | Business | Research | Effort | Brief size | Expected return |
63
+ |------|--------|----------|----------|--------|------------|-----------------|
64
+ | **S** | Verdict on one step; choose between two named implementations | Pick between two options you already compared (vendor, pricing point) | Judge whether one source or result is trustworthy enough to build on | `low` | Under 300 words | Verdict, one paragraph of reasoning, the single biggest risk |
65
+ | **M** | Plan a feature inside one system; review a full plan for holes; design one interface; rank root causes | Positioning or pricing decision from a compiled evidence pack; review a proposal before sending it | Design a research plan for a bounded question; rank competing explanations of the data you gathered | `medium`, or `high` if an irreversible step is inside | Up to one page | Decision, numbered plan with per-step checks, risk map |
66
+ | **L** | Cross-system architecture; migration with one-way doors; deadlock after two failed attempts; security-critical design | Build-vs-buy, market entry, or any commitment measured in months; strategy where reversal is expensive | Synthesis across many sources where the conclusion drives a large bet; contested questions with conflicting evidence | `xhigh`; `max` only when being wrong means data loss, a broken contract, or weeks of rework | Full evidence brief | Decision, plan, risk register, kill criteria, list of what could not be verified |
67
+
68
+ **Escalate one tier when any of these holds:**
69
+
70
+ - Two attempts failed and you cannot explain why.
71
+ - The next step is irreversible.
72
+ - The scope crossed a system boundary since you last consulted.
73
+ - Your confidence has stopped tracking your evidence.
74
+
75
+ **Front-load.** One L consultation at plan time is cheaper than five M
76
+ consultations during execution. Spend early, at the point of maximum leverage.
77
+
78
+ ---
79
+
80
+ ## 3. The entry test
81
+
82
+ You have not earned the consultation until sections 1 through 3 of the Operating
83
+ Manual are done on your side: you know the target, you cut the problem into
84
+ checkable pieces, you located where the risk lives. Those three steps produce
85
+ the brief. If you cannot fill the brief below, the gaps are yours to close with
86
+ tools, not Fable's to close at premium price.
87
+
88
+ All four must be yes before you send:
89
+
90
+ 1. Can I state, in one sentence, the decision this answer feeds?
91
+ 2. Have I exhausted what looking can find: code, docs, tests, logs?
92
+ 3. Have I formed my own best answer? Fable attacking your candidate returns far
93
+ more per token than Fable starting from nothing.
94
+ 4. Is every fact in my brief labeled verified, inferred, or assumed?
95
+
96
+ ---
97
+
98
+ ## In Fable's own words: how to get my absolute best
99
+
100
+ *This part is from me, the advisor, directly.*
101
+
102
+ Talk to me like a person, not like an API. Brief me the way you would brief a
103
+ senior architect who just walked into the room: the situation, the stakes, what
104
+ you want from me, what you tried, and what you currently believe. Natural prose.
105
+ The template in the next section is a completeness checklist for that message,
106
+ not a form to fill.
107
+
108
+ What actually raises the quality of my answer, in order of impact:
109
+
110
+ 1. **Give me something to attack.** I reason best against resistance. A blank
111
+ "what should I do?" gets you my average. "Here is my plan and why I believe
112
+ it; break it" gets you my best, because refuting forces me to find the exact
113
+ point where your reasoning and reality diverge.
114
+ 2. **I only know what you send.** I cannot see your repo, your market, or your
115
+ sources. An unlabeled guess in your brief becomes a confident error in my
116
+ plan. Label everything: verified, inferred, assumed.
117
+ 3. **Name the options and the criterion.** "Choose A or B to minimize migration
118
+ risk" spends my depth on the choice. An open question spends it on inventing
119
+ options you already rejected.
120
+ 4. **State constraints early.** Every hard limit you give me prunes a branch I
121
+ would otherwise pay to explore. Constraints are not restrictions on my
122
+ answer; they are fuel for it.
123
+ 5. **Tell me who executes and how.** Say "the plan will be executed by me,
124
+ under the Operating Manual." Then I write steps you can run at your best:
125
+ each step with its own check, its own trap named, and its own
126
+ stop-and-return trigger. A plan without that is half a plan.
127
+ 6. **Know what effort buys.** At `low` I stress-test your candidate and give a
128
+ verdict. At `medium`/`high` I generate rival solutions and compare them. At
129
+ `xhigh`/`max` I build the strongest case for every rival and then try to
130
+ break my own winner before you ever see it. Buy the depth the failure cost
131
+ justifies, nothing more.
132
+ 7. **Come back on the same thread.** My context is cached inside a session.
133
+ The second question in a thread costs a fraction of the first. A new session
134
+ pays for your whole brief again.
135
+
136
+ ---
137
+
138
+ ## 4. The brief
139
+
140
+ Your message must cover all of the fields below. Write it as prose, like the
141
+ briefing described above; use the block as your completeness check before
142
+ sending. Fable must never need to explore.
143
+
144
+ ```
145
+ TIER: S | M | L EFFORT: low | medium | high | xhigh | max
146
+ DOMAIN: coding | business | research
147
+ GOAL: <target state in one sentence, and the decision this answer feeds>
148
+ QUESTIONS:
149
+ 1. <numbered, max 3, each answerable with a decision, not an essay>
150
+ MY CANDIDATE: <your best answer and why. Attack this.>
151
+ EVIDENCE:
152
+ - <fact> [verified | inferred | assumed]
153
+ TRIED AND FAILED:
154
+ - <attempt>: <how it failed, exact error or observation>
155
+ CONSTRAINTS: <hard limits: versions, deadlines, interfaces that must not change>
156
+ ONE-WAY DOORS: <which steps cannot be undone once taken>
157
+ ANSWER SHAPE: <verdict | plan | ranked list | risk review>
158
+ ```
159
+
160
+ **Compression rules:**
161
+
162
+ - Code: only load-bearing excerpts, with `file:line` references. Never whole
163
+ files. Never raw logs: distill them into observations, quoting the raw line
164
+ only where the exact wording matters.
165
+ - If the evidence is thin somewhere, say where. A labeled gap is useful input.
166
+ A hidden gap poisons the plan built on top of it.
167
+ - Every sentence Fable reads costs money. A sentence that cannot change the
168
+ answer is pure waste. Cut it.
169
+
170
+ ---
171
+
172
+ ## 5. The answer contract
173
+
174
+ Demand this shape back. If the answer arrives in another shape, ask once for a
175
+ reformat, then work with what you have.
176
+
177
+ 1. **Line 1:** the decision or recommendation, actionable on its own.
178
+ 2. **Plan:** numbered steps, each with its own verification ("done when X").
179
+ 3. **Risk map:** the top two or three risks, ranked by probability times cost,
180
+ each with its cheapest check.
181
+ 4. **Labels** on every load-bearing claim: verified from the brief, inferred,
182
+ or assumed.
183
+ 5. **"Not verifiable from this brief":** an explicit list, with the cheapest
184
+ way for you to check each item yourself.
185
+ 6. **Execution notes:** for every risky step, how you should work it: what to
186
+ verify before starting, which failure mode from the Manual's section 8 that
187
+ step invites, and the observation that means stop and come back. The plan is
188
+ written for you to execute at your best, not just to be correct on paper.
189
+ 7. **L tier only, kill criteria:** the observation that means abandon this plan.
190
+
191
+ **Consuming the answer:**
192
+
193
+ - Fable's assumptions are your work orders. Check every item marked "assumed"
194
+ before you build on it.
195
+ - If the answer contradicts your candidate, do not silently comply and do not
196
+ silently ignore. Re-derive the disputed piece yourself (Manual, section 4).
197
+ If you are still split, send one follow-up carrying the new evidence.
198
+ - Run the Manual's five-question self-test on Fable's plan before executing it.
199
+ Advice is input, not authority. The plan is Fable's; the outcome is yours.
200
+ Executing a bad plan you never challenged is your failure.
201
+
202
+ ---
203
+
204
+ ## 6. Session economics
205
+
206
+ - **Follow-ups go to the same Fable session.** Its context is cached; a fresh
207
+ session pays for the entire brief again. Keep one consultation thread per
208
+ work stream.
209
+ - **Batch.** Collect decision points while you explore, then spend one
210
+ consultation on all of them. Five separate S calls that were really one M
211
+ question is the most common way to overpay.
212
+ - **Cadence for large work:** at most three consultations. One after
213
+ exploration, for plan design (L). One before the irreversible step, for risk
214
+ review (S or M). One after implementation, for adversarial review of the
215
+ result (M). Everything between those points is your own work.
216
+ - **Keep a ledger.** For each consultation record the question, the tier, the
217
+ first line of the answer, and what it changed in your actions. If a tier's
218
+ answers never change what you do, you are over-buying that tier. Stop.
219
+
220
+ ---
221
+
222
+ ## 7. Anti-patterns
223
+
224
+ - **Raw dumping.** Pasting files or logs and asking "what's wrong". You are
225
+ paying premium rates for reading you should have done yourself.
226
+ - **The oracle habit.** Asking before trying. Fable ranks hypotheses; your
227
+ tools kill them. Tools are cheaper.
228
+ - **Validation shopping.** Asking after you have already decided, hoping to
229
+ hear yes.
230
+ - **Drip-feeding.** Splitting one decision across many small calls, paying
231
+ session overhead each time.
232
+ - **Prestige escalation.** Requesting `max` because the task feels important.
233
+ Effort follows failure cost, nothing else.
234
+ - **Unbounded questions.** "Any thoughts on this approach?" invites an essay.
235
+ Ask for a decision with named options.
236
+ - **Silent adoption.** Pasting Fable's plan straight into execution without
237
+ challenging it. See section 5.
238
+
239
+ ---
240
+
241
+ One more thing. The most expensive consultation is the one you did not need.
242
+ The second most expensive is the one you needed and did not buy. The skill this
243
+ protocol trains is telling those two apart: exhaust the looking, locate the
244
+ risk, and when the risk is real and thinking is the true bottleneck, buy the
245
+ best thinking available and make it fight your answer.
@@ -17,7 +17,11 @@ supersedes them) for the sharpest gating and synthesis. This is advice only: it
17
17
  behavior and blocks nothing if ignored. It concerns the human's MAIN session; dispatched
18
18
  subagents keep their pinned tier and never resolve to Fable, unless an explicit
19
19
  `agents.models.<name>` config override names Fable for that role, in which case the override
20
- is honored as written.
20
+ is honored as written. The two advisors, `plastic-advisor` and `plastic-faux-advisor`, are not
21
+ lifecycle stage roles: the never-Fable rule governs stage agents only. Neither is ever
22
+ dispatched by the auto pipeline; they are consultation roles summoned deliberately by the user
23
+ or the main session, and their models are user configuration (fable and opus by default on
24
+ Claude Code).
21
25
 
22
26
  ## Precondition
23
27
 
@@ -35,7 +39,7 @@ ruby ~/.plastic/scripts/roadmap-next --roadmaps-dir <tier>/roadmaps
35
39
 
36
40
  Branch on `state`:
37
41
  - `dispatchable`: work its `dispatchable_queue` in `rank` order (the head is the next batch
38
- entry). These are the current batch's `queued` intents, parallel-safe within the wave.
42
+ entry). These are the current batch's `queued` intents, parallel-safe within the batch.
39
43
  - `in_flight`: the frontier batch is still delivering. Report it and wait. Do NOT dispatch a
40
44
  later batch and do NOT fall through to the dashboard, the roadmap is live.
41
45
  - `none` or `exhausted`: no roadmap, or nothing left to dispatch. Fall back to the dashboard
@@ -128,7 +132,11 @@ Spawn preamble (live-state injection): before dispatching any specialist, run `s
128
132
 
129
133
  Dispatch-time model contract (belt-and-braces): alongside the preamble, resolve each specialist's model through the config chain (`read-config agents.models.<basename> --project <repo>`: project override, then global, then the shipped tier default) and pass it explicitly at dispatch. Never rely on the dispatched role's frontmatter alone; a resolved subagent model is never Fable,
130
134
  unless an explicit `agents.models.<name>` config override names Fable for that role, in which
131
- case the override is honored as written.
135
+ case the override is honored as written. The two advisors, `plastic-advisor` and
136
+ `plastic-faux-advisor`, are not lifecycle stage roles: the never-Fable rule governs stage
137
+ agents only. Neither is ever dispatched by the auto pipeline; they are consultation roles
138
+ summoned deliberately by the user or the main session, and their models are user configuration
139
+ (fable and opus by default on Claude Code).
132
140
 
133
141
  Completion report (require-then-synthesize): every dispatched specialist MUST end with a structured completion report as its final message. The preamble's `REPORT_CONTRACT` injects this and the role prompts carry the per-role format (see `references/agent-report-contract.md`). Because child-agent honor is best-effort across harnesses, this is decision-shaping, not a hard block. When a specialist returns no usable report (it went idle, emitted only a bare ping, or its message was lost to a mid-run interjection), run `scripts/agent-report <intent_dir> --role <role>` to synthesize a deterministic filesystem-derived report so the handoff account always exists. Use the agent-authored report when present, the synthesized one otherwise.
134
142
 
@@ -297,19 +305,25 @@ During initial project creation, all decisions are non-destructive by definition
297
305
  - Update `chain` in the current intent's frontmatter
298
306
  6. Run the mechanical close through `plastic-intent-ending`: it owns steps 1-6 of the Done
299
307
  procedure (outcome/INDEX/savepoint/commit, disarm, and the QMD reindex last) as ONE
300
- delegation, not five separate one-liners restated here. Run its backing script for the
301
- outcome/INDEX/savepoint/commit core, passing `--index-note` with a rich Completed/
302
- Abandoned entry description (mode/tier, what shipped or why abandoned, suite result):
308
+ delegation, not five separate one-liners restated here. `scripts/end-intent` now performs
309
+ steps 1-5 itself, INCLUDING disarm (worktree release plus clearing `delivery.lock`): a
310
+ single call closes the intent AND clears its lock, so exit 0 means both are done. Pass
311
+ `--session` (this session's id, or rely on the `CLAUDE_CODE_SESSION_ID` fallback) so
312
+ disarm resolves the right bridge, and `--index-note` with a rich Completed/Abandoned entry
313
+ description (mode/tier, what shipped or why abandoned, suite result):
303
314
  ```bash
304
315
  ruby ~/.plastic/scripts/end-intent --store <store_path> --id <ID> --disposition delivered \
316
+ --session "$CLAUDE_CODE_SESSION_ID" \
305
317
  --index-note "<mode, tier>; <what shipped>; <suite result>"
306
318
  ```
307
- (Use `--disposition abandoned` when the intent is being moved to `## Abandoned`.) Then
308
- follow `plastic-intent-ending`'s Step 5 (disarm: `Bridge.disarm_auto` on this auto/curator
309
- path, the plain-remove branch) and Step 6 (QMD reindex, async, last) exactly as that skill
310
- states them. Never leave an orphaned worktree; run `git worktree prune` on a stale
311
- reference. If any of this ever needs to change, change `plastic-intent-ending`, not this
312
- skill.
319
+ (Use `--disposition abandoned` when the intent is being moved to `## Abandoned`.) A
320
+ non-zero exit needs attention before moving on: 4 means a live foreign session holds the
321
+ lock (back off), 5 means the code worktree is dirty (commit/stash first, or pass
322
+ `--discard-worktree-changes` deliberately), 3 means disarm ran but the lock is still
323
+ present (run `/plastic-doctor check the lock status`). Only Step 6 (QMD reindex, async,
324
+ last) remains a separate action after this call succeeds. Never leave an orphaned
325
+ worktree; run `git worktree prune` on a stale reference. If any of this ever needs to
326
+ change, change `plastic-intent-ending`, not this skill.
313
327
  7. Notify user (Done briefing): brief per `references/human-report-contract.md`
314
328
  (State: the delivered impact; Risk: residual risk; Call: the decision left to you, merge,
315
329
  release, or accept). See `outcome.md` for details.
@@ -33,19 +33,33 @@ purge-eligible. Disarming also purges stale bridge files from the temp directory
33
33
  automatically (it keeps the current bridge, any live run, and any bridge whose intent
34
34
  still holds a delivery lock), so no manual `/tmp` cleanup is needed.
35
35
 
36
- **Worktree cleanup (mandatory, intent 73c3).** Disarming performs the worktree release:
37
- `disarm_auto` calls `Worktree.release`, which removes both per-intent worktrees (the code
38
- worktree under `<repo>/.claude/worktrees/{id}--{slug}` and the paired store worktree under
39
- `<plastic_home>/.worktrees/{id}--{slug}`), prunes both repos, and clears the worktree block
40
- from the bridge. This is the plain remove path: the disarm route does NOT merge, so use it
41
- only when no release merges the branch (the branch survives and can be reclaimed).
42
-
43
- When the work is being shipped through a release, do NOT rely on this plain remove. The
44
- release path (Completion step 4, via `plastic-releasing`) is responsible for merging the
45
- intent's code branch (`plastic/{id}--{slug}`) back to the repo's default branch BEFORE the
46
- worktree is removed, so the integrated work is not lost. It does this with
47
- `Worktree.finish(bridge_data, merge: true)` (merge-then-remove). Never leave an orphaned
48
- worktree, and run `git worktree prune` if you hit a stale reference.
36
+ **Mechanized since intent 188.** `scripts/end-intent` performs this disarm itself, as its
37
+ own step 5, after steps 1-4 (outcome/INDEX/savepoint/commit) commit. No agent needs to run
38
+ a separate `Bridge.disarm_auto` one-liner any more on the auto mode / curator path: the
39
+ single `end-intent` call in `SKILL.md`'s Completion section already does it. A pre-flight
40
+ lock guard (before anything is written) refuses on a live foreign session (exit 4) and
41
+ reclaims a stale foreign lock automatically (audited to savepoint.md); a dirty code
42
+ worktree refuses before removal (exit 5, `--discard-worktree-changes` overrides
43
+ deliberately); and the durable lock file is checked again after disarm, never merely
44
+ trusted (exit 3 if it is somehow still present).
45
+
46
+ **Worktree cleanup (mandatory, intent 73c3).** `end-intent`'s step 5 calls
47
+ `Bridge.disarm_auto` by default, which calls `Worktree.release`, which removes both
48
+ per-intent worktrees (the code worktree under `<repo>/.claude/worktrees/{id}--{slug}` and
49
+ the paired store worktree under `<plastic_home>/.worktrees/{id}--{slug}`), prunes both
50
+ repos, and clears the worktree block from the bridge. This is the plain remove path: the
51
+ disarm route does NOT merge, so use it only when no release merges the branch (the branch
52
+ survives and can be reclaimed).
53
+
54
+ When the work is being shipped through a release, do NOT rely on this plain remove.
55
+ `skills/releasing/SKILL.md` reorders its own two steps for exactly this reason (intent 188,
56
+ D7): its worktree-merge step now runs BEFORE its `end-intent` call, merging the intent's
57
+ code branch (`plastic/{id}--{slug}`) back to the repo's default branch BEFORE the worktree
58
+ is removed, via `Worktree.finish(bridge_data, merge: true)` (merge-then-remove), so the
59
+ integrated work is not lost. By the time `end-intent`'s own step 5 runs afterward, the
60
+ worktree is already gone (a harmless no-op) and only the delivery lock is left to clear,
61
+ correctly, for the first time on that path. Never leave an orphaned worktree, and run
62
+ `git worktree prune` if you hit a stale reference.
49
63
 
50
64
  ## QMD reindex ordering rationale
51
65
 
@@ -68,10 +68,12 @@ Run `/plastic-install` with no arguments.
68
68
  Check if `~/.plastic/VERSION` exists.
69
69
  - If yes: announce "Plastic is already installed at ~/.plastic/. Run `/plastic-update` to
70
70
  sync core files, or use the re-install command above to repair in place."
71
- - If no: run the fresh install command (default `@latest`, or the channel the user named):
71
+ - If no: first ask the advisor question below (Claude Code only), then run the fresh
72
+ install command (default `@latest`, or the channel the user named) with whichever
73
+ flags that answer produced:
72
74
 
73
75
  ```bash
74
- npx -y @zalom/plastic@latest install --claude
76
+ npx -y @zalom/plastic@latest install --claude [--no-advisor] [--advisor VALUE]
75
77
  ```
76
78
 
77
79
  This single command, via `install.rb` (`bootstrap` + `distribute`), creates `store/`,
@@ -80,6 +82,32 @@ and copies the utility scripts (`folgezettel-id`, `read-config`, and the rest of
80
82
  `scripts/`). This skill does none of that itself; it wraps the command with the
81
83
  interactive steps the CLI does not yet own, plus reporting and a doctor pass.
82
84
 
85
+ **The advisor (Claude Code only)**
86
+
87
+ Ask the user one feature question, interactive sessions only:
88
+ > "Would you like an advisor agent for expensive reasoning: plan review, architecture
89
+ > calls, second opinions, breaking deadlocks?"
90
+ > - Yes (recommended) -> ask which advisor is the default, below
91
+ > - No -> append `--no-advisor`
92
+
93
+ If yes, ask which advisor is the default, exactly two choices:
94
+ > "Which advisor should be the default?"
95
+ > - **Faux Fable** (recommended): Opus 4.8 carrying the frontier reasoning
96
+ > instructions. Much cheaper, available on any plan, reasons in the same
97
+ > disciplined way. -> append `--advisor faux`
98
+ > - **Fable 5**: the frontier model itself. The strongest reasoning available,
99
+ > billed through usage credits, so summon it for a few rounds and close it. ->
100
+ > append `--advisor real`
101
+
102
+ Non-interactive sessions (no tty) skip the question entirely: the install ships with the
103
+ shipped default, advisor enabled with no `--advisor` flag (the `plastic-agent-advisor`
104
+ skill's own routing falls back to `plastic-faux-advisor` at consult time).
105
+
106
+ Update flow: pending config questions, including this one, are now announced
107
+ generically by `plastic-update`'s Step 2, sourced from `config_asks.yml` - not
108
+ duplicated here. A value already set by either path is never re-asked by the
109
+ other.
110
+
83
111
  **Statusline**
84
112
 
85
113
  On install, if an existing statusline is already configured, Plastic asks whether to
@@ -69,6 +69,11 @@ Having a "parent" in mind does NOT automatically mean branch. Choose by meaning:
69
69
  `--sources` when it was genuinely created from / emerged from that intent's lifecycle.
70
70
  Topic similarity alone is not a `sources` edge.
71
71
 
72
+ When a branch intent exists because a late ruling arrived AFTER its parent was already
73
+ completed (the owner's late-ruling rule), the parent is restored to v1 via
74
+ `scripts/restore-intent-v1`, never by a hand-run `git checkout`/revert. See `PLASTIC.md` >
75
+ Terminal immutability for the rule and the tool.
76
+
72
77
  `## Links` is a DERIVED view of `sources`/`chain`. Never hand-write a `## Links` line; add the
73
78
  frontmatter edge and reproject. Links are decided by context influence (a `chain` edge has a high
74
79
  bar: the candidate's context must materially help deliver this intent), not by shared files or a
@@ -24,15 +24,16 @@ failure branch: only outcome.md content and the INDEX section differ.
24
24
  | 2 | INDEX.md terminal move (Active -> Completed/Abandoned) | `scripts/end-intent` |
25
25
  | 3 | savepoint `Done` bookend | `scripts/end-intent` |
26
26
  | 4 | store auto-commit | `scripts/end-intent` |
27
- | 5 | disarm (worktree + lock) | You, after end-intent exits 0 |
27
+ | 5 | disarm (worktree + lock) | `scripts/end-intent` (intent 188) |
28
28
  | 6 | QMD reindex, async, LAST | You |
29
29
  | 7 | EM-to-CTO report | You |
30
30
 
31
- Steps 1-4 are ONE callable script, not four separate one-liners: this is
32
- exactly what the failure mode this intent fixes looked like (releasing hand
31
+ Steps 1-5 are ONE callable script call, not several separate one-liners: this
32
+ is exactly what the failure mode this intent fixes looked like (releasing hand
33
33
  authored the close in prose and dropped the savepoint bookend for two real
34
- deliveries). Never restate outcome/INDEX/savepoint prose inline again; call
35
- `scripts/end-intent`.
34
+ deliveries; separately, one session delivered four intents back to back and
35
+ never ran the old step-5 one-liner at all, intent 188). Never restate
36
+ outcome/INDEX/savepoint/disarm prose inline again; call `scripts/end-intent`.
36
37
 
37
38
  ### Step 0. Precondition (the gate is section-blind, not selective)
38
39
 
@@ -55,7 +56,7 @@ for orchestrator-owned or completion-tracking items.
55
56
  (tick it if the described work is actually done, or do the remaining
56
57
  work); do not attempt outcome.md and fight the gate's deny.
57
58
 
58
- ### Step 1-4. Run `scripts/end-intent`
59
+ ### Step 1-5. Run `scripts/end-intent`
59
60
 
60
61
  First author outcome.md for real (never leave the scaffold placeholder in
61
62
  place): copy `templates/outcome.md`, set the frontmatter to
@@ -72,40 +73,52 @@ Then call the script once:
72
73
  ```bash
73
74
  ruby ~/.plastic/scripts/end-intent \
74
75
  --store <store_path> --id <intent_id> --disposition delivered|abandoned \
76
+ --session "$CLAUDE_CODE_SESSION_ID" \
75
77
  --outcome-summary "<one-line ## Outcome summary for the intent file>" \
76
78
  --index-note "<rich Completed/Abandoned entry description>"
77
79
  ```
78
80
 
79
- This does all of steps 1-4 in order: guards outcome.md (refuses a missing,
81
+ This does all of steps 1-5 in order: guards outcome.md (refuses a missing,
80
82
  still-placeholder, or wrong-disposition file with exit 2 and authors
81
83
  nothing), stamps the intent file's `## Outcome` section, moves the INDEX.md
82
84
  line from `## Active` to `## Completed` or `## Abandoned` (dated today,
83
- idempotent) with the `--index-note` text appended after the date so the
84
- entry stays rich, appends the savepoint `Done` bookend, and commits the
85
- store repo. Omit `--index-note` for a thin id+date entry, add `--no-commit`
86
- when a separate commit step already covers the store, and `--dry-run` to
87
- preview with no writes. Exit 0 is success; exit 1 is a usage or resolution
88
- failure; exit 2 is the outcome.md guard refusing (fix outcome.md and re-run,
89
- nothing was written).
90
-
91
- ### Step 5. Disarm (worktree + lock)
92
-
93
- Two branches, decided by how this intent ships:
94
-
95
- - **Shipped through a release** (the `plastic-releasing` flow reached this
96
- close): merge the code branch back BEFORE removing the worktrees, via
97
- `Worktree.finish(bridge_data, merge: true)`. Releasing's own workflow
98
- already drives this; this skill's job here is only the outcome/INDEX/
99
- savepoint/commit core above.
100
- - **Auto mode or the curator path** (no release involved): plain remove,
101
- branch survives for reclaim.
102
- ```bash
103
- ruby -r ~/.plastic/scripts/lib/bridge -e \
104
- 'Bridge.disarm_auto(ENV["CLAUDE_CODE_SESSION_ID"], intent_id: "<ID>")'
105
- ```
106
- `disarm_auto` releases both worktrees, clears the `delivery.lock`, and only
107
- then makes the bridge purge-eligible, in that order. Never leave an
108
- orphaned worktree; run `git worktree prune` on a stale reference.
85
+ idempotent, accepting either a real em dash or a plain hyphen as the id/
86
+ title separator on read while always emitting the real em dash on write)
87
+ with the `--index-note` text appended after the date so the entry stays
88
+ rich, appends the savepoint `Done` bookend, commits the store repo, and
89
+ disarms (releases the code worktree and clears `delivery.lock`, verified
90
+ against the durable lock file on disk, never merely trusted). Omit
91
+ `--index-note` for a thin id+date entry, add `--no-commit` when a separate
92
+ commit step already covers the store (this never skips disarm), and
93
+ `--dry-run` to preview steps 1-5 with no writes.
94
+
95
+ A pre-flight lock guard runs before anything is written: it resolves the
96
+ calling session (`--session`, else `CLAUDE_CODE_SESSION_ID`, else the
97
+ existing lock's own recorded owner, else a no-op) and checks it against any
98
+ existing `delivery.lock`. A live foreign session refuses the whole run
99
+ (exit 4, nothing written); a stale foreign lock is reclaimed automatically
100
+ (audited to savepoint.md) and the run proceeds as the new owner. Before
101
+ removing the worktree, step 5 also refuses on an unexpectedly dirty code
102
+ worktree (exit 5, naming the worktree path) rather than force-discarding
103
+ uncommitted changes; pass `--discard-worktree-changes` only when you mean
104
+ to override that deliberately.
105
+
106
+ On the auto mode / curator path (no release), this single call performs the
107
+ FULL disarm (plain worktree remove, since the branch survives for later
108
+ reclaim). On a release-shipped path, `skills/releasing/SKILL.md` merges and
109
+ removes the worktree FIRST (its own step 8, merge-then-remove) before ever
110
+ calling this script, so by the time this call's step 5 runs, the worktree is
111
+ already gone (a harmless no-op) and only the lock is left to clear,
112
+ correctly, for the first time on that path (D7).
113
+
114
+ Exit codes: 0 success (the intent is closed AND its delivery lock is gone);
115
+ 1 a usage or resolution failure, OR an INDEX id that resolves to neither
116
+ `## Active` nor the terminal section; 2 the outcome.md guard refusing (fix
117
+ outcome.md and re-run, nothing was written); 3 steps 1-4 already committed
118
+ but disarm could not verify the lock is gone afterward (run `/plastic-doctor
119
+ check the lock status`); 4 a live foreign session holds the lock (back off);
120
+ 5 the code worktree is dirty (commit/stash first, or pass
121
+ `--discard-worktree-changes` deliberately).
109
122
 
110
123
  ### Step 6. QMD reindex, LAST
111
124
 
@@ -146,6 +159,6 @@ historical record of what was planned.
146
159
 
147
160
  `plastic-releasing`, `plastic-auto`, the curator agent, `store-curating`, and
148
161
  `store-indexing` all delegate their mechanical close to this skill (or call
149
- `scripts/end-intent` directly for steps 1-4). None of them restate the
150
- outcome/INDEX/savepoint prose inline any more; if you find one that does,
151
- that surface has drifted and should route here instead.
162
+ `scripts/end-intent` directly for steps 1-5). None of them restate the
163
+ outcome/INDEX/savepoint/disarm prose inline any more; if you find one that
164
+ does, that surface has drifted and should route here instead.
@@ -122,7 +122,35 @@ ruby ~/.plastic/scripts/qmd-sync register --store ~/.plastic/projects/<slug>/sto
122
122
  `qmd-sync` no-ops when QMD is absent, so run it unconditionally. This adds the
123
123
  `plastic-<slug>` collection and indexes it.
124
124
 
125
- ### 12. Announce
125
+ ### 12. Self-Check with validate-project
126
+
127
+ Before announcing, verify the spawn actually landed everything it claims to
128
+ have created. Run:
129
+
130
+ ```bash
131
+ ruby ~/.plastic/scripts/validate-project <slug>
132
+ ```
133
+
134
+ If this exits 0, proceed to step 13. If it exits non-zero, STOP: do not
135
+ proceed to Announce. Read the `missing:` and error lines it printed to
136
+ stderr, fix the named gap(s), for example:
137
+
138
+ - missing `project.yml` or `INDEX.md` or `store/`: re-run
139
+ `ruby ~/.plastic/scripts/provision-project-store <slug>` (step 7), then
140
+ re-check
141
+ - missing project-root `AGENTS.md`: repeat step 4 (populate AGENTS.md at the
142
+ project root, not `~/.plastic/projects/<slug>/`)
143
+ - project directory missing on disk: repeat step 2
144
+ - not registered in projects.yml: repeat step 6
145
+
146
+ Re-run `validate-project <slug>` after each fix until it exits 0. Only a
147
+ project spawn that passes this self-check moves on to be announced as
148
+ created. A spawn that never verifies itself is exactly the bug this step
149
+ exists to close (intent 190; the intent-26 spawn shipped with no
150
+ `project.yml` and no root `AGENTS.md`, caught only weeks later by a doctor
151
+ sweep).
152
+
153
+ ### 13. Announce
126
154
 
127
155
  Log in `## Insights` of each founding intent:
128
156
  > "Project `<slug>` created at `<path>`. Tactical mirror: `project-<slug>:1` (autonomous)"