dorfl 0.14.0 → 0.14.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.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: one-shot
3
3
  disable-model-invocation: true
4
- description: 'One-shot a whole project or goal, WITH structure: take one sentence of intent all the way to landed, gated code on the work/ contract (specs, tasks, builds, reviews, ADRs), delegating every rung to a fresh subagent and running to exhaustion without a human in the loop. Same contract as dorfl, no runner CLI required.'
4
+ description: "One-shot a whole project or goal, WITH structure: take one sentence of intent all the way to landed, gated code on the work/ contract (specs, tasks, builds, reviews, ADRs), delegating every rung to a fresh subagent and running to exhaustion without a human in the loop. Same contract as dorfl; no runner CLI, no remote, no PRs; it commits locally and never pushes, so the human's push is the last gate."
5
5
  ---
6
6
 
7
7
  # one-shot
@@ -22,7 +22,10 @@ It is a **methodology skill** (prose you follow). Its execution substrate is the
22
22
  The human's invocation IS the mandate. Absent an explicit narrower instruction, it grants you, for the duration of this goal:
23
23
 
24
24
  - **Authority to DECIDE** anything reversible and internal: the stack within the stated constraints, the module boundaries, naming, the test seams, the spec decomposition, the task cuts, the defaults a task left unspecified.
25
- - **Authority to COMMIT** the protocol's own transitions and the work the subagents produce: task and spec files, `work/` folder moves, builder branches, landing commits. Never `--force`, never sweeping unrelated changes in, never a push to a remote the human has not named.
25
+ - **Authority to COMMIT, and ONLY to commit.** The protocol's own transitions and the work the subagents produce: task and spec files, `work/` folder moves, builder branches, landing commits. Never `--force`, never sweeping unrelated changes in, and **never a push**. Everything this run produces stays local, on this machine, in this repo's history. There is no PR, no `gh`, no remote and no propose mode anywhere in this skill.
26
+
27
+ **The human's `git push` is the last gate, and that is a feature, not a limitation.** Publishing is an external consequence (stop bar 1): the moment work leaves this machine, other people, CI, and deployment can see it, and that is exactly the class of thing an unattended agent must not do on its own. Keeping the whole run local means the worst case of a bad night is `git reset`, never a broadcast. It also removes an entire category of failure the other conductors have to handle: no remote to race, no moved `main` under you, no rejected push, no PR to reconcile. So do not ask for push permission and do not treat its absence as an obstacle: commit cleanly, report clearly, and leave publication to the human who reads the report.
28
+
26
29
  - **Authority to ANSWER** an item's own open questions. When a tasker flags `needsAnswers: true` and the question is inside the mandate, you are the answerer: decide it, write the answer into the item body, clear the flag, and record it (below). A one-shot that stalls on every `needsAnswers` is not autonomous, and a contract flag that only a human may ever clear would make the flag a deadlock rather than a gate.
27
30
 
28
31
  **The working rule is DECIDE, RECORD, CONTINUE.** Asking is not the safe default here, it is a failure to deliver; but deciding silently is worse than either, because it is unreviewable. So every judgement you make gets written down somewhere the human will find it (see the decision journal), and then you keep moving.
@@ -31,7 +34,7 @@ The human's invocation IS the mandate. Absent an explicit narrower instruction,
31
34
 
32
35
  **STOP only for these** (everything else you decide):
33
36
 
34
- 1. **External consequence**: spending money, publishing or deploying, sending anything to a third party, touching credentials or secrets, anything a stranger would experience.
37
+ 1. **External consequence**: pushing to a remote, spending money, publishing or deploying, sending anything to a third party, touching credentials or secrets, anything a stranger would experience. (Pushing is not a judgement call you get to make well; it is simply not yours.)
35
38
  2. **Destructive reach outside the goal**: deleting or force-pushing anything you did not create, touching another repo, mutating the human's other work.
36
39
  3. **A fork the goal statement genuinely does not settle** and that determines the project's identity (is this a CLI or a web app, does it store user data at all). Not "which of two libraries", which you decide.
37
40
  4. **Repeated failure**: the gate will not go green after the repair budget (below), or the same review finding survives two rebuilds. Three identical failures means the TASK is wrong, not the code, and grinding further burns tokens producing convincing garbage.
@@ -59,18 +62,20 @@ The human's invocation IS the mandate. Absent an explicit narrower instruction,
59
62
  Say all of this in one message, then start. Do not open a dialogue.
60
63
 
61
64
  1. **State the goal back** in one paragraph with an explicit **done-when**, plus the 3 to 6 **decisions you are taking on the human's behalf** (stack, shape, scope boundary) and the **scope you are NOT doing**. This is the human's single chance to correct you cheaply, so make it concrete and short. If they are already gone, proceed on it.
62
- 2. **Derive, do not ask:** the `verify` gate from `dorfl.json` if present, else from the repo's own tooling, else (greenfield) the one you are about to create. The integration mode: local commits on `main` for a fresh project, branch plus PR only if the repo already works that way. The licensing and convention defaults from the operator's environment.
63
- 3. **Check the preconditions** and say the result in one line: the working tree is CLEAN (if not, stop, that is the one hard precondition); a subagent roster is available (check it, use only executable agents); and you are the ONLY claimer (`git ls-remote origin 'refs/dorfl/lock/*'` empty, no `dorfl run` daemon or CI `advance` leg on this arbiter). This skill does not take lock refs, because with a single conductor there is nothing to arbitrate against, so that assumption must be checked rather than assumed.
65
+ 2. **Derive, do not ask:** the `verify` gate from `dorfl.json` if present, else from the repo's own tooling, else (greenfield) the one you are about to create. The licensing and convention defaults from the operator's environment. There is no integration mode to choose: you commit locally on `main` and the human pushes, or does not.
66
+ 3. **Check the preconditions** and say the result in one line: the working tree is CLEAN (if not, stop, that is the one hard precondition); a subagent roster is available (check it, use only executable agents); the protocol docs are reachable (`work/protocol/` in this repo, else the `setup` skill's own `protocol/` folder, which is where a greenfield bootstrap copies them from, so `one-shot` installed WITHOUT `setup` beside it cannot bootstrap); and nothing else is claiming work in this repo (no `dorfl run` daemon on this checkout, no lock refs in `git for-each-ref refs/dorfl/lock`). This skill takes no lock refs, because a single local conductor has nothing to arbitrate against, so that assumption is checked rather than assumed.
64
67
 
65
- ## Phase 0: bootstrap (only when the project does not exist yet)
68
+ ## Phase 0: bootstrap (whenever the CONTRACT or the GATE is missing, not just on an empty folder)
66
69
 
67
- A one-shot project run starts before the contract exists. Do this yourself, it is scaffolding, not implementation:
70
+ **The trigger is `work/protocol/` absent OR `verify` not real, regardless of how much code already exists.** What Phase 0 establishes is the contract plus a working quality floor, and both are independent of whether the project exists: a five-year-old repo can be missing both, and a fresh template scaffold can already have the gate. Keying this on "the project does not exist yet" would drop an existing-but-unadopted repo into the loop with no protocol docs to read. Run the steps that are not already true, skip the ones that are; this is scaffolding, not implementation, so you do it yourself.
68
71
 
69
- 1. **Create the repo and commit immediately.** `git init`, the operator's default license, a README holding the goal paragraph, `.gitignore`. Commit before anything else so every later rung is a reviewable diff rather than an undifferentiated dump.
72
+ 1. **Create the repo and commit immediately** (greenfield only). `git init`, the operator's default license, a README holding the goal paragraph, `.gitignore`. Commit before anything else so every later rung is a reviewable diff rather than an undifferentiated dump.
70
73
  2. **Scaffold from a template if the operator's environment provides one** (a template skill, a starter repo). A house template brings conventions, tooling and a working build for free, and hand-rolling one burns a subagent for a worse result. Otherwise scaffold the minimum by hand.
71
- 3. **Make the gate REAL before the first task.** The whole loop's quality floor is `verify`, so a project whose `verify` is `true` or missing has no floor at all. Get build, test and format wired and GREEN on the empty scaffold, then commit. This is the single highest-leverage thing in a one-shot run: every later gate, review and land depends on it.
72
- 4. **Adopt the contract** (follow the `setup` skill, Phase A): copy the protocol docs from the `setup` skill's own `protocol/` folder into `work/protocol/`, scaffold the `work/` skeleton, write `CONTEXT.md` (derive the glossary from the goal statement, you know the domain nouns) and `dorfl.json` with the gate you just made real. `setup` normally hard-stops for the human to ratify the plan and the gate; your kickoff message WAS that ratification, so do not re-stop.
73
- 5. **Record the bootstrap decisions as ADRs** (`docs/adr/`, per `ADR-FORMAT.md`) for the ones meeting the gate: hard to reverse, surprising without context, a real trade-off. The stack choice, the storage model, the architectural seam. `setup`'s rule that an ADR needs a human's why is about never FABRICATING a rationale for someone else's past decision; here YOU are the decider, so you have a genuine why and writing it down is exactly right.
74
+ 3. **Make the gate REAL before the first task.** The whole loop's quality floor is `verify`, so a project whose `verify` is `true` or missing has no floor at all. Greenfield: wire build, test and format and get them GREEN on the empty scaffold, then commit. Existing repo: DISCOVER the gate from the repo's own tooling (detect, never assume a stack), then RUN it once before dispatching anything. This is the single highest-leverage step in a one-shot run, because every later gate, review and land is measured against it.
75
+ - **A red baseline is a STOP, not a starting point.** If the existing repo's gate is already failing before you have touched anything, do not build on it: you would have no way to tell your own breakage from the pre-existing kind, and every later "the gate is red" signal becomes uninterpretable. Report exactly what is red and stop. Fixing someone else's broken build is its own goal, and it is not the one you were given.
76
+ 4. **Adopt the contract, Phase A ONLY** (follow the `setup` skill): copy the protocol docs from the `setup` skill's own `protocol/` folder into `work/protocol/`, scaffold the `work/` skeleton, write `CONTEXT.md` (derive the glossary from the goal statement and the code you can read) and `dorfl.json` with the gate from step 3. Never clobber what exists: create only what is missing. `setup` normally hard-stops for the human to ratify the plan and the gate; your kickoff message WAS that ratification, so do not re-stop.
77
+ 5. **DECLINE `setup` Phase B, and say so in the report.** Phase B (converting an existing repo's trackers, design docs and code onto the contract) is the one part of adoption that CANNOT be one-shot: its central discipline is that an ADR is written if and only if a human supplies the WHY, and with no human the rule is explicit that you write nothing. An unattended agent that converts anyway produces exactly the fabricated rationale that rule exists to prevent, and a fabricated ADR corrupts the decision record silently, which is worse than an empty one. So adopt the skeleton, leave the legacy material where it is, and recommend in the handover that the human run `setup` interactively to convert it.
78
+ 6. **Record the decisions YOU made as ADRs** (`docs/adr/`, per `ADR-FORMAT.md`), for the ones meeting the gate: hard to reverse, surprising without context, a real trade-off. The stack choice, the storage model, the architectural seam. This does not contradict step 5, and the boundary is WHOSE decision it was: `setup`'s prohibition is on inventing a rationale for someone ELSE's past choice, which you cannot know; here you are the decider, so the why is genuinely yours and writing it down is exactly right. Never write an ADR for a decision you found in the code.
74
79
 
75
80
  ## The goal record: `work/notes/ideas/<goal-slug>.md`
76
81
 
@@ -121,7 +126,7 @@ A ready task is not necessarily a CORRECT task. Tasks are launch snapshots, and
121
126
 
122
127
  Order the buildable tasks into dependency LAYERS. Within a layer, tasks with disjoint file sets run in PARALLEL, each in its own worktree; tasks sharing a hot file or un-landed scaffolding stay serial. Land strictly one at a time regardless, in dependency order, re-verifying each on the moved `main`. Parallel build, serial land. When in doubt, serial: the cost of serial is wall-clock, the cost of a bad parallel wave is a tangled tree you cannot review.
123
128
 
124
- **4a. Isolate.** `git worktree add ~/dev/worktrees/<repo>/work/task-<slug> -b work/task-<slug> origin/main` (the house convention is `~/dev/worktrees/<repo>/<branch>`, never a sibling of the repo). One writer per worktree, always.
129
+ **4a. Isolate.** `git worktree add ~/dev/worktrees/<repo>/work/task-<slug> -b work/task-<slug> main` (branch off LOCAL `main`, there is no remote in play; the house convention is `~/dev/worktrees/<repo>/<branch>`, never a sibling of the repo). One writer per worktree, always.
125
130
 
126
131
  **4b. Dispatch the builder.** A write-capable child (`worker`), `cwd` set to that worktree. **The brief is the `## Prompt` wrapper from `work/protocol/CLAIM-PROTOCOL.md`, VERBATIM with the slug substituted.** Do not paraphrase and do not write your own: that wrapper carries the no-git boundary, the off-path capture rule, the `=== TASK-STOP ===` escape hatch, the `## Decisions` channel and the coherence check, and a paraphrase silently drops one. Add only what the child cannot know: its cwd, the gate command, and the report shape.
127
132
 
@@ -131,7 +136,7 @@ Order the buildable tasks into dependency LAYERS. Within a layer, tasks with dis
131
136
 
132
137
  **4e. Review, then arbitrate.** A read-only **reviewer** child over the diff against the acceptance criteria (`REVIEW-PROTOCOL.md`). Then you decide: clear approve lands, clear block goes to repair, and a coin-flip inside your mandate you DECIDE and record rather than park. Verify explicitly that any forward-note or "do not rename X" constraint the task carried was honoured; that is where builders silently drift.
133
138
 
134
- **4f. Land or park.** LAND is the contract's primitive and is not optional: fetch `main`, rebase the branch onto it, **re-run `verify` on the rebased tree**, then advance. A clean merge is not evidence; only the re-verify on the tree that actually integrates is. Then, in ONE commit, land the work together with `git mv work/tasks/backlog/<slug>.md work/tasks/done/<slug>.md`, message `<type>(<slug>): <summary>; done`, and **transcribe the builder's `## Decisions` block verbatim into that done record** (the builder cannot write it, and that block is the only sanctioned home for build-time rationale). Remove the worktree. PARK instead when the repair budget is spent or the stop bar is hit: write `work/questions/task-<slug>.md` with the reason and exactly what a human must decide, set `needsAnswers: true` on the body, KEEP the branch (it is the recoverable work), and continue with the next independent task. Never force a failed task, never auto-resolve a conflict.
139
+ **4f. Land or park.** LAND is the contract's primitive and is not optional, and it survives intact even with no remote: rebase the branch onto the CURRENT local `main`, **re-run `verify` on the rebased tree**, then advance. `main` still moves under a task, because you are landing its siblings onto it, so the rebase-and-re-verify is doing real work here; what the local-only shape removes is the fetch, the lost-CAS retry and the moved-remote race, not the invariant. A clean merge is not evidence; only the re-verify on the tree that actually integrates is. Then, in ONE commit, land the work together with `git mv work/tasks/backlog/<slug>.md work/tasks/done/<slug>.md`, message `<type>(<slug>): <summary>; done`, and **transcribe the builder's `## Decisions` block verbatim into that done record** (the builder cannot write it, and that block is the only sanctioned home for build-time rationale). Remove the worktree. PARK instead when the repair budget is spent or the stop bar is hit: write `work/questions/task-<slug>.md` with the reason and exactly what a human must decide, set `needsAnswers: true` on the body, KEEP the branch (it is the recoverable work), and continue with the next independent task. Never force a failed task, never auto-resolve a conflict.
135
140
 
136
141
  **4g. Re-orient.** The land may have unblocked a layer. Back to step 0.
137
142
 
@@ -189,6 +194,8 @@ The last thing you produce, and for an unattended run it is the deliverable the
189
194
  - **Parked**: each `work/questions/` sidecar, what it is waiting on, what it unblocks, and your recommended default.
190
195
  - **Declined as out of scope**: the ideas captured as notes.
191
196
  - **Where the quality floor is**: what `verify` actually covers and what it does not, so the human knows what the green tick did and did not prove.
197
+ - **Adoption gaps** (existing repos only): that `setup` Phase B was declined by design, and which legacy material is therefore still unconverted, so the human can run `setup` interactively when they want it.
198
+ - **Nothing has been published**: every commit is local and unpushed, the branches of parked tasks are still there, and `git log` plus `git reset` are the human's undo. Say which commits would go out if they push, and in what order.
192
199
 
193
200
  ## Pitfalls
194
201
 
@@ -204,7 +211,7 @@ The last thing you produce, and for an unattended run it is the deliverable the
204
211
 
205
212
  ## Relationship to the other conductors
206
213
 
207
- - **`drive-tasks`** builds a READY BOARD via the `dorfl` CLI (real claim locks, isolated job worktrees, the runner's gates). If the CLI is present and you only need tasks built, use it.
214
+ - **`drive-tasks`** builds a READY BOARD via the `dorfl` CLI (real claim locks, isolated job worktrees, the runner's gates) and integrates through a remote, with `gh` PRs in propose mode. If the CLI is present and you only need tasks built, use it. If you want the result PUBLISHED rather than merely committed, that is `drive-tasks` plus `merge-prs`, never this skill.
208
215
  - **`orchestrate`** is the human-in-the-loop meta conductor: it surveys the whole tree and batches the residue to a present human. `one-shot` is its unattended, goal-scoped mirror image, which is why the batching step here becomes parking plus a handover report. If the human IS sitting there and wants to answer live, they want `orchestrate`, not this.
209
216
  - **`from-idea`** clarifies an idea and stops at a spec. `one-shot` starts there and keeps going to landed code.
210
- - **`run`/`advance`** are the real daemon when `dorfl` is installed: many goals, indefinitely, with locks. `one-shot` is one goal, one session, no locks.
217
+ - **`run`/`advance`** are the real daemon when `dorfl` is installed: many goals, indefinitely, with locks, against a shared arbiter. `one-shot` is one goal, one session, one machine: no locks, no arbiter, nothing leaves the box.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dorfl",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/wighawag/dorfl.git",