Replace 960-line bash script with ~680-line Python module that leans on
pyyaml and jsonschema instead of shelling to yq/jq/awk/sed/envsubst for every
field. Ecosystem dependencies pinned through the existing flake pythonEnv.
Motivation: the generator had outgrown bash. Recent bugs (awk frontmatter
state machine eating markdown ---, envsubst variable scope, shell quoting in
nested heredocs, multi-section rule surgery) were all classic bash pitfalls
that don't exist in Python.
Design notes:
- Uses pyyaml for TEAM.yaml / SETTINGS.yaml parsing.
- Uses jsonschema to validate both inside the generator (previously only in
flake.nix's embedded Python block).
- Does NOT use python-frontmatter because its content-stripping drops
leading blank lines that matter for byte-level parity with bash output.
Replaced with a 6-line fence-split that preserves whitespace exactly.
- Does NOT use tomli-w because it can't emit multiline-basic-string
("\"\"\"...\"\"\"") literals — it would escape every newline in the
developer_instructions body onto a single line, destroying readability.
Codex TOML output is hand-built with a documented comment.
- Opencode skill pool now symlinks per-skill based on applies_to instead
of a blanket symlink, honoring TEAM.yaml's skill filtering.
Verified: snapshotted generated outputs before the port and diffed after.
All of claude/, codex/, opencode/ are byte-identical to baseline except
claude/settings.json, which now uses json.dumps(indent=2) multi-line arrays
instead of hand-built compact arrays — confirmed semantically identical via
json.load comparison.
flake.nix, install.sh, README.md, .gitignore updated to reference
generate.py instead of generate.sh. generate.sh deleted.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Drop rules/02-responses.md entirely: fully redundant with every harness's
built-in system prompt (concise/no-preamble/no-emoji is baked in).
- Trim 04-tools.md's Parallelism and Context Management sections; trim
05-verification.md's "run tests" bullet. All covered by harness defaults.
- Scope 01-session.md to claude only (memory/ hierarchy is Claude-specific).
- Update schemas/team.schema.json const-pin to match the new rules.order.
- Strip vestigial Claude-style YAML frontmatter from agents/*.md sources
(extract_body was already discarding it; TEAM.yaml is the real source).
- Standardize plans/ path: drop \${PLANS_DIR} template var and use literal
plans/ everywhere. Claude/codex/opencode now share one plans convention.
- Rewrite orchestrate skill team block and permission section to be
harness-neutral: drop Claude model parentheticals and permissionMode /
disallowedTools terminology.
- Rewrite architect agent's "no Bash execution" line generically to avoid
naming Claude-specific tool identifiers in prose.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- opus → gpt-5.4, sonnet → gpt-5.3-codex, haiku → gpt-5.1-codex-mini
- effort max → extra high (was xhigh)
- config.toml default model → gpt-5.3-codex
- README model mapping table updated
Replace generate-codex.sh with unified generate.sh that produces both
claude/ and codex/ output from template source files.
Agent bodies use ${PLANS_DIR}, ${WEB_SEARCH}, ${SEARCH_TOOLS} placeholders
expanded per-target via envsubst. Skills and rules made tool-agnostic
(no Claude tool names or .claude/ paths). Orchestrate skill stays
Claude-only.
install.sh now symlinks from claude/agents/ instead of agents/ directly.
flake.nix adds gettext (envsubst) to devShell.
- reviewer, auditor: add qa-checklist to skills (both produce envelopes)
- worker-protocol: annotate ac_coverage as optional in envelope template
- message-schema: document that security_findings.high is non-blocking
- qa-checklist: reframe plan_result has_blockers as intent confirmation
- CLAUDE.md: add missing message-schema and project to skill list
- debugger, documenter: add qa-checklist to skills (worker-protocol references it)
- message-schema: make moderate_count/minor_count required on review_verdict,
make has_blockers required on plan_result, remove dangling format field
- orchestrate: split blocked routing by type (plan_result vs worker_submission)
- worker-protocol: remove stale migration note about freetext RFR
- qa-checklist: add plan_result has_blockers hard rule
- architect: remove dangling format field from plan_result envelope
- install.sh: replace unreachable $? check with `if !` pattern (set -e
exits before the check runs on Windows mklink failure)
- settings.json: remove fragile Bash deny patterns that can't match across
path separators; broaden .env denies to recursive **/.env with Read/Write/Edit
- worker-protocol: align QA instruction with qa-checklist — qa_check goes in
frontmatter envelope, not as a prose line
- Split monolithic CLAUDE.md into 7 focused rule files in rules/
- Remove agent-team specific content from global rules (subagent cost,
model defaults, tier shortcuts) — already covered by orchestrate skill
- Add "prefer summaries over verbatim output" to orchestrate Step 8
- Update install.sh to symlink rules/ directory
- Trim CLAUDE.md to a minimal pointer since rules auto-load
- Replace command-specific Bash denies (cat/less) with broad glob
patterns that catch any command referencing .ssh, .aws, .gnupg, .env
- Add Write/Edit deny rules for ~/.ssh, ~/.aws, ~/.gnupg to prevent
writes, not just reads
- Replace "Karen/Verification" with "reviewer/auditor" in worker-protocol
- Reframe parallel dispatch rationale from false "~10% token cost" (only
applies to fork agents with identical prefixes) to accurate wall-clock
latency savings
- Add Permission model section documenting that permissionMode is
overridden when parent runs in acceptEdits mode; disallowedTools is
the actual safety boundary
- Create .claude/memory/ as canonical project memory location
- Add MEMORY.md index and first entry: TODO for inter-agent JSON schema
- Document project memory convention in CLAUDE.md (path, format, commit policy)