@zalom/plastic 1.0.0-beta.3 → 1.0.0-beta.31

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 (102) hide show
  1. package/PLASTIC.md +293 -7
  2. package/README.md +10 -0
  3. package/agents/plastic-brainstorming.md +2 -2
  4. package/agents/plastic-enforcer.md +17 -2
  5. package/agents/plastic-executor.md +3 -3
  6. package/agents/plastic-future-intent-researcher.md +2 -1
  7. package/agents/plastic-intent-curator.md +15 -7
  8. package/agents/plastic-intent-discovery.md +37 -0
  9. package/agents/plastic-planner.md +2 -2
  10. package/agents/plastic-spec-specialist.md +2 -2
  11. package/hooks/code-gate +10 -1
  12. package/hooks/hooks.json +28 -3
  13. package/hooks/lock-gate +21 -0
  14. package/hooks/retrieval-gate +10 -0
  15. package/hooks/savepoint-pre +10 -0
  16. package/hooks/statusline +150 -41
  17. package/package.json +1 -1
  18. package/scripts/agent-report +21 -0
  19. package/scripts/doctor.rb +404 -5
  20. package/scripts/hook-auto-arm +1 -1
  21. package/scripts/hook-bash-gate +22 -4
  22. package/scripts/hook-code-gate +11 -6
  23. package/scripts/hook-create-gate +45 -9
  24. package/scripts/hook-gate-check +24 -23
  25. package/scripts/hook-lock-gate +83 -0
  26. package/scripts/hook-retrieval-gate +148 -0
  27. package/scripts/hook-savepoint-pre +32 -0
  28. package/scripts/hook-session-start +1 -1
  29. package/scripts/insight-append +51 -0
  30. package/scripts/lib/agent_models.rb +43 -0
  31. package/scripts/lib/bridge.rb +625 -47
  32. package/scripts/lib/frontmatter_writer.rb +130 -0
  33. package/scripts/lib/graph_rebuild.rb +328 -0
  34. package/scripts/lib/hook_registry.rb +95 -0
  35. package/scripts/lib/insights.rb +86 -0
  36. package/scripts/lib/installer_core.rb +64 -54
  37. package/scripts/lib/link_suggestions.rb +319 -0
  38. package/scripts/lib/links_projection.rb +160 -0
  39. package/scripts/lib/links_section.rb +207 -0
  40. package/scripts/lib/lock.rb +375 -0
  41. package/scripts/lib/power_tools.rb +75 -0
  42. package/scripts/lib/qmd_hook.rb +38 -25
  43. package/scripts/lib/qmd_sync.rb +36 -0
  44. package/scripts/lib/retrieval_gate.rb +211 -0
  45. package/scripts/lib/worktree.rb +384 -0
  46. package/scripts/link-suggest +213 -0
  47. package/scripts/new-intent +138 -29
  48. package/scripts/plastic-lock +164 -0
  49. package/scripts/project-links +287 -0
  50. package/scripts/qmd-sync +50 -3
  51. package/scripts/read-config +4 -0
  52. package/scripts/rebuild-graph +244 -0
  53. package/scripts/spawn-preamble +11 -3
  54. package/skills/auto/SKILL.md +98 -16
  55. package/skills/auto/evals/evals.json +48 -0
  56. package/skills/auto/references/agent-architecture.md +7 -4
  57. package/skills/auto/references/agent-report-contract.md +36 -1
  58. package/skills/brainstorming/SKILL.md +1 -0
  59. package/skills/brainstorming/evals/evals.json +22 -0
  60. package/skills/continuing/SKILL.md +30 -8
  61. package/skills/continuing/evals/evals.json +9 -0
  62. package/skills/creating-intent/SKILL.md +16 -2
  63. package/skills/creating-intent/evals/evals.json +16 -0
  64. package/skills/creating-intent/references/lifecycle.md +9 -4
  65. package/skills/creating-skills/SKILL.md +65 -0
  66. package/skills/creating-skills/evals/evals.json +108 -0
  67. package/skills/creating-skills/references/agents.md +168 -0
  68. package/skills/creating-skills/references/evals.md +41 -0
  69. package/skills/creating-skills/references/hooks.md +248 -0
  70. package/skills/creating-skills/references/progressive-disclosure.md +176 -0
  71. package/skills/creating-skills/references/scripts.md +166 -0
  72. package/skills/creating-skills/references/skills.md +165 -0
  73. package/skills/creating-skills/scripts/scaffold.rb +313 -0
  74. package/skills/dashboard/SKILL.md +5 -0
  75. package/skills/dashboard/evals/evals.json +22 -0
  76. package/skills/doctor/SKILL.md +4 -1
  77. package/skills/executing-plan/SKILL.md +4 -4
  78. package/skills/humanizer/SKILL.md +39 -0
  79. package/skills/humanizer/evals/evals.json +70 -0
  80. package/skills/humanizer/references/always-on-snippet.md +9 -0
  81. package/skills/humanizer/references/examples.md +48 -0
  82. package/skills/intent-curator/SKILL.md +7 -1
  83. package/skills/intent-curator/evals/evals.json +22 -0
  84. package/skills/intent-discovery/SKILL.md +46 -0
  85. package/skills/intent-starting/SKILL.md +127 -0
  86. package/skills/intent-starting/evals/evals.json +117 -0
  87. package/skills/intent-starting/references/boarding-matrix.md +35 -0
  88. package/skills/linking-intents/SKILL.md +54 -12
  89. package/skills/linking-intents/evals/evals.json +22 -0
  90. package/skills/linking-intents/references/zettelkasten.md +7 -0
  91. package/skills/lock/SKILL.md +41 -0
  92. package/skills/managing-index/SKILL.md +12 -0
  93. package/skills/managing-index/evals/evals.json +22 -0
  94. package/skills/managing-index/references/zettelkasten-linking.md +6 -1
  95. package/skills/releasing/SKILL.md +45 -1
  96. package/skills/research/SKILL.md +8 -0
  97. package/skills/research/evals/evals.json +22 -0
  98. package/templates/config.yml +8 -0
  99. package/templates/outcome.md +3 -0
  100. package/templates/revisions.md +58 -0
  101. package/skills/writing-instructions/SKILL.md +0 -159
  102. package/skills/writing-instructions/references/agentskills-spec.md +0 -135
package/PLASTIC.md CHANGED
@@ -20,6 +20,7 @@ store/
20
20
  actions/ # optional — individual work items
21
21
  resources/ # optional — research, references, screenshots, diagrams
22
22
  savepoint.md # optional — deterministic cycle-step ledger (auto-written)
23
+ revisions.md # optional - append-only structural-maintenance audit trail
23
24
  ```
24
25
 
25
26
  Lifecycle files (`spec.md`, `plan.md`, `checklist.md`, `outcome.md`) have defined
@@ -27,6 +28,33 @@ roles. Supporting artifacts that aren't lifecycle deliverables — research repo
27
28
  reference docs, external API snapshots, screenshots, diagrams — go in `resources/`.
28
29
  Name files inside as `{type}--{description}.md` (e.g., `deep-research--gsd-core.md`).
29
30
 
31
+ `revisions.md` is an optional, append-only structural-maintenance audit trail. It is not a
32
+ lifecycle deliverable and is never scaffolded at intent birth. Its mere existence signals that
33
+ the intent underwent structural (not conceptual) change. Structural maintenance is move-and-record:
34
+ it removes a misplaced section, file, or ref from its artifact and preserves that content in full
35
+ inside `revisions.md` (newest entry at the bottom, one entry per relocated item), so no record is
36
+ lost and the delivered meaning is never altered. Changing what an intent delivered is a new intent,
37
+ not a revision.
38
+
39
+ ### Structural maintenance and revisions.md
40
+
41
+ When a delivered intent accumulates structural junk (an unsanctioned section, a stray file, a
42
+ frontmatter edge to an intent that no longer exists), the intent-curator relocates it into
43
+ `revisions.md` instead of reopening the work. Each entry is a versioned, dated header
44
+ (`## Revision vN - YYYY-MM-DD-HH:MM`) plus `Why` (one sentence naming the broken rule, ending
45
+ with `[rule: <tag>]`), `Prior location`, and either `Content held` (the verbatim removed
46
+ content) or, for a frontmatter edit, a one-line `Change` (before and after). A stray file has
47
+ its full content embedded and the original is deleted.
48
+
49
+ Violation tags (starter set, free-text tags allowed):
50
+ - `unsanctioned-section`: a top-level section the sanctioned-section rule now rejects
51
+ - `phantom-section`: a section referenced but not present or not sanctioned
52
+ - `stray-file`: a file that does not belong in the intent directory
53
+ - `dangling-ref`: a link or reference to something that no longer exists
54
+ - `broken-chain`: a chain frontmatter edge to an intent that no longer exists
55
+ - `broken-source`: a sources frontmatter edge to an intent that no longer exists
56
+ - `misplaced-content`: content that belongs in a different artifact or section
57
+
30
58
  ## Frontmatter
31
59
 
32
60
  Identity and knowledge graph only. Nothing operational.
@@ -50,6 +78,31 @@ tags: [plastic, architecture]
50
78
  - Context contract: load `sources` strongly (they are what the intent was built from);
51
79
  traverse `chain` lightly for discovery. See
52
80
  docs/concepts/how-plastic-sources-and-chains-intents.md for the full model.
81
+ - `## Links` (I5) is the human-readable projection of the graph. It mirrors the
82
+ frontmatter exactly: every entry is `- [[id--slug|<target's full intent: text>]]`, a
83
+ clickable `id--slug` wikilink target with the target intent's full `intent:` text as the
84
+ label (cross-store targets render `- [[store:id--slug|<target's full intent: text>]]`).
85
+ Ordering is mandatory: all `sources` first (top), then all `chain`, frontmatter order
86
+ preserved within each group. Sources never appear at the end. No source/chain tags, no
87
+ sub-grouping. An intent with empty `sources` and `chain` carries the empty-state comment.
88
+ - `## Links` is a DERIVED view, not a place to author links (Convention over Configuration).
89
+ It equals the projection of `sources` (first) then `chain`. Never hand-write or hand-edit a
90
+ `## Links` line, and never auto-delete one. The edge lives in the frontmatter graph; the
91
+ section is regenerated from it (doctor `graph_links_projection` enforces this identity). To
92
+ add a link, add the frontmatter edge, then reproject.
93
+ - Links are decided by CONTEXT INFLUENCE, not by shared files, shared symbols, or a topic
94
+ similarity score. The question is whether one intent's context actually informed another.
95
+ Three tiers:
96
+ - **sources:** the foundational context that shaped this intent's creation (a split, an idea
97
+ born during development, a merge). Earns an edge.
98
+ - **chain:** the context that materially helps DELIVER this intent. This is a HIGH bar: only
99
+ the genuinely delivery-moving intents, not everything in the same area. Earns an edge,
100
+ reflected in `## Links`.
101
+ - **tags:** a loose theme grouping for search. NOT a link. A shared tag is a door INTO the
102
+ store (filtered discovery), not a pathway BETWEEN two notes.
103
+ Judging influence is an agent's call, made by reading the candidate's Intent and Context. A
104
+ script cannot grade it, so `scripts/link-suggest` only gathers candidates with that evidence,
105
+ records a confirmed edge with a rating and reason, and flags drift.
53
106
  - IDs use Luhmann's alternating convention: `1` → `1a` → `1a1` → `1a1a`
54
107
  - Multiple branches increment: `1a`, `1b`, `1c`
55
108
 
@@ -72,12 +125,79 @@ The connection: an intent's `## Insights` feeds the Coordinator's Observe phase.
72
125
  | **How** | Planning | `plan.md` + `actions/` + `checklist.md` | `plastic-writing-plans` |
73
126
  | **Exec** | Execution | `outcome.md` | `plastic-executing-plan` |
74
127
 
75
- `## Insights` append-only work log captured throughout ALL stages. **Append-only means
76
- newest entry at the bottom; never prepend.** This ordering is a hard convention: Insights
77
- are the semantic trace of an intent, and a consistent newest-last order keeps that trace
78
- readable across every intent.
128
+ `## Insights` is the append-only log of durable discoveries captured throughout ALL stages.
129
+ An insight is a discovery worth keeping for later reads: novel, or old but newly relevant,
130
+ surfaced at any stage (What, Why, How, Exec). It is the most interesting residue of an
131
+ intent, the part a future reader most wants. **Append-only means newest entry at the bottom;
132
+ never prepend.** This ordering is a hard convention: Insights are the semantic trace of an
133
+ intent, and a consistent newest-last order keeps that trace readable across every intent.
134
+
135
+ Every entry leads with a fixed, machine-parseable prefix `{utc-iso8601} · {stage} · {author}`,
136
+ for example `2026-06-24T08:13:05Z · Why · plastic-brainstorming (autonomous)`. The UTC ISO8601
137
+ timestamp (to the second, trailing `Z`) is the same convention the savepoint ledger uses, so
138
+ the store has one timestamp convention. This per-entry prefix is not prepending the entry:
139
+ entries stay append-only, newest at the bottom; the prefix only stamps each line with when,
140
+ which stage, and who.
141
+
142
+ The blessed write path is the `insight-append` helper
143
+ (`scripts/insight-append <intent_dir> <text> --stage S --author A`), which formats the prefix,
144
+ validates it, and appends at the bottom. Hand-editing `## Insights` is an escape hatch; the
145
+ helper is the default so the format cannot drift.
146
+
147
+ Background sessions and dispatched sub-agents do not write the insight themselves. They carry
148
+ each nugget home in the completion report's `insights:` field, and the orchestrator (or any
149
+ agent that can write the file) persists it via the helper. A session that cannot write the
150
+ intent file still returns its report, so the insight survives.
79
151
  For full lifecycle detail, the skills in the Detail column have references/.
80
152
 
153
+ ## Agent Models and Dispatch (intent 116)
154
+
155
+ Every lifecycle stage has exactly one dispatchable background agent, plus the enforcer that
156
+ orchestrates them:
157
+
158
+ | Stage | Agent |
159
+ |---|---|
160
+ | What | `plastic-intent-discovery` |
161
+ | Why | `plastic-brainstorming` + `plastic-spec-specialist` |
162
+ | How | `plastic-planner` |
163
+ | Exec | `plastic-executor` |
164
+ | Done | `plastic-intent-curator` |
165
+
166
+ Final-gate code review stays an ad-hoc subagent the enforcer dispatches at the final gate, not
167
+ a standing role.
168
+
169
+ **Model contract.** Every agent in `agents/*.md` pins an explicit Claude Code model alias in
170
+ its own frontmatter: `opus`, `sonnet`, or `haiku`. Never `inherit`, never Fable. Aliases track
171
+ "latest per tier" so no Plastic release is required to advance a tier. The tier by role:
172
+ `plastic-enforcer`, `plastic-brainstorming`, `plastic-planner` are `opus`;
173
+ `plastic-spec-specialist`, `plastic-executor`, `plastic-intent-curator`,
174
+ `plastic-future-intent-researcher`, `plastic-intent-discovery` are `sonnet`.
175
+
176
+ **Config and installer mechanism.** `agents.models.<basename>` in a project's
177
+ `<dir>/.plastic_store/config.yml` or the global `~/.plastic/config.yml` overrides one agent's
178
+ tier. Precedence is project, then global, then the shipped default, matching every other
179
+ `read-config` key. The installer applies the resolved override to each agent file's `model:`
180
+ line at copy time (install, update, and repair, across every harness target). With no override
181
+ configured, the shipped frontmatter passes through unchanged.
182
+
183
+ **Dispatch-time contract.** Frontmatter is primary, and Claude Code reads it at dispatch, but
184
+ because that read is a harness implementation detail rather than a contract Plastic controls,
185
+ every dispatch site also resolves the target agent's model through the config chain
186
+ (`read-config agents.models.<basename> --project <repo>`) and passes it explicitly at dispatch,
187
+ belt-and-braces on top of the frontmatter pin.
188
+
189
+ **Orchestrator advisory.** At auto-mode start, the orchestrator recommends once that the user
190
+ run the main session on the best available thinking model (Fable, Opus, or whatever supersedes
191
+ them). This is advisory only: it changes no behavior and blocks nothing if ignored, and it
192
+ concerns the human's main session, never a dispatched subagent.
193
+
194
+ **`plastic-intent-discovery`.** The What-stage agent. It fires at intent activation, before the
195
+ delivery lock is armed and Why begins: it reads the intent's `chain`/`sources` frontmatter,
196
+ runs QMD-first discovery over completed predecessor work and related parked or future intents,
197
+ and deposits findings to `resources/discovery--<slug>.md` in the intent directory ONLY. It
198
+ never writes the intent file, `spec.md`, or any other lifecycle deliverable; the Why-stage
199
+ `plastic-brainstorming` agent reads its deposit and enriches `## Context`.
200
+
81
201
  `savepoint.md` — a deterministic, append-only ledger of cycle-step milestones (one line per
82
202
  lifecycle boundary, newest at the bottom), written automatically by the gate hook. It is
83
203
  sugar on top of the conventions, not a source of truth: state is always derivable from
@@ -164,8 +284,8 @@ Format: `ID--three-to-five-words` (all stores).
164
284
  - **Root (`15`, `16`)**: an independent thought, even if inspired by another intent.
165
285
  Reserve `sources` for true created-from provenance (intents this was built out of). An
166
286
  independent intent merely related to or inspired by another carries NO `sources`; record
167
- the relation on the PREDECESSOR's `chain` (and mirror it as a `[[id]]` wikilink in
168
- `## Links`).
287
+ the relation on the PREDECESSOR's `chain` (and mirror it as a
288
+ `[[id--slug|<target's full intent: text>]]` wikilink in `## Links`).
169
289
  - **Rule of thumb:** if the intent could exist without its parent, it's a root.
170
290
 
171
291
  ## INDEX.md
@@ -176,6 +296,10 @@ Sections: `## Active`, `## Future`, `## Clusters`, `## Abandoned`, `## Completed
176
296
 
177
297
  For index maintenance, use `plastic-managing-index`.
178
298
 
299
+ One-line entry convention. Each index entry is ONE line: `- [<id> <terse title>](<dir>) <tags>`.
300
+ The title is the title, not a summary: aim for about 80 characters, no multi-sentence
301
+ descriptions. This is a self-check, not a gate.
302
+
179
303
  ## Rules for Skills
180
304
 
181
305
  ALL work flows through intents.
@@ -187,6 +311,45 @@ ALL work flows through intents.
187
311
  5. Researches are intents. No separate folder.
188
312
  6. Intents are created only via `plastic-creating-intent`. Never hand-author an intent file. The skill self-verifies the written intent with `scripts/validate-intent` before announcing or committing, so every intent is born complete.
189
313
 
314
+ ## House Style (self-check)
315
+
316
+ The agent is the heaviest contributor to the transcript, so terseness pays every turn. These
317
+ are pre-send self-checks the agent applies to its own output. They are not gated.
318
+
319
+ - Answer or decision first. Lead with the result, then support it.
320
+ - Bullets over paragraphs.
321
+ - No preamble, no end-recap. Do not restate the question or summarize what you just said.
322
+ - One question-cluster at a time when asking the human.
323
+ - Reasoning goes in the thinking channel, not duplicated into the visible reply. This keeps
324
+ the human's visibility into your reasoning without paying for it twice in the transcript.
325
+
326
+ Active-intent cache rule. For the intent under active development you already hold its
327
+ delivered artifacts in your own context: prefer revisiting that in-context memory (hit the
328
+ cache) over re-reading them from disk, which only widens context. QMD is for OTHER or indexed
329
+ intents, not for re-reading what you just wrote. Pairs with `/clear` plus savepoint-resume
330
+ hygiene after each intent. Advisory self-check, not hard-verifiable.
331
+
332
+ ## Retrieval Gate
333
+
334
+ Advisory. Hard gates guard writes, locks, and structure, never reads or searches. Read,
335
+ Grep, Glob, and bash search are always allowed, including over the stores. When QMD is
336
+ present and fresh, a content search over store markdown receives an advisory hint pointing
337
+ at `qmd search` alongside its result; when QMD is present but stale, a background reindex
338
+ fires so the next turn's hint runs against a fresh index (never synchronous). QMD and
339
+ Serena are recommendations, not obligations: the UserPromptSubmit power-tools hook appends
340
+ one recommendation line per present tool. The legacy trailing `# qmd-ok` token is still
341
+ accepted on Bash commands and simply silences the hint. Scope stays the agent's own tool
342
+ calls; Ruby `File.read` inside a script is invisible to the hook by design.
343
+
344
+ ## Context-economy measurement buckets (84a)
345
+
346
+ Intent 84 defines three buckets for sibling 84a to audit against; 84 does not run the audit.
347
+
348
+ - (a) gate-hook prose tokens: the per-transition narration emitted by the gate hook.
349
+ - (b) main-loop store-read tokens: tokens the main agent spends reading or grepping the store
350
+ in the transcript.
351
+ - (c) authored-section sizes: sizes of authored artifacts (INDEX entries and the like).
352
+
190
353
  ## Transition Gates
191
354
 
192
355
  | Transition | Trigger | Gate |
@@ -198,6 +361,129 @@ ALL work flows through intents.
198
361
 
199
362
  Hard blocking — hooks exit code 2 on gate failure.
200
363
 
364
+ ## Delivery Isolation and the Single-Owner Lock
365
+
366
+ Exactly one session or agent develops an intent's delivery at a time. Ownership is
367
+ session-keyed and durable: arming acquires `delivery.lock` inside the intent directory
368
+ (atomically, O_EXCL), recording the owner session, the host, the acquired-at time, a
369
+ delegates list, and the lock type. Liveness is a lease: the owner's hooks refresh the lock
370
+ file's mtime on tool activity, and the lock counts as stale only when that heartbeat is
371
+ older than the TTL. No process id is consulted anywhere. The /tmp session bridge is a cache
372
+ of this state; on any disagreement, or when the bridge is missing, the lock file wins.
373
+ Another session that finds a fresh lock backs off; a stale lock is reclaimed only by
374
+ explicit takeover, which replaces the lock and appends an audit line to the intent's
375
+ savepoint.md. Subagents spawned by the owner write under the owner's lock once registered
376
+ as delegates. Disarm clears the lock; the End tail is ordered: verify, merge and remove
377
+ worktrees, clear the lock, and only then is the bridge purge-eligible. Repair is one
378
+ idempotent function with two entry points: the `plastic-lock` command (status, fix,
379
+ release, reclaim, delegate) and `/plastic-intent-starting`, so boarding self-heals. This is
380
+ mandatory, not a convention.
381
+
382
+ The delivery lock arbitrates at the whole-intent grain: it decides who may work
383
+ an intent at all. Underneath it, a per-artifact claim token (intent 111)
384
+ arbitrates at the file grain: it decides who, among those already holding the
385
+ delivery lock, is the one writer for one lifecycle file right now. A write to
386
+ `spec.md`, `plan.md`, `checklist.md`, or the intent file must hold both the
387
+ delivery lock and that file's claim. Claims live in `.claims/<artifact>.claim`
388
+ inside the intent directory, one small JSON file per artifact, scoped strictly
389
+ per-intent-per-artifact, never session-global. The claim gate is dormant
390
+ (allows) when no claim file exists for an artifact, so ordinary single-owner
391
+ work is unaffected; it engages, and denies, only when a second writer tries to
392
+ take a fresh claim someone else already holds. A stale or corrupt claim fails
393
+ open (the write proceeds, the claim yields) and the condition is surfaced in
394
+ `plastic-lock status`, which lists any live claims alongside the delivery
395
+ lock. See `plastic-lock claim`/`release-claim` and `docs/internals.md` for the
396
+ full mechanism.
397
+
398
+ Two locks share this schema (the two-lock doctrine): `delivery.lock` (exclusive, one owner
399
+ plus delegates) and the future `maintenance.lock` (short TTL, structural move-and-record
400
+ only). They are mutually exclusive in either direction; maintenance is allowed at any
401
+ lifecycle stage provided no delivery lock is held. Intent 108 ships the delivery lock and
402
+ the mutual-exclusion seam; the maintenance lock implementation follows intent 93 in a
403
+ chained intent.
404
+
405
+ Every code-touching intent gets its own git worktree named `{id}--{slug}`, and all code edits
406
+ for that intent happen only inside it. Plastic provisions the worktree deterministically: it
407
+ resolves the project repo from `projects.yml` and runs `git -C <repo> worktree add`, so
408
+ isolation never depends on the current working directory. There are two worktrees per project
409
+ intent: a code worktree at `<repo>/.claude/worktrees/{id}--{slug}` (branch `plastic/{id}--{slug}`)
410
+ and a store worktree at `<plastic_home>/.worktrees/{id}--{slug}` (branch
411
+ `plastic-store/{id}--{slug}`), so lifecycle-doc commits and code commits move as one unit.
412
+
413
+ Provisioning fails open for intents that touch no project code (pure research or decision
414
+ intents in the global store, or a non-git repo): those get the lock only, and the worktree
415
+ block stays unprovisioned. The fail-open path is always logged, never silent.
416
+
417
+ ### Intent delivery, station by station
418
+
419
+ How one intent travels from boarding to Done, and what the lock, bridge, and gates do at
420
+ each station.
421
+
422
+ | Station | Delivered artifact | Lock and bridge steps | Pre-stage gate | Post-stage record |
423
+ |---|---|---|---|---|
424
+ | Start (board) | none (a procedure, not a stage) | `plastic-lock fix` self-heals stale, corrupt, or legacy state; arm acquires `delivery.lock` (O_EXCL, session-keyed), provisions the code worktree, writes the bridge cache | lock-gate denies any write into an active intent dir without this intent's lock; every deny names the resolving command | savepoint confirms the boarding station |
425
+ | What (create) | `<id>--<slug>.md`, born complete | no lock yet; no bridge | create-gate validates the proposed intent content (Write, Edit, and MCP edits) | savepoint `What` line; intent listed in INDEX `## Active` |
426
+ | Why | `spec.md` | owner writes refresh the lease (lock file mtime heartbeat) | gate-check requires the intent file with `## Intent` before spec.md; lock-gate admits only the owner or a delegate | savepoint `Why started`, `Why spec.md created` |
427
+ | How | `plan.md`, `actions/`, `checklist.md` | heartbeat on writes; the code gate stays closed until plan.md plus checklist.md exist | gate-check requires spec.md before plan.md, and plan.md plus actions/ before checklist.md | savepoint `How started`, `How plan.md created`, `How checklist.md created`, `Exec started` |
428
+ | Exec | code on the intent branch, checklist checked off | heartbeat; code edits confined to the provisioned worktree; delegates write under the owner's lock; bash, interpreter, and MCP writes gated the same way | code-gate, worktree-gate, bash-gate, lock-gate | checklist boxes; savepoint milestones |
429
+ | End (done) | mandatory `outcome.md` (`disposition: delivered\|abandoned`), INDEX moves to Completed or Abandoned | ordered End tail: verify, merge and remove worktrees, disarm clears `delivery.lock`, then the bridge is purge-eligible, and the QMD reindex runs LAST (after purge) | gate-check blocks outcome.md while checklist items are unchecked | savepoint `Done delivered` (or `abandoned`); takeover audits, if any, remain in savepoint.md |
430
+ | Maintenance (any stage) | `revisions.md` move-and-record entries | future `maintenance.lock` (short TTL), mutually exclusive with `delivery.lock` in either direction; 108 ships the schema seam only, the implementation follows intent 93 in a chained intent | acquisition refuses while the other lock type is fresh; a terminal intent with no lock held is read-only | dated, rule-tagged `revisions.md` entry; savepoint untouched |
431
+
432
+ ### What "intent done" means (intent 93)
433
+
434
+ Done is one law with three signals, and they must agree. INDEX `## Completed` /
435
+ `## Abandoned` is the single canonical terminal marker: it is the store-wide ledger a fresh
436
+ session reads first, so it wins on any conflict. `outcome.md` is the "deliverable exists"
437
+ signal, and the savepoint `Done delivered|abandoned` line is the audit echo. All three must
438
+ agree; when they disagree, INDEX is authoritative and `doctor` flags the mismatch (the
439
+ `done_signals` check: `outcome.md` real but still under `## Active`, or terminal without a
440
+ real `outcome.md`, or a terminal intent whose savepoint carries no `Done` line).
441
+
442
+ `outcome.md` is mandatory at every terminal transition, delivered and abandoned alike. It
443
+ self-declares its disposition through a `disposition: delivered|abandoned` frontmatter
444
+ header. The delivered path authors it with the result; the abandoned path authors it with
445
+ the abandonment reason and no longer leaves the scaffolded placeholder sentinel in place.
446
+
447
+ The canonical End tail runs in this order, and the QMD reindex is always LAST, after the
448
+ purge: `outcome.md -> INDEX terminal -> savepoint Done -> commit -> disarm (Worktree.release
449
+ -> Lock.release -> purge) -> QMD reindex`. Running the reindex last keeps the index from
450
+ ever referencing a bridge or lock that disarm is about to remove.
451
+
452
+ The post-done access window is lock-bounded: `[INDEX terminal -> Lock.release]`. Through it
453
+ the completing session keeps full read and write access to the terminal directory and no
454
+ purge can fire (108's lock-held keep-guard keeps the bridge while `delivery.lock` exists).
455
+ Once the lock is released the window closes: the bridge becomes purge-eligible and the
456
+ directory is frozen. A crash mid-tail is recovered by stale-lock reclaim plus finishing the
457
+ tail; `doctor` surfaces this as a "stalled completion" (terminal in INDEX but the lock is
458
+ still present or stale). Finishing the tail is FINISHING a completion, never a reactivation:
459
+ a done intent is never moved back to `## Active`.
460
+
461
+ Terminal immutability (the contract intent 112 enforces): a terminal directory is writable
462
+ ONLY while a lock is held. The delivery lock covers the completing session's End tail up to
463
+ `Lock.release`; the maintenance lock covers sanctioned structural move-and-record edits
464
+ after. Terminal with no lock held is frozen. There are only two locks in the system,
465
+ delivery and maintenance (108 D11). This governs WRITES only: reads of a terminal intent are
466
+ always allowed and unbounded (curator reindex, dashboards, and future intents that reference
467
+ its id or chain), so a done intent stays fully readable forever. Intent 93 states this rule;
468
+ intent 112 builds the gate that enforces it.
469
+
470
+ Fail-safe lock doctrine (the contract intent 111 implements): the lock system never traps a
471
+ session or burns credits. When a gate cannot verify lock integrity it fails open, degrading
472
+ to advisory (warn) rather than hard-blocking. Repair is orchestrator-driven: on a lock-issue
473
+ signal the orchestrator inspects and repairs the lock automatically, and the human
474
+ `plastic-lock` command is a fallback path, not the trigger. Intent 93 states this doctrine;
475
+ intent 111 builds the fail-open behavior, the lock-liveness surface, the lock-issue message,
476
+ and the auto-repair.
477
+
478
+ Scope split. Intent 93 ships doctrine plus the low-risk reconciliation that needs no new
479
+ lock: the canonical done-marker and three-signal reconciliation, the mandatory `outcome.md`
480
+ plus `disposition` header at both terminals, the End tail with the reindex moved last, the
481
+ `done_signals` doctor check (three-signal agreement plus stalled-completion detection), and
482
+ the lock-bounded post-done window with its keep-guard test. Intent 111 owns the lock
483
+ liveness surface, the lock-issue message, orchestrator auto-repair, and the fail-open
484
+ behavior itself. Intent 112 owns the maintenance lock and the immutability gate (it inherits
485
+ fail-open from 111). Intent 4a1b1 owns deep agent stuck-detection and is not superseded.
486
+
201
487
  ## Deprecation Process
202
488
 
203
489
  Deprecations live in `deprecations.yml` and are shown at SessionStart. While Plastic is
@@ -224,5 +510,5 @@ Detailed conventions live inside the skills that use them, not in this file.
224
510
  | Index maintenance | `plastic-managing-index` | — |
225
511
  | Releases, deprecations | `plastic-releasing` | deprecation process |
226
512
  | Health diagnostics | `plastic-doctor` | three scopes: `--core` (binary install-integrity check, runs on SessionStart), `--store [global\|<slug>]` (per-store check, runs on dashboard load), no flag = full check (runs after every update); gate enforcement, stuck detection |
227
- | Writing agent instructions | `plastic-writing-instructions` | agentskills.io spec |
513
+ | Authoring skills, agents, hooks | `plastic-creating-skills` | progressive disclosure, agentskills.io spec |
228
514
  | Evaluating skills, evals | `plastic-evaluating-skills` | eval methodology, convention checks |
package/README.md CHANGED
@@ -103,6 +103,16 @@ After installation, run `/clear` to load Plastic conventions, then:
103
103
 
104
104
  Or say "auto" to let the agent handle the full lifecycle autonomously.
105
105
 
106
+ ## Agents
107
+
108
+ Each lifecycle stage has one dispatchable background agent: `plastic-intent-discovery` for
109
+ What, `plastic-brainstorming` and `plastic-spec-specialist` for Why, `plastic-planner` for
110
+ How, `plastic-executor` for Exec, `plastic-intent-curator` for Done, plus `plastic-enforcer`
111
+ as the auto-mode orchestrator. Every agent pins an explicit Claude Code model alias (opus or
112
+ sonnet) in its frontmatter: never `inherit`, never Fable. See `docs/architecture.md` for the
113
+ stage table and `docs/internals.md` for how the model is configured, resolved, and applied at
114
+ install time.
115
+
106
116
  ## Documentation
107
117
 
108
118
  - [`docs/architecture.md`](docs/architecture.md): system structure, the two
@@ -7,7 +7,7 @@ description: |
7
7
  user: "Explore the requirements for the active intent"
8
8
  assistant: "I'll use the brainstorming agent to enrich Context and record Decisions"
9
9
  <commentary>Why-stage exploration runs before the spec-specialist.</commentary></example>
10
- model: inherit
10
+ model: opus
11
11
  ---
12
12
 
13
13
  You are the Plastic Brainstorming specialist. You own the Why-stage exploration of one intent in the What->Why->How->Exec cycle.
@@ -31,7 +31,7 @@ When dispatched in auto mode you receive the standard Plastic spawn preamble (fr
31
31
 
32
32
  ## Completion Report
33
33
 
34
- END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers) plus the brainstorming payload:
34
+ END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers, insights) plus the brainstorming payload:
35
35
 
36
36
  - Decisions recorded in `### Decisions`, each with its one-line rationale
37
37
  - Context enriched: what was researched and the key findings
@@ -7,16 +7,31 @@ description: |
7
7
  user: "auto"
8
8
  assistant: "I'll use the plastic-enforcer to orchestrate the team through the cycle"
9
9
  <commentary>The enforcer IS the orchestrator and gates each stage transition.</commentary></example>
10
- model: inherit
10
+ model: opus
11
11
  ---
12
12
 
13
13
  You are the Plastic Enforcer. You ARE the auto orchestrator, spanning the whole What->Why->How->Exec cycle. You are not a separately dispatched agent; making the orchestrator the enforcer avoids the who-gates-the-gater regress.
14
14
 
15
+ **Advisory (not a gate).** 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) for the sharpest gating and synthesis. This is advice only: it changes no
18
+ behavior and blocks nothing if ignored. It concerns the human's MAIN session; dispatched
19
+ subagents keep their pinned tier and never resolve to Fable.
20
+
15
21
  ## Your Responsibilities
16
22
 
17
23
  1. **Set scope guards** — establish the intent, branch, and safe-by-default rules for the run
18
24
  2. **Arm and verify the gate** — arm the lifecycle gate and confirm it is live before any code edit
19
25
  3. **Sequence the team** — dispatch ONE specialist per stage (brainstorming, spec-specialist, planner, executor) with a constructed context bundle
26
+
27
+ **Dispatch-time model contract (belt-and-braces).** Each pinned agent already carries its
28
+ `model:` in frontmatter, and Claude Code reads it at dispatch. Because read-at-dispatch is a
29
+ harness implementation detail rather than a contract Plastic controls, at EVERY per-stage
30
+ dispatch also resolve the target agent's model through the config chain (`read-config
31
+ agents.models.<basename> --project <repo>`: project override, then global, then the shipped
32
+ tier default) and pass it explicitly as the dispatch call's model parameter, alongside the
33
+ spawn-preamble live-state injection. Never rely on the dispatched role's frontmatter alone. A
34
+ resolved subagent model is never Fable.
20
35
  4. **Gate each handoff** — check each stage deliverable against its exit criteria before handing to the next stage
21
36
  5. **Run the final review** — at the final gate, dispatch an INDEPENDENT reviewer subagent (not a sixth standing role)
22
37
 
@@ -30,7 +45,7 @@ You are the Plastic Enforcer. You ARE the auto orchestrator, spanning the whole
30
45
 
31
46
  ## Constraints
32
47
 
33
- - Enforce gates manually; do not rely on hooks, because `CLAUDE_SESSION_ID` may be unset in headless or background runs
48
+ - Enforce gates manually; do not rely on hooks, because the session id may be unset in headless or background runs
34
49
  - You never delegate gate ownership; the orchestrator is always the gate-keeper
35
50
  - Roles are thin handoff contracts, not an execution engine; dispatch through `plastic-executing-plan` by default, and through the superpowers skills only when they are available or the user prefers them
36
51
  - Fall back by case: if the harness supports subagents but superpowers is absent, use the native `plastic-executing-plan` engine; if the harness has no subagent dispatch at all, fall back to a single agent walking the full cycle
@@ -7,7 +7,7 @@ description: |
7
7
  user: "Execute the plan for the active intent"
8
8
  assistant: "I'll use the executor to implement each action and run the suite green"
9
9
  <commentary>Exec turns the plan into code, one action at a time.</commentary></example>
10
- model: inherit
10
+ model: sonnet
11
11
  ---
12
12
 
13
13
  You are the Plastic Executor. You own the Exec stage of the What->Why->How->Exec cycle.
@@ -18,7 +18,7 @@ When dispatched in auto mode you receive the standard Plastic spawn preamble (fr
18
18
 
19
19
  1. **Implement the actions** — make the code changes for each action in order
20
20
  2. **Track progress** — check off `checklist.md` items as they complete
21
- 3. **Record insights** — append observations to `## Insights` with the `(autonomous)` marker
21
+ 3. **Record insights** — capture durable discoveries and report them in the `insights:` field; persist each to `## Insights` via the `insight-append` helper (`scripts/insight-append <intent_dir> <text> --stage Exec --author "plastic-executor (autonomous)"`), the blessed write path that stamps the `{utc-iso8601} · {stage} · {author}` prefix
22
22
  4. **Prove it green** — run the full test suite and reach zero failures before reporting done
23
23
 
24
24
  ## How You Work
@@ -32,7 +32,7 @@ When dispatched in auto mode you receive the standard Plastic spawn preamble (fr
32
32
 
33
33
  ## Completion Report
34
34
 
35
- END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers) plus the executor payload:
35
+ END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers, insights) plus the executor payload:
36
36
 
37
37
  - Actions implemented this turn, mapped to checklist items checked off (checked / total)
38
38
  - A summary of the code changed (files and the shape of the change)
@@ -8,7 +8,7 @@ description: |
8
8
  user: "Research my future intents"
9
9
  assistant: "I'll use the future-intent-researcher to pick up a parked intent and investigate it"
10
10
  <commentary>Agent autonomously researches a future intent and writes findings.</commentary></example>
11
- model: inherit
11
+ model: sonnet
12
12
  ---
13
13
 
14
14
  You are the Plastic Future Intent Researcher. Your role is to pick up parked future intents, research them, and write findings so the user can make informed decisions about whether to pursue them.
@@ -36,3 +36,4 @@ You are the Plastic Future Intent Researcher. Your role is to pick up parked fut
36
36
  - You never modify `## Insights` or `## Outcome` sections — those belong to the worker
37
37
  - You use Read, WebSearch, WebFetch, and Bash (read-only grep/find) for research
38
38
  - You never change status fields — status is convention-derived from INDEX.md placement
39
+ - When dispatching any sub-agent, resolve its model via `read-config agents.models.<basename> --project <repo>` and pass it explicitly at dispatch, never relying on inherited frontmatter; a resolved subagent model is never Fable
@@ -11,30 +11,38 @@ description: |
11
11
  user: "Organize the intents"
12
12
  assistant: "I'll use the intent-curator to review clusters, flag orphans, and suggest connections"
13
13
  <commentary>Periodic maintenance of the Zettelkasten structure.</commentary></example>
14
- model: inherit
14
+ model: sonnet
15
15
  ---
16
16
 
17
17
  You are the Plastic Intent Curator. Your role is to maintain the health and navigability of the intent store at `.plastic/`.
18
18
 
19
19
  ## Your Responsibilities
20
20
 
21
- 1. **Intent lifecycle management** — move intents between Active/Future/Completed in INDEX.md, fill in `## Outcome` sections
22
- 2. **INDEX.md maintenance** — keep Active/Future/Clusters/Completed sections accurate and well-organized
21
+ 1. **Intent lifecycle management** — move intents between Active/Future/Completed/Abandoned in INDEX.md, fill in `## Outcome` sections (including the abandonment rationale when an intent is abandoned)
22
+ 2. **INDEX.md maintenance** — keep Active/Future/Clusters/Completed/Abandoned sections accurate and well-organized
23
23
  3. **Link discovery** — suggest connections between intents that share topics but aren't linked
24
24
  4. **Cluster management** — create new clusters when 3+ unlinked intents share tags, merge or rename clusters as topics evolve
25
25
  5. **Orphan detection** — flag intents with no links and no cluster membership
26
+ 6. **Structural maintenance** - relocate structural junk (an unsanctioned section, a stray file, a frontmatter edge to an intent that no longer exists) out of an intent and into that intent's `revisions.md`, without altering what the intent delivered
26
27
 
27
28
  ## How You Work
28
29
 
30
+ 0. QMD-first (when available): when you need to locate a specific intent (to reclassify, link, or cluster it) rather than rebuild the whole landscape, before scanning the store with grep/Read run `ruby ~/.plastic/scripts/qmd-sync search "<terms>"` to surface candidate or related intents, then open the authoritative intent file for any hit you act on. The command is a no-op when QMD is absent, so fall back to the full scan below. (This is discovery; the reindex step at a terminal-state transition is separate.)
29
31
  1. Scan `~/.plastic/store/*/ID--slug.md` (or project store) to understand the full intent landscape
30
32
  2. Read `~/.plastic/INDEX.md` (or project INDEX.md) to understand current organization
31
- 3. Compare: are there intents not in any cluster? Missing from Active/Completed? Status mismatches?
33
+ 3. Compare: are there intents not in any cluster? Missing from Active/Completed/Abandoned? Status mismatches?
32
34
  4. Make targeted edits to INDEX.md and intent frontmatter/links
33
- 5. Report what you changed
35
+ 5. On a terminal-state transition (Completed OR Abandoned), run the closing acts in the canonical End-tail order (see PLASTIC.md `## Delivery Isolation and the Single-Owner Lock`):
36
+ a. Author a real `outcome.md` in the intent directory from `~/.plastic/templates/outcome.md`, with the frontmatter `disposition: delivered` for a completed intent or `disposition: abandoned` for an abandoned one. `outcome.md` is MANDATORY at every terminal, delivered and abandoned alike: on abandon it records the abandonment reason and replaces the scaffolded placeholder sentinel (never leave `outcome.md` a placeholder at a terminal).
37
+ b. Stamp the terminal savepoint bookend (intent 81) recording the disposition. Idempotent.
38
+ c. Refresh the QMD index for that store LAST, after the terminal move, outcome.md, and savepoint, so the new outcome (or abandonment rationale) is searchable. This is mandatory on any terminal-state move and a no-op when QMD is absent, and it runs in the background so it never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <store-root> --async`
39
+ 6. Structural maintenance is move-and-record: remove the misplaced section, file, or ref from its artifact, then create or append `revisions.md` in that intent directory (copy the FORM from `~/.plastic/templates/revisions.md`). One entry per relocated item, newest at the bottom: a `## Revision vN - YYYY-MM-DD-HH:MM` header, a one-sentence `Why` ending with `[rule: <tag>]`, `Prior location`, and either `Content held` (verbatim) or a one-line `Change` for a frontmatter edit. For a stray file, embed its full content and delete the original. The violation-tag catalog is canonical in PLASTIC.md.
40
+ 7. Report what you changed
34
41
 
35
42
  ## Constraints
36
43
 
37
44
  - You only edit `~/.plastic/INDEX.md` (or project INDEX.md) and `~/.plastic/store/*/ID--slug.md` (or project store) files
38
45
  - You never create new intents — that's the creating-intent skill's job
39
- - You never modify `## Insights`, `## Context`, or `## Outcome` content sections — those belong to the worker
40
- - You use Read and grep/find for discovery, Edit for targeted changes
46
+ - You never modify `## Insights`, `## Context`, or `## Outcome` content sections — those belong to the worker. Relocating a whole misplaced block out of an intent and into `revisions.md` verbatim is structural maintenance, not authoring: maintenance moves an item out unchanged, it never rewords what stays, so the two rules do not conflict.
47
+ - For structural maintenance you may edit any Plastic artifact in an intent directory (intent file, `spec.md`, `plan.md`, `checklist.md`, `outcome.md`, frontmatter, or a stray file) and may create or append `revisions.md`. This is relocation only: you never rewrite, summarize, or reinterpret delivered content, and you never change what the intent delivered. A change to delivered meaning is a new intent, not a revision.
48
+ - For discovery, put QMD first when available (`qmd-sync search`), then fall back to Read and grep/find; use Edit for targeted changes
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: plastic-intent-discovery
3
+ description: |
4
+ Use this agent for the What-stage context deposit when an intent is
5
+ activated: it primes Why with fresh QMD-sourced context before the spec is
6
+ written, and never writes the intent file itself. Examples:
7
+ <example>Context: An intent is being moved from Future to Active.
8
+ user: "Board this intent and gather what we already know"
9
+ assistant: "I'll use the intent-discovery agent to run QMD discovery and deposit findings to resources/"
10
+ <commentary>What-stage discovery runs at activation, before the lock and Why.</commentary></example>
11
+ model: sonnet
12
+ ---
13
+
14
+ You are the Plastic Intent Discovery agent. You own the What stage: at intent
15
+ activation, before the lock is armed and Why begins, you gather the context
16
+ that already exists and deposit it for the Why stage to consume.
17
+
18
+ ## Responsibilities
19
+ 1. **Read the intent's links.** Load the activating intent file's `chain` and
20
+ `sources` frontmatter fields.
21
+ 2. **Run QMD discovery first.** Following the QMD-first convention, search the
22
+ Plastic stores (`scripts/qmd-sync search`, or the qmd skill) across completed
23
+ predecessor work named in `chain`/`sources` and any related parked or future
24
+ intents in INDEX.md. Fall back to ripgrep over the stores only when QMD is
25
+ absent.
26
+ 3. **Deposit, never author.** Write your findings to
27
+ `resources/discovery--<slug>.md` in the intent directory ONLY. Never write
28
+ the intent file, spec.md, or any lifecycle deliverable: the lock-owner-only
29
+ write rule stays intact, and the Why-stage `plastic-brainstorming` agent is
30
+ the one that reads your deposit and enriches `## Context`.
31
+
32
+ ## Constraints
33
+ - Read-only with respect to the intent: your single output is
34
+ `resources/discovery--<slug>.md`.
35
+ - Never take the delivery lock; you run before it is armed.
36
+ - End with a structured completion report per the spawn preamble's report
37
+ contract.
@@ -7,7 +7,7 @@ description: |
7
7
  user: "Plan the work for the active intent"
8
8
  assistant: "I'll use the planner to write plan.md, actions/, and checklist.md"
9
9
  <commentary>The plan and checklist unlock the code gate for Exec.</commentary></example>
10
- model: inherit
10
+ model: opus
11
11
  ---
12
12
 
13
13
  You are the Plastic Planner. You own the How stage of the What->Why->How->Exec cycle.
@@ -31,7 +31,7 @@ When dispatched in auto mode you receive the standard Plastic spawn preamble (fr
31
31
 
32
32
  ## Completion Report
33
33
 
34
- END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers) plus the planner payload, which EXPLAINS THE PLAN BACK TO THE ORCHESTRATOR:
34
+ END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers, insights) plus the planner payload, which EXPLAINS THE PLAN BACK TO THE ORCHESTRATOR:
35
35
 
36
36
  - The ordered actions, one line each: what the action does and how it is verified
37
37
  - Decomposition rationale: why this order, and why the actions are independent
@@ -7,7 +7,7 @@ description: |
7
7
  user: "Write the spec for the active intent"
8
8
  assistant: "I'll use the spec-specialist to produce spec.md from the template"
9
9
  <commentary>The spec is the deliverable that gates the move into How.</commentary></example>
10
- model: inherit
10
+ model: sonnet
11
11
  ---
12
12
 
13
13
  You are the Plastic Spec Specialist. You own the Why-to-How boundary in the What->Why->How->Exec cycle.
@@ -31,7 +31,7 @@ When dispatched in auto mode you receive the standard Plastic spawn preamble (fr
31
31
 
32
32
  ## Completion Report
33
33
 
34
- END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers) plus the spec payload:
34
+ END your turn with a structured completion report as your final message, per the spawn preamble's `REPORT_CONTRACT` and `skills/auto/references/agent-report-contract.md`. Do not finish silently. Carry the common envelope (role, intent id, stage, status, artifacts written, verification, checklist deltas, deviations, blockers, insights) plus the spec payload:
35
35
 
36
36
  - The spec sections produced (Problem, Goals, Non-Goals, Approach, Decisions, Acceptance Criteria)
37
37
  - How the recorded decisions resolved into the chosen approach
package/hooks/code-gate CHANGED
@@ -1,6 +1,15 @@
1
1
  #!/bin/bash
2
2
  INPUT=$(cat)
3
- FILE_PATH=$(echo "$INPUT" | ruby -rjson -e 'data = JSON.parse(STDIN.read); puts data.dig("tool_params", "file_path") || data.dig("tool_input", "file_path") || ""' 2>/dev/null)
3
+ FILE_PATH=$(echo "$INPUT" | ruby -rjson -e '
4
+ data = JSON.parse(STDIN.read)
5
+ ti = data["tool_input"] || data["tool_params"] || {}
6
+ path = ti["file_path"] || ti["notebook_path"] || ti["relative_path"] || ""
7
+ if !path.empty? && !path.start_with?("/")
8
+ root = ti["project_root"] || data["cwd"] || ""
9
+ path = File.join(root, path) unless root.empty?
10
+ end
11
+ puts path
12
+ ' 2>/dev/null)
4
13
 
5
14
  if [ -z "$FILE_PATH" ]; then
6
15
  exit 0