Knowledge from agent threads
Much of a team's reasoning happens in agent threads: a colleague and Claude Code or Codex weigh two approaches, find a pitfall, settle a rule, and the thread ends. kontext distill reads such threads and turns what should outlive them into knowledge candidates. They land in the local inbox and are shared only when promoted with a commit and reviewed, like anything else captured.
Threads are read from this machine: every colleague distills their own. Raw transcripts never enter the repository; only the entries that come out of them do.
From the command line
kontext distill # list this repository's threads on this machine
kontext distill --claude last # the newest Claude Code thread of this repository
kontext distill --codex 01a0e6c1 # a Codex thread by id (or prefix)
kontext distill --superset # every thread of the current Superset workspace
kontext distill --superset calm-river # a workspace by id, worktree name, path or branch
kontext distill slack-thread.md # any text: a copied Slack thread, a PR discussion, notes
pbpaste | kontext distill - # the same from stdinSuperset workspace 7c41e0d2 · Fix rounding in the cart · fix/rounding · 1 thread(s) here
Distilling 1 thread(s)…
superset:7c41e0d2/claude:4f1c2a9b · 1 part(s), 42s · 2 entries
[decision] Round prices half-even (libs/pricing/src/round.ts)
→ inbox:2026-09-29-round-prices-half-evenWhat happens:
- The thread is read into a compact transcript: what the developer asked, what the agent answered, what it edited and ran (
→ edit src/cache.ts,→ $ git commit …). Tool output, reasoning, injected instructions (AGENTS.md, environment, hooks), Claude Code bash-mode output (!commands and what they printed) and compaction summaries are left out. A harness notification, such as Claude Code's<task-notification>for a finished background agent, becomes one line (→ Agent "…" finished: <the start of its result>). Paths are made relative to the repository, an agent's per-session temp dirs are shortened to<tmp>/, and secrets are redacted. - The transcript is split into parts of about 45,000 characters (
--max-parts, default 12, spread over a longer thread) and sent to your LLM adapter, several at a time (--jobs). - The model names the decisions, conventions, pitfalls and incidents the team should still know later, at most
--maxper thread (5), and is shown what is recorded already, so it does not repeat it. Findings similar to an existing entry or inbox candidate are dropped. - Each finding becomes an inbox candidate with its paths, the commits the thread made it in,
origin: threadand its source (claude:4f1c2a9b, shown bykontext inbox, dropped on promotion).
Review them with kontext inbox, promote each with the change it belongs to (kontext prepare-commit --promote <id>, or ctx_prepare_commit from an agent), drop the rest (kontext inbox drop <id>). --dry-run prints the findings without capturing them (it also works where kontext is not set up yet).
| Option | Default | |
|---|---|---|
--llm | init.llm | adapter with an llm op (llm-codex, llm-claude, …); needed when several are configured |
--max | 5 | most entries per thread |
--max-parts | 12 | most transcript parts per thread |
--jobs | 3 | parallel model calls |
--list | list the threads instead of distilling them | |
--dry-run | print, do not capture |
Sensitive threads
Work threads carry what a project is made of: people's names and addresses, pasted emails and logs, hosts, customer data. Measured on a real client thread: of 52 MB of transcript, 240 KB reach the model (0.5 %). Tool output and file contents never do, and what is left is masked further:
secrets, as everywhere in kontext: a private key is masked as a whole PEM block, from
BEGINtoEND, not only its first line;email addresses; phone numbers with a
+and national numbers written with separators (at least nine digits); IBANs; card numbers; IPv4 and IPv6 addresses (127.0.0.1and::1stay);every match on a line, not only the first;
your own patterns, e.g. a client's integration ids or customer names, joined with any the repository declares:
toml# .git/kontext/config.toml (this clone only) or ~/.config/kontext/repos/<slug>.toml [secrets] redact = ["\\bINT-\\d+\\b", "\\bAcme Corp\\b"]
A pattern that does not compile stops distill, ctx_threads and the autopilot before anything is sent; kontext status names it. A wrong pattern is never dropped silently.
What is not masked: names of people and companies that match no pattern, street addresses, free-text identifiers, and the meaning of what was said. Add patterns for what your client considers sensitive, and read the prompt with --dry-run first when in doubt.
What a prompt sends: the masked transcript part, the repository's name, the list of entries already recorded (titles and ids, so the model does not repeat them) and the instructions. The repository's remote URL, host and organisation are not sent.
The model is asked to write for the team (roles instead of people's names, no contact data, records, credentials or hosts), and what it writes is masked again. Nothing is shared before you review it in the inbox.
For a client's repository, also decide:
- where the transcript goes: the model of the
llmadapter reads it. Use the provider the client's data already goes to (for a Claude Code thread,--llm llm-claude) or pin it for the repository with[init] llm = "llm-claude"in~/.config/kontext/repos/<slug>.toml; - where the knowledge lives:
.ai/in a client's repository is the client's call. Until they agree, keep the store private, in a locally excluded directory (repositories you do not own).
From an agent
The kontext-distill prompt (/mcp__kontext__kontext-distill in Claude Code), or simply asking "distill the durable knowledge from thread claude:4f1c2a9b", lets the connected agent do it with its own model, no LLM adapter needed:
ctx_threadswithout arguments lists this repository's recent threads and the current Superset workspace;ctx_threads thread="claude:4f1c2a9b"returns the transcript, in parts (part=2, … when it says there are more). It reads onlyclaude:,codex:,superset:,lastand files under known transcript roots;- the agent checks
ctx_search, then records each finding withctx_capture(withsourceandcommits).
Superset
Superset runs agents in workspaces (a worktree, or a session directory) and gives each an id ($SUPERSET_WORKSPACE_ID in its terminals). kontext reads Superset's own records (~/.superset/host/<organization>/host.db, with the sqlite3 command): the workspace's path and branch, and the agent sessions its terminals ran. Their transcripts are found in every Claude Code account (~/.claude, ~/.claude-*, $CLAUDE_CONFIG_DIR) and in Codex's sessions ($CODEX_HOME, ~/.codex), plus any thread started in the workspace's directory.
--supersetalone means the workspace of the terminal you are in; a name can be the worktree directory (calm-river), a path, a branch or an id prefix.- Superset binds agents to terminals, not directories: a thread one of its terminals ran in another repository is skipped ("ran outside this repository"). Distill it from that repository.
- Runs that keep no transcript (
codex exec --ephemeral, for example) are counted as "without a transcript".
Where transcripts come from
| Agent | Files |
|---|---|
| Claude Code | <config>/projects/<path as slug>/<session>.jsonl for each config dir |
| Codex | <CODEX_HOME>/sessions/YYYY/MM/DD/rollout-<time>-<id>.jsonl and archived_sessions/ |
| anything else | a file or stdin, read as plain text |