{
  "markdown": "<div align=\"center\">\n\n<img src=\"assets/logo.svg\" alt=\"DoD-Guard\" width=\"160\" height=\"160\" />\n\n# DoD-Guard\n\n### Definition of Done as an executable barrier for Claude Code\n\n*Stops AI agents (and humans) from declaring tasks **done** while the code is still half-baked.*\n\n[![GitHub release](https://img.shields.io/github/v/release/atoslins/dod-guard?include_prereleases&label=release)](https://github.com/atoslins/dod-guard/releases)\n[![CI](https://img.shields.io/github/actions/workflow/status/atoslins/dod-guard/test.yml?branch=main&label=CI)](https://github.com/atoslins/dod-guard/actions)\n[![claude-code](https://img.shields.io/badge/claude--code-%E2%89%A5%202.1-blue)](https://docs.anthropic.com/claude-code)\n[![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n[![python](https://img.shields.io/badge/python-%E2%89%A5%203.10-blue)](https://www.python.org/)\n[![bash](https://img.shields.io/badge/bash-%E2%89%A5%204.0-blue)](https://www.gnu.org/software/bash/)\n[![tests](https://img.shields.io/badge/tests-94%20passing-brightgreen)](tests/)\n[![shellcheck](https://img.shields.io/badge/shellcheck-clean-brightgreen)](https://www.shellcheck.net/)\n\n</div>\n\n---\n\n<p align=\"center\">\n  <img src=\"assets/demo.svg\" alt=\"DoD-Guard /dod:verify going from FAIL to PASS after fixing two stubs\" width=\"100%\" />\n</p>\n\n---\n\n## Why this exists\n\nLLM-driven coding assistants are wired to declare \"done.\" The failure modes are everywhere:\n\n- A function ships as `pass` / `return None` / `TODO: implement`.\n- A test asserts `expect(x).toBeDefined()` — it proves the function exists, not that it works.\n- A summary claims \"tests pass\" while three tests were silently `.skip`-ed.\n- An end-to-end behavior is announced without a single command being run.\n- A confident final report has zero supporting evidence.\n\nDoD-Guard turns the **Definition of Done** from a prompt into a wall the agent cannot talk past. Hooks block at the source of every shortcut. Read-only adversarial subagents audit the orchestrator from the outside. The `Stop` hook refuses to release the turn while the DoD is unmet — with proper `stop_hook_active` loop prevention.\n\n---\n\n## How it works\n\nFive reinforcing layers, ordered by cost-to-execute (cheapest first):\n\n```\n┌──────────────────────────────────────────────────────────────┐\n│  L5  Skills            reframe how the orchestrator plans    │\n│  L4  Slash commands    /dod:verify  /dod:audit  /dod:confess │\n│  L3  Subagents         7 adversarial validators (read-only)  │\n│  L2  Hooks             SessionStart · PostToolUse · Stop     │\n│  L1  Detectors         bash + python — milliseconds, no LLM  │\n└──────────────────────────────────────────────────────────────┘\n```\n\n| Layer | What it stops |\n|-------|----------------|\n| **Detectors** | Stubs, TODOs, empty bodies, tautological tests, NotImpl markers |\n| **Hooks** | Bypass attempts via edit, commit, declaring done before verifying |\n| **Subagents** | Bugs detectors miss; weak tests; unverified claims; regressions; e2e gaps |\n| **Slash commands** | Manual entry points; emergency rituals (`/dod:confess`) |\n| **Skills** | Reframe the orchestrator's worldview when entering a DoD-guarded project |\n\nSee [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the layer diagram and the full flow on \"Claude declares done.\"\n\n---\n\n## Install\n\nInside any Claude Code session:\n\n```bash\n/plugin marketplace add https://github.com/atoslins/dod-guard\n/plugin install dod-guard@dod-guard-local\n/reload-plugins\n```\n\nTo develop locally:\n\n```bash\ngit clone https://github.com/atoslins/dod-guard\n/plugin marketplace add /absolute/path/to/dod-guard\n/plugin install dod-guard@dod-guard-local\n/reload-plugins\n```\n\n---\n\n## First-run\n\nInside any project you want to guard:\n\n```bash\n/dod:init                # detects stack (Node / Python / Go / Rust), writes config + DOD.md\n/dod:checklist           # shows the Definition of Done\n/dod:verify              # 30-second deterministic check\n```\n\nThat's it. From that point on, hooks fire automatically on every edit, every commit attempt, and every turn-end. If the orchestrator tries to declare \"done\" with a stub in the diff, the `Stop` hook returns:\n\n```json\n{\"decision\": \"block\",\n \"reason\": \"DoD-Guard: cannot end the turn — Definition of Done is unmet.\n            Run /dod:verify to see the full list of blocking issues.\"}\n```\n\n---\n\n## The commands\n\n| Command | Purpose | Time |\n|---------|---------|------|\n| **`/dod:init`** | Bootstrap config and DoD checklist for the project | < 5 s |\n| **`/dod:verify`** | Fast 5-phase deterministic check; refreshes the marker | ~ 30 s |\n| **`/dod:audit`** | Full multi-agent audit (7 subagents in parallel) | 2-3 min |\n| **`/dod:report`** | Read existing reports, format markdown — no LLM | < 1 s |\n| **`/dod:stubs`** | Fastest scan: stubs and TODOs only | ~ 2 s |\n| **`/dod:tests`** | Audit only test quality (post-TDD) | ~ 30 s |\n| **`/dod:checklist`** | Show DoD with this session's auto-verified items | < 5 s |\n| **`/dod:confess`** | Force a 7-section paranoid self-audit | ~ 10 s |\n\n---\n\n## What gets caught\n\n### Cross-language (Python / JS / TS / Go / Rust / Ruby / Bash)\n\n| Pattern | Detector |\n|---------|----------|\n| `pass` · `...` · `return None` · `{}` as function body | `detect-empty-functions.py` (AST for Python) |\n| `TODO` · `FIXME` · `XXX` · `HACK` markers | `detect-stubs.sh` + `detect-todos.sh --diff` |\n| `NotImplementedError` · `todo!()` · `unimplemented!()` · `panic(\"not implemented\")` | `check-not-implemented.sh` |\n| Action-named fns returning only `null` / `{}` / `[]` | `detect-suspicious-returns.py` |\n\n### JavaScript / TypeScript-specific\n\n| Pattern | Detector |\n|---------|----------|\n| `expect(x).toBeDefined()` / `.not.toBeNull()` / `.toBeTruthy()` on a literal | `detect-test-tautology.py` |\n| `expect(mock).toHaveBeenCalled()` with no matching `.toHaveBeenCalledWith(...)` | `detect-test-tautology.py` |\n| `expect.assertions(0)` · `expect({}).toMatchSnapshot()` | `detect-test-tautology.py` |\n| `assert.ok(true)` · `.to.be.ok` · `.to.exist` (Node / chai weak) | `detect-test-tautology.py` |\n| `test.skip` / `xit` / `xdescribe` added in this diff | `detect-test-tautology.py` |\n\n### Go-specific\n\n| Pattern | Detector |\n|---------|----------|\n| `func NewX() *X { return &X{} }` (constructor with no fields set) | `detect-suspicious-returns.py` |\n| `_ = err` · `_, _ = ...` (error-swallow) | `detect-suspicious-returns.py` |\n| `assert.True(t, true)` · `assert.Equal(t, x, x)` · `assert.NoError(t, nil)` | `detect-test-tautology.py` |\n| `TestX(t *testing.T)` body with no assertion-like call | `detect-test-tautology.py` |\n| `t.Skip(...)` · `t.Log(\"TODO...\")` | `detect-test-tautology.py` |\n| `// nolint:` added in the diff | `detect-stubs.sh` · `detect-todos.sh` |\n\n### Multi-agent verification\n\n| Audit | Subagent |\n|-------|----------|\n| Bugs, edge cases, security, race conditions | `adversarial-reviewer` |\n| Test quality (tautologies, mocks-only, decorative asserts) | `test-quality-auditor` |\n| End-to-end behavior proof (curl, CLI, real probe) | `e2e-verifier` |\n| Regressions vs. the last baseline | `regression-hunter` |\n| Every claim in the completion report cross-checked | `claim-validator` |\n| Stubs, TODOs, completeness | `completeness-auditor` |\n| Final verdict aggregation (one FAIL = FAIL) | `final-judge` |\n\n---\n\n## A concrete scenario\n\n> *\"Add a `/refund` endpoint. We'll wire up the payment gateway later.\"*\n\n**Without DoD-Guard:** the orchestrator writes a `return null` stub, adds a test that mocks the gateway and asserts `null`, declares done. The PR ships broken.\n\n**With DoD-Guard:**\n\n1. The orchestrator writes the stub.\n2. `PostToolUse` hook fires `detect-stubs.sh`. Returns `count: 2` (TODO marker + suspicious return).\n3. Hook emits `{\"decision\": \"block\", \"reason\": \"DoD-Guard: 2 issue(s) detected...\"}`.\n4. The orchestrator cannot continue without either implementing the gateway *or* returning `501 Not Implemented` with a test for that response.\n5. Before declaring done, `/dod:confess` forces a 7-section honest report. `claim-validator` cross-checks each claim against the diff.\n6. `Stop` hook re-runs verification. PASS only when zero blocking issues remain.\n\nSee [docs/EXAMPLES.md](docs/EXAMPLES.md) for four full scenarios.\n\n---\n\n## Customization\n\nEvery detector and every hook is tunable per-project via `.dod-guard.json`:\n\n```json\n{\n  \"strictness\": \"normal\",                          // strict | normal | lenient\n  \"detectors\": {\n    \"stubs\":          { \"enabled\": true, \"severity\": \"block\" },\n    \"test_tautology\": { \"enabled\": true, \"severity\": \"block\" }\n  },\n  \"hooks\": {\n    \"post_edit\":  { \"severity\": \"block\" },\n    \"pre_commit\": { \"require_verify_recent\": true, \"verify_ttl_seconds\": 600 },\n    \"stop_gate\":  { \"skip_tests\": false }\n  },\n  \"audit\": {\n    \"parallel\": true,\n    \"subagents\": [\"completeness-auditor\", \"test-quality-auditor\", \"regression-hunter\"]\n  },\n  \"exemptions\": {\n    \"paths\": [\"**/migrations/**\", \"vendor/**\", \"src/generated/**\"]\n  }\n}\n```\n\nHighlights:\n\n- Three strictness levels, per-detector severity overrides.\n- Custom regex patterns (e.g., a company-specific `@INTERNAL_TODO`).\n- Glob-based exemptions (with `DODG_NO_EXEMPTIONS=1` bypass for tests).\n- Custom detectors via local `scripts/local/detect-*.py`.\n- Per-stack DoD templates auto-selected by `/dod:init` (Node, Go, generic).\n\nFull reference: [docs/CUSTOMIZATION.md](docs/CUSTOMIZATION.md).\n\n---\n\n## Project layout\n\n```\n.claude-plugin/\n  plugin.json                    manifest\n  marketplace.json               single-plugin marketplace entry\nhooks/\n  hooks.json                     event wiring\n  handlers/                      5 hook scripts\nscripts/\n  detect-*.{sh,py}               7 detectors\n  run-full-suite.sh              test runner auto-detection\n  run-verification-pipeline.sh   aggregator → JSON verdict\n  lib/                           shared helpers (exemptions, language detection)\nagents/                          7 adversarial subagents\ncommands/                        8 slash commands\nskills/*/SKILL.md                4 behavior-shaping skills\ntemplates/                       .dod-guard.json + DOD.md per stack\ndocs/                            ARCHITECTURE · CUSTOMIZATION · EXAMPLES · DEVELOPMENT\ntests/\n  test-*.sh                      4 test suites (94 assertions)\n  fixtures/                      negative + clean test projects\n```\n\n---\n\n## Verification\n\nThe plugin verifies itself. A 94-assertion test suite covers every detector, every hook, and every adversarial agent. Run any of them with one command:\n\n```bash\nbash tests/test-detectors.sh        # 28 / 28 — all detectors against fixtures\nbash tests/test-hooks.sh            # 18 / 18 — payload simulation for the 5 hooks\nbash tests/test-agents-syntax.sh    # 36 / 36 — agent + command frontmatter\nbash tests/test-integration.sh      # 12 / 12 — end-to-end init → block → fix → pass\n```\n\n`shellcheck -x` is clean on every shell script. `python3 -m py_compile` is clean on every Python script. `claude plugin validate` passes for both `plugin.json` and `marketplace.json`.\n\nThe plugin's own source is held to its own rules: `bash scripts/run-verification-pipeline.sh --skip-tests` returns `VERDICT: PASS, 0 issues`.\n\n---\n\n## Contributing\n\nPRs welcome. The short version:\n\n```bash\ngit clone https://github.com/atoslins/dod-guard\ncd dod-guard\nbash tests/test-detectors.sh\nbash tests/test-hooks.sh\nbash tests/test-agents-syntax.sh\nbash tests/test-integration.sh\nshellcheck -x hooks/handlers/*.sh scripts/*.sh tests/*.sh\n```\n\nThe contribution guide is in [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md). Style, testing, and release process are documented there.\n\nOpen issues and discussions are tracked at [github.com/atoslins/dod-guard/issues](https://github.com/atoslins/dod-guard/issues).\n\n---\n\n## FAQ\n\n**Can the orchestrator just ignore the hooks?**\nNo. Hooks are executed by Claude Code itself before and after every tool call. They return JSON the agent must obey (`{\"decision\": \"block\"}` halts the turn). The agent literally cannot proceed.\n\n**Doesn't this slow everything down?**\nThe detectors are bash + Python AST — under 100 ms on small projects, under a second on large ones. The full `/dod:audit` (7 subagents in parallel) takes 2-3 minutes and is meant for end-of-task, not every turn.\n\n**What happens if a hook itself has a bug?**\nThe `Stop` hook honors `stop_hook_active: true` from the payload — if the hook keeps blocking, Claude Code routes the agent back to the user after one cycle. No infinite loops. Other hooks no-op silently when `.dod-guard.json` is absent.\n\n**Does this replace code review?**\nNo. It catches the *category* of failure that LLM agents disproportionately produce (premature completion, decorative tests, swallowed errors). Human review still catches design issues, architectural drift, and product-fit problems. Use both.\n\n**Can I disable a specific detector?**\nYes, in `.dod-guard.json`. But prefer narrowing patterns over disabling — the detector is cheap, the value of catching one real bug is high.\n\n---\n\n## Acknowledgments\n\nDoD-Guard borrows ideas from:\n\n- The Claude Code plugin and hook ecosystem.\n- The `adversarial-review` pattern of independent skeptic subagents.\n- The Test-Driven Development / Definition-of-Done discipline from agile and lean engineering.\n\nThe thread that ties them together is a single principle: **evidence before assertion, always.**\n\n---\n\n## License\n\nMIT © Atos Daniel de Assis Lins. See [LICENSE](LICENSE).\n\n<div align=\"center\">\n<sub>Built with — and for — Claude Code.</sub>\n</div>\n",
  "bytes": 13547,
  "sha": "b80c654a27e8b45e1d3b07bc045bf19bcf3a8a04cfcd8a598bcef6d8d7e40a12",
  "repo_slug": "atoslins/dod-guard",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_atoslins_dod_guard_dod_guard_64e52563/readme"
}