Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ jobs:
run: bash test/smoke.sh
- name: Cross-file invariants
run: bash test/invariants.sh
- name: Codex adapter behavior (no model calls)
run: bash test/codex.sh
- name: ShellCheck
run: |
shellcheck --version >/dev/null 2>&1 || { echo "shellcheck not installed; skipping"; exit 0; }
shellcheck bin/init.sh bin/release.sh test/smoke.sh test/invariants.sh
shellcheck bin/init.sh bin/release.sh test/smoke.sh test/invariants.sh test/codex.sh test/codex-sandbox.sh
for f in templates/scripts/*.tmpl; do
shellcheck --shell=bash "$f"
done
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,43 @@ update workflow. Version bumps mean: **MAJOR** = state-file contract /
role authority / script interface changed; **MINOR** = new template,
script, flag, or role rule; **PATCH** = prose and docs.

## Unreleased

- `[contract]` OpenCode role templates move from the legacy singular
`.opencode/agent/` directory to V2's canonical `.opencode/agents/` path.
Plain bootstrap refuses to create a second role tree beside an unmigrated
one, while stamp-less update recovery can still read either layout.
Migration: `migrations/03-opencode-v2-agents-directory.md`.
- `[safety]` Fresh scaffolds now include `scripts/verify-models.sh`; feature
preflight resolves every OpenCode-dispatched model against the authenticated
live server and verifies that required roles and their ordered permission
rules actually loaded after restarts, upgrades, migrations, or permission
edits. Disk configuration alone is no longer treated as readiness evidence.
- `[contract]` Writable task records, outputs, server credentials, session pins,
and logs move from `.agents/` to `.pipeline/` for both leads. Codex protects
`.agents/` under its default workspace policy; skills remain at
`.agents/skills/`. Migration: `migrations/02-pipeline-directory.md`.
Read-only update triage accepts legacy provenance stamps; a plain bootstrap
refuses an unmigrated runtime rather than silently creating another one.
- `[process]` Codex leads capture exact session IDs through reviewed lifecycle
hooks, pin them per team name, and resume through `codex-lead.sh`. Failed
resumes, missing capture, and concurrent launches stop explicitly. The task
template gains an optional Codex planner thread ID for corrections/recovery.
- `[process]` Added Codex lead/planner model and reasoning flags, defaulting to
inheritance and preserved through the provenance stamp. Supporting delegate,
status-board, and karpathy-guidelines skills are now installed deterministically.
- `[safety]` Codex preflight probes writable state and authenticated OpenCode
access from the active sandbox. The adapter distinguishes workflow consent
from runtime permission approval and preserves task/thread state on failure.
Update consent explicitly covers Codex permissions, execution rules, and hooks.
- `[process]` Added no-model behavioral tests for launcher/hook/preflight and
migration failures, plus an opt-in real Codex sandbox test. CI runs the
behavioral suite. Live model workflow verification remains a documented
manual check; these tests do not claim to establish model-level parity.
- `[docs]` Added `docs/CODEX.md`, migration/recovery guidance, and generalized
lessons about protected instruction directories, exact-session identity,
lifecycle trust, and separate workflow/runtime approvals.

## v0.9.0 — 2026-09-27

- `[safety]` Synced this toolkit's own opencode v2 migration into the
Expand Down
28 changes: 18 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A reusable, project-agnostic version of the planner → implement → review →
test multi-agent pipeline. `bin/init.sh` scaffolds it into any target repo:
Claude or Codex as lead, Claude/Codex planning, OpenCode (any vendor) for
cross-vendor implement/review/test, a state file (`.agents/T-<id>.md`) as the
cross-vendor implement/review/test, a state file (`.pipeline/T-<id>.md`) as the
one handoff surface between roles, and a `delegate` skill that keeps the
orchestrating lead's own context small across a long run.

Expand All @@ -18,12 +18,14 @@ toolkit's own code.

## Commands

No build step, no dependencies, no LLM calls in the test path. Verify a
No build step or package dependencies, no LLM calls in the default test path.
Tests use Bash plus Python's standard library. Verify a
change with the automated smoke run:

```bash
bash test/smoke.sh # scaffolder guarantees + the two structural scripts
bash test/invariants.sh # every load-bearing rule present in every copy
bash test/codex.sh # generated launcher/hooks/preflight, no model calls
```

`smoke.sh` scaffolds into a throwaway directory and asserts the core
Expand Down Expand Up @@ -63,13 +65,14 @@ files are skipped, not clobbered (`render()`'s core guarantee).
| `skills/toolkit-release/` | Conversational release flow: classify commits since the last tag into `[contract]›[safety]›[process]›[docs]`, propose a semver-ish version, get user approval, write the CHANGELOG section, run `bin/release.sh` |
| `test/smoke.sh` | The automated smoke run (see Commands). CI runs it plus shellcheck on every push |
| `test/invariants.sh` | Cross-file rule presence check: one grep per (rule, file) pair over the hand-synced copies. Add a rule = one line in its table |
| `test/codex.sh` | Behavioral checks for the generated launcher, lifecycle hooks, preflight, inheritance, and migration failures, using CLI doubles and no model calls |
| `.github/workflows/ci.yml` | Runs `test/smoke.sh` + shellcheck (`bin/init.sh`, the test, and every `templates/scripts/*.tmpl`) |
| `templates/claude/agents/` | `planner.md.tmpl`, `senior-dev.md.tmpl` — Claude subagent role definitions |
| `templates/claude/commands/` | `feature.md.tmpl` — the `/feature` pipeline command (the lead's own instructions); `toolkit-update.md.tmpl` — the `/toolkit-update` merge command for already-scaffolded projects |
| `templates/codex/` | Root `AGENTS.md`, a project-scoped planner agent, and `feature` / `toolkit-update` skills. Thin Codex lead adapter over the canonical Claude command flow |
| `templates/opencode/agent/` | `builder.md.tmpl`, `reviewer.md.tmpl`, `tester.md.tmpl` — OpenCode role definitions |
| `templates/opencode/agents/` | `builder.md.tmpl`, `reviewer.md.tmpl`, `tester.md.tmpl` — OpenCode role definitions |
| `templates/agents-state/` | `TEMPLATE.md.tmpl` — the `T-<id>` state-file shape every role reads and appends to |
| `templates/scripts/` | `oc.sh.tmpl` (OpenCode CLI wrapper), `team.sh.tmpl` (+ `team-completion.bash.tmpl`; tmux layout), `verify-state.sh.tmpl` (state file) / `verify-spec.sh.tmpl` (spec, before the approval gate) / `promote-findings.sh.tmpl` — all deterministic, no-LLM-call structural checks |
| `templates/scripts/` | `oc.sh.tmpl` (OpenCode CLI wrapper), `team.sh.tmpl` (+ `team-completion.bash.tmpl`; tmux layout), `verify-state.sh.tmpl` (state file) / `verify-spec.sh.tmpl` (spec, before the approval gate) / `verify-models.sh.tmpl` (authenticated live model check) / `promote-findings.sh.tmpl` — all deterministic, no-LLM-call checks |
| `skills/delegate/` | Context-discipline rules for the lead — usable independently of `init.sh` |
| `skills/toolkit-init/` | Thin skill wrapping `bin/init.sh`, for running the scaffold conversationally |
| `skills/dev-team-generator/` | Self-contained, interview-driven alternative to `toolkit-init`: generates the team + flow live for whatever tool(s) are actually available, instead of stamping out `templates/`. Its own `reference/lessons-learned.md` is a generalized, tool-agnostic distillation of this toolkit's hardening history — see the Conventions bullet below |
Expand Down Expand Up @@ -108,7 +111,7 @@ files are skipped, not clobbered (`render()`'s core guarantee).
"report your findings/output to the lead."
- **Keep `templates/` and any applied copy of this toolkit in sync** (any
repo that has scaffolded it, with its own `.claude/` + `.opencode/` +
`.agents/TEMPLATE.md`) when one side gets a
`.pipeline/TEMPLATE.md`) when one side gets a
structural fix — a new state-file field, a new script, a report-back
change. They're meant to be the same mechanism, generic vs. applied.
`test/invariants.sh` covers the state-file contract's two copies; the
Expand Down Expand Up @@ -155,20 +158,20 @@ files are skipped, not clobbered (`render()`'s core guarantee).
destination already exists — if an edit to a `.tmpl` file doesn't show up
after a re-run against an existing target, that's why, not a bug in
`init.sh`. Use `init.sh --update` to see what changed instead.
- `.agents/.needs-customization` is written only when `FRESH_SCAFFOLD` was
- `.pipeline/.needs-customization` is written only when `FRESH_SCAFFOLD` was
true *before* any `render()` call ran (checked via whether
`.claude/commands/feature.md` already existed) — never on `--update`,
and never again once deleted. The provenance stamp
(`.agents/.toolkit-version`) follows the same ordering rule: written
(`.pipeline/.toolkit-version`) follows the same ordering rule: written
exactly once on a fresh scaffold, never by `--update` (that would erase
the baseline it exists to record), rewritten only by an explicit
`--refresh-stamp` after a merge is accepted. If you add a new
marker-gated behavior, keep that "computed once, before any write"
ordering or a later non-fresh `init.sh` run will re-trigger it.
- `templates/opencode/agent/reviewer.md.tmpl` defaults to blanket
- `templates/opencode/agents/reviewer.md.tmpl` defaults to blanket
`edit: deny` / `write: deny`, unlike a project that has since widened its
own copy (e.g. an applied copy's reviewer allows
`.agents/**`). That gap is intentional — see README's "Design decisions"
`.pipeline/**`). That gap is intentional — see README's "Design decisions"
— not drift to fix by copying the widened version back over the
template.
- A permission block that reads correctly in YAML is not proof it's
Expand All @@ -182,8 +185,13 @@ files are skipped, not clobbered (`render()`'s core guarantee).

Actively developed; history in git. The scaffolder's core guarantees are
covered by `test/smoke.sh`, and cross-copy rule presence by
`test/invariants.sh` (CI: both + shellcheck). What's *not*
`test/invariants.sh` (CI: smoke + invariants + Codex behavior + shellcheck). What's *not*
automated: a live end-to-end pipeline run against a real OpenCode server,
and live permission-enforcement verification — those stay manual per
README's "Design decisions". Treat README.md's "Known gaps" and
REVIEW.md's open items as the backlog.

`test/codex.sh` adds behavioral coverage of the generated Codex integration.
`test/codex-sandbox.sh` is an opt-in real CLI sandbox check without model calls.
Live planner discovery and full workflow execution remain manual; do not call
the CLI-double suite an end-to-end model run.
Loading