{
  "markdown": "# eight-eyes\n\n[![CI](https://github.com/AgentBuildersApp/eight-eyes/actions/workflows/test.yml/badge.svg)](https://github.com/AgentBuildersApp/eight-eyes/actions/workflows/test.yml)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n[![Version](https://img.shields.io/badge/version-5.0.0--alpha-orange.svg)](VERSION)\n[![stdlib only](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](#requirements)\n\n![eight-eyes](docs/images/header.png)\n\n> AI agents agree with each other. That's the problem.\n\n### The Failure Nobody Talks About\n\nYou ask an AI agent to review code it just wrote. It says *\"looks good.\"* You ask a second agent. It reads the first agent's summary, anchors on the same framing, and also says *\"looks good.\"*\n\nMeanwhile:\n\n```\n  jwt.decode(token, public_key, algorithms=[\"HS256\"])\n  #                 ^^^^^^^^^^              ^^^^^^^\n  #  RSA public key used as HMAC secret → attacker forges any token\n  #  CVE-2016-10555 — sitting in plain sight\n```\n\n**Nobody caught it** because every reviewer saw the same narrative, used the same tools, and had the same incentives. This is how AI agents fail — not by crashing, but by agreeing.\n\n### The Fix\n\n**eight-eyes** splits a review into eight constrained roles — each aimed at a different failure surface. The skeptic never sees the implementer's narrative. The security auditor cannot edit files. The implementer cannot run Bash.\n\nThese aren't suggestions in a system prompt. They are **hook-enforced walls** that intercept tool calls before execution. If the model ignores the prompt, the hook still blocks the action.\n\n---\n\n## What It Catches\n\nA single `/8eyes` mission on a JWT auth refactor surfaces findings like these — independently and in parallel:\n\n| Role | Verdict | Finding |\n|------|---------|---------|\n| **skeptic** | needs_changes | Token refresh endpoint is untested. If the refresh token is expired, the user hits a bare 500 — no redirect, no retry, no error message. |\n| **security** | needs_changes | `jwt.decode()` uses `algorithms=['HS256']` but the key is an RSA public key. An attacker can forge tokens by signing with the public key as an HMAC secret. See CVE-2016-10555. |\n| **performance** | approve | No N+1 patterns. Token validation adds ~2ms per request — within budget. |\n| **accessibility** | approve | Login error states have `aria-live` regions and visible focus indicators. Passes axe-core audit. |\n| **verifier** | needs_changes | Criterion \"refresh token rotation on use\" — NOT MET. `/auth/refresh` returns a new access token but reuses the same refresh token. Evidence: curl output shows identical `refresh_token` in response. |\n\nEach finding includes file paths, line numbers, and concrete evidence. The verifier runs only the commands you approved at init time — it cannot invent its own.\n\n---\n\n## Why Hook-Enforcement Changes Everything\n\n### The Prompt Problem\n\nWhen you rely on prompts to enforce constraints:\n\n```\nPrompt: \"Please stay read-only\"\n\n├── Model ignores it → Writes happen → Hidden vulnerability\n└── Model forgets  → Writes happen → Silent drift\n```\n\n**The failure mode is silent.** You don't know the model drifted until the damage is in the diff.\n\n### The Hook Solution\n\neight-eyes intercepts at the tool layer — before the action executes:\n\n```\nHook: PreToolUse blocks write\n\n├── Model tries anything → Write denied → Audit log captures attempt\n└── Model compliant     → Write allowed → Enforced by architecture\n```\n\n### The Four Enforcement Points\n\n| Hook | When it fires | What it enforces |\n|------|--------------|-----------------|\n| `SubagentStart` | Role begins | Injects role context and blind-review barriers. The skeptic physically cannot see the implementer's summary. |\n| `PreToolUse` | Before any tool call | Blocks out-of-scope writes and unapproved commands before execution. |\n| `PostToolUse` | After any tool call | Auto-reverts unauthorized writes for read-only roles. |\n| `SubagentStop` | Role ends | Requires a structured result block with evidence. Missing or invalid results are rejected. |\n\n**The difference:** Prompts can be overridden. Hooks cannot.\n\nThe full enforcement model — gate classes, failure modes, and per-platform coverage — is defined in `spec/enforcement.yaml` and inspectable at any time:\n\n```bash\npython3 scripts/collabctl.py capabilities\n```\n\n---\n\n## Quick Start\n\n### Claude Code\n\n```bash\nclaude plugin marketplace add AgentBuildersApp/eight-eyes\nclaude plugin install 8eyes@8eyes-marketplace\n```\n\n### GitHub Copilot CLI\n\n```bash\ncopilot plugin marketplace add AgentBuildersApp/eight-eyes\ncopilot plugin install 8eyes@8eyes-marketplace\n```\n\n### OpenAI Codex CLI\n\n```bash\ngit clone https://github.com/AgentBuildersApp/eight-eyes.git\ncd eight-eyes\npython3 install.py --platform codex_cli\n```\n\n### Manual install (all platforms)\n\n```bash\ngit clone https://github.com/AgentBuildersApp/eight-eyes.git\ncd eight-eyes\npython3 install.py\n```\n\nThen run your first mission:\n\n```bash\n/8eyes:collab Refactor auth to use JWT\n```\n\nThis initializes a mission, sets scope boundaries, and launches the eight roles through the phase flow. When it finishes, you get a structured result from each role with findings, evidence, and a pass/needs_changes/abort recommendation.\n\n### Verify & Manage\n\n```bash\npython3 scripts/collabctl.py --version          # Check installed version\npython3 scripts/collabctl.py verify --install-only  # Verify without a git repo\npython3 scripts/collabctl.py locate              # Show all install locations\npython3 install.py --uninstall                   # Clean removal\n```\n\n### Platform Notes\n\n| Platform | Python | Notes |\n|----------|--------|-------|\n| macOS / Linux | `python3` on PATH | Symlinks to home directory. No `sudo` needed. |\n| Windows | `python3` or `python` | Symlinks with copy fallback. File locking uses `msvcrt`. |\n| CI / Docker | 3.10 through 3.13 | Zero dependencies. No `pip install` step. Ensure `git` is in the image. |\n\n---\n\n## What's New in 5.0\n\n### Verifiable enforcement\n\nPrevious versions told you what was enforced. Now you can verify it yourself:\n\n```bash\npython3 scripts/collabctl.py capabilities\n```\n\n```\nHook               Gate Class     Failure Mode     Claude    Copilot   Codex\nPreToolUse         hard_gate      deny             supported supported degraded\nSubagentStop       hard_gate      block            supported supported —\nPostToolUse        recovery       fail_open        supported supported degraded\nStop               lifecycle      warn             supported supported supported\nSessionStart       lifecycle      fail_open        supported supported degraded\nSubagentStart      lifecycle      fail_open        supported supported —\nPreCompact         observability  async_fail_open  supported —         —\n```\n\nEvery hook has an explicit gate class, failure mode, and per-platform support level. `--json` gives you machine-readable output for CI. This is the enforcement contract — not a README claim, but an inspectable artifact that tests are written against.\n\n### Machine-readable mission status\n\n```bash\npython3 scripts/collabctl.py status --json\n```\n\nReturns structured JSON with planned roles, completed roles with outcomes, pending roles, skipped roles, fail-closed state, and loop count. Build dashboards, integrate with CI, or pipe to `jq` — mission state is no longer trapped in text output.\n\n### Custom roles are first-class\n\nIn 4.x, a manifest-defined `read_only` custom role silently bypassed PostToolUse audit and revert handling. If your custom auditor accidentally wrote a file, nothing caught it.\n\nIn 5.0, custom roles receive the same compensating revert as built-in roles. Write attempts are reverted. Revert events are ledgered with `revert_mode` (tracked checkout vs untracked delete) and `revert_success` status. The audit trail distinguishes built-in from custom role type.\n\n### Platform coverage you can test against\n\nPlatform support is no longer a table in a README. It is a machine-readable matrix in `spec/enforcement.yaml`, verified by parity tests that run against the actual adapter manifests. If a hook is marked \"supported\" for Copilot, the Copilot adapter manifest includes it — and a test asserts that. If Codex says \"degraded,\" every surface agrees.\n\n---\n\n## When This Matters\n\n### Solo Developer\n\nYou wrote the code and reviewed it yourself. `eight-eyes` gives you eight reviewers who didn't write it and can't see each other's notes. The verifier runs your acceptance criteria against the actual code — confidence is not proof.\n\n### Security-Critical Work\n\nYou're building auth or payment flows where a missed edge case has real consequences. The security role reviews like an external auditor — read-only, approved scan commands only. It cannot \"fix\" things and accidentally hide the vulnerability.\n\n### AI-Assisted Development\n\nYour team uses AI coding agents but nobody reviews the output with adversarial intent. `eight-eyes` reviews AI-generated code like a junior developer's first PR — except it can't be talked out of its concerns. The skeptic literally cannot see the author's narrative.\n\n### Decisions and Documents\n\nA PRD got two thumbs up. Nobody caught that the latency budget assumes a service that hasn't been built yet. The skeptic would have — it reviews blind, without the author's framing. The verifier would have — it checks claims against evidence, not confidence. These roles constrain how the reviewer behaves, not what it reviews.\n\n---\n\n## The 8 Roles\n\n| Role | What it catches | How it is enforced |\n|------|------------------|-------------------|\n| `implementer` | Incorrect implementation, missed requirements | Writes limited to `allowed_paths`; no Bash |\n| `test-writer` | Missing tests, weak edge coverage | Writes limited to `test_paths`; no Bash |\n| `skeptic` | Anchoring bias, rollback risk, hidden coupling | Read-only; blind review (no implementer context) |\n| `security` | Auth bypass, injection, secrets exposure | Read-only + approved scan commands |\n| `performance` | N+1 queries, algorithmic blowups | Read-only + approved benchmark commands |\n| `accessibility` | Keyboard traps, missing labels, contrast failures | Read-only + approved a11y commands |\n| `docs` | Stale docs, undocumented behavior | Writes limited to `doc_paths`; no Bash |\n| `verifier` | Confidence without proof | Read-only + approved verification commands |\n\n### The Phase Flow\n\n```\nplan → implement → test → audit → verify → docs → close\n                        ↑                    |\n                        └── loop on failure ─┘\n```\n\nDuring `audit`, the skeptic, security, performance, and accessibility roles run **in parallel**. If any returns `needs_changes`, the mission loops back to `implement` automatically.\n\n### Research gate and buyoff\n\nBefore meaningful implementation, `/collab` can record a Stage 0 research gate:\n\n- deterministic confidence score from explicit factors and penalties\n- research mode: `skip`, `targeted`, or `broad`\n- structured plan buyoff stored in mission state\n- runtime enforcement that blocks implementer writes until required research is satisfied\n\nUse `python3 scripts/collabctl.py research show` and `python3 scripts/collabctl.py buyoff plan ...` to inspect and record this state.\n\nMinimal broad-research flow:\n\n```bash\npython3 scripts/collabctl.py init \\\n  --objective \"Roll out research gate\" \\\n  --allowed-path scripts --allowed-path hooks --allowed-path tests \\\n  --criterion \"Repo test suite passes.\" \\\n  --verify-command \"python3 -m pytest -q\" \\\n  --domain platform \\\n  --action-type architecture \\\n  --risk medium \\\n  --root-cause-clarity 2 \\\n  --fix-path-clarity 2 \\\n  --verification-clarity 1 \\\n  --prior-pattern-match 2 \\\n  --environmental-stability 1 \\\n  --penalty-architecture \\\n  --penalty-cross-module \\\n  --research-rationale \"Cross-cutting coordinator change.\"\n\npython3 scripts/collabctl.py research add-source \\\n  --title \"collab skill policy\" \\\n  --kind local_doc \\\n  --location \"skills/collab/SKILL.md\"\n\npython3 scripts/collabctl.py research add-source \\\n  --title \"8eyes workflow\" \\\n  --kind local_doc \\\n  --location \"commands/8eyes.md\"\n\npython3 scripts/collabctl.py research add-artifact \\\n  --path \"docs/research-gate.md\" \\\n  --kind spec\n\npython3 scripts/collabctl.py research complete\npython3 scripts/collabctl.py buyoff plan --recommendation approve_with_research\npython3 scripts/collabctl.py phase implement --awaiting-user false\n```\n\n### Blind Review\n\nThe skeptic sees the objective, acceptance criteria, and changed paths — but **not** the implementer's narrative or summary. This is enforced by context shaping at the hook level. The skeptic forms an independent opinion because it does not have the implementer's framing in its context window.\n\n---\n\n## Architecture\n\n![Architecture](docs/images/architecture.png)\n\nMission state lives under the Git common directory, not the working tree. That keeps the coordinator, the root checkout, and any isolated worktrees pointed at the same manifest, ledger, and per-role result files.\n\nWorktree isolation is used where incidental writes or tool artifacts would otherwise leak across roles.\n\n---\n\n## Configuration\n\n### Model Routing\n\nRoute specific roles to different model backends:\n\n```bash\n/8eyes:collab Refactor auth --model-map '{\"skeptic\":\"claude-opus-4-20250514\",\"security\":\"claude-opus-4-20250514\"}'\n```\n\n### Custom Roles\n\nAdd roles without changing the core engine:\n\n```bash\npython3 scripts/collabctl.py init \\\n  --objective \"Run lint review\" \\\n  --allowed-path src \\\n  --custom-role \"name=linter,scope=read_only,commands=eslint src/\"\n```\n\n### TDD Mode\n\n`--tdd` changes the phase order to `plan → test → implement`. The hook layer blocks implementer writes until a test-writer result exists.\n\n### REVIEW.md\n\nDrop a `REVIEW.md` in your project root with review criteria. It is automatically injected into the skeptic, security, and verifier context:\n\n```markdown\n## Review Criteria\n- All API endpoints must validate input before processing\n- No credentials in logs, error messages, or API responses\n- Database queries must use parameterized statements\n- Frontend changes must pass axe-core accessibility audit\n```\n\nWorks the same for non-code reviews:\n\n```markdown\n## Review Criteria\n- Every latency claim cites a measured benchmark, not an estimate\n- Data flows that cross trust boundaries are identified\n- Dependencies on unbuilt systems are flagged as risks\n```\n\n### CLI Reference\n\n| Command | What it does |\n|---------|-------------|\n| `init` | Creates a mission with objective, scope, and acceptance criteria |\n| `show` | Prints the active mission state as JSON |\n| `status` | Shows role progress with timing and model identity. `--json` for machine-readable output |\n| `timeline` | Chronological role dispatch and completion table |\n| `report` | Consolidated findings across all roles |\n| `phase <name>` | Advances the mission to the next phase |\n| `close pass\\|abort` | Closes the mission with scope verification |\n| `verify` | Checks installation. `--install-only` skips git requirement. |\n| `capabilities` | Displays the enforcement model: hook semantics, gate classes, and per-platform coverage. `--role <name>` filters to one role. `--json` for machine-readable output |\n| `locate` | Prints all known install locations per platform |\n| `--version` | Prints the installed version |\n\n---\n\n## Platform Support\n\n| Platform | Status | Scope Enforcement |\n|----------|--------|-------------------|\n| Claude Code | Full (GA) | Hook-level (all tools) |\n| Copilot CLI | Full (GA) | Hook-level (all tools) |\n| Codex CLI | Experimental | Hook-level (Bash only), prompt-level (Write/Edit) |\n\n## Testing\n\n152 tests. Stdlib only. No external dependencies.\n\n```bash\npython3 -m pytest tests/ -q\n```\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---------|-----|\n| `/8eyes` does nothing | Run `python3 install.py` inside a Git repo |\n| Implementer writes denied | Add `--allowed-path` entries at init |\n| Bash denied for audit role | Add via `--security-command`, `--benchmark-command`, etc. |\n| Phase transition rejected | Follow the phase table, or `--force` to override |\n| `close` blocked by scope violation | Use `--force-close \"reason\"` to override |\n| Verify fails outside git repo | Use `--install-only` flag |\n\n## Requirements\n\n- Python 3.10+\n- Git\n- One or more: Claude Code, Copilot CLI, Codex CLI\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details on adding custom roles or platform adapters.\n\n## License\n\nMIT\n",
  "bytes": 16564,
  "sha": "381bef35eb28888b73fa900b69ea8fac008eef3300f5ccd715b36de145aaa9a4",
  "repo_slug": "agentbuildersapp/eight-eyes",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_agentbuildersapp_eight_eyes_eight_eyes_9e5b4b76/readme"
}