@hecer/yoke 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +7 -0
- package/CHANGELOG.md +169 -149
- package/README.md +24 -16
- package/TODOS.md +8 -0
- package/agents/docs.toml +6 -0
- package/agents/implementer.toml +6 -0
- package/agents/reviewer.toml +6 -0
- package/agents/security.toml +6 -0
- package/bench/README.md +45 -42
- package/bench/RESULTS.md +46 -36
- package/bench/result-schema.mjs +12 -0
- package/bench/results/claude-2026-07-27T18-03-26.json +50 -0
- package/bench/results/codex-unavailable-1785175418318.json +15 -0
- package/bench/results/gemini-2026-07-27T18-03-44.json +46 -0
- package/bench/run-matrix.mjs +26 -0
- package/bench/run.mjs +127 -115
- package/canon/loop/prd.schema.md +5 -0
- package/canon/manifest.yaml +1 -1
- package/canon/skills/authoring-prd/SKILL.md +6 -0
- package/canon/skills/ship/SKILL.md +2 -7
- package/canon/tools/codex-rtk-hook.mjs +36 -0
- package/dist/agents/providers.js +23 -0
- package/dist/agents/telemetry.js +30 -0
- package/dist/agents/types.js +1 -0
- package/dist/audit/changes.js +6 -0
- package/dist/audit/command.js +64 -0
- package/dist/audit/dependencies.js +21 -0
- package/dist/audit/secrets.js +16 -0
- package/dist/audit/types.js +1 -0
- package/dist/cli.js +22 -4
- package/dist/loop/claims.js +57 -0
- package/dist/loop/cleanup.js +10 -4
- package/dist/loop/git.js +8 -2
- package/dist/loop/identity.js +27 -0
- package/dist/loop/loop.js +20 -2
- package/dist/loop/merge-queue.js +20 -0
- package/dist/loop/parallel.js +39 -0
- package/dist/loop/prd.js +48 -2
- package/dist/loop/run-command.js +51 -6
- package/dist/loop/runner.js +41 -29
- package/dist/loop/scheduler.js +8 -0
- package/dist/prd/command.js +6 -0
- package/dist/retrofit/config.js +12 -0
- package/dist/retrofit/planners/codex.js +64 -19
- package/dist/review/command.js +52 -12
- package/dist/review/verdict.js +45 -0
- package/docs/MIGRATING-TO-1.0.md +33 -0
- package/docs/superpowers/plans/2026-07-27-yoke-1.0-release.md +205 -0
- package/docs/superpowers/specs/2026-07-27-yoke-1.0-hardening-and-codex-parity-design.md +164 -0
- package/hooks/hooks.json +19 -0
- package/package.json +82 -67
- package/bench/.runs/claude-2026-07-09T22-34-01/.yoke/config.yaml +0 -6
- package/bench/.runs/claude-2026-07-09T22-34-01/.yoke/context/DECISIONS.md +0 -9
- package/bench/.runs/claude-2026-07-09T22-34-01/.yoke/prd.yaml +0 -38
- package/bench/.runs/claude-2026-07-09T22-34-01/bench-verify.mjs +0 -15
- package/bench/.runs/claude-2026-07-09T22-34-01/package.json +0 -9
- package/bench/.runs/claude-2026-07-09T22-34-01/src/index.mjs +0 -48
- package/bench/.runs/claude-2026-07-09T22-34-01/tests/STORY-1.test.mjs +0 -24
- package/bench/.runs/claude-2026-07-09T22-34-01/tests/STORY-2.test.mjs +0 -28
- package/bench/.runs/claude-2026-07-09T22-34-01/tests/STORY-3.test.mjs +0 -25
- package/bench/.runs/gemini-2026-07-09T22-34-02/.yoke/config.yaml +0 -6
- package/bench/.runs/gemini-2026-07-09T22-34-02/.yoke/prd.yaml +0 -32
- package/bench/.runs/gemini-2026-07-09T22-34-02/bench-verify.mjs +0 -15
- package/bench/.runs/gemini-2026-07-09T22-34-02/package.json +0 -9
- package/bench/.runs/gemini-2026-07-09T22-34-02/src/index.mjs +0 -3
- package/bench/.runs/gemini-2026-07-09T22-34-02/tests/STORY-1.test.mjs +0 -24
- package/bench/.runs/gemini-2026-07-09T22-34-02/tests/STORY-2.test.mjs +0 -28
- package/bench/.runs/gemini-2026-07-09T22-34-02/tests/STORY-3.test.mjs +0 -25
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Yoke 1.0 Release Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Ship Yoke 1.0 with native Codex parity, safe and observable runners, mechanical reviews, human-owned commits, a security gate, dependency-aware parallel execution, and reproducible release claims.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Keep the existing canon → retrofit → loop layers, but split provider-specific execution from loop policy. Add small schema-validated modules for review verdicts, commit identity, audits, PRD dependencies, and parallel scheduling; the CLI composes them without duplicating policy.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript ESM, Node.js 20+, Zod, YAML, Vitest, Git worktrees, npm packaging, provider CLIs.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Task 1: Release truth and dependency baseline
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Modify: `package.json`
|
|
17
|
+
- Modify: `package-lock.json`
|
|
18
|
+
- Modify: `canon/manifest.yaml`
|
|
19
|
+
- Create: `scripts/release-metadata.mjs`
|
|
20
|
+
- Create: `tests/release/metadata.test.ts`
|
|
21
|
+
- Modify: `.github/workflows/ci.yml`
|
|
22
|
+
|
|
23
|
+
- [ ] **Step 1: Write a failing metadata test** proving the script reads package version, manifest skill/agent counts, and a Vitest summary string and produces stable README replacements.
|
|
24
|
+
- [ ] **Step 2: Run `npm test -- tests/release/metadata.test.ts`** and confirm failure because `scripts/release-metadata.mjs` does not exist.
|
|
25
|
+
- [ ] **Step 3: Implement exported `collectMetadata(root, testSummary)` and `updateReadme(readme, metadata)` functions** plus `--check` and `--write` CLI modes. The updater owns markers for version, test count, skill count, and agents.
|
|
26
|
+
- [ ] **Step 4: Upgrade Vitest to the newest compatible stable release, regenerate the lockfile, and set package/canon/plugin/extension versions to `1.0.0`.**
|
|
27
|
+
- [ ] **Step 5: Add `lint`, `docs:check`, `docs:update`, `audit:ci`, and `package:check` scripts and exercise them in CI on Windows and Linux.**
|
|
28
|
+
- [ ] **Step 6: Run the focused test, `npm audit`, `npm run build`, and `npm test`; commit as `chore(release): establish 1.0 release truth`.**
|
|
29
|
+
|
|
30
|
+
### Task 2: Native Codex skills, hooks, agents, and plugin
|
|
31
|
+
|
|
32
|
+
**Files:**
|
|
33
|
+
- Modify: `src/retrofit/planners/codex.ts`
|
|
34
|
+
- Modify: `src/retrofit/merge-json.ts`
|
|
35
|
+
- Modify: `canon/AGENTS.md`
|
|
36
|
+
- Create: `codex-plugin/plugin.json`
|
|
37
|
+
- Create: `codex-plugin/hooks/hooks.json`
|
|
38
|
+
- Create: `codex-plugin/agents/implementer.toml`
|
|
39
|
+
- Create: `codex-plugin/agents/reviewer.toml`
|
|
40
|
+
- Create: `codex-plugin/agents/security.toml`
|
|
41
|
+
- Create: `codex-plugin/agents/docs.toml`
|
|
42
|
+
- Modify: `tests/retrofit/planners-codex.test.ts`
|
|
43
|
+
- Modify: `tests/retrofit/retrofit.integration.test.ts`
|
|
44
|
+
|
|
45
|
+
- [ ] **Step 1: Extend the Codex planner tests** to require every manifest skill under `.agents/skills`, a merged `.codex/config.toml`, `.codex/hooks.json`, four `.codex/agents/*.toml` files, `RTK.md`, and `@RTK.md` in generated `AGENTS.md`.
|
|
46
|
+
- [ ] **Step 2: Run `npm test -- tests/retrofit/planners-codex.test.ts tests/retrofit/retrofit.integration.test.ts`** and confirm missing-artifact failures.
|
|
47
|
+
- [ ] **Step 3: Implement skill copying and generated Codex artifacts.** Config uses project-local `[mcp_servers.*]`; the hook uses `PreToolUse` with command `rtk hook codex`; each agent file defines `name`, `description`, `sandbox_mode`, and narrow `developer_instructions`.
|
|
48
|
+
- [ ] **Step 4: Add the distributable Codex plugin manifest** referencing `../canon/skills`, bundled hooks, MCP configuration, and agents without duplicating skill bodies.
|
|
49
|
+
- [ ] **Step 5: Re-run focused tests and canon validation; commit as `feat(codex): add native skills hooks agents and plugin`.**
|
|
50
|
+
|
|
51
|
+
### Task 3: Provider adapters and permission profiles
|
|
52
|
+
|
|
53
|
+
**Files:**
|
|
54
|
+
- Create: `src/agents/types.ts`
|
|
55
|
+
- Create: `src/agents/providers.ts`
|
|
56
|
+
- Create: `src/agents/telemetry.ts`
|
|
57
|
+
- Modify: `src/loop/runner.ts`
|
|
58
|
+
- Modify: `src/retrofit/config.ts`
|
|
59
|
+
- Modify: `src/cli.ts`
|
|
60
|
+
- Create: `tests/agents/providers.test.ts`
|
|
61
|
+
- Create: `tests/agents/telemetry.test.ts`
|
|
62
|
+
- Modify: `tests/loop/runner.test.ts`
|
|
63
|
+
|
|
64
|
+
- [ ] **Step 1: Write failing tests** for `safe`, `unsafe`, and `read-only` invocations for Claude, Codex, and Gemini, plus structured usage/model parsing with an explicit unavailable state.
|
|
65
|
+
- [ ] **Step 2: Run the three focused test files** and confirm the provider module is missing.
|
|
66
|
+
- [ ] **Step 3: Implement `AgentProvider` and `PermissionProfile`** with provider-owned invocation and telemetry parsing. `unsafe` contains the previous bypass flags; safe/read-only never contain them.
|
|
67
|
+
- [ ] **Step 4: Add optional `runner.permissions` and CLI `--unsafe`; default to `safe`.** Reject unsupported provider/profile pairs with exit code 2 and print the effective profile at startup.
|
|
68
|
+
- [ ] **Step 5: Refactor runner construction through the provider registry while preserving watchdog and Claude usage behavior.**
|
|
69
|
+
- [ ] **Step 6: Run focused and full tests; commit as `feat(runner): add safe provider profiles and telemetry`.**
|
|
70
|
+
|
|
71
|
+
### Task 4: Schema-validated independent review
|
|
72
|
+
|
|
73
|
+
**Files:**
|
|
74
|
+
- Create: `src/review/verdict.ts`
|
|
75
|
+
- Modify: `src/review/command.ts`
|
|
76
|
+
- Modify: `src/loop/runner.ts`
|
|
77
|
+
- Modify: `src/loop/run-command.ts`
|
|
78
|
+
- Modify: `src/cli.ts`
|
|
79
|
+
- Create: `tests/review/verdict.test.ts`
|
|
80
|
+
- Modify: `tests/review/command.test.ts`
|
|
81
|
+
- Modify: `tests/loop/standalone-review.test.ts`
|
|
82
|
+
- Modify: `tests/loop/loop-cli.integration.test.ts`
|
|
83
|
+
|
|
84
|
+
- [ ] **Step 1: Write failing verdict tests** for approve, reject, malformed JSON, missing file, findings, and cleanup.
|
|
85
|
+
- [ ] **Step 2: Write failing resolution tests** proving reviewer differs from implementer and self-review requires `--allow-self-review`.
|
|
86
|
+
- [ ] **Step 3: Run focused tests** and confirm failures against the exit-code implementation.
|
|
87
|
+
- [ ] **Step 4: Implement `ReviewVerdictSchema`, `readReviewVerdict`, and `reviewVerdictPath`.** Prompts receive the absolute path and exact JSON contract; process failure and verdict are reported separately.
|
|
88
|
+
- [ ] **Step 5: Make standalone and loop reviews parse the verdict, reject missing/malformed output, and expose `--json` plus `--allow-self-review`.**
|
|
89
|
+
- [ ] **Step 6: Run focused and full tests; commit as `feat(review): enforce independent structured verdicts`.**
|
|
90
|
+
|
|
91
|
+
### Task 5: Explicit commit identity
|
|
92
|
+
|
|
93
|
+
**Files:**
|
|
94
|
+
- Create: `src/loop/identity.ts`
|
|
95
|
+
- Modify: `src/loop/git.ts`
|
|
96
|
+
- Modify: `src/loop/gates.ts`
|
|
97
|
+
- Modify: `src/loop/run-command.ts`
|
|
98
|
+
- Modify: `src/retrofit/config.ts`
|
|
99
|
+
- Modify: `canon/skills/ship/SKILL.md`
|
|
100
|
+
- Modify: `tests/loop/git.test.ts`
|
|
101
|
+
- Create: `tests/loop/identity.test.ts`
|
|
102
|
+
|
|
103
|
+
- [ ] **Step 1: Write failing tests** for config precedence, Git fallback, missing identity, exact commit author/committer, and absence of AI trailers.
|
|
104
|
+
- [ ] **Step 2: Run focused tests** and confirm the current ambient-only behavior fails.
|
|
105
|
+
- [ ] **Step 3: Add optional `commit.authorName`, `commit.authorEmail`, and `commit.allowCoAuthors` defaulting false.** Implement `resolveCommitIdentity` and pass identity via `git -c user.name=... -c user.email=... commit`.
|
|
106
|
+
- [ ] **Step 4: Resolve identity before acquiring the loop lock and print it once; fail before implementation when incomplete.** Remove the Claude co-author recipe from `ship` and state that project commit policy wins.
|
|
107
|
+
- [ ] **Step 5: Run focused/full tests; commit as `feat(git): enforce human-owned commit identity`.**
|
|
108
|
+
|
|
109
|
+
### Task 6: First-class security audit gate
|
|
110
|
+
|
|
111
|
+
**Files:**
|
|
112
|
+
- Create: `src/audit/types.ts`
|
|
113
|
+
- Create: `src/audit/dependencies.ts`
|
|
114
|
+
- Create: `src/audit/secrets.ts`
|
|
115
|
+
- Create: `src/audit/changes.ts`
|
|
116
|
+
- Create: `src/audit/command.ts`
|
|
117
|
+
- Modify: `src/retrofit/config.ts`
|
|
118
|
+
- Modify: `src/loop/loop.ts`
|
|
119
|
+
- Modify: `src/loop/reporter.ts`
|
|
120
|
+
- Modify: `src/cli.ts`
|
|
121
|
+
- Create: `tests/audit/command.test.ts`
|
|
122
|
+
- Create: `tests/audit/secrets.test.ts`
|
|
123
|
+
- Modify: `tests/loop/loop.test.ts`
|
|
124
|
+
|
|
125
|
+
- [ ] **Step 1: Write failing tests** for stable finding schema, high-confidence secret patterns, dependency command resolution, sensitive changed paths, suppression reasons, human/JSON output, and loop blocking.
|
|
126
|
+
- [ ] **Step 2: Run audit tests** and confirm module-not-found failures.
|
|
127
|
+
- [ ] **Step 3: Implement `runAudit` with deterministic injected command/Git seams.** Findings contain `ruleId`, `severity`, `message`, `file`, and optional `line`; exit 0 means no unsuppressed blocking findings, 1 means findings, 2 means not runnable.
|
|
128
|
+
- [ ] **Step 4: Add `yoke audit`, `--json`, `audit.enabled`, `audit.command`, and versioned suppressions.** Run it after verify/perf and before review.
|
|
129
|
+
- [ ] **Step 5: Run focused/full tests and `npm audit`; commit as `feat(audit): add dependency secret and diff security gate`.**
|
|
130
|
+
|
|
131
|
+
### Task 7: PRD dependency graph and scheduler
|
|
132
|
+
|
|
133
|
+
**Files:**
|
|
134
|
+
- Modify: `src/loop/prd.ts`
|
|
135
|
+
- Modify: `src/prd/command.ts`
|
|
136
|
+
- Modify: `canon/loop/prd.schema.md`
|
|
137
|
+
- Modify: `canon/skills/authoring-prd/SKILL.md`
|
|
138
|
+
- Modify: `tests/loop/prd.test.ts`
|
|
139
|
+
- Modify: `tests/prd/command.test.ts`
|
|
140
|
+
- Create: `tests/loop/scheduler.test.ts`
|
|
141
|
+
- Create: `src/loop/scheduler.ts`
|
|
142
|
+
|
|
143
|
+
- [ ] **Step 1: Write failing schema tests** for optional `needs`, `area`, and `agent`, plus unknown dependency, self-dependency, duplicate ID, and cycle diagnostics.
|
|
144
|
+
- [ ] **Step 2: Write failing scheduler tests** for ready-set priority, dependency blocking, area exclusion, and affinity.
|
|
145
|
+
- [ ] **Step 3: Run focused tests** and confirm new fields/validation are absent.
|
|
146
|
+
- [ ] **Step 4: Extend `StorySchema`, implement `validateDependencies` and `readyStories`, and update PRD drafting guidance.** Missing optional fields normalize to dependency-free serial behavior.
|
|
147
|
+
- [ ] **Step 5: Run focused/full tests; commit as `feat(prd): add dependency graph and ready scheduler`.**
|
|
148
|
+
|
|
149
|
+
### Task 8: Claims, merge queue, and bounded parallel execution
|
|
150
|
+
|
|
151
|
+
**Files:**
|
|
152
|
+
- Create: `src/loop/claims.ts`
|
|
153
|
+
- Create: `src/loop/merge-queue.ts`
|
|
154
|
+
- Create: `src/loop/parallel.ts`
|
|
155
|
+
- Modify: `src/loop/git.ts`
|
|
156
|
+
- Modify: `src/loop/gates.ts`
|
|
157
|
+
- Modify: `src/loop/run-command.ts`
|
|
158
|
+
- Modify: `src/loop/cleanup.ts`
|
|
159
|
+
- Modify: `src/loop/reporter.ts`
|
|
160
|
+
- Modify: `src/cli.ts`
|
|
161
|
+
- Create: `tests/loop/claims.test.ts`
|
|
162
|
+
- Create: `tests/loop/merge-queue.test.ts`
|
|
163
|
+
- Create: `tests/loop/parallel.test.ts`
|
|
164
|
+
- Modify: `tests/loop/git.test.ts`
|
|
165
|
+
- Modify: `tests/loop/cleanup.test.ts`
|
|
166
|
+
|
|
167
|
+
- [ ] **Step 1: Write failing claim tests** for atomic acquisition, stale takeover, dispatcher ownership, and scoped cleanup.
|
|
168
|
+
- [ ] **Step 2: Write failing merge-queue tests** for FIFO order, rebase, integrated-tree re-verification, conflict retry, identity-preserving commit, and never persisting `passes: true` on failure.
|
|
169
|
+
- [ ] **Step 3: Write failing dispatcher tests** for max concurrency, dependencies, areas, affinity, pause, iteration cap, and `--parallel=1` equivalence.
|
|
170
|
+
- [ ] **Step 4: Implement claim and merge-queue modules with injectable clocks, workers, Git, and gates.** Add Git rebase/base SHA operations without weakening existing fast-forward integrity.
|
|
171
|
+
- [ ] **Step 5: Implement `runParallelLoop` and CLI `--parallel=N`; force worktree isolation for `N > 1`.** Emit worker/queue NDJSON events and retain the dispatcher lock.
|
|
172
|
+
- [ ] **Step 6: Extend cleanup with explicit provider-worktree reporting/removal flag.** Default cleanup remains project-scoped and non-destructive.
|
|
173
|
+
- [ ] **Step 7: Run focused/full tests; commit as `feat(loop): add dependency-aware parallel merge queue`.**
|
|
174
|
+
|
|
175
|
+
### Task 9: Cross-runner benchmark evidence
|
|
176
|
+
|
|
177
|
+
**Files:**
|
|
178
|
+
- Modify: `bench/run.mjs`
|
|
179
|
+
- Create: `bench/run-matrix.mjs`
|
|
180
|
+
- Modify: `bench/README.md`
|
|
181
|
+
- Modify: `bench/RESULTS.md`
|
|
182
|
+
- Create: `tests/bench/result-schema.test.ts`
|
|
183
|
+
|
|
184
|
+
- [ ] **Step 1: Write a failing schema test** requiring fixture version, permission profile, model/usage availability, verdict, conflicts, wall time, iterations, final tests, and sample label.
|
|
185
|
+
- [ ] **Step 2: Run the focused test** and confirm existing result objects are incomplete.
|
|
186
|
+
- [ ] **Step 3: Extend the harness and add a sequential matrix launcher** that records unavailable/auth failures as honest result rows without treating them as quality measurements.
|
|
187
|
+
- [ ] **Step 4: Build Yoke and run available authenticated provider benchmarks.** Never invent Codex/Gemini results; record the exact blocker where credentials or CLI support are absent.
|
|
188
|
+
- [ ] **Step 5: Run benchmark schema/full tests; commit as `bench: add cross-runner telemetry matrix`.**
|
|
189
|
+
|
|
190
|
+
### Task 10: Documentation, migration, package, and publication
|
|
191
|
+
|
|
192
|
+
**Files:**
|
|
193
|
+
- Modify: `README.md`
|
|
194
|
+
- Modify: `CHANGELOG.md`
|
|
195
|
+
- Create: `docs/MIGRATING-TO-1.0.md`
|
|
196
|
+
- Create: `TODOS.md`
|
|
197
|
+
- Modify: `CONTRIBUTING.md`
|
|
198
|
+
- Modify: `.github/workflows/ci.yml`
|
|
199
|
+
|
|
200
|
+
- [ ] **Step 1: Update README commands, architecture, agent artifact table, safety model, review contract, parallel loop, audit gate, benchmark caveats, and generated metadata markers.** Remove completed roadmap items and link remaining work to `TODOS.md`.
|
|
201
|
+
- [ ] **Step 2: Add migration and changelog entries** covering safe permissions, independent verdicts, commit identity, PRD fields, and new CLI flags.
|
|
202
|
+
- [ ] **Step 3: Run `npm run docs:update` followed by `npm run docs:check`; commit as `docs: prepare Yoke 1.0 release`.**
|
|
203
|
+
- [ ] **Step 4: Run fresh full verification:** `npm ci`, `npm run lint`, `npm run build`, `npm test`, `npm run yoke -- validate canon`, `npm audit`, `npm run package:check`, `npm pack`, and tarball install smoke test.
|
|
204
|
+
- [ ] **Step 5: Inspect `git diff`, `git log`, package contents, version, and author/committer identity; ensure the tree is clean and every commit is authored by `HECer <hec_er@web.de>`.**
|
|
205
|
+
- [ ] **Step 6: Push `main` to `origin`, publish `@hecer/yoke@1.0.0`, verify the registry version, and push the `v1.0.0` tag.** If npm requires interactive 2FA, report the exact OTP command boundary without changing package state further.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Yoke 1.0 — hardening, Codex parity, and parallel delivery
|
|
2
|
+
|
|
3
|
+
**Status:** Approved design, ready for implementation planning
|
|
4
|
+
**Release target:** `@hecer/yoke@1.0.0`
|
|
5
|
+
|
|
6
|
+
## Goal
|
|
7
|
+
|
|
8
|
+
Make Yoke's cross-agent promise true at the integration, execution, and evidence layers:
|
|
9
|
+
Codex receives the same reusable methodology as Claude; reviews produce a mechanical verdict;
|
|
10
|
+
autonomous execution is safe by default; commits have an explicit human identity; parallel work
|
|
11
|
+
lands through a verified merge queue; and published claims are generated from reproducible data.
|
|
12
|
+
|
|
13
|
+
## Compatibility contract
|
|
14
|
+
|
|
15
|
+
- Existing `.yoke/config.yaml` files remain valid. New fields are optional and receive safe defaults.
|
|
16
|
+
- The CLI keeps all existing commands and exit codes. New commands and flags are additive.
|
|
17
|
+
- `--unsafe` is an explicit per-run escalation. Existing configurations do not silently gain broader permissions.
|
|
18
|
+
- Existing PRDs without `needs`, `area`, or `agent` behave as serial, dependency-free backlogs.
|
|
19
|
+
- Serial execution remains the default. Parallel execution requires `--parallel=N`, where `N > 1`.
|
|
20
|
+
- A 1.0 migration note documents every behavior whose default becomes safer.
|
|
21
|
+
|
|
22
|
+
## Native Codex integration
|
|
23
|
+
|
|
24
|
+
The Codex retrofit planner copies every canon skill to `.agents/skills/<id>/SKILL.md`, the native
|
|
25
|
+
repository skill location. It generates a directly usable, trusted-project `.codex/config.toml`
|
|
26
|
+
instead of describing it as a global snippet. Codex receives an RTK `PreToolUse` hook through
|
|
27
|
+
`.codex/hooks.json`; `RTK.md` remains as readable fallback guidance and `AGENTS.md` imports it.
|
|
28
|
+
|
|
29
|
+
Yoke also ships a Codex-compatible plugin bundle containing the canon skills, hook definition, and
|
|
30
|
+
MCP declarations. Repository-local custom agents provide narrow implementer, reviewer, security,
|
|
31
|
+
and documentation roles. These are conveniences over the same canon, not a second source of truth.
|
|
32
|
+
|
|
33
|
+
Generated artifacts remain non-destructive: Yoke backs up overwritten files, merges supported
|
|
34
|
+
configuration, and preserves project-owned instruction blocks.
|
|
35
|
+
|
|
36
|
+
## Mechanical review verdicts
|
|
37
|
+
|
|
38
|
+
`--review` resolves the first available agent that differs from the implementer. If no independent
|
|
39
|
+
agent is available, the command fails before implementation unless the caller explicitly requests
|
|
40
|
+
`--allow-self-review`.
|
|
41
|
+
|
|
42
|
+
Reviewers write a versioned JSON verdict to a Yoke-owned temporary path:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"schemaVersion": 1,
|
|
47
|
+
"verdict": "approve",
|
|
48
|
+
"summary": "All acceptance criteria are covered.",
|
|
49
|
+
"findings": []
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Yoke validates the file, rejects missing or malformed verdicts, and blocks on any `reject` verdict.
|
|
54
|
+
The process exit code remains execution telemetry only. Standalone `yoke review` uses the same
|
|
55
|
+
protocol and prints findings in human or JSON form.
|
|
56
|
+
|
|
57
|
+
## Safe runner profiles
|
|
58
|
+
|
|
59
|
+
- `safe` is the default and uses each CLI's non-interactive workspace-write mode without granting
|
|
60
|
+
arbitrary host access where the provider supports it.
|
|
61
|
+
- `unsafe` uses full-bypass flags and requires `--unsafe` or `runner.permissions: unsafe`.
|
|
62
|
+
- `read-only` is available for reviewer and audit roles.
|
|
63
|
+
|
|
64
|
+
The effective runner, model when reported, permission profile, working directory, and network mode
|
|
65
|
+
are emitted at run start. Yoke refuses incompatible combinations instead of silently escalating.
|
|
66
|
+
Worktree isolation is automatic for parallel runs and recommended for serial unsafe runs.
|
|
67
|
+
|
|
68
|
+
## Human-owned commits
|
|
69
|
+
|
|
70
|
+
Configuration accepts:
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
commit:
|
|
74
|
+
authorName: HECer
|
|
75
|
+
authorEmail: hec_er@web.de
|
|
76
|
+
allowCoAuthors: false
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
When absent, Yoke resolves the repository's Git identity and fails clearly if no name or email is
|
|
80
|
+
available. Each commit passes the identity directly to Git. Yoke never adds AI co-author trailers;
|
|
81
|
+
canon skills respect `allowCoAuthors: false`, which is the default.
|
|
82
|
+
|
|
83
|
+
## Dependency-aware parallel loop
|
|
84
|
+
|
|
85
|
+
PRD stories gain optional `needs: string[]`, `area: string`, and
|
|
86
|
+
`agent: claude | codex | gemini`. `yoke prd check` rejects missing dependencies,
|
|
87
|
+
self-dependencies, and cycles. The scheduler runs only ready stories and never runs two stories
|
|
88
|
+
from the same area concurrently.
|
|
89
|
+
|
|
90
|
+
Workers claim stories through project-scoped claim files containing dispatcher ID, PID, base commit,
|
|
91
|
+
and timestamp. Each worker runs implement, verify, performance, and independent review gates in its
|
|
92
|
+
own worktree. Successful workers enter a FIFO merge queue. The integrator rebases onto current HEAD,
|
|
93
|
+
re-runs verification when HEAD moved, fast-forward integrates, updates context and PRD state, and
|
|
94
|
+
commits with the configured human identity. Conflicts or post-rebase failures return the story to the
|
|
95
|
+
open set; they never mark it passed.
|
|
96
|
+
|
|
97
|
+
The dispatcher owns the existing loop lock. Cleanup removes only project-owned claims and processes.
|
|
98
|
+
`--parallel=1` is behaviorally equivalent to the serial isolated loop.
|
|
99
|
+
|
|
100
|
+
## Security gate
|
|
101
|
+
|
|
102
|
+
`yoke audit [dir]` provides exit-code and JSON contracts for dependency auditing, conservative
|
|
103
|
+
tracked-secret detection, sensitive changed-file checks, and an optional project security command.
|
|
104
|
+
Findings have stable rule IDs and severities. Suppressions require a versioned reason and exact rule
|
|
105
|
+
ID. The loop can run audit after verify and before review.
|
|
106
|
+
|
|
107
|
+
## Cross-runner telemetry and benchmarks
|
|
108
|
+
|
|
109
|
+
Provider adapters own invocation, structured event parsing, usage/model extraction, permissions, and
|
|
110
|
+
review transport. Claude keeps stream-json; Codex and Gemini use supported JSON modes where available
|
|
111
|
+
and explicitly report unavailable usage otherwise.
|
|
112
|
+
|
|
113
|
+
Benchmarks record fixture version, runner/model, permission profile, outcome, wall time, token usage,
|
|
114
|
+
iterations, review verdict, conflicts, and final tests. Authenticated live runs stay opt-in and public
|
|
115
|
+
CI uses deterministic fake CLIs. Committed results state sample size and missing credentials honestly.
|
|
116
|
+
|
|
117
|
+
## CI, dependencies, and release truth
|
|
118
|
+
|
|
119
|
+
Vitest and its Vite/PostCSS chain are upgraded until development and production audits are clean. CI
|
|
120
|
+
adds deterministic source checks, build/tests, canon validation, audit policy, documentation drift
|
|
121
|
+
checks, `npm pack --dry-run`, and a tarball install smoke test.
|
|
122
|
+
|
|
123
|
+
A metadata script derives package version, skill count, test count, and supported agents for README
|
|
124
|
+
badges and prose. The canon version follows the package version and the `0.0.0` fallback is removed.
|
|
125
|
+
CHANGELOG and migration documentation explain 1.0 behavior.
|
|
126
|
+
|
|
127
|
+
## Repository hygiene
|
|
128
|
+
|
|
129
|
+
Cleanup detects stale Yoke and provider worktrees but does not remove provider-owned worktrees without
|
|
130
|
+
an explicit flag. Open roadmap work is mirrored into a versioned backlog or GitHub issues so it is
|
|
131
|
+
executable rather than living only in README prose.
|
|
132
|
+
|
|
133
|
+
## Error handling and observability
|
|
134
|
+
|
|
135
|
+
All machine interfaces are schema-versioned. Missing or malformed verdicts, unavailable CLIs,
|
|
136
|
+
unsupported safe modes, stale claims, conflicts, and audit findings preserve evidence and produce
|
|
137
|
+
distinct reasons. NDJSON includes worker, queue, review, security, cost, and commit-identity events.
|
|
138
|
+
No failure path marks a story passed before integrated-tree gates and the commit succeed.
|
|
139
|
+
|
|
140
|
+
## Testing strategy
|
|
141
|
+
|
|
142
|
+
Implementation follows red-green-refactor. Tests cover schema compatibility, generated artifacts,
|
|
143
|
+
review parsing and selection, safe invocations, Git identity, DAG validation, scheduling, claims,
|
|
144
|
+
merge retries, audit rules, telemetry, metadata generation, and CLI exit codes. Temporary Git repos
|
|
145
|
+
exercise commits, worktrees, conflicts, and authorship. Optional authenticated smoke scripts cover
|
|
146
|
+
real CLIs without blocking public CI.
|
|
147
|
+
|
|
148
|
+
Final verification runs the complete test matrix, build, canon validation, audit, documentation check,
|
|
149
|
+
package dry-run, and fresh install smoke test from the generated tarball.
|
|
150
|
+
|
|
151
|
+
## Delivery sequence
|
|
152
|
+
|
|
153
|
+
1. Release truth and dependency baseline.
|
|
154
|
+
2. Codex native artifacts and plugin.
|
|
155
|
+
3. Provider adapters, safe permissions, and telemetry.
|
|
156
|
+
4. Mechanical review verdict and independent reviewer resolution.
|
|
157
|
+
5. Commit identity enforcement.
|
|
158
|
+
6. Security gate.
|
|
159
|
+
7. PRD dependency schema and scheduler.
|
|
160
|
+
8. Claims, workers, and merge queue.
|
|
161
|
+
9. Cross-runner benchmarks and authenticated smoke scripts.
|
|
162
|
+
10. README, migration guide, changelog, version 1.0.0, verification, Git push, npm publish.
|
|
163
|
+
|
|
164
|
+
Each item lands as a focused commit authored only by `HECer <hec_er@web.de>`.
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Yoke command compression for Codex",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "^Bash$",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "node \"$PLUGIN_ROOT/canon/tools/codex-rtk-hook.mjs\"",
|
|
11
|
+
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"node (Join-Path $env:PLUGIN_ROOT 'canon/tools/codex-rtk-hook.mjs')\"",
|
|
12
|
+
"timeout": 5,
|
|
13
|
+
"statusMessage": "Compressing command output with RTK"
|
|
14
|
+
}
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,67 +1,82 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@hecer/yoke",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "One harness, three agents, zero trust in \"done\" — cross-agent coding harness for Claude Code, Codex CLI, and Gemini CLI: one skill canon, mechanical safety gates, an autonomous loop with screenshot/video proofs.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"yoke": "./dist/cli.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"dist",
|
|
11
|
-
"canon",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"README.md",
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
},
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@hecer/yoke",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "One harness, three agents, zero trust in \"done\" — cross-agent coding harness for Claude Code, Codex CLI, and Gemini CLI: one skill canon, mechanical safety gates, an autonomous loop with screenshot/video proofs.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"yoke": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"canon",
|
|
12
|
+
".codex-plugin",
|
|
13
|
+
"agents",
|
|
14
|
+
"hooks",
|
|
15
|
+
"bench/README.md",
|
|
16
|
+
"bench/RESULTS.md",
|
|
17
|
+
"bench/result-schema.mjs",
|
|
18
|
+
"bench/run.mjs",
|
|
19
|
+
"bench/run-matrix.mjs",
|
|
20
|
+
"bench/fixtures",
|
|
21
|
+
"bench/results",
|
|
22
|
+
"docs",
|
|
23
|
+
"CHANGELOG.md",
|
|
24
|
+
"TODOS.md",
|
|
25
|
+
"README.md",
|
|
26
|
+
"LICENSE"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/HECer/yoke.git"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/HECer/yoke#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/HECer/yoke/issues"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"claude-code",
|
|
41
|
+
"codex",
|
|
42
|
+
"gemini-cli",
|
|
43
|
+
"agents",
|
|
44
|
+
"agentic-coding",
|
|
45
|
+
"harness",
|
|
46
|
+
"autonomous",
|
|
47
|
+
"ralph-loop",
|
|
48
|
+
"code-review",
|
|
49
|
+
"skills",
|
|
50
|
+
"agents-md",
|
|
51
|
+
"tdd",
|
|
52
|
+
"claude-plugin",
|
|
53
|
+
"claude-code-plugin",
|
|
54
|
+
"gemini-cli-extension"
|
|
55
|
+
],
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsc",
|
|
62
|
+
"lint": "tsc --noEmit",
|
|
63
|
+
"test": "vitest run",
|
|
64
|
+
"docs:check": "node scripts/release-metadata.mjs --check",
|
|
65
|
+
"docs:update": "node scripts/release-metadata.mjs --write",
|
|
66
|
+
"audit:ci": "npm audit --audit-level=high",
|
|
67
|
+
"package:check": "npm pack --dry-run",
|
|
68
|
+
"yoke": "tsx src/cli.ts",
|
|
69
|
+
"prepublishOnly": "npm run lint && npm run build && vitest run && npm run docs:check && npm run package:check"
|
|
70
|
+
},
|
|
71
|
+
"dependencies": {
|
|
72
|
+
"yaml": "^2.5.0",
|
|
73
|
+
"zod": "^3.23.8"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@types/node": "^22.7.0",
|
|
77
|
+
"smol-toml": "^1.7.0",
|
|
78
|
+
"tsx": "^4.19.1",
|
|
79
|
+
"typescript": "^5.6.2",
|
|
80
|
+
"vitest": "^4.1.10"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
## 2026-07-09 — STORY-1: slugify(text): URL-safe slugs
|
|
3
|
-
claude implemented STORY-1
|
|
4
|
-
|
|
5
|
-
## 2026-07-09 — STORY-2: truncate(text, max): word-boundary truncation with ellipsis
|
|
6
|
-
claude implemented STORY-2
|
|
7
|
-
|
|
8
|
-
## 2026-07-09 — STORY-3: titleCase(text): English title casing
|
|
9
|
-
claude implemented STORY-3
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
- id: STORY-1
|
|
2
|
-
title: "slugify(text): URL-safe slugs"
|
|
3
|
-
priority: 1
|
|
4
|
-
acceptance:
|
|
5
|
-
- Export `slugify(text)` from src/index.mjs
|
|
6
|
-
- Lowercases input and joins words with single dashes
|
|
7
|
-
- "Strips characters that are not alphanumeric, dash, or space (apostrophes
|
|
8
|
-
vanish: \"What's Up, Doc?\" -> \"whats-up-doc\")"
|
|
9
|
-
- Collapses runs of spaces/dashes into one dash; trims leading/trailing
|
|
10
|
-
dashes
|
|
11
|
-
- Input with no usable characters returns the empty string
|
|
12
|
-
- node bench-verify.mjs exits 0
|
|
13
|
-
passes: true
|
|
14
|
-
- id: STORY-2
|
|
15
|
-
title: "truncate(text, max): word-boundary truncation with ellipsis"
|
|
16
|
-
priority: 2
|
|
17
|
-
acceptance:
|
|
18
|
-
- Export `truncate(text, max)` from src/index.mjs
|
|
19
|
-
- Strings with length <= max are returned unchanged
|
|
20
|
-
- Longer strings are cut at a word boundary and end with the single
|
|
21
|
-
character … (U+2026); result length never exceeds max
|
|
22
|
-
- If even the first word does not fit, hard-cut mid-word so the result
|
|
23
|
-
(incl. …) has exactly max characters
|
|
24
|
-
- max < 1 throws RangeError
|
|
25
|
-
- node bench-verify.mjs exits 0
|
|
26
|
-
passes: true
|
|
27
|
-
- id: STORY-3
|
|
28
|
-
title: "titleCase(text): English title casing"
|
|
29
|
-
priority: 3
|
|
30
|
-
acceptance:
|
|
31
|
-
- Export `titleCase(text)` from src/index.mjs
|
|
32
|
-
- Capitalizes the first letter of each significant word; rest of each word
|
|
33
|
-
lowercased (handles ALL-CAPS input)
|
|
34
|
-
- Small words (a, an, the, and, but, or, for, nor, of, on, in, to, at, by,
|
|
35
|
-
up) stay lowercase mid-title
|
|
36
|
-
- The first and the last word are always capitalized, even if small
|
|
37
|
-
- node bench-verify.mjs exits 0
|
|
38
|
-
passes: true
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Cumulative verify: the loop sets YOKE_STORY (e.g. STORY-2); we run the test
|
|
2
|
-
// files for that story AND all earlier ones, so later stories can't break
|
|
3
|
-
// earlier work. Without YOKE_STORY (final quality check), all tests run.
|
|
4
|
-
import { spawnSync } from 'node:child_process'
|
|
5
|
-
|
|
6
|
-
const TOTAL = 3
|
|
7
|
-
const story = process.env.YOKE_STORY
|
|
8
|
-
const n = story ? Number(story.split('-')[1]) : TOTAL
|
|
9
|
-
const upTo = Number.isFinite(n) && n >= 1 && n <= TOTAL ? n : TOTAL
|
|
10
|
-
|
|
11
|
-
const files = []
|
|
12
|
-
for (let i = 1; i <= upTo; i++) files.push(`tests/STORY-${i}.test.mjs`)
|
|
13
|
-
|
|
14
|
-
const r = spawnSync(process.execPath, ['--test', ...files], { stdio: 'inherit' })
|
|
15
|
-
process.exit(r.status ?? 1)
|