Skip to main content

The project store

A kapi project consists of:

  • the recipe (kapi.yaml), your config: content, where each voice and set of terms applies, flows, defaults, languages;
  • the files, your deliverable: the source and target files on disk;
  • the project store, your work: what kapi derives from your files, plus the context the project works under and the decisions people record in it.

The storage model has two authoritative sources:

Your files are the source of truth for the deliverable, and the store is the source of truth for the context. Derived indexes and caches can be rebuilt.

What's in the store​

kapi separates derived content data from authored context. The checkout index belongs to one checkout; the context database is shared by the project's checkouts in the local workspace.

LayerLives inKindLose it?
context storea workspace under your data directoryauthored: terms, voice profiles, content memory, recorded decisionsback it up with kapi store export
historythe same workspaceevery note, suggestion and decision, with the evidence behind each (Growing context)shared by kapi context sync, and included in an export
drafts waiting for reviewthe same workspaceauthored: the drafts of a language whose files materialize: on-converge withholds, and the edits made to themkept until a delivery writes them to their files
checkout index.kapi/work/store.dbderived from your files: the block cache, the overlays a run wrote, the extraction stampsrebuilds on the next run
cache.kapi/work/cache/derived: parse cache, extractions, collections, sync cacherebuilds on the next run

The checkout index stays with your checkout​

.kapi/work/store.db holds what kapi read out of the working tree: the parsed blocks, the translations a run produced before you merged them, and the stamps that let the next run skip a file it has already read. A second checkout of the project keeps one of its own, because each describes the tree beside it.

The context store sits outside your checkout​

The terms, the voice profiles, the content memory and the record of who approved what live in a workspace under your per-user data directory, one database per project:

<data directory>/workspaces/default/
workspace.db the project registry, the context graph, and the record
of what people and agents have recorded and decided
projects/<key>.db one project's terms, voice profiles, memory and decisions

The data directory is $KAPI_DATA_DIR when you set it, $XDG_DATA_HOME/kapi when that is set, and otherwise the platform's own: ~/Library/Application Support/kapi on macOS, %LocalAppData%\kapi on Windows, ~/.local/share/kapi elsewhere. kapi creates the workspace on first use; no recipe setting is required.

kapi init assigns a stable project id:. Clones and worktrees with that id share the local context store while maintaining separate indexes of their files. Switching branches preserves the context. Checks and context queries use the same store, so a rule you keep is available to the next command in every checkout.

Use kapi store import to read context files from a checkout. Nothing in them is in force until a person reads them in.

What to commit, and what to ignore​

Commit the recipe and agent configuration. .kapi/ holds checkout-local data: the block store, caches, redaction vault and personal reader filters. Shared filters are kept in the project's context store. By default, kapi init writes .kapi/.gitignore containing * to exclude the directory from version control.

Deletion has different consequences for each location:

  • rm -rf .kapi/work/cache is always safe. Everything under it is rebuilt on the next run.
  • Deleting .kapi/ removes derived data, personal filters and any redaction vault. The redaction vault at .kapi/vault/ contains withheld originals that are neither committed nor synced. Merge in-flight batches before deleting it. Workspace context is unaffected, and so are the drafts of a language waiting for review and the edits made to them: the next kapi up serves them again without translating them anew. In a project that declares redaction, the values withheld from those drafts are in the vault, and a draft reads with placeholders without it.
  • Deleting the workspace costs the context of every project on the machine: the terms, the voice profiles, the content memory and the recorded decisions. A project with a context backend keeps a copy there once you run kapi context sync; for any other, take a copy with kapi store export before you do anything that reaches your data directory.

Repairing non-canonical locale identifiers​

kapi stores and looks up locale identifiers in canonical form. Some rows may use an identifier such as nb_NO that does not match a lookup for nb-NO, leaving terms or approved wording absent from results. kapi status and kapi up report these rows when detected.

kapi store locales # inspect stored locale identifiers
kapi store rebuild # write the context rows again from their history

kapi files every row under the canonical identifier as it writes it, so kapi store rebuild writes the project's context rows again in canonical form.

Rows in the checkout index are what kapi read out of your own files, so kapi rebuilds them from the files: delete .kapi/work/store.db and the next kapi up reads your files again.

Rebuilding the context store from its history​

Every change to a project's terms, voice profiles, content memory and approvals is kept in workspace.db together with what it wrote: an import, an edit through kapi apply, a rule a person kept or dropped, the wording a run approved, a decision in a review. The project's database holds what those changes add up to, and kapi can write it again from the history:

kapi store rebuild

It empties the project's terms, voice profiles, content memory and approvals, and the rules the project applied to every project, then replays the history into them. --checkpoint keeps a copy of the result, so the next rebuild starts from it and replays only the changes after it. The result is the store the changes left behind, so a rebuild is safe to run whenever a store looks wrong. A row that no recorded change wrote is not written again. It takes a few seconds for a project with tens of thousands of approved entries.

One context graph​

The workspace keeps a graph that links a term to the blocks that use it, a decision to the block it approves, and both to their context coordinates. A project answers graph questions without a server: which blocks use this term, in which collection, at which coordinate. Because the graph spans the projects you have opened, which projects use this concept is a question you can ask locally too. A connected project answers the same query shapes server-side across more dimensions. See C-03: The context store and graph.

Two stages: working, then ship​

The store also explains the two stages of a run:

  1. Working: kapi run (with no -o, in a project) lands its translations as overlays in the block tables of store.db, and a kapi up under materialize: on-converge keeps the drafts of each language that waits for review in the workspace. The work is recorded and not yet in your files.
  2. Ship: kapi merge writes that work out to the target files, the drafts of a language waiting for review and the edits made to them first, and the workspace stops keeping them; kapi status then reads the files (plus the block-state record) for the real ship state, the kapi loop's ladders and gates.

So coverage has two readings: "what's translated in the store" (working, pre-merge) and "what's in the files and reviewed" (ship). In Kapi Desktop, the project home's Content axis is the working reading; kapi status reports the ship reading.

A decision is durable the moment it is recorded​

Approving a translation records a decision in the store, and it counts from that moment (see Review). Every checkout of the project reads it, and there is no second step.

The decision holds for the exact wording of the translation and of the source it was approved against. Editing either drops the block below reviewed, a changed link as much as a changed word.

kapi status --review # the worklist: blocks awaiting approval
kapi apply <<<'{"ops":[{"op":"decide","at":{"doc":"src/en.json","block":"save.label","edition":"nb"},"if_match":"r:74dbfac2ed1c9d6e","outcome":"establish"}]}'
kapi context log # the decision, with the evidence behind it

A team shares the record through the project's context backend: kapi context sync shares it, and the next sync on every other machine reads it.

The same model maps to a server-backed project: with the server plugin installed, it pushes its decisions to a remote (kapi push) and pulls them back (kapi pull), the same record with a different sink.

A store with nothing in it​

kapi decides whether a store is present table by table. A context store whose terms tables are empty behaves exactly as though there were no terms store at all: the terminology gate enforces nothing, kapi up --plan never creates state, and kapi pack carries only the parts that hold something.

The same model runs in the browser. The playground and the labs keep their files, the workspace and its history in the browser's storage for the site, so a project is still there after a reload or a browser restart. One tab holds the workspace at a time. A second tab keeps its own work in memory and says so beside its files, and Use the workspace here moves the workspace to it; the first tab then keeps its files in memory and says so. The browser may clear what a site keeps (Safari does after seven days without a visit), so treat the browser copy as a cache: Export workspace in the files panel saves the files, each project's context and every terms store outside a project as a .kpz, and Import workspace reads one back into any browser, including the same one after a reset. A project's context can also be shared through a folder on your computer; see Sharing context.

The store, the content memory and your files​

  • The content memory in the store is a recycle corpus. A memory operation through kapi apply adds leverage for future translation and records no review; a review outcome is a decision. See Memory & terms storage.
  • Your files are authoritative for your translations. The store indexes what the files hold.

See also​

  • Sharing context: sharing the context with the team, reading a checkout's context files in, and packing it into one file for a backup or another machine.
  • The kapi loop: the derived ladder, gates, and review queue.
  • Projects: how a run's source and sink resolve.
  • Project file reference: the recipe fields, and what each one binds.