Spec-as-Source · Scoped · Agent-neutral · Any profession

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.

$ npx -y @openhint/cli bootstrap

Works with Claude Code, Cursor, Codex, GitHub Copilot, OpenCode, or your own agent.

api/invoice.ts.hint Markdown
# entity Invoice {#invoice} Persisted invoice record. ## field total: Decimal Decimal string, 2 places. Never float. # func validateInvoice ## arg invoice: Invoice ## result: Invoice ## bad SilentDefaults Never make an invalid Invoice appear valid.
hint emit api/invoice.ts
api/invoice.ts — written by the spec deterministic
// hint:begin — generated from api/invoice.ts.hint // Needs importing above this region: // Decimal // Persisted invoice record. export interface Invoice { // Decimal string, 2 places. Never float. total: Decimal; } export function validateInvoice(invoice: Invoice): Invoice { // Honor: // bad SilentDefaults: // Never make an invalid Invoice appear valid. // hint:hole(func validateInvoice:body) — your code; kept across re-emits. throw new Error("Not implemented."); // hint:end of hole. } // hint:end — everything below is yours; the spec never touches it.
The spec is maintained. The implementation answers to it. No model in the loop — retrieval before, emission between, drift detection after
The paradigm

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 specone central folder, per featureper path, inherited root → folder → file
Contentsrequirements, design, tasks with statusesdurable intent only — never task state
Lifetimethe featurethe repository
Coupling to the workregeneration by a modelretrieval before, drift detection after, deterministic emission between
Ownershipthe vendor's ecosystemyour repository, in git, agent-neutral
Domainsoftwareany — 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.

Beyond code

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 repositoryA law firm's mattersA knowledge wiki
Hintbookhintbook-software-engineerhintbook-lawyerhintbook-librarian
Vocabularydecision invariant func entity badparty clause obligation right redlinesource concept claim decision openquestion
A scopesrc/billing/_.hint governs billingclients/acme/nda/_.hint governs that matterwiki/retrieval/_.hint defines one linked topic
Before touching itthe constraints that apply to this filethe constraints that apply to this documentthe topic, claims, and linked evidence needed now
Drift meansthe code moved away from the specthe document moved away from the positiona 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.

What is HINT

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.

How it works

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.

01 / RECORD

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
02 / CHECK

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
03 / GENERATE

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
Know the task but not the path? hint search "how do we sign tokens" ranks every spec offline.
Already have the code? 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.

Emission

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.

Above the region

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.

Inside the region

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.

Below hint:end

Yours, 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.

Conformance

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 installRead through
typescript javascriptyour project's own typescript
pythonPython's ast, from the standard library
goGo's go/ast, from the standard library
rubyRuby's Ripper, from the standard library
json yaml tomlNode's parser, the engine's own, Python's tomllib
sqlSQLite'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.

The design

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.

Owned by the repo

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.

Never a hollow success

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.

No built-in keywords

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.

Deterministic & convergent

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.

Built for every profession

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.

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.

Contracts Policies Requirements Specs Reports Audits Test cases Checklists RFPs Proposals Documentation SOPs Acceptance criteria

hintbook-software-engineer

live
goalscopeentityfieldfuncflowerrorrulebadtestuidep

A shared core plus engineering contracts for intent, data, behavior, UI and constraints.

hintbook-lawyer

live
partyclauseobligationrightexceptionbreachredlineneverliabilityauthority

A shared core plus the vocabulary of matters, clauses, obligations and red lines.

hintbook-librarian

live
sourceconceptentityclaimdecisionopenquestionsupersedesrelates

22 keywords including the shared core, for source-grounded knowledge and typed links.

Quick start

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.

Run `npx -y @openhint/cli bootstrap` from the repository root and follow exactly what it prints.
01

Install & initialize

Install the CLI, then mark the project root. hint config writes hint.yml; hint apply teaches your agent how to query HINT.

# install the CLI npm install -g @openhint/cli # scaffold + register a hintbook hint config hint add @openhint/hintbook-software-engineer # teach your agent to query HINT hint apply
02

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.

# what does this repo already know about this path? hint src/billing/invoice.ts # know the task, not the path? rank every .hint, offline hint search "how are invoice totals stored" # what has come loose from the code it describes? hint status # handing work to a fresh agent? add the framing hint --prompt src/billing/invoice.ts | claude -p # optional: for specs that declare surfaces the code must contain hint verify src/billing/invoice.ts hint lock src/billing/invoice.ts
03

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.

# write the artifact this spec produces hint emit src/billing/invoice.ts # CI: everything committed still equals what its spec produces hint emit --check # brownfield: draft specs from code that already exists hint extract src/billing
FAQ

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.