ctx is a local CLI for indexing and searching existing agent history. The security boundary for this branch is the local machine, the configured ctx data root, and provider transcript files the user explicitly imports or allows ctx to discover.
Security review for the current product covers:
- the
ctxCLI commands documented indocs/cli-reference.md; - the default data root
${CTX_DATA_ROOT:-~/.ctx}; - the immutable Core/Tantivy generations in
search/lexicaland the optional generation-bound flat-F32 semantic data insearch/semantic; - the content-free local usage sidecar in
usage.sqliteand, when installed, the encrypted Local Pro graph; - local
config.tomland diagnostic logs when present; - read-only discovery of known provider history paths;
- explicit imports for supported local transcript formats, including Codex, Pi, Claude, OpenCode, Gemini, Cursor, Copilot CLI, and Factory AI Droid;
- setup, status, sources, import, show, search, MCP, and doctor output;
- JSON output treated as private local data unless reviewed before sharing.
Setup, source discovery, import, and search do not require API keys, repository writes, shell startup-file edits, or background processes. No session text, prompts, or transcripts leave this machine by default. When local-only security mode is enabled, these commands also do not use network access.
Do not publish private prompts, command output, customer data, credentials, raw transcripts, SQLite databases, or local archives in a public issue. Use the project's private security reporting channel when available. If no private channel is available for the repository you are using, contact a maintainer before sharing reproducer data.
Useful reports include:
- affected command or data flow;
- ctx version or commit;
- operating system;
- whether
CTX_DATA_ROOTor--data-rootwas set; - provider and source format, if relevant;
- a minimal sanitized reproducer;
- expected and observed behavior.
Treat the ctx data root and command output as sensitive. They may contain source code, prompts, local paths, tool-call arguments, private repository names, and typed identifiers extracted from provider transcripts.
Provider transcript files remain the provider-owned acquisition authority for import and daemon refresh. Those flows publish policy-selected searchable content, metadata, and exact provider and source identities into immutable Core/Tantivy generations. Search, show, locate, and MCP retrieval read the active verified generation; they do not reopen provider history at query time. Provider SQLite inputs are opened only as short read-only logical snapshots during import or refresh. A temporarily inaccessible or changed input may fail that refresh, while the last verified Core generation remains available for retrieval until a later refresh publishes new content.
Search, show, MCP, and JSON output are local/private by default and may contain indexed transcript text, local paths, token-shaped strings, command output, and other transcript data. Review copied output before sharing it outside the machine.
Before adding a new provider importer or expanding stored fields, the change needs tests for malformed input, source-path handling, local payload handling, and the no-network/no-repository-write behavior required by local-only security mode.