-
Notifications
You must be signed in to change notification settings - Fork 0
Connecting Your Project
Every fact KAUT stores is bound to a data source — a code file, a glob, a ticket, a human
statement, or a file in another repository — and anchored to the commit it was derived at.
That binding is what makes freshness mechanical: when the bound sources change, the fact
flips stale without any AI involved. This page explains the binding grammar, the store
layers, what belongs in each, and how multi-repo workspaces extend the same model across
repositories. The normative contract behind all of it is SCHEMA.md in the repo.
Each doc's frontmatter declares one or more typed sources (SCHEMA.md §2.1, §17):
file:src/router/routes.ts one file, relative to the project repo root
file-glob:packages/core/src/** a glob, relative to the project repo root
ticket:TICKET-16576 a ticket reference (provenance only)
user:2026-06-10 a human statement, dated (provenance only)
repo:billing:file:openapi/api.yaml a file in another workspace member repo (see below)
- Only
file:/file-glob:participate in freshness diffing and thebrokenrule;ticket:/user:are provenance — they can never go stale or break. -
repo:<name>:file:<path>is resolved through the workspace registry and checked existence-only at that member repo's HEAD: missing ⇒broken; present ⇒ never stale. - An OpenAPI-style fragment (
file:openapi/api.yaml#/components/...) is stripped to the file path for diffing; the fragment stays in the raw value for human reference.
No source — no claim. Unsourced text cannot enter the store.
The frontmatter sources: list binds the whole doc. A section can scope its own binding
with a comment immediately after its ## heading:
## Pointers
<!-- sources: file:src/router/routes.ts -->
<!-- trust: T1 -->A section with its own binding is evaluated against those sources; a section without one
inherits the doc-level list. The doc's verdict is the worst section's; the affected-files
list is the union. Section bindings are also what kaut touched matches when it names the
docs a code change owes an update.
Every doc records the commit it was true at — always a commit on the main line (the
tracked main branch), never a feature branch or the working tree. Freshness is evaluated
against the merge base with main, so working on a branch never flaps stored verdicts; your
branch's own edits surface only as an ephemeral branch-advisory at read time.
When re-deriving, anchor to the main branch tip — kaut refresh names the exact target
ref. The draft queue enforces this at the door: an anchor that is not a commit of the anchor
repo, or not on its main line, is refused.
-
stale—git diffover the doc's file sources betweenderived_from_commitand the main-line anchor is non-empty; or (err-toward-stale) the anchor commit is unknown to the repo or not an ancestor of the main line. -
broken— afile:/file-glob:source matches zero paths in the anchor tree. A broken pattern cannot be diffed, so it never reports fresh — renames and typos are caught, not hidden. Arepo:source whose path is missing at the member's HEAD is broken too; an unresolvable registry or member repo makes the docstalewith an "unverifiable" note — the engine errs toward stale, never toward fresh.
The full verdict set and priority (tampered > disputed > broken > stale > branch-advisory)
is in SCHEMA.md §11 and §16; exactly one verdict renders per answer.
The directory a doc lives in is its layer (id = path without .md):
| Layer | What belongs there |
|---|---|
map/ |
The project skeleton — route table, package graph, service map. Script-generated (T0), regenerated by kaut map, never hand-edited |
domains/ |
Thin per-domain notes: pointers and invariants — where things live and what must hold, not retellings of code |
decisions/ |
The "why": business rules, constraints, decisions with their reasons, ticket-anchored |
flows/ |
End-to-end flows across components — how a request/feature traverses the system |
contracts/ |
Interface agreements between components or repos (APIs, message shapes) |
runbook/ |
Operational procedures verified by running them (startup, debug, environments) |
bootstrap/ |
Orientation plans for working in a repo — where to start, what to read |
The litmus test decides what may be stored at all:
If tomorrow's agent can get it from the code cheaply — don't store it.
KAUT stores what code cannot say: intent, business rules, constraints, decisions and their reasons. Everything cheaply derivable from code is derived on demand instead — a derived fact can go stale; a re-derived one cannot.
kaut map regenerates the map/ layer deterministically (no LLM). Which collectors run,
and where they look, is configuration in the store's kaut.config.json:
-
map.collectors— any ofroutemap|pkggraph|composemap; default["routemap", "pkggraph"];[]disables map generation. -
map.routesFile/map.constantsFile— route-map inputs (default is Vue-conventionalsrc/router/routes.ts). If the file is absent, the collector is skipped with a note and the rest still run. -
map.packagesDir— package-graph monorepo directory (defaultpackages). -
map.composeFile— compose-map input (defaultdocker-compose.yml).
Each adapter refuses to write rather than emit a partial map when its input fails its
self-check. Full config reference: docs/HANDBOOK.md §15.
For a landscape of repositories, kaut workspace init derives everything from one manifest
owned by your orchestration framework (e.g. TAUT):
node <engine>/kaut.mjs workspace init --manifest <conductor>/manifest.json
node <engine>/kaut.mjs workspace listWhat it gives you (SCHEMA.md §21):
-
A workspace registry (
~/.kaut/workspaces/<name>.json) — a derived copy of the manifest, regenerated wholesale on every init; the resolver behindrepo:sources and the workspace-widedoctor/stale/digestsweeps. -
A store per member repo, provisioned through the ordinary bootstrap (idempotent; a
member marked
do-not-touchin the manifest gets a registry entry and nothing else). -
One system store for landscape-level knowledge (cross-repo flows, contracts,
runbooks), anchored to a launcher repo via config
project.anchorRepo— its freshness is checked against that repo no matter where it is read from. -
Cross-repo bindings —
repo:<name>:file:<path>sources let a doc in one store cite files in sibling repos, resolved through the registry.
One MCP server then serves the whole workspace — each tool call names its repo (MCP Server).