Skip to main content
kane-cli context builds a local knowledge store (.context/ in your project directory) from your requirement documents, then uses an AI agent to extract use-cases from them. The store is content-addressed: every snapshot is identified by a hash of its bytes. This is the first stage of the assurance lifecycle: Source → Use-case → Scenario → AC → Test.

context ingest: snapshot and extract your sources

context ingest saves a snapshot of one or more files in .context/, creating the store on first use, and then extracts them. What happens after the snapshot depends on where and how you run it:
  • On a terminal, the run continues straight into the interactive extract chat.
  • --mode agent extracts headless on the NDJSON stream. Each landed file emits one ingested event before extraction begins. See Automation.
  • --mode override also extracts headless, and accepts every default automatically.
  • --mode ci, or piped stdin with no --mode, only lands the files: they are snapshotted, nothing is extracted, the run exits 0, and a guidance line on stderr tells you what to run next.
--plan, --force, and --trust are passed through to the extraction, and they are refused in the land-only modes. A source is a file path or a remote URL: a Jira issue, a Confluence page, a Linear issue or document, or a public web page. See Requirement Sources for every accepted type. The confirmation you see (the receipt) depends on how you run the command. On a terminal it is a human-readable line (landed prd (prd.md) — new source). Under ci and piped runs it follows the byte-exact script format shown below. Under --mode agent nothing prints outside the stream: the ingested event is the receipt.
Each source gets a stable id. By default it is the filename slug (prd-online-store.md → prd-online-store), or the issue key for a ticket (ENG-42 → eng-42). Pass --as <id> to choose the id yourself. Ingest decides identity the same way every time: Two helpers keep a document’s versions together:
  • --as records a new version. If a colleague hands you PRD-v2.md for an existing source prd, run ingest PRD-v2.md --as prd to record it as a new version of prd. The head moves and dependent items go stale. Because --as names a single identity, it refuses more than one file.
  • Version suggestion (terminal only). If you ingest prd-v2.md while a source prd exists, Kane CLI asks “looks like a new version of prd — ingest as prd?”. Accept to version prd, or decline to create prd-v2 as its own source. Piped runs never prompt and never link versions automatically, so pass --as explicitly in scripts.

Accepted sources

Files: text and structured text up to 2 MB, images up to 5 MB, and PDF and Word documents up to 25 MB. Remote sources are passed as a URL and need the matching connection on your account:
Anything else is rejected with UNSUPPORTED_MEDIA, and an oversized file with FILE_TOO_LARGE. Requirement Sources documents every source type with its size cap, citation granularity, identity rules, and refusal codes.
A Jira ENG-42 and a Linear ENG-42 both create the id eng-42. If a URL’s id already belongs to a different kind of source, the ingest refuses and offers a way to recover, rather than silently replacing the existing source.
If the new bytes are a changed version of a source you have already extracted from, use kane-cli maintain reconcile instead of a plain re-ingest. It records the same head move and works out what the change means for your suite, in one step.

context extract: propose use-cases

context extract runs the extraction agent over every ingested source whose current snapshot has not been extracted yet. Snapshots that already have a committed extraction are skipped; pass --force to extract one again. Most of the time you start with context ingest, which lands your files and then runs exactly this step. Run extract on its own to sweep again, to target one source with --source, or to --resume a session. On a terminal, extraction runs as an interactive chat. Headless use is opt-in: a non-TTY run with no --mode exits 2 and asks you to pass --mode agent|ci|override. See Automation for how headless runs behave. Two rules apply when a run covers several sources:
  • The sweep continues past failures. If one source fails, Kane CLI prints one line and moves on to the next source. The run exits 1 at the end if anything failed. A failed source is retried on the next run without --force.
  • Only one extraction runs per store. A run holds an extraction lock while it works. A second run started at the same time refuses immediately with another extraction is running on this context (pid N) — retry when it finishes (exit 2, code EXTRACT_LOCKED). If a run dies, its lock clears itself.
What the agent does:
  • Proposes use-cases from each source. Each use-case has a detailed description (flows, inputs, states, boundaries) and criteria[]: short, cited sketches of the promises in the source that matter for acceptance. Criteria are hints for kane-cli design, never test oracles.
  • Cites everything. Every proposal must quote exact evidence from the source. Fabricated evidence is rejected before anything is written. Image evidence cites the image itself, because there is no text to quote.
  • Asks when the source is ambiguous. Conflicting requirements become clarifying questions, each with options, a recommended default, and a risk level.
  • Checks what you already have. Before proposing, the agent reads the existing graph without changing it. If you already committed a use-case, the new evidence is added to the existing node (shown as ≈ matches) instead of creating a duplicate.
Extraction stops at the use-case. Scenarios, ACs, and tests are created by the design engine, because each stage can only create its own kinds of item. Flags:

The interactive session

The chat has two zones:
  • The scrollback holds the complete session: source banners, the agent’s narrative, its reasoning and tool lines, each turn’s proposals as an item table, answer receipts, commit receipts, and the closing session summary.
  • The live region below it holds only what is happening now: the working line (press ctrl+t to expand the agent’s reasoning) and one panel.
A three-line status bar sits between the two zones and summarizes the session’s state. Its last line lists only the keys that work right now, so the legend is always accurate. Every action is a panel. There is no free-typing command line. Each state shows its actions as rows you can select. The cursor starts on row 1, and row 1 is always the recommended next step. Use ↑↓ to move, ⏎ to select, and digits to jump. Typing anywhere opens the inline editor on the trailing ✎ free-text row. On a question, your words become the answer. Between turns, they steer the agent (“make UC-4 high risk”, “also cover the coupon path”). Item tables and ids. Every new item gets a short sequential id (UC-4, AC-12, T-3) when it is created, and ids are never renumbered. Both you and the agent use them: the agent refers to items by id, and your steering matches them without regard to case. Each turn’s items appear as a table (id · title · a badge for the kind of item · summary), sorted from high to medium to low risk. A row whose commit has not landed yet shows (staged) instead of a placeholder id. These ids are reserved, so context name refuses them. Nodes created without a short id keep their longer slugs, and get an id only if you run context name --backfill. Questions. When the agent needs answers, the question panel takes over. Each question shows its options with the recommended one selected, plus the rationale and the risk.
  • Multi-select questions show real checkboxes: space toggles an option, and ✔ done — confirm selection submits.
  • Esc steps back to a question you already answered so you can pick again (echoed as ↳ changed), and ← → move between the questions in a batch.
  • The batch action » Go with recommendations (tab) answers everything still open with the recommended picks.
  • When an option needs a typed value (“Provide the URL”), selecting the row opens an inline editor, so the answer carries both the pick and your value.
Adding a source mid-session. The @ key (shown in the panel legend when available) opens the attach panel, which has one editor for a path or URL. When you submit, the whole question batch is set aside: nothing is answered and nothing is lost. The source lands and commits, the agent reads it, explains what it settled, and asks again only what is still open. Answers you already gave are pre-filled when it asks again. Only sources you provide can land. If the agent invents a path on its own, the ingest refuses (INGEST_UNAUTHORIZED_REF) and nothing lands. To do the same thing headless, run --resume <sid> --with-source <path|url>. A new version of a known source. If a landed source is a new version of a source the graph already knows, Kane CLI does not simply extract it again. Instead, the next check-in offers review change(s) detected in <source> as its first row. You can choose later, and the offer comes back at each check-in until you take it. Selecting it walks you through the held changes as review cards, the same review that maintain reconcile runs. While a source is held for review, a reconcile cannot move its head until that review is done. Between turns, the idle panel offers the actions for the current state. Typically these are looks good — finish the session (row 1), design tests for a use-case… (a picker that runs a design session and then returns to this one), view the N drafts, and ✎ tell me what to change. The view explorer. Any view … row opens a read-only explorer over the session’s items. Press ⏎ on an item to open its full dossier: status, risk, every content field, its criteria with their raw citations (cite <source-id> <anchor> — "verbatim quote"), provenance, and dependencies by id. Esc walks back. The explorer only displays items; you make decisions in the panels. Ctrl+C pauses the session instead of killing it. The first press asks the agent to save the session. A second Ctrl+C at any point exits immediately. To finish cleanly, choose row 1 on the idle panel. However a session ends (finished, paused, interrupted, or crashed), it prints one session summary block into the scrollback. The summary shows the state and what happened, including the credits used for paused, crashed, and held sessions. If the session can be resumed, it shows the exact resume command, including the --message form, plus the trace line. A pause exits 3. If the save cannot finish within a few seconds, the run exits 130 and says interrupted — session not saved. During the chat, proposals commit as drafts (derived). Reviewing and promoting them is the job of context review, described below.

Pausing and resuming

The session is saved and the run exits 3 with the exact resume command when the agent needs an answer you are not there to give, when you press Ctrl+C, or when the process dies mid-run. You can resume any time within 24 hours:
There are three ways to answer when you resume:
  • In plain words: --message. The agent maps your statement to its pending questions. If your statement answers none of them, it is treated as steering (“also cover the coupon path”).
  • By id: --answer <question-id>=<option number | free text>. Use this for scripted resumes. It is repeatable and works only with --resume --mode agent. Each answer that lands is echoed as a panel_resolved event before the run continues:
  • By landing a source instead: --resume <sid> --with-source <path|url>. The file or URL lands first and the pending batch is set aside (ask_deferred on the stream). The agent reads the new source and asks again only what it did not settle. Only refs you provide can land; anything else refuses with INGEST_UNAUTHORIZED_REF.
A resumed session tells you what happened while you were away. Questions answered elsewhere are never asked again, defaults the agent assumed in your absence are reported (N default(s) were assumed while you were away), and your earlier answers are pre-filled, not submitted automatically.

context review: review outside the extract session

context review walks existing nodes through the review checklist and lands all your verdicts as one batched record. Choose a queue with --queue:
  • derived (default): everything unreviewed.
  • skipped: only the items you skipped during an extract review.
  • archived: items you can restore. An explicit approve makes them trusted again.
  • drift: a listing only, which works without a TTY. It shows nodes whose evidence is stale or orphaned, with their pinned sources, so you know what to extract again.
In any queue, approve promotes a node and reject archives it (a trusted node can be demoted). Edit creates a new version that supersedes the old one. Nodes never change once written, so edits never rewrite history and existing references never break. Headless verdicts. --verdicts <file.json> takes a JSON array of entries like this:
resolution is one of approved | edited | rejected | skipped | supersede, with optional reason, edit, and supersede_target fields. The file is applied all or nothing: every ref must resolve and be in a review queue, or nothing commits (exit 2). With --json, each verdict that lands is echoed as one NDJSON row. Archiving needs explicit consent. A headless rejection does not destroy anything. --verdicts holds rejected entries as non-destructive pending_archive facts (exit 0, with a prominent summary). To actually archive them, pass --allow-archive and --because "<reason>", and the reason goes on the record. Under --mode ci, archiving is refused whatever flags you pass (exit 2, all or nothing). Single decisions from a script. --approve <refs...> lands approvals. --skip and --defer record nothing and leave the items in the queue. You cannot combine these three flags with --verdicts. Review has no auto-approve mode, by design: trust requires a human decision. The structured flags and --verdicts land your decisions; they never make decisions for you.

Inspecting the graph

context list

Lists nodes with their trust and freshness.
  • --inferred shows only unreviewed (derived) nodes.
  • --stale shows only stale or orphaned nodes: evidence pinned to an outdated snapshot, or no live source at all.
  • --all includes superseded versions, which are hidden by default.
  • --json prints one JSON object per line.

context view

Renders the whole graph as a single self-contained HTML page. The page shows a swimlane per use-case, provenance links back to each source, trust and staleness at a glance, a commit rail along the bottom, and detail panels you can click into for each node’s lineage. The page is a snapshot: it needs no server and works offline, so run the command again to refresh it. Piped runs write the file and print its path instead of opening a browser. --json prints the computed data for scripting.

context explain

Replays a node’s recorded history straight from the store, without ever calling a model. You see when and why the node was created, every review verdict, edits and supersessions, and name assignments. <ref> is a logical id (uc-manage-the-cart) or a cid (the content id).

context sessions

Paused extract and design sessions are kept under .context/sessions/ for 24 hours.
  • list shows each session with its number of pending questions, its expiry, and a resume command ready to paste.
  • show <sid> prints everything the paused agent is waiting on: the questions in full, any defaults it assumed in your absence, and the ways to resume.
  • clean removes expired sessions. clean <sid> removes one session, and --all removes everything.

Housekeeping

context retire

Retires a source. Its use-cases are not deleted; they read orphaned once no live source provides evidence for them. You can undo a retirement with revert.

context name

Assigns a stable kebab-case name. A name is never part of a node’s identity, so renaming never changes its address. Names follow edits: a name assigned to version 1 keeps pointing at the current version. The sequential ids (uc-3, ac-12, …) are reserved for ids assigned at creation, so name refuses them (exit 2).

context revert

Undoes a record’s effects by appending a compensation record: created items are tombstoned, heads move back, and trust states are restored. History is never rewritten, so the store keeps both the mistake and its correction. Reverting a revert restores the original effects.

context fsck / context rebuild

fsck verifies the full chain of records and checks the read caches for drift (exit 1 on any issue). Run it whenever someone has changed .context/ by hand. rebuild wipes the derived caches and regenerates them from the verified records. It is always safe to run. Confirmation for destructive commands. retire, revert, name --backfill, and rebuild ask for confirmation on a terminal (default No) and need an explicit --yes when headless. Read commands never create a .context/ store in a directory that has none; only ingest and extract do.

Trust and freshness

Freshness is independent of trust. A node is fresh, stale (the source snapshot moved), orphaned (no live source provides evidence for it), or superseded (this version was replaced). A stale use-case is still trusted; it only needs to be checked again against the new snapshot, which is what kane-cli maintain reconcile does.

The store on disk

Two rules from the overview are worth repeating: the store has a single writer, and it is never merged with git. When Kane CLI creates the store inside a git repository, it adds .context/ to your .gitignore. kane-cli context ingest, kane-cli context clone and kane-cli context sync doctor --export all do this, and say added .context/ to .gitignore once. If the line cannot be written, the store is still created and warning: could not add .context/ to .gitignore: <reason> explains why; add the line yourself in that case. Set KANE_CONTEXT_GITIGNORE=0 to stop Kane CLI from adding it. To share the store with your team, bind it to a location (a GitHub repository, an S3-compatible bucket, or a folder on a shared drive) and use kane-cli context push, kane-cli context pull, kane-cli context sync and kane-cli context clone. See Sharing the context graph with your team. A teammate who pulls your records gets the same use-cases, cited lines, and review verdicts you committed, without ingesting anything again. .context/sync/ holds the files sharing adds: the location list (which contains no secrets), a backup and a receipt for every rebase, and the location’s state for this machine.

Tracing a run

Every extract and design run prints a trace: <path> line with the path to its log file. Check that file first when a run does something you did not expect.

For agents and CI

Agents and CI documents headless extraction (--mode agent|ci|override), the NDJSON event stream, exit codes, and how pausing and resuming work. A pipeline that works on a shared store clones it once, pulls before each run, and pushes after. The sync commands use the same stream; see the sync verbs on the stream. For the CI setup, see CI/CD.

Sharing a context store

For location setup, sync, pull, push, clone, and recovering from a rebase, see Sharing the context graph with your team.

Lifecycle automation contracts

context name, context retire, and context revert accept --mode agent and emit an envelope that ends in done. Destructive operations in agent mode need --yes even when stdin is a TTY. Other modes keep their human-readable output. Read commands use their documented --json flags; do not assume they all accept --mode. context review --mode agent or --json returns rows describing each review outcome on success, instead of the conversational done envelope. An agent-mode error early in the run may emit error followed by done, so check the command’s own output and its exit code.

Next steps