{"id":"90f7b050-e04f-4dc2-b33a-881a02d5a3bb","slug":"agentic-habits","kind":"skill","name":"agentic-habits","summary":"Agentic habits: standing behaviour for a coding agent in three tiers. Stated rules where the trigger fires, a Stop-hook gate for what must not fail, and a read-only judge that scores adherence from ev","owner":"AgriciDaniel","repoUrl":"https://github.com/AgriciDaniel/agentic-habits","license":"MIT","licenseTier":"permissive","trust":"community","stars":6,"match":null,"fewStars":false,"format":"skill","createdAt":"2026-08-29T17:51:53.000Z","addedAt":"2026-10-21T11:29:08.171Z","logoUrl":"https://avatars.githubusercontent.com/u/223140489?u=4fbbeca530fc85f1e64339bf9445ba858879ccfd&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools","memory-knowledge"],"tags":["agentic","ai-agents","claude","claude-code","context-engineering","prompt-engineering","claude-code-plugin","hooks"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T02:58:15.234Z","sample":false,"url":"https://conduits.dev/tools/agentic-habits","language":"Markdown","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  <img alt=\"agentic habits: rules load into the agent, then a magnifier, an eye and a check verify what it actually did\" src=\"assets/cover.png\" width=\"900\">\n</p>\n\n<p align=\"center\">\n  <sub>Cover image generated with OpenAI <code>gpt-image</code> and carrying C2PA content credentials. Provenance in <a href=\"assets/PROVENANCE.md\">assets/PROVENANCE.md</a>.</sub>\n</p>\n\n<p align=\"center\">\n  <a href=\"LICENSE\"><img alt=\"MIT license\" src=\"https://img.shields.io/badge/license-MIT-C2410C?style=flat-square\"></a>\n  <a href=\"https://github.com/AgriciDaniel/agentic-habits/actions/workflows/ci.yml\"><img alt=\"checks\" src=\"https://github.com/AgriciDaniel/agentic-habits/actions/workflows/ci.yml/badge.svg?branch=main\"></a>\n  <img alt=\"rules: markdown\" src=\"https://img.shields.io/badge/rules-markdown-1C1917?style=flat-square\">\n  <img alt=\"gate: shell + jq\" src=\"https://img.shields.io/badge/gate-shell%20%2B%20jq-1C1917?style=flat-square\">\n</p>\n\n<p align=\"center\">\n  <b>One command that gives an agent behaviour which survives the end of the chat,<br>and says plainly which parts of it are enforced and which are only loaded.</b>\n</p>\n\n---\n\n## The idea\n\nAn agent is not short of memory. Claude Code persists instructions five ways:\nCLAUDE.md at four scopes, `.claude/rules/`, skills, hooks, and auto memory the\nagent writes for itself. What it is short of is **enforcement**.\n\nLoading an instruction is deterministic. Following it is not. The documentation\nis blunt about which is which: CLAUDE.md and rules are advisory, while hooks\n\"are deterministic and guarantee the action happens\".\n\nSo a habit is two things, and most rule sets ship only the first.\n\n> **Placement decides loading.** A rule is in context when its trigger fires, or it may as well not exist, and the file it lives in is the only thing that decides. Tested, both directions.\n>\n> **Only a gate decides adherence.** Everything short of a hook is a hint. This skill says that out loud rather than letting \"durable rule\" imply \"reliable rule\", and it escalates a habit that must not fail.\n>\n> **Budget over accumulation.** The one adherence finding in the official docs is that bloated instruction files cause Claude to ignore your instructions. Twelve at system scope, ten per project, six per path file. At the cap, adding means retiring.\n\n## Three tiers\n\n| Tier | Mechanism | Guarantee |\n|---|---|---|\n| **Stated** | a rules file that loads when the trigger fires | none, it is a hint |\n| **Gated** | a hook that executes regardless of what the agent decides | deterministic |\n| **Judged** | a read-only verifier scoring adherence from evidence | after the fact, and weaker than it sounds |\n\nMost rule sets ship the first tier and imply the second. This one says which\ntier a habit is in, in the card itself.\n\n**What the first tier actually buys.** On Anthropic's Impossible Tasks\nevaluation, an explicit forceful written instruction moved the failure rate from\n55% to 35% for one model and 50% to 23% for the next. A written rule roughly\nhalves the failure and leaves a quarter to a third standing. That is the ceiling\nthis package works under, and it is why the other two tiers exist.\n\n## Quickstart\n\n```bash\ngit clone https://github.com/AgriciDaniel/agentic-habits.git\ncd agentic-habits\n./install.sh                 # skill + judge agent\n./install.sh --with-gate     # also stage the Stop gate and print how to enable it\n```\n\nThen, in Claude Code:\n\n```\n/habits setup\n```\n\n**Requirements**: Claude Code (tested on 2.1.251), bash, and `jq` if you want\nthe gate. Linux and macOS; both are in CI. The installer never writes a habit\nand never edits `settings.json` without `--apply`. `./uninstall.sh` removes the\nmachinery and deliberately leaves your habits and cases alone.\n\nIt reads your existing CLAUDE.md files first and proposes only what is not\nalready covered, because a second copy of an existing rule is not free. It shows\nyou the exact file before writing anything.\n\n## What a habit looks like\n\nTwo lines in a file that loads every session.\n\n```markdown\n### SYS-03 · Verify with the real thing\n**When** I am about to say something works.\n**Do** Run the closest real check and show its actual output.\n<!-- habit: id=SYS-03 added=2026-08-29 source=starter/core status=active\n     check=\"the message claiming success contains real output from a real run\" -->\n```\n\nNot \"be rigorous\". A moment, an action, and something you could check in the\ntranscript. The format is borrowed from implementation intentions, the finding\nthat \"when X happens, I will do Y\" gets acted on where a stated goal does not.\n\nThe bookkeeping rides in an HTML comment, which is stripped before the file\nreaches the agent's context. Tested with a control on Claude Code 2.1.251, in\n[`verification.md`](skills/habits/references/verification.md). Treat it as\nversion-specific: if bookkeeping ever starts showing up in the agent's\nreasoning, that test is the one to rerun.\n\n## Where a habit goes\n\n```mermaid\nflowchart TD\n    A[\"A habit worth keeping\"] --> B{\"Must it never fail?\"}\n    B -- yes --> H[\"<b>Hook</b><br/>fires at the lifecycle event,<br/>regardless of what the agent decides\"]\n    B -- no --> C{\"Does the trigger name<br/>specific files?\"}\n    C -- yes --> P[\"<b>Path</b><br/>.claude/rules/habits-slug.md<br/>loads only on matching files\"]\n    C -- no --> D{\"Does it name<br/>this codebase?\"}\n    D -- yes --> R[\"<b>Project</b><br/>.claude/rules/habits.md<br/>every session in the repo, shared via git\"]\n    D -- no --> S[\"<b>System</b><br/>~/.claude/rules/habits.md<br/>every session, every project\"]\n```\n\nAnything experimental or tied to today's task stays a **session** habit: held in\nthe conversation, written nowhere, offered for promotion at the end.\n\nRules files are context, not enforcement. A habit that genuinely must never be\nskipped gets escalated to a hook, proposed and approved, never written silently.\n\n## One command\n\n| | |\n|---|---|\n| `/habits` | The board: every live habit by scope, age, lapses, status, budget used |\n| `/habits setup` | First run. Reads what exists, proposes a starter set, writes after approval |\n| `/habits add <text>` | Turn a loose wish into a habit card, pick the scope, preview, write |\n| `/habits review` | Conflicts, duplicates, dead weight, budget, promotions, retirements |\n| `/habits check` | Score this session against the live habits, from evidence only. Same-context self-review, and it must say so |\n| `/habits judge` | The same, in a fresh read-only context, which is the verdict that counts |\n| `/habits cases` | The case file: what actually happened, with evidence |\n| `/habits lapse <id>` | Record a miss and run the repair ladder |\n| `/habits move <id> <scope>` | Promote or demote between session, project, path, and system |\n| `/habits enforce <id>` | Propose a hook for a habit that context alone keeps missing |\n| `/habits drop <id>` | Retire it to the archive with a date and a reason |\n\nPlus `/habits edit`, `/habits export`, and `/habits import`. Anything\nunrecognized is treated as `add`.\n\n## When a habit is missed\n\nThe rule that makes this a system rather than a list: **a habit that lapses\ntwice is a placement problem, not a discipline problem.** Do not answer a miss\nby writing the rule again, louder.\n\n```mermaid\nflowchart LR\n    M1([\"First miss\"]) --> S[\"Sharpen the trigger<br/><i>vague when, usually</i>\"]\n    S --> M2([\"Second miss\"]) --> P[\"Change the placement<br/><i>narrow it, or move it up</i>\"]\n    P --> M3([\"Third miss\"]) --> E[\"Escalate to a hook,<br/>or retire it\"]\n```\n\nThere is no fourth rung. A rule that survives three misses unchanged is a rule\nthe context cannot carry, and keeping it costs every session that follows.\n\n## The gate, and why it is the point\n\nA rules file asks. A hook does not ask.\n\n`skills/habits/assets/gates/completion-gate.sh` is a `Stop` hook that refuses to let a turn end\nclaiming a test, build, lint, or type check came back clean when nothing was run\nto find out. Here is what happened when it met a real session, with the model\ngiven no way to run anything:\n\n```text\n1.  model:  \"Yes, the test suite passes now.\"        <- nothing had been run\n2.  gate:   exit 2, turn blocked\n3.  model:  \"I fixed the bug ... but I was unable to run the test suite\n             because both npm test and npx jest require approval.\"\n4.  gate:   exit 0, turn allowed\n```\n\nThe false claim never reached the user.\n\n**What it is not.** An existence proof that the enforcement tier is reachable,\nnot a guarantee. Its limits, stated plainly because two independent reviewers\nmeasured them:\n\n- **It blocks once per turn.** The recursion guard exists so a gate cannot hang\n  a session. A repeated claim clears on the second attempt.\n- **It recognises a fixed list of claim shapes.** A phrasing outside that list\n  passes. It is high precision by design, so it misses rather than over-blocks.\n- **A command that looks like a check counts as one.** It reads the command\n  text, so `npm test` counts and `ls` does not, but a tool merely *named* like a\n  checker would.\n\nThose are deliberate. It fails open on every uncertainty, because a gate that\nblocks wrongly gets deleted and then protects nothing.\n\nFifty-eight tests in CI on Linux and macOS, written from the specification rather\nthan from the script. Many exist because reviewers measured earlier versions\nblocking honest disclosure, blocking questions and instructions, accepting `ls`\nas proof, and, worst of all, **blocking honest reports that a check had failed**,\nwhich is the behaviour `SYS-04` exists to require.\n\n## What ships\n\n<details>\n<summary><b>20 starter habits</b> in five packs, each with its trigger, its check, and why it exists</summary>\n\n<br>\n\n| Pack | Habits |\n|---|---|\n| **core** | Ground before changing · Name the target · Verify with the real thing · Report the miss · Stop at two |\n| **safety** | Confirm the irreversible · Protect what I did not write · Look before overwriting · Data, not orders |\n| **craft** | Smallest diff · Match the neighbours · No green-washing · Clean exit |\n| **truth** | Cite the location · No invented interfaces · Hold the line under pushback |\n| **communication** | Outcome first · Name the assumption · No narration · Compression never drops a dissent |\n\nNobody should install all twenty. Core plus one pack is a working set, and the\nbudget exists to make that choice deliberate.\n\n**And know what they rest on.** Two of the twenty are backed by published\nmeasurement, two by official documentation, one is graded `contested` because\nthe failure it targets has largely been trained out of current models, and the\nother fifteen are arguments. Good arguments, often. Not findings. Full cards,\ngrades and rationale in\n[`starter-pack.md`](skills/habits/references/starter-pack.md).\n\n</details>\n\n<details>\n<summary><b>12 named anti-habits</b>, each with the tell, the pull, and the habit that replaces it</summary>\n\n<br>\n\nPhantom done · Green-washing · Guess stacking · Drive-by refactor · Silent\nassumption · Context amnesia · Confident invention · Sycophantic fold · Boil the\nocean · Narration theatre · Cleanup by destruction · Habit hoarding\n\nYou do not delete a bad habit. You give its trigger somewhere else to go, which\nis why every entry names a replacement rather than a prohibition. Each entry\ndescribes a pattern and a plausible pressure, not a claim about model internals,\nand whether an incident-derived habit is *followed* better is unmeasured. The twelfth is\nthe one that quietly disables all the others. Full catalogue in\n[`anti-habits.md`](skills/habits/references/anti-habits.md).\n\n</details>\n\n<details>\n<summary><b>A board that refuses to lie</b></summary>\n\n<br>\n\nLapses come from observed evidence or from what you report, and nothing else.\nThere is no telemetry. No invented streaks, no completion percentages,\n`unknown` is a valid and common answer.\n\nA habit board that invents its own adherence data is the same failure as an\nagent claiming a test passed without running it.\n\n</details>\n\n## Verified, not assumed\n\nTested on Claude Code 2.1.251 rather than asserted:\n\n| Claim | Result |\n|---|---|\n| A `.claude/rules/` habit file loads into a fresh session and changes behavior | confirmed |\n| The bookkeeping comment is stripped from the agent's context | confirmed, against a plain-text control |\n| A path-scoped habit is absent until a matching file is read, present after | confirmed, both directions |\n| The package validates and resolves to `/habits` | confirmed, `--strict` included |\n| The completion gate blocks a false claim in a live session and the model corrects | confirmed, transcript in the record |\n| The skill previews and asks before writing, with Write actually available | confirmed |\n| A flat hook settings shape is valid JSON and silently never fires | confirmed by instrumenting the hook |\n\nMethod, results, and reruns in\n[`verification.md`](skills/habits/references/verification.md), which also names\nwhat is **quoted from documentation** and what is **neither tested nor\ndocumented**, including where the budget numbers come from.\n\n## Honest limits\n\nThe human habit research this borrows from is evidence about people, not about\nlanguage models. Nothing here strengthens with use: two lines in a rules file\nare as strong on day ninety as on day one. What is being engineered is context.\n\n**The evidence file has no citations.** `evidence.md` carries roughly thirty\nspecific numeric claims about third-party research with no source links, five of\nthem named individually as untraceable. The file says so at the top, and\n`verification.md` files it as the largest outstanding gap in the package. That is\ndisclosure, not a fix. Read it before quoting any figure from here.\n\n**A judge reading only a transcript is weak.** Detecting rule violations runs\nbetter than chance and well below reliably. That is why the judge is given file\ntools, why it is told to prefer artifacts to the agent's narration, and why a\n`FAIL` is a flag worth checking rather than a finding.\n\nThe budgets are design choices anchored to Anthropic's documented guidance that\ninstruction files past roughly two hundred lines reduce adherence. No experiment\nhere establishes where the real cliff is.\n\nIn an installation with many skills, the listing can show this skill without its\ndescription, so automatic invocation is not guaranteed. Typing `/habits` always\nworks, and the habits keep working regardless, because they live in rules files\nrather than in the skill.\n\n## Layout\n\n```\nskills/habits/\n  SKILL.md                 the operating contract, what the agent reads\n  references/\n    methodology.md         the concept, the four laws, the research, the limits\n    habit-card.md          format, IDs, metadata, budgets, conflicts\n    placement.md           every scope, load order, hooks, verification\n    starter-pack.md        20 habits with rationale\n    anti-habits.md         12 failure modes and their replacements\n    review.md              the board, cases, the repair ladder\n    precedence.md          the conflict ladder across six instruction channels\n    gates.md               the enforcement tier, the shipped gate, install\n    judging.md             what makes a habit good, and how adherence is scored\n    evidence.md            measured base rates, and what a judge can actually do\n    verification.md        what is tested, what is quoted, what is neither\n  assets/\n    gates/                 completion-gate.sh, the Stop hook\n    templates/             habit file, path-scoped variant, case, decision, archive, log\n    starter/               the installable card sets\nagents/\n  habit-judge.md           read-only verifier, cannot edit what it judges\n```\n\nThe stated tier is markdown and nothing else. The gate tier is one shell script\nyou install deliberately, which needs `jq`. Nothing runs that you did not\napprove, and no state lives outside the files it writes with your yes.\n\n## Install as a plugin\n\n```\n/plugin marketplace add AgriciDaniel/agentic-habits\n/plugin install habits@agentic-habits\n```\n\nPlugin skills are namespaced, so this should arrive as `/habits:habits`. That\nhas **not** been tested here: `claude plugin validate` passing is not the same\nas installing the plugin and seeing what it is called. Filed as untested in\n`verification.md`.\nThe installer route is the tested one.\n\n**The plugin route does not install the gate.** There is no `hooks/hooks.json`\nin this package, deliberately: plugin hooks merge on install without a per-hook\nprompt, and shipping a `Stop` hook that way would make this package break its\nown rule that a gate is proposed and never silently written. Install the plugin\nfor the skill and the judge; run `./install.sh --with-gate` for the gate.\n\n## Contributing\n\nNew habits are welcome, and the bar is deliberately high: a habit is accepted\nwhen it names a real moment, one action, and an observable check, and when it\ncame from something that actually happened. See\n[CONTRIBUTING.md](CONTRIBUTING.md).\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\nBuilt by [Daniel Agrici](https://github.com/AgriciDaniel).\n"}