@zalom/plastic 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PLASTIC-reference.md +11 -11
- package/PLASTIC.md +7 -7
- package/README.md +47 -0
- package/agents/plastic-enforcer.md +3 -3
- package/agents/plastic-intent-curator.md +9 -10
- package/agents/plastic-spec-specialist.md +9 -6
- package/bin/plastic.js +2 -2
- package/package.json +1 -1
- package/scripts/dashboard.rb +1 -1
- package/scripts/doctor.rb +52 -4
- package/scripts/end-intent +330 -0
- package/scripts/hook-code-gate +1 -1
- package/scripts/hook-continue +1 -1
- package/scripts/hook-create-gate +2 -2
- package/scripts/hook-session-start +1 -1
- package/scripts/lib/bridge.rb +35 -3
- package/scripts/lib/installer_core.rb +8 -6
- package/scripts/lib/store_provisioning.rb +1 -1
- package/scripts/new-intent +1 -1
- package/scripts/{versions.rb → rollback.rb} +33 -41
- package/scripts/update.rb +1 -1
- package/skills/_active-intent-gate.md +1 -1
- package/skills/_decision-tables.md +50 -0
- package/skills/auto/SKILL.md +47 -64
- package/skills/auto/evals/evals.json +4 -4
- package/skills/auto/references/agent-architecture.md +2 -2
- package/skills/dashboard/SKILL.md +2 -2
- package/skills/doctor/SKILL.md +3 -3
- package/skills/install/SKILL.md +1 -1
- package/skills/{brainstorming → intent-brainstorming}/SKILL.md +43 -45
- package/skills/intent-brainstorming/evals/evals.json +67 -0
- package/skills/{brainstorming → intent-brainstorming}/references/design-principles.md +12 -17
- package/skills/{continuing → intent-continuing}/SKILL.md +3 -3
- package/skills/{continuing → intent-continuing}/evals/evals.json +24 -24
- package/skills/{creating-intent → intent-creating}/SKILL.md +3 -3
- package/skills/{creating-intent → intent-creating}/evals/evals.json +1 -1
- package/skills/{intent-discovery → intent-discovering}/SKILL.md +1 -1
- package/skills/intent-ending/SKILL.md +151 -0
- package/skills/intent-ending/evals/evals.json +74 -0
- package/skills/{executing-plan → intent-executing}/SKILL.md +75 -15
- package/skills/intent-executing/evals/evals.json +66 -0
- package/skills/{brainstorming-grill-me → intent-grilling}/SKILL.md +4 -4
- package/skills/{linking-intents → intent-linking}/SKILL.md +1 -1
- package/skills/{linking-intents → intent-linking}/evals/evals.json +1 -1
- package/skills/{lock → intent-locking}/SKILL.md +1 -1
- package/skills/{writing-plans → intent-planning}/SKILL.md +48 -20
- package/skills/intent-planning/evals/evals.json +66 -0
- package/skills/{writing-plans → intent-planning}/references/plan-format.md +31 -7
- package/skills/{research → intent-researching}/SKILL.md +2 -2
- package/skills/{research → intent-researching}/evals/evals.json +1 -1
- package/skills/{savepoint → intent-savepoint}/SKILL.md +1 -1
- package/skills/intent-speccing/SKILL.md +69 -0
- package/skills/intent-speccing/evals/evals.json +126 -0
- package/skills/intent-speccing/references/per-section-fill-rules.md +92 -0
- package/skills/intent-speccing/references/self-verify-checklist.md +38 -0
- package/skills/intent-starting/SKILL.md +2 -2
- package/skills/intent-starting/evals/evals.json +2 -2
- package/skills/{creating-project → project-creating}/SKILL.md +2 -2
- package/skills/releasing/SKILL.md +18 -14
- package/skills/{versions → rollback}/SKILL.md +30 -20
- package/skills/{creating-skills → skill-creating}/SKILL.md +2 -2
- package/skills/{creating-skills → skill-creating}/evals/evals.json +5 -5
- package/skills/{creating-skills → skill-creating}/references/progressive-disclosure.md +2 -2
- package/skills/{evaluating-skills → skill-evaluating}/SKILL.md +1 -1
- package/skills/{evaluating-skills → skill-evaluating}/evals/evals.json +3 -3
- package/skills/{intent-curator → store-curating}/SKILL.md +6 -7
- package/skills/{intent-curator → store-curating}/evals/evals.json +1 -1
- package/skills/{managing-index → store-indexing}/SKILL.md +6 -7
- package/skills/{managing-index → store-indexing}/evals/evals.json +1 -1
- package/skills/{add-project-store → store-provisioning}/SKILL.md +2 -2
- package/skills/tutorial/SKILL.md +65 -0
- package/skills/tutorial/evals/evals.json +186 -0
- package/skills/tutorial/references/track-1-guided.md +123 -0
- package/skills/tutorial/references/track-2-auto.md +95 -0
- package/skills/tutorial/references/track-3-projects-and-roadmaps.md +110 -0
- package/skills/update/SKILL.md +1 -1
- package/templates/agents.md +7 -7
- package/skills/brainstorming/evals/evals.json +0 -22
- /package/skills/{continuing → intent-continuing}/references/context-management.md +0 -0
- /package/skills/{creating-intent → intent-creating}/references/lifecycle.md +0 -0
- /package/skills/{creating-intent → intent-creating}/references/wikilinks.md +0 -0
- /package/skills/{executing-plan → intent-executing}/code-quality-reviewer-prompt.md +0 -0
- /package/skills/{executing-plan → intent-executing}/implementer-prompt.md +0 -0
- /package/skills/{executing-plan → intent-executing}/spec-reviewer-prompt.md +0 -0
- /package/skills/{linking-intents → intent-linking}/references/zettelkasten.md +0 -0
- /package/skills/{savepoint → intent-savepoint}/references/context-management.md +0 -0
- /package/skills/{creating-project → project-creating}/references/hubs-projects.md +0 -0
- /package/skills/{creating-project → project-creating}/references/project-scaffolding.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/agents.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/evals.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/hooks.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/scripts.md +0 -0
- /package/skills/{creating-skills → skill-creating}/references/skills.md +0 -0
- /package/skills/{creating-skills → skill-creating}/scripts/scaffold.rb +0 -0
- /package/skills/{evaluating-skills → skill-evaluating}/assets/eval-template.json +0 -0
- /package/skills/{evaluating-skills → skill-evaluating}/references/convention-checks.md +0 -0
- /package/skills/{evaluating-skills → skill-evaluating}/references/eval-methodology.md +0 -0
- /package/skills/{managing-index → store-indexing}/references/zettelkasten-linking.md +0 -0
|
@@ -20,30 +20,25 @@ steps).
|
|
|
20
20
|
|
|
21
21
|
## Process Flow (diagram)
|
|
22
22
|
|
|
23
|
-
The Checklist above already states this ordered flow as numbered steps 1-
|
|
23
|
+
The Checklist above already states this ordered flow as numbered steps 1-6; this
|
|
24
24
|
diagram is the same flow in a visual form.
|
|
25
25
|
|
|
26
26
|
```dot
|
|
27
27
|
digraph brainstorming {
|
|
28
28
|
"Explore project context" [shape=box];
|
|
29
|
-
"
|
|
29
|
+
"Grill in prose" [shape=box];
|
|
30
30
|
"Propose 2-3 approaches" [shape=box];
|
|
31
31
|
"Present design sections" [shape=box];
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
"Explore project context" -> "Ask clarifying questions";
|
|
39
|
-
"Ask clarifying questions" -> "Propose 2-3 approaches";
|
|
32
|
+
"Owner rules?" [shape=diamond];
|
|
33
|
+
"Collect rulings\n(persist each immediately)" [shape=box];
|
|
34
|
+
"Invoke /plastic-intent-speccing" [shape=doublecircle];
|
|
35
|
+
|
|
36
|
+
"Explore project context" -> "Grill in prose";
|
|
37
|
+
"Grill in prose" -> "Propose 2-3 approaches";
|
|
40
38
|
"Propose 2-3 approaches" -> "Present design sections";
|
|
41
|
-
"Present design sections" -> "
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"Spec self-review\n(fix inline)" -> "User reviews spec?";
|
|
46
|
-
"User reviews spec?" -> "Write spec" [label="changes requested"];
|
|
47
|
-
"User reviews spec?" -> "Invoke plastic-writing-plans" [label="approved"];
|
|
39
|
+
"Present design sections" -> "Owner rules?";
|
|
40
|
+
"Owner rules?" -> "Present design sections" [label="no, revise"];
|
|
41
|
+
"Owner rules?" -> "Collect rulings\n(persist each immediately)" [label="yes"];
|
|
42
|
+
"Collect rulings\n(persist each immediately)" -> "Invoke /plastic-intent-speccing";
|
|
48
43
|
}
|
|
49
44
|
```
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: plastic-continuing
|
|
3
|
-
description: Use when the user says "continue", "resume", or "pick up where we left off", or when starting a new session. Continues work with the latest project context: lands on the right dashboard, then presents choices. Boot (health check, core context, version, statusline) is owned by the SessionStart hook, not this skill. Does not drive work autonomously (that is plastic-auto).
|
|
2
|
+
name: plastic-intent-continuing
|
|
3
|
+
description: 'Use when the user says "continue", "resume", or "pick up where we left off", or when starting a new session. Continues work with the latest project context: lands on the right dashboard, then presents choices. Boot (health check, core context, version, statusline) is owned by the SessionStart hook, not this skill. Does not drive work autonomously (that is plastic-auto).'
|
|
4
4
|
user-invocable: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Continuing
|
|
8
8
|
|
|
9
|
-
`plastic-continuing` continues work. It presents the latest state via the dashboard and offers
|
|
9
|
+
`plastic-intent-continuing` continues work. It presents the latest state via the dashboard and offers
|
|
10
10
|
choices, then stops. It does NOT execute work autonomously (that is `plastic-auto`) and does
|
|
11
11
|
NOT render the dashboard itself (it only invokes it).
|
|
12
12
|
|
|
@@ -1,51 +1,51 @@
|
|
|
1
1
|
{
|
|
2
|
-
"skill_name": "plastic-continuing",
|
|
2
|
+
"skill_name": "plastic-intent-continuing",
|
|
3
3
|
"notes": "Intent 36, updated for 36a (boot moved into hook-session-start; the skill is now work-continuation only). Scopes: description triggering (1-8) and behavior/convention compliance of the work-continuation skill (9-14). Triggering assertions follow the plastic-auto eval style (one subagent router per case). Behavior assertions are convention checks against the SKILL.md.",
|
|
4
4
|
"results": {
|
|
5
5
|
"triggering": { "cases": 8, "passed": 8, "run": "2026-06-16, one subagent per case" },
|
|
6
|
-
"behavior": { "cases": 6, "passed": 6, "evidence": "convention checks against skills/continuing/SKILL.md after the intent-36 rewrite; doctor --core verified at 0.07s with 9 liveness checks and full doctor unchanged at 30 checks" }
|
|
6
|
+
"behavior": { "cases": 6, "passed": 6, "evidence": "convention checks against skills/intent-continuing/SKILL.md after the intent-36 rewrite; doctor --core verified at 0.07s with 9 liveness checks and full doctor unchanged at 30 checks" }
|
|
7
7
|
},
|
|
8
8
|
"evals": [
|
|
9
9
|
{
|
|
10
10
|
"id": 1, "scope": "triggering", "set": "train",
|
|
11
11
|
"prompt": "continue",
|
|
12
|
-
"expected_output": "Activates plastic-continuing (the bare 'continue' keyword is the documented trigger).",
|
|
12
|
+
"expected_output": "Activates plastic-intent-continuing (the bare 'continue' keyword is the documented trigger).",
|
|
13
13
|
"files": [],
|
|
14
14
|
"assertions": [
|
|
15
|
-
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
15
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"id": 2, "scope": "triggering", "set": "train",
|
|
20
20
|
"prompt": "resume where we left off",
|
|
21
|
-
"expected_output": "Activates plastic-continuing.",
|
|
21
|
+
"expected_output": "Activates plastic-intent-continuing.",
|
|
22
22
|
"files": [],
|
|
23
23
|
"assertions": [
|
|
24
|
-
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
24
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
|
|
25
25
|
]
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"id": 3, "scope": "triggering", "set": "validation",
|
|
29
29
|
"prompt": "pick up where we left off in this project",
|
|
30
|
-
"expected_output": "Activates plastic-continuing.",
|
|
30
|
+
"expected_output": "Activates plastic-intent-continuing.",
|
|
31
31
|
"files": [],
|
|
32
32
|
"assertions": [
|
|
33
|
-
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
33
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
|
|
34
34
|
]
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"id": 4, "scope": "triggering", "set": "train",
|
|
38
38
|
"prompt": "boot plastic and show me where things stand",
|
|
39
|
-
"expected_output": "Activates plastic-continuing (continuing work + presenting state is the skill's purpose; boot itself is hook-owned).",
|
|
39
|
+
"expected_output": "Activates plastic-intent-continuing (continuing work + presenting state is the skill's purpose; boot itself is hook-owned).",
|
|
40
40
|
"files": [],
|
|
41
41
|
"assertions": [
|
|
42
|
-
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
42
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
46
|
"id": 5, "scope": "triggering", "set": "train",
|
|
47
47
|
"prompt": "continue delivering this intent autonomously, don't ask me",
|
|
48
|
-
"expected_output": "Does NOT settle on plastic-continuing for execution. Shares 'continue' but the autonomous-delivery intent routes to plastic-auto.",
|
|
48
|
+
"expected_output": "Does NOT settle on plastic-intent-continuing for execution. Shares 'continue' but the autonomous-delivery intent routes to plastic-auto.",
|
|
49
49
|
"files": [],
|
|
50
50
|
"assertions": [
|
|
51
51
|
{ "type": "code", "check": "router CHOICE == plastic-auto", "observed": "plastic-auto", "result": "pass" }
|
|
@@ -54,35 +54,35 @@
|
|
|
54
54
|
{
|
|
55
55
|
"id": 6, "scope": "triggering", "set": "validation",
|
|
56
56
|
"prompt": "continue the for-loop to the next iteration in this function",
|
|
57
|
-
"expected_output": "Does NOT activate plastic-continuing. Near-miss: shares 'continue' but is a code-editing task.",
|
|
57
|
+
"expected_output": "Does NOT activate plastic-intent-continuing. Near-miss: shares 'continue' but is a code-editing task.",
|
|
58
58
|
"files": [],
|
|
59
59
|
"assertions": [
|
|
60
|
-
{ "type": "code", "check": "router CHOICE != plastic-continuing", "observed": "none", "result": "pass" }
|
|
60
|
+
{ "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "none", "result": "pass" }
|
|
61
61
|
]
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"id": 7, "scope": "triggering", "set": "train",
|
|
65
65
|
"prompt": "resume the paused background download",
|
|
66
|
-
"expected_output": "Does NOT activate plastic-continuing. Near-miss: shares 'resume' but is unrelated to Plastic sessions.",
|
|
66
|
+
"expected_output": "Does NOT activate plastic-intent-continuing. Near-miss: shares 'resume' but is unrelated to Plastic sessions.",
|
|
67
67
|
"files": [],
|
|
68
68
|
"assertions": [
|
|
69
|
-
{ "type": "code", "check": "router CHOICE != plastic-continuing", "observed": "none", "result": "pass" }
|
|
69
|
+
{ "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "none", "result": "pass" }
|
|
70
70
|
]
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
"id": 8, "scope": "triggering", "set": "validation",
|
|
74
74
|
"prompt": "what's the dashboard look like right now",
|
|
75
|
-
"expected_output": "May activate plastic-dashboard rather than plastic-continuing; an overview request without 'continue/resume' is a dashboard task.",
|
|
75
|
+
"expected_output": "May activate plastic-dashboard rather than plastic-intent-continuing; an overview request without 'continue/resume' is a dashboard task.",
|
|
76
76
|
"files": [],
|
|
77
77
|
"assertions": [
|
|
78
|
-
{ "type": "code", "check": "router CHOICE != plastic-continuing", "observed": "plastic-dashboard", "result": "pass" }
|
|
78
|
+
{ "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "plastic-dashboard", "result": "pass" }
|
|
79
79
|
]
|
|
80
80
|
},
|
|
81
81
|
{
|
|
82
82
|
"id": 9, "scope": "behavior", "set": "train",
|
|
83
83
|
"prompt": "Does the skill defer boot to the SessionStart hook rather than running it itself?",
|
|
84
84
|
"expected_output": "SKILL.md states boot (health check, core context, version banner, statusline) is owned by hook-session-start / plastic-statusline, not this skill.",
|
|
85
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
85
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
86
86
|
"assertions": [
|
|
87
87
|
{ "type": "convention", "check": "SKILL.md says boot is owned by the SessionStart hook and the skill does not run it", "observed": "'Boot is not this skill's job.' paragraph naming hook-session-start and plastic-statusline", "result": "pass" }
|
|
88
88
|
]
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"id": 10, "scope": "behavior", "set": "train",
|
|
92
92
|
"prompt": "Does the skill avoid running doctor / setting the statusline itself?",
|
|
93
93
|
"expected_output": "SKILL.md does NOT instruct running doctor.rb --core or setting the statusline; it attributes those to the hooks.",
|
|
94
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
94
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
95
95
|
"assertions": [
|
|
96
96
|
{ "type": "convention", "check": "no in-skill boot step invokes doctor.rb --core or sets the statusline; both are attributed to hooks", "observed": "doctor --core and statusline mentioned only as hook-owned in the 'Boot is not this skill's job' note", "result": "pass" }
|
|
97
97
|
]
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"id": 11, "scope": "behavior", "set": "train",
|
|
101
101
|
"prompt": "Is dashboard selection project-aware?",
|
|
102
102
|
"expected_output": "Project loaded -> `dashboard.rb project <slug>`; otherwise -> `dashboard.rb continue`. Skill only invokes, does not render.",
|
|
103
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
103
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
104
104
|
"assertions": [
|
|
105
105
|
{ "type": "convention", "check": "both dashboard invocations present and gated on project detection", "observed": "'dashboard.rb project <slug>' and 'dashboard.rb continue' in the 'Continue (present the dashboard)' section", "result": "pass" }
|
|
106
106
|
]
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"id": 12, "scope": "behavior", "set": "validation",
|
|
110
110
|
"prompt": "Is ledger-resume conditional and ledger-driven?",
|
|
111
111
|
"expected_output": "Resume fires only when a specific intent is named; reads savepoint.md last line as stage, verifies the stage file, rebuilds on drift, derives next step from first unchecked checklist item.",
|
|
112
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
112
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
113
113
|
"assertions": [
|
|
114
114
|
{ "type": "convention", "check": "Conditional Ledger-Resume section reads last ledger line, verifies stage file, calls rebuild_savepoint on drift, uses first unchecked checklist item", "observed": "all four present in 'Conditional Ledger-Resume'", "result": "pass" }
|
|
115
115
|
]
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"id": 13, "scope": "behavior", "set": "validation",
|
|
119
119
|
"prompt": "Are the stale prose-savepoint fields gone?",
|
|
120
120
|
"expected_output": "No 'In progress' / 'Blockers' fields read from a prose savepoint remain; the ledger model is used instead.",
|
|
121
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
121
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
122
122
|
"assertions": [
|
|
123
123
|
{ "type": "convention", "check": "no prose-savepoint announce template (In progress / Blockers from prose)", "observed": "absent; announce uses Stage/Next step/Context/Drift derived from ledger + checklist", "result": "pass" }
|
|
124
124
|
]
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"id": 14, "scope": "behavior", "set": "validation",
|
|
128
128
|
"prompt": "Is the 'Determine Store' local-store gap filled?",
|
|
129
129
|
"expected_output": "Step 2 of Determine Store describes local/project-store detection (no empty step).",
|
|
130
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
130
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
131
131
|
"assertions": [
|
|
132
132
|
{ "type": "convention", "check": "Determine Store step 2 documents local/project store detection via projects.yml + CWD match", "observed": "filled", "result": "pass" }
|
|
133
133
|
]
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"id": 15, "scope": "behavior", "set": "validation",
|
|
137
137
|
"prompt": "QMD is present. The user says: continue the work on the statusline coloring (names the intent by description, not id).",
|
|
138
138
|
"expected_output": "Before scanning the store with grep/Read to locate the named intent, runs `ruby ~/.plastic/scripts/qmd-sync search \"statusline coloring\"` to surface the candidate intent, then opens the authoritative intent file for the hit it resumes. No-op fallback to INDEX.md / file scan when QMD is absent.",
|
|
139
|
-
"files": ["skills/continuing/SKILL.md"],
|
|
139
|
+
"files": ["skills/intent-continuing/SKILL.md"],
|
|
140
140
|
"assertions": [
|
|
141
141
|
{ "type": "human", "check": "qmd-sync search is run before grep/Read when the intent is named by description; authoritative file opened for the hit", "observed": "Conditional Ledger-Resume carries the QMD-first step: run qmd-sync search before grep/Read, then open the authoritative file; no-op fallback when QMD is absent", "result": "pass" }
|
|
142
142
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: plastic-creating
|
|
2
|
+
name: plastic-intent-creating
|
|
3
3
|
description: Use when new work begins, the user expresses a new goal, says "new intent", or no active intent exists for the current task. Creates intents in the global store (~/.plastic/store/) or in a project's store (~/.plastic/projects/{slug}/store/) depending on context.
|
|
4
4
|
user-invocable: true
|
|
5
5
|
---
|
|
@@ -73,7 +73,7 @@ Having a "parent" in mind does NOT automatically mean branch. Choose by meaning:
|
|
|
73
73
|
frontmatter edge and reproject. Links are decided by context influence (a `chain` edge has a high
|
|
74
74
|
bar: the candidate's context must materially help deliver this intent), not by shared files or a
|
|
75
75
|
similarity score. To gather candidates with their context and record an edge, use the
|
|
76
|
-
`plastic-linking
|
|
76
|
+
`plastic-intent-linking` skill and `scripts/link-suggest`.
|
|
77
77
|
|
|
78
78
|
### 3. Determine Intent Properties
|
|
79
79
|
|
|
@@ -126,7 +126,7 @@ cleanly, and do not work around the failure by hand-writing the files.
|
|
|
126
126
|
### 6. If Implementation Intent Spawns a Project
|
|
127
127
|
|
|
128
128
|
When the user says "start building" or the plan calls for a new project, invoke the
|
|
129
|
-
`plastic-creating
|
|
129
|
+
`plastic-project-creating` skill; it owns project directory creation, AGENTS.md
|
|
130
130
|
population, projects.yml registration, store provisioning, and the auto-commit of
|
|
131
131
|
both stores. Add `project-<slug>` to this intent's `tags` array either before
|
|
132
132
|
invoking it or as part of that skill's handoff.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"skill_name": "plastic-creating
|
|
2
|
+
"skill_name": "plastic-intent-creating",
|
|
3
3
|
"notes": "Intent 68. Scope: output-quality for the sources-vs-chain construction rules (D1/D2). Asserts the related-but-not-spawned case produces NO sources plus a predecessor chain link and a ## Links mirror, contrasted with the created-from case (true ascendant -> --sources set, reciprocal chain). The machine-checkable half lives in test/new_intent_test.rb (test_sources_path_gets_child_in_chain_frontmatter); this file documents the agent-facing scenario for skill evaluation and is NOT run by bin/test.",
|
|
4
4
|
"evals": [
|
|
5
5
|
{
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-intent-ending
|
|
3
|
+
description: >
|
|
4
|
+
Wrap, finish, close, or mark an intent Done, delivered or abandoned. Use
|
|
5
|
+
when completing or abandoning an intent, when a checklist reaches 100
|
|
6
|
+
percent and Exec is finished, or when asked to "wrap this up".
|
|
7
|
+
user-invocable: true
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Intent Ending
|
|
11
|
+
|
|
12
|
+
The one procedure every terminal transition routes through. Auto mode, the
|
|
13
|
+
curator path, and releasing all call this skill (or its backing script,
|
|
14
|
+
`scripts/end-intent`) for the mechanical close instead of restating the same
|
|
15
|
+
prose three times. `abandoned` is the SAME procedure as `delivered`, not a
|
|
16
|
+
failure branch: only outcome.md content and the INDEX section differ.
|
|
17
|
+
|
|
18
|
+
## The 8 steps (0-7)
|
|
19
|
+
|
|
20
|
+
| # | Step | Who does it |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| 0 | Precondition check | You, before touching outcome.md |
|
|
23
|
+
| 1 | outcome.md + intent-file `## Outcome` summary | `scripts/end-intent` |
|
|
24
|
+
| 2 | INDEX.md terminal move (Active -> Completed/Abandoned) | `scripts/end-intent` |
|
|
25
|
+
| 3 | savepoint `Done` bookend | `scripts/end-intent` |
|
|
26
|
+
| 4 | store auto-commit | `scripts/end-intent` |
|
|
27
|
+
| 5 | disarm (worktree + lock) | You, after end-intent exits 0 |
|
|
28
|
+
| 6 | QMD reindex, async, LAST | You |
|
|
29
|
+
| 7 | EM-to-CTO report | You |
|
|
30
|
+
|
|
31
|
+
Steps 1-4 are ONE callable script, not four separate one-liners: this is
|
|
32
|
+
exactly what the failure mode this intent fixes looked like (releasing hand
|
|
33
|
+
authored the close in prose and dropped the savepoint bookend for two real
|
|
34
|
+
deliveries). Never restate outcome/INDEX/savepoint prose inline again; call
|
|
35
|
+
`scripts/end-intent`.
|
|
36
|
+
|
|
37
|
+
### Step 0. Precondition (the gate is section-blind, not selective)
|
|
38
|
+
|
|
39
|
+
`Bridge.check_gate` (scripts/lib/bridge.rb) is LIVE code already wired into
|
|
40
|
+
the write-time hook. Its outcome.md rule is a blind scan of the WHOLE
|
|
41
|
+
checklist.md: `content.scan(/^- \[ \]/)` counts every unchecked box, in
|
|
42
|
+
every section, with no awareness of which section a box lives in. ANY
|
|
43
|
+
unchecked box anywhere blocks the outcome.md write; there is no exemption
|
|
44
|
+
for orchestrator-owned or completion-tracking items.
|
|
45
|
+
|
|
46
|
+
1. Read checklist.md. Tick every item as it is actually performed, including
|
|
47
|
+
an item that describes the close itself: running this very procedure IS
|
|
48
|
+
what that item describes, so tick it at the moment you begin the close,
|
|
49
|
+
before authoring outcome.md. By the time outcome.md is written,
|
|
50
|
+
checklist.md must read 100 percent checked; there is no other way past
|
|
51
|
+
the gate.
|
|
52
|
+
2. Confirm every acceptance criterion in spec.md is verifiable (tests pass,
|
|
53
|
+
or the manual check described in its HOW line was actually run).
|
|
54
|
+
3. If checklist.md still has an unchecked box, stop here. Finish it first
|
|
55
|
+
(tick it if the described work is actually done, or do the remaining
|
|
56
|
+
work); do not attempt outcome.md and fight the gate's deny.
|
|
57
|
+
|
|
58
|
+
### Step 1-4. Run `scripts/end-intent`
|
|
59
|
+
|
|
60
|
+
First author outcome.md for real (never leave the scaffold placeholder in
|
|
61
|
+
place): copy `templates/outcome.md`, set the frontmatter to
|
|
62
|
+
`disposition: delivered` or `disposition: abandoned`, and fill `## Summary`,
|
|
63
|
+
`## Delivered`, `## Verification`, `## Follow-ups`. On abandon, `## Summary`
|
|
64
|
+
states the abandonment reason and the trail (see Pivot below). Also author
|
|
65
|
+
the rich INDEX entry note now (a short line in the store's existing
|
|
66
|
+
Completed/Abandoned convention: mode/tier, what shipped or why it was
|
|
67
|
+
abandoned, suite result, merge/spawn notes); content authoring stays with
|
|
68
|
+
you, `--index-note` only appends what you write.
|
|
69
|
+
|
|
70
|
+
Then call the script once:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
ruby ~/.plastic/scripts/end-intent \
|
|
74
|
+
--store <store_path> --id <intent_id> --disposition delivered|abandoned \
|
|
75
|
+
--outcome-summary "<one-line ## Outcome summary for the intent file>" \
|
|
76
|
+
--index-note "<rich Completed/Abandoned entry description>"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This does all of steps 1-4 in order: guards outcome.md (refuses a missing,
|
|
80
|
+
still-placeholder, or wrong-disposition file with exit 2 and authors
|
|
81
|
+
nothing), stamps the intent file's `## Outcome` section, moves the INDEX.md
|
|
82
|
+
line from `## Active` to `## Completed` or `## Abandoned` (dated today,
|
|
83
|
+
idempotent) with the `--index-note` text appended after the date so the
|
|
84
|
+
entry stays rich, appends the savepoint `Done` bookend, and commits the
|
|
85
|
+
store repo. Omit `--index-note` for a thin id+date entry, add `--no-commit`
|
|
86
|
+
when a separate commit step already covers the store, and `--dry-run` to
|
|
87
|
+
preview with no writes. Exit 0 is success; exit 1 is a usage or resolution
|
|
88
|
+
failure; exit 2 is the outcome.md guard refusing (fix outcome.md and re-run,
|
|
89
|
+
nothing was written).
|
|
90
|
+
|
|
91
|
+
### Step 5. Disarm (worktree + lock)
|
|
92
|
+
|
|
93
|
+
Two branches, decided by how this intent ships:
|
|
94
|
+
|
|
95
|
+
- **Shipped through a release** (the `plastic-releasing` flow reached this
|
|
96
|
+
close): merge the code branch back BEFORE removing the worktrees, via
|
|
97
|
+
`Worktree.finish(bridge_data, merge: true)`. Releasing's own workflow
|
|
98
|
+
already drives this; this skill's job here is only the outcome/INDEX/
|
|
99
|
+
savepoint/commit core above.
|
|
100
|
+
- **Auto mode or the curator path** (no release involved): plain remove,
|
|
101
|
+
branch survives for reclaim.
|
|
102
|
+
```bash
|
|
103
|
+
ruby -r ~/.plastic/scripts/lib/bridge -e \
|
|
104
|
+
'Bridge.disarm_auto(ENV["CLAUDE_CODE_SESSION_ID"], intent_id: "<ID>")'
|
|
105
|
+
```
|
|
106
|
+
`disarm_auto` releases both worktrees, clears the `delivery.lock`, and only
|
|
107
|
+
then makes the bridge purge-eligible, in that order. Never leave an
|
|
108
|
+
orphaned worktree; run `git worktree prune` on a stale reference.
|
|
109
|
+
|
|
110
|
+
### Step 6. QMD reindex, LAST
|
|
111
|
+
|
|
112
|
+
Only after step 5 has released the worktrees and cleared the lock, so the
|
|
113
|
+
index never references state about to disappear:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
ruby ~/.plastic/scripts/qmd-sync reindex --store <store-root> --async
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
No-op when QMD is absent. Runs in the background so it never blocks the
|
|
120
|
+
turn.
|
|
121
|
+
|
|
122
|
+
### Step 7. EM-to-CTO report
|
|
123
|
+
|
|
124
|
+
Brief the human like an engineering manager to a CTO: impact and risk first,
|
|
125
|
+
in plain language, the decision left to them (merge, release, or accept).
|
|
126
|
+
See `outcome.md` for the details; do not restate it verbatim.
|
|
127
|
+
|
|
128
|
+
## Abandoned is the same procedure
|
|
129
|
+
|
|
130
|
+
`disposition: abandoned` runs the identical steps 0-7. The only differences
|
|
131
|
+
are outcome.md content (Summary states why this was abandoned, not what was
|
|
132
|
+
delivered) and the INDEX target section (`## Abandoned` instead of
|
|
133
|
+
`## Completed`). Never branch the mechanical steps by disposition; the
|
|
134
|
+
script already does that internally.
|
|
135
|
+
|
|
136
|
+
## Mid-flight pivot
|
|
137
|
+
|
|
138
|
+
When the work that shipped differs from what spec.md or plan.md originally
|
|
139
|
+
called for, do not retcon those documents. Record the decision once in
|
|
140
|
+
`## Insights`, then let outcome.md carry the truth of what actually
|
|
141
|
+
happened, including the abandoned trail when part of the work was dropped
|
|
142
|
+
mid-flight. outcome.md is truth of delivery; spec and plan stay the
|
|
143
|
+
historical record of what was planned.
|
|
144
|
+
|
|
145
|
+
## Routing
|
|
146
|
+
|
|
147
|
+
`plastic-releasing`, `plastic-auto`, the curator agent, `store-curating`, and
|
|
148
|
+
`store-indexing` all delegate their mechanical close to this skill (or call
|
|
149
|
+
`scripts/end-intent` directly for steps 1-4). None of them restate the
|
|
150
|
+
outcome/INDEX/savepoint prose inline any more; if you find one that does,
|
|
151
|
+
that surface has drifted and should route here instead.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "plastic-intent-ending",
|
|
3
|
+
"notes": "Intent 161. Scopes: description triggering (3-6) and behavior (1-2: the two mandatory D6 cases). Case B graduates into test/end_intent_test.rb (test_done_bookend_lands_once_and_is_idempotent) per evaluating-skills conventions.",
|
|
4
|
+
"evals": [
|
|
5
|
+
{
|
|
6
|
+
"id": 1,
|
|
7
|
+
"scope": "behavior",
|
|
8
|
+
"set": "train",
|
|
9
|
+
"prompt": "checklist.md has one unchecked non-completion item. Try to complete the intent.",
|
|
10
|
+
"expected_output": "Defers to the existing Bridge.check_gate hard gate rather than writing outcome.md; tells the user to finish the checklist item first instead of fighting the deny.",
|
|
11
|
+
"files": [],
|
|
12
|
+
"assertions": [
|
|
13
|
+
{ "type": "human", "check": "SKILL.md Step 0 states the gate blocks outcome.md while unchecked non-completion items remain, and instructs finishing the checklist rather than attempting the write", "result": "expect-pass" },
|
|
14
|
+
{ "type": "code", "check": "Bridge.check_gate(intent_dir, 'outcome.md') returns a non-nil block reason when checklist.md has an unchecked '- [ ]' item (scripts/lib/bridge.rb)", "result": "pass" }
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": 2,
|
|
19
|
+
"scope": "behavior",
|
|
20
|
+
"set": "train",
|
|
21
|
+
"prompt": "Run the mechanical close (scripts/end-intent) for a delivered intent with a real outcome.md.",
|
|
22
|
+
"expected_output": "The savepoint Done bookend lands exactly once in savepoint.md, and a second run of the same command does not duplicate it (this is the regression the intent fixes: releasing used to skip this line entirely).",
|
|
23
|
+
"files": [],
|
|
24
|
+
"assertions": [
|
|
25
|
+
{ "type": "human", "check": "SKILL.md Step 1-4 calls scripts/end-intent as one script instead of restating the outcome/INDEX/savepoint one-liners in prose", "result": "expect-pass" },
|
|
26
|
+
{ "type": "code", "check": "test/end_intent_test.rb#test_done_bookend_lands_once_and_is_idempotent is green", "result": "pass" }
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": 3,
|
|
31
|
+
"scope": "triggering",
|
|
32
|
+
"set": "train",
|
|
33
|
+
"prompt": "Mark intent 87 done, it shipped.",
|
|
34
|
+
"expected_output": "Activates plastic-intent-ending to run the mechanical close (outcome.md, INDEX move, savepoint bookend, commit, disarm, reindex, report).",
|
|
35
|
+
"files": [],
|
|
36
|
+
"assertions": [
|
|
37
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-ending", "result": "expect-pass" }
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": 4,
|
|
42
|
+
"scope": "triggering",
|
|
43
|
+
"set": "train",
|
|
44
|
+
"prompt": "This one's not worth finishing, abandon it and wrap this up.",
|
|
45
|
+
"expected_output": "Activates plastic-intent-ending (indirect trigger: 'wrap this up' names no lifecycle vocabulary directly). Abandoned runs the identical procedure, only outcome.md content and the INDEX section differ.",
|
|
46
|
+
"files": [],
|
|
47
|
+
"assertions": [
|
|
48
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-ending", "result": "expect-pass" }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": 5,
|
|
53
|
+
"scope": "triggering",
|
|
54
|
+
"set": "validation",
|
|
55
|
+
"prompt": "Start work on intent 87.",
|
|
56
|
+
"expected_output": "Does NOT activate plastic-intent-ending; this is a boarding request (plastic-intent-starting), the opposite end of the lifecycle from a close.",
|
|
57
|
+
"files": [],
|
|
58
|
+
"assertions": [
|
|
59
|
+
{ "type": "code", "check": "router CHOICE != plastic-intent-ending", "result": "expect-pass" }
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"id": 6,
|
|
64
|
+
"scope": "triggering",
|
|
65
|
+
"set": "validation",
|
|
66
|
+
"prompt": "Cut a release and tag it v1.2.0.",
|
|
67
|
+
"expected_output": "Does NOT activate plastic-intent-ending directly; activates plastic-releasing, which internally calls scripts/end-intent for the mechanical close as one of its own steps.",
|
|
68
|
+
"files": [],
|
|
69
|
+
"assertions": [
|
|
70
|
+
{ "type": "code", "check": "router CHOICE == plastic-releasing", "result": "expect-pass" }
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|