precedent

skill
Security Audit
Warn
Health Warn
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Claude Code skill: remembers your architectural and business decisions across every project, and surfaces them as precedent when a comparable choice comes up.

README.md

precedent

test
license
version

precedent gives your coding agent a memory of the architectural, business and tooling
choices you have settled — across every project, for years — and puts them back in front of
you when a similar choice comes up again.

You decided something two years ago, in a repo you have not opened since, for a reason that
made sense at the time. The code still shows what you chose. The why is gone, and so is
the list of things you rejected on the way. precedent keeps all three and hands them to the
agent while the choice is still on the table.

Works with Claude Code, Codex and Cursor.

What it looks like

A session opens. Before you type anything, the agent is handed this:

project: gym-bot   tags: bot, telegram, python

== decided here (2) ==
  [architecture] webhook, not polling  (ingest)
  [tooling] uv, no durable venv  (packaging)

== precedent from comparable projects ==
  persistence: postgres   [3x: bot-alpha,bot-beta,bot-gamma]
  logging: structlog      [3x: bot-alpha,bot-beta,bot-gamma]

Then you work normally. You never type a command:

you    Let's just use SQLite for bot state, keeps deploy simple.

agent  Worth knowing first: you rejected SQLite for bot state in bot-alpha —
       "two bots already share one Postgres; SQLite locks up once webhook
       handlers run concurrently." You chose Postgres for this in 3 other
       projects.

       That reason is about concurrent writers. This bot has one handler and
       one writer, so it does not apply here. SQLite is fine.

       Want me to record it as a deliberate departure, so the warning stops
       firing in this project but still fires elsewhere?

you    yes

agent  Recorded: persistence -> sqlite, despite the Postgres precedent.

That is the whole loop. The agent reads the graph when you weigh something, writes to it when
you settle something, and asks before writing — a wrong entry is worse than a missing one,
because it gets quoted back as precedent.

A warning is not a veto. Every rationale carries a condition, and the agent's job is to ask
whether that condition still holds. Consistency is usually right, and sometimes exactly wrong.

What the agent does with it

You say It does
"let's go with X" records the decision, with your reason and what you rejected
"what did I use last time" / "which should I use here" prior decisions on that topic, plus a verdict on the option you named
"X was a mistake" / "X bit us" / "never again" inverts the precedent — every project that chose X stops counting toward the pattern
"I usually do X, but not here" records the departure so the warning is answered, not repeated forever
starting work somewhere it has not briefed you on reads the project and records the decisions already visible in its manifests, CI and docs

Ten skills carry this, one per path (record, check, regret, diverge, prime, tag,
analyze, suggest, maintain, plus the judgment skill that decides which applies). Each
fires from its own description, so nothing has to be typed. If you want to type, they are
slash commands in Claude Code and Cursor, $-prefixed in Codex.

Install

Requires uv and Python 3.12+, and Claude Code, Codex or Cursor.
Linux, macOS or Windows. The CLI itself has no install step: it is a PEP 723 script with its
package beside it, and uv fetches what it needs on first run, then reuses a cached
environment. (A persistent virtualenv was measured and rejected. It saves 11 ms per call, both
paths being dominated by the engine import, and costs an install step plus an environment to
keep in sync.) What differs by agent is how the skills and the hook get in front of it.

Claude Code can take either channel below; Codex and Cursor only ACR. Pick one per machine —
both channels install the same SessionStart hook, and two of them prime every session twice.

Without uv

The CLI is plain Python 3.12+ with one dependency, graphdblite. <cli> below is
adapters/claude/skills/precedent/scripts/precedent.py in a clone, or the path the session
brief prints. Run it as a file, from any directory; do not copy precedent.py away from the
precedent_cli/ directory next to it.

pipx (1.4 or later) is the closest to uv. It reads the same inline metadata, installs
graphdblite into a cached environment on first run and reuses it afterwards, so there is no
manual install:

python3 -m pip install --user pipx   # or: brew install pipx / apt install pipx / scoop install pipx
pipx run <cli> brief --project .

A virtualenv and pip, if you'd rather not add pipx. Here you install the dependency yourself,
once:

python3 -m venv ~/.local/share/precedent/venv
~/.local/share/precedent/venv/bin/python -m pip install graphdblite
~/.local/share/precedent/venv/bin/python <cli> brief --project .

On Windows, create the venv with py -3.12 -m venv ... (or python -m venv ...), since
python3 often doesn't exist there; the interpreter is then ...\venv\Scripts\python.exe.
Installing into the system Python
(pip install graphdblite with no venv) also works where your distribution allows it; many
refuse with externally-managed-environment (PEP 668), which is why the venv is the example.

The skills and the session-start hook call uv run. Without uv the hook stays silent, so
tell the agent which interpreter to use, or run the commands yourself.

Claude Code plugin

Two commands, no bootstrap binary:

/plugin marketplace add asm0dey/precedent
/plugin install precedent@precedent

That installs the ten skills and wires the session-start hook. The statusline badge is still
manual — Claude Code has no plugin-provided statusline (docs/setup.md).

The plugin root is the repository root, not adapters/claude/. /plugin install copies the
plugin root and nothing above it, so an adapter-rooted plugin would ship the skills and the hook
without the CLI all of them drive (it lives in the precedent skill's scripts/) — and the hook
fails closed, which looks exactly like a quiet session. Rooting at the repository puts the CLI
inside the installed tree at the path the hook already resolves in a clone. The cost is that
skills and the hook are no longer where convention looks, so .claude-plugin/plugin.json names
both paths.

Both manifests, plugin.json and marketplace.json, are generated from the ACR manifest below by
scripts/gen-plugin-json.py (--check fails CI if they drift, or if a path plugin.json names
stops existing).

ACR (Codex, Cursor, and Claude Code)

ACR is the only channel that reaches Codex
and Cursor. It is driven by agent-plugin.yaml, which ships the ten skills, with the CLI inside the
precedent one, and the session-start hook:

acr install github:asm0dey/precedent --agent claude-code   # or codex, or cursor
acr realize

install resolves the latest GitHub release, so a release has to exist. Each of the ten skills
is its own artifact, and realize writes them into the agent's own skills directory:
.claude/skills/, .codex/skills/ or .cursor/skills/ as appropriate.

All three agents read those paths, so every skill works on every agent. The realized directories
carry an ACR prefix (acr__asm0dey__precedent__precedent-check), which matters only if you type
the name: skills fire from their descriptions, and that is how they are meant to fire. Codex
registers them under their frontmatter name regardless, so $precedent-check works there.

Manual symlink

What every channel above ends up doing to ~/.claude/, done by hand. Also the option if you
would rather not add a marketplace or install ACR:

git clone https://github.com/asm0dey/precedent ~/src/precedent
ln -s ~/src/precedent/adapters/claude/skills/* ~/.claude/skills/

Then wire the session-start hook

The hook runs a brief for the working directory and injects it, so a session opens already
knowing what you decided here and in comparable projects. It stays quiet where the graph has
nothing to say, so empty directories cost nothing. ACR wires it for you; the plugin ships it in
hooks.json; the symlink route needs a few lines in ~/.claude/settings.json.

Subagents never see a session's hook output, so the plugin's hooks.json also runs the same
hook on SubagentStart (session-start.sh --subagent): every subagent gets the brief for its
own working directory and the standing orders, except read-only helpers such as Explore.
ACR installs have no subagent hook; there, copy the precedents that bind the task into each
subagent prompt.

In Claude Code builds with function hooks (mods), the plugin also loads
adapters/claude/hooks/register.ts, which turns two standing orders from reminders into
behaviour: a Bash cd into another project attaches that project's brief, and a manifest edit
that adds an option you recorded as rejected or regretted (H2, Dependabot, ...) attaches those
records for the model to judge. Elsewhere it does not load and the skill works as before.

That wiring, the [PRECEDENT] statusline badge, the Windows PowerShell variants, where the store
lives and how to move or sync it, and the CLI underneath all of it:
docs/setup.md.

Is this a memory layer?

It is memory, in the sense that something survives the end of the session. What goes in is a
lot narrower than what most tools in that space keep.

The unit here is a settled decision: a topic, the option you chose, the options you
rejected, and the reason. That is the entire record. Transcripts, session summaries and
inferred preferences about your coding style all stay out of it.

Three things follow from that shape.

Rejected options get a home. sqlite sits in the graph as the thing three projects turned
down, with the reason attached. A store that keeps what is true has nowhere to put what you
decided against, which is precisely what you need at the moment you are about to choose it
again.

Retrieval runs on project kinship. Precedent is ranked by how many tags two projects share,
and the output names the tags that did the matching. Your Telegram bot inherits from your other
Telegram bots. Your Next.js app stays out of it, however close the sentences describing them
embed.

A norm can be inverted. Marking a repeated choice as a regret makes every project that made
it stop counting toward the pattern. Without that, "you chose mongo in eight projects" argues
for a ninth, and repetition turns a scar into a recommendation.

Principles reach every session. A choice promoted to a principle, or a topicless one you add
yourself (principle --id no-pgrep-f --statement "..."), prints with the standing orders at
the start of every session, in every directory and for every agent. principle --id X --retire --because "..." stops it, and keeps the reason.

How it compares

Stores Retrieval Scope Answers with
precedent settled decisions with rejected options tag overlap between projects every project you work in a verdict (CONFLICT / DIVERGENCE / REGRET)
Mem0, Zep / Graphiti, Letta facts and preferences extracted from conversation embedding similarity, plus a graph of entities; Zep adds validity windows over time a user or an assistant relevant memories
OpenMemory MCP, basic-memory notes and captured preferences, as markdown or a local store search over the note index one user across MCP clients matching notes
CLAUDE.md, AGENTS.md, editor rules instructions you wrote by hand loaded whole, every session the repo the file sits in the file's contents
adr-tools, Log4brains ADRs as markdown, with supersession links grep, or a generated site the repo, or a site built from several the document you searched for

The row that comes closest is the ADR one, and the gap is when the answer arrives. An ADR is a
document you go and read, filed in the repo where the decision was made. Precedent is queried by
the agent while a choice is on the table, in whatever repo you happen to be in, and it answers
with a verdict about the option you named. The two coexist happily. This repo keeps ADRs under
docs/adr/ and records the same decisions in the graph.

The other rows are answering a different question. They are built to remember you across
conversations. Precedent remembers what you settled, which is a much smaller set, and worth
carrying between projects for years.

What it does not do

  • No semantic search. Ask it about "the database thing" and you get nothing; ask about the
    persistence topic and you get everything.
  • No conversation history. It never sees your chats, only the records the agent writes.
  • Tags come from the agent, never from a keyword rule (see How it finds comparable work).
  • Single user, local files. Syncing across machines has a sharp edge, covered in
    docs/setup.md.

When precedent does not simply apply

Four situations get confused with each other, and each wants a different record. You say the
ordinary sentence; the agent picks the right one.

The situation What gets recorded
The precedent is sound, but this project is genuinely different a decision despite the precedent
The choice was right then and is wrong now, here a decision that supersedes the old one
The choice was wrong everywhere, and you repeated it a regret, which inverts the norm
The choice was right — you just wrote it down badly an amendment, which rewords it in place

The first matters more than it looks. Diverge without recording why, and the graph reports
DIVERGENCE in that project forever: a warning that is correct, unanswerable and permanent,
which is how a useful signal becomes noise. Record the exception and it reads as acknowledged
here
, while the plain warning still fires everywhere else.

The third exists because repetition is what gives precedent its weight, which is a problem when
the repeated thing was a mistake. Without it, "you chose mongo in eight projects" reads as a
strong norm. Afterwards the agent is told:

REGRET: you chose this in 8 project(s) and later concluded it was a mistake —
   "schema drift made every migration a manual rewrite ..."
   you now prefer: postgres

Nothing is deleted. The eight keep their original rationales, because a reason that looked good
eight separate times is what tells you the lesson was expensive and the trap convincing. They
simply stop counting as a norm.

The fourth looks like the smallest and is the one worth getting right. check prints the title
first, so the title is the part quoted back as your own reasoning — and a decision titled more
narrowly than it is gets read as not-applicable, re-litigated, and answered a second time. An
amendment fixes the words without inventing a change of mind, and the id keeps resolving.

How it finds comparable work

A project carries a set of tags, never one type. A service is not backend or java or
distributed. It is all three, and which of them a past decision rhymes with depends on the
decision. Persistence choices travel along backend, build choices along java, retry
semantics along distributed.

Precedent is ranked by tag overlap, so a sibling sharing four tags outranks one sharing a
single generic tag, and you can see which tags did the matching.

Tags are supplied by the agent, never inferred. Keyword matching was tried and removed: a Rust
CLI named nextgen was classified web-frontend because the word "next" appeared in its
description, and react-native matched react before it could match itself. A wrong
classification is worse than none, because the project then silently inherits decisions from
unrelated work.

There is no list of known build files either. The tool shows the directory's top-level contents
and lets the agent read them, so build.zig, shard.yml, BUILD.bazel or whatever appears
next year is as visible as package.json.

Monorepos need no special handling. Containment is a string-prefix fact over the path key,
so tagging /repo/backend and /repo/slackbot separately keeps them from lending each other
precedent, while decisions recorded at /repo (CI, branching, licensing) are inherited by both.
A project's durable identity is its git remote, so a clone at a different path still resolves to
the same node; the local path stays as an alias. See docs/adr/0002.

Measured

Four realistic prompts, run by subagents with the skill and without it, graded against 29
assertions by an independent grader: 26/29 (90%) with the skill against a 35% ± 15%
baseline, for +36s and +6.9k tokens per run.

The sharpest result is a baseline failure. Asked what to be consistent with when starting a new
Telegram bot, the skill-less run read the manifests of two unrelated FastAPI services and
recommended async SQLAlchemy: precedent transferred across the wrong kind of project, stated
confidently.

The full table, what the three failures were, and which numbers are carried over rather than
re-run: docs/measured.md. evals/ holds the prompts, assertions and a
fixture seeder.

License

MIT

Reviews (0)

No results found