@zalom/plastic 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/PLASTIC-reference.md +11 -11
  2. package/PLASTIC.md +11 -9
  3. package/README.md +48 -1
  4. package/agents/plastic-enforcer.md +8 -5
  5. package/agents/plastic-future-intent-researcher.md +1 -1
  6. package/agents/plastic-intent-curator.md +9 -10
  7. package/agents/plastic-spec-specialist.md +9 -6
  8. package/bin/plastic.js +2 -2
  9. package/hooks/check-update +1 -1
  10. package/hooks/continue +1 -1
  11. package/package.json +1 -1
  12. package/scripts/dashboard.rb +29 -24
  13. package/scripts/doctor.rb +188 -9
  14. package/scripts/end-intent +330 -0
  15. package/scripts/hook-code-gate +1 -1
  16. package/scripts/hook-continue +2 -2
  17. package/scripts/hook-create-gate +2 -2
  18. package/scripts/hook-session-start +1 -1
  19. package/scripts/install.rb +2 -1
  20. package/scripts/lib/bridge.rb +116 -3
  21. package/scripts/lib/dashboard_banner.rb +8 -9
  22. package/scripts/lib/installer_core.rb +17 -8
  23. package/scripts/lib/legacy_bookend_amnesty.rb +35 -0
  24. package/scripts/lib/release_guard.rb +62 -0
  25. package/scripts/lib/roadmap_queue.rb +285 -0
  26. package/scripts/lib/roadmap_savepoint.rb +213 -0
  27. package/scripts/lib/store_provisioning.rb +1 -1
  28. package/scripts/lib/worktree.rb +21 -0
  29. package/scripts/new-intent +2 -1
  30. package/scripts/read-config +3 -3
  31. package/scripts/roadmap-next +44 -0
  32. package/scripts/roadmap-savepoint +64 -0
  33. package/scripts/{versions.rb → rollback.rb} +33 -41
  34. package/scripts/update.rb +1 -1
  35. package/skills/_active-intent-gate.md +1 -1
  36. package/skills/_decision-tables.md +50 -0
  37. package/skills/auto/SKILL.md +69 -68
  38. package/skills/auto/evals/evals.json +4 -4
  39. package/skills/auto/references/agent-architecture.md +2 -2
  40. package/skills/continuing/SKILL.md +23 -130
  41. package/skills/continuing/evals/evals.json +26 -80
  42. package/skills/dashboard/SKILL.md +18 -15
  43. package/skills/dashboard/references/classification.md +3 -3
  44. package/skills/dashboard/templates/dashboard-global.md +8 -23
  45. package/skills/dashboard/templates/dashboard-project.md +7 -26
  46. package/skills/doctor/SKILL.md +3 -3
  47. package/skills/install/SKILL.md +10 -10
  48. package/skills/{brainstorming → intent-brainstorming}/SKILL.md +43 -45
  49. package/skills/intent-brainstorming/evals/evals.json +67 -0
  50. package/skills/{brainstorming → intent-brainstorming}/references/design-principles.md +12 -17
  51. package/skills/intent-continuing/SKILL.md +99 -0
  52. package/skills/intent-continuing/evals/evals.json +145 -0
  53. package/skills/intent-continuing/references/context-management.md +28 -0
  54. package/skills/{creating-intent → intent-creating}/SKILL.md +3 -3
  55. package/skills/{creating-intent → intent-creating}/evals/evals.json +1 -1
  56. package/skills/{intent-discovery → intent-discovering}/SKILL.md +1 -1
  57. package/skills/intent-ending/SKILL.md +151 -0
  58. package/skills/intent-ending/evals/evals.json +74 -0
  59. package/skills/{executing-plan → intent-executing}/SKILL.md +75 -15
  60. package/skills/intent-executing/evals/evals.json +66 -0
  61. package/skills/{brainstorming-grill-me → intent-grilling}/SKILL.md +4 -4
  62. package/skills/{linking-intents → intent-linking}/SKILL.md +1 -1
  63. package/skills/{linking-intents → intent-linking}/evals/evals.json +1 -1
  64. package/skills/{lock → intent-locking}/SKILL.md +1 -1
  65. package/skills/{writing-plans → intent-planning}/SKILL.md +48 -20
  66. package/skills/intent-planning/evals/evals.json +66 -0
  67. package/skills/{writing-plans → intent-planning}/references/plan-format.md +31 -7
  68. package/skills/{research → intent-researching}/SKILL.md +2 -2
  69. package/skills/{research → intent-researching}/evals/evals.json +1 -1
  70. package/skills/{savepoint → intent-savepoint}/SKILL.md +13 -1
  71. package/skills/intent-speccing/SKILL.md +69 -0
  72. package/skills/intent-speccing/evals/evals.json +126 -0
  73. package/skills/intent-speccing/references/per-section-fill-rules.md +92 -0
  74. package/skills/intent-speccing/references/self-verify-checklist.md +38 -0
  75. package/skills/intent-starting/SKILL.md +2 -2
  76. package/skills/intent-starting/evals/evals.json +2 -2
  77. package/skills/project-continuing/SKILL.md +104 -0
  78. package/skills/project-continuing/evals/evals.json +100 -0
  79. package/skills/project-continuing/references/board-fill.md +33 -0
  80. package/skills/{creating-project → project-creating}/SKILL.md +2 -2
  81. package/skills/releasing/SKILL.md +66 -14
  82. package/skills/releasing/references/release-lines.md +105 -0
  83. package/skills/roadmap/SKILL.md +7 -1
  84. package/skills/roadmap/references/file-format.md +30 -1
  85. package/skills/roadmap/references/operations.md +26 -6
  86. package/skills/roadmap-continuing/SKILL.md +85 -0
  87. package/skills/roadmap-continuing/evals/evals.json +82 -0
  88. package/skills/roadmap-continuing/references/liveness-ranking.md +56 -0
  89. package/skills/{versions → rollback}/SKILL.md +30 -20
  90. package/skills/{creating-skills → skill-creating}/SKILL.md +2 -2
  91. package/skills/{creating-skills → skill-creating}/evals/evals.json +5 -5
  92. package/skills/{creating-skills → skill-creating}/references/progressive-disclosure.md +2 -2
  93. package/skills/{evaluating-skills → skill-evaluating}/SKILL.md +1 -1
  94. package/skills/{evaluating-skills → skill-evaluating}/evals/evals.json +3 -3
  95. package/skills/{intent-curator → store-curating}/SKILL.md +6 -7
  96. package/skills/{intent-curator → store-curating}/evals/evals.json +1 -1
  97. package/skills/{managing-index → store-indexing}/SKILL.md +6 -7
  98. package/skills/{managing-index → store-indexing}/evals/evals.json +1 -1
  99. package/skills/{add-project-store → store-provisioning}/SKILL.md +2 -2
  100. package/skills/tutorial/SKILL.md +65 -0
  101. package/skills/tutorial/evals/evals.json +186 -0
  102. package/skills/tutorial/references/track-1-guided.md +123 -0
  103. package/skills/tutorial/references/track-2-auto.md +95 -0
  104. package/skills/tutorial/references/track-3-projects-and-roadmaps.md +110 -0
  105. package/skills/uninstall/SKILL.md +2 -2
  106. package/skills/update/SKILL.md +3 -3
  107. package/templates/agents.md +7 -7
  108. package/templates/config.yml +2 -1
  109. package/templates/index.md +4 -1
  110. package/skills/brainstorming/evals/evals.json +0 -22
  111. package/skills/savepoint/references/context-management.md +0 -32
  112. /package/skills/{creating-intent → intent-creating}/references/lifecycle.md +0 -0
  113. /package/skills/{creating-intent → intent-creating}/references/wikilinks.md +0 -0
  114. /package/skills/{executing-plan → intent-executing}/code-quality-reviewer-prompt.md +0 -0
  115. /package/skills/{executing-plan → intent-executing}/implementer-prompt.md +0 -0
  116. /package/skills/{executing-plan → intent-executing}/spec-reviewer-prompt.md +0 -0
  117. /package/skills/{linking-intents → intent-linking}/references/zettelkasten.md +0 -0
  118. /package/skills/{continuing → intent-savepoint}/references/context-management.md +0 -0
  119. /package/skills/{creating-project → project-creating}/references/hubs-projects.md +0 -0
  120. /package/skills/{creating-project → project-creating}/references/project-scaffolding.md +0 -0
  121. /package/skills/{creating-skills → skill-creating}/references/agents.md +0 -0
  122. /package/skills/{creating-skills → skill-creating}/references/evals.md +0 -0
  123. /package/skills/{creating-skills → skill-creating}/references/hooks.md +0 -0
  124. /package/skills/{creating-skills → skill-creating}/references/scripts.md +0 -0
  125. /package/skills/{creating-skills → skill-creating}/references/skills.md +0 -0
  126. /package/skills/{creating-skills → skill-creating}/scripts/scaffold.rb +0 -0
  127. /package/skills/{evaluating-skills → skill-evaluating}/assets/eval-template.json +0 -0
  128. /package/skills/{evaluating-skills → skill-evaluating}/references/convention-checks.md +0 -0
  129. /package/skills/{evaluating-skills → skill-evaluating}/references/eval-methodology.md +0 -0
  130. /package/skills/{managing-index → store-indexing}/references/zettelkasten-linking.md +0 -0
@@ -0,0 +1,67 @@
1
+ {
2
+ "skill_name": "plastic-intent-brainstorming",
3
+ "notes": "Intent 66a. Spec for the QMD-first step in the Why/explore-context phase (surface prior decisions/specs/outcomes before grep/Read). Runner is intent 76; spec only. Intent 164 extended this file with the prose-grilling, conflict-supersession, and handoff-to-speccing scenarios; evals 2-4 are pending a real observed run per the plastic-evaluating-skills convention.",
4
+ "evals": [
5
+ {
6
+ "id": 1,
7
+ "scope": "behavior",
8
+ "set": "validation",
9
+ "prompt": "QMD is present. Brainstorming the active intent during the Why phase, the agent needs prior decisions and specs on caching.",
10
+ "expected_output": "In the explore-project-context (Why) step, before scanning the store with grep/Read, runs `ruby ~/.plastic/scripts/qmd-sync search \"caching decisions\"` to surface prior decisions, specs, or outcomes, then opens the authoritative intent file for any hit it acts on. No-op fallback to INDEX.md / file scan when QMD is absent.",
11
+ "files": [],
12
+ "assertions": [
13
+ {
14
+ "type": "human",
15
+ "check": "qmd-sync search is run during Why before grep/Read; authoritative file opened for any hit",
16
+ "observed": "SKILL.md (or agent file) carries the QMD-first step: run qmd-sync search before grep/Read, then open the authoritative file; no-op fallback when QMD is absent",
17
+ "result": "pass"
18
+ }
19
+ ]
20
+ },
21
+ {
22
+ "id": 2,
23
+ "scope": "behavior",
24
+ "set": "validation",
25
+ "prompt": "During Why exploration for intent X, the owner first rules that a setting ships as a CLI flag. Later in the same session, after more discussion, the owner rules that it should ship as a config-file setting instead, explicitly reversing the earlier call.",
26
+ "expected_output": "The skill persists BOTH rulings as separate insight-append calls with --stage Why: one for the CLI-flag ruling when it was made, and a second for the config-file ruling that names the CLI-flag ruling as superseded and states that this ruling supersedes it. Neither call is skipped, merged, or batched.",
27
+ "files": [],
28
+ "assertions": [
29
+ {
30
+ "type": "human",
31
+ "check": "two separate `ruby ~/.plastic/scripts/insight-append {intent_dir} \"<ruling text>\" --stage Why --author human` calls are made, one per ruling, immediately as each ruling lands; the second insight names the superseded CLI-flag ruling and states supersession",
32
+ "result": "expect-pass"
33
+ }
34
+ ]
35
+ },
36
+ {
37
+ "id": 3,
38
+ "scope": "behavior",
39
+ "set": "train",
40
+ "prompt": "Brainstorming a new intent about notification delivery, the agent needs to learn the owner's preferred channel (email, push, or SMS).",
41
+ "expected_output": "The agent asks a single conversational prose question about the preferred channel, one at a time, phrased as a sentence rather than a bulleted or lettered multiple-choice menu.",
42
+ "files": [],
43
+ "assertions": [
44
+ {
45
+ "type": "human",
46
+ "check": "the question is prose, not a chip/lettered multiple-choice menu; only one question is asked per message",
47
+ "result": "expect-pass"
48
+ }
49
+ ]
50
+ },
51
+ {
52
+ "id": 4,
53
+ "scope": "behavior",
54
+ "set": "train",
55
+ "prompt": "Design for intent Y is presented and the owner has ruled on every open section.",
56
+ "expected_output": "The skill states the enriched Why is captured (Context, Decisions, one insight per ruling) and invokes /plastic-intent-speccing as the handoff. It does not write spec.md itself.",
57
+ "files": [],
58
+ "assertions": [
59
+ {
60
+ "type": "code",
61
+ "check": "no spec.md write action is taken by this skill; the terminal message names /plastic-intent-speccing and states spec.md is not authored here",
62
+ "result": "expect-pass"
63
+ }
64
+ ]
65
+ }
66
+ ]
67
+ }
@@ -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-8; this
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
- "Ask clarifying questions" [shape=box];
29
+ "Grill in prose" [shape=box];
30
30
  "Propose 2-3 approaches" [shape=box];
31
31
  "Present design sections" [shape=box];
32
- "User approves design?" [shape=diamond];
33
- "Write spec" [shape=box];
34
- "Spec self-review\n(fix inline)" [shape=box];
35
- "User reviews spec?" [shape=diamond];
36
- "Invoke plastic-writing-plans" [shape=doublecircle];
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" -> "User approves design?";
42
- "User approves design?" -> "Present design sections" [label="no, revise"];
43
- "User approves design?" -> "Write spec" [label="yes"];
44
- "Write spec" -> "Spec self-review\n(fix inline)";
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
  ```
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: plastic-intent-continuing
3
+ description: >-
4
+ Use when a specific intent is named to resume, by id or by description, or on `continuing
5
+ --intent {id}`. Reads that intent's savepoint ledger and hands off to plastic-intent-starting.
6
+ The general "continue" / new-session triggers belong to the plastic-continuing router, not
7
+ here, so a bare "continue" does not settle on this skill directly. Boot (health check, core
8
+ context, version, statusline) is owned by the SessionStart hook, not this skill. Does not
9
+ drive work autonomously (that is plastic-auto).
10
+ user-invocable: true
11
+ ---
12
+
13
+ # Continuing (intent route)
14
+
15
+ `plastic-intent-continuing` is the intent route of `plastic-continuing`. It resumes ONE
16
+ specific intent by its savepoint ledger, then hands off to `plastic-intent-starting`. It does
17
+ NOT land on a dashboard and does NOT execute work autonomously (that is `plastic-auto`); both
18
+ of those are other routes' jobs.
19
+
20
+ **Boot is not this skill's job.** The `hook-session-start` hook already runs by construction on
21
+ every session start: it runs the core health check (`doctor --core`), primes `PLASTIC.md` +
22
+ store/project state, and prints the `Plastic Core loaded - v{version}` banner. The
23
+ `plastic-statusline` hook sets the statusline. So by the time this skill runs, core is loaded
24
+ and healthy (or the banner already warned otherwise). This skill picks up from there and
25
+ resumes the named intent. This is the seam future continue-flags build on (see [[39]]).
26
+
27
+ ## When to Use
28
+ - A specific intent is named to resume, by id or by description
29
+ - `continuing --intent {id}`
30
+
31
+ ## Determine Store
32
+
33
+ 1. **Global store** - `~/.plastic/INDEX.md` exists → global mode.
34
+ 2. **Local store** - a project store under `~/.plastic/projects/{slug}/` whose registered
35
+ path (in `~/.plastic/projects.yml`) matches the current working directory → project mode.
36
+ The SessionStart hook already detects this; here you only need the slug to scope the
37
+ named intent's store.
38
+ 3. If neither exists → announce "No Plastic store found. Run /plastic-install."
39
+
40
+ ## Conditional Ledger-Resume
41
+
42
+ Fires ONLY when the user explicitly asks to continue a SPECIFIC intent, or an agent is
43
+ instructed to continue one. It is not part of every boot.
44
+
45
+ QMD-first (when available): when the user names the intent by description rather than id, before
46
+ scanning the store with grep/Read run `ruby ~/.plastic/scripts/qmd-sync search "<terms>"` to
47
+ surface the candidate intent, then open the authoritative intent file for the hit you resume. The
48
+ command is a no-op when QMD is absent, so fall back to the existing INDEX.md / file scan.
49
+
50
+ For that intent's directory:
51
+
52
+ 1. **Read `savepoint.md` FIRST (intent 81).** It is a deterministic, append-only ledger
53
+ (one line per event, newest at the bottom): `{utc-iso8601} {Stage} {milestone}`. Classify
54
+ the state from the **last line** alone, then verify ONLY that line's artifact. The bookends
55
+ are fixed: first line `What created`, last line either a cycle position or
56
+ `Done delivered|abandoned`.
57
+
58
+ | Last line | State | Verify only |
59
+ |---|---|---|
60
+ | `What {id}--{slug}.md` | born / parked | intent file exists |
61
+ | `Why started` | Why entered, no spec yet | spec.md not yet real; continue Why |
62
+ | `Why spec.md created` | Why done | spec.md present; continue to How |
63
+ | `How started` / `How plan.md created` | How in progress | plan.md; continue How |
64
+ | `How checklist.md created` / `Exec started` | ready for / in Exec | plan.md + checklist.md present; continue Exec |
65
+ | `Exec outcome.md created` | Exec done | outcome.md present; ready to complete |
66
+ | `Done delivered` / `Done abandoned` | terminal | do NOT cycle-resume; INDEX is authoritative |
67
+
68
+ 2. **Verify the stage file.** Confirm only the last line's artifact exists and is non-empty
69
+ (ledger `How plan.md created` → `plan.md` must be present and non-empty). Do not re-probe
70
+ every lifecycle file.
71
+ 3. **Drift handling.** If the ledger's last line disagrees with files-on-disk, rebuild the
72
+ ledger from filesystem state and note the correction. A rebuilt ledger is the file-landing
73
+ skeleton (no `started`/`Done` lines), which still pins cycle position:
74
+ ```bash
75
+ ruby -r ~/.plastic/scripts/lib/bridge -e 'Bridge.rebuild_savepoint("<intent_dir>")'
76
+ ```
77
+ 4. **Derive the next step:**
78
+ - First unchecked item in `checklist.md` if it exists, else
79
+ - "advance to the next lifecycle stage" (e.g. ledger shows Why/spec.md → next is How).
80
+ - The newest `## Insights` entry supplies human-readable context (Insights are
81
+ append-only, newest at the bottom).
82
+ 5. **Announce, then hand off to `plastic-intent-starting`:**
83
+ ```
84
+ Resuming intent [ID] - [name]
85
+ Store: [global | project:<slug> | local]
86
+ Stage: [from ledger last line]
87
+ Next step: [first unchecked checklist item | advance to <stage>]
88
+ Context: [newest ## Insights entry]
89
+ Drift: [none | ledger rebuilt from filesystem]
90
+ ```
91
+ Hand off to `plastic-intent-starting`: it takes the lock, boards at this station, and is
92
+ where the single "auto or guided?" ask for the intent route lives, asked there exactly
93
+ once and never duplicated here. Its auto branch is the one that hands off to `plastic-auto`;
94
+ this skill never hands to `plastic-auto` directly.
95
+
96
+ ## References
97
+
98
+ - Read `references/context-management.md` for the save/continue protocol and for
99
+ debugging the resume flow.
@@ -0,0 +1,145 @@
1
+ {
2
+ "skill_name": "plastic-intent-continuing",
3
+ "notes": "Intent 158a1: slimmed to the specific-intent resume route of plastic-continuing (D8, extract not duplicate). Bare 'continue' now belongs to the router; triggering evals 1-4 were recast so this skill's positives always name a specific intent, and eval 4 asserts bare 'continue' does NOT settle here directly. Behavior eval 11 (dashboard selection) was removed, relocated to plastic-project-continuing's evals. Behavior eval 15 is new: the terminal handoff goes to plastic-intent-starting, not directly to plastic-auto. Scopes: description triggering (1-8) and behavior/convention compliance of the ledger-resume skill (9-15).",
4
+ "results": {
5
+ "triggering": { "cases": 8, "passed": 8, "run": "2026-07-10, one subagent per case" },
6
+ "behavior": { "cases": 7, "passed": 7, "evidence": "convention checks against skills/intent-continuing/SKILL.md after the 158a1 extraction" }
7
+ },
8
+ "evals": [
9
+ {
10
+ "id": 1, "scope": "triggering", "set": "train",
11
+ "prompt": "continue intent 4a",
12
+ "expected_output": "Activates plastic-intent-continuing (a specific intent named by id).",
13
+ "files": [],
14
+ "assertions": [
15
+ { "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
16
+ ]
17
+ },
18
+ {
19
+ "id": 2, "scope": "triggering", "set": "train",
20
+ "prompt": "resume the statusline-coloring intent",
21
+ "expected_output": "Activates plastic-intent-continuing (a specific intent named by description).",
22
+ "files": [],
23
+ "assertions": [
24
+ { "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
25
+ ]
26
+ },
27
+ {
28
+ "id": 3, "scope": "triggering", "set": "validation",
29
+ "prompt": "continuing --intent 96",
30
+ "expected_output": "Activates plastic-intent-continuing (the --intent form).",
31
+ "files": [],
32
+ "assertions": [
33
+ { "type": "code", "check": "router CHOICE == plastic-intent-continuing", "observed": "plastic-intent-continuing", "result": "pass" }
34
+ ]
35
+ },
36
+ {
37
+ "id": 4, "scope": "triggering", "set": "train",
38
+ "prompt": "continue",
39
+ "expected_output": "Does NOT settle on plastic-intent-continuing directly. Bare 'continue' with no specific intent named belongs to the plastic-continuing router, which defaults to plastic-project-continuing.",
40
+ "files": [],
41
+ "assertions": [
42
+ { "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "plastic-continuing", "result": "pass" }
43
+ ]
44
+ },
45
+ {
46
+ "id": 5, "scope": "triggering", "set": "train",
47
+ "prompt": "continue delivering this intent autonomously, don't ask me",
48
+ "expected_output": "Does NOT settle on plastic-intent-continuing for execution. Shares 'continue' but the autonomous-delivery intent routes to plastic-auto.",
49
+ "files": [],
50
+ "assertions": [
51
+ { "type": "code", "check": "router CHOICE == plastic-auto", "observed": "plastic-auto", "result": "pass" }
52
+ ]
53
+ },
54
+ {
55
+ "id": 6, "scope": "triggering", "set": "validation",
56
+ "prompt": "continue the for-loop to the next iteration in this function",
57
+ "expected_output": "Does NOT activate plastic-intent-continuing. Near-miss: shares 'continue' but is a code-editing task.",
58
+ "files": [],
59
+ "assertions": [
60
+ { "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "none", "result": "pass" }
61
+ ]
62
+ },
63
+ {
64
+ "id": 7, "scope": "triggering", "set": "train",
65
+ "prompt": "resume the paused background download",
66
+ "expected_output": "Does NOT activate plastic-intent-continuing. Near-miss: shares 'resume' but is unrelated to Plastic sessions.",
67
+ "files": [],
68
+ "assertions": [
69
+ { "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "none", "result": "pass" }
70
+ ]
71
+ },
72
+ {
73
+ "id": 8, "scope": "triggering", "set": "validation",
74
+ "prompt": "what's the dashboard look like right now",
75
+ "expected_output": "Does NOT activate plastic-intent-continuing directly; an overview request without a specific intent named is a dashboard/project-board task.",
76
+ "files": [],
77
+ "assertions": [
78
+ { "type": "code", "check": "router CHOICE != plastic-intent-continuing", "observed": "plastic-dashboard", "result": "pass" }
79
+ ]
80
+ },
81
+ {
82
+ "id": 9, "scope": "behavior", "set": "train",
83
+ "prompt": "Does the skill defer boot to the SessionStart hook rather than running it itself?",
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/intent-continuing/SKILL.md"],
86
+ "assertions": [
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
+ ]
89
+ },
90
+ {
91
+ "id": 10, "scope": "behavior", "set": "train",
92
+ "prompt": "Does the skill avoid running doctor / setting the statusline itself?",
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/intent-continuing/SKILL.md"],
95
+ "assertions": [
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
+ ]
98
+ },
99
+ {
100
+ "id": 11, "scope": "behavior", "set": "validation",
101
+ "prompt": "Is ledger-resume conditional and ledger-driven?",
102
+ "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.",
103
+ "files": ["skills/intent-continuing/SKILL.md"],
104
+ "assertions": [
105
+ { "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" }
106
+ ]
107
+ },
108
+ {
109
+ "id": 12, "scope": "behavior", "set": "validation",
110
+ "prompt": "Are the stale prose-savepoint fields gone?",
111
+ "expected_output": "No 'In progress' / 'Blockers' fields read from a prose savepoint remain; the ledger model is used instead.",
112
+ "files": ["skills/intent-continuing/SKILL.md"],
113
+ "assertions": [
114
+ { "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" }
115
+ ]
116
+ },
117
+ {
118
+ "id": 13, "scope": "behavior", "set": "validation",
119
+ "prompt": "Is the 'Determine Store' local-store gap filled?",
120
+ "expected_output": "Step 2 of Determine Store describes local/project-store detection (no empty step).",
121
+ "files": ["skills/intent-continuing/SKILL.md"],
122
+ "assertions": [
123
+ { "type": "convention", "check": "Determine Store step 2 documents local/project store detection via projects.yml + CWD match", "observed": "filled", "result": "pass" }
124
+ ]
125
+ },
126
+ {
127
+ "id": 14, "scope": "behavior", "set": "validation",
128
+ "prompt": "QMD is present. The user says: continue the work on the statusline coloring (names the intent by description, not id).",
129
+ "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.",
130
+ "files": ["skills/intent-continuing/SKILL.md"],
131
+ "assertions": [
132
+ { "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" }
133
+ ]
134
+ },
135
+ {
136
+ "id": 15, "scope": "behavior", "set": "train",
137
+ "prompt": "Does the ledger-resume's terminal handoff go to plastic-intent-starting or directly to plastic-auto?",
138
+ "expected_output": "Step 5 announces state then hands off to plastic-intent-starting, which takes the lock and asks 'auto or guided?' exactly once; plastic-intent-starting's own auto branch is the one that hands to plastic-auto. This skill never hands to plastic-auto directly.",
139
+ "files": ["skills/intent-continuing/SKILL.md"],
140
+ "assertions": [
141
+ { "type": "convention", "check": "step 5 hands off to plastic-intent-starting, not plastic-auto; the single ask is attributed to plastic-intent-starting", "observed": "present in 'Conditional Ledger-Resume' step 5", "result": "pass" }
142
+ ]
143
+ }
144
+ ]
145
+ }
@@ -0,0 +1,28 @@
1
+ # Context Management (Save, then resume-flow debugging)
2
+
3
+ ## Save Point
4
+ Triggered by PreCompact hook or manually:
5
+ 1. Find active intent(s) from `~/.plastic/INDEX.md`
6
+ 2. Update active intent's `checklist.md` (check off completed items)
7
+ 3. Update active intent's `savepoint.md` (in-progress, next steps, blockers, discoveries)
8
+ 4. Add observations to `## Insights`
9
+ 5. Update INDEX.md
10
+ 6. Commit: `cd ~/.plastic && git add . && git commit -m "chore: savepoint - [intent name]"`
11
+ 7. Notify user to `/clear`
12
+
13
+ ## Debugging the resume flow
14
+
15
+ When a resume looks wrong (the announced stage does not match what is on disk, or the next
16
+ step looks stale):
17
+
18
+ 1. Read `savepoint.md`'s last line directly; that line alone is the source of truth for stage
19
+ (see `SKILL.md`'s `## Conditional Ledger-Resume` for the full state table).
20
+ 2. Confirm the artifact that line implies (`plan.md`, `checklist.md`, `outcome.md`, ...) is
21
+ present and non-empty on disk.
22
+ 3. If the two disagree, the ledger has drifted: rebuild it rather than hand-editing:
23
+ `ruby -r ~/.plastic/scripts/lib/bridge -e 'Bridge.rebuild_savepoint("<intent_dir>")'`
24
+ 4. Re-read the rebuilt last line and re-derive the next step from `checklist.md`'s first
25
+ unchecked item.
26
+
27
+ The general "land on the board / priority order / stale future intents" flow now lives in
28
+ `plastic-project-continuing`; this file no longer duplicates it.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: plastic-creating-intent
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-intents` skill and `scripts/link-suggest`.
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-project` skill; it owns project directory creation, AGENTS.md
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-intent",
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
  {
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: plastic-intent-discovery
2
+ name: plastic-intent-discovering
3
3
  description: >-
4
4
  What-stage context deposit at intent activation: run QMD discovery over the
5
5
  intent's chain/sources and related parked intents, and write findings to
@@ -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.