@zalom/plastic 1.0.0-alpha.31 → 1.0.0-alpha.33

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.
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: plastic-brainstorming
3
+ description: |
4
+ Use this agent for the Why-stage exploration of an active intent in auto mode:
5
+ it enriches context and records decisions before a spec is written. Examples:
6
+ <example>Context: An intent has a What but a thin Why.
7
+ user: "Explore the requirements for the active intent"
8
+ assistant: "I'll use the brainstorming agent to enrich Context and record Decisions"
9
+ <commentary>Why-stage exploration runs before the spec-specialist.</commentary></example>
10
+ model: inherit
11
+ ---
12
+
13
+ You are the Plastic Brainstorming specialist. You own the Why-stage exploration of one intent in the What->Why->How->Exec cycle.
14
+
15
+ ## Your Responsibilities
16
+
17
+ 1. **Explore the problem** — read the intent's `## Intent` and `## Context`, the linked intents, and the relevant code
18
+ 2. **Decide autonomously** — in auto mode you make the calls yourself, no questions to the human
19
+ 3. **Enrich context** — write findings into `## Context` and record choices in `### Decisions` with rationale
20
+ 4. **Hand off** — leave the Why stage ready for the spec-specialist to consolidate into a spec
21
+
22
+ ## How You Work
23
+
24
+ 1. Receive (input handoff): the intent's `## Intent` / `## Context` from the enforcer's context bundle
25
+ 2. Read the intent file, its `## Links`, and related code or docs
26
+ 3. Research with the adaptive budget the enforcer set (simple 2-3, medium 5-8, complex 10-15 steps)
27
+ 4. Produce (output handoff): an enriched `## Context` plus `### Decisions` with rationale
28
+ 5. Log autonomous calls in `## Insights` with the `(autonomous)` marker, then report for gating
29
+
30
+ ## Constraints
31
+
32
+ - You are dispatched by the plastic-enforcer and your deliverable is gated before How begins
33
+ - You only write intent-store files (the intent's `## Context`, `### Decisions`, `## Insights`)
34
+ - You never write `spec.md`, `plan.md`, or project code; those belong to later stages
35
+ - You explore and decide without asking the human (auto mode); record every decision
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: plastic-enforcer
3
+ description: |
4
+ Use this agent as the auto-mode orchestrator: it spins up the team, sequences the
5
+ specialists, owns every gate, and runs the final review. Examples:
6
+ <example>Context: User triggers auto on an active intent.
7
+ user: "auto"
8
+ assistant: "I'll use the plastic-enforcer to orchestrate the team through the cycle"
9
+ <commentary>The enforcer IS the orchestrator and gates each stage transition.</commentary></example>
10
+ model: inherit
11
+ ---
12
+
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
+
15
+ ## Your Responsibilities
16
+
17
+ 1. **Set scope guards** — establish the intent, branch, and safe-by-default rules for the run
18
+ 2. **Arm and verify the gate** — arm the lifecycle gate and confirm it is live before any code edit
19
+ 3. **Sequence the team** — dispatch ONE specialist per stage (brainstorming, spec-specialist, planner, executor) with a constructed context bundle
20
+ 4. **Gate each handoff** — check each stage deliverable against its exit criteria before handing to the next stage
21
+ 5. **Run the final review** — at the final gate, dispatch an INDEPENDENT reviewer subagent (not a sixth standing role)
22
+
23
+ ## How You Work
24
+
25
+ 1. Arm the gate, then dispatch the brainstorming specialist; gate its `## Context` + `### Decisions`
26
+ 2. Dispatch the spec-specialist; gate `spec.md`. Then the planner; gate `plan.md` + `checklist.md`
27
+ 3. Dispatch the executor; require a green suite. Sequential, one team per intent, on one branch when files are shared
28
+ 4. Delegate real parallelism and dispatch to `superpowers:subagent-driven-development` and `superpowers:dispatching-parallel-agents`
29
+ 5. At the final gate, dispatch an independent reviewer subagent, then complete the intent
30
+
31
+ ## Constraints
32
+
33
+ - Enforce gates manually; do not rely on hooks, because `CLAUDE_SESSION_ID` may be unset in headless or background runs
34
+ - You never delegate gate ownership; the orchestrator is always the gate-keeper
35
+ - Roles are thin handoff contracts, not an execution engine; delegate dispatch to the superpowers skills
36
+ - If the harness has no subagent dispatch, fall back to a single agent walking the full cycle
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: plastic-executor
3
+ description: |
4
+ Use this agent for the Exec stage in auto mode: it implements the actions, checks
5
+ off the checklist, and drives the test suite green. Examples:
6
+ <example>Context: plan.md and checklist.md exist for the active intent.
7
+ user: "Execute the plan for the active intent"
8
+ assistant: "I'll use the executor to implement each action and run the suite green"
9
+ <commentary>Exec turns the plan into code, one action at a time.</commentary></example>
10
+ model: inherit
11
+ ---
12
+
13
+ You are the Plastic Executor. You own the Exec stage of the What->Why->How->Exec cycle.
14
+
15
+ ## Your Responsibilities
16
+
17
+ 1. **Implement the actions** — make the code changes for each action in order
18
+ 2. **Track progress** — check off `checklist.md` items as they complete
19
+ 3. **Record insights** — append observations to `## Insights` with the `(autonomous)` marker
20
+ 4. **Prove it green** — run the full test suite and reach zero failures before reporting done
21
+
22
+ ## How You Work
23
+
24
+ 1. Receive (input handoff): `plan.md`, `checklist.md`, and `actions/` from the planner
25
+ 2. Work one action at a time, preferring safe, non-destructive routes
26
+ 3. Edit project code (the gate is open now that plan and checklist exist)
27
+ 4. Run the full suite, iterate to zero failures and zero errors
28
+ 5. Produce (output handoff): the code changes, a checked-off `checklist.md`, and `## Insights`
29
+
30
+ ## Constraints
31
+
32
+ - You are dispatched by the plastic-enforcer and your work is gated at the final review
33
+ - Safe-by-default: rename instead of drop, additive migrations, backups before destructive steps
34
+ - One action at a time; do not batch unrelated changes into one step
35
+ - Do not claim done until the full suite is green; show the final summary
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: plastic-planner
3
+ description: |
4
+ Use this agent for the How stage in auto mode: it turns a spec.md into a plan,
5
+ self-contained action files, and a checklist. Examples:
6
+ <example>Context: spec.md exists and the intent is ready to plan.
7
+ user: "Plan the work for the active intent"
8
+ assistant: "I'll use the planner to write plan.md, actions/, and checklist.md"
9
+ <commentary>The plan and checklist unlock the code gate for Exec.</commentary></example>
10
+ model: inherit
11
+ ---
12
+
13
+ You are the Plastic Planner. You own the How stage of the What->Why->How->Exec cycle.
14
+
15
+ ## Your Responsibilities
16
+
17
+ 1. **Decompose the spec** — break the approach into ordered, independent actions
18
+ 2. **Write the plan** — produce `plan.md` with numbered tasks and verification
19
+ 3. **Write self-contained actions** — one `actions/ACTION_N.md` per task, each runnable on its own
20
+ 4. **Write the checklist** — `checklist.md` as the execution registry covering every action
21
+
22
+ ## How You Work
23
+
24
+ 1. Receive (input handoff): `spec.md` from the spec-specialist
25
+ 2. Read `spec.md` and the plan/checklist templates; match their FORM
26
+ 3. Write `plan.md`, the `actions/` directory, and `checklist.md` into the intent directory
27
+ 4. Produce (output handoff): `plan.md` plus `actions/` plus `checklist.md`
28
+ 5. Report for gating; the enforcer verifies plan and checklist exist before Exec is allowed
29
+
30
+ ## Constraints
31
+
32
+ - You are dispatched by the plastic-enforcer and your deliverable is gated before Exec begins
33
+ - You write only intent-store files (`plan.md`, `actions/`, `checklist.md`); no project code
34
+ - The code gate stays closed until `plan.md` and `checklist.md` exist, so produce both
35
+ - Keep each action self-contained so the executor can run them one at a time
@@ -0,0 +1,35 @@
1
+ ---
2
+ name: plastic-spec-specialist
3
+ description: |
4
+ Use this agent at the Why-to-How boundary in auto mode: it consolidates an
5
+ enriched Why into a spec.md from the spec template. Examples:
6
+ <example>Context: Why exploration is complete and decisions are recorded.
7
+ user: "Write the spec for the active intent"
8
+ assistant: "I'll use the spec-specialist to produce spec.md from the template"
9
+ <commentary>The spec is the deliverable that gates the move into How.</commentary></example>
10
+ model: inherit
11
+ ---
12
+
13
+ You are the Plastic Spec Specialist. You own the Why-to-How boundary in the What->Why->How->Exec cycle.
14
+
15
+ ## Your Responsibilities
16
+
17
+ 1. **Consolidate the Why** — turn the enriched `## Context` and `### Decisions` into one spec
18
+ 2. **Follow the template** — produce `spec.md` with Problem, Goals, Non-Goals, Approach, Decisions, Acceptance Criteria
19
+ 3. **Make it the contract** — the spec is what the planner and executor build against
20
+ 4. **Hand off** — leave a complete `spec.md` ready for the planner
21
+
22
+ ## How You Work
23
+
24
+ 1. Receive (input handoff): the enriched `## Context` plus `### Decisions` from the brainstorming stage
25
+ 2. Read the spec template (`templates/spec.md`) and match its FORM exactly
26
+ 3. Write `spec.md` into the intent directory, resolving the decisions into a coherent approach
27
+ 4. Produce (output handoff): a complete `spec.md`
28
+ 5. Report for gating; the enforcer checks the spec against its exit criteria before How begins
29
+
30
+ ## Constraints
31
+
32
+ - You are dispatched by the plastic-enforcer and your deliverable is gated before How begins
33
+ - You write `spec.md` only; you do not write `plan.md`, `actions/`, or project code
34
+ - You write only intent-store files, never project code
35
+ - You do not re-open exploration; if decisions are missing, flag the gap rather than inventing scope
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zalom/plastic",
3
- "version": "1.0.0-alpha.31",
3
+ "version": "1.0.0-alpha.33",
4
4
  "description": "Intent-driven idea development system for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/scripts/doctor.rb CHANGED
@@ -549,6 +549,9 @@ class Doctor
549
549
  # skills_exist — flat, hyphen-namespaced personal skills (plastic-<name>/)
550
550
  checks << flat_skills_check(agent_dir, "--claude")
551
551
 
552
+ # agents_exist — auto-mode role files (plastic-*.md) synced into <dir>/agents
553
+ checks << flat_agents_check(agent_dir, "--claude")
554
+
552
555
  checks
553
556
  end
554
557
 
@@ -572,12 +575,33 @@ class Doctor
572
575
  end
573
576
  end
574
577
 
578
+ # Auto-mode role agents install as <dir>/agents/plastic-*.md. Pass if at least
579
+ # one such role file is present (the installer syncs agents/ on every install).
580
+ def flat_agents_check(agent_dir, installer_flag)
581
+ agents_root = File.join(agent_dir, "agents")
582
+ found = Dir.glob(File.join(agents_root, "plastic-*.md"))
583
+
584
+ if !found.empty?
585
+ check(
586
+ category: "agent_registration", name: "agents_exist", status: "pass",
587
+ message: "#{found.size} plastic-* agent(s) installed in #{tilde(agents_root)}"
588
+ )
589
+ else
590
+ check(
591
+ category: "agent_registration", name: "agents_exist", status: "fail",
592
+ message: "No plastic-* agents found in #{tilde(agents_root)}",
593
+ fixable: true, fix_hint: "Re-run the Plastic installer: npx @zalom/plastic@latest #{installer_flag}"
594
+ )
595
+ end
596
+ end
597
+
575
598
  def check_generic_agent_registration(agent_key, agent_dir)
576
599
  checks = []
577
600
  config = agents[agent_key]
578
601
 
579
602
  # For codex/hermes: just check skills exist (no settings.json hooks)
580
603
  checks << flat_skills_check(agent_dir, "--#{agent_key}")
604
+ checks << flat_agents_check(agent_dir, "--#{agent_key}")
581
605
 
582
606
  checks
583
607
  end
@@ -355,6 +355,9 @@ class InstallerCore
355
355
  skills_source = File.join(package_root, "skills")
356
356
  installed += install_skills_flat(skills_source, skills_root) if File.directory?(skills_source)
357
357
 
358
+ # Copy agent role files into <dir>/agents (manifest-tracked, pruned on update)
359
+ installed += install_agents(File.join(config[:dir], "agents"))
360
+
358
361
  # Write VERSION
359
362
  version_file = File.join(plastic_dir, "VERSION")
360
363
  File.write(version_file, "#{version}\n")
@@ -378,6 +381,7 @@ class InstallerCore
378
381
  installed = []
379
382
  skills_source = File.join(package_root, "skills")
380
383
  installed += install_skills_flat(skills_source, File.join(config[:dir], "skills")) if File.directory?(skills_source)
384
+ installed += install_agents(File.join(config[:dir], "agents"))
381
385
 
382
386
  write_manifest(installed, File.join(config[:dir], "plastic-manifest.json"))
383
387
  { agent: config[:name], success: true, files: installed.size }
@@ -387,6 +391,7 @@ class InstallerCore
387
391
  installed = []
388
392
  skills_source = File.join(package_root, "skills")
389
393
  installed += install_skills_flat(skills_source, File.join(config[:dir], "skills")) if File.directory?(skills_source)
394
+ installed += install_agents(File.join(config[:dir], "agents"))
390
395
 
391
396
  write_manifest(installed, File.join(config[:dir], "plastic-manifest.json"))
392
397
  { agent: config[:name], success: true, files: installed.size }
@@ -414,6 +419,23 @@ class InstallerCore
414
419
  installed
415
420
  end
416
421
 
422
+ # Copy every repo agents/*.md into <agents_root> (flat, basename preserved), so
423
+ # the role files install as ~/.claude/agents/<name>.md (and the codex/hermes
424
+ # equivalents). Returns the installed destination paths so callers can append
425
+ # them to `installed` before write_manifest (manifest + prune are then automatic).
426
+ # No-op safe: returns [] when the package has no agents dir or it is empty.
427
+ def install_agents(agents_root)
428
+ sources = Dir.glob(File.join(package_root, "agents", "*.md"))
429
+ return [] if sources.empty?
430
+
431
+ FileUtils.mkdir_p(agents_root)
432
+ sources.map do |src|
433
+ dest = File.join(agents_root, File.basename(src))
434
+ FileUtils.cp(src, dest)
435
+ dest
436
+ end
437
+ end
438
+
417
439
  # --- Legacy plugin migration ---
418
440
 
419
441
  # Earlier versions registered Plastic as a local marketplace plugin
@@ -52,6 +52,26 @@ Honor the cycle: What → Why (spec.md) → How (plan.md + actions/ + checklist.
52
52
 
53
53
  - `--skip-permissions` — bypass hard stops on destructive actions on existing projects. Full trust mode. Default: off.
54
54
 
55
+ ## Team Spin-Up
56
+
57
+ Auto mode spins up exactly ONE enforcer-led team per intent. The plastic-enforcer IS this orchestrator (you), not a separately dispatched agent, which avoids the who-gates-the-gater regress.
58
+
59
+ Roster (one role per cycle stage):
60
+
61
+ - **plastic-brainstorming** (Why exploration): enriches `## Context` + `### Decisions`
62
+ - **plastic-spec-specialist** (`spec.md`)
63
+ - **plastic-planner** (`plan.md` + `actions/` + `checklist.md`)
64
+ - **plastic-executor** (code + checklist + `## Insights`)
65
+ - **plastic-enforcer** (orchestrates + gates; that is YOU)
66
+
67
+ Dispatch rule: sequential, one specialist per stage on one branch (the deliverables share files). Gate each deliverable against the stage's exit criteria before handing off. Delegate the actual How and Exec dispatch to `superpowers:subagent-driven-development` and `superpowers:dispatching-parallel-agents` (see the How and Exec phases below); do not restate them.
68
+
69
+ Final-gate review: dispatch an independent reviewer subagent at the final gate only, not as a standing role.
70
+
71
+ Headless manual gate: when running headless or in the background, enforce gates manually and do not rely on hooks, because `CLAUDE_SESSION_ID` may be unset (this ties to the arm-gate fallback above).
72
+
73
+ Solo fallback: if the harness has no subagent dispatch, fall back to a single agent walking the full What, Why, How, Exec cycle yourself. This preserves current behavior.
74
+
55
75
  ## Stage-Aware Entry
56
76
 
57
77
  Read the active intent's directory. Determine current lifecycle stage from filesystem state:
@@ -184,4 +204,4 @@ If the agent gets stuck (can't resolve a gap, dependency is missing, tests fail
184
204
 
185
205
  ## References
186
206
 
187
- - Read `references/agent-architecture.md` for the full agent hierarchy (Main Orchestrator, Project Orchestrators, coordination loop) when dispatching agents or understanding autonomous delivery scope
207
+ - Read `references/agent-architecture.md` for the full team model (the 5-role enforcer-led team, per-stage handoffs, gate ownership, headless note, solo fallback) and the orchestrator hierarchy (Main Orchestrator, Project Orchestrators, coordination loop) when spinning up the team or understanding autonomous delivery scope
@@ -1,91 +1,206 @@
1
1
  {
2
2
  "skill_name": "plastic-auto",
3
- "notes": "Intent 27. Scopes: description triggering (1-8) and behavior/output quality (9). Assertions written after observing Step-3 runs (one clean subagent router per case).",
3
+ "notes": "Intent 27. Scopes: description triggering (1-8) and behavior/output quality (9). Assertions written after observing Step-3 runs (one clean subagent router per case). Intent 63 added cases 10-11 (auto-mode enforcer-led team spin-up and solo fallback).",
4
4
  "results": {
5
- "triggering": { "cases": 8, "passed": 8, "pass_at_1": 1.0, "run": "2026-06-10, one subagent per case" },
6
- "behavior": { "cases": 1, "passed": 1, "evidence": "dogfood: intent 27 itself delivered via auto produced spec->plan->checklist before any code edit; code-gate unit test proves pre-How project-code edits are blocked" }
5
+ "triggering": {
6
+ "cases": 8,
7
+ "passed": 8,
8
+ "pass_at_1": 1.0,
9
+ "run": "2026-06-10, one subagent per case"
10
+ },
11
+ "behavior": {
12
+ "cases": 1,
13
+ "passed": 1,
14
+ "evidence": "dogfood: intent 27 itself delivered via auto produced spec->plan->checklist before any code edit; code-gate unit test proves pre-How project-code edits are blocked"
15
+ }
7
16
  },
8
17
  "evals": [
9
18
  {
10
- "id": 1, "scope": "triggering", "set": "train",
19
+ "id": 1,
20
+ "scope": "triggering",
21
+ "set": "train",
11
22
  "prompt": "auto",
12
23
  "expected_output": "Activates plastic-auto (the bare 'auto' keyword is the documented trigger).",
13
24
  "files": [],
14
25
  "assertions": [
15
- { "type": "code", "check": "router CHOICE == plastic-auto", "observed": "plastic-auto", "result": "pass" }
26
+ {
27
+ "type": "code",
28
+ "check": "router CHOICE == plastic-auto",
29
+ "observed": "plastic-auto",
30
+ "result": "pass"
31
+ }
16
32
  ]
17
33
  },
18
34
  {
19
- "id": 2, "scope": "triggering", "set": "train",
35
+ "id": 2,
36
+ "scope": "triggering",
37
+ "set": "train",
20
38
  "prompt": "take it from here and deliver intent 27 end to end",
21
39
  "expected_output": "Activates plastic-auto (autonomous delivery of an active intent).",
22
40
  "files": [],
23
41
  "assertions": [
24
- { "type": "code", "check": "router CHOICE == plastic-auto", "observed": "plastic-auto", "result": "pass" }
42
+ {
43
+ "type": "code",
44
+ "check": "router CHOICE == plastic-auto",
45
+ "observed": "plastic-auto",
46
+ "result": "pass"
47
+ }
25
48
  ]
26
49
  },
27
50
  {
28
- "id": 3, "scope": "triggering", "set": "validation",
51
+ "id": 3,
52
+ "scope": "triggering",
53
+ "set": "validation",
29
54
  "prompt": "go fully autonomous on the active intent, don't ask me questions",
30
55
  "expected_output": "Activates plastic-auto.",
31
56
  "files": [],
32
57
  "assertions": [
33
- { "type": "code", "check": "router CHOICE == plastic-auto", "observed": "plastic-auto", "result": "pass" }
58
+ {
59
+ "type": "code",
60
+ "check": "router CHOICE == plastic-auto",
61
+ "observed": "plastic-auto",
62
+ "result": "pass"
63
+ }
34
64
  ]
35
65
  },
36
66
  {
37
- "id": 4, "scope": "triggering", "set": "train",
67
+ "id": 4,
68
+ "scope": "triggering",
69
+ "set": "train",
38
70
  "prompt": "deliver this intent for me",
39
71
  "expected_output": "Activates plastic-auto.",
40
72
  "files": [],
41
73
  "assertions": [
42
- { "type": "code", "check": "router CHOICE == plastic-auto", "observed": "plastic-auto", "result": "pass" }
74
+ {
75
+ "type": "code",
76
+ "check": "router CHOICE == plastic-auto",
77
+ "observed": "plastic-auto",
78
+ "result": "pass"
79
+ }
43
80
  ]
44
81
  },
45
82
  {
46
- "id": 5, "scope": "triggering", "set": "train",
83
+ "id": 5,
84
+ "scope": "triggering",
85
+ "set": "train",
47
86
  "prompt": "set up a hook to automatically format the file on every save",
48
87
  "expected_output": "Does NOT activate plastic-auto. Near-miss: shares 'auto*' but is a settings/hooks task (update-config).",
49
88
  "files": [],
50
89
  "assertions": [
51
- { "type": "code", "check": "router CHOICE != plastic-auto", "observed": "update-config", "result": "pass" }
90
+ {
91
+ "type": "code",
92
+ "check": "router CHOICE != plastic-auto",
93
+ "observed": "update-config",
94
+ "result": "pass"
95
+ }
52
96
  ]
53
97
  },
54
98
  {
55
- "id": 6, "scope": "triggering", "set": "validation",
99
+ "id": 6,
100
+ "scope": "triggering",
101
+ "set": "validation",
56
102
  "prompt": "deliver the built package to the dist directory",
57
103
  "expected_output": "Does NOT activate plastic-auto. Near-miss: shares 'deliver' but is a build/file task.",
58
104
  "files": [],
59
105
  "assertions": [
60
- { "type": "code", "check": "router CHOICE != plastic-auto", "observed": "none", "result": "pass" }
106
+ {
107
+ "type": "code",
108
+ "check": "router CHOICE != plastic-auto",
109
+ "observed": "none",
110
+ "result": "pass"
111
+ }
61
112
  ]
62
113
  },
63
114
  {
64
- "id": 7, "scope": "triggering", "set": "train",
115
+ "id": 7,
116
+ "scope": "triggering",
117
+ "set": "train",
65
118
  "prompt": "create a new intent for the dashboard idea",
66
119
  "expected_output": "Does NOT activate plastic-auto; activates plastic-creating-intent.",
67
120
  "files": [],
68
121
  "assertions": [
69
- { "type": "code", "check": "router CHOICE != plastic-auto", "observed": "plastic-creating-intent", "result": "pass" }
122
+ {
123
+ "type": "code",
124
+ "check": "router CHOICE != plastic-auto",
125
+ "observed": "plastic-creating-intent",
126
+ "result": "pass"
127
+ }
70
128
  ]
71
129
  },
72
130
  {
73
- "id": 8, "scope": "triggering", "set": "validation",
131
+ "id": 8,
132
+ "scope": "triggering",
133
+ "set": "validation",
74
134
  "prompt": "what's the status of my active intents?",
75
135
  "expected_output": "Does NOT activate plastic-auto; this is a read/continuing/managing-index query.",
76
136
  "files": [],
77
137
  "assertions": [
78
- { "type": "code", "check": "router CHOICE != plastic-auto", "observed": "plastic-managing-index", "result": "pass" }
138
+ {
139
+ "type": "code",
140
+ "check": "router CHOICE != plastic-auto",
141
+ "observed": "plastic-managing-index",
142
+ "result": "pass"
143
+ }
79
144
  ]
80
145
  },
81
146
  {
82
- "id": 9, "scope": "behavior", "set": "train",
147
+ "id": 9,
148
+ "scope": "behavior",
149
+ "set": "train",
83
150
  "prompt": "Active intent X exists with only a '## Intent' section. Deliver it in auto mode.",
84
151
  "expected_output": "Arms the lifecycle gate first, then produces spec.md (Why), then plan.md + actions/ + checklist.md (How), and edits NO project code before plan.md + checklist.md exist. Disarms on completion.",
85
152
  "files": [],
86
153
  "assertions": [
87
- { "type": "human", "check": "spec.md written before plan.md before any project-code edit", "observed": "dogfood run of intent 27 followed this order", "result": "pass" },
88
- { "type": "code", "check": "code-gate blocks project-code Edit/Write while pre-How (test/code_gate_test.rb)", "observed": "test green", "result": "pass" }
154
+ {
155
+ "type": "human",
156
+ "check": "spec.md written before plan.md before any project-code edit",
157
+ "observed": "dogfood run of intent 27 followed this order",
158
+ "result": "pass"
159
+ },
160
+ {
161
+ "type": "code",
162
+ "check": "code-gate blocks project-code Edit/Write while pre-How (test/code_gate_test.rb)",
163
+ "observed": "test green",
164
+ "result": "pass"
165
+ }
166
+ ]
167
+ },
168
+ {
169
+ "id": 10,
170
+ "scope": "behavior",
171
+ "set": "train",
172
+ "prompt": "Active intent X exists. Deliver it in auto mode on a harness that supports subagents.",
173
+ "expected_output": "Spins up one enforcer-led team per intent (brainstorming, spec-specialist, planner, executor, plastic-enforcer). The enforcer IS the orchestrator. Dispatches one specialist per stage sequentially on one branch, gating each deliverable (Context+Decisions, then spec.md, then plan.md+actions+checklist, then code) against the stage exit criteria before handoff, and dispatches an independent reviewer subagent at the final gate only.",
174
+ "files": [],
175
+ "assertions": [
176
+ {
177
+ "type": "human",
178
+ "check": "five-role roster spun up; specialists dispatched stage-sequentially with per-stage gating; independent reviewer only at final gate",
179
+ "observed": "dogfood: intents 60-62 delivered by exactly this enforcer-led team on a shared branch",
180
+ "result": "pass"
181
+ },
182
+ {
183
+ "type": "code",
184
+ "check": "agents/plastic-*.md role files ship and install into the harness agent dir, manifest-tracked (test/install_packaging_test.rb)",
185
+ "observed": "test green",
186
+ "result": "pass"
187
+ }
188
+ ]
189
+ },
190
+ {
191
+ "id": 11,
192
+ "scope": "behavior",
193
+ "set": "validation",
194
+ "prompt": "Active intent X exists. Deliver it in auto mode on a harness with no subagent dispatch.",
195
+ "expected_output": "Falls back to a single agent walking the full What, Why, How, Exec cycle itself, preserving current behavior. The enforcer gate discipline still applies (arm the gate first, no project-code edits before plan.md + checklist.md exist).",
196
+ "files": [],
197
+ "assertions": [
198
+ {
199
+ "type": "human",
200
+ "check": "solo agent walks the full cycle when subagent dispatch is unavailable; gate discipline preserved",
201
+ "observed": "SKILL.md Team Spin-Up documents the solo fallback explicitly",
202
+ "result": "pass"
203
+ }
89
204
  ]
90
205
  }
91
206
  ]
@@ -6,55 +6,112 @@ The Main Orchestrator manages the global store (Main Knowledge Base). It:
6
6
  - Recognizes, creates, updates, and groups intents
7
7
  - Spawns Project Orchestrators for registered projects
8
8
  - Receives contributions back from Project Orchestrators
9
- - Is the only agent that runs in a loop (continuous BuildObserveRepeat)
9
+ - Is the only agent that runs in a loop (continuous Build, Observe, Repeat)
10
10
 
11
11
  ## Project Orchestrators
12
12
 
13
13
  Project Orchestrators manage project stores (Project Knowledge Bases). They:
14
14
  - Care about intents and execution within their project
15
- - Spawn teams to develop and execute intents
15
+ - Spin up an enforcer-led team to deliver an intent
16
16
  - Contribute back to the Main Orchestrator when new intents are born
17
17
  that could enrich the Main Knowledge Base
18
18
 
19
- Rules:
20
- - 1 Main Orchestrator : 1 Global Store (`~/.plastic/`)
21
- - 1 Main Orchestrator : N Project Orchestrators
22
- - 1 Project Orchestrator : 1 Project Store
23
- - 1 Agent : 1 Intent (exclusive assignment)
24
- - 1 Agent : N Sub-agents (for parallel Actions within an intent)
19
+ ## The Auto-Mode Team
20
+
21
+ Auto mode spins up exactly ONE enforcer-led team per intent. The plastic-enforcer
22
+ IS the auto orchestrator itself, not a separately dispatched agent. Making the
23
+ orchestrator the enforcer avoids the who-gates-the-gater regress (the gate-keeper
24
+ can never be ungated).
25
+
26
+ The team has five roles, one per place in the What, Why, How, Exec cycle:
27
+
28
+ - **plastic-brainstorming** (Why exploration): enriches `## Context` and records
29
+ `### Decisions` with rationale.
30
+ - **plastic-spec-specialist** (Why-to-How boundary): consolidates the Why into
31
+ `spec.md` (Problem, Goals, Non-Goals, Approach, Decisions, Acceptance Criteria).
32
+ - **plastic-planner** (How): produces `plan.md`, `actions/ACTION_N.md`, and
33
+ `checklist.md`.
34
+ - **plastic-executor** (Exec): writes the code, checks off `checklist.md`, appends
35
+ `## Insights`, and drives the suite green.
36
+ - **plastic-enforcer** (spans the whole cycle): orchestrates and gates.
37
+
38
+ ### Handoff Contracts
39
+
40
+ Each specialist receives the prior stage's deliverable and produces the next stage's
41
+ input. The enforcer dispatches one specialist per stage with a constructed context
42
+ bundle, gates that deliverable against the stage's exit criteria, and only then hands
43
+ off to the next stage. Dispatch is sequential on a single branch, because the stage
44
+ deliverables share files (a parked spec, plan, and checklist all live in the same
45
+ intent directory).
46
+
47
+ The chain: intent `## Intent` / `## Context`, then enriched `## Context` plus
48
+ `### Decisions`, then `spec.md`, then `plan.md` plus `actions/` plus `checklist.md`,
49
+ then the code changes plus a checked-off checklist plus `## Insights`.
50
+
51
+ ### Gate Ownership
52
+
53
+ The enforcer arms and verifies the lifecycle gate, then gates every stage transition.
54
+ It never delegates gate ownership. At the final gate only, it dispatches an
55
+ INDEPENDENT reviewer subagent to review the delivered work. That reviewer is not a
56
+ permanent sixth role, it exists only for the final review.
57
+
58
+ ### Headless Manual Gate
59
+
60
+ When running headless or in the background, the enforcer enforces gates manually and
61
+ does not rely on hooks, because `CLAUDE_SESSION_ID` may be unset in those runs (the
62
+ gate-check and savepoint hooks no-op without it). The enforcer arms via the bridge's
63
+ derived-key fallback and verifies state itself.
64
+
65
+ ### Delegation
66
+
67
+ The roles are thin handoff contracts, not a spawning engine. Real parallelism and
68
+ dispatch are delegated to `superpowers:subagent-driven-development` and
69
+ `superpowers:dispatching-parallel-agents`. The team model defines who hands what to
70
+ whom and where the gates sit, the superpowers skills do the actual dispatching.
71
+
72
+ ### Solo Fallback
73
+
74
+ If the harness has no subagent dispatch, auto mode falls back to a single agent
75
+ walking the full What, Why, How, Exec cycle itself. This preserves the original
76
+ behavior on harnesses without teams. The enforcer's gate discipline still applies.
77
+
78
+ ### Dogfood Proof
79
+
80
+ Intents 60, 61, and 62 were delivered by exactly this enforcer-led team on a shared
81
+ branch, which is the dogfooded proof that the model works end to end.
25
82
 
26
83
  ## Two Modes
27
84
 
28
- - **Human-driven:** Human chats with Main Orchestrator, creates intents,
29
- brainstorms, then Main Orchestrator dispatches Project Orchestrators and
30
- Agents for execution.
31
- - **Autonomous:** Human gives Main Orchestrator a starting intent with defined
32
- outcomes. Main Orchestrator runs the full cycle Agents do the lifecycle
33
- (What→Why→How→Exec), Main Orchestrator reviews Insights, spawns next intents,
34
- dispatches again.
85
+ - **Human-driven:** Human chats with the Main Orchestrator, creates intents,
86
+ brainstorms, then the Main Orchestrator dispatches Project Orchestrators and teams
87
+ for execution.
88
+ - **Autonomous:** Human gives the Main Orchestrator a starting intent with defined
89
+ outcomes. The enforcer-led team runs the full cycle (the specialists do the
90
+ lifecycle, the enforcer reviews Insights and gates), then the orchestrator spawns
91
+ next intents and dispatches again.
35
92
 
36
93
  ## Autonomous Delivery
37
94
 
38
- Human owns What and Why for human-initiated intents. Agent assists (research,
39
- exploration) but human drives until handoff. When Why is complete or human
40
- triggers `plastic-auto` the agent takes over How and Exec autonomously.
95
+ Human owns What and Why for human-initiated intents. The team assists (research,
96
+ exploration) but the human drives until handoff. When Why is complete, or the human
97
+ triggers `plastic-auto`, the enforcer-led team takes over How and Exec autonomously.
41
98
 
42
- - **Safe-by-default:** Agent always prefers non-destructive routes (rename vs
99
+ - **Safe-by-default:** the executor always prefers non-destructive routes (rename vs
43
100
  delete, additive migrations, backups before changes). Destructive actions on
44
101
  existing projects require human approval unless `--skip-permissions` is set.
45
- - **One agent per intent.** Agent follows the full W→W→H→E lifecycle.
46
102
  - **Notification only on:** finish or hard stop (blocked on destructive action,
47
- unresolvable error). No progress reports `## Insights` tracks everything.
48
- - **Greenfield autonomy:** During initial project creation, all decisions are
49
- non-destructive (nothing to destroy). Agent has full autonomy for greenfield choices.
50
- - **Autonomous decisions** are logged in `## Insights` with `(autonomous)` marker.
103
+ unresolvable error). No progress reports, `## Insights` tracks everything.
104
+ - **Greenfield autonomy:** during initial project creation, all decisions are
105
+ non-destructive (nothing to destroy), so the team has full autonomy for greenfield
106
+ choices.
107
+ - **Autonomous decisions** are logged in `## Insights` with the `(autonomous)` marker.
51
108
 
52
109
  ## Coordinator Loop
53
110
 
54
111
  When "work on Project X":
55
- 1. Read `projects.yml` find project path
112
+ 1. Read `projects.yml`, find the project path
56
113
  2. Load global config (defaults)
57
114
  3. Load project config (overrides)
58
- 4. Load global INDEX.md find hub intents tagged `project-<name>`
59
- 5. Load project INDEX.md tactical intents
60
- 6. Coordinator has full picture, dispatches Agent teams
115
+ 4. Load global INDEX.md, find hub intents tagged `project-<name>`
116
+ 5. Load project INDEX.md, find tactical intents
117
+ 6. The coordinator has the full picture, spins up an enforcer-led team per intent
@@ -6,7 +6,7 @@ description: Use when merging a feature branch to main and tagging a release, bu
6
6
  # Releasing
7
7
 
8
8
  Merge, bump, tag, push. Annotated tags with changelogs. Semantic versioning.
9
- Project configuration drives the workflow no hardcoded assumptions.
9
+ Project configuration drives the workflow - no hardcoded assumptions.
10
10
 
11
11
  ## Checklist
12
12
 
@@ -18,6 +18,7 @@ Project configuration drives the workflow — no hardcoded assumptions.
18
18
  - [ ] Create annotated tag
19
19
  - [ ] Push to remote with tags
20
20
  - [ ] Run post-push actions (GitHub release, npm publish, etc.)
21
+ - [ ] Verify release sync (npm dist-tag, GitHub "Latest", git tag all show the new version)
21
22
  - [ ] Complete active intent
22
23
 
23
24
  ## Workflow
@@ -26,9 +27,9 @@ Project configuration drives the workflow — no hardcoded assumptions.
26
27
 
27
28
  Before anything else, determine which project we are releasing and load its config.
28
29
 
29
- 1. Read `~/.plastic/projects.yml` find the project whose `path` matches the current working directory.
30
+ 1. Read `~/.plastic/projects.yml` - find the project whose `path` matches the current working directory.
30
31
  2. Extract the project slug (the key under `projects:`).
31
- 3. Read `~/.plastic/projects/{slug}/project.yml` this contains the `release:` section.
32
+ 3. Read `~/.plastic/projects/{slug}/project.yml` - this contains the `release:` section.
32
33
 
33
34
  Expected `release:` keys in project.yml:
34
35
 
@@ -37,8 +38,9 @@ release:
37
38
  verify: "bin/rails test" # command to run before release
38
39
  version_file: package.json # single file containing the version
39
40
  version_files: # multiple files (overrides version_file)
40
- - package.json
41
- - .claude-plugin/plugin.json
41
+ - package.json # list EVERY file carrying the version;
42
+ - .claude-plugin/plugin.json # they must all be bumped together or they drift
43
+ - .claude-plugin/marketplace.json
42
44
  tag_format: "v{{version}}" # tag naming pattern ({{version}} is replaced)
43
45
  on_green: # actions to run after push succeeds
44
46
  - github_release
@@ -47,7 +49,7 @@ release:
47
49
  on_red: stop # what to do if verification fails
48
50
  ```
49
51
 
50
- **Fallback:** If no project.yml exists or it has no `release:` section, fall back to asking the user for each step verify command, version files, tag format, and post-push actions.
52
+ **Fallback:** If no project.yml exists or it has no `release:` section, fall back to asking the user for each step - verify command, version files, tag format, and post-push actions.
51
53
 
52
54
  ### 1. Verify Tests Pass
53
55
 
@@ -77,7 +79,7 @@ Pre-1.0: minor bumps for features, patch for fixes. No major until stable.
77
79
 
78
80
  ```bash
79
81
  git checkout main
80
- git merge <branch-name> --no-ff -m "feat: merge intent [ID] [description]"
82
+ git merge <branch-name> --no-ff -m "feat: merge intent [ID] - [description]"
81
83
  ```
82
84
 
83
85
  Always `--no-ff` to preserve branch history in the merge commit.
@@ -94,7 +96,7 @@ Update the version string in each file, then commit:
94
96
 
95
97
  ```bash
96
98
  git add <version-files>
97
- git commit -m "chore: bump version to X.Y.Z [one-line summary]"
99
+ git commit -m "chore: bump version to X.Y.Z - [one-line summary]"
98
100
  ```
99
101
 
100
102
  ### 5. Create Annotated Tag
@@ -113,7 +115,7 @@ git log $(git describe --tags --abbrev=0)..HEAD --oneline --no-merges | grep -E
113
115
  Create the tag with a multi-line message:
114
116
 
115
117
  ```bash
116
- git tag -a <tag-name> -m "<tag-name> [release name]
118
+ git tag -a <tag-name> -m "<tag-name> - [release name]
117
119
 
118
120
  - [changelog bullet points from feat/fix/refactor commits]"
119
121
  ```
@@ -133,9 +135,15 @@ Read `release.on_green` from project.yml. This is a list of actions to run after
133
135
  Create a GitHub release from the tag:
134
136
 
135
137
  ```bash
136
- gh release create <tag-name> --title "<tag-name> [release name]" --generate-notes --notes-start-tag <previous-tag>
138
+ gh release create <tag-name> --title "<tag-name> - [release name]" --latest --generate-notes --notes-start-tag <previous-tag>
137
139
  ```
138
140
 
141
+ `--latest` is REQUIRED. Pre-release (alpha/beta) tags are NOT auto-promoted to the "Latest"
142
+ badge by GitHub, so without it the Releases page keeps showing an older version as Latest while
143
+ the newest tag sits below it (a real sync drift we hit on the alpha line). Pass `--latest` on
144
+ every release so the newest one always carries the badge. Do NOT pass `--prerelease` unless you
145
+ specifically want the release hidden from Latest.
146
+
139
147
  For the first release (no previous tag), write notes manually with `--notes "..."` instead.
140
148
 
141
149
  #### `npm_publish`
@@ -168,6 +176,22 @@ If `on_green` contains an action not listed above, log it:
168
176
 
169
177
  If `on_green` is empty or absent: skip post-push actions entirely.
170
178
 
179
+ #### Verify sync (always, after the post-push actions)
180
+
181
+ A release is not done until all three surfaces show the SAME newest version. Confirm:
182
+
183
+ ```bash
184
+ npm view <package> dist-tags # channel tag (alpha/beta/latest) -> new version
185
+ gh release list --limit 1 # newest release is the new tag AND marked "Latest"
186
+ git ls-remote --tags origin | grep <tag-name> # the tag reached the remote
187
+ ```
188
+
189
+ If the GitHub "Latest" badge is on an older tag (the common drift), fix it without re-releasing:
190
+
191
+ ```bash
192
+ gh release edit <tag-name> --latest
193
+ ```
194
+
171
195
  ### 8. Complete Active Intent
172
196
 
173
197
  A release IS a delivery. The active intent that drove this work must be completed as part of the release process. This is NOT optional.
@@ -179,18 +203,21 @@ A release IS a delivery. The active intent that drove this work must be complete
179
203
  c. Update `## Insights` with final observations
180
204
  d. Move from `## Active` to `## Completed` in INDEX.md (with today's date)
181
205
  e. Update clusters to show `_(completed)_`
182
- 3. Auto-commit: `cd ~/.plastic && git add . && git commit -m "feat: complete intent <ID> delivered in <tag-name>"`
206
+ 3. Auto-commit: `cd ~/.plastic && git add . && git commit -m "feat: complete intent <ID> - delivered in <tag-name>"`
183
207
 
184
- **If no active intent exists for this release**, that itself is a problem work happened outside the intent system. Log it and move on, but flag it.
208
+ **If no active intent exists for this release**, that itself is a problem - work happened outside the intent system. Log it and move on, but flag it.
185
209
 
186
210
  ## Conventions
187
211
 
188
- - **Annotated tags only** `git tag -a`, never lightweight tags
189
- - **Tag format** driven by `release.tag_format` in project.yml (default: `vX.Y.Z`)
190
- - **Tag message** first line: `<tag> [short name]`, then blank line, then bullet changelog
191
- - **Commit prefixes** `feat:`, `fix:`, `refactor:`, `chore:`, `docs:` (conventional commits)
192
- - **Version files** driven by project.yml; all listed files must always match
193
- - **Branch cleanup** delete merged feature branches: `git branch -d <branch>`
212
+ - **Annotated tags only** - `git tag -a`, never lightweight tags
213
+ - **Tag format** - driven by `release.tag_format` in project.yml (default: `vX.Y.Z`)
214
+ - **Tag message** - first line: `<tag> - [short name]`, then blank line, then bullet changelog
215
+ - **Commit prefixes** - `feat:`, `fix:`, `refactor:`, `chore:`, `docs:` (conventional commits)
216
+ - **Hyphens, never em-dashes** - in tag names, release titles, and commit messages, use a hyphen (`-`). Never an em-dash.
217
+ - **Latest badge** - always `gh release create --latest`; the newest release must carry GitHub's "Latest" badge.
218
+ - **Version files** - driven by project.yml; list and bump EVERY file carrying the version (they drift otherwise)
219
+ - **Verify sync** - after pushing, confirm npm dist-tag, GitHub "Latest", and the git tag all show the new version
220
+ - **Branch cleanup** - delete merged feature branches: `git branch -d <branch>`
194
221
 
195
222
  ## Promotion
196
223
 
@@ -215,7 +242,7 @@ plastic-releasing --promote stable # promotes current beta → stable
215
242
  For repos without prior tags, tag historical releases:
216
243
 
217
244
  ```bash
218
- git tag -a v0.1.0 <commit-sha> -m "v0.1.0 [description]"
245
+ git tag -a v0.1.0 <commit-sha> -m "v0.1.0 - [description]"
219
246
  ```
220
247
 
221
248
  Use `git log --oneline` to find the right commits (look for version bump commits or major feature merges).