The spec is
the source.
Keep durable intent beside the work it governs. HINT gives every agent the relevant rules, reports drift, and writes what the spec fully determines.
Works with Claude Code, Cursor, Codex, GitHub Copilot, OpenCode, or your own agent.
redline Survival never reached the document — the hintbook ships no template for it, so an internal position stays internal.
The agent asks for one topic and gets its evidence closure — not a dump of the whole wiki. hint lint . --strict-graph catches dead links, orphan topics, and duplicate identities in CI.
Spec-as-Source, without the model in the loop.
Spec-as-Source is the position that the specification — not the code — is the artifact you maintain and the authority the work answers to. The usual formulation attaches a second clause: and the code is regenerated from the spec by a model. That clause is what has kept the idea impractical. Model output is non-deterministic, so every regeneration is a re-roll, every hand edit fights the generator, and drift comes back through the door built for it.
HINT drops the model, not the source of truth. The .hint files hold the intent. Where a spec describes something machine-derivable, a template renders it — byte-identical every run, reviewable in a normal diff. Where it does not, humans and agents do the work. Three mechanisms keep the two coupled, and not one of them calls a model.
Retrieval before the work
hint <path> returns the part of the spec that governs that path, inherited root-first, and nothing else. Cheap enough to run before every edit — which is the only way it gets run.
Drift detection after it
hint status, and an advisory line on every read, say when the implementation has moved away from the spec governing it — while the correction is still cheap.
Emission where it is derivable
hint emit writes the part of a file the spec fully determines, through templates the hintbook supplies. What no template can derive becomes a hole — with the constraints it must honor printed above it, and your implementation kept across every re-emit. hint emit --check gates it in CI.
| Spec Kit · Kiro · Tessl · … | HINT | |
|---|---|---|
| Unit of spec | one central folder, per feature | per path, inherited root → folder → file |
| Contents | requirements, design, tasks with statuses | durable intent only — never task state |
| Lifetime | the feature | the repository |
| Coupling to the work | regeneration by a model | retrieval before, drift detection after, deterministic emission between |
| Ownership | the vendor's ecosystem | your repository, in git, agent-neutral |
| Domain | software | any — the vocabulary is installed, not compiled in |
The per-feature shape is the one that matters most in practice: it cannot say “strict typing here, and a documented exception in the legacy module.” Scoping is not a detail — it is the reason one global instruction file fails, and one central spec folder fails the same way for the same reason.
The engine ships with no vocabulary at all.
Every other tool in this category has its vocabulary compiled in, which is why every one of them is about software. HINT's engine knows no keywords at all — it understands files, headings, nesting, and inheritance. What a decision, an invariant, a clause, or an obligation means comes from a hintbook: a flat folder of Markdown templates you install like a dependency.
| A software repository | A law firm's matters | A knowledge wiki | |
|---|---|---|---|
| Hintbook | hintbook-software-engineer | hintbook-lawyer | hintbook-librarian |
| Vocabulary | decision invariant func entity bad | party clause obligation right redline | source concept claim decision openquestion |
| A scope | src/billing/_.hint governs billing | clients/acme/nda/_.hint governs that matter | wiki/retrieval/_.hint defines one linked topic |
| Before touching it | the constraints that apply to this file | the constraints that apply to this document | the topic, claims, and linked evidence needed now |
| Drift means | the code moved away from the spec | the document moved away from the position | a dead link, orphan topic, or conflicting identity appeared |
Nothing in the engine changes between those columns — that is the whole point. Authoring a hintbook takes no programming: Markdown files with {name}-style placeholders. A profession that can write down its own rules can have a vocabulary for them.
One instruction file for the whole repo is the wrong shape.
A CLAUDE.md grows without bound, applies everywhere at once, and gets loaded whole on every task — so most of what the agent reads is irrelevant, and the part that mattered was three hundred lines down. HINT scopes knowledge to the paths it governs and returns only what applies.
Zero syntax friction
A .hint file is pure Markdown. Nothing new to learn, instantly readable by humans and AI alike, with native highlighting in any editor.
Scoped and inherited
A folder's _.hint governs everything beneath it; a path picks up its own knowledge plus every ancestor. A rule about billing governs billing — and nothing else.
Costs what it carries
Output is proportional to how much applies — a path nothing governs returns nothing. Cheap enough to ask before every edit, which is the only way it gets used.
Three rungs. Climb only as far as a file earns.
A repository does not have to pick one rung for all of itself. Most files stay on the first; a handful of contracts earn the second; the mechanical part of a few earns the third. Each rung is the one below it plus one more guarantee.
The spec is written down
Every heading is a typed block — decision, invariant, bad, clause. hint <path> returns the part that governs that path, inherited root-first, and nothing else.
hint src/billing/invoice.ts
The code answers to it
A spec that declares surfaces is compared against what the file actually contains — parameters, their types, the return. Deterministic and token-free, so it belongs in CI rather than in a review comment.
hint verify src/billing/invoice.ts
The spec writes it
For the part a template fully determines, the duplication disappears: the file is produced from the spec, and what cannot be derived is left as a hole for you or your agent to fill.
hint emit src/billing/invoice.ts
hint search "how do we sign tokens" ranks every spec offline.
hint extract src/billing drafts the specs from it — the on-ramp for a repository that did not start this way.
Or never run it by hand at all.
hint apply writes a short block into your AGENTS.md and CLAUDE.md teaching an agent how to query HINT — and how to record what it learns. After that, just keep working in normal dialogue; the agent calls hint itself. The block stays small: the knowledge stays in .hint, never duplicated into tool-specific files.
What the spec determines, the spec writes.
Half of what a spec says is mechanical — the types, the fields, the signatures, the clause structure. Keeping a second hand-written copy of it is the duplication that makes specs rot. hint emit renders that half through the hintbook's templates, and leaves the other half — the part that takes judgment — as a marked hole.
Your imports
The emitter knows the type names the spec used, and can never know which module of your project provides them. So it lists what is still outstanding, and the list disappears when nothing is.
The spec's, rewritten each run
Declarations the spec fully determines. Byte-identical every time, so hint emit --check is an assertion in CI rather than an opinion.
hint:endYours, untouched
Helpers, and anything the spec does not own. Both boundaries say which zone they open and close, so the split is a structure rather than something to remember.
A hole is where the work goes
What no template can derive becomes a hole, with the constraints that govern it printed directly above — the bad, the flow, the invariant it must honor. Fill it once and it survives every re-emission. Change the spec and the declarations move while your body stays.
It refuses rather than loses
If the spec block that owned an implementation is deleted or renamed, the write is refused and the labels are named — because a body with nowhere to go cannot be recovered afterwards. The same applies to a file somebody already wrote by hand: HINT will not append a region to it without being asked.
And what it cannot write, it can still check.
A spec that declares surfaces — a func, an entity, a field — can be checked against the code mechanically. hint verify compares shape: the declared parameters, their types, the return type, the fields of a structure. No model, no tokens, exits non-zero so CI can gate on it.
| Nine languages, nothing to install | Read through |
|---|---|
typescript javascript | your project's own typescript |
python | Python's ast, from the standard library |
go | Go's go/ast, from the standard library |
ruby | Ruby's Ripper, from the standard library |
json yaml toml | Node's parser, the engine's own, Python's tomllib |
sql | SQLite's parser, via Python's sqlite3 |
Every one parses with the language's own parser — none of them is a parser we wrote. That is the entry requirement, not a coincidence: a hand-written parser that is subtly wrong produces confident, wrong findings, and this is a check you are meant to gate a merge on. A language whose parser cannot be reached without an install stays an external command instead.
It never reports a check it did not run.
Having no adapter is a supported setup and passes in silence. An adapter that was configured and could not answer — a missing toolchain, a version that moved, a file that will not parse — is named on stderr with its own reason, and the summary says it fell back to the weaker check. The alternative is a project that believes it has conformance checking while nothing is being checked.
A small, honest core. An open, extensible vocabulary.
The engine understands only structure — files, headings, bodies. What each keyword means is supplied by hintbooks: installable packages of instruction templates. Swap the book, and the same files render in a different profession's language.
Not by one AI tool
.hint is the source of truth, versioned in git and reviewed in normal diffs. Every agent reads the same answer; nothing is duplicated into tool-specific files.
It tells you when it matched nothing
A mistyped path, a glob that hit nothing, a check with no target — each says so and exits non-zero. 0 succeeded, 1 a check failed, 2 nothing matched.
The vocabulary is yours
Publish your own hintbook as an npm package, a git repo, or a plain folder. Authoring one needs no code — if you can write Markdown, you can build it.
Same input, same output
Sorted traversal, stable trees, pure interpolation — byte-identical output you can diff in CI. Retrieval is local BM25F: no model, no service, no network, nothing read into your context.
Software is the first vocabulary — not the definition.
HINT isn't only for programmers. Any repository of high-stakes work has knowledge worth scoping to the paths it governs: the engineer knows the architecture, the lawyer knows the deal, and the librarian keeps a shared wiki grounded in sources.
Software Engineers
Architecture, contracts, data models, and anti-patterns
Lawyers
Matters, clauses, obligations, sources, and red lines
Knowledge Librarians
Sources, claims, decisions, open questions, and linked topics
Business Analysts
Requirements, use cases, business rules, and traceability
Product Managers
PRDs, stories, criteria, goals, and sourced metrics
QA Engineers
Test plans, negative paths, coverage, and deterministic Gherkin
Not just for programmers — context for your assistant.
HINT pays off most wherever a wrong answer is expensive: analytics, compliance, finance, procurement, medicine, government, QA, documentation, and product. Anywhere the job means repeatable, high-stakes artifacts.
hintbook-software-engineer
liveA shared core plus engineering contracts for intent, data, behavior, UI and constraints.
hintbook-lawyer
liveA shared core plus the vocabulary of matters, clauses, obligations and red lines.
hintbook-librarian
live22 keywords including the shared core, for source-grounded knowledge and typed links.
From zero to a spec that governs your repo, in five minutes.
Let the agent you already use set it up.
Paste this into Claude Code, Codex, Cursor, VS Code / GitHub Copilot, or another coding agent. The CLI prints a self-contained prompt; the agent initializes HINT, merges only its own project-level MCP configuration, and verifies the result.
Install & initialize
Install the CLI, then mark the project root. hint config writes hint.yml; hint apply teaches your agent how to query HINT.
Record it, then ask about a path
Write what future work must know, then run hint <path> before changing that path. Use hint search when you know the task rather than the file, and hint status to inventory drift.
Optional: let the spec write the file
With an emit pack installed, the spec produces the artifact. A generated file has three zones and every marker names the one it opens or closes: above the region are your imports, inside it is what the spec owns and rewrites each run, below it is yours. Implementations go in a hole and survive every re-emit — and if the block that owned one is deleted, the write is refused rather than losing the work. Already have code? hint extract drafts specs from it.
The short version
What is HINT?
HINT keeps durable project knowledge in Markdown files beside the work it governs and returns the relevant part on demand.
Does HINT call an AI model?
No. Retrieval, compilation, verification and emission are deterministic local operations.
Which assistants work with HINT?
Any assistant that can run commands or connect through MCP, including Claude Code, Cursor, Codex, GitHub Copilot and OpenCode.
Is HINT only for software?
No. Install a profession hintbook to use the same engine for legal, audit, product, documentation and other work.
Stop re-explaining your repo.
Write it down once, next to the code. Every agent, every session, gets exactly what applies.