devlyn-cli 4.1.0 → 4.2.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/AGENTS.md +10 -94
- package/CLAUDE.md +7 -160
- package/LICENSE +21 -0
- package/README.md +65 -110
- package/bin/devlyn.js +95 -116
- package/bin/instruction-templates.json +43 -2
- package/bin/instructions.js +29 -8
- package/config/skills/_shared/adapters/claude.md +8 -85
- package/config/skills/_shared/adapters/codex.md +14 -34
- package/config/skills/_shared/adapters/omp.md +1 -11
- package/config/skills/_shared/codex-monitored.sh +4 -54
- package/config/skills/_shared/engine-doctor.sh +18 -58
- package/config/skills/_shared/engine-preflight.md +15 -47
- package/config/skills/_shared/expected-contract.py +242 -0
- package/config/skills/_shared/expected.schema.json +10 -95
- package/config/skills/_shared/invocation-receipt.py +26 -757
- package/config/skills/_shared/platform-support.py +37 -28
- package/config/skills/_shared/role-config.py +100 -421
- package/config/skills/_shared/runtime-principles.md +17 -93
- package/config/skills/_shared/task-complete.py +490 -285
- package/config/skills/_shared/task-completion.md +235 -0
- package/config/skills/devlyn-engines/SKILL.md +9 -11
- package/config/skills/devlyn-ideate/SKILL.md +57 -107
- package/config/skills/devlyn-ideate/references/elicitation.md +18 -99
- package/config/skills/devlyn-ideate/references/loop.md +110 -0
- package/config/skills/devlyn-ideate/references/package-format.md +128 -0
- package/config/skills/devlyn-ideate/scripts/acceptance.py +795 -0
- package/config/skills/devlyn-ideate/scripts/queue.py +1780 -0
- package/package.json +2 -3
- package/config/commit-conventions.md +0 -28
- package/config/skills/_shared/adapters/README.md +0 -74
- package/config/skills/_shared/adapters/grok.md +0 -100
- package/config/skills/_shared/archive_run.py +0 -969
- package/config/skills/_shared/codex-config.md +0 -81
- package/config/skills/_shared/collect-codex-findings.py +0 -505
- package/config/skills/_shared/finish-gate.py +0 -521
- package/config/skills/_shared/grok-anchor-guard.py +0 -78
- package/config/skills/_shared/judge-output-parser.py +0 -200
- package/config/skills/_shared/judge-role-evidence.py +0 -320
- package/config/skills/_shared/phase-prompt-render.py +0 -183
- package/config/skills/_shared/process-evidence.py +0 -926
- package/config/skills/_shared/resolve-bootstrap.py +0 -1410
- package/config/skills/_shared/resolve-stop-hook.py +0 -359
- package/config/skills/_shared/run-bounded.py +0 -58
- package/config/skills/_shared/spec-verify-check.py +0 -5083
- package/config/skills/_shared/state-phase-write.py +0 -5989
- package/config/skills/_shared/terminal-claim-check.py +0 -777
- package/config/skills/_shared/verify-merge-findings.py +0 -3528
- package/config/skills/devlyn-design-ui/SKILL.md +0 -650
- package/config/skills/devlyn-ideate/references/from-spec-mode.md +0 -61
- package/config/skills/devlyn-ideate/references/project-mode.md +0 -80
- package/config/skills/devlyn-ideate/references/spec-template.md +0 -121
- package/config/skills/devlyn-ideate/references/templates/decision.md +0 -48
- package/config/skills/devlyn-ideate/references/templates/roadmap.md +0 -50
- package/config/skills/devlyn-ideate/references/templates/vision.md +0 -44
- package/config/skills/devlyn-queue/SKILL.md +0 -66
- package/config/skills/devlyn-queue/scripts/append.py +0 -94
- package/config/skills/devlyn-resolve/SKILL.md +0 -379
- package/config/skills/devlyn-resolve/references/free-form-mode.md +0 -71
- package/config/skills/devlyn-resolve/references/outer-loop.md +0 -23
- package/config/skills/devlyn-resolve/references/phases/build-gate.md +0 -75
- package/config/skills/devlyn-resolve/references/phases/cleanup.md +0 -33
- package/config/skills/devlyn-resolve/references/phases/implement.md +0 -44
- package/config/skills/devlyn-resolve/references/phases/plan.md +0 -39
- package/config/skills/devlyn-resolve/references/phases/probe-derive.md +0 -261
- package/config/skills/devlyn-resolve/references/phases/surface-close.md +0 -34
- package/config/skills/devlyn-resolve/references/phases/verify.md +0 -310
- package/config/skills/devlyn-resolve/references/state-schema.md +0 -152
- package/config/skills/devlyn-resolve/references/task-completion.md +0 -160
- package/config/templates/prompt-templates.md +0 -71
- package/config/templates/template-feature.spec.md +0 -255
- package/config/templates/template-product-spec.md +0 -680
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Outer-owner task completion
|
|
2
|
+
|
|
3
|
+
Completion belongs to the outer task owner after source acceptance; it does not
|
|
4
|
+
change product verdicts or worker isolation. Direct work edits the current
|
|
5
|
+
checkout, then delivers each completed, verified request with attributable
|
|
6
|
+
changes. Finish the whole request, including steering received before acceptance;
|
|
7
|
+
internal subtasks, messages and conversation end are not delivery boundaries.
|
|
8
|
+
Honor explicit batching or delivery holds; otherwise deliver completed requests
|
|
9
|
+
without waiting for later requests.
|
|
10
|
+
|
|
11
|
+
Without a delivery instruction, use project policy below, default `auto`. A bare
|
|
12
|
+
commit request uses `--local-only`, a PR request `--mode pr`, and a merge request
|
|
13
|
+
`--mode auto`. Local-only/no-push restrictions prevent publication; no-commit or
|
|
14
|
+
just-edit instructions skip delivery. Existing session-wide restrictions remain
|
|
15
|
+
in force until changed. Read-only work, unchanged work and incidental generated
|
|
16
|
+
files do not trigger delivery. An ideate drain delivers every task.
|
|
17
|
+
|
|
18
|
+
## Concurrent writers
|
|
19
|
+
|
|
20
|
+
When other sessions or agents are known to write this checkout (the user says
|
|
21
|
+
so, or you see them), allocate a worktree below before editing. Changes present
|
|
22
|
+
at the start are the user's work in progress: preserve them, and continue unless
|
|
23
|
+
their ownership or the task's dependence on them is unclear. Re-read a file
|
|
24
|
+
before overwriting it, and check `git status` and the diff at verification and
|
|
25
|
+
commit points. On changes you cannot explain, stop writing to the shared
|
|
26
|
+
checkout and ask whether to continue there or isolate. With no one to ask, move
|
|
27
|
+
only your own edits, and only when the task's context can be rebuilt in the
|
|
28
|
+
worktree; otherwise leave the checkout as it is and report the task blocked.
|
|
29
|
+
Isolation changes the work location, not delivery scope. Allocate for the
|
|
30
|
+
resolved delivery policy and reuse that worktree when suitable. Isolation
|
|
31
|
+
without delivery uses `--local-base`. A local receipt remains local; later
|
|
32
|
+
publication requires a fresh publication allocation, candidate and acceptance.
|
|
33
|
+
|
|
34
|
+
## Allocate for delivery or isolation
|
|
35
|
+
|
|
36
|
+
Use the caller's DEVLYN_SHARED_DIR. When this reference is opened
|
|
37
|
+
directly, bind it to this reference's reader-supplied containing
|
|
38
|
+
directory, resolving directory symlinks first. Missing source identity is
|
|
39
|
+
BLOCKED:skill-source-unresolved; a missing task-complete.py is
|
|
40
|
+
BLOCKED:shared-dir-unresolved. Never select another installation.
|
|
41
|
+
|
|
42
|
+
For direct delivery, run the bound task-complete.py after completing the request's
|
|
43
|
+
edits and checks, before committing the delivery candidate. Allocate before
|
|
44
|
+
editing when concurrency requires isolation; if isolation is unavailable, do
|
|
45
|
+
not write to the shared checkout. Queue drains retain their allocation order.
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
python3 "$DEVLYN_SHARED_DIR/task-complete.py" allocate --repo . \
|
|
49
|
+
--task '<task identity>' --branch '<absent task branch>' \
|
|
50
|
+
--worktree '<absent path>' --repository '<owner/repo>' --remote origin --base main
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Every delivery allocation owns a linked worktree; `--worktree` is required.
|
|
54
|
+
A publication allocation normally starts at the exact fetched remote base,
|
|
55
|
+
independent of the anchor's branch or dirty state, and leaves the anchor's
|
|
56
|
+
HEAD, index and files untouched. For a commit request, local-only work or
|
|
57
|
+
isolation without publication, use `--local-base` with the exact current HEAD
|
|
58
|
+
and omit `--repository`/`--remote`. Nothing is fetched or pushed; complete with
|
|
59
|
+
`--local-only` only when committing is allowed.
|
|
60
|
+
|
|
61
|
+
When delivery is implicit and no GitHub origin is configured, use the existing
|
|
62
|
+
local-only route and report `LOCAL_ONLY`, the commit and why no PR/merge occurred.
|
|
63
|
+
An explicit PR/merge request remains blocked. Authentication, network and
|
|
64
|
+
configuration failures are not grounds for this fallback.
|
|
65
|
+
|
|
66
|
+
After local completion or confirmed PR merge, reconcile the original checkout
|
|
67
|
+
only when its branch and changes remain understood and can be preserved.
|
|
68
|
+
After remote delivery, fetch first. If the branch can fast-forward to the
|
|
69
|
+
delivered result, recheck the copied edits' current ownership and contents,
|
|
70
|
+
then remove them: `git restore --source=HEAD --staged --worktree -- <paths>`
|
|
71
|
+
for tracked paths holding only your edits, and delete copied untracked files.
|
|
72
|
+
Then use `git merge --ff-only <task branch>` for local delivery, or
|
|
73
|
+
`git merge --ff-only <remote>/<base>` on the base branch after remote delivery;
|
|
74
|
+
a drain's `Bring into` command is its own. Once a local delivery is reconciled,
|
|
75
|
+
remove its worktree and task branch (`git worktree remove <worktree>`,
|
|
76
|
+
`git branch -d <task branch>`). Do not switch branches, create a reconciliation
|
|
77
|
+
merge commit or discard WIP to force this step. If reconciliation is unsafe,
|
|
78
|
+
retain and report the edits, delivered result and remaining bring-in action.
|
|
79
|
+
|
|
80
|
+
Save the returned receipt path under the common Gitdir. `reconciled` reports earlier accepted,
|
|
81
|
+
PR-delivered tasks whose merged resources were cleaned or retained; it is
|
|
82
|
+
informational, so never resume or release a receipt you do not own. Existing
|
|
83
|
+
branches/trees cannot be adopted, even when their names look generated. Nor
|
|
84
|
+
can a receipt that never reached `allocation: owned`: remove its worktree and
|
|
85
|
+
branch if present, delete its receipt directory, then allocate again.
|
|
86
|
+
Unreceipted tasks remain owner-managed.
|
|
87
|
+
|
|
88
|
+
Copy attributable task edits into the allocated worktree as a patch, never a
|
|
89
|
+
stash. Establish attribution from the pre-edit contents and starting Git state,
|
|
90
|
+
including staged, unstaged and untracked work. A path-scoped
|
|
91
|
+
`git diff --binary HEAD` (after `git add -N` for new files), applied with
|
|
92
|
+
`git -C <worktree> apply --3way`, is suitable only when every included change
|
|
93
|
+
belongs to this task and its prerequisites exist in the candidate baseline. Otherwise construct the task-only
|
|
94
|
+
delta; if attribution or independence from unshipped work is unclear, preserve
|
|
95
|
+
the checkout and report delivery blocked.
|
|
96
|
+
|
|
97
|
+
Review the resulting candidate diff and verify that candidate. Reuse prior
|
|
98
|
+
check evidence only when the checked source and relevant execution inputs are
|
|
99
|
+
unchanged; changed bases, conflict resolutions or other relevant differences
|
|
100
|
+
require the affected checks again.
|
|
101
|
+
|
|
102
|
+
Keep the original edits through pending or failed delivery; only reconciliation
|
|
103
|
+
removes them. Preserve all other work and report anything left behind.
|
|
104
|
+
|
|
105
|
+
Allocation also returns a receipt-owned `scratch` directory. Put disposable
|
|
106
|
+
build intermediates there (for example, set
|
|
107
|
+
`CARGO_TARGET_DIR` to `<scratch>/target`). Keep source checkouts, Git data,
|
|
108
|
+
lockfiles, reports and restart evidence outside scratch. Do not create unowned
|
|
109
|
+
temporary build trees or preserve them by copying them into evidence custody.
|
|
110
|
+
Prefer `TemporaryDirectory`/`finally` for short-lived test fixtures.
|
|
111
|
+
|
|
112
|
+
After waiting for task writers, `complete --writers-stopped` empties this
|
|
113
|
+
scratch on delivery returns, including local-only and pending-PR routes. To
|
|
114
|
+
release build caches when parking or after a failed run, use:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
python3 "$DEVLYN_SHARED_DIR/task-complete.py" clean-scratch \
|
|
118
|
+
--receipt '<returned receipt.json>' --writers-stopped
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This empties only the prospectively owned scratch, preserves its directory
|
|
122
|
+
identity for interrupted cleanup and later builds, checks live users and reports
|
|
123
|
+
the logical byte count separately from actual free disk space. It does not depend on a product PASS or rewrite that verdict.
|
|
124
|
+
Unknown historical roots, source/recovery data, shared caches and terminal
|
|
125
|
+
history are never adopted or swept. A refused cleanup does not block source
|
|
126
|
+
delivery; it stays visible in the handoff with its receipt and retry command
|
|
127
|
+
(`CLEANUP_PENDING` after delivered source). No task is described as cleaned
|
|
128
|
+
while owned disposable files remain. On resumption, finish any pending scratch
|
|
129
|
+
cleanup before allocating more temporary storage; the next allocation also
|
|
130
|
+
retries it for completed deliveries with released writers. Rebuild from retained
|
|
131
|
+
inputs when needed; cleanup is not an instruction to restart parked work.
|
|
132
|
+
|
|
133
|
+
## Accept a scoped commit
|
|
134
|
+
|
|
135
|
+
In the allocated worktree, finish the candidate's decisive checks and diff
|
|
136
|
+
review, then stage and commit only accepted task changes. The helper never
|
|
137
|
+
stages product files. Write a
|
|
138
|
+
root acceptance file in the checkout (usually ignored `.devlyn/acceptance.json`):
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{"kind":"direct","task":"<task identity>","source_sha":"<full commit>","checks":[{"command":"<actual check>","evidence":".devlyn/checks.log"}]}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The owner accepts these checks; the helper preserves evidence bytes and does
|
|
145
|
+
not independently prove the assertions. Acceptance binds exact source and
|
|
146
|
+
evidence before publication. Direct `complete` binds acceptance itself; no
|
|
147
|
+
separate `accept` call is needed.
|
|
148
|
+
|
|
149
|
+
Changed accepted source or evidence requires a new accepted task, never implicit
|
|
150
|
+
descendant approval. Resume an existing receipt only for its unchanged candidate.
|
|
151
|
+
After merge, implement follow-ups from the updated base. An additive follow-up
|
|
152
|
+
depending on an open PR waits for that predecessor to merge.
|
|
153
|
+
|
|
154
|
+
If a correction invalidates an open candidate, run `complete --mode pr` against
|
|
155
|
+
its unchanged receipt, with its task tree clean, to cancel owned auto-merge, then
|
|
156
|
+
reobserve the PR. If it
|
|
157
|
+
remains open, close it as superseded and retain its receipt and custody; do not
|
|
158
|
+
resume its delivery. Allocate a replacement from the current remote base,
|
|
159
|
+
include only the still-needed task changes and correction, and verify and
|
|
160
|
+
accept it anew. If the predecessor has merged, make a new follow-up instead.
|
|
161
|
+
|
|
162
|
+
Queue drains follow ideate's loop protocol
|
|
163
|
+
(`../devlyn-ideate/references/loop.md`): its evidence-derived `loop` result is
|
|
164
|
+
bound with `accept` before the queue-only terminal commit is attached with
|
|
165
|
+
`attach`, and dependent local tasks allocate from the accepted predecessor's
|
|
166
|
+
source. Failed results keep custody and a recovery ref but are never published.
|
|
167
|
+
|
|
168
|
+
## Deliver and resume
|
|
169
|
+
|
|
170
|
+
Wait for your children, stop your dev servers and task writers, then leave the
|
|
171
|
+
task tree. Make the FIRST completion call from outside it with the installed
|
|
172
|
+
helper and `--writers-stopped`; this releases the tree for cleanup after merge:
|
|
173
|
+
|
|
174
|
+
```sh
|
|
175
|
+
python3 "$DEVLYN_SHARED_DIR/task-complete.py" complete \
|
|
176
|
+
--receipt '<returned receipt.json>' \
|
|
177
|
+
--acceptance '<task worktree>/.devlyn/acceptance.json' --writers-stopped
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Project policy is `git config --local devlyn.completionMode auto|pr`; absent means
|
|
181
|
+
`auto`. Invalid local values fail before external effects, even with an override.
|
|
182
|
+
Use `complete --mode auto|pr` for one task, or `--local-only`/`--no-push` to honor
|
|
183
|
+
the user's delivery restriction. These per-task choices persist in the receipt; `--local-only` is refused once the task ref is pushed.
|
|
184
|
+
|
|
185
|
+
`pr` pushes the exact accepted task ref and creates/reuses its exact repository,
|
|
186
|
+
head and base PR. While OPEN, it cancels owned auto-merge, reports `PR` with its URL
|
|
187
|
+
and retains the checkout. Once MERGED by any method, either mode cleans released
|
|
188
|
+
resources in that call, on resume or at the next allocation. Default `auto` also requests
|
|
189
|
+
`gh pr merge --auto --merge --match-head-commit <accepted SHA>`. Repository
|
|
190
|
+
checks/reviews and merge policy remain authoritative: no admin bypass, strategy
|
|
191
|
+
fallback or repository setting changes. When the repository disallows merge
|
|
192
|
+
commits or refuses the request, delivery reports `PR` with `merge_refused` and
|
|
193
|
+
the PR waits for a person. Command success alone never proves merge.
|
|
194
|
+
|
|
195
|
+
`PENDING` retains the workspace and reports a receipt-based resume command.
|
|
196
|
+
`BLOCKED` names the cause and retry action; repair that condition before retrying.
|
|
197
|
+
Resume reobserves Git/PR state under a per-receipt lock, reuses the original
|
|
198
|
+
acceptance and performs only missing eligible effects.
|
|
199
|
+
|
|
200
|
+
Verification and delivery obey the session's actual permissions. When an
|
|
201
|
+
operation needs unavailable approval, finish permitted work, preserve the edits
|
|
202
|
+
and evidence, and report that operation and its retry action. Before allocation,
|
|
203
|
+
identify the original checkout and outstanding operation; after allocation,
|
|
204
|
+
include the receipt-based resume command. Headless execution neither waives
|
|
205
|
+
permissions nor silently changes delivery policy.
|
|
206
|
+
|
|
207
|
+
Report verification, delivery and checkout reconciliation separately. A delivery
|
|
208
|
+
error does not rewrite an accepted product result; unperformed verification
|
|
209
|
+
must never be reported as accepted.
|
|
210
|
+
|
|
211
|
+
## Yield and retain recoverability
|
|
212
|
+
|
|
213
|
+
Cleanup requires actual matching MERGED evidence; linked-tree removal also
|
|
214
|
+
requires the owner's recorded release. OS observation supplements it; neither the receipt
|
|
215
|
+
nor a scan guarantees exclusion of future writers. Processes with cwd or open
|
|
216
|
+
files inside the tree, inaccessible process state (on Linux, other users'
|
|
217
|
+
processes unless run as root), caller cwd inside the tree, dirty/untracked files,
|
|
218
|
+
a nested repository or worktree, or changed refs/Gitdir/registration retain
|
|
219
|
+
affected resources. Use `git worktree lock` to keep a tree.
|
|
220
|
+
On native Windows, locking and file durability are supported, but the helper cannot prove writer cessation and reports `writer observation unsupported on this platform; retain workspace`. Even `--writers-stopped` cannot authorize deletion without that observation: retain the workspace, its task refs and external receipt/custody, report delivery separately, and preserve the receipt-based resume command. A merged delivery therefore reports `CLEANUP_PENDING` (delivery `COMPLETE`) with `workspace_cleanup` naming the reason and resume. Do not kill unknown processes or force worktree removal to make completion pass.
|
|
221
|
+
|
|
222
|
+
The receipt directory holds byte-verified `custody/`, `manifest.json` and a guarded
|
|
223
|
+
`refs/devlyn/completed/<id>` recovery ref. Check evidence is copied there
|
|
224
|
+
before publication; removal rechecks it, the recovery ref and the merge commit on base.
|
|
225
|
+
Ignored build output and other ignored files are disposable under native
|
|
226
|
+
non-force worktree removal. The tree's `.devlyn/` files are byte/mode-verified
|
|
227
|
+
and preserved as `<receipt dir>/records/.devlyn`; non-regular files or symlinks
|
|
228
|
+
there retain the tree. Partial/corrupt custody or records retain it for repair.
|
|
229
|
+
|
|
230
|
+
Legacy in-place receipts retire refs only once their task branch is no longer
|
|
231
|
+
checked out; their checkout is never modified. Local ref deletion is guarded by
|
|
232
|
+
the expected SHA; remote deletion uses an exact force-with-lease solely as
|
|
233
|
+
compare-and-delete, never for product publication. A changed remote branch is
|
|
234
|
+
retained. Retry uses the external receipt/evidence after removal. Recovery
|
|
235
|
+
refs/evidence have no automatic expiry.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devlyn-engines
|
|
3
|
-
description: Show and pin engine
|
|
3
|
+
description: Show and pin the engine that executes devlyn implementation work. Reads and writes machine-local .devlyn/engines.json with fail-closed validation. Use when the user asks which engine is configured, wants to force a specific engine for implementation ("수동모드", "engine 고정", "use codex to implement"), or wants to clear the pin back to the default.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
Utility front-end for the
|
|
6
|
+
Utility front-end for the executor contract in `_shared/engine-preflight.md`. It adds no semantics of its own.
|
|
7
7
|
|
|
8
8
|
<args>
|
|
9
9
|
$ARGUMENTS
|
|
@@ -48,18 +48,16 @@ with the failed path. Never search another installation.
|
|
|
48
48
|
Verify DEVLYN_SHARED_DIR/role-config.py and DEVLYN_SHARED_DIR/engine-doctor.sh before their respective commands. In omp, use `printf '%s\n' skill://devlyn-engines`.
|
|
49
49
|
</runtime_paths>
|
|
50
50
|
|
|
51
|
-
## No args — status
|
|
51
|
+
## No args — status
|
|
52
52
|
|
|
53
|
-
1. Run `python3 "$DEVLYN_SHARED_DIR/role-config.py" --workdir "$PWD" --default-engine <
|
|
54
|
-
2. Run `bash "$DEVLYN_SHARED_DIR/engine-doctor.sh"` and show its availability/eligibility table.
|
|
53
|
+
1. Run `python3 "$DEVLYN_SHARED_DIR/role-config.py" --workdir "$PWD" --default-engine <this CLI's engine>` and print the executor's engine, source (`engines.json` pin or `default`) and availability. `inactive` lists keys earlier releases wrote for retired pipeline roles: they select nothing, and `clear` removes them. CLI presence is not authentication.
|
|
54
|
+
2. Run `bash "$DEVLYN_SHARED_DIR/engine-doctor.sh"` and show its availability/eligibility table.
|
|
55
55
|
3. Show the subcommands below. Status never launches a model.
|
|
56
56
|
|
|
57
57
|
## Subcommands
|
|
58
58
|
|
|
59
|
-
- `executor <name>` —
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
- `role <name> clear` — same command with `--value clear` removes only that override.
|
|
63
|
-
- `clear` — invoke the helper with `--set-role clear` to remove legacy and role pins; preserve unrelated keys and delete an empty file.
|
|
59
|
+
- `executor <name>` — run the status command with `--set-executor <name>`. It refuses a name with no `_shared/adapters/<name>.md`, or whose adapter declares `executor: no`, and lists the valid names. An engine whose CLI is not available is still pinned, with a warning: pins are promises, and dispatch stops with `BLOCKED:<name>-unavailable` until it is installed.
|
|
60
|
+
- `clear` — run the status command with `--clear`: it removes the executor pin and the inactive keys, preserves unrelated keys, and deletes an empty file.
|
|
61
|
+
- `pair` and `role` were removed with the retired pipeline roles: say so and change nothing.
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
Pass the engine name as one structured argument, never by shell interpolation of user text. After every change, re-print the status. Never modify anything outside `.devlyn/engines.json`.
|
|
@@ -1,33 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devlyn-ideate
|
|
3
|
-
description:
|
|
3
|
+
description: Loop designer and intent queue. Turns an intent or a document into a validated loop package (a meta-prompt plus self-contained task contracts), queues its tasks, reports queue status, and drains the queue serially with evidence-derived acceptance, recovery and delivery. Operations — plan, add, status, drain; a bare intent is planned and, when the request authorizes implementation, continues through add and drain; no arguments shows status. Use when the user wants an idea, goal or document planned into tasks, wants to stack work ("queue this", "큐에 넣어줘"), asks what is queued, or wants unattended execution ("drain the queue", "큐 드레인 시작", "밤새 돌려줘").
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Ideate owns planning and durable serial execution. Each task runs under the installed methodology, the CLAUDE.md/AGENTS.md instruction block; ideate adds no phase graph, reviewer quota, engine router or restart cycle.
|
|
7
7
|
|
|
8
|
-
<
|
|
8
|
+
<ideate_args>
|
|
9
9
|
$ARGUMENTS
|
|
10
|
-
</
|
|
11
|
-
|
|
12
|
-
<orchestrator_context>
|
|
13
|
-
This skill is OPTIONAL. `/devlyn-resolve` is standalone-capable: free-form mode handles trivial/medium tasks without a spec, `--spec` mode accepts handwritten specs from any source. Use ideate when the user wants AI to do the elicitation work.
|
|
14
|
-
</orchestrator_context>
|
|
15
|
-
|
|
16
|
-
<elicitation_contract>
|
|
17
|
-
The user does not know context engineering. They will under-specify and over-assume. AI's job is to ask focused, specific questions that surface the missing engineering decisions.
|
|
18
|
-
|
|
19
|
-
1. Ask one or two questions per turn, not more. Multi-question lists overwhelm and produce shallow answers.
|
|
20
|
-
2. Questions are concrete and decision-grade — what is the input, what is the expected output, what command verifies success, what files are out of scope.
|
|
21
|
-
3. Do not ask design preferences the user clearly does not have. Infer the simplest reasonable default and confirm in one line.
|
|
22
|
-
4. Stop when the spec passes structural lint AND the user explicitly confirms or 8 turns have elapsed (whichever comes first). Eight turns is a hard ceiling — beyond that, the spec is either ready or the task is too large for ideate.
|
|
23
|
-
5. The output is the spec, not a transcript. Do not include the conversation in the saved files.
|
|
24
|
-
</elicitation_contract>
|
|
10
|
+
</ideate_args>
|
|
25
11
|
|
|
26
12
|
<harness_principles>
|
|
27
|
-
|
|
13
|
+
`_shared/runtime-principles.md`, mirrored in the installed instruction block (read the file only when no block is loaded), binds package content as well as the conversation: a requirement "for future flexibility" violates Subtractive-first, and acceptance that permits a silent fallback violates No-workaround. Flag these while planning, not after execution.
|
|
28
14
|
</harness_principles>
|
|
29
15
|
|
|
30
16
|
<runtime_paths>
|
|
17
|
+
Before any operation, establish the bindings below.
|
|
18
|
+
|
|
31
19
|
Resolve bundled resources from the SKILL.md loaded for this invocation.
|
|
32
20
|
|
|
33
21
|
Reader-rendered directory hint:
|
|
@@ -61,116 +49,78 @@ written as _shared/... use this binding. Verify the directory and each
|
|
|
61
49
|
required resource before use; failure is BLOCKED:shared-dir-unresolved
|
|
62
50
|
with the failed path. Never search another installation.
|
|
63
51
|
|
|
64
|
-
Verify
|
|
52
|
+
Verify DEVLYN_SKILL_DIR/scripts/queue.py before running it. In omp, use `printf '%s\n' skill://devlyn-ideate`.
|
|
65
53
|
</runtime_paths>
|
|
66
54
|
|
|
67
|
-
|
|
68
|
-
Default engine: Claude. The per-engine adapter from `_shared/adapters/<engine>.md` is prepended to the elicitation prompt so the model honors its own official prompt-engineering guidance during the Q&A.
|
|
69
|
-
</engine_routing>
|
|
70
|
-
|
|
71
|
-
<modes>
|
|
72
|
-
Four modes, selected by flag:
|
|
73
|
-
|
|
74
|
-
1. **Default** (no flag) — single-spec elicitation. AI asks questions in-conversation until lint passes. Output: `<spec-dir>/<id>-<slug>/spec.md` + `<spec-dir>/<id>-<slug>/spec.expected.json`. Default spec dir: `docs/specs/` (configurable via `--spec-dir <path>`).
|
|
75
|
-
2. **`--quick`** — one-line goal, AI synthesizes a spec with explicit assumptions block, asks the user to confirm or correct in a single turn. Use when the user wants speed over thoroughness.
|
|
76
|
-
3. **`--from-spec <path>`** — external spec exists. AI lints it for the canonical structure, normalizes section names, generates a missing `spec.expected.json` if absent, fixes minor schema issues, and stops. Does NOT reshape Requirements / Out-of-Scope content; structural changes only.
|
|
77
|
-
4. **`--project`** — multi-feature project. AI elicits a project description, decomposes it into 3-7 feature specs, writes `<spec-dir>/plan.md` (the index) and one `<spec-dir>/<id>/spec.md` + `<spec-dir>/<id>/spec.expected.json` per feature. See `references/project-mode.md`.
|
|
55
|
+
## Operations
|
|
78
56
|
|
|
79
|
-
|
|
80
|
-
|
|
57
|
+
| Invocation | Behavior |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `plan <intent or absolute document path>` | Inspect, elicit what is necessary and write a validated loop package. Does not enqueue or execute. |
|
|
60
|
+
| `add <intent or absolute package path>` | Plan when necessary, then capture the package and queue its tasks in dependency order. Does not execute. |
|
|
61
|
+
| `status` | Reconciled pending, active, accepted and failed counts; the next runnable task; delivery and recovery blockers. |
|
|
62
|
+
| `drain` | Resume or drain the queue serially under existing execution authorization. |
|
|
63
|
+
| Bare intent | Plan; when the request authorizes implementation, continue through add and drain without reconfirmation. |
|
|
64
|
+
| No arguments | Status. |
|
|
81
65
|
|
|
82
|
-
|
|
83
|
-
The spec carries `spec.kind ∈ {feature, spike, prototype}` in its frontmatter. The kind changes downstream behavior:
|
|
66
|
+
Two controls only: `--autonomous` applies the autonomous policy to plan or add (drain always applies it), and `--local-only` keeps a drain's delivery local (`--no-push` is equivalent). A delivery restriction already established for a loop persists. Engine selection and pins stay project and host settings (`/devlyn-engines`).
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
- **spike** — exploratory work; deliverable is learning, evidence, or a disposable demo. `/devlyn-resolve --spec` proceeds but VERIFY's quality bar is relaxed for code that the spike says is throwaway.
|
|
87
|
-
- **prototype** — between feature and spike. Production-shape but not production-grade. CLEANUP runs; VERIFY's quality bar is stricter than spike, looser than feature.
|
|
68
|
+
A removed flag stops with its instruction and selects no other behavior.
|
|
88
69
|
|
|
89
|
-
|
|
90
|
-
|
|
70
|
+
| Flag | Instruction |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `--quick` | Removed: use `plan <intent>`, adding `--autonomous` to plan without questions. |
|
|
73
|
+
| `--from-spec <path>` | Removed: use `plan <absolute path>`; the document stays unchanged as the input contract. |
|
|
74
|
+
| `--project` | Removed: every plan is a loop package with as many tasks as the intent needs. |
|
|
75
|
+
| `--spec-dir`, `--spec-id`, `--in-place` | Removed: packages live at `docs/specs/<loop-id>/` with generated IDs, and input documents are never rewritten. |
|
|
76
|
+
| `--engine` | Removed: drain uses the configured executor; pin it with `/devlyn-engines executor <name>`. |
|
|
91
77
|
|
|
92
|
-
##
|
|
78
|
+
## Question policy
|
|
93
79
|
|
|
94
|
-
|
|
95
|
-
- `--quick`
|
|
96
|
-
- `--from-spec <path>`
|
|
97
|
-
- `--project`
|
|
98
|
-
- `--spec-dir <path>` (default `docs/specs/`)
|
|
99
|
-
- `--engine MODE` (default `claude`)
|
|
100
|
-
- `--spec-id <id>` — optional explicit id; auto-generated when absent.
|
|
80
|
+
> Inspect available project facts before asking. Ask only when the unresolved answer changes authorized behavior, scope, data semantics, acceptance or delivery. State the recommended answer and its consequence. Ask the smallest useful question. Stop eliciting when the contract is executable and verifiable; no turn target or mandatory confirmation applies. Existing authorization remains effective.
|
|
101
81
|
|
|
102
|
-
|
|
82
|
+
## Autonomous policy
|
|
103
83
|
|
|
104
|
-
|
|
105
|
-
- default → PHASE 1.
|
|
106
|
-
- `--quick` → PHASE 1Q (single turn assume-and-confirm).
|
|
107
|
-
- `--from-spec` → PHASE 1F (lint + normalize external).
|
|
108
|
-
- `--project` → PHASE 1P (project decomposition).
|
|
84
|
+
> For ordinary details the intent leaves open within authorized scope, follow established project conventions, otherwise the narrowest literal or conventional reading consistent with the request; these defaults may be user-visible but must be low-consequence and reversible. Record each choice and reason once. Material ambiguity means competing readings with materially different intended outcomes, unresolved persistent data or state semantics, or public surface beyond the request; stop affected work as needs-review with a concrete question. Independent authorized work may continue. Never omit requested work or weaken acceptance to obtain completion.
|
|
109
85
|
|
|
110
|
-
##
|
|
86
|
+
## plan
|
|
111
87
|
|
|
112
|
-
|
|
88
|
+
1. Inspect, then elicit, per [elicitation.md](references/elicitation.md). A document argument is the input contract: carry each substantive requirement into a task without weakening it, cite the document in `## Intent`, and never modify it.
|
|
89
|
+
2. Write `docs/specs/<loop-id>/meta.md` and each task's `spec.md` and `spec.expected.json` per [package-format.md](references/package-format.md). In the manifest, `base_ref` is the delivery branch and `base_sha` the exact commit the loop builds on; `delivery` is `local-only` when the user restricted delivery or, recorded as an assumption, when `origin` does not name one GitHub repository; `pr` when the user asked to stop at the PR; `auto` when the user asked to merge, even under a `pr` project policy; else the project's `git config --local devlyn.completionMode` (absent means `auto`). An explicit PR or merge request whose `origin` does not name one GitHub repository stops planning with that question. `## Execution policy` quotes the autonomous policy, which binds every task's executor.
|
|
90
|
+
3. Run `python3 "$DEVLYN_SKILL_DIR/scripts/queue.py" check '<absolute meta.md>'` and repair the package until it reports `VALID`.
|
|
91
|
+
4. Report the package path, the tasks with their dependencies, and every recorded assumption.
|
|
113
92
|
|
|
114
|
-
|
|
115
|
-
1. Reads the user's initial goal from `<elicit_config>`.
|
|
116
|
-
2. Identifies the missing engineering decisions (input shape, output shape, success command, scope boundary, constraints).
|
|
117
|
-
3. Asks 1-2 focused questions per turn until each blank is filled or the user accepts an inferred default.
|
|
118
|
-
4. Maintains a running draft spec in `.devlyn/ideate-draft.md` (run-scoped, gitignored).
|
|
119
|
-
5. Stops when the structural lint passes AND user confirms, or 8 turns elapsed.
|
|
93
|
+
## add
|
|
120
94
|
|
|
121
|
-
|
|
122
|
-
- Frontmatter has `id`, `title`, `kind`, `status: planned`, `complexity`.
|
|
123
|
-
- `## Context` non-empty (≥ 1 sentence).
|
|
124
|
-
- `## Requirements` has ≥ 1 `- [ ]` bullet.
|
|
125
|
-
- `## Out of Scope` present (may list "none" if truly nothing).
|
|
126
|
-
- `## Verification` is preceded by a `<!-- devlyn:verification -->` sentinel and has either ≥ 1 named command OR sibling `spec.expected.json` declares `"pure_design": true`.
|
|
95
|
+
An absolute path to a package's `meta.md` is added as it is; anything else is planned first. Add with `python3 "$DEVLYN_SKILL_DIR/scripts/queue.py" add '<absolute meta.md>'`, the only writer of a loop's queue file `docs/specs/<loop-id>/queue.md`; never edit one by hand. In every delivery mode add makes no commit on the checked-out branch and leaves the branch, the index and tracked files as they are: it holds the package and its rows at `refs/devlyn/captures/<loop-id>`, records the add and removes the package copies equal to that capture. Report the capture ref and its `git show` command, any `cleanup` entry, and that a revision needs a new loop id. It refuses package changes staged in the index (unstage them and add again), and a retry of the same add reports it as added, also once the copies are gone. Tasks start from committed state, a local loop from the branch it was added on and `auto`/`pr` from the remote base, so commit, and for `auto`/`pr` push, whatever the plan depends on. A pending legacy raw-intent row of `docs/specs/queue.md` is replaced in place by a package whose `## Intent` reproduces the row verbatim, added with `--materialize <line>`.
|
|
127
96
|
|
|
128
|
-
|
|
129
|
-
1. Write `<spec-dir>/<id>-<slug>/spec.md` (the spec).
|
|
130
|
-
2. Generate `<spec-dir>/<id>-<slug>/spec.expected.json` following `references/spec-template.md` § "Sibling file: `spec.expected.json`" for constraint coverage, diff scope and guard controls.
|
|
131
|
-
3. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check <spec-path>` to validate the actual spec's carrier shape and supported `complexity` frontmatter. Sibling `spec.expected.json` takes precedence over the legacy inline `## Verification` JSON carrier. If exit 2, fix the file named in the error and re-run.
|
|
132
|
-
4. Run `python3 "$DEVLYN_SHARED_DIR/spec-verify-check.py" --check-expected <expected-path>` to validate sibling `spec.expected.json` against `_shared/expected.schema.json` plus sibling spec `complexity` frontmatter. If exit 2, fix the JSON/frontmatter and re-run.
|
|
133
|
-
5. Print: `spec ready — /devlyn-resolve --spec <spec-path>`.
|
|
97
|
+
## status
|
|
134
98
|
|
|
135
|
-
|
|
99
|
+
Run `python3 "$DEVLYN_SKILL_DIR/scripts/queue.py" status --repo .` and report its counts, `next`, `blockers`, pending deliveries with their resume commands and any `cleanup` entry.
|
|
136
100
|
|
|
137
|
-
|
|
101
|
+
## drain
|
|
138
102
|
|
|
139
|
-
|
|
140
|
-
2. AI surfaces an explicit "Assumptions made" section listing every inferred decision.
|
|
141
|
-
3. User responds with "go" / "fix X" / "no, different".
|
|
142
|
-
4. On "go": write spec + spec.expected.json + lint + announce.
|
|
143
|
-
5. On "fix X": apply correction, re-show, ask again. Maximum 3 correction rounds before escalating to default mode.
|
|
103
|
+
Follow [loop.md](references/loop.md). The executor is the configured route, the `.devlyn/engines.json` `executor` pin or else this CLI, checked per `_shared/engine-preflight.md`. Pass its argv after `--`. `<git dir>` is the output of `git rev-parse --path-format=absolute --git-common-dir`, where the executor commits and writes its submission; the drain fills `{worktree_git_dir}` with the task worktree's own Git directory, which Codex's sandbox keeps read-only unless that exact directory is listed:
|
|
144
104
|
|
|
145
|
-
|
|
105
|
+
| Executor | argv |
|
|
106
|
+
|---|---|
|
|
107
|
+
| Claude | `claude -p "<prompt>" --dangerously-skip-permissions --add-dir "<git dir>"` |
|
|
108
|
+
| Codex | `bash "<DEVLYN_SHARED_DIR>/codex-monitored.sh" --skip-git-repo-check -s workspace-write -c 'sandbox_workspace_write.writable_roots=["<git dir>","{worktree_git_dir}"]' -c 'sandbox_workspace_write.network_access=true' "<prompt>"` |
|
|
146
109
|
|
|
147
|
-
|
|
110
|
+
Another engine needs an argv that starts one fresh non-interactive session able, without prompts, to edit, run commands and commit in its task worktree and to write the packet's submission file. `<prompt>` carries the absolute binding values, while `{packet}` stays literal for the drain to fill:
|
|
148
111
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
4. Apply structural fixes only — do NOT reshape Requirements / Out-of-Scope content. The user's substantive intent is preserved.
|
|
153
|
-
5. Generate `spec.expected.json` if absent, following the same template carrier guidance as default mode.
|
|
154
|
-
6. Write the normalized spec back to `<spec-dir>/<id>-<slug>/` (preserves original at `<path>` untouched unless user passes `--in-place`).
|
|
155
|
-
7. Run both lint checks: `--check <spec-path>` and `--check-expected <expected-path>`.
|
|
156
|
-
8. Lint pass → announce. Lint fail → surface the unfixable issue and exit non-zero.
|
|
157
|
-
|
|
158
|
-
## PHASE 1P: PROJECT MODE
|
|
159
|
-
|
|
160
|
-
Prompt body: `references/project-mode.md`.
|
|
161
|
-
|
|
162
|
-
1. AI elicits a project description (longer Q&A — multi-feature scope warrants more turns).
|
|
163
|
-
2. AI decomposes the project into 3-7 feature specs. Each feature is independently shippable; cross-feature dependencies surface explicitly in the spec frontmatter `depends_on:` field.
|
|
164
|
-
3. AI writes `<spec-dir>/plan.md` — index file with: project name, decomposition rationale, list of feature specs with id + title + dependency, suggested implementation order.
|
|
165
|
-
4. AI writes one `<spec-dir>/<id>/spec.md` + `<spec-dir>/<id>/spec.expected.json` per feature, each lint-validated.
|
|
166
|
-
5. Announce: `project ready — N specs at <spec-dir>/. Start with /devlyn-resolve --spec <first-spec-path>`.
|
|
112
|
+
```text
|
|
113
|
+
Execute the devlyn loop task packet {packet}: work only in its owned worktree under the installed instructions; meet its obligations, then write its submission and any review records as "Executor exchange" and "Review records" in <DEVLYN_SKILL_DIR>/references/loop.md specify. Set DEVLYN_SKILL_DIR=<DEVLYN_SKILL_DIR> and DEVLYN_SHARED_DIR=<DEVLYN_SHARED_DIR> from these literal values, never from your inherited environment. Never push, open a pull request or merge: the drain delivers.
|
|
114
|
+
```
|
|
167
115
|
|
|
168
|
-
|
|
116
|
+
```sh
|
|
117
|
+
python3 "$DEVLYN_SKILL_DIR/scripts/queue.py" drain --repo . [--local-only] -- <executor argv>
|
|
118
|
+
```
|
|
169
119
|
|
|
170
|
-
|
|
120
|
+
A drain can run for hours. Do not end the turn until it exits: run it in the foreground with the longest allowed timeout, or in the background and await its completion notice, because a headless host kills background tasks at its final response.
|
|
171
121
|
|
|
172
|
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
122
|
+
- `WAITING` on legacy rows: plan and materialize each under the autonomous policy, then drain again; a row whose planning stops on material ambiguity stays pending and its question is reported.
|
|
123
|
+
- `WAITING` on anything else, or `BLOCKED`: report the reason and resume commands; never edit receipts, refs or queue rows to get past them.
|
|
124
|
+
- An interrupted drain is resumed by running `drain` again; accepted work is never replayed, and a failed task is never rerun: plan its work again as a new loop.
|
|
175
125
|
|
|
176
|
-
|
|
126
|
+
Report each task's product result, delivery status, PR URL, resume command, assumptions and unresolved questions, plus whole-loop acceptance, the package's `## Decisions and assumptions`, the drain report paths and its exact `Bring into` command; leave running it to the user. Report any `cleanup` entry too: a package copy left in the checkout stops that command until it is removed.
|