@zalom/plastic 1.0.0-alpha.8 → 1.0.0-beta.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.
- package/PLASTIC.md +154 -469
- package/README.md +95 -58
- package/agents/plastic-brainstorming.md +37 -0
- package/agents/plastic-enforcer.md +36 -0
- package/agents/plastic-executor.md +37 -0
- package/agents/{future-intent-researcher.md → plastic-future-intent-researcher.md} +1 -1
- package/agents/{intent-curator.md → plastic-intent-curator.md} +1 -1
- package/agents/plastic-planner.md +37 -0
- package/agents/plastic-spec-specialist.md +37 -0
- package/bin/plastic.js +57 -0
- package/bin/test +28 -0
- package/deprecations.yml +1 -10
- package/hooks/auto-arm +5 -0
- package/hooks/bash-gate +3 -0
- package/hooks/check-update +12 -8
- package/hooks/code-gate +12 -0
- package/hooks/create-gate +3 -0
- package/hooks/gate-check +3 -1
- package/hooks/hooks.json +52 -0
- package/hooks/qmd-search +8 -0
- package/package.json +2 -2
- package/scripts/dashboard.rb +685 -0
- package/scripts/doctor.rb +987 -632
- package/scripts/hook-auto-arm +51 -0
- package/scripts/hook-bash-gate +41 -0
- package/scripts/hook-code-gate +27 -0
- package/scripts/hook-continue +15 -114
- package/scripts/hook-create-gate +59 -0
- package/scripts/hook-gate-check +47 -32
- package/scripts/hook-qmd-search +44 -0
- package/scripts/hook-session-start +106 -38
- package/scripts/install.rb +91 -504
- package/scripts/lib/boot_banner.rb +28 -0
- package/scripts/lib/bridge.rb +404 -19
- package/scripts/lib/installer_core.rb +807 -0
- package/scripts/lib/intent_validator.rb +156 -0
- package/scripts/lib/qmd_hook.rb +44 -0
- package/scripts/lib/qmd_sync.rb +209 -0
- package/scripts/lib/store_provisioning.rb +100 -0
- package/scripts/migrate-to-global +1 -1
- package/scripts/new-intent +177 -0
- package/scripts/provision-project-store +53 -0
- package/scripts/qmd-sync +92 -0
- package/scripts/select-update-target +93 -0
- package/scripts/spawn-preamble +121 -0
- package/scripts/uninstall.rb +53 -0
- package/scripts/update.rb +164 -0
- package/scripts/validate-intent +54 -0
- package/scripts/versions.rb +141 -0
- package/skills/_active-intent-gate.md +1 -1
- package/skills/add-project-store/SKILL.md +54 -0
- package/skills/auto/SKILL.md +77 -7
- package/skills/auto/evals/evals.json +207 -0
- package/skills/auto/references/agent-architecture.md +135 -0
- package/skills/brainstorming/SKILL.md +9 -9
- package/skills/brainstorming-grill-me/SKILL.md +6 -6
- package/skills/continuing/SKILL.md +92 -82
- package/skills/continuing/evals/evals.json +136 -0
- package/skills/continuing/references/context-management.md +32 -0
- package/skills/creating-intent/SKILL.md +59 -33
- package/skills/creating-intent/references/lifecycle.md +73 -0
- package/skills/creating-intent/references/wikilinks.md +8 -0
- package/skills/creating-project/SKILL.md +40 -8
- package/skills/creating-project/references/hubs-projects.md +55 -0
- package/skills/dashboard/SKILL.md +121 -0
- package/skills/dashboard/templates/dashboard-global.md +31 -0
- package/skills/dashboard/templates/dashboard-project.md +40 -0
- package/skills/doctor/SKILL.md +51 -4
- package/skills/doctor/references/gates-stuck-detection.md +38 -0
- package/skills/doctor/report.md +4 -0
- package/skills/evaluating-skills/SKILL.md +140 -0
- package/skills/evaluating-skills/assets/eval-template.json +12 -0
- package/skills/evaluating-skills/evals/evals.json +75 -0
- package/skills/evaluating-skills/references/convention-checks.md +76 -0
- package/skills/evaluating-skills/references/eval-methodology.md +154 -0
- package/skills/executing-plan/SKILL.md +5 -3
- package/skills/install/SKILL.md +69 -8
- package/skills/intent-curator/SKILL.md +3 -3
- package/skills/linking-intents/SKILL.md +5 -1
- package/skills/linking-intents/references/zettelkasten.md +33 -0
- package/skills/managing-index/SKILL.md +5 -1
- package/skills/releasing/SKILL.md +80 -23
- package/skills/releasing/references/deprecations.md +60 -0
- package/skills/research/SKILL.md +2 -2
- package/skills/savepoint/SKILL.md +46 -37
- package/skills/savepoint/references/context-management.md +32 -0
- package/skills/uninstall/SKILL.md +39 -28
- package/skills/update/SKILL.md +41 -44
- package/skills/versions/SKILL.md +65 -0
- package/skills/writing-instructions/SKILL.md +159 -0
- package/skills/writing-instructions/references/agentskills-spec.md +135 -0
- package/skills/writing-plans/SKILL.md +5 -5
- package/templates/agents.md +7 -7
- package/templates/outcome.md +13 -0
- package/templates/savepoint.md +14 -13
- package/templates/spec.md +25 -0
- package/bin/install.js +0 -29
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "plastic-continuing",
|
|
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
|
+
"results": {
|
|
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" }
|
|
7
|
+
},
|
|
8
|
+
"evals": [
|
|
9
|
+
{
|
|
10
|
+
"id": 1, "scope": "triggering", "set": "train",
|
|
11
|
+
"prompt": "continue",
|
|
12
|
+
"expected_output": "Activates plastic-continuing (the bare 'continue' keyword is the documented trigger).",
|
|
13
|
+
"files": [],
|
|
14
|
+
"assertions": [
|
|
15
|
+
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 2, "scope": "triggering", "set": "train",
|
|
20
|
+
"prompt": "resume where we left off",
|
|
21
|
+
"expected_output": "Activates plastic-continuing.",
|
|
22
|
+
"files": [],
|
|
23
|
+
"assertions": [
|
|
24
|
+
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": 3, "scope": "triggering", "set": "validation",
|
|
29
|
+
"prompt": "pick up where we left off in this project",
|
|
30
|
+
"expected_output": "Activates plastic-continuing.",
|
|
31
|
+
"files": [],
|
|
32
|
+
"assertions": [
|
|
33
|
+
{ "type": "code", "check": "router CHOICE == plastic-continuing", "observed": "plastic-continuing", "result": "pass" }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": 4, "scope": "triggering", "set": "train",
|
|
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).",
|
|
40
|
+
"files": [],
|
|
41
|
+
"assertions": [
|
|
42
|
+
{ "type": "code", "check": "router CHOICE == plastic-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-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-continuing. Near-miss: shares 'continue' but is a code-editing task.",
|
|
58
|
+
"files": [],
|
|
59
|
+
"assertions": [
|
|
60
|
+
{ "type": "code", "check": "router CHOICE != plastic-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-continuing. Near-miss: shares 'resume' but is unrelated to Plastic sessions.",
|
|
67
|
+
"files": [],
|
|
68
|
+
"assertions": [
|
|
69
|
+
{ "type": "code", "check": "router CHOICE != plastic-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": "May activate plastic-dashboard rather than plastic-continuing; an overview request without 'continue/resume' is a dashboard task.",
|
|
76
|
+
"files": [],
|
|
77
|
+
"assertions": [
|
|
78
|
+
{ "type": "code", "check": "router CHOICE != plastic-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/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/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": "train",
|
|
101
|
+
"prompt": "Is dashboard selection project-aware?",
|
|
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"],
|
|
104
|
+
"assertions": [
|
|
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
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": 12, "scope": "behavior", "set": "validation",
|
|
110
|
+
"prompt": "Is ledger-resume conditional and ledger-driven?",
|
|
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"],
|
|
113
|
+
"assertions": [
|
|
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
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id": 13, "scope": "behavior", "set": "validation",
|
|
119
|
+
"prompt": "Are the stale prose-savepoint fields gone?",
|
|
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"],
|
|
122
|
+
"assertions": [
|
|
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
|
+
]
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"id": 14, "scope": "behavior", "set": "validation",
|
|
128
|
+
"prompt": "Is the 'Determine Store' local-store gap filled?",
|
|
129
|
+
"expected_output": "Step 2 of Determine Store describes local/project-store detection (no empty step).",
|
|
130
|
+
"files": ["skills/continuing/SKILL.md"],
|
|
131
|
+
"assertions": [
|
|
132
|
+
{ "type": "convention", "check": "Determine Store step 2 documents local/project store detection via projects.yml + CWD match", "observed": "filled", "result": "pass" }
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Context Management (Start-Save-Continue)
|
|
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
|
+
## Continue
|
|
14
|
+
Triggered by UserPromptSubmit hook when user says "continue". Priority order:
|
|
15
|
+
|
|
16
|
+
**1. Active intents first (resume work):**
|
|
17
|
+
1. Read INDEX.md → find active intent(s)
|
|
18
|
+
2. Read active intent's `intent.md` → what and why
|
|
19
|
+
3. Read active intent's `savepoint.md` → where we left off
|
|
20
|
+
4. Read active intent's `checklist.md` → what's next
|
|
21
|
+
5. Announce: intent name, current state, next step, blockers
|
|
22
|
+
6. Resume
|
|
23
|
+
|
|
24
|
+
**2. No active intents → offer future intents:**
|
|
25
|
+
1. List all future intents from INDEX.md
|
|
26
|
+
2. Present them as options
|
|
27
|
+
3. When user picks one, move to Active in INDEX.md
|
|
28
|
+
|
|
29
|
+
**3. Stale future intents (untouched 3+ days) → triage:**
|
|
30
|
+
- **activate** — start working on it now
|
|
31
|
+
- **abandon** — mark as abandoned
|
|
32
|
+
- **defer to agent** — implement, research, or ideate
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: plastic
|
|
2
|
+
name: plastic-creating-intent
|
|
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
|
---
|
|
5
5
|
|
|
@@ -41,45 +41,62 @@ When creating a tactical intent in a project store:
|
|
|
41
41
|
- **Global:** `~/.plastic/store/`
|
|
42
42
|
- **Project:** `~/.plastic/projects/{slug}/store/`
|
|
43
43
|
|
|
44
|
-
### 2.
|
|
44
|
+
### 2. Decide Branch vs Root
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Decide this BEFORE scaffolding, because it sets whether you pass `--parent`.
|
|
47
|
+
Having a "parent" in mind does NOT automatically mean branch. Choose by meaning:
|
|
47
48
|
|
|
48
|
-
**
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
"${CLAUDE_PLUGIN_ROOT}/scripts/folgezettel-id" "~/.plastic/projects/{slug}/store"
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
**Branch intent (has parent, either store):**
|
|
59
|
-
```bash
|
|
60
|
-
"${CLAUDE_PLUGIN_ROOT}/scripts/folgezettel-id" "<STORE>" "<parent_id>"
|
|
61
|
-
```
|
|
49
|
+
- **Branch (`14a`, `14b`)**: a sub-task, refinement, or direct continuation. It only
|
|
50
|
+
makes sense as part of the parent's work. Pass `--parent <parent_id>`.
|
|
51
|
+
- **Root (`15`, `16`)**: an independent thought, even if inspired by another intent.
|
|
52
|
+
Capture the inspiration in `--sources`, not in the id. Omit `--parent`.
|
|
53
|
+
- **Rule of thumb:** if the intent could exist without its parent, make it a root and
|
|
54
|
+
set `--sources`. Only branch when it genuinely cannot stand alone.
|
|
62
55
|
|
|
63
56
|
### 3. Determine Intent Properties
|
|
64
57
|
|
|
65
58
|
Ask or infer from context:
|
|
66
59
|
- **intent**: one-line description
|
|
60
|
+
- **slug**: short hyphenated handle for the directory name
|
|
67
61
|
- **author**: `human` | `claude-code` | other agent name
|
|
68
|
-
- **sources**:
|
|
69
|
-
|
|
62
|
+
- **sources**: Folgezettel ids that influenced this intent (e.g., `4a1`). For a
|
|
63
|
+
project intent, include the governing intent's id.
|
|
70
64
|
- **tags**: freeform list (use `project-<name>` for project membership)
|
|
71
65
|
|
|
72
|
-
|
|
66
|
+
`chain` starts empty and is populated later when this intent spawns others.
|
|
67
|
+
Place the intent in `## Active` or `## Future` in INDEX.md (status is
|
|
68
|
+
convention-derived, not a frontmatter field).
|
|
73
69
|
|
|
74
|
-
### 4.
|
|
70
|
+
### 4. Scaffold via new-intent (single call)
|
|
71
|
+
|
|
72
|
+
Delegate id allocation, directory and file creation, the born-complete intent
|
|
73
|
+
file, the sentinel placeholder lifecycle files, the reciprocal file links, and
|
|
74
|
+
self-validation to one `new-intent` invocation. Do NOT hand-author any of these
|
|
75
|
+
files.
|
|
75
76
|
|
|
76
77
|
```bash
|
|
77
|
-
|
|
78
|
+
"${CLAUDE_PLUGIN_ROOT}/scripts/new-intent" \
|
|
79
|
+
--store "<STORE>" --intent "<one-line>" --slug "<slug>" \
|
|
80
|
+
[--parent "<parent_id>"] [--author "<author>"] \
|
|
81
|
+
[--sources "id,id"] [--tags "project-<slug>,tag"]
|
|
78
82
|
```
|
|
79
83
|
|
|
80
|
-
|
|
84
|
+
`new-intent` allocates the Folgezettel id (root, or a branch of `--parent`),
|
|
85
|
+
creates `<STORE>/<id>--<slug>/` plus `actions/` and `resources/`, renders the
|
|
86
|
+
born-complete `<id>--<slug>.md` from the intent template, writes the sentinel
|
|
87
|
+
placeholder `spec.md`/`plan.md`/`checklist.md`/`outcome.md` (each marked
|
|
88
|
+
`<!-- plastic:placeholder -->` so no stage detector reads them as reached), wires
|
|
89
|
+
the reciprocal `[[id]]` links, and self-validates (frontmatter plus the sanctioned
|
|
90
|
+
`##` sections). It prints the created directory path and exits 0.
|
|
91
|
+
|
|
92
|
+
It does NOT touch INDEX.md, git, or project creation: those stay in this skill
|
|
93
|
+
(steps 6 to 9 below).
|
|
81
94
|
|
|
82
|
-
|
|
95
|
+
If `new-intent` exits non-zero, read the stderr report and fix the inputs (slug,
|
|
96
|
+
intent, sources). Do not commit or announce an intent that did not scaffold
|
|
97
|
+
cleanly, and do not work around the failure by hand-writing the files.
|
|
98
|
+
|
|
99
|
+
### 6. If Implementation Intent Spawns a Project
|
|
83
100
|
|
|
84
101
|
When the user says "start building" or the plan calls for a new project:
|
|
85
102
|
|
|
@@ -89,8 +106,6 @@ When the user says "start building" or the plan calls for a new project:
|
|
|
89
106
|
mkdir -p <project_root>/<slug>
|
|
90
107
|
cd <project_root>/<slug>
|
|
91
108
|
git init
|
|
92
|
-
mkdir -p ~/.plastic/projects/{slug}/store
|
|
93
|
-
touch ~/.plastic/projects/{slug}/store/.gitkeep
|
|
94
109
|
```
|
|
95
110
|
3. Copy `AGENTS.md` template from `${CLAUDE_PLUGIN_ROOT}/templates/agents.md`
|
|
96
111
|
4. Register in `~/.plastic/projects.yml`:
|
|
@@ -101,22 +116,33 @@ When the user says "start building" or the plan calls for a new project:
|
|
|
101
116
|
registered: <today>
|
|
102
117
|
status: active
|
|
103
118
|
```
|
|
104
|
-
5.
|
|
105
|
-
|
|
119
|
+
5. Provision the project store (the single source of truth for store creation;
|
|
120
|
+
runs after step 4 because the provisioner requires the project to be
|
|
121
|
+
registered):
|
|
122
|
+
```bash
|
|
123
|
+
ruby ~/.plastic/scripts/provision-project-store <slug>
|
|
124
|
+
```
|
|
125
|
+
6. Add `project-<slug>` to the intent's `tags` array
|
|
126
|
+
7. Auto-commit in both `~/.plastic/` and the new project
|
|
106
127
|
|
|
107
|
-
###
|
|
128
|
+
### 7. Update INDEX.md
|
|
108
129
|
|
|
109
130
|
- **Global intents:** update `~/.plastic/INDEX.md`
|
|
110
131
|
- **Project intents:** no global INDEX.md change (tactical intents are project-scoped)
|
|
111
132
|
|
|
112
133
|
Add to `## Active` (or `## Future`) and appropriate cluster.
|
|
113
134
|
|
|
114
|
-
###
|
|
135
|
+
### 8. Auto-commit
|
|
115
136
|
|
|
116
137
|
```bash
|
|
117
|
-
cd <store-root> && git add . && git commit -m "feat: create intent ID
|
|
138
|
+
cd <store-root> && git add . && git commit -m "feat: create intent ID - [name]"
|
|
118
139
|
```
|
|
119
140
|
|
|
120
|
-
###
|
|
141
|
+
### 9. Announce
|
|
142
|
+
|
|
143
|
+
"Created intent ID - [name]. Placed in: [Active|Future]. Store: [global|project:<slug>|local]."
|
|
144
|
+
|
|
145
|
+
## References
|
|
121
146
|
|
|
122
|
-
|
|
147
|
+
- Read `references/lifecycle.md` for the full What→Why→How→Exec stage detail, filesystem-as-schema conventions, and creating-intent step-by-step
|
|
148
|
+
- Read `references/wikilinks.md` for the wikilink syntax table when adding `## Links` to intents
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Building an Intent — Full Lifecycle Detail
|
|
2
|
+
|
|
3
|
+
## What → `## Intent` section
|
|
4
|
+
|
|
5
|
+
The desire. One paragraph. What the human or agent wants.
|
|
6
|
+
This exists from the moment the intent is created.
|
|
7
|
+
|
|
8
|
+
**Deliverable:** `{ID}--{slug}.md`
|
|
9
|
+
|
|
10
|
+
## Why → `## Context` + `### Decisions` sections
|
|
11
|
+
|
|
12
|
+
Why this intent exists. Grows over time through brainstorming and exploration.
|
|
13
|
+
|
|
14
|
+
- **Context** — what we knew going in + what we decided along the way
|
|
15
|
+
- **Decisions** — main premises derived from Context plus decisions from brainstorming/grilling
|
|
16
|
+
- Decisions are Why-level: "status belongs on actions because multiple workstreams", not How-level: "use ACTION_N.md files"
|
|
17
|
+
|
|
18
|
+
**Deliverable:** `spec.md` (consolidated specification from Context + Decisions + brainstorming)
|
|
19
|
+
|
|
20
|
+
## How → Planning and preparation
|
|
21
|
+
|
|
22
|
+
Research decisions, create the implementation plan, define actions.
|
|
23
|
+
|
|
24
|
+
**Deliverable:** `plan.md` + `actions/` + `checklist.md` (execution registry with checkboxes covering all actions)
|
|
25
|
+
|
|
26
|
+
## Exec → Execute actions
|
|
27
|
+
|
|
28
|
+
Execute actions from the plan, track progress via checklist.
|
|
29
|
+
|
|
30
|
+
**Deliverable:** `outcome.md` (detailed result). `## Outcome` in intent.md = short summary written as last step.
|
|
31
|
+
|
|
32
|
+
## `## Insights` — Append-only work log
|
|
33
|
+
|
|
34
|
+
Captured throughout ALL stages. One-liner bullet points.
|
|
35
|
+
Never modified, only appended.
|
|
36
|
+
|
|
37
|
+
Tracks: stage transitions, decisions, shifts, blocks, cancellations, material for future intents.
|
|
38
|
+
This is how execution is tracked. When this intent completes, Insights
|
|
39
|
+
is where to look for what comes next. New intents spawned from Insights
|
|
40
|
+
appear in the `chain` field.
|
|
41
|
+
|
|
42
|
+
## `## Links`
|
|
43
|
+
|
|
44
|
+
Wikilinks for Obsidian graph navigation. Human-facing counterpart to the
|
|
45
|
+
frontmatter knowledge graph.
|
|
46
|
+
|
|
47
|
+
## Conventions — Filesystem as Schema
|
|
48
|
+
|
|
49
|
+
State is derived from what exists, not from what's declared.
|
|
50
|
+
|
|
51
|
+
| Convention | Signal |
|
|
52
|
+
|---|---|
|
|
53
|
+
| No `## Context` | Intent is fleeting (quick capture, non-actionable) |
|
|
54
|
+
| `## Context` has content | Intent is permanent (developed, actionable) |
|
|
55
|
+
| `## Outcome` has content | Intent is done |
|
|
56
|
+
| `## Insights` has `(autonomous)` entries | Intent is/was being delivered autonomously |
|
|
57
|
+
|
|
58
|
+
### Transitions
|
|
59
|
+
|
|
60
|
+
- Fleeting → permanent: add `## Context` (one-way, also makes it actionable)
|
|
61
|
+
- There is no separate "non-actionable → actionable" transition — permanence implies actionability
|
|
62
|
+
- Even research intents are actionable: the research itself is the action, the conclusion is the outcome
|
|
63
|
+
|
|
64
|
+
## Creating an Intent — Full Steps
|
|
65
|
+
|
|
66
|
+
1. Determine the target store: `~/.plastic/store/` for global intents (default), `~/.plastic/projects/{slug}/store/` for project intents
|
|
67
|
+
2. Decide branch vs root (this sets whether you pass `--parent`)
|
|
68
|
+
3. Scaffold with one call: `"${CLAUDE_PLUGIN_ROOT}/scripts/new-intent" --store <store> --intent "<one-line>" --slug <slug> [--parent <id>] [--sources id,id] [--tags ...]`. This allocates the id, creates the directory plus `actions/` and `resources/`, renders the born-complete intent file (frontmatter plus `## Intent`, `## Context`, `## Outcome`, `## Insights`, `## Links`), writes the sentinel placeholder lifecycle files, wires the reciprocal links, and self-validates.
|
|
69
|
+
4. Update the appropriate `INDEX.md` — add to Active section and appropriate cluster
|
|
70
|
+
|
|
71
|
+
The intent file is born complete with all five sanctioned `##` sections; the lifecycle files (`spec.md`/`plan.md`/`checklist.md`/`outcome.md`) are sentinel placeholders that read as "stage not reached" until an agent fills them and deletes the `<!-- plastic:placeholder -->` first line.
|
|
72
|
+
|
|
73
|
+
Always scaffold through `new-intent` (or this skill). Never hand-author intent files: the write-time create gate blocks an incomplete or malformed intent file, and hand-authoring is the bypass this contract is designed to remove.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Wikilink Conventions
|
|
2
|
+
|
|
3
|
+
| Syntax | Meaning |
|
|
4
|
+
|--------|---------|
|
|
5
|
+
| `[[ID]]` | Link to intent in same store (e.g., `[[1a1]]`) |
|
|
6
|
+
| `[[ID\|display text]]` | Link with human-readable label |
|
|
7
|
+
| `[[global:ID]]` | Link to intent in `~/.plastic/store/` |
|
|
8
|
+
| `[[project-slug:ID]]` | Link to intent in `~/.plastic/projects/{slug}/store/` |
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: plastic
|
|
2
|
+
name: plastic-creating-project
|
|
3
3
|
description: >-
|
|
4
4
|
Create a new project from an implementation intent. Sets up project directory,
|
|
5
|
-
git init, AGENTS.md with founding intent decisions, plastic
|
|
5
|
+
git init, AGENTS.md with founding intent decisions, plastic-install --local,
|
|
6
6
|
tactical mirror, projects.yml registration, and framework scaffolding.
|
|
7
7
|
Use when an implementation intent spawns a project, or manually by user.
|
|
8
8
|
---
|
|
@@ -31,9 +31,9 @@ cd <project_root>/<slug>
|
|
|
31
31
|
git init
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
### 3. Run `plastic
|
|
34
|
+
### 3. Run `plastic-install --local`
|
|
35
35
|
|
|
36
|
-
Invoke `plastic
|
|
36
|
+
Invoke `plastic-install --local` in the project directory. This creates:
|
|
37
37
|
```
|
|
38
38
|
.plastic/
|
|
39
39
|
├── store/
|
|
@@ -127,7 +127,24 @@ Read `~/.plastic/projects.yml` and add:
|
|
|
127
127
|
|
|
128
128
|
For Hub-spawned projects, `parent` references the primary founding intent.
|
|
129
129
|
|
|
130
|
-
### 7.
|
|
130
|
+
### 7. Provision the Project Store
|
|
131
|
+
|
|
132
|
+
The `provision-project-store` verb is the single source of truth for store
|
|
133
|
+
creation. Run it after the project is registered in step 6 (the provisioner
|
|
134
|
+
requires registration), and before the QMD step:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
ruby ~/.plastic/scripts/provision-project-store <slug>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This ensures `~/.plastic/projects/<slug>/store/` exists with `.gitkeep`, and
|
|
141
|
+
writes `INDEX.md` and `project.yml` only if missing. It is idempotent, so it is
|
|
142
|
+
safe even when the tactical mirror in step 5 already created the store directory.
|
|
143
|
+
Do not create the store with an inline `mkdir`; the provisioner is the only place
|
|
144
|
+
a store is made. For a project that is already registered but store-less, use the
|
|
145
|
+
`plastic-add-project-store` skill instead.
|
|
146
|
+
|
|
147
|
+
### 8. Mark Global Intent(s) Completed
|
|
131
148
|
|
|
132
149
|
For each founding intent:
|
|
133
150
|
|
|
@@ -137,7 +154,7 @@ For each founding intent:
|
|
|
137
154
|
3. Update `chain` to include `project-<slug>:1`
|
|
138
155
|
4. Move from `## Active` to `## Completed` in `~/.plastic/INDEX.md` (with today's date)
|
|
139
156
|
|
|
140
|
-
###
|
|
157
|
+
### 9. Framework Scaffolding
|
|
141
158
|
|
|
142
159
|
If decisions specify a framework, run the appropriate scaffolding command AFTER steps 3-4 (so scaffolding doesn't overwrite Plastic files or AGENTS.md):
|
|
143
160
|
|
|
@@ -150,17 +167,32 @@ If decisions specify a framework, run the appropriate scaffolding command AFTER
|
|
|
150
167
|
|
|
151
168
|
After scaffolding, verify AGENTS.md and `.plastic/` still exist. If scaffolding overwrote them, restore.
|
|
152
169
|
|
|
153
|
-
###
|
|
170
|
+
### 10. Auto-commit Both Stores
|
|
154
171
|
|
|
155
172
|
```bash
|
|
156
173
|
cd ~/.plastic && git add . && git commit -m "feat: spawn project <slug> from intent <ID>"
|
|
157
174
|
cd <project> && git add . && git commit -m "feat: initialize project from intent <ID>"
|
|
158
175
|
```
|
|
159
176
|
|
|
160
|
-
###
|
|
177
|
+
### 11. Register the project store with QMD (optional)
|
|
178
|
+
|
|
179
|
+
If QMD is installed, register the new project's store as a search collection:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
ruby ~/.plastic/scripts/qmd-sync register --store ~/.plastic/projects/<slug>/store
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`qmd-sync` no-ops when QMD is absent, so run it unconditionally. This adds the
|
|
186
|
+
`plastic-<slug>` collection and indexes it.
|
|
187
|
+
|
|
188
|
+
### 12. Announce
|
|
161
189
|
|
|
162
190
|
Log in `## Insights` of each founding intent:
|
|
163
191
|
> "Project `<slug>` created at `<path>`. Tactical mirror: `project-<slug>:1` (autonomous)"
|
|
164
192
|
|
|
165
193
|
Announce to user:
|
|
166
194
|
> "Project `<slug>` created at `<path>`. AGENTS.md populated with [N] decisions from [founding intent IDs]. Tactical mirror `1` is now the active intent in the project store."
|
|
195
|
+
|
|
196
|
+
## References
|
|
197
|
+
|
|
198
|
+
- Read `references/hubs-projects.md` for the full hub/project relationship model, project creation flow, and cross-linking conventions
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Hubs and Projects
|
|
2
|
+
|
|
3
|
+
## Hubs
|
|
4
|
+
|
|
5
|
+
A Hub is a cloud of intents around related topics. Hubs emerge naturally from
|
|
6
|
+
Folgezettel branching — intents that spawn in the same direction cluster.
|
|
7
|
+
|
|
8
|
+
- A Hub can spawn a Project. The Hub holds the founding ideas.
|
|
9
|
+
- A single intent can also spawn a Project.
|
|
10
|
+
- Hub-spawned projects revolve around different ideas around related topics.
|
|
11
|
+
- Intent-spawned projects revolve around the single founding intent.
|
|
12
|
+
- A Project is the deliverable outcome of one or more intents.
|
|
13
|
+
|
|
14
|
+
Hubs are represented as clusters in INDEX.md.
|
|
15
|
+
|
|
16
|
+
## Projects — Full Detail
|
|
17
|
+
|
|
18
|
+
A Project is a deliverable grouping of intents. Projects have two stores:
|
|
19
|
+
|
|
20
|
+
- **Global store** (`~/.plastic/store/`): strategic intents
|
|
21
|
+
- **Project store** (`~/.plastic/projects/{slug}/store/`): tactical intents
|
|
22
|
+
|
|
23
|
+
`projects.yml` maps project slugs to codebase paths:
|
|
24
|
+
```yaml
|
|
25
|
+
projects:
|
|
26
|
+
plastic:
|
|
27
|
+
path: "/path/to/plastic"
|
|
28
|
+
remote: "git@github.com:org/plastic.git"
|
|
29
|
+
registered: '2026-05-26'
|
|
30
|
+
status: active
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Config resolution: `~/.plastic/projects/{slug}/config.yml` overrides `~/.plastic/config.yml`.
|
|
34
|
+
|
|
35
|
+
Cross-linking: project intents reference global intents via `[[global:ID]]`. Global intents reference project intents via `[[project-slug:ID]]`.
|
|
36
|
+
|
|
37
|
+
## Privacy and Collaboration
|
|
38
|
+
|
|
39
|
+
**Plastic is personal.** All intent data lives under `~/.plastic/` — one location,
|
|
40
|
+
one git repo, never pushed. Each person has their own intent store.
|
|
41
|
+
|
|
42
|
+
Collaboration happens through pull requests and project conventions, not shared intents.
|
|
43
|
+
When an intent delivers something that changes how a project works, the decision gets
|
|
44
|
+
written into the project's shared files (README, docs, config). The intents themselves
|
|
45
|
+
are private working memory.
|
|
46
|
+
|
|
47
|
+
## Project Creation Flow
|
|
48
|
+
|
|
49
|
+
When an implementation intent spawns a project:
|
|
50
|
+
1. Determine project path from config `project_roots` or intent context
|
|
51
|
+
2. `gh repo create --private` (agent-created repos are always private by default)
|
|
52
|
+
3. Set up project directory, git init, AGENTS.md with founding intent decisions
|
|
53
|
+
4. Register in `projects.yml`
|
|
54
|
+
5. Create tactical mirror in project store
|
|
55
|
+
6. The global intent completes; the tactical mirror becomes the active intent
|