@hecer/yoke 1.0.0 → 1.1.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.
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "yoke",
3
+ "owner": { "name": "HECer" },
4
+ "metadata": { "description": "Yoke — cross-agent coding harness for Claude Code, Codex CLI, and Gemini CLI" },
5
+ "plugins": [
6
+ {
7
+ "name": "yoke",
8
+ "source": "./",
9
+ "description": "One curated skill canon plus mechanical safety gates and an autonomous loop (yoke CLI: npm i -g @hecer/yoke).",
10
+ "author": { "name": "HECer" },
11
+ "homepage": "https://github.com/HECer/yoke",
12
+ "repository": "https://github.com/HECer/yoke",
13
+ "license": "MIT",
14
+ "keywords": ["harness", "cross-agent", "tdd", "code-review", "codex", "gemini-cli"],
15
+ "category": "development"
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
+ "name": "yoke",
4
+ "displayName": "Yoke",
5
+ "version": "1.1.0",
6
+ "description": "Cross-agent coding harness: one curated skill canon (TDD, brainstorming, plans, reviews, shipping, design verification) plus mechanical safety gates and an autonomous loop via the yoke CLI.",
7
+ "author": { "name": "HECer", "url": "https://github.com/HECer" },
8
+ "homepage": "https://github.com/HECer/yoke#readme",
9
+ "repository": "https://github.com/HECer/yoke",
10
+ "license": "MIT",
11
+ "keywords": ["harness", "cross-agent", "tdd", "code-review", "autonomous-loop", "codex", "gemini-cli"],
12
+ "skills": "./canon/skills/"
13
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yoke",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Cross-agent coding discipline, mechanical gates, and release workflows",
5
5
  "skills": "./canon/skills/",
6
6
  "hooks": "./hooks/hooks.json"
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0 — 2026-07-30
4
+
5
+ ### Added
6
+ - Shared five-question `yoke setup` wizard with provider-aware defaults for Claude, Codex, and Gemini.
7
+ - Persisted default runner selection and `auto|critical` loop decision policies.
8
+ - Provider-neutral `yoke-workflow` skill for planning questions, approved-plan PRD handoff, autonomous story execution, and critical-decision resume.
9
+ - Structured critical-decision requests with `yoke loop decision` and `yoke loop answer`; answers are validated, committed under the configured human identity, and resume the same story.
10
+ - Approved `.yoke/plan.md` context in PRD drafting and a lint gate for unresolved planning placeholders.
11
+
12
+ ### Fixed
13
+ - Retrofit and loop on/off now preserve timeout, decision, runner, and permission settings.
14
+ - Empty projects prefer the active agent host instead of silently installing Claude artifacts in Codex.
15
+ - Loop and PRD runner selection now prefer an explicit flag, then the configured runner, then the active host.
16
+ - Retrofit reports no longer label every provider as Claude Code.
17
+ - Critical-decision resumes retain isolation, review, runner, permissions, timeout, JSON, policy, and iteration settings instead of falling back to an unreviewed default run.
18
+ - Decision answers use an atomic owner-token lock and recoverable request journal, are checked against the active PRD story, bounded as untrusted data, and committed path-by-path so unrelated edits cannot enter the human-owned commit.
19
+ - Decision recovery now binds the exact selected answer to its commit, rolls back only its own interrupted context append, namespaces resume state per project/worktree, and serializes cleanup with loop startup.
20
+ - Active agent session markers now outrank globally configured provider home directories, and setup rejects partially invalid agent lists.
21
+
22
+ ### Changed
23
+ - New setups enable the loop by default and choose `decisionPolicy: auto`; the wizard can select `critical` or disable the loop.
24
+ - Legacy `loop.onAmbiguity` and `--on-ambiguity` remain compatibility aliases.
25
+
3
26
  ## 1.0.0 — 2026-07-27
4
27
 
5
28
  ### Added
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # 🐂 Yoke
4
4
 
5
- <!-- yoke:version:start -->1.0.0<!-- yoke:version:end -->
6
- <!-- yoke:tests:start -->500<!-- yoke:tests:end -->
7
- <!-- yoke:skills:start -->28<!-- yoke:skills:end -->
5
+ <!-- yoke:version:start -->1.1.1<!-- yoke:version:end -->
6
+ <!-- yoke:tests:start -->559<!-- yoke:tests:end -->
7
+ <!-- yoke:skills:start -->29<!-- yoke:skills:end -->
8
8
  <!-- yoke:agents:start -->Claude | Codex | Gemini<!-- yoke:agents:end -->
9
9
 
10
10
  ### One harness, three agents — and zero trust in "done."
@@ -17,7 +17,7 @@
17
17
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](#-license)
18
18
  ![Node](https://img.shields.io/badge/node-%E2%89%A520-339933?logo=node.js&logoColor=white)
19
19
  ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)
20
- ![Tests](https://img.shields.io/badge/tests-500%20passing-brightgreen.svg)
20
+ ![Tests](https://img.shields.io/badge/tests-559%20passing-brightgreen.svg)
21
21
  ![Agents](https://img.shields.io/badge/agents-Claude%20%7C%20Codex%20%7C%20Gemini-8A2BE2)
22
22
  ![Built with TDD](https://img.shields.io/badge/built%20with-TDD%20%2B%20review-ff69b4.svg)
23
23
 
@@ -25,12 +25,13 @@
25
25
 
26
26
  </div>
27
27
 
28
- > **TL;DR** — `yoke new my-app --idea="..."` scaffolds a git repo, installs the harness for all three agents, and drafts a story backlog from your idea. `yoke loop run my-app --isolate --review` then implements it story by story behind hard gates: **clean tree → acceptance criteria → your real tests green → an independent model approves → commit**. If any gate is red, nothing is committed. When a story is done, there's a photo of it in `.yoke/proof/<story>/`.
28
+ > **TL;DR** — `yoke setup .` asks five questions and installs the native harness for your agent. `yoke new my-app --idea="..."` bootstraps a project and drafts its story backlog. `yoke loop run my-app --isolate --review` then implements it story by story behind hard gates: **clean tree → acceptance criteria → your real tests green → an independent model approves → commit**. If any gate is red, nothing is committed. When a story is done, there's a photo of it in `.yoke/proof/<story>/`.
29
29
 
30
- Yoke 1.0 is safe-by-default: provider CLIs use autonomous sandbox profiles unless `--unsafe`
30
+ Yoke 1.1 is safe-by-default: provider CLIs use autonomous sandbox profiles unless `--unsafe`
31
31
  is explicit; reviews require a schema-valid verdict and a different model unless
32
32
  `--allow-self-review` is explicit; commits enforce the human identity from project config or Git.
33
- See [the 1.0 migration guide](docs/MIGRATING-TO-1.0.md).
33
+ See [the 1.1 migration guide](docs/MIGRATING-TO-1.1.md) for setup/decision parity and
34
+ [the 1.0 guide](docs/MIGRATING-TO-1.0.md) for the earlier safety-policy changes.
34
35
 
35
36
  ---
36
37
 
@@ -71,7 +72,7 @@ $ ls reading-app/.yoke/proof/STORY-2/
71
72
  home.png list.png # photographic evidence, labelled per story
72
73
  ```
73
74
 
74
- Every claim in that transcript is enforced by code paths with tests behind them — 500 of them, and this repo was built by its own loop and gates ([how it was built](#-why--how-it-was-built)).
75
+ Every claim in that transcript is enforced by code paths with tests behind them — 559 of them, and this repo was built by its own loop and gates ([how it was built](#-why--how-it-was-built)).
75
76
 
76
77
  ## 🚀 Quickstart
77
78
 
@@ -84,15 +85,14 @@ yoke new my-app --idea="a CLI that tracks reading lists"
84
85
  yoke loop on my-app && yoke loop run my-app --isolate
85
86
 
86
87
  # — or retrofit an existing project —
87
- yoke validate canon # 1) sanity-check the canon
88
- yoke retrofit /path/to/project --agent=all # 2) install (non-destructive)
89
- yoke loop on /path/to/project # 3) optional: the autonomous loop
88
+ yoke setup /path/to/project # interactive: agents, graph, loop, runner, decisions
89
+ yoke validate canon # sanity-check the canon
90
90
  yoke loop run /path/to/project --isolate --reviewer=codex --max=20
91
91
  ```
92
92
 
93
93
  > Requires Node ≥ 20 and git. No global install? `node /path/to/yoke/dist/cli.js …` or `npm --prefix /path/to/yoke run yoke -- …` work too. The MCP tools (rtk, graphify/Serena, Playwright MCP) are wired by Yoke but installed separately — the generated config is a clearly-labelled, adjustable template.
94
94
 
95
- ### Or install the skills as a Claude Code plugin
95
+ ### Skills before the first setup
96
96
 
97
97
  The canon is also packaged as a Claude Code plugin — the repo is its own marketplace:
98
98
 
@@ -103,6 +103,12 @@ The canon is also packaged as a Claude Code plugin — the repo is its own marke
103
103
 
104
104
  That gives you all canon skills under the `yoke:` namespace (e.g. `yoke:tdd`, `yoke:review`) inside Claude Code — no retrofit needed. The `yoke` CLI (loop, gates, retrofit for Codex/Gemini) still comes from `npm i -g @hecer/yoke`. Gemini CLI users can likewise `gemini extensions install https://github.com/HECer/yoke`.
105
105
 
106
+ For Codex, no preinstalled skill is required: run `npx @hecer/yoke setup .` in a terminal, or
107
+ ask Codex to run the five-question Yoke setup flow. The retrofit writes native skills to
108
+ `.agents/skills/`, including `yoke-retrofit` and `yoke-workflow`; start a fresh Codex task if an
109
+ already-open task does not discover newly installed skills. The npm package also contains
110
+ `.codex-plugin/plugin.json` for Codex plugin hosts.
111
+
106
112
  ### Staying up to date
107
113
 
108
114
  Yoke checks for new releases npm/gh-style: a **non-blocking background check** (at most once a day, detached, offline-safe) prints a one-line hint when a newer version exists — upgrading itself is always an explicit act:
@@ -124,11 +130,11 @@ Auto-upgrade is deliberately **not** the default: a gate harness shouldn't chang
124
130
 
125
131
  Yoke is meant to be operated *by* your coding agent — after a retrofit, the agent has the skills, the safety policy, and the routing, so it knows the methodology. Copy-paste prompts (identical wording works for Claude Code, Codex CLI, and Gemini CLI):
126
132
 
127
- > **Set it up** — *"Install the Yoke harness in this project: run `yoke retrofit . --agent=all`, pick the code-graph you'd recommend for this codebase, and leave the autonomous loop disabled for now. Then summarise what changed and commit it."*
133
+ > **Set it up** — *"Set up Yoke in this project. Ask me the Yoke setup questions one at a time with your recommendation, then run `yoke setup . --yes` with the selected host, agents, code graph, loop, runner, and decision policy. Commit in my configured identity."*
128
134
 
129
135
  > **Work the disciplined way** — *"From now on follow the Yoke skills you just installed: brainstorm → spec → plan → TDD → review before merging. Use the `review` skill before any merge."*
130
136
 
131
- > **Run autonomously** — *"Write `.yoke/prd.yaml` with one story per task (each needs acceptance criteria — see the `authoring-prd` skill), set `verify.command` in `.yoke/config.yaml`, enable the loop with `yoke loop on .`, then run it in small visible batches: `yoke loop run . --max=5`. After each batch show me `yoke loop status .`."*
137
+ > **Plan, then run autonomously** — *"Use the `yoke-workflow` skill. Ask only the planning questions that materially change the product, write the approved plan and loop-ready stories, then execute every approved story without routine follow-ups. Follow the configured `auto` or `critical` decision policy."*
132
138
 
133
139
  > **Watch / unblock** — *"Run `yoke loop status .`. If it says BLOCKED, run the project's verify command, find the root cause, fix it without weakening tests, then continue the loop."*
134
140
 
@@ -142,13 +148,14 @@ Yoke's CLI is deterministic and chainable by design: an agent (or a shell `&&`)
142
148
 
143
149
  | Command | What it does | Exit codes |
144
150
  |---|---|---|
151
+ | `yoke setup [dir] [--yes] [--host=] [--agent=] [--runner=] [--code-graph=] [--decision-policy=] [--loop\|--no-loop]` | Shared five-question setup for Claude, Codex, and Gemini; `--yes` applies supplied/default choices non-interactively | `0` · `1` invalid setup |
145
152
  | `yoke validate [canonDir]` | Validate the canon (schema, frontmatter, templates) | `0` valid · `1` errors |
146
153
  | `yoke new <dir> [--idea=] [--agent=] [--runner=] [--loop]` | Greenfield bootstrap: git init → scaffold → retrofit → context → PRD (drafted from `--idea`) → committed | `0` · `1` usage / non-empty dir / draft failed (scaffold survives) · `2` draft agent unavailable |
147
154
  | `yoke retrofit [dir] [--agent=claude,codex,gemini\|all] [--code-graph=graphify\|serena] [--loop]` | Install/update the harness, non-destructively | `0` |
148
155
  | `yoke prd draft [dir] --idea= [--runner=] [--force]` | Idea → 5–12 stories with testable acceptance criteria | `0` · `1` invalid/guarded · `2` agent unavailable |
149
156
  | `yoke prd check [dir]` | PRD lint gate (schema, dependencies, cycles, duplicate ids, acceptance) | `0` valid · `1` violations |
150
157
  | `yoke context init\|status [dir]` | Durable context layer (`PROJECT/DECISIONS/KNOWLEDGE.md`) | `0` |
151
- | `yoke loop on\|off\|status\|run\|cleanup [dir]` | Autonomous loop; cleanup deletes worktrees only with `--remove-worktrees` | run: `0` complete · `1` blocked/cap · `2` not runnable / already locked · `3` paused |
158
+ | `yoke loop on\|off\|status\|decision\|answer\|resume\|run\|cleanup [dir]` | Autonomous loop; `decision` shows a critical stop, `answer` records it and resumes, `resume` retries a failed restart with the preserved safety options; cleanup deletes worktrees only with `--remove-worktrees` | run: `0` complete · `1` blocked/cap · `2` not runnable / already locked · `3` paused |
152
159
  | `yoke review [dir] [--reviewer=] [--base=] [--focus=] [--json] [--allow-self-review]` | An independent model writes a schema-valid verdict | `0` approved · `1` findings/invalid verdict · `2` no independent reviewer |
153
160
  | `yoke audit [dir] [--json]` | Dependency, high-confidence secret, and sensitive-change audit | `0` green · `1` blocking findings · `2` not runnable |
154
161
  | `yoke design-scan [dir] [--max=N] [--report]` | Static AI-slop design gate | `0` within budget · `1` over |
@@ -214,7 +221,7 @@ Three layers — **Canon** (`yoke validate`) → **Retrofit** (`yoke retrofit`)
214
221
  > instructions (tech stack, workflow, `@`-includes) inside it. Works in any yoke-written file;
215
222
  > content *outside* the markers is still replaced (and backed up under `.yoke/backup/`).
216
223
 
217
- ## 🧰 What's in the canon — 28 skills
224
+ ## 🧰 What's in the canon — 29 skills
218
225
 
219
226
  `yoke retrofit` installs all of these into each agent natively. Provenance is credited in [`canon/skills/ATTRIBUTION.md`](canon/skills/ATTRIBUTION.md).
220
227
 
@@ -250,11 +257,12 @@ To stop overlapping skills from auto-invoking against each other, `canon/AGENTS.
250
257
  | `retro` | Engineering retrospective from commit history |
251
258
  | `document-release` | Post-ship documentation sync (README / CHANGELOG / …) |
252
259
 
253
- **Yoke-native** — *authored or adapted for this harness (8)*
260
+ **Yoke-native** — *authored or adapted for this harness (9)*
254
261
 
255
262
  | Skill | What it does |
256
263
  |---|---|
257
264
  | `yoke-retrofit` | Set up the Yoke harness in a project (detect → plan → apply) |
265
+ | `yoke-workflow` | Provider-neutral planning questions → approved PRD → autonomous stories → critical-decision resume |
258
266
  | `authoring-prd` | Slice a product idea into loop-ready stories with testable acceptance criteria |
259
267
  | `minimal-code` | Write the least code that solves the task (YAGNI; ponytail-derived) |
260
268
  | `performance` | Efficiency as a measured requirement: benchmarks as tests, budgets as gates, optimizations local + documented |
@@ -278,7 +286,7 @@ existing projects), then: creates and `git init`s the directory, writes a minima
278
286
  **context layer** (with `--idea` seeded into `PROJECT.md` as the north star), writes a commented
279
287
  **PRD template** to `.yoke/prd.yaml`, and makes the initial commit — so `--isolate` works from
280
288
  iteration 1. With `--idea`, it then drafts the PRD from your idea via an agent (`--runner=`,
281
- default `claude`) and commits it as a second commit (`docs: draft PRD from idea`).
289
+ the configured runner or active host) and commits it as a second commit (`docs: draft PRD from idea`).
282
290
 
283
291
  - **Exit codes** — `0` success; `1` usage / non-empty dir / draft failure (the scaffold survives —
284
292
  retry with `yoke prd draft`); `2` requested draft agent unavailable.
@@ -287,16 +295,18 @@ default `claude`) and commits it as a second commit (`docs: draft PRD from idea`
287
295
  stories with testable behavioral acceptance criteria (greenfield STORY-1 scaffolds the project
288
296
  skeleton + test suite and wires `verify.command`). An existing PRD with stories is never
289
297
  overwritten without `--force`; the untouched template doesn't trigger the guard. Runs through
290
- the same idle-timeout watchdog as the loop (`--timeout`).
298
+ the same idle-timeout watchdog as the loop (`--timeout`). If `.yoke/plan.md` exists, its approved
299
+ goals, non-goals, constraints, and decisions are injected as settled context instead of being
300
+ reopened by the drafting agent.
291
301
 
292
302
  **`yoke prd check [dir]`** is the chainable pre-loop lint gate: schema validation plus
293
- duplicate-id, empty-acceptance, and zero-stories checks. Exits `0` with
303
+ duplicate-id, empty-acceptance, unresolved-placeholder, and zero-stories checks. Exits `0` with
294
304
  `✓ PRD valid — N stories, M pass`, `1` on any violation. The `authoring-prd` canon skill
295
305
  teaches interactive sessions the same story-slicing discipline.
296
306
 
297
307
  ## 🤖 The autonomous loop
298
308
 
299
- Opt-in and off by default. Each iteration starts a **fresh agent** and passes through hard gates before anything is committed:
309
+ Opt-in; `yoke setup` recommends enabling it for new installs, while `retrofit` alone keeps it off unless requested. Each iteration starts a **fresh agent** and passes through hard gates before anything is committed:
300
310
 
301
311
  ```mermaid
302
312
  flowchart LR
@@ -320,7 +330,7 @@ yoke loop run . \
320
330
  --runner=codex \ # implement with Codex…
321
331
  --reviewer=claude \ # …review with Claude (role separation)
322
332
  --isolate \ # each story in a throwaway git worktree
323
- --on-ambiguity=abort \ # strict: stop on undecidable criteria instead of guessing
333
+ --decision-policy=critical \ # pause only for high-impact decisions; routine choices stay autonomous
324
334
  --max=20
325
335
  yoke loop off . # disable
326
336
  ```
@@ -380,25 +390,51 @@ A per-iteration **idle timeout** guards against a genuinely hung agent: if the a
380
390
  output is **never** killed — the output stream *is* the liveness signal. Set a project default
381
391
  with `loop.timeoutMinutes` in `.yoke/config.yaml`.
382
392
 
383
- ### Ambiguous stories: questions belong in planning
393
+ ### Decision policy: autonomous by default, interrupt only when configured
394
+
395
+ Planning questions happen before the loop. The provider-neutral `yoke-workflow` skill asks only
396
+ questions whose answer materially changes product behavior, scope, architecture, security, data
397
+ ownership, external cost, or an irreversible choice. It saves the approved brief in
398
+ `.yoke/plan.md`; `yoke prd draft` consumes it, and `yoke prd check` rejects explicit unresolved
399
+ placeholders such as `TBD`.
400
+
401
+ The unattended loop then follows `loop.decisionPolicy`:
384
402
 
385
- A loop run has nobody to ask, so the runner prompt always forbids questions. What the agent
386
- does when an acceptance criterion is genuinely ambiguous is configurable:
403
+ ```yaml
404
+ loop:
405
+ enabled: true
406
+ decisionPolicy: critical # or auto
407
+ runner:
408
+ agent: codex # setup chooses the current host by default
409
+ ```
387
410
 
388
- - **Default (`resolve`) — never stop:** the agent picks the interpretation most consistent
389
- with the other criteria and the existing code, states it in its final message, and the loop
390
- keeps going.
391
- - **Strict (`abort`):** the agent must not guess — it writes its open question(s) to
392
- `.yoke/ambiguity.md` and stops. The loop consumes that file, skips verify (an unimplemented
393
- story would otherwise sail through on pre-existing green tests), and blocks with the
394
- question in the reason, e.g.
395
- `story S6 stopped: ambiguous acceptance criteria — Which auth provider should S6 use?`
396
- Answer by sharpening the story's acceptance criteria, then re-run.
411
+ - **`auto` (default):** routine ambiguity and implementation details are resolved using the
412
+ approved plan, acceptance criteria, current code, and project conventions. The loop does not
413
+ ask follow-up questions.
414
+ - **`critical`:** routine choices are still resolved automatically. Only high-impact decisions
415
+ involving public architecture, security/privacy, destructive migration or data loss, material
416
+ external cost, legal/compliance exposure, or another irreversible choice may pause the story.
417
+ The agent writes a schema-validated request; the loop blocks before verify and preserves it as
418
+ `.yoke/pending-decision.yaml`.
419
+
420
+ Inspect and answer a critical stop:
421
+
422
+ ```bash
423
+ yoke loop decision .
424
+ yoke loop answer . --choice=A --rationale="Matches the existing identity model"
425
+ ```
397
426
 
398
- Enable strict mode per run with `yoke loop run . --on-ambiguity=abort` or per project with
399
- `loop.onAmbiguity: abort` in `.yoke/config.yaml`. Either way, the cheapest fix is upstream:
400
- put every clarifying question into the PRD **before** the loop starts (`yoke prd draft`
401
- criteria must be testable and decision-free).
427
+ `answer` validates the choice against the still-open story, appends it to
428
+ `.yoke/context/DECISIONS.md`, commits only that file using the configured human identity, clears
429
+ the pending request, and resumes the same story with the original runner, isolation, review,
430
+ permission, timeout, JSON, decision-policy, and iteration settings intact. Add
431
+ `--no-resume` when a supervisor should restart the loop separately. If the automatic restart
432
+ cannot begin because a provider/reviewer is unavailable or another process owns the lock, run
433
+ `yoke loop resume .`; its request-bound options are retained under Git's private state directory
434
+ until a loop actually runs. To intentionally abandon an orphaned or stale private resume state,
435
+ use `yoke loop resume . --discard`; pending decisions are never deleted by that command. Existing
436
+ `loop.onAmbiguity: resolve|abort` and `--on-ambiguity=` remain supported as compatibility aliases;
437
+ new projects should use `decisionPolicy: auto|critical`.
402
438
 
403
439
  ### Performance budgets: efficiency as a gate, not a style
404
440
 
@@ -429,21 +465,26 @@ committed even if the agent process exited non-zero (a common Windows `.cmd`-wra
429
465
  A failing verify is retried up to `verify.retries` times (default 1) so a transient flake
430
466
  self-heals while a real failure still blocks.
431
467
 
432
- `.yoke/loop-status.json`, `.yoke/loop.log`, `.yoke/loop.lock`, `.yoke/story-durations.json`,
433
- and `.yoke/ambiguity.md` are runtime artifacts; `yoke retrofit` gitignores them (along with
468
+ `.yoke/loop-status.json`, `.yoke/loop.log`, `.yoke/loop.lock`, its takeover/recovery leases, lock/decision temp files, `.yoke/story-durations.json`,
469
+ `.yoke/ambiguity.md`, and the critical-decision request/answering files are runtime artifacts;
470
+ `yoke retrofit` gitignores them (along with
434
471
  `.yoke/worktrees/`, `.yoke/backup/`, and `.yoke/proof/`) so they never trip the clean-tree gate.
435
472
 
436
473
  ### Single-flight guard + cleanup
437
474
 
438
475
  Two concurrent `yoke loop run`s would race on the PRD and status files, so the loop takes a
439
- **lock** (`.yoke/loop.lock`) for the duration of a run. A second invocation exits `2` with
476
+ **lock** (`.yoke/loop.lock`) for the duration of a run. Complete lock metadata is published atomically;
477
+ stale takeover is serialized by `.yoke/loop.lock.takeover`. A second invocation exits `2` with
440
478
  `Another loop is already running here (pid …). If that is wrong, run: yoke loop cleanup`. A lock
441
479
  whose holder process is dead is taken over automatically (with a warning).
442
480
 
443
481
  **`yoke loop cleanup [dir]`** removes what a crashed loop leaves behind: every worktree under
444
482
  `.yoke/worktrees/` (via `git worktree remove --force` + `prune` — user-created worktrees are
445
483
  never touched) and a **stale** lock file. A live lock is reported and left alone. Exits `0`
446
- when everything cleaned, `1` if any removal failed.
484
+ when everything cleaned, `1` if any removal failed. If a machine/process crash leaves the cleanup
485
+ recovery lease itself behind, an operator can run
486
+ `yoke loop cleanup . --discard-stale-recovery`; Yoke refuses while its recorded PID is alive, and
487
+ the force flag must not be run concurrently.
447
488
 
448
489
  ## 🔍 Cross-model review (`yoke review`)
449
490
 
@@ -527,7 +568,8 @@ Yoke keeps durable, cross-session context so a fresh-context agent is never blin
527
568
 
528
569
  `yoke retrofit` scaffolds these files (non-destructively — your edits are never overwritten).
529
570
  The loop reads them into every agent + reviewer prompt and logs decisions back on each story's
530
- commit. Manage them directly with `yoke context init` and `yoke context status`. The
571
+ commit. Decision history is explicitly delimited as untrusted reference data, so stored text is
572
+ never treated as fresh instructions. Manage the files directly with `yoke context init` and `yoke context status`. The
531
573
  `maintaining-context` skill teaches agents to honour the same files during interactive work.
532
574
 
533
575
  > Commit `.yoke/context/` to git. The `--isolate` loop runs each iteration in a worktree
@@ -598,14 +640,14 @@ docs/superpowers/ # the spec and every component's implementation plan
598
640
 
599
641
  ## 🗺️ Roadmap
600
642
 
601
- Yoke 1.0's completed release work moved to the changelog. Remaining, explicitly scoped work
643
+ Yoke 1.1's completed release work moved to the changelog. Remaining, explicitly scoped work
602
644
  is tracked in [`TODOS.md`](TODOS.md), including provider subprocess wiring for the tested
603
645
  parallel dispatcher, broader benchmark samples, native output schemas, and release provenance.
604
646
 
605
647
  ## 🧪 Development
606
648
 
607
649
  ```bash
608
- npm test # vitest (500 tests)
650
+ npm test # vitest (559 tests)
609
651
  npm run build # tsc, no emit errors
610
652
  npm run yoke -- validate canon
611
653
  ```
package/canon/AGENTS.md CHANGED
@@ -17,6 +17,8 @@ When several skills could match the same task, resolve deterministically:
17
17
  `tdd`, `subagent-driven-development`, `systematic-debugging`, …) take precedence and set the
18
18
  process. Role skills (`review`, `ship`, `health`, `retro`, …) add a perspective on top.
19
19
  2. **One canonical entrypoint per concern** — pick the most specific:
20
+ - Set up or update Yoke → `yoke-retrofit`
21
+ - Yoke-owned planning + autonomous story execution → `yoke-workflow`
20
22
  - Plan-time architecture review → `plan-eng-review`
21
23
  - Plan-time product / scope review → `plan-ceo-review`
22
24
  - **Pre-merge code review → `review`** (the single canonical one)
@@ -4,7 +4,8 @@ The autonomous loop is OPTIONAL and toggle-able:
4
4
 
5
5
  - `yoke loop on` / `yoke loop off` — enable/disable (recorded in `.yoke/config.yaml`, default off).
6
6
  - `yoke loop status` — show enabled state + PRD progress.
7
- - `yoke loop run [--max=N] [--isolate]` — run the loop (default cap 25 iterations).
7
+ - `yoke loop run [--max=N] [--isolate] [--decision-policy=auto|critical]` — run the loop (default cap 25 iterations).
8
+ - `yoke loop decision` / `yoke loop answer --choice=<id>` — inspect and answer a structured critical stop; answering records a human-owned, decision-file-only commit and resumes by default with the original runner, isolation, review, permission, timeout, and policy settings. `yoke loop resume` retries a restart that could not begin without weakening those settings.
8
9
 
9
10
  Pass `--isolate` to run each iteration in a fresh git worktree: the agent works on a throwaway checkout, and only a verified, committed story is fast-forwarded back into the main tree. A failed iteration never touches your working tree. Requires `.yoke/prd.yaml` to be committed to git, since the worktree is a checkout of HEAD.
10
11
 
@@ -17,7 +18,8 @@ When enabled and run, each iteration:
17
18
  1. Pre-dispatch gate: the git worktree must be clean, else `blocked`.
18
19
  2. Pick the highest-priority unfinished PRD story (`.yoke/prd.yaml`).
19
20
  3. Stop-the-Line gate: the story must have acceptance criteria, else `blocked`.
20
- 4. Run a fresh agent to implement ONE story. The runner is selected by `--runner=<claude|codex|gemini>` or the first configured agent (default claude); the loop refuses to start if that agent's CLI is not installed.
21
+ 4. Run a fresh agent to implement ONE story. Runner precedence is explicit `--runner`, configured `runner.agent`, active agent host, then the first configured agent. The loop refuses to start if that CLI is not installed.
22
+ With `decisionPolicy: auto`, routine ambiguity is resolved from the approved plan and project conventions. With `critical`, only high-impact architecture, security/privacy, destructive data, material-cost, compliance, or irreversible choices may produce `.yoke/decision-request.yaml`; the loop validates its bounded single-line fields, unique options, and active story ID, blocks before verify, and preserves it for `yoke loop answer`.
21
23
  5. Run the project's verify command (config `verify.command`, or detected `npm test`).
22
24
  **Verify is the source of truth** — the agent's exit code is advisory, so a spurious
23
25
  non-zero exit (e.g. a Windows `.cmd` wrapper) cannot block a story whose tests are green.
@@ -1,9 +1,10 @@
1
1
  name: yoke-canon
2
- version: 1.0.0
2
+ version: 1.1.0
3
3
  agents: [claude, codex, gemini]
4
4
  skills:
5
5
  - { id: tdd, path: skills/tdd, kind: methodology }
6
6
  - { id: yoke-retrofit, path: skills/yoke-retrofit, kind: methodology }
7
+ - { id: yoke-workflow, path: skills/yoke-workflow, kind: methodology }
7
8
  - { id: minimal-code, path: skills/minimal-code, kind: methodology }
8
9
  - { id: maintaining-context, path: skills/maintaining-context, kind: methodology }
9
10
  # superpowers skills (kind: methodology)
@@ -26,9 +26,10 @@ good stories (small, testable, ordered) let it run overnight.
26
26
  criterion. If the whole project has a budget, wire `perf.command` in `.yoke/config.yaml`
27
27
  (see the `performance` skill) instead of repeating it per story.
28
28
  7. **Ask everything now.** Clarifying questions belong in this planning round — a loop run
29
- has nobody to ask. A criterion that still needs a decision ("TBD", "choose a provider")
30
- is not loop-ready; resolve it here or the agent will either guess (default) or block
31
- (`--on-ambiguity=abort`).
29
+ is unattended. A criterion that still contains `TBD` or another placeholder is not
30
+ loop-ready, and `yoke prd check` rejects it. During implementation,
31
+ `loop.decisionPolicy: auto` resolves routine ambiguity; `critical` pauses only for
32
+ high-impact choices and resumes after `yoke loop answer` records the answer.
32
33
  8. **Model real dependencies.** Add `needs` only for hard prerequisites, `area` for files or
33
34
  subsystems that must not be edited concurrently, and `agent` only as an affinity hint.
34
35
  Dependency IDs must exist; self-dependencies and cycles are invalid.
@@ -7,6 +7,10 @@ description: Use at the start of any non-trivial task — the default order of o
7
7
 
8
8
  For any non-trivial change, move through these phases in order (skip only what genuinely does not apply):
9
9
 
10
+ When `.yoke/config.yaml` exists and the user wants Yoke to own planning plus autonomous
11
+ execution, use `yoke-workflow` as the entrypoint. It adds the approved-plan → PRD → loop
12
+ handoff and the configured critical-decision behavior to the phases below.
13
+
10
14
  1. **Brainstorm** the idea into a clear design — see `brainstorming`.
11
15
  2. **Plan** a concrete, testable implementation — see `writing-plans`.
12
16
  3. **Understand the code** — map the blast radius with the code-graph before changing anything.
@@ -1,19 +1,26 @@
1
1
  ---
2
2
  name: yoke-retrofit
3
- description: Use when asked to "retrofit", "yoke this project", or set up the Yoke harness in a project — runs yoke retrofit, picks a code-graph tool, and asks whether to enable the autonomous loop.
3
+ description: Use when asked to "retrofit", "yoke this project", or set up the Yoke harness in a project — runs the shared setup wizard and configures the same behavior for Claude, Codex, and Gemini.
4
4
  ---
5
5
 
6
6
  # Yoke Retrofit
7
7
 
8
- Set up (or update) the Yoke harness in the current project.
8
+ Set up or update Yoke through the shared `yoke setup` contract.
9
9
 
10
- 1. **Choose the code-graph tool.** Ask the user which to wire, and recommend based on the project:
11
- - **Serena** (LSP-accurate, symbol-exact refactoring, no stale index) — recommend for large, strongly-typed codebases (TypeScript, Python, Go) doing systematic refactoring, where missing a reference is costly. Needs one language server per language.
12
- - **graphify** (fast, multimodal: code + PDFs + diagrams + images; ~70x token reduction on large mixed repos; honest INFERRED/AMBIGUOUS edges) — recommend for rapid exploration / migration / onboarding of large or unfamiliar repos, or repos with mixed non-code content.
13
- Make a direct recommendation for THIS project, then run with `--code-graph=serena` or `--code-graph=graphify` (default graphify if the user has no preference). The choice is saved in `.yoke/config.yaml`.
14
- 2. Run `yoke retrofit . --agent=all --code-graph=<choice>` (or a subset of agents). Non-destructive — existing files are backed up under `.yoke/backup/` before any overwrite; `.claude/settings.json` is merged, not replaced. Generated per agent: Claude (`.claude/skills/`, `AGENTS.md`, `CLAUDE.md`, `.mcp.json`, rtk hook when WSL is available); Codex (`AGENTS.md`, `.codex/config.toml`, `RTK.md`); Gemini (`GEMINI.md`, `.gemini/commands/*.toml`, `.gemini/settings.json`).
15
- 3. **Ask whether to enable the autonomous Loop** (default off). If yes, add `--loop`. Toggle any time with `yoke loop on|off`.
16
- 4. Show the printed report (created/overwritten/unchanged/merged + detected agents) and where backups went. Note that the generated MCP launch commands may need adjusting to the user's local tool installs.
17
- 5. **Preserve project content.** If the pre-retrofit `CLAUDE.md`/`GEMINI.md` had project-specific instructions (tech stack, workflow, `@`-includes), move them from the backup into the preserve block the generated file ships (`<!-- yoke:preserve:start -->` … `<!-- yoke:preserve:end -->`). Everything inside these markers survives every future `yoke retrofit` — in any yoke-written file; content outside them is replaced (but backed up).
10
+ 1. Inspect the project and identify the current host (`claude`, `codex`, or `gemini`).
11
+ 2. Ask these setup questions one at a time and give a direct recommendation:
12
+ - target agents (recommend the current host; use `all` for deliberately cross-agent projects),
13
+ - code-graph tool,
14
+ - autonomous loop on/off,
15
+ - default runner (recommend the current host),
16
+ - decision mode: `auto` or `critical`.
17
+ 3. Recommend the code graph based on this project:
18
+ - **Serena** is LSP-accurate and best for large typed codebases or systematic symbol refactors where a missed reference is costly. It needs a language server per language.
19
+ - **graphify** is fast and multimodal, and is best for exploration, migration, onboarding, or mixed code and document repositories. Its graph is an index and can become stale.
20
+ 4. Apply the answers without a second round of prompts:
21
+ `yoke setup . --yes --host=<host> --agent=<agents> --code-graph=<choice> --runner=<runner> --decision-policy=<auto|critical> --loop|--no-loop`.
22
+ A human who runs `yoke setup .` directly receives the same five terminal questions.
23
+ 5. Show the generated report and backup paths. Existing files are backed up under `.yoke/backup/`; settings are merged where supported.
24
+ 6. If an old generated `CLAUDE.md` or `GEMINI.md` contained project-specific instructions, restore them inside its `<!-- yoke:preserve:start -->` / `<!-- yoke:preserve:end -->` block. Preserve blocks survive every later retrofit.
18
25
 
19
- The harness includes a `minimal-code` skill (YAGNI / lazy-senior-dev) that nudges every agent to write the least code that solves the task — saving tokens and reducing maintenance.
26
+ The generated harness includes the provider-neutral `yoke-workflow` skill. It owns the planning questions, approved-plan handoff, autonomous stories, and critical-decision resume flow.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: yoke-workflow
3
+ description: Use when the user asks Yoke to plan and build a feature, run stories autonomously, continue a Yoke loop, or only interrupt for major decisions.
4
+ ---
5
+
6
+ # Yoke Workflow
7
+
8
+ Provide the same interaction contract in Claude, Codex, and Gemini.
9
+
10
+ 1. Read `.yoke/config.yaml`. If it is missing, offer `yoke setup . --host=<current-agent>` and run the setup flow before planning.
11
+ 2. Plan before starting the loop. Inspect the project, then ask one focused question at a time only where the answer changes product behavior, scope, architecture, security, data ownership, external cost, or an irreversible choice. Include a recommended answer. Resolve routine implementation details yourself.
12
+ 3. Summarize the agreed design in `.yoke/plan.md`, including goals, non-goals, constraints, and decisions. Use the `authoring-prd` skill to turn it into small stories with testable acceptance criteria. Run `yoke prd check .`.
13
+ 4. Ask once for approval of the complete plan and story set. Do not begin implementation before that approval.
14
+ 5. If `loop.enabled` is true, run the stories without routine follow-up questions using the configured runner. Prefer `yoke loop run . --max=5 --isolate`, report status after each batch, and continue until complete or genuinely blocked.
15
+ 6. Respect `loop.decisionPolicy`:
16
+ - `auto`: choose the most suitable option from the plan, current code, and established conventions. Record the interpretation and continue.
17
+ - `critical`: routine ambiguity is still resolved automatically. If the loop reports a pending critical decision, run `yoke loop decision .`, present its options and recommendation to the user, ask exactly that question, then run `yoke loop answer . --choice=<id> --rationale="<answer>"`. The answer command records the decision and resumes the same story.
18
+ 7. Never ask whether to run tests, review, commit, or continue to the next approved story. Those are part of the approved workflow.
19
+
20
+ The user's configured commit identity is authoritative. Do not add an AI co-author unless `commit.allowCoAuthors` explicitly permits it.
@@ -0,0 +1,26 @@
1
+ export function detectHostAgent(env = process.env) {
2
+ // Active-session markers outrank install/config directory hints inherited by
3
+ // other shells. A globally set CODEX_HOME must not hijack a Claude session.
4
+ if (env.CODEX_THREAD_ID || env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE)
5
+ return 'codex';
6
+ if (env.CLAUDECODE || env.CLAUDE_CODE_ENTRYPOINT)
7
+ return 'claude';
8
+ if (env.GEMINI_CLI)
9
+ return 'gemini';
10
+ if (env.CODEX_HOME)
11
+ return 'codex';
12
+ if (env.CLAUDE_CONFIG_DIR)
13
+ return 'claude';
14
+ if (env.GEMINI_CLI_HOME)
15
+ return 'gemini';
16
+ return undefined;
17
+ }
18
+ export function resolveRunnerAgent(config, explicit, host) {
19
+ if (explicit)
20
+ return explicit;
21
+ if (config?.runner?.agent)
22
+ return config.runner.agent;
23
+ if (host && (!config || config.agents.length === 0 || config.agents.includes(host)))
24
+ return host;
25
+ return config?.agents[0] ?? host ?? 'claude';
26
+ }
@@ -14,9 +14,9 @@ const argsFor = (agent, permissions) => {
14
14
  return ['exec', '--full-auto', '--json'];
15
15
  }
16
16
  if (permissions === 'unsafe')
17
- return ['--yolo', '--output-format', 'stream-json'];
17
+ return ['--yolo'];
18
18
  const approval = permissions === 'read-only' ? 'plan' : 'auto_edit';
19
- return ['--approval-mode', approval, '--sandbox', '--output-format', 'stream-json'];
19
+ return ['--approval-mode', approval, '--sandbox'];
20
20
  };
21
21
  export function buildProviderInvocation(agent, prompt, cwd, permissions = 'safe') {
22
22
  return { command: agent, args: argsFor(agent, permissions), input: prompt, cwd };