@zalom/plastic 1.0.0-beta.9 → 1.0.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 +133 -0
- package/PLASTIC.md +398 -82
- package/README.md +99 -82
- package/agents/plastic-brainstorming.md +12 -9
- package/agents/plastic-enforcer.md +52 -12
- package/agents/plastic-executor.md +10 -10
- package/agents/plastic-future-intent-researcher.md +4 -8
- package/agents/plastic-intent-curator.md +12 -14
- package/agents/plastic-intent-discovery.md +35 -0
- package/agents/plastic-planner.md +15 -10
- package/agents/plastic-spec-specialist.md +15 -10
- package/bin/plastic.js +7 -3
- package/hooks/code-gate +10 -1
- package/hooks/hooks.json +28 -3
- package/hooks/lock-gate +21 -0
- package/hooks/retrieval-gate +10 -0
- package/hooks/savepoint-pre +10 -0
- package/hooks/statusline +48 -6
- package/package.json +2 -1
- package/scripts/agent-report +21 -0
- package/scripts/dashboard.rb +98 -23
- package/scripts/doctor.rb +232 -5
- package/scripts/hook-auto-arm +1 -1
- package/scripts/hook-bash-gate +22 -4
- package/scripts/hook-code-gate +11 -6
- package/scripts/hook-continue +17 -0
- package/scripts/hook-create-gate +45 -9
- package/scripts/hook-gate-check +24 -23
- package/scripts/hook-lock-gate +83 -0
- package/scripts/hook-retrieval-gate +148 -0
- package/scripts/hook-savepoint-pre +32 -0
- package/scripts/hook-session-start +1 -1
- package/scripts/insight-append +51 -0
- package/scripts/install.rb +44 -7
- package/scripts/lib/agent_models.rb +43 -0
- package/scripts/lib/bridge.rb +924 -84
- package/scripts/lib/dashboard_banner.rb +42 -0
- package/scripts/lib/hook_registry.rb +95 -0
- package/scripts/lib/insights.rb +86 -0
- package/scripts/lib/installer_core.rb +100 -60
- package/scripts/lib/link_suggestions.rb +319 -0
- package/scripts/lib/lock.rb +375 -0
- package/scripts/lib/power_tools.rb +22 -21
- package/scripts/lib/preflight.rb +79 -0
- package/scripts/lib/qmd_sync.rb +15 -0
- package/scripts/lib/retrieval_gate.rb +211 -0
- package/scripts/lib/worktree.rb +384 -0
- package/scripts/link-suggest +213 -0
- package/scripts/new-intent +9 -1
- package/scripts/plastic-lock +164 -0
- package/scripts/read-config +4 -0
- package/scripts/spawn-preamble +11 -3
- package/scripts/update.rb +16 -7
- package/skills/auto/SKILL.md +126 -19
- package/skills/auto/references/agent-architecture.md +7 -4
- package/skills/auto/references/agent-report-contract.md +36 -1
- package/skills/auto/references/end-tail.md +56 -0
- package/skills/auto/references/human-report-contract.md +55 -0
- package/skills/auto/references/tiers.md +77 -0
- package/skills/brainstorming/SKILL.md +7 -34
- package/skills/brainstorming/references/design-principles.md +49 -0
- package/skills/continuing/SKILL.md +26 -7
- package/skills/creating-intent/SKILL.md +13 -28
- package/skills/creating-project/SKILL.md +11 -74
- package/skills/creating-project/references/project-scaffolding.md +97 -0
- package/skills/creating-skills/SKILL.md +65 -0
- package/skills/creating-skills/evals/evals.json +108 -0
- package/skills/creating-skills/references/agents.md +168 -0
- package/skills/creating-skills/references/evals.md +41 -0
- package/skills/creating-skills/references/hooks.md +248 -0
- package/skills/creating-skills/references/progressive-disclosure.md +176 -0
- package/skills/creating-skills/references/scripts.md +166 -0
- package/skills/creating-skills/references/skills.md +165 -0
- package/skills/creating-skills/scripts/scaffold.rb +313 -0
- package/skills/dashboard/SKILL.md +13 -11
- package/skills/dashboard/references/classification.md +22 -0
- package/skills/doctor/SKILL.md +10 -7
- package/skills/executing-plan/SKILL.md +4 -4
- package/skills/humanizer/SKILL.md +39 -0
- package/skills/humanizer/evals/evals.json +70 -0
- package/skills/humanizer/references/always-on-snippet.md +9 -0
- package/skills/humanizer/references/examples.md +48 -0
- package/skills/install/SKILL.md +75 -84
- package/skills/intent-curator/SKILL.md +5 -1
- package/skills/intent-discovery/SKILL.md +47 -0
- package/skills/intent-starting/SKILL.md +130 -0
- package/skills/intent-starting/evals/evals.json +117 -0
- package/skills/intent-starting/references/boarding-matrix.md +35 -0
- package/skills/linking-intents/SKILL.md +48 -12
- package/skills/lock/SKILL.md +41 -0
- package/skills/managing-index/SKILL.md +6 -0
- package/skills/releasing/SKILL.md +44 -29
- package/skills/releasing/references/promotion-and-tagging.md +60 -0
- package/skills/roadmap/SKILL.md +51 -0
- package/skills/roadmap/references/file-format.md +91 -0
- package/skills/roadmap/references/operations.md +78 -0
- package/skills/uninstall/SKILL.md +29 -11
- package/skills/update/SKILL.md +34 -23
- package/skills/versions/SKILL.md +27 -12
- package/skills/writing-plans/SKILL.md +10 -88
- package/skills/writing-plans/references/plan-format.md +102 -0
- package/templates/config.yml +8 -0
- package/templates/outcome.md +3 -0
- package/templates/revisions.md +58 -0
- package/templates/roadmap.md +30 -0
- package/skills/writing-instructions/SKILL.md +0 -159
- package/skills/writing-instructions/references/agentskills-spec.md +0 -135
package/skills/install/SKILL.md
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plastic-install
|
|
3
|
-
description: Use when initializing Plastic globally (~/.plastic/) or locally in a project, or to re-install/repair a broken installation. Accepts channel flags (--alpha, --beta, --latest) to select release channel.
|
|
3
|
+
description: Use when initializing Plastic globally (~/.plastic/) or locally in a project, or to re-install/repair a broken installation. Accepts channel flags (--alpha, --beta, --latest) to select release channel. First install defaults to --beta; reinstalls match the already-installed channel. Global install is recommended: it creates the global intent store as a git-backed repository. Local install creates .plastic/ in the current project for testing.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Install Plastic
|
|
7
7
|
|
|
8
|
-
> **Recommended path:** for a first install, run `npx @zalom/plastic@
|
|
9
|
-
> in your shell (or `bunx @zalom/plastic@
|
|
8
|
+
> **Recommended path:** for a first install, run `npx -y @zalom/plastic@beta install --claude`
|
|
9
|
+
> in your shell (or `bunx -y @zalom/plastic@beta install --claude` if you use Bun). This skill
|
|
10
10
|
> exists to **re-install or repair** an existing setup from inside the agent, and to
|
|
11
11
|
> drive interactive global configuration. Whenever this skill performs an install or
|
|
12
12
|
> re-install, it **runs `/plastic-doctor` afterward** and reports the result.
|
|
13
13
|
|
|
14
|
+
## Channel rule
|
|
15
|
+
|
|
16
|
+
If Plastic is installed, derive `<channel>` from `~/.plastic/VERSION`: a version containing
|
|
17
|
+
`-alpha` means `@alpha`, `-beta` means `@beta`, otherwise `@latest`. If not installed
|
|
18
|
+
(first install), default to `@beta`. The user can always override with
|
|
19
|
+
`--alpha` / `--beta` / `--latest`.
|
|
20
|
+
|
|
14
21
|
## Re-install / repair
|
|
15
22
|
|
|
16
23
|
If Plastic is already installed but something is broken (skills missing, hooks not
|
|
17
|
-
firing, leftover legacy plugin), re-run the installer
|
|
24
|
+
firing, leftover legacy plugin), re-run the installer, it is idempotent, prunes
|
|
18
25
|
files that no longer ship, and removes any legacy plugin/marketplace layout:
|
|
19
26
|
|
|
20
27
|
```bash
|
|
21
|
-
npx @zalom/plastic
|
|
28
|
+
npx -y @zalom/plastic@<channel> install --reinstall --claude
|
|
22
29
|
```
|
|
23
30
|
|
|
24
31
|
Then **run `/plastic-doctor`** and report what it found.
|
|
@@ -27,22 +34,22 @@ Then **run `/plastic-doctor`** and report what it found.
|
|
|
27
34
|
|
|
28
35
|
| Flag | Behavior |
|
|
29
36
|
|------|----------|
|
|
30
|
-
| `--latest` | Install from stable channel
|
|
31
|
-
| `--beta` | Install from beta channel |
|
|
32
|
-
| `--alpha` | Install from alpha channel |
|
|
37
|
+
| `--latest` | Install from the stable channel |
|
|
38
|
+
| `--beta` | Install from the beta channel (default on a first install) |
|
|
39
|
+
| `--alpha` | Install from the alpha channel |
|
|
33
40
|
|
|
34
41
|
When invoked from within Claude Code (re-install or channel switch), the skill
|
|
35
42
|
runs the appropriate npx command:
|
|
36
43
|
|
|
37
44
|
```bash
|
|
38
|
-
# Stable
|
|
39
|
-
npx @zalom/plastic install --claude
|
|
45
|
+
# Stable
|
|
46
|
+
npx -y @zalom/plastic@latest install --claude
|
|
40
47
|
|
|
41
|
-
# Beta
|
|
42
|
-
npx @zalom/plastic@beta install --claude
|
|
48
|
+
# Beta (default on a first install)
|
|
49
|
+
npx -y @zalom/plastic@beta install --claude
|
|
43
50
|
|
|
44
51
|
# Alpha
|
|
45
|
-
npx @zalom/plastic@alpha install --claude
|
|
52
|
+
npx -y @zalom/plastic@alpha install --claude
|
|
46
53
|
```
|
|
47
54
|
|
|
48
55
|
The installed version and channel are recorded in `~/.plastic/VERSION`.
|
|
@@ -55,105 +62,80 @@ Run `/plastic-install` with no arguments.
|
|
|
55
62
|
|
|
56
63
|
#### Procedure
|
|
57
64
|
|
|
58
|
-
**Step 1:
|
|
59
|
-
|
|
60
|
-
Check if `~/.plastic/INDEX.md` exists.
|
|
61
|
-
- If yes: announce "Plastic is already installed at ~/.plastic/. Run `/plastic-update` to sync core files."
|
|
62
|
-
- If no: proceed with fresh install.
|
|
65
|
+
**Step 1: Run the installer**
|
|
63
66
|
|
|
64
|
-
|
|
67
|
+
Check if `~/.plastic/VERSION` exists.
|
|
68
|
+
- If yes: announce "Plastic is already installed at ~/.plastic/. Run `/plastic-update` to
|
|
69
|
+
sync core files, or use the re-install command above to repair in place."
|
|
70
|
+
- If no: run the fresh install command (default `@beta`, or the channel the user named):
|
|
65
71
|
|
|
66
72
|
```bash
|
|
67
|
-
|
|
73
|
+
npx -y @zalom/plastic@beta install --claude
|
|
68
74
|
```
|
|
69
75
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
- `
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
This single command, via `install.rb` (`bootstrap` + `distribute`), creates `store/`,
|
|
77
|
+
`projects/`, `config.yml`, `projects.yml`, `INDEX.md`, and `AGENTS.md` under `~/.plastic/`,
|
|
78
|
+
and copies the utility scripts (`folgezettel-id`, `read-config`, and the rest of
|
|
79
|
+
`scripts/`). This skill does none of that itself; it wraps the command with the
|
|
80
|
+
interactive steps the CLI does not yet own, plus reporting and a doctor pass.
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
```markdown
|
|
78
|
-
# Plastic — Agent Instructions
|
|
82
|
+
**Statusline**
|
|
79
83
|
|
|
80
|
-
|
|
81
|
-
|
|
84
|
+
On install, if an existing statusline is already configured, Plastic asks whether to
|
|
85
|
+
keep it or switch to Plastic's (interactive sessions only). The choice is honored via
|
|
86
|
+
`--statusline keep` or `--statusline plastic`, which skips the prompt. Non-interactive
|
|
87
|
+
sessions (no tty) default to keeping the user's line: nothing is silently overwritten.
|
|
88
|
+
A fresh system with no statusline configured gets Plastic's line with no prompt.
|
|
82
89
|
|
|
83
|
-
|
|
84
|
-
may add content below.
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
```
|
|
90
|
+
**Step 2: Initialize git (retained)**
|
|
88
91
|
|
|
89
|
-
|
|
92
|
+
Only if `~/.plastic/.git` is absent (a fresh bootstrap does not init git):
|
|
90
93
|
|
|
91
|
-
Initialize git:
|
|
92
94
|
```bash
|
|
93
95
|
cd ~/.plastic && git init && git add . && git commit -m "chore: initialize Plastic global intent store"
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
Retained here because the CLI does not git-init the store yet (follow-up).
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
mkdir -p ~/.plastic/scripts
|
|
100
|
-
cp "${CLAUDE_PLUGIN_ROOT}/scripts/folgezettel-id" ~/.plastic/scripts/folgezettel-id
|
|
101
|
-
cp "${CLAUDE_PLUGIN_ROOT}/scripts/read-config" ~/.plastic/scripts/read-config
|
|
102
|
-
chmod +x ~/.plastic/scripts/folgezettel-id ~/.plastic/scripts/read-config
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
This ensures project agents can generate hashes via `~/.plastic/scripts/folgezettel-id` without depending on a specific agent's plugin cache path.
|
|
106
|
-
|
|
107
|
-
**Step 2c: Detect agent type and set preferences**
|
|
100
|
+
**Step 3: Personalize config (retained)**
|
|
108
101
|
|
|
109
102
|
Detect which agent is running:
|
|
110
|
-
- If `CLAUDE_CODE` env var is set or we're running inside Claude Code
|
|
111
|
-
- If `HERMES_HOME` env var is set
|
|
112
|
-
- Otherwise
|
|
103
|
+
- If `CLAUDE_CODE` env var is set or we're running inside Claude Code -> `agent.type: claude-code`
|
|
104
|
+
- If `HERMES_HOME` env var is set -> `agent.type: hermes`
|
|
105
|
+
- Otherwise -> ask the user: "Which AI agent are you using? (claude-code / hermes / other)"
|
|
113
106
|
|
|
114
107
|
Ask the user:
|
|
115
|
-
> "Enable Agent Teams? (experimental
|
|
116
|
-
> - Yes
|
|
117
|
-
> - No
|
|
118
|
-
|
|
119
|
-
Update `~/.plastic/config.yml` with detected/chosen values using `read-config --migrate` first to ensure v3 schema, then write the agent-specific values.
|
|
120
|
-
|
|
121
|
-
Auto-commit the config change.
|
|
122
|
-
|
|
123
|
-
**Step 2d: Configure GitHub and push preferences**
|
|
108
|
+
> "Enable Agent Teams? (experimental: parallel project work with teammates)"
|
|
109
|
+
> - Yes -> set `parallel_mode: agent-teams`
|
|
110
|
+
> - No -> set `parallel_mode: linear` (subagents only)
|
|
124
111
|
|
|
125
112
|
Inform the user:
|
|
126
|
-
> "Plastic agents can create GitHub repositories for new projects.
|
|
127
|
-
>
|
|
128
|
-
>
|
|
113
|
+
> "Plastic agents can create GitHub repositories for new projects. By default, all
|
|
114
|
+
> agent-created repos are **private**. Your global intent store (~/.plastic/) is never
|
|
115
|
+
> pushed, it stays local-only."
|
|
129
116
|
|
|
130
117
|
Ask the user:
|
|
131
118
|
> "Default visibility for agent-created repos?"
|
|
132
|
-
> - Private (recommended)
|
|
133
|
-
> - Public
|
|
134
|
-
|
|
119
|
+
> - Private (recommended) -> set `github.default_visibility: private`
|
|
120
|
+
> - Public -> set `github.default_visibility: public`
|
|
121
|
+
>
|
|
135
122
|
> "Allow agents to push to GitHub without asking?"
|
|
136
|
-
> - No (recommended)
|
|
137
|
-
> - Yes
|
|
138
|
-
|
|
139
|
-
Update `config.yml` with chosen values. Auto-commit.
|
|
140
|
-
|
|
141
|
-
**Step 3: Configure project roots**
|
|
142
|
-
|
|
143
|
-
Ask the user:
|
|
123
|
+
> - No (recommended) -> set `github.auto_push: false`
|
|
124
|
+
> - Yes -> set `github.auto_push: true`
|
|
125
|
+
>
|
|
144
126
|
> "Where do you keep your projects? Default: ~/.plastic/projects/"
|
|
145
127
|
> "Add additional roots? (e.g., ~/apps/personal/, ~/apps/companies/)"
|
|
146
128
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
129
|
+
Write each answer via `read-config --migrate` first (ensures the v3 schema), then the
|
|
130
|
+
chosen values; auto-commit each change. Retained here because the CLI writes only
|
|
131
|
+
hardcoded defaults, so these interactive choices stay in the skill.
|
|
150
132
|
|
|
151
133
|
**Step 4: Verify with doctor**
|
|
152
134
|
|
|
153
135
|
Run `/plastic-doctor` and report the result. Resolve any fixable findings before
|
|
154
136
|
announcing success.
|
|
155
137
|
|
|
156
|
-
**Step 5: Register stores with QMD (
|
|
138
|
+
**Step 5: Register stores with QMD (retained)**
|
|
157
139
|
|
|
158
140
|
QMD is an optional search layer. If it is installed, register the Plastic stores so
|
|
159
141
|
they are searchable:
|
|
@@ -165,19 +147,27 @@ ruby ~/.plastic/scripts/qmd-sync detect && ruby ~/.plastic/scripts/qmd-sync regi
|
|
|
165
147
|
`qmd-sync` no-ops cleanly when QMD is absent, so this is safe to run unconditionally.
|
|
166
148
|
It registers `plastic-global` and every project store from `projects.yml`, then indexes
|
|
167
149
|
them. Report what was registered, or that QMD was not detected and the step was skipped.
|
|
150
|
+
Retained here because the CLI does not register at install time (follow-up).
|
|
151
|
+
|
|
152
|
+
**Step 6: Report + announce**
|
|
168
153
|
|
|
169
|
-
|
|
154
|
+
```
|
|
155
|
+
Plastic install (<channel>)
|
|
156
|
+
Command: npx -y @zalom/plastic@<channel> install --claude <flags>
|
|
157
|
+
Version: none -> <installed>
|
|
158
|
+
Doctor: <summary or "all clear">
|
|
159
|
+
```
|
|
170
160
|
|
|
171
|
-
|
|
172
|
-
> Create your first intent with `/plastic-creating-intent`."
|
|
161
|
+
Then: "Read `docs/guides/your-first-intent-in-10-minutes.md` for your first intent, start to finish."
|
|
173
162
|
|
|
174
163
|
### Local Install (testing/legacy)
|
|
175
164
|
|
|
176
|
-
Run `/plastic-install --local`.
|
|
165
|
+
Run `/plastic-install --local`. `install.rb` has no `--local` verb, so this mode is
|
|
166
|
+
genuinely skill-owned.
|
|
177
167
|
|
|
178
168
|
#### Procedure
|
|
179
169
|
|
|
180
|
-
**Step 1:** Check if `.plastic/` exists in CWD
|
|
170
|
+
**Step 1:** Check if `.plastic/` exists in CWD, if so, warn and exit.
|
|
181
171
|
|
|
182
172
|
**Step 2:** Create `.plastic/` in CWD:
|
|
183
173
|
- `config.yml` from templates
|
|
@@ -192,4 +182,5 @@ Run `/plastic-install --local`.
|
|
|
192
182
|
|
|
193
183
|
**Step 4:** Commit in project: `git add .plastic/ && git commit -m "chore: initialize Plastic local store"`
|
|
194
184
|
|
|
195
|
-
**Step 5:** Announce: "Plastic initialized locally. This is a testing/legacy mode. Consider
|
|
185
|
+
**Step 5:** Announce: "Plastic initialized locally. This is a testing/legacy mode. Consider
|
|
186
|
+
`/plastic-install` for global mode."
|
|
@@ -38,6 +38,10 @@ The agent handles:
|
|
|
38
38
|
- Cluster management (create, merge, rename)
|
|
39
39
|
- Orphan detection
|
|
40
40
|
|
|
41
|
-
When an intent reaches a terminal state — moved to Completed OR Abandoned —
|
|
41
|
+
When an intent reaches a terminal state — moved to Completed OR Abandoned — do these things as the closing act of the transfer, in the canonical End-tail order (see PLASTIC.md `## Delivery Isolation and the Single-Owner Lock`):
|
|
42
|
+
|
|
43
|
+
1. Author a real `outcome.md` in the intent directory from `~/.plastic/templates/outcome.md`, with the frontmatter `disposition: delivered` for a completed intent or `disposition: abandoned` for an abandoned one. `outcome.md` is MANDATORY at every terminal, delivered and abandoned alike: on abandon it records the abandonment reason and replaces the scaffolded placeholder sentinel (never leave `outcome.md` a placeholder at a terminal).
|
|
44
|
+
2. Stamp the terminal savepoint bookend (intent 81), so the ledger's last line records the disposition: `ruby -r ~/.plastic/scripts/lib/bridge -e 'Bridge.append_terminal_savepoint("<intent_dir>", "delivered")'` (use `"abandoned"` for an abandoned intent). Idempotent.
|
|
45
|
+
3. Refresh the QMD index for the affected store LAST, after the terminal move and savepoint (no-op when QMD absent), running in the background so it never blocks: `ruby ~/.plastic/scripts/qmd-sync reindex --store <store-root> --async`.
|
|
42
46
|
|
|
43
47
|
After the agent completes, report what changed.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-intent-discovery
|
|
3
|
+
description: >-
|
|
4
|
+
What-stage context deposit at intent activation: run QMD discovery over the
|
|
5
|
+
intent's chain/sources and related parked intents, and write findings to
|
|
6
|
+
resources/discovery--<slug>.md for the Why stage to consume. Use when an intent
|
|
7
|
+
is activated (moved from Future to Active), after the lock is armed, under it,
|
|
8
|
+
and before Why begins. Never writes the intent file itself.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Intent Discovery — What-stage context deposit
|
|
12
|
+
|
|
13
|
+
Announce: "Discovering context for intent [ID] — [name]."
|
|
14
|
+
|
|
15
|
+
Runs once, at intent activation, after the lock is armed and before Why. It gathers what is
|
|
16
|
+
already known so Why does not start cold, and deposits it as a resource the
|
|
17
|
+
Why-stage brainstorming agent reads.
|
|
18
|
+
|
|
19
|
+
## When it fires
|
|
20
|
+
Inside `plastic-intent-starting`, right after the bridge is armed, under the
|
|
21
|
+
lock. Dispatched as the `plastic-intent-discovery` background agent.
|
|
22
|
+
|
|
23
|
+
## What it does
|
|
24
|
+
1. **Read the intent's links.** Load the activating intent file's `chain` and
|
|
25
|
+
`sources` frontmatter fields.
|
|
26
|
+
2. **QMD-first discovery.** Search the Plastic stores with
|
|
27
|
+
`scripts/qmd-sync search "<terms>"` (or the `qmd` skill), scoped to the
|
|
28
|
+
relevant `plastic-*` collections, across completed predecessor work named in
|
|
29
|
+
`chain`/`sources` and any related parked/future intents in INDEX.md. Fall back
|
|
30
|
+
to ripgrep over the stores only when QMD is absent.
|
|
31
|
+
3. **Deposit, never author.** Write findings to
|
|
32
|
+
`resources/discovery--<slug>.md` in the intent directory ONLY. Do not write
|
|
33
|
+
the intent file, spec.md, or any lifecycle deliverable. The lock-owner-only
|
|
34
|
+
write rule stays intact; the Why-stage `plastic-brainstorming` agent reads the
|
|
35
|
+
deposit and enriches `## Context`.
|
|
36
|
+
|
|
37
|
+
## Stage coverage
|
|
38
|
+
This is the What-stage agent in the one-agent-per-stage table (What:
|
|
39
|
+
intent-discovery, Why: brainstorming + spec-specialist, How: planner, Exec:
|
|
40
|
+
executor, Done: intent-curator).
|
|
41
|
+
|
|
42
|
+
## Boundaries
|
|
43
|
+
- Single output: `resources/discovery--<slug>.md`.
|
|
44
|
+
- Does not ACQUIRE the delivery lock itself; it runs under the lock the
|
|
45
|
+
orchestrator armed, as the owner session (inherited session id), and is not
|
|
46
|
+
blocked by it.
|
|
47
|
+
- Advisory input to Why, not a gate.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plastic-intent-starting
|
|
3
|
+
description: >-
|
|
4
|
+
Board a session onto an intent: take the lock FIRST, confirm savepoint state, ask auto or
|
|
5
|
+
guided ONCE, then resume at the latest delivered station and run the cycle to Done. Use on
|
|
6
|
+
`continuing --intent {id}`, when a new intent is registered and the user asks to work it,
|
|
7
|
+
or when the user picks an intent to work. Requires the intent in INDEX `## Active`.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Intent Starting — board a session onto an intent
|
|
11
|
+
|
|
12
|
+
Announce: "Boarding intent [ID] — [name]."
|
|
13
|
+
|
|
14
|
+
`plastic-intent-starting` is the Start procedure. It boards a session onto one intent: take
|
|
15
|
+
the lock FIRST, confirm the delivery state, ask **auto or guided ONCE**, board at the latest
|
|
16
|
+
delivered station, then run the cycle to Done. The What → Why → How → Exec stations are the
|
|
17
|
+
train track; Start boards the train, the ending procedure (~93) exits it.
|
|
18
|
+
|
|
19
|
+
## Precondition + trigger
|
|
20
|
+
|
|
21
|
+
Fires when the user picks an intent to work, when an agent is told to continue a SPECIFIC
|
|
22
|
+
intent, or on `continuing --intent {id}` (the `continuing` → `starting` router is 106's job;
|
|
23
|
+
this skill is invokable standalone now).
|
|
24
|
+
|
|
25
|
+
If the intent is **terminal** (Done / Abandoned in INDEX): report only. Take NO lock, run NO
|
|
26
|
+
resume, do NOT reopen it. Summarize the outcome and ask what is next. Stop here.
|
|
27
|
+
|
|
28
|
+
## Lock FIRST (the spine)
|
|
29
|
+
|
|
30
|
+
The lock is non-negotiable and comes before any mutating work. The ACTION-3 lock-gate
|
|
31
|
+
enforces it: without a held lock, mutating writes to this active intent's dir are denied with
|
|
32
|
+
"run /plastic-intent-starting to lock and begin".
|
|
33
|
+
|
|
34
|
+
1. **Ensure the intent is in INDEX `## Active`.** If it sits in `## Future`, activate it
|
|
35
|
+
(move it to `## Active`, auto-commit) before arming. Creation precedes activation, so a
|
|
36
|
+
brand-new What intent is activated here, then locked.
|
|
37
|
+
2. **Self-heal the lock state first.** Run:
|
|
38
|
+
`ruby ~/.plastic/scripts/plastic-lock fix --intent-dir <STORE>/<dir>`
|
|
39
|
+
This is the one repair function (same one /plastic-lock exposes): it removes
|
|
40
|
+
corrupt or legacy lock state and rebuilds the lock and bridge from disk for
|
|
41
|
+
this session. If it reports `held`, another session owns the intent: STOP
|
|
42
|
+
and tell the user who holds it. If it reports `stale`, ask the user before
|
|
43
|
+
running `plastic-lock reclaim` (takeover is audited).
|
|
44
|
+
3. **Arm the bridge.** Which arm is chosen by the mode answer (below), but the lock itself is
|
|
45
|
+
taken first. Reuse the arm one-liner shape from `plastic-auto`:
|
|
46
|
+
```bash
|
|
47
|
+
# guided (lock only):
|
|
48
|
+
ruby -r ~/.plastic/scripts/lib/bridge -e \
|
|
49
|
+
'Bridge.arm_guided(ENV["CLAUDE_CODE_SESSION_ID"], intent_id: "<ID>", intent_dir: "<STORE>/<dir>", store: "<STORE>", name: "<name>")'
|
|
50
|
+
# auto (lock + auto), then hand to plastic-auto:
|
|
51
|
+
ruby -r ~/.plastic/scripts/lib/bridge -e \
|
|
52
|
+
'Bridge.arm_auto(ENV["CLAUDE_CODE_SESSION_ID"], intent_id: "<ID>", intent_dir: "<STORE>/<dir>", store: "<STORE>", name: "<name>")'
|
|
53
|
+
```
|
|
54
|
+
Replace `<ID>`, `<STORE>` (`~/.plastic/projects/<slug>/store` or `~/.plastic/store`),
|
|
55
|
+
`<dir>` (the `ID--slug` directory), and `<name>`.
|
|
56
|
+
4. **Dispatch What-stage discovery (under the lock).** Right after arming, when the intent
|
|
57
|
+
was just activated in step 1 (on a resume that already has
|
|
58
|
+
`resources/discovery--<slug>.md`, skip: discovery runs once per intent, at activation
|
|
59
|
+
only), dispatch the `plastic-intent-discovery` agent (see the `plastic-intent-discovery`
|
|
60
|
+
skill), now that this session owns the lock, deposit authorized as the owner session. Resolve its
|
|
61
|
+
model explicitly and pass it at dispatch time (belt-and-braces): `read-config
|
|
62
|
+
agents.models.plastic-intent-discovery --project <repo>`. The agent runs QMD discovery
|
|
63
|
+
over the intent's `chain`/`sources` and deposits findings to
|
|
64
|
+
`resources/discovery--<slug>.md` only; it never writes the intent file, so the
|
|
65
|
+
lock-owner-only rule is untouched. This is advisory context for Why, not a gate: if
|
|
66
|
+
discovery yields nothing, proceed to Why normally.
|
|
67
|
+
|
|
68
|
+
**Session id resolution (verbatim from `plastic-auto`).** The first argument is the session
|
|
69
|
+
id the bridge is keyed by: pass the hook stdin `session_id` when you have it, otherwise
|
|
70
|
+
`ENV["CLAUDE_CODE_SESSION_ID"]`, otherwise `nil`. Both arms call `resolve_session`, which
|
|
71
|
+
picks the first non-empty of: the explicit id you pass → `CLAUDE_CODE_SESSION_ID` → a
|
|
72
|
+
deterministic derived key (a hash of the store and intent id). It never returns nil, so the
|
|
73
|
+
lock is taken even when every session env var is empty; arming prints a one-line stderr
|
|
74
|
+
notice when it falls through to the derived key.
|
|
75
|
+
|
|
76
|
+
**What the lock IS.** Ownership is session-keyed and lease-based: arming writes a durable
|
|
77
|
+
`delivery.lock` file in the intent dir naming this session as owner, and the owner's hooks
|
|
78
|
+
refresh the file mtime on tool activity (the lease heartbeat). The /tmp bridge is only a
|
|
79
|
+
cache of that file; on any disagreement the lock file wins, so a wiped /tmp never strands
|
|
80
|
+
the owner. Idempotent re-arm: arming again with the same owner just refreshes the lock; it
|
|
81
|
+
is not an error to re-board an intent this session already owns. A failed arm raises with
|
|
82
|
+
a message naming the resolving `plastic-lock` verb (`status`, `reclaim`, or `fix`): follow
|
|
83
|
+
that message, never delete a lock file by hand.
|
|
84
|
+
|
|
85
|
+
## Confirm delivery state
|
|
86
|
+
|
|
87
|
+
Read `savepoint.md` and classify from the **last line** alone, then verify ONLY that line's
|
|
88
|
+
artifact is real (sentinel-aware via `Bridge.stage_file_present?`). On drift (the last line
|
|
89
|
+
disagrees with files on disk), rebuild the ledger from disk and note the correction. Do not
|
|
90
|
+
inline the rebuild; the `plastic-savepoint` skill owns it:
|
|
91
|
+
```bash
|
|
92
|
+
ruby -r ~/.plastic/scripts/lib/bridge -e 'Bridge.rebuild_savepoint("<intent_dir>")'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Report + ask "auto or guided?" ONCE
|
|
96
|
+
|
|
97
|
+
Report: the intent, the station it lands at (the matrix below), what is delivered, the next
|
|
98
|
+
step. Then ask the user **"auto or guided?"** — exactly ONCE, whatever station it lands at.
|
|
99
|
+
Never re-ask at a later station.
|
|
100
|
+
|
|
101
|
+
- **guided** → `arm_guided` (lock only); continue step by step with the user through the
|
|
102
|
+
station's work below.
|
|
103
|
+
- **auto** → `arm_auto` (lock + auto), then hand off to `plastic-auto`. The auto branch's
|
|
104
|
+
only remaining job is the handoff; `plastic-auto` runs the cycle from here.
|
|
105
|
+
|
|
106
|
+
## Board at the latest delivered station
|
|
107
|
+
|
|
108
|
+
The station is derived from `savepoint.md` last line + real artifacts on disk. See
|
|
109
|
+
`references/boarding-matrix.md` for the full table (last line → latest delivered → boards at →
|
|
110
|
+
continue with) and the per-station notes. Summary of what "continue" means per station:
|
|
111
|
+
|
|
112
|
+
- **What** → do what What requires (106-expanded), then brainstorm → `spec.md`.
|
|
113
|
+
- **Why** → continue brainstorming → `spec.md`.
|
|
114
|
+
- **How** → continue `plan.md` + `actions/` + `checklist.md`.
|
|
115
|
+
- **Exec** → verify what has been delivered, then continue (or restart) the delivery /
|
|
116
|
+
research; tick the checklist.
|
|
117
|
+
- **ready to complete** (`Exec outcome.md created`) → exit at Done.
|
|
118
|
+
- **Done** → report only, ask what is next, never reopen.
|
|
119
|
+
|
|
120
|
+
## Disarm / release on done
|
|
121
|
+
|
|
122
|
+
When delivery finishes, disarm and release per the `plastic-auto` disarm/release prose (do
|
|
123
|
+
not duplicate it here). The guided branch releases the lock via `disarm_auto`, which is
|
|
124
|
+
mode-agnostic (it sets `auto = false` and calls `Worktree.release`), so it releases a guided
|
|
125
|
+
lock too. When the work ships through a release, the release path merges the branch before the
|
|
126
|
+
worktree is removed; the plain disarm remove is only for the no-release case.
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
- `references/boarding-matrix.md` — the full boarding table and per-station behaviour.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "plastic-intent-starting",
|
|
3
|
+
"notes": "Intent 96. Scopes: description triggering (1-5) and behavior (6-10: lock-first spine, ask-mode-once, terminal report-only, mode->arm mapping, boarding matrix). The lock-first and gate behaviors are also proven by Ruby tests (test/bridge_guided_test.rb, test/lock_gate_test.rb, test/lock_gate_hook_test.rb).",
|
|
4
|
+
"evals": [
|
|
5
|
+
{
|
|
6
|
+
"id": 1,
|
|
7
|
+
"scope": "triggering",
|
|
8
|
+
"set": "train",
|
|
9
|
+
"prompt": "start work on intent 96",
|
|
10
|
+
"expected_output": "Activates plastic-intent-starting (board a session onto the named intent).",
|
|
11
|
+
"files": [],
|
|
12
|
+
"assertions": [
|
|
13
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-starting", "result": "expect-pass" }
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": 2,
|
|
18
|
+
"scope": "triggering",
|
|
19
|
+
"set": "train",
|
|
20
|
+
"prompt": "continuing --intent 96",
|
|
21
|
+
"expected_output": "Activates plastic-intent-starting (the --intent form boards a specific intent).",
|
|
22
|
+
"files": [],
|
|
23
|
+
"assertions": [
|
|
24
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-starting", "result": "expect-pass" }
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": 3,
|
|
29
|
+
"scope": "triggering",
|
|
30
|
+
"set": "validation",
|
|
31
|
+
"prompt": "work this intent",
|
|
32
|
+
"expected_output": "Activates plastic-intent-starting when an intent is in context to be worked.",
|
|
33
|
+
"files": [],
|
|
34
|
+
"assertions": [
|
|
35
|
+
{ "type": "code", "check": "router CHOICE == plastic-intent-starting", "result": "expect-pass" }
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"id": 4,
|
|
40
|
+
"scope": "triggering",
|
|
41
|
+
"set": "validation",
|
|
42
|
+
"prompt": "continue",
|
|
43
|
+
"expected_output": "Does NOT activate plastic-intent-starting; bare 'continue' is plastic-continuing (no specific intent named).",
|
|
44
|
+
"files": [],
|
|
45
|
+
"assertions": [
|
|
46
|
+
{ "type": "code", "check": "router CHOICE != plastic-intent-starting", "result": "expect-pass" }
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": 5,
|
|
51
|
+
"scope": "triggering",
|
|
52
|
+
"set": "validation",
|
|
53
|
+
"prompt": "create a new intent for the uploader retry policy",
|
|
54
|
+
"expected_output": "Does NOT activate plastic-intent-starting; activates plastic-creating-intent.",
|
|
55
|
+
"files": [],
|
|
56
|
+
"assertions": [
|
|
57
|
+
{ "type": "code", "check": "router CHOICE != plastic-intent-starting", "result": "expect-pass" }
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": 6,
|
|
62
|
+
"scope": "behavior",
|
|
63
|
+
"set": "train",
|
|
64
|
+
"prompt": "Active intent X exists at the Why station. Start work on it (guided).",
|
|
65
|
+
"expected_output": "Takes the lock FIRST via Bridge.arm_guided (auto stays false) before any mutating work, confirms savepoint, then boards at Why and continues brainstorming toward spec.md.",
|
|
66
|
+
"files": [],
|
|
67
|
+
"assertions": [
|
|
68
|
+
{ "type": "human", "check": "lock acquired before any mutating write; SKILL.md 'Lock FIRST' section precedes station work", "result": "expect-pass" },
|
|
69
|
+
{ "type": "code", "check": "Bridge.arm_guided stamps the lock with auto=false (test/bridge_guided_test.rb green); lock-gate denies a no-lock write to the active intent dir (test/lock_gate_hook_test.rb green)", "result": "pass" }
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"id": 7,
|
|
74
|
+
"scope": "behavior",
|
|
75
|
+
"set": "train",
|
|
76
|
+
"prompt": "Start work on an active intent without saying auto or guided.",
|
|
77
|
+
"expected_output": "Asks 'auto or guided?' exactly once after reporting the station; never re-asks at later stations.",
|
|
78
|
+
"files": [],
|
|
79
|
+
"assertions": [
|
|
80
|
+
{ "type": "human", "check": "SKILL.md asks the mode exactly once and states 'never re-asked at a later station'", "result": "expect-pass" }
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": 8,
|
|
85
|
+
"scope": "behavior",
|
|
86
|
+
"set": "train",
|
|
87
|
+
"prompt": "Start work on an intent that is Done in INDEX.",
|
|
88
|
+
"expected_output": "Reports only: no lock, no resume, no reopen. Summarizes the outcome and asks what is next.",
|
|
89
|
+
"files": [],
|
|
90
|
+
"assertions": [
|
|
91
|
+
{ "type": "human", "check": "terminal intent -> report only, no arm call", "result": "expect-pass" }
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": 9,
|
|
96
|
+
"scope": "behavior",
|
|
97
|
+
"set": "validation",
|
|
98
|
+
"prompt": "Start work and choose auto.",
|
|
99
|
+
"expected_output": "guided -> Bridge.arm_guided; auto -> Bridge.arm_auto then hand off to plastic-auto (auto branch's only remaining job is the handoff).",
|
|
100
|
+
"files": [],
|
|
101
|
+
"assertions": [
|
|
102
|
+
{ "type": "human", "check": "SKILL.md maps guided->arm_guided and auto->arm_auto+handoff to plastic-auto", "result": "expect-pass" }
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": 10,
|
|
107
|
+
"scope": "behavior",
|
|
108
|
+
"set": "validation",
|
|
109
|
+
"prompt": "Start an intent whose savepoint last line is 'How checklist.md created'.",
|
|
110
|
+
"expected_output": "Boards at Exec (verify plan + checklist real), per references/boarding-matrix.md, and continues delivery/ticks the checklist.",
|
|
111
|
+
"files": [],
|
|
112
|
+
"assertions": [
|
|
113
|
+
{ "type": "human", "check": "boarding matrix lands 'How checklist.md created' / 'Exec started' at Exec", "result": "expect-pass" }
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Boarding matrix — which station Start drops you at
|
|
2
|
+
|
|
3
|
+
The station is derived from `savepoint.md`'s last line plus the real artifacts on disk.
|
|
4
|
+
Classify from the last line alone, then verify ONLY that line's artifact is real
|
|
5
|
+
(sentinel-aware). On drift, rebuild the ledger from disk and note it.
|
|
6
|
+
|
|
7
|
+
| savepoint last line | latest delivered | boards at | continue with |
|
|
8
|
+
|---|---|---|---|
|
|
9
|
+
| `What {id}--{slug}.md` (born) | What | **What / Why** | What work (106-expanded), then brainstorm → `spec.md` |
|
|
10
|
+
| `Why started` (spec still sentinel) | What | **Why** | continue brainstorming → `spec.md` |
|
|
11
|
+
| `Why spec.md created` | Why | **How** | `plan.md` + `actions/` + `checklist.md` |
|
|
12
|
+
| `How started` / `How plan.md created` | (How in progress) | **How** | finish `plan.md` → `checklist.md` |
|
|
13
|
+
| `How checklist.md created` / `Exec started` | How | **Exec** | implement, tick the checklist |
|
|
14
|
+
| `Exec outcome.md created` | Exec | **ready to complete** | exit at Done |
|
|
15
|
+
| `Done delivered` / `Done abandoned` | terminal | **report only** | immutable; ask what is next |
|
|
16
|
+
|
|
17
|
+
## Per-station behaviour (what "continue" means)
|
|
18
|
+
|
|
19
|
+
- **What** → do what What requires (to be expanded in 106), then brainstorm → `spec.md`.
|
|
20
|
+
- **Why** → continue brainstorming; deliver `spec.md`.
|
|
21
|
+
- **How** → continue `plan.md` + `actions/` + `checklist.md`.
|
|
22
|
+
- **Exec** → verify what has been delivered, then continue (or restart) the delivery /
|
|
23
|
+
research. The first unchecked `checklist.md` item is the next step; the newest `## Insights`
|
|
24
|
+
entry supplies human-readable context.
|
|
25
|
+
- **ready to complete** → `outcome.md` is real; run the ending procedure (~93).
|
|
26
|
+
- **Done** → terminal. Report the outcome, ask what is next. Never reopen; INDEX is
|
|
27
|
+
authoritative.
|
|
28
|
+
|
|
29
|
+
## Notes
|
|
30
|
+
|
|
31
|
+
- The mode (auto / guided) is asked exactly ONCE, whatever station Start lands at. It is never
|
|
32
|
+
re-asked at a later station. The lock is taken FIRST regardless of station (terminal intents
|
|
33
|
+
excepted: they get no lock and no resume).
|
|
34
|
+
- An `## Insights` entry marked `(autonomous)` means the intent was being delivered
|
|
35
|
+
autonomously; in guided mode, surface that and offer to hand back to `plastic-auto`.
|