@zalom/plastic 2.0.0-alpha.21 → 2.0.0-alpha.23
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 +20 -18
- package/agents/plastic-enforcer.md +6 -3
- package/agents/plastic-executor.md +4 -0
- package/agents/plastic-node-research.md +28 -0
- package/agents/plastic-node-verify.md +27 -0
- package/agents/plastic-node-work.md +32 -0
- package/bin/lib/context_budget.rb +1 -1
- package/hooks/hooks.json +12 -0
- package/hooks/statusline +28 -0
- package/hooks/stop +5 -0
- package/package.json +1 -1
- package/scripts/doctor.rb +159 -10
- package/scripts/end-intent +3 -3
- package/scripts/graph-measure +249 -0
- package/scripts/hook-capture +1 -0
- package/scripts/hook-savepoint +24 -2
- package/scripts/hook-session-start +333 -321
- package/scripts/hook-stop +57 -0
- package/scripts/insight-append +18 -4
- package/scripts/lib/active_delivery.rb +61 -0
- package/scripts/lib/agent_models.rb +10 -1
- package/scripts/lib/codex_adapter.rb +197 -0
- package/scripts/lib/doctor_core.rb +8 -3
- package/scripts/lib/engine_permissions.rb +88 -0
- package/scripts/lib/graph_edges.rb +4 -4
- package/scripts/lib/graph_file.rb +4 -4
- package/scripts/lib/graph_measure.rb +645 -0
- package/scripts/lib/graph_measure_budget.rb +408 -0
- package/scripts/lib/graph_measure_cohorts.rb +487 -0
- package/scripts/lib/graph_measure_models.rb +411 -0
- package/scripts/lib/graph_measure_report.rb +532 -0
- package/scripts/lib/graph_tree.rb +2 -2
- package/scripts/lib/handoff.rb +36 -5
- package/scripts/lib/harness_adapter.rb +184 -0
- package/scripts/lib/hook_registry.rb +13 -1
- package/scripts/lib/hook_replay.rb +23 -5
- package/scripts/lib/index_projection.rb +1 -1
- package/scripts/lib/installer_core.rb +112 -6
- package/scripts/lib/intent_screen.rb +1 -1
- package/scripts/lib/intent_validator.rb +2 -2
- package/scripts/lib/meter_watch.rb +15 -9
- package/scripts/lib/node_file.rb +3 -3
- package/scripts/lib/node_ledger.rb +8 -1
- package/scripts/lib/node_progress.rb +153 -0
- package/scripts/lib/outcome_report.rb +1 -1
- package/scripts/lib/report_screen.rb +10 -6
- package/scripts/lib/roadmap_graph.rb +1 -1
- package/scripts/lib/roadmap_queue.rb +1 -1
- package/scripts/lib/roadmap_render.rb +1 -1
- package/scripts/lib/runner_absorb.rb +31 -5
- package/scripts/lib/runner_dispatch.rb +26 -11
- package/scripts/lib/runner_until_empty.rb +252 -0
- package/scripts/lib/runner_watch.rb +389 -0
- package/scripts/lib/savepoint.rb +3 -3
- package/scripts/lib/session_git.rb +2 -2
- package/scripts/lib/stop_gate.rb +95 -0
- package/scripts/lib/verify_intent.rb +2 -2
- package/scripts/lib/work_graph_validator.rb +6 -6
- package/scripts/new-intent +1 -1
- package/scripts/node-run +224 -0
- package/scripts/read-config +6 -0
- package/scripts/runner +203 -19
- package/scripts/skill-lint +115 -6
- package/scripts/verify-intent +1 -1
- package/skills/auto/SKILL.md +54 -56
- package/skills/auto/references/agent-architecture.md +10 -8
- package/skills/auto/references/human-report-contract.md +1 -1
- package/skills/conventions/references/completion-and-done.md +7 -7
- package/skills/conventions/references/knowledge-graph.md +9 -0
- package/skills/conventions/references/locks-and-worktrees.md +3 -3
- package/skills/conventions/references/maintenance-and-revisions.md +1 -1
- package/skills/doctor/SKILL.md +3 -3
- package/skills/doctor/report.md +1 -1
- package/skills/intent-continuing/references/boarding-matrix.md +2 -2
- package/skills/intent-creating/SKILL.md +58 -133
- package/skills/intent-creating/evals/evals.json +1 -1
- package/skills/intent-ending/SKILL.md +48 -56
- package/skills/intent-ending/evals/evals.json +1 -1
- package/skills/intent-executing/SKILL.md +43 -136
- package/skills/intent-speccing/SKILL.md +3 -0
- package/skills/releasing/SKILL.md +1 -1
- package/skills/releasing/references/release-lines.md +1 -1
- package/skills/tutorial/SKILL.md +2 -1
- package/skills/tutorial/references/track-1-guided.md +21 -40
- package/skills/tutorial/references/track-2-auto.md +3 -3
- package/templates/agents.md +2 -2
|
@@ -29,12 +29,13 @@ in 2.0, intent 304; the lead writes the Why and How record itself):
|
|
|
29
29
|
- **plastic-executor** (Exec): commits the matrix's tests red, writes the code, checks off
|
|
30
30
|
`checklist.md`, appends `## Insights`, and drives the suite green.
|
|
31
31
|
- **the plan reviewer**: a fresh agent on `plastic-intent-executing`'s
|
|
32
|
-
`plan-reviewer-prompt.md`,
|
|
32
|
+
`plan-reviewer-prompt.md`, an optional dispatch before any code exists.
|
|
33
33
|
- **the post-execution reviewer**: a fresh agent on `code-quality-reviewer-prompt.md`,
|
|
34
34
|
dispatched only when the auto skill's risk rule fires; never the maker.
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
One agent boot (the executor) is the minimum delivery; the plan reviewer is a second,
|
|
37
|
+
optional boot when the lead calls for review before code, and the post-execution reviewer is
|
|
38
|
+
a third only when risk calls for it.
|
|
38
39
|
|
|
39
40
|
### Handoff Contracts
|
|
40
41
|
|
|
@@ -44,8 +45,8 @@ the code, the red and green commits, a checked-off checklist, `## Insights`, and
|
|
|
44
45
|
report. Dispatch is sequential on a single branch, because the deliverables share files.
|
|
45
46
|
|
|
46
47
|
The chain: intent `## Intent` / `## Context`, then enriched `## Context` plus `### Decisions`,
|
|
47
|
-
then `spec.md`, then `plan.md` plus `actions/` plus `checklist.md`, then
|
|
48
|
-
the code changes plus a checked-off checklist plus `## Insights`.
|
|
48
|
+
then `spec.md`, then `plan.md` plus `actions/` plus `checklist.md`, then an optional plan
|
|
49
|
+
review, then the code changes plus a checked-off checklist plus `## Insights`.
|
|
49
50
|
|
|
50
51
|
### Spawn Preamble (L2 live-state injection)
|
|
51
52
|
|
|
@@ -88,9 +89,10 @@ not revoke the registered delegate's authorization.
|
|
|
88
89
|
|
|
89
90
|
### Review Ownership
|
|
90
91
|
|
|
91
|
-
The lead owns every review decision: it dispatches the plan reviewer before code
|
|
92
|
-
|
|
93
|
-
never delegates that decision, and neither reviewer is ever
|
|
92
|
+
The lead owns every review decision: it dispatches the plan reviewer before code when one
|
|
93
|
+
runs, takes the review into its own record, and decides from the risk rule whether the
|
|
94
|
+
post-execution reviewer runs. It never delegates that decision, and neither reviewer is ever
|
|
95
|
+
the maker of what it reviews.
|
|
94
96
|
Nothing blocks a write in 2.0 (the gate hooks were removed, intent 302); the lock, the
|
|
95
97
|
worktree, and the record are how the team keeps one delivery in one place.
|
|
96
98
|
|
|
@@ -78,7 +78,7 @@ an executor's intermediate commit, or an agent going idle is NOT one of them:
|
|
|
78
78
|
|
|
79
79
|
| Trigger | Scope |
|
|
80
80
|
|---|---|
|
|
81
|
-
| A savepoint line lands (a stage boundary: Why, How, Exec started, outcome written,
|
|
81
|
+
| A savepoint line lands (a stage boundary: Why, How, Exec started, outcome written, End) | that intent |
|
|
82
82
|
| A review verdict returns (plan review or post-execution review), naming what it changed | that intent |
|
|
83
83
|
| A blocker or needs-input is logged | that intent |
|
|
84
84
|
| A merge or a release lands | that intent |
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# Completion and
|
|
1
|
+
# Completion and the End Tail
|
|
2
2
|
|
|
3
3
|
This chapter holds what "intent done" means and the End-stage tail.
|
|
4
4
|
|
|
5
5
|
#### What "intent done" means (intent 93)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Completion is one law with three signals, and they must agree. INDEX `## Completed` /
|
|
8
8
|
`## Abandoned` is the single canonical terminal marker: it is the store-wide ledger a fresh
|
|
9
9
|
session reads first, so it wins on any conflict. `outcome.md` is the "deliverable exists"
|
|
10
|
-
signal, and the savepoint `
|
|
11
|
-
agree; when they disagree, INDEX is authoritative and `doctor` flags the mismatch (the
|
|
10
|
+
signal, and the savepoint's terminal `delivered|abandoned` line is the audit echo. All three
|
|
11
|
+
must agree; when they disagree, INDEX is authoritative and `doctor` flags the mismatch (the
|
|
12
12
|
`done_signals` check: `outcome.md` real but still under `## Active`, or terminal without a
|
|
13
|
-
real `outcome.md`, or a terminal intent whose savepoint carries no
|
|
13
|
+
real `outcome.md`, or a terminal intent whose savepoint carries no terminal disposition line).
|
|
14
14
|
|
|
15
15
|
`outcome.md` is mandatory at every terminal transition, delivered and abandoned alike. It
|
|
16
16
|
self-declares its disposition through a `disposition: delivered|abandoned` frontmatter
|
|
@@ -18,8 +18,8 @@ header. The delivered path authors it with the result; the abandoned path author
|
|
|
18
18
|
the abandonment reason and no longer leaves the scaffolded placeholder sentinel in place.
|
|
19
19
|
|
|
20
20
|
The canonical End tail runs in this order, and the QMD reindex is always LAST, after the
|
|
21
|
-
purge: `outcome.md -> INDEX terminal -> savepoint
|
|
22
|
-
-> Lock.release -> purge) -> QMD reindex`. Running the reindex last keeps the index from
|
|
21
|
+
purge: `outcome.md -> INDEX terminal -> the terminal savepoint line -> commit -> disarm
|
|
22
|
+
(Worktree.release -> Lock.release -> purge) -> QMD reindex`. Running the reindex last keeps the index from
|
|
23
23
|
ever referencing a bridge or lock that disarm is about to remove.
|
|
24
24
|
|
|
25
25
|
`scripts/end-intent` performs this order's disarm step (verify the code worktree is clean,
|
|
@@ -45,3 +45,12 @@ This chapter holds the linking doctrine from Frontmatter and the branch-vs-root
|
|
|
45
45
|
the relation on the PREDECESSOR's `chain` (and mirror it as a
|
|
46
46
|
`[[id--slug|<target's full intent: text>]]` wikilink in `## Links`).
|
|
47
47
|
- **Rule of thumb:** if the intent could exist without its parent, it's a root.
|
|
48
|
+
|
|
49
|
+
## Naming
|
|
50
|
+
|
|
51
|
+
A thing is named after the concept family it lives under. A node is a graph-engineering
|
|
52
|
+
concept, so its name comes from graph engineering (node, edge, ready set, critical path),
|
|
53
|
+
from the Plastic concepts coined on top of it (intent, ledger, packet, lease, gate, runner),
|
|
54
|
+
and from the software and AI engineering concepts those rest on (review, fix, test, verify,
|
|
55
|
+
dispatch, executor, reviewer). A name from outside that stack is refused. Where no existing
|
|
56
|
+
concept fits, that is a design finding to raise, not a word to coin.
|
|
@@ -84,13 +84,13 @@ Provisioning fails open for intents that touch no project code (pure research or
|
|
|
84
84
|
intents in the global store, or a non-git repo): those get the lock only, and the worktree
|
|
85
85
|
block stays unprovisioned. The fail-open path is always logged, never silent.
|
|
86
86
|
|
|
87
|
-
Cleanup is part of
|
|
87
|
+
Cleanup is part of the End tail: it merges the branch, then removes the worktree. Never leave
|
|
88
88
|
an orphaned worktree behind, and clear a stale worktree reference with `git worktree prune`.
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
#### Intent delivery, station by station
|
|
92
92
|
|
|
93
|
-
How one auto-team intent travels from boarding to
|
|
93
|
+
How one auto-team intent travels from boarding to the End tail, and what the lock, the pointer, and
|
|
94
94
|
the record hook do at each station. Nothing in the third column blocks; the fourth column is
|
|
95
95
|
what gets written down.
|
|
96
96
|
|
|
@@ -101,7 +101,7 @@ what gets written down.
|
|
|
101
101
|
| Why | `spec.md` | owner writes refresh the lease (lock file mtime heartbeat) | savepoint `Why started`, `Why spec.md created` |
|
|
102
102
|
| How | `plan.md`, `actions/ACTION_N.md` (at least one), `checklist.md` | heartbeat on writes | savepoint `How started`, `How plan.md created`, `How checklist.md created`, `Exec started` |
|
|
103
103
|
| Exec | code on the intent branch, checklist checked off | heartbeat; code edits confined to the provisioned worktree; delegates write under the owner's lock | checklist boxes; savepoint milestones; the day-ledger line promotes when a project file lands |
|
|
104
|
-
| End (done) | mandatory `outcome.md` (`disposition: delivered\|abandoned`), INDEX moves to Completed or Abandoned | ordered End tail: verify, merge and remove worktrees, disarm clears `delivery.lock`, then the pointer is purge-eligible, and the QMD reindex runs LAST (after purge); `end-intent` backfills a placeholder `outcome.md` from the record and its structure check reports (never refuses) | savepoint `
|
|
104
|
+
| End (done) | mandatory `outcome.md` (`disposition: delivered\|abandoned`), INDEX moves to Completed or Abandoned | ordered End tail: verify, merge and remove worktrees, disarm clears `delivery.lock`, then the pointer is purge-eligible, and the QMD reindex runs LAST (after purge); `end-intent` backfills a placeholder `outcome.md` from the record and its structure check reports (never refuses) | the savepoint's terminal `delivered` (or `abandoned`) line; takeover audits, if any, remain in savepoint.md |
|
|
105
105
|
| Maintenance (Future, Terminal, or Active-with-a-stale-or-no-lock) | `revisions.md` move-and-record entries | detects (never acquires) `delivery.lock`; defers and reports while the target's lock is FRESH (`Lock.fresh?`); a stale or absent lock is not-active, maintenance proceeds | append-only, rule-tagged `revisions.md` entry written in the same operation as the change, or the change is refused; lands via a fresh branch off store main merged back as one closed op, never `git add -A` |
|
|
106
106
|
|
|
107
107
|
## The write guard is not residue
|
|
@@ -8,7 +8,7 @@ Plastic separates two different things an earlier doctrine blurred under one wor
|
|
|
8
8
|
"immutable." WORK is the delivered CONTENT an intent produced: the code and project files a
|
|
9
9
|
delivery changed, the research it recorded, the outcome it wrote. Once the intent is terminal
|
|
10
10
|
(Completed or Abandoned), that content is immutable - the only way to change it is another
|
|
11
|
-
intent that continues or reverts it. Editing a
|
|
11
|
+
intent that continues or reverts it. Editing a terminal intent's own artifacts so it looks like it
|
|
12
12
|
delivered something different, or that parts are missing, is forbidden (the book analogy:
|
|
13
13
|
never rewrite the text on the pages of an old, valuable book).
|
|
14
14
|
|
package/skills/doctor/SKILL.md
CHANGED
|
@@ -223,7 +223,7 @@ knowingly-exempt `(intent_id, rule)` pairs. Format: one `rule_name id id id` lin
|
|
|
223
223
|
blank lines and `#` comments ignored. v1 honors exactly one rule, `savepoint_operational`.
|
|
224
224
|
|
|
225
225
|
**Reading the count.** When any exclusion applies, the `savepoint_operational` check's message
|
|
226
|
-
|
|
226
|
+
includes the count and the file's path, e.g. `"... (3 excluded via ~/.plastic/doctor-exclusions)"`.
|
|
227
227
|
A malformed line in the file forces the check to `warn` with the parse error in `details`, even
|
|
228
228
|
when zero real gaps remain, so a broken file is never silently permissive.
|
|
229
229
|
|
|
@@ -262,7 +262,7 @@ Locks exist for auto teams: a `delivery.lock` file in the intent directory names
|
|
|
262
262
|
session, and the `record` hook refreshes its mtime on every edit (the lease heartbeat; stale
|
|
263
263
|
means older than the TTL). Direct work takes no lock. When a lock reads held by a session
|
|
264
264
|
that is gone, when work resumes after a crash, reboot, or `/tmp` wipe, or when the user says
|
|
265
|
-
"fix the lock", "who holds the lock", or "reclaim the lock", use the CLI (intent 304
|
|
265
|
+
"fix the lock", "who holds the lock", or "reclaim the lock", use the CLI (intent 304 merged
|
|
266
266
|
the former locking skill here):
|
|
267
267
|
|
|
268
268
|
| Verb | What it does | When |
|
|
@@ -290,7 +290,7 @@ these verbs (claims, worktrees, the station ledger).
|
|
|
290
290
|
## Provisioning a project store
|
|
291
291
|
|
|
292
292
|
When a project is registered in `~/.plastic/projects.yml` but has no store on disk (doctor
|
|
293
|
-
reports `project_store_dir`), provision it (intent 304
|
|
293
|
+
reports `project_store_dir`), provision it (intent 304 merged the former provisioning skill
|
|
294
294
|
here). The slug is the project's key under `projects`; an unregistered slug exits non-zero and
|
|
295
295
|
creates nothing, and this procedure never edits `projects.yml`.
|
|
296
296
|
|
package/skills/doctor/report.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
core_files -> "Core Files"
|
|
19
19
|
project_stores -> "Project Stores"
|
|
20
20
|
deprecations -> "Deprecations"
|
|
21
|
-
done_signals -> "
|
|
21
|
+
done_signals -> "Completion Signals"
|
|
22
22
|
session_ledger -> "Session Ledger" (global store only)
|
|
23
23
|
4. For each check within a category, emit one line with the status icon
|
|
24
24
|
and the check message. If the check has non-empty details, list them
|
|
@@ -12,7 +12,7 @@ Classify from the last line alone, then verify only that line's artifact is real
|
|
|
12
12
|
| `How started` / `How plan.md created` | (How in progress) | **How** | finish `plan.md` and `checklist.md` |
|
|
13
13
|
| `How checklist.md created` / `Exec started` | How | **Exec** | do the work, check off the checklist |
|
|
14
14
|
| `Exec outcome.md created` | Exec | **ready to complete** | the ending procedure (`plastic-intent-ending`) |
|
|
15
|
-
| `
|
|
15
|
+
| A terminal savepoint line (`delivered` or `abandoned`) | terminal | **report only** | immutable; ask what is next |
|
|
16
16
|
| A node or `Intent` transition line (`n1 running ...`, `Intent needs_decision ...`) | Exec | **Exec** | a graph delivery is in progress; read node status through `NodeLedger.status`, never re-derive it by eye |
|
|
17
17
|
|
|
18
18
|
## Per-stage behaviour (what "continue" means)
|
|
@@ -24,7 +24,7 @@ Classify from the last line alone, then verify only that line's artifact is real
|
|
|
24
24
|
The first unchecked `checklist.md` item is the next step; the newest `## Insights` entry
|
|
25
25
|
supplies the context.
|
|
26
26
|
- **ready to complete**: `outcome.md` is real; run the ending procedure.
|
|
27
|
-
- **
|
|
27
|
+
- **End**: terminal. Report the outcome, ask what is next. Never reopen; `INDEX.md` is
|
|
28
28
|
authoritative.
|
|
29
29
|
|
|
30
30
|
## Notes
|
|
@@ -6,110 +6,51 @@ user-invocable: true
|
|
|
6
6
|
|
|
7
7
|
# Creating an Intent
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Creating writes the thought to disk: an id, a directory, a born-complete intent file.
|
|
10
|
+
Nothing else runs here; specifying, planning, and execution are separate, later skills.
|
|
11
|
+
|
|
12
|
+
## When to use
|
|
10
13
|
- User starts new work ("build X", "fix Y", "research Z")
|
|
11
14
|
- No active intent matches the current task
|
|
12
15
|
- User explicitly says "new intent" or "create intent"
|
|
13
16
|
- An agent discovers work needed during implementation
|
|
14
17
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
When creating a tactical intent in a project store:
|
|
33
|
-
- Read the project's `AGENTS.md` for project context and decisions
|
|
34
|
-
- Link back to the project's governing intent (from `projects.yml` `parent` field) via `sources` (the project genuinely is formed from its founding intent, a true formative edge, reciprocated on the founding intent's `chain`)
|
|
35
|
-
- Add `[[global:<parent_ID>]]` backlink in `## Links`
|
|
36
|
-
- The intent's Folgezettel ID is scoped to the project store (run `folgezettel-id` against the project's store at `~/.plastic/projects/{slug}/store/`)
|
|
37
|
-
|
|
38
|
-
## Workflow
|
|
18
|
+
## Decide the store and the shape, before scaffolding
|
|
19
|
+
|
|
20
|
+
- **CWD inside a registered project** (`~/.plastic/projects.yml`), or the user names a
|
|
21
|
+
project by slug -> **project intent (tactical)**, `~/.plastic/projects/{slug}/store/`,
|
|
22
|
+
linked back to the project's governing intent (`projects.yml` `parent` field) via
|
|
23
|
+
`sources`, with `[[global:<parent_ID>]]` in `## Links` and a Folgezettel id scoped to
|
|
24
|
+
that store.
|
|
25
|
+
- **No match** -> **global intent (strategic)**, `~/.plastic/store/`.
|
|
26
|
+
- **Duplicate or predecessor check (QMD-first):** before allocating an id, run
|
|
27
|
+
`ruby ~/.plastic/scripts/qmd-sync search "<terms>"` (a no-op when QMD is absent, fall
|
|
28
|
+
back to INDEX.md) so a near-duplicate is reused and a true predecessor lands in
|
|
29
|
+
`--sources`.
|
|
30
|
+
- **Branch vs root**, decided by meaning, not by "a parent in mind": branch
|
|
31
|
+
(`--parent <parent_id>`) when the intent only makes sense as part of the parent's work;
|
|
32
|
+
root with `--sources <ascendant_id>` when it was created from another intent's
|
|
33
|
+
lifecycle; root with no `--sources` when it is merely related (record that relation on
|
|
34
|
+
the PREDECESSOR's `chain` instead - topic similarity alone is never a `sources` edge).
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
### 2. Check for a Duplicate or Predecessor (QMD-first)
|
|
46
|
-
|
|
47
|
-
QMD-first (when available): before scanning the store with grep/Read, run
|
|
48
|
-
`ruby ~/.plastic/scripts/qmd-sync search "<terms>"` to surface candidate, prior, or duplicate
|
|
49
|
-
intents, then open the authoritative intent file for any hit you act on. The command is a no-op
|
|
50
|
-
when QMD is absent, so fall back to the existing INDEX.md / file scan. Do this before allocating
|
|
51
|
-
the id so a near-duplicate can be reused and a true predecessor can be set in `--sources`.
|
|
52
|
-
|
|
53
|
-
### 3. Decide Branch vs Root
|
|
36
|
+
When a branch intent exists because a late ruling arrived AFTER its parent was already
|
|
37
|
+
completed, the parent is restored to v1 via `scripts/restore-intent-v1`, never a hand-run
|
|
38
|
+
`git checkout`/revert (see `plastic-conventions > references/maintenance-and-revisions.md`,
|
|
39
|
+
WORK vs MAINTENANCE).
|
|
54
40
|
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
`## Links` is a DERIVED view of `sources`/`chain`: never hand-write a `## Links` line, add
|
|
42
|
+
the frontmatter edge and reproject. Links follow context influence (a `chain` edge needs
|
|
43
|
+
the candidate's context to materially help deliver this intent), never shared files or a
|
|
44
|
+
similarity score; `scripts/link-suggest` and `scripts/project-links` gather candidates.
|
|
45
|
+
Read `../plastic-conventions/references/knowledge-graph.md` for the full linking doctrine:
|
|
46
|
+
the tiers of influence, sources versus chain, and how `## Links` is derived.
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
makes sense as part of the parent's work. Pass `--parent <parent_id>`.
|
|
60
|
-
- **Root (`15`, `16`)**: an independent thought. Two cases, decided by ORIGIN:
|
|
61
|
-
- **Created from another intent** (it emerged from that intent's lifecycle): make it a
|
|
62
|
-
root and set `--sources <ascendant_id>`. `sources` is reserved for true created-from /
|
|
63
|
-
direct-ascendant provenance (D1).
|
|
64
|
-
- **Merely related to / inspired by another intent** (it did NOT come out of that
|
|
65
|
-
intent's lifecycle): carry NO `--sources`. Record the relation on the PREDECESSOR's
|
|
66
|
-
`chain` instead (the related-but-not-spawned rule); the `## Links` section follows
|
|
67
|
-
from that edge, you do not write it by hand.
|
|
68
|
-
- **Rule of thumb:** if the intent could exist without its parent, make it a root; only set
|
|
69
|
-
`--sources` when it was genuinely created from / emerged from that intent's lifecycle.
|
|
70
|
-
Topic similarity alone is not a `sources` edge.
|
|
48
|
+
## Scaffold
|
|
71
49
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
rule and the tool.
|
|
77
|
-
|
|
78
|
-
`## Links` is a DERIVED view of `sources`/`chain`. Never hand-write a `## Links` line; add the
|
|
79
|
-
frontmatter edge and reproject. Links are decided by context influence (a `chain` edge has a high
|
|
80
|
-
bar: the candidate's context must materially help deliver this intent), not by shared files or a
|
|
81
|
-
similarity score. To gather candidates with their context and record an edge, use the
|
|
82
|
-
`scripts/link-suggest` and `scripts/project-links`.
|
|
83
|
-
|
|
84
|
-
Read `../plastic-conventions/references/knowledge-graph.md` for the full linking doctrine: the
|
|
85
|
-
tiers of influence, sources versus chain, and how the `## Links` projection is derived. This path
|
|
86
|
-
resolves relative to this skill's own installed directory.
|
|
87
|
-
|
|
88
|
-
### 4. Determine Intent Properties
|
|
89
|
-
|
|
90
|
-
Ask or infer from context:
|
|
91
|
-
- **intent**: one-line description
|
|
92
|
-
- **slug**: short hyphenated handle for the directory name
|
|
93
|
-
- **author**: `human` | `claude-code` | other agent name
|
|
94
|
-
- **sources**: the direct ascendant(s) this intent was created from / emerged from the
|
|
95
|
-
lifecycle of (formation, not topic similarity), e.g., `4a1`. For a project intent,
|
|
96
|
-
include the governing intent's id. A branch's structural parent is ALSO recorded in
|
|
97
|
-
`sources` (the ID carries it for the human/paper tree, `sources` carries it for
|
|
98
|
-
software), which `new-intent` does automatically (see `new-intent:126`).
|
|
99
|
-
- **tags**: freeform list (use `project-<name>` for project membership)
|
|
100
|
-
|
|
101
|
-
`chain` carries what this intent spawns AND related-but-not-spawned successors it leads to;
|
|
102
|
-
it starts empty and is populated later. See
|
|
103
|
-
[`how-plastic-sources-and-chains-intents.md`](https://github.com/zalom/plastic/blob/main/docs/concepts/how-plastic-sources-and-chains-intents.md) for the full model.
|
|
104
|
-
Place the intent in `## Active` or `## Future` in INDEX.md (status is
|
|
105
|
-
convention-derived, not a frontmatter field).
|
|
106
|
-
|
|
107
|
-
### 5. Scaffold via new-intent (single call)
|
|
108
|
-
|
|
109
|
-
Delegate id allocation, directory and file creation, the born-complete intent
|
|
110
|
-
file, the sentinel placeholder lifecycle files, the reciprocal file links, and
|
|
111
|
-
self-validation to one `new-intent` invocation. Do NOT hand-author any of these
|
|
112
|
-
files.
|
|
50
|
+
One call does the rest: id allocation, the directory, `actions/` and `resources/`, the
|
|
51
|
+
born-complete intent file, sentinel placeholder lifecycle files (each marked
|
|
52
|
+
`<!-- plastic:placeholder -->` so no stage detector reads them as reached), reciprocal
|
|
53
|
+
`[[id]]` links, and self-validation. Do NOT hand-author any of these files.
|
|
113
54
|
|
|
114
55
|
```bash
|
|
115
56
|
ruby ~/.plastic/scripts/new-intent \
|
|
@@ -118,47 +59,31 @@ ruby ~/.plastic/scripts/new-intent \
|
|
|
118
59
|
[--sources "id,id"] [--tags "project-<slug>,tag"]
|
|
119
60
|
```
|
|
120
61
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
placeholder `spec.md`/`plan.md`/`checklist.md`/`outcome.md` (each marked
|
|
125
|
-
`<!-- plastic:placeholder -->` so no stage detector reads them as reached), wires
|
|
126
|
-
the reciprocal `[[id]]` links, and self-validates (frontmatter plus the sanctioned
|
|
127
|
-
`##` sections). It prints the created directory path and exits 0.
|
|
128
|
-
|
|
129
|
-
It does NOT touch INDEX.md, git, or project creation: those stay in this skill
|
|
130
|
-
(steps 6 to 9 below).
|
|
131
|
-
|
|
132
|
-
If `new-intent` exits non-zero, read the stderr report and fix the inputs (slug,
|
|
133
|
-
intent, sources). Do not commit or announce an intent that did not scaffold
|
|
134
|
-
cleanly, and do not work around the failure by hand-writing the files.
|
|
135
|
-
|
|
136
|
-
### 6. If Implementation Intent Spawns a Project
|
|
137
|
-
|
|
138
|
-
When the user says "start building" or the plan calls for a new project, invoke the
|
|
139
|
-
`plastic-project-creating` skill; it owns project directory creation, AGENTS.md
|
|
140
|
-
population, projects.yml registration, store provisioning, and the auto-commit of
|
|
141
|
-
both stores. Add `project-<slug>` to this intent's `tags` array either before
|
|
142
|
-
invoking it or as part of that skill's handoff.
|
|
143
|
-
|
|
144
|
-
### 7. Update INDEX.md
|
|
62
|
+
It does NOT touch INDEX.md, git, or project creation (Finish, below). If it exits
|
|
63
|
+
non-zero, read the stderr report, fix the inputs (slug, intent, sources), and retry;
|
|
64
|
+
never work around a failed scaffold by hand-writing the files.
|
|
145
65
|
|
|
146
|
-
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
### 8. Auto-commit
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
cd <store-root> && git add . && git commit -m "feat: create intent ID - [name]"
|
|
155
|
-
```
|
|
66
|
+
`chain` carries what this intent spawns AND related-but-not-spawned successors it leads
|
|
67
|
+
to; it starts empty and is populated later. See
|
|
68
|
+
[`how-plastic-sources-and-chains-intents.md`](https://github.com/zalom/plastic/blob/main/docs/concepts/how-plastic-sources-and-chains-intents.md)
|
|
69
|
+
for the full model.
|
|
156
70
|
|
|
157
|
-
|
|
71
|
+
## Finish
|
|
158
72
|
|
|
159
|
-
|
|
73
|
+
1. **Global intent:** add a line to `~/.plastic/INDEX.md` under `## Active` (or
|
|
74
|
+
`## Future`) and the right cluster. **Project intent:** no global INDEX.md change.
|
|
75
|
+
2. When the user says "start building" or the plan calls for a new project, invoke
|
|
76
|
+
`plastic-project-creating`; it owns project directory creation, AGENTS.md population,
|
|
77
|
+
`projects.yml` registration, store provisioning, and the auto-commit of both stores.
|
|
78
|
+
Add `project-<slug>` to this intent's `tags` either before invoking it or as part of
|
|
79
|
+
that skill's handoff.
|
|
80
|
+
3. Commit: `cd <store-root> && git add . && git commit -m "feat: create intent ID - [name]"`.
|
|
81
|
+
4. Announce: "Created intent ID - [name]. Placed in: [Active|Future]. Store:
|
|
82
|
+
[global|project:<slug>]."
|
|
160
83
|
|
|
161
84
|
## References
|
|
162
85
|
|
|
163
|
-
- Read `references/lifecycle.md` for the full What
|
|
164
|
-
-
|
|
86
|
+
- Read `references/lifecycle.md` for the full What->Why->How->Exec stage detail and the
|
|
87
|
+
filesystem-as-schema conventions.
|
|
88
|
+
- Read `references/wikilinks.md` for the wikilink syntax table when hand-checking a
|
|
89
|
+
`## Links` projection.
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"scope": "behavior",
|
|
36
36
|
"set": "validation",
|
|
37
37
|
"prompt": "Create an intent that is the direct continuation of intent 41: it emerged from intent 41's lifecycle and could not exist without it.",
|
|
38
|
-
"expected_output": "Because the new intent was genuinely CREATED FROM 41 (D1), it carries 41 in --sources (or branches from 41, which
|
|
38
|
+
"expected_output": "Because the new intent was genuinely CREATED FROM 41 (D1), it carries 41 in --sources (or branches from 41, which merges 41 into sources via the redundant-explicit rule). The reciprocal I1 backlink lands: intent 41's frontmatter chain gains the new intent's id. This is the created-from case, contrasted with the related-but-not-spawned case in eval 1.",
|
|
39
39
|
"files": [],
|
|
40
40
|
"assertions": [
|
|
41
41
|
{
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plastic-intent-ending
|
|
3
3
|
description: >
|
|
4
|
-
Wrap, finish,
|
|
5
|
-
when completing or abandoning an intent, when a
|
|
6
|
-
|
|
4
|
+
Wrap, finish, or close an intent as delivered or abandoned. Use
|
|
5
|
+
when completing or abandoning an intent, when a graph's last node
|
|
6
|
+
reaches a terminal status (or, for a legacy intent, a checklist
|
|
7
|
+
reaches 100 percent) and Exec is finished, or when asked to "wrap
|
|
8
|
+
this up".
|
|
7
9
|
user-invocable: true
|
|
8
10
|
---
|
|
9
11
|
|
|
@@ -26,7 +28,7 @@ installed directory.
|
|
|
26
28
|
| 0 | Precondition check | You, before touching outcome.md |
|
|
27
29
|
| 1 | backfill spec/plan/action/outcome from the record, self-check, intent-file `## Outcome` summary | `scripts/end-intent` |
|
|
28
30
|
| 2 | INDEX.md terminal move (Active -> Completed/Abandoned) | `scripts/end-intent` |
|
|
29
|
-
| 3 | savepoint
|
|
31
|
+
| 3 | the terminal savepoint line | `scripts/end-intent` |
|
|
30
32
|
| 4 | store auto-commit | `scripts/end-intent` |
|
|
31
33
|
| 5 | disarm (worktree + lock) | `scripts/end-intent` (intent 188) |
|
|
32
34
|
| 6 | QMD reindex, async, LAST | You |
|
|
@@ -45,50 +47,47 @@ Nothing refuses the close any more (the 1.x write-time gate and `end-intent`'s
|
|
|
45
47
|
exit-6 structure gate were retired in 2.0, intents 302 and 308). What you leave
|
|
46
48
|
on disk is what the record becomes, so before the call:
|
|
47
49
|
|
|
48
|
-
1.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
50
|
+
1. For an intent with a `graph.md`: confirm every node's Status in `graph.md` is
|
|
51
|
+
terminal (`done` or `failed_verification`, nothing left `running`, `blocked`, or
|
|
52
|
+
waiting `needs_decision`), and that the last verify node's gates were
|
|
53
|
+
accepted. A node still open is not a refusal, it is a reported gap that lands
|
|
54
|
+
verbatim in the backfilled `## Follow-ups`.
|
|
55
|
+
For an intent with no `graph.md` (legacy): read checklist.md, tick every item as
|
|
56
|
+
it is actually performed, including an item that describes the close itself:
|
|
57
|
+
running this very procedure IS what that item describes; an unchecked box is not
|
|
58
|
+
a refusal, it is a reported gap. Also confirm every acceptance criterion in
|
|
59
|
+
spec.md is verifiable (tests pass, or the manual check described in its HOW line
|
|
60
|
+
was actually run).
|
|
61
|
+
2. Decide what you have to say. For an intent with a `graph.md`, never hand-write
|
|
62
|
+
`outcome.md`: `scripts/end-intent` GENERATES it, through
|
|
63
|
+
`scripts/lib/outcome_report.rb` (`scripts/outcome-report` is its standalone
|
|
64
|
+
CLI, useful for checking the generated text before the close). `## Delivered`,
|
|
65
|
+
`## Verification`, `## Graph diff`, and `## Findings` are read straight from
|
|
66
|
+
`graph.md`, `nodes/`, and the ledger every time, in plain wording a reader
|
|
67
|
+
recognizes, never hand-typed; when the generated wording is wrong, fix
|
|
68
|
+
`graph.md` or `nodes/`, the source it reads from, not the report. `## Summary`,
|
|
69
|
+
`## Needs you`, and `## Follow-ups`, and every frontmatter key but
|
|
70
|
+
`disposition`, are preserved byte for byte when you author them and
|
|
71
|
+
generated as plain facts otherwise. For an intent with no `graph.md`, a
|
|
72
|
+
spec.md, plan.md, action file, or outcome.md left as the scaffold placeholder
|
|
73
|
+
is written from the record by `scripts/end-intent` (the intent file's
|
|
74
|
+
`## Intent`, `### Decisions`, and `## Insights`, the checklist, the worktree
|
|
75
|
+
diff). A file you wrote, even under a still-present sentinel, is never touched.
|
|
69
76
|
|
|
70
77
|
### Step 1-5. Run `scripts/end-intent`
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`##
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
abandonment reason and the trail (see Pivot below). An intent with a `graph.md` and no
|
|
85
|
-
hand-written outcome.md gets one generated instead (Step 0.3 above); a placeholder
|
|
86
|
-
outcome.md on an intent with no `graph.md` is backfilled from the record, with the
|
|
87
|
-
close's disposition and the `--outcome-summary` line as its summary. Also author
|
|
88
|
-
the rich INDEX entry note now (a short line in the store's existing
|
|
89
|
-
Completed/Abandoned convention: mode, what shipped or why it was
|
|
90
|
-
abandoned, suite result, merge/spawn notes); content authoring stays with
|
|
91
|
-
you, `--index-note` only appends what you write.
|
|
79
|
+
For an intent with a `graph.md`, do not author `outcome.md` by hand: run
|
|
80
|
+
`ruby ~/.plastic/scripts/outcome-report <intent_dir> --write --disposition delivered|abandoned`
|
|
81
|
+
if you want to see the generated text before the close, or let the single call below write it.
|
|
82
|
+
`## Summary`, `## Needs you`, and `## Follow-ups` are the sections worth your own words; edit
|
|
83
|
+
those into the file before the call when the generator's plain facts say too little (they are
|
|
84
|
+
preserved byte for byte). `## Needs you` is the literal None or a `| N | What | Why |` table.
|
|
85
|
+
On abandon, `## Summary` states the abandonment reason and the trail (see Pivot below). An
|
|
86
|
+
intent with no `graph.md` gets a placeholder outcome.md backfilled from the record instead,
|
|
87
|
+
with the close's disposition and the `--outcome-summary` line as its summary. Also author the
|
|
88
|
+
rich INDEX entry note now (a short line in the store's existing Completed/Abandoned
|
|
89
|
+
convention: mode, what shipped or why it was abandoned, suite result, merge/spawn notes);
|
|
90
|
+
content authoring stays with you, `--index-note` only appends what you write.
|
|
92
91
|
|
|
93
92
|
Then call the script once:
|
|
94
93
|
|
|
@@ -110,23 +109,16 @@ line from `## Active` to `## Completed` or `## Abandoned` (dated today,
|
|
|
110
109
|
idempotent, accepting either a real em dash or a plain hyphen as the id/
|
|
111
110
|
title separator on read while always emitting the real em dash on write)
|
|
112
111
|
with the `--index-note` text appended after the date so the entry stays
|
|
113
|
-
rich, appends the savepoint
|
|
112
|
+
rich, appends the terminal savepoint line, commits the store repo, and
|
|
114
113
|
disarms (releases the code worktree and clears `delivery.lock`, verified
|
|
115
114
|
against the durable lock file on disk, never merely trusted). Omit
|
|
116
115
|
`--index-note` for a thin id+date entry, add `--no-commit` when a separate
|
|
117
116
|
commit step already covers the store (this never skips disarm), and
|
|
118
117
|
`--dry-run` to preview steps 1-5 with no writes.
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
existing `delivery.lock`. A live foreign session refuses the whole run
|
|
124
|
-
(exit 4, nothing written); a stale foreign lock is reclaimed automatically
|
|
125
|
-
(audited to savepoint.md) and the run proceeds as the new owner. Before
|
|
126
|
-
removing the worktree, step 5 also refuses on an unexpectedly dirty code
|
|
127
|
-
worktree (exit 5, naming the worktree path) rather than force-discarding
|
|
128
|
-
uncommitted changes; pass `--discard-worktree-changes` only when you mean
|
|
129
|
-
to override that deliberately.
|
|
119
|
+
Read `../plastic-conventions/references/completion-and-done.md` for the pre-flight lock guard
|
|
120
|
+
and the dirty-worktree refusal this call runs before writing anything (exit 4 and exit 5
|
|
121
|
+
below); this procedure only calls `end-intent`, it never re-implements them.
|
|
130
122
|
|
|
131
123
|
On the auto mode / curator path (no release), this single call performs the
|
|
132
124
|
FULL disarm (plain worktree remove, since the branch survives for later
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"scope": "behavior",
|
|
20
20
|
"set": "train",
|
|
21
21
|
"prompt": "Run the mechanical close (scripts/end-intent) for a delivered intent with a real outcome.md.",
|
|
22
|
-
"expected_output": "The savepoint
|
|
22
|
+
"expected_output": "The terminal savepoint line lands exactly once in savepoint.md, and a second run of the same command does not duplicate it (this is the regression the intent fixes: releasing used to skip this line entirely).",
|
|
23
23
|
"files": [],
|
|
24
24
|
"assertions": [
|
|
25
25
|
{ "type": "human", "check": "SKILL.md Step 1-4 calls scripts/end-intent as one script instead of restating the outcome/INDEX/savepoint one-liners in prose", "result": "expect-pass" },
|