{
  "markdown": "# Hats\n\nBDD-driven AI dev team for Claude Code and Codex. Five roles, one shared\nproject protocol.\n\n```\nmanager -> designer -> cto -> qa -> developer\n   |          |         |      |       |\n specs     mockups    stack  tests    code\n```\n\n## Quick Start — Claude Code\n\n```bash\n/plugin marketplace add deadsimple-xyz/claude-plugins\n/plugin install hats@deadsimple\n/reload-plugins\n/hats:init                         # creates .hats/ directory structure\n/hats:manager                      # \"What are we building?\"\n```\n\nRequires [Claude Code](https://docs.anthropic.com/en/docs/claude-code) CLI.\n\n## Quick Start — Codex\n\n```bash\ncodex plugin marketplace add deadsimple-xyz/hats\ncodex plugin add hats@deadsimple-xyz\n```\n\nStart a new conversation after installing, then invoke the skills with a `$`\nprefix:\n\n```text\n$hats:init\n$hats:manager\n```\n\nClaude Code discovers `.claude-plugin/plugin.json`; Codex discovers\n`.codex-plugin/plugin.json`. Both manifests package the same `skills/`,\n`agents/`, `hooks/`, and `scripts/` directories from this repository.\n\n## Skills and commands\n\n```\n/hats:init          # set up project (new or existing)\n/hats:manager       # specs & planning\n/hats:designer      # wireframes & UI descriptions\n/hats:cto           # stack decisions\n/hats:qa            # automated tests from specs\n/hats:developer     # implementation (TDD)\n/hats:autopilot     # run the full pipeline autonomously\n/hats:solo          # exit role mode, work as plain Claude\n/hats:doctor        # diagnose and fix project structure\n```\n\nThe list above uses Claude Code slash-command spelling. In Codex, use the same\nnames with a `$` prefix (`$hats:qa`, `$hats:developer`, and so on). The role\nprofiles under `agents/` are shared unchanged by both hosts.\n\nThe typical flow is `manager > designer > cto > qa > developer`, but you can talk to any role at any time. If you know your stack, skip the CTO. If you have your own designs, skip the Designer. If something breaks in tests, jump into QA and discuss it.\n\n## How It Works\n\nYou are the product owner. You talk to the **Manager** and describe what you want. The Manager writes [Gherkin](https://cucumber.io/docs/gherkin/) specs -- human-readable, machine-parseable `.feature` files:\n\n```gherkin\n@auth\nFeature: JWT Authentication\n  Users can register and login.\n  Technical: RS256, access token 15min, refresh 7d.\n\n  @critical @happy-path\n  Scenario: Successful login\n    Given a user \"test@mail.com\" with password \"secret123\" exists\n    When user sends POST /auth/login with valid credentials\n    Then response status is 200\n    And response contains access_token and refresh_token\n```\n\nThen each role takes over:\n\n| Role | Can read | Can write |\n|------|----------|-----------|\n| **Manager** | `.hats/shared/` | `.hats/manager/`, `.hats/shared/specs/`, `.hats/shared/manager2team.md` |\n| **Designer** | `.hats/shared/` | `.hats/designer/`, `.hats/shared/designs/`, `.hats/shared/designer2team.md` |\n| **CTO** | `.hats/shared/` | `.hats/cto/`, `.hats/shared/stack.md`, `setup.md`, `api.md`, `cto2team.md` |\n| **QA** | `.hats/shared/`, `.hats/qa/` | `.hats/qa/`, `.hats/shared/qa-report.md`, `qa2dev.md`, `qa2designer.md`, `test-contract.md` |\n| **Developer** | `.hats/shared/` + project root | project root, `.hats/shared/setup.md`, `api.md`, `dev2qa.md`, `dev2designer.md` |\n\nUnder Claude Code's file tools, permissions are enforced by hooks -- the\nDeveloper literally *can't* read tests, and the QA *can't* read source code.\nBoth halves are checked by rows in `tests/read-guard.test.sh`; the QA half was\nprose until 5.0.0, which is precisely why the tests exist.\n\nCodex sends normal edits as `apply_patch`; Hats expands a multi-file patch and\nchecks every source and destination path against the same write rules. Codex\nnormally reads files through its shell tool, so its read fence is audit-only:\ndisallowed-looking reads are recorded by `bash-audit.sh`, not refused. This is\nthe same deliberate Bash escape hatch described below, but it is the normal\nread path in Codex rather than an exceptional one.\n\n**Know the edge of that guarantee.** The hooks match the Claude file tools —\n`Write`, `Edit`, `Read`, `Glob`, `Grep` — plus Codex `apply_patch` writes.\n**Bash is audited, not blocked**, so a role that reaches for a shell can read\nand write anything: `cat src/app.ts` works, and so does `echo … > file`. Roles\nneed Bash constantly and legitimately, and deciding what an arbitrary command\nwill touch means parsing a shell — so this is a known edge rather than an\noversight (`tests/KNOWN-GAPS.md`, G3). The fences shape what a role does by\ndefault; they are not a sandbox. QA writes a plain-language report\n(`.hats/shared/qa-report.md`) so the Developer understands what failed and why,\nwithout seeing test code.\n\n## Project Structure\n\nAfter `/hats:init`:\n\n```\nmy-app/\n  .hats/\n    manager/         Private workspace (Manager)\n    designer/        Private workspace (Designer)\n    cto/             Private workspace (CTO)\n    qa/              Automated e2e tests + run-tests.sh\n    shared/          All cross-role data\n      specs/           .feature files (Manager writes)\n      designs/         Mockups and wireframes (Designer writes)\n      stack.md         Technology decisions (CTO)\n      setup.md         How to run the project (CTO/Developer)\n      api.md           API conventions (CTO/Developer)\n      test-contract.md qa attributes & expectations (QA)\n      qa-report.md     Test results for Developer (QA)\n      manager2team/    Manager -> team           one file per entry\n      cto2team/        CTO -> team               + INDEX.md, newest first\n      designer2team/   Designer -> team\n      qa2dev/          QA -> Developer\n      dev2qa/          Developer -> QA\n      dev2designer/    Developer -> Designer\n      qa2designer/     QA -> Designer\n      threads/         any role may append (conversations)\n    tasks/           what is being worked on, one folder per task\n    status.json      Current state and message counters\n    role             Active role (managed by hooks)\n  src/               Your code lives at project root\n```\n\n## Tasks are folders in git\n\nSpecs say what must be **true**. Tasks say what someone is **doing** — and\nuntil v5 hats had no answer at all to «what is in flight, and what was closed\nyesterday and why» that outlived the session it was asked in.\n\n```\n.hats/tasks/\n  INDEX.md                        the board, one table\n  0042-runner-flaky-on-login/\n    task.md                       status / priority / owner / spec + the ask\n    understanding.md              written when work starts\n    resolution.md                 written when it closes\n```\n\nThree gates, enforced by the hook rather than asked for in a prompt:\n\n- **`open -> done` is refused** — a task closes only after being in work.\n- **`in_progress` needs a non-empty `understanding.md`** — say what you think\n  the job is *before* doing it. Afterwards that sentence is a summary, which is\n  a different and much easier thing to write.\n- **`done` needs a non-empty `resolution.md`** — what you checked, what you\n  concluded. The next person's question is «how do you know».\n\n```bash\nbash \"$HATS/scripts/task.sh\" new \"Runner is flaky on login\" 1 developer @auth\nbash \"$HATS/scripts/task.sh\" next\nbash \"$HATS/scripts/task.sh\" status .hats/tasks/0042-runner-flaky-on-login in_progress\n```\n\nEditing `task.md` by hand works too and is gated identically — the helper is a\nconvenience, not the fence.\n\n## Channels are directories\n\nEach channel is a directory of entries plus a generated `INDEX.md`, newest\nfirst:\n\n```\n.hats/shared/qa2dev/\n  INDEX.md                  read this\n  0246-2026-07-30-qa.md     one entry, one subject\n  0245-2026-07-30-qa.md\n  ARCHIVE.md                everything as it was before migration\n```\n\n**Why.** A channel used to be one file, appended at the bottom. `Read` returns\nthe first 2000 lines and the roles are told never to `tail`. Measured on a live\nproject: `qa2dev.md` held 15 entries spanning `[40]..[51]`, and a role\nfollowing its own instructions saw 6 of them and stopped at `[42]`. Nine\nentries were read by nobody, ever. It goes wrong at about 130 KB — most\nprojects by their second month.\n\nMigrate an existing project with `/hats:doctor`, or by hand:\n\n```bash\nbash \"$HATS/scripts/channel.sh\" split .hats/shared/qa2dev.md\n```\n\nThe split is verified byte-for-byte before anything is written, and the\noriginal is kept as `ARCHIVE.md`. Run across six live projects: 35 channels of\n35 migrated with no loss, and what a role reads on activation went from 2894 KB\nto 119 KB of index.\n\nWrite with the same helper, which numbers, dates, names you and refreshes the\nindex:\n\n```bash\necho \"Runner is green.\" | bash \"$HATS/scripts/channel.sh\" \\\n  append .hats/shared/qa2dev QA\n```\n\n## Roles, sessions and the fence\n\nThe active role lives in `.hats/role`, and the guards read it. Two things worth\nknowing:\n\n- **`HATS_ROLE` pins the role.** Set it in the environment and the role cannot\n  be changed from inside the session — a write to `.hats/role` is refused and\n  says why. Use it wherever the fence must be real: autopilot, spawned per-role\n  sessions, CI. Without it the door stays open, because the same door is how a\n  human switches roles.\n- **The role is per-session.** Two Claude Code sessions in one repo used to\n  share one role file, so the second session's switch silently re-aimed the\n  first one's fence. Each session now keeps its own position, and every switch\n  appends a line to `.hats/role-history` — audit that is not behind the debug\n  flag.\n\n## Debug Logging\n\n\nEnable debug logging to see exactly what each role does — every tool use, command, file read/write, and guard block:\n\n```bash\ntouch .hats/debug          # enable\nrm .hats/debug             # disable\n```\n\nLogs go to `.hats/logs/YYYY-MM-DD.jsonl` (one JSON object per line). Zero overhead when disabled — the hook checks for the flag file and exits immediately.\n\nExample log:\n```jsonl\n{\"ts\":\"2026-03-04T14:30:00Z\",\"role\":\"none\",\"tool\":\"Write\",\"file\":\".hats/role\"}\n{\"ts\":\"2026-03-04T14:30:01Z\",\"role\":\"manager\",\"tool\":\"Read\",\"file\":\"agents/manager.md\"}\n{\"ts\":\"2026-03-04T14:30:05Z\",\"role\":\"manager\",\"tool\":\"Agent\",\"description\":\"Write feature specs\"}\n{\"ts\":\"2026-03-04T14:30:07Z\",\"role\":\"manager\",\"tool\":\"Write\",\"file\":\".hats/shared/manager2team.md\"}\n{\"ts\":\"2026-03-04T14:30:15Z\",\"event\":\"write_block\",\"role\":\"designer\",\"file\":\"src/index.ts\",\"tool\":\"Write\",\"reason\":\"designer can only write inside .hats/\"}\n```\n\nSee [self-learning.md](self-learning.md) for how to use logs to improve Hats itself.\n\n## Decision records & reopen triggers\n\nDecisions that outlive the chat get one line in the file they belong to — auditable later, and tagged with the condition that should make you revisit them:\n\n- **CTO** records each significant stack choice in `stack.md`: `**Postgres** — over SQLite, because concurrent writes + RLS. Reopen if we drop multi-tenant.`\n- **QA** tags `@critical` contract items in `test-contract.md` with the scope they hold for and a reopen condition — so a green test on the wrong assumption gets caught.\n- **Developer** flags a hit `Reopen if …` condition up to CTO/QA instead of silently coding around a decision that no longer holds.\n\nOne line per decision is the whole ceremony. (Borrowed in spirit from the [First Principles Framework](https://github.com/ailev/FPF) — the idea, not the formalism.)\n\n## What «done» means\n\nEvery role reads four shared fragments at activation, and they carry the parts\nof the job that are the same for everyone:\n\n| fragment | what it settles |\n|---|---|\n| `agents/_shared/pipeline.md` | the whole route, who owes what to whom, what you can reach without asking, what needs the human, what is impossible, and the two-attempt rule |\n| `agents/_shared/channels.md` | how channels are read and written, and why `status.json` is a state file rather than a third channel |\n| `agents/_shared/tasks.md` | the task board and the three gates |\n| `agents/_shared/evidence.md` | a green you have never seen go red is not evidence |\n\nThe last one is the expensive rule and the one that pays fastest. Closing\nsomething on the strength of a test means breaking the mechanism the test\nwatches, seeing the row go red **for the reason you named**, putting it back,\nand saying so in one line. If breaking the mechanism changes nothing, that is\nthe finding: the rows never touched it.\n\nThe QA report carries a three-line signature — what was checked (the command\nand its actual numbers), what was concluded (including what is still open), and\nwhat was falsified.\n\n## Testing hats itself\n\n```bash\nbash tests/run.sh\n```\n\nNo framework to install. Known gaps live in `tests/KNOWN-GAPS.md`: they print\non every run, they do not fail it, and they DO fail it the day they start\npassing — so a gap cannot be closed silently or forgotten.\n\n## Why\n\nWhen one AI writes code AND tests, it tests its own assumptions -- same blind spots. By splitting into roles with separate contexts and separate prompts, the QA tests *requirements* while the Developer implements *solutions*. Neither can see the other's code.\n\nThe Developer can't read test source -- only test results via `.hats/shared/qa-report.md` and `bash .hats/qa/run-tests.sh`. The QA can't read implementation -- it writes tests from specs alone. Gherkin `.feature` files are the contract between roles: readable by you, parseable by the AI.\n\n## License\n\nMIT\n",
  "bytes": 13399,
  "sha": "0a968cfce3db98558100028d93e8eb041ee865eebee14f91ea1088ebff26e5af",
  "repo_slug": "deadsimple-xyz/hats",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_deadsimple_xyz_hats_hats_e0d20cb4/readme"
}