@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.
- package/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +13 -0
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +23 -0
- package/README.md +87 -45
- package/canon/AGENTS.md +2 -0
- package/canon/loop/loop-spec.md +4 -2
- package/canon/manifest.yaml +2 -1
- package/canon/skills/authoring-prd/SKILL.md +4 -3
- package/canon/skills/workflow/SKILL.md +4 -0
- package/canon/skills/yoke-retrofit/SKILL.md +18 -11
- package/canon/skills/yoke-workflow/SKILL.md +20 -0
- package/dist/agents/host.js +26 -0
- package/dist/agents/providers.js +2 -2
- package/dist/cli.js +170 -5
- package/dist/context/context.js +15 -2
- package/dist/loop/cleanup.js +97 -32
- package/dist/loop/decision.js +517 -0
- package/dist/loop/git.js +23 -0
- package/dist/loop/lock.js +104 -13
- package/dist/loop/loop.js +29 -0
- package/dist/loop/run-command.js +69 -8
- package/dist/loop/runner.js +7 -1
- package/dist/prd/command.js +27 -24
- package/dist/retrofit/command.js +3 -2
- package/dist/retrofit/config.js +5 -1
- package/dist/retrofit/gitignore.js +8 -0
- package/dist/retrofit/report.js +1 -1
- package/dist/setup/command.js +82 -0
- package/docs/MIGRATING-TO-1.1.md +27 -0
- package/docs/PUBLISHING.md +77 -41
- package/gemini-extension.json +6 -0
- package/package.json +4 -2
|
@@ -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
|
+
}
|
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.
|
|
6
|
-
<!-- yoke:tests:start -->
|
|
7
|
-
<!-- yoke:skills:start -->
|
|
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)
|
|
18
18
|

|
|
19
19
|

|
|
20
|
-

|
|
21
21
|

|
|
22
22
|

|
|
23
23
|
|
|
@@ -25,12 +25,13 @@
|
|
|
25
25
|
|
|
26
26
|
</div>
|
|
27
27
|
|
|
28
|
-
> **TL;DR** — `yoke new my-app --idea="..."`
|
|
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.
|
|
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.
|
|
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 —
|
|
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
|
|
88
|
-
yoke
|
|
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
|
-
###
|
|
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** — *"
|
|
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
|
-
> **
|
|
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 —
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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
|
-
--
|
|
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
|
-
###
|
|
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
|
-
|
|
386
|
-
|
|
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
|
-
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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 (
|
|
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)
|
package/canon/loop/loop-spec.md
CHANGED
|
@@ -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.
|
|
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.
|
package/canon/manifest.yaml
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
name: yoke-canon
|
|
2
|
-
version: 1.
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
|
8
|
+
Set up or update Yoke through the shared `yoke setup` contract.
|
|
9
9
|
|
|
10
|
-
1.
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
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
|
+
}
|
package/dist/agents/providers.js
CHANGED
|
@@ -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'
|
|
17
|
+
return ['--yolo'];
|
|
18
18
|
const approval = permissions === 'read-only' ? 'plan' : 'auto_edit';
|
|
19
|
-
return ['--approval-mode', approval, '--sandbox'
|
|
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 };
|