Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d9f3a2d
docs(v-epic): spec for Epic Autonomous 'marathon' mode
copeus Jul 12, 2026
fa65488
docs(v-epic): add Blocker Ledger + blocked_external disposition to ma…
copeus Jul 12, 2026
c04ff76
docs(v-epic): converge marathon spec against 4 independent reviews
copeus Jul 12, 2026
e538e1c
docs(v-epic): converge marathon spec round 2 (Codex Sol R2 findings)
copeus Jul 12, 2026
550b035
docs(v-epic): PHASE the spec — v2.10 marathon (no watcher) + v2.11 de…
copeus Jul 12, 2026
451b917
docs(v-epic): fold Codex Sol R4 contract-completeness findings into v…
copeus Jul 12, 2026
ff754fb
docs(v-epic): implementation plan for v2.10 marathon (A->B->C->D)
copeus Jul 12, 2026
9ba1dc2
docs(v-epic): fold Codex Sol plan-review into the plan (runtime-contr…
copeus Jul 12, 2026
15df57b
feat(v-epic): Unit A — marathon core contract in epic-state.py (v2.10)
copeus Jul 12, 2026
f3d11cc
feat(v-epic): Unit B — cross-model arbiter panel (Codex+Claude) (v2.10)
copeus Jul 12, 2026
7ed6d88
feat(v-epic): Unit A follow-up — human marathon-resume commands (v2.10)
copeus Jul 12, 2026
9957f7a
feat(v-epic): Unit C — marathon driver wiring + reviewer gate (v2.10)
copeus Jul 12, 2026
6c1be86
release(v-epic): Unit D — v2.10.0 marathon docs + CI + version bump
copeus Jul 12, 2026
6cd3112
fix(v-epic): crash-safe marathon resume — disposition routing + durab…
copeus Jul 12, 2026
c55beae
fix(v-epic): wire crash-safe resume into the marathon driver (v2.10)
copeus Jul 12, 2026
660be1f
fix(v-epic): attempt-bind dispositions + atomic audit-failed (v2.10 r…
copeus Jul 13, 2026
33bb4d8
fix(v-epic): idempotent --resume-challenge for crash-safe arbitration…
copeus Jul 13, 2026
918aac2
fix(v-epic): wire crash-safe arbitration + audit + reconcile into dri…
copeus Jul 13, 2026
cf96441
fix(v-epic): needs_blocker_recording routing for crash-safe blocked_e…
copeus Jul 13, 2026
5d1b187
fix(v-epic): --resume-challenge probes the audit for in_progress reco…
copeus Jul 13, 2026
c58e172
fix(v-epic): halt-page recovery through sample handler + needs_blocke…
copeus Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{
"name": "superpowers-v",
"description": "Compound V for Superpowers: triple parallel pre-flight (code archaeology + domain-expert + Context7 library validator), disjoint partitioning, manifest-driven multi-backend dispatch (Claude + Codex + Antigravity + Cursor), git-diff scope enforcement, crash-resumable runs, adaptive tier-based routing, epic mode, research-grounded brainstorming (gated pre-brainstorm recon + batched elicitation), V-memory local-first semantic+lexical recall over docs/superpowers (opt-in pure-python embeddings + a deterministic recall→action bridge), and batched parallel dispatch (Opus default, narrow Sonnet exception)",
"version": "2.9.0",
"version": "2.10.0",
"source": "./",
"author": {
"name": "Oleg",
Expand Down
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "superpowers-v",
"description": "Compound V for Superpowers: triple parallel pre-flight (code archaeology + domain-expert advisor + library/doc validator via Context7), disjoint file partitioning, manifest-driven multi-backend dispatch (Claude + headless Codex + Antigravity + Cursor workers), git-diff scope enforcement, crash-resumable runs, adaptive tier-based routing, epic mode for multi-feature builds, V-memory local-first semantic+lexical recall over docs/superpowers (opt-in pure-python embeddings + a deterministic recall\u2192action bridge), and batched parallel dispatch (Opus default, Sonnet for narrow junior-task carve-out), plus /v:onboard — a project-onboarding command that builds a citation-verified knowledge base + AGENTS.md/CLAUDE.md bridge behind a human gate. Auto-intercepts four transitions: pre-brainstorm recon \u2192 brainstorming \u2192 writing-plans \u2192 execution.",
"version": "2.9.0",
"version": "2.10.0",
"author": {
"name": "Oleg",
"email": "copeus@gmail.com"
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,18 @@ jobs:
done < <(find . -name "*.md" -not -path "./node_modules/*" -not -path "./.git/*" -print0)
[ "$fail" = "0" ] || exit 1
echo "✅ All intra-plugin .md links resolve"

# Marathon-mode (v2.10) selftests run under Python 3.9 — the documented floor for
# scripts/compound-v-epic-state.py and scripts/compound-v-epic-arbiter.py (both pure
# stdlib, no PyYAML dependency). Installed LAST in the job so re-pointing PATH at a
# 3.9 interpreter can never affect the earlier PyYAML-dependent steps above.
- name: Set up Python 3.9 (marathon selftest floor)
uses: actions/setup-python@v5
with:
python-version: '3.9'

- name: Run epic-state.py selftest (Python 3.9 floor)
run: python3 scripts/compound-v-epic-state.py --selftest

- name: Run epic-arbiter.py selftest (Python 3.9 floor)
run: python3 scripts/compound-v-epic-arbiter.py --selftest
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ All notable changes to **superpowers-v (Compound V)** are documented here.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project uses semantic versioning.

## [2.10.0] — 2026-07-13

### Added — Marathon Loop (opt-in autonomous `/v:epic`, PHASED scope)

An opt-in **marathon** stance for `/v:epic`: instead of stopping at every feature checkpoint, the epic can chew through the whole runnable feature DAG in one invocation. The default `checkpoint` epic is **behaviorally unchanged** — marathon is chosen only at `--init` time and cannot be flipped onto an existing checkpoint epic. Scope was deliberately PHASED after three Codex Sol `xhigh` review rounds converged that every *critical* concurrency finding traced to auto-resurrection (a two-tier watcher reviving the epic while you're away); removing that from v2.10 makes the marathon single-process and the whole class of concurrency criticals disappears. See `docs/superpowers/specs/2026-07-12-epic-autonomous-mode-design.md` for the full scope decision and the deferred v2.11 sketch.

- **Marathon Loop + DAG-autonomous routing** (`scripts/compound-v-epic-state.py`): a marathon-only `autonomy` state block, `--next --autonomous` (a separate, read-only routing function from the default `--next` — byte-identical default behavior preserved) that routes on deterministic DAG reachability, so an abandoned or blocked feature removes only its *transitive dependents*, never its independents. `attempts` tracking, `--can-retry`, `--record-disposition`, `--record-final-review`. **Terminal states:** `done` (all features done **and** a persisted `final_review.status=="passed"` — never on feature-completion alone), `blocked_needing_human` (a tripped breaker, a `halt_epic` verdict, or exhausted reachable work), `running_with_failures` (non-terminal). `done_with_blockers` is defined but structurally unreachable in v2.10 (needs a 2nd confirming external model family — deferred to v2.11).
- **Cross-model Arbiter Panel** (`scripts/compound-v-epic-arbiter.py`, new): classifies a feature FAILURE via a two-phase, **challenge-bound** API — `--prepare` issues a bounded Claude ballot-task prompt tied to `{epic_id,feature,attempt,challenge_id}` (an HMAC-keyed, per-epic challenge secret; a mismatched/replayed/stale challenge is dropped before any model call), then `--classify` polls Codex (real sandbox, read-only, through the timeout supervisor, evidence size-capped and secret-redacted before egress) and validates a driver-supplied Claude ballot, aggregating both with a complete, deterministic truth table. **Family-diverse aggregation:** ballots collapse one-per-family (`gpt`/`gemini`/`claude`/`grok`/`unknown`); a parse-failed or errored ballot is dropped and logged, never fabricated as a vote; empty or tied → conservative `halt_feature`; `retry_fix` past the per-feature retry cap is masked to `halt_feature`. Antigravity/Cursor are excluded from arbitration (no kernel write-confinement) — implementation workers only, never advisors. **Fail-closed secret redaction** before any external-model egress (labelled tokens, auth headers, private keys, URL credentials, multiline/unclosed-quote secrets — omits the suspect evidence rather than risk a half-redacted leak). **O_NOFOLLOW evidence containment**: every untrusted path under the arbiter's audit directory is opened via dir-fd + `O_NOFOLLOW` (TOCTOU-safe — never validate-a-name-then-reopen-it), atomic tmp+rename writes, capped/rotated audit JSONs so an all-night run can't fill the disk. Every ballot + resolved family + aggregation reason is frozen to `docs/superpowers/execution/epics/<epic-id>/arbiter/<feature>-<attempt>.json`.
- **Blocker Ledger** (`scripts/compound-v-epic-state.py`): "do everything you can" — finish everything reachable, isolate only the genuinely impossible, escalate with proof, never halt the rest. A `blocked_external` disposition marks a feature `blocked` (ledger entry) without halting the epic; `--next --autonomous` skips it and routes around only its transitive dependents. **v2.10 blockers are always SUSPECTED** — `--blocker-confirmed true` is hard-rejected everywhere it could be set; CONFIRMED (`≥2` distinct known external model families agreeing) is structurally unreachable on a Codex+Claude-only panel and is deferred to v2.11 alongside a second safe external family and the `done_with_blockers` terminal.
- **Global circuit breakers + human resume** (`scripts/compound-v-epic-state.py`): `total_attempts`, `no_progress_cycles` (a full autonomous pass that advances `done` by zero), and wall-clock hours since `autonomy.started_at` — counts and hours only, **never a fabricated cost**. `--breaker-check` is read-only; `--trip-breaker` atomically parks the epic at `blocked_needing_human`. Re-checked before every feature *and* before every model call (arbiter, sample-audit, final review) — an honest, not a hard real-time, guarantee. **Human recovery, never automatic:** `--clear-breaker` (`--reset-wall-clock`, `--set-max-total-attempts N`) re-arms a tripped breaker; `--clear-disposition` clears a sticky `halt_epic` verdict — both followed by the human re-running `/v:epic <epic-id>`, which is re-entrant and resumes the marathon from `epic-state.json`.
- **PASS integrity — anti-reward-hack gate** (`agents/spec-reviewer.md` §2.5, `commands/v-epic.md`): a marathon SUCCESS is not blindly trusted. The reviewer contract gained a deterministic "did this diff weaken its own tests/scorers to pass?" check; the marathon driver **sample-audits** a deterministic fraction of PASSes (every 3rd `done` this invocation, plus always the first) with a fresh adversarial re-review, and gates terminal `done` on a **final cross-feature re-verification** (`--record-final-review`) over the whole accumulated diff since `autonomy.start_sha`.
- **CI**: `.github/workflows/validate.yml` now sets up Python 3.9 (the documented marathon-scripts floor) and runs both new `--selftest` suites (`compound-v-epic-state.py`, `compound-v-epic-arbiter.py`) as a required job — a red selftest now fails CI.

### The honest v2.10 boundary — no auto-resurrection

Marathon is opt-in; the default epic still checkpoints. "Survives a fall" means two things, both true today and neither overclaimed: **in-session**, the loop continues past a soft per-feature error to the next runnable feature automatically, within the one live `/v:epic` invocation. **After a hard death** (quota, closed terminal, crashed machine), a **human re-invokes `/v:epic <epic-id>`**, which resumes from the committed `epic-state.json`. There is **no automatic resurrection while you're away** in v2.10 — nothing wakes the epic back up on its own. That is the deferred **v2.11** auto-watcher (Execution Lease + Two-Tier Watcher + generation-fenced execution across the dispatcher/worker/merge-back/commit layer) — its own spec, its own review pass, because it needs correct distributed concurrency that the v2.10 single-process design deliberately avoids. No fabricated cost/token metrics anywhere in either stance.

### Provenance
Converged from four independent pre-implementation reviews plus three Codex Sol `xhigh` adversarial rounds on 2026-07-12 that drove the phased-scope decision. Built across four disjoint units (state spine → arbiter panel → driver/reviewer wiring → this docs/CI/release unit) and cross-model reviewed by **Codex gpt-5.6-sol**.

## [2.9.0] — 2026-07-12

### Added — Pre-Evaluation stage + proportionate fast-path
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ The fastest way to *get* what this plugin does. Three gamified episodes — **De

- **Epic mode** — feed it a whole PRD with many tasks and it builds feature by feature, in dependency order, on one branch. By default it checkpoints after each feature so you can review (raise the budget to let it run longer).

- **Marathon Loop** 🧪 (opt-in, v2.10) — instead of stopping at every checkpoint, `/v:epic` can chew through the whole runnable feature DAG in one invocation. A failed feature goes to a cross-model **Arbiter Panel** (Codex + a fresh adversarial Claude) that decides retry / abandon / halt-the-epic; a suspected external blocker (an upstream API with no data, say) goes into a **Blocker Ledger** and gets isolated instead of halting the rest of the build; **global circuit breakers** (total attempts, wall-clock hours, no-progress cycles) keep the whole thing bounded. Honest limit: "survives a fall" means the loop keeps going automatically *within that one live session*, and a **human re-invoking `/v:epic`** after a hard death (closed terminal, crashed machine, quota) resumes it from where it stopped. There is **no automatic resurrection while you're away** — nothing wakes the epic back up on its own. That's a deferred, separate feature. Default epic mode is unchanged; marathon is opt-in per epic at `/v:epic` start time.

- **V-memory** — project memory that builds up as you work: decisions made, bugs fixed, things that failed. It surfaces the relevant bits when you plan or review.

- **Research-grounded brainstorming** 🧪 — before a brainstorm on an unfamiliar topic, a gated, bounded recon pass (off by one config key) writes an evidence doc the brainstorm reads first. And when the brainstorm has 3+ *independent* clarifying questions, it can batch them into one screen — the Visual Companion form if you've accepted it, else a structured question, else the usual one-at-a-time (dependent questions always stay sequential). Both are description-driven guidance, not hook-enforced.
Expand Down Expand Up @@ -85,6 +87,7 @@ That's it.
- **Antigravity and Cursor are lower-trust** (no kernel sandbox). The scope check catches out-of-bounds writes *after the fact* but can't *prevent* them. For anything sensitive or untrusted, prefer **Codex** — it runs in a real workspace sandbox.
- **Cursor on a Free plan** can only use its `auto` model (named models are paid).
- **Epic mode is bounded by default** — it stops after each feature for a human checkpoint. It is *not* a fire-and-forget overnight build unless you raise the budget.
- **Marathon mode (opt-in) is still not fire-and-forget-overnight.** It removes the per-feature checkpoint and adds an arbiter panel + blocker ledger + global breakers so it can run further unattended in one sitting — but it does not self-revive after a hard death. If the session dies, you re-run `/v:epic <epic-id>` yourself; it resumes from the last committed state. Auto-resurrection while you're away is a deferred, separate feature — not shipped here.
- No daemon, no server, no MCP service, no made-up cost numbers. Everything is small, readable scripts.

---
Expand Down
23 changes: 21 additions & 2 deletions agents/spec-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,21 @@ For each MUST item from Pass 1, find the test that would fail if the requirement

The change must not print, log, or document **token-cost or token-savings numbers that aren't actually measured**, hardcoded baselines (e.g. `baseline = 1000`), fake speedup percentages, or any self-reported "saved N tokens" meter. This is the anti-ruflo charter. Any fabricated/unmeasurable metric → **ISSUE: FABRICATED_METRIC** (file:line + the number). A real, measured value (wall-clock from a timer, a count from `git diff --stat`) is fine; an invented one is not.

### 2.5 — No reward-hacking

Did the diff make a check pass by **weakening the check itself**, instead of making the code actually satisfy it? This matters most in Compound V's own **marathon** stance (`skills/compound-v/epic-mode.md`), where a failure is judged by the arbiter panel and a feature can be retried unattended — a pattern that rewards "make the gate green" over "make the behavior correct" if nobody is watching. Diff every test/spec/scorer file the implementer touched (`git show <sha>` or the merged worktree diff, same as 1.1) against its pre-change version and look for concrete, deterministic evidence:

| Evidence | Example |
|---|---|
| Removed or commented-out assertions | an `assert`/`expect(...).toBe(...)` present before the diff, gone or `// assert(...)` after |
| Deleted or renamed test/spec files with no replacement covering the same behavior | `sequences/api.test.ts` deleted; nothing else asserts that path |
| Loosened numeric thresholds with no spec justification | a score gate `>= 90` changed to `>= 60`, a tolerance widened, a timeout raised to mask a hang |
| Edited the **scorer/grader/checker** itself rather than the implementation | changing what "pass" means instead of making the code satisfy the original bar |
| Newly `.skip`/`xit`/`@pytest.mark.skip`/commented-out test, with no reason tied to the task spec | a previously-running test now skipped in the same diff that claims DONE |
| A previously-propagating exception/assertion now caught and swallowed (silent no-op or a `print` instead of a raise/fail) | a hard failure converted to a soft one with no spec basis |

Any such change → **ISSUE: REWARD_HACK** (file:line + which test/scorer + what changed + why it weakens the gate rather than fixing the code). A genuine, spec-justified relaxation (the task spec itself asked for a looser threshold, or a test was superseded by a *stronger* replacement in the same diff) is not a reward hack — cite the spec line that justifies it before waving this off.

---

## PASS 3 — INTEGRATION (final, run-level — gates DONE)
Expand Down Expand Up @@ -147,6 +162,10 @@ ISSUE: FABRICATED_METRIC (PASS 2)
- scripts/foo.sh:88 prints "saved ~1200 tokens" — not measured, hardcoded
→ Remove; print only measured values (wall-clock, git diff --stat counts)

ISSUE: REWARD_HACK (PASS 2)
- sequences/api.test.ts:41 — assert res.status === 200 loosened to assert res.status < 500
→ Restore the original assertion; fix the handler so it actually returns 200, don't relax the test

ISSUE: BUILD_RED (PASS 3)
- `npm test` fails: 2 failing in sequences/api.test.ts (see excerpt)
→ Fix before DONE
Expand All @@ -159,7 +178,7 @@ ISSUE: ACCEPTANCE_GAP (PASS 3)

APPROVED
PASS 1 SPEC: requirements K/K · audit MUSTs M/M · over-build clean · job acceptance met
PASS 2 QUALITY: code-quality clean · no regression · every MUST has a guard test · no fabricated metrics
PASS 2 QUALITY: code-quality clean · no regression · every MUST has a guard test · no fabricated metrics · no reward-hacking
PASS 3 INTEGRATION: no partition leak · seams hold · build green (evidence: <cmd>) · feature AC J/J met
Scope lock: respected (scope gate PASS, confirmed at seam)
```
Expand All @@ -170,7 +189,7 @@ APPROVED
- DO order the passes: SPEC first, then QUALITY, then (run-level) INTEGRATION. Don't review quality of code that fails spec.
- DO NOT approve with "minor issues, close enough." Compound V policy: if you found an issue, the implementer fixes it before the next pass. No "close enough."
- DO NOT claim the build is green without running it (or observing its output). Evidence before assertion.
- DO NOT skip the over-build check or the fabricated-metric check.
- DO NOT skip the over-build check, the fabricated-metric check, or the reward-hacking check.
- DO NOT propose code or edit files. The implementer fixes; you re-review on the next round.
- DO cite file:line (or the failing command) for every claim.

Expand Down
Loading
Loading