@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.
- package/agents/plastic-brainstorming.md +35 -0
- package/agents/plastic-enforcer.md +36 -0
- package/agents/plastic-executor.md +35 -0
- package/agents/plastic-planner.md +35 -0
- package/agents/plastic-spec-specialist.md +35 -0
- package/package.json +1 -1
- package/scripts/doctor.rb +24 -0
- package/scripts/lib/installer_core.rb +22 -0
- package/skills/auto/SKILL.md +21 -1
- package/skills/auto/evals/evals.json +137 -22
- package/skills/auto/references/agent-architecture.md +85 -28
- package/skills/releasing/SKILL.md +46 -19
- /package/agents/{future-intent-researcher.md → plastic-future-intent-researcher.md} +0 -0
- /package/agents/{intent-curator.md → plastic-intent-curator.md} +0 -0
|
@@ -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
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
|
package/skills/auto/SKILL.md
CHANGED
|
@@ -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
|
|
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": {
|
|
6
|
-
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
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,
|
|
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
|
-
{
|
|
88
|
-
|
|
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 Build
|
|
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
|
-
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
31
|
-
- **Autonomous:** Human gives Main Orchestrator a starting intent with defined
|
|
32
|
-
outcomes.
|
|
33
|
-
|
|
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.
|
|
39
|
-
exploration) but human drives until handoff. When Why is complete
|
|
40
|
-
triggers `plastic-auto
|
|
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:**
|
|
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
|
|
48
|
-
- **Greenfield autonomy:**
|
|
49
|
-
non-destructive (nothing to destroy)
|
|
50
|
-
|
|
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
|
|
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
|
|
59
|
-
5. Load project INDEX.md
|
|
60
|
-
6.
|
|
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
|
|
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`
|
|
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`
|
|
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
|
|
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]
|
|
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
|
|
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>
|
|
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>
|
|
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>
|
|
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
|
|
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**
|
|
189
|
-
- **Tag format**
|
|
190
|
-
- **Tag message**
|
|
191
|
-
- **Commit prefixes**
|
|
192
|
-
- **
|
|
193
|
-
- **
|
|
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
|
|
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).
|
|
File without changes
|
|
File without changes
|