Every change, in the open.
What changed in dctx, release by release, including known issues we have measured and not yet fixed. This page is generated from CHANGELOG.md.
Unreleased In development
- Docs: byte stability re-measured on 2026-11-06 — 33/33 text and 33/33 JSON map answers identical after unrelated edits and over five runs (see docs/research/stability-20261105/REPORT.md); SPEC and README status texts updated, historical 0/63 kept.
- Formal: the plugin TLC gate accepts the newer TLC wording 'Temporal property X was violated.' / 'Invariant X was violated.' (all 8 baselines, 59 mutants, 37 witnesses pass); host-specific tla2tools.jar paths removed; TLC trace files ignored.
- Self-hosted CI (
.github/workflows/ci.yml): the job run step by step on a self-hosted Linux runner (16 cores) from a cleangit archiveof the commit; results and badge recorded indocs/ci/RESULTS.md— 2279 run, 2279 passed, 0 skipped. - Third-party npm licence inventory:
scripts/npm_licenses.pyindexes every repositorypackage-lock.jsonintoTHIRD_PARTY_NPM.md;npm_licenses.py --checkruns in CI and fails on a disallowed licence or a stale report.
1.1.0
Release 1.1.0 (v1.1.0-rc1). It folds in the 1.0.1 line, which was never released on its own.
Added
- Perl (
.pl,.pm,.t,.psgi):package A::B;andpackage A { .. }astypesymbols holding every latersub(namedA::B::name) asfnsymbols (guessconfidence, full tier). POD is masked like a comment; call edges come fromname(..), bareword calls with an argument and&name, never after->,subor a sigil. - Fortran (
.f90,.f95,.f03,.f08,.f,.for):module, derivedtypeand namedinterfaceastypesymbols;program,functionandsubroutineasfnsymbols namedmodule::name(guessconfidence, full tier). Keywords are case-insensitive,!comments only, fixed-form column rules are not modelled; call edges skip intrinsic and control keywords that precede(. - Verilog/SystemVerilog (
.v,.vh,.sv,.svh):module,macromodule,interface,packageandclassdeclarations astypeoutline symbols andfunction/taskdeclarations asfnsymbols (guessconfidence, full tier), with module-scope call edges and<module> <instance> (instantiation links resolved through the call index. - Prefix-stable
packoutput (DCX-P-PACK): tree lines carry theIDonly, with noMOD:and noSIZE:, so a baretouchleaves the page byte-identical and an edit keeps everything before the edited file as a shared prefix for prompt caches.--tree-stamps=on|off(defaultoff) selects the built-in tree template;onreproduces the 1.0.0 bytes. The desktop tree-only export keeps its digest line last, behind a stable lead line. - Stat stamps in the manifest (DCX-P-STAMP): a stamp pass runs before the digest, with a racy-timestamp guard; a touch-only change is decided by content. A gate replays 200 random edits against a cold rebuild.
- Record and entry caps (DCX-P-CACHE): checked during the scan and set by
DCTX_MAX_RECORDSandDCTX_MAX_ENTRIES; the cache is reclaimed on publish, evicts before refusing, and readers share one lock. - Open-source maintenance model (DCX-OSS):
MAINTENANCE.md,TRADEMARK.md, a DCO inCONTRIBUTING.mdandFUNDING.yml; the desktop app is open source too.
Changed
- Id lookup (DCX-P-IDX) uses a sorted hash index instead of a linear node scan.
- Large source files were split into submodules by pure moves (400-line rule):
pack.rs,path.rs,reuse.rs,bound.rs,plugin.rs,yaml.rsand others. No behaviour change. - The version is 1.1.0 for every
crates/*andplugins/*package; the desktop app stays on 0.11.0.
Fixed
- A closed stdout pipe (
dctx pack | head) exits 0 without a panic.
1.0.0
The first v1 release, folded from the 0.26 development line. Every crates/* and plugins/* package, VERSION, project-meta.yaml and the README badge are at 1.0.0 (tools/sync-version.sh --check keeps them and their Cargo.lock entries together). The desktop app keeps its own version line (0.11.0) and its own release workflow.
Shipped surface
- Map verbs:
dctx map map | find | neighbors | explain | read | skeleton | grep | hubs | path | export, with hard token budgets, stable ids, cursor paging and precision labels; call and import edges are lexical. dctx mcp: a stdio MCP server exposing the map verbs as tools.dctx pack: the whole project as one structured block to stdout, the clipboard or--output.dctx pack --for "<text>" --budget N: task context for an agent card:map findon the names the text mentions, then neighbors and read of the best hits, whole lines only, within N estimated tokens (ceil(2 × UTF-8 bytes / 7), default 3000).tools/cardgen/context.shprepends it to a card;docs/guides/AGENTS-SNIPPET.mdis theAGENTS.mdsection that tells agents to run it first;tools/cardgen/dogfood.pyrecords before/after prompt tokens for the ten v1 cards.dctx languages: one registry with three tiers (full, outline, docs) that also renders the README table.- Privacy deny: sensitive files (env files, keys, credentials, ...),
.gitat any depth and symlinks are never read or printed bypack, any map verb ormcp; there is no override flag. Detection is by file name only. - Determinism: two fresh indexes give byte-identical answers, and an unrelated edit changes only
hubs;scripts/release-check.shgates both, and counts network syscalls understrace -f(must be zero). dctx --versionprintsdctx 1.0.0 (<git sha>); the sha is embedded at build time,unknownwithout git.- README benchmark section rendered from the committed run 7 JSON by
scripts/render_readme.py;just readme-checkfails when the README differs.
Out of scope for v1
- Any network or cloud feature.
- macOS and Windows support claims (untested); Linux x86_64 is the only tested platform.
- Watch or incremental mode beyond re-indexing.
- Fortran and Verilog (both shipped in 1.1.0).
- Shell call edges.
- Embeddings and semantic search.
- LSP-grade type resolution.
- A stable plugin ABI and desktop API (unstable, not a v1 contract).
- Cross-repository queries.
- Publishing to crates.io or GitHub (an owner decision).
Added
- Call and import edges in the map index:
dctx map neighbors --edge calls|importsnow answers who calls what, resolved by lexical scope, imports and module paths, withname/guessconfidence; ambiguous references are dropped. - New map verbs:
skeleton <file>(declaration signatures, no bodies),grep <literal>(hits grouped by enclosing symbol),hubs(most-called symbols and per-directory counts),path <FROM> <TO>(shortest edge path) andexport --format json|mermaid(the whole graph).neighbors --depthgoes up to 4 (breadth-first, each node once). dctx mcp: a stdio MCP server exposing the map verbs as tools.dctx languages(--json,--markdown): every supported language with its tag, file names, tier (full: symbols and lexical call edges; outline: symbols only; docs: sections) and confidence, from one facade registry (dctx::LANGUAGES) that also feeds--version --verboseand the README table, which a test diffs.- A CLI exit-code contract (
docs/CLI-EXIT-CODES.md) formap,pack,mcp,languagesand unknown commands: 0 ok, 1 no result (an id not in the index, a binary file target, nothing to pack), 2 usage, 3 index error. Every failure prints ahint:line. Previously every failure exited 1. A non-UTF-8 argument is now a usage error instead of a panic, an unknown flag is named as unknown, anddctx map <verb> --helpprints a page with anExample:line for each map verb. - Outline symbols (
guessconfidence) for 25 more formats: Scala, Dart, Zig, Solidity, Gleam, Groovy; Elixir, Lua, OCaml, R, Julia, Haskell; Terraform/HCL, SQL, shell, Makefile, Dockerfile, protobuf, Pascal, GraphQL; and headed sections for.txt,.rst,.adoc,.organd.texdocuments. - A three-way benchmark against graphify and Trail-Code (
docs/BENCHMARK-20261030.md) and the gap matrix behind it (docs/GAP-MATRIX-20261030.md). - dctx Desktop is free, forever for individuals, teams and companies (announcement).
- The dctx Context Management Specification (
docs/SPEC.md): prompt-processing efficiency as the core belief, the ten RAG defect classes and how dctx rules them out, the seven-layer organization policy, prefix-stable tiers and delta answers, the persistent index, the plugin boundary and the roadmap. - An isolated, reproducible benchmark against Trail-Code (
docs/research/trail-code-2026-10/): methodology, raw data, scripts and numbered findings. - Map mode (
dctx map):map,find,neighbors,explainandreadwith hard token budgets (up to 2,000 per answer), cursor paging, stable ids, explicitmoved/gone/ambiguousoutcomes and precision labels on every answer. - First-party structural extractors for JavaScript, TypeScript/TSX, Python, Go, Java, C/C++, C#, Kotlin, Ruby, PHP, Swift, Markdown and JSON/TOML/YAML; Rust through
syn. - A verified map generation reused across CLI invocations.
- Plugin host: capability grants, consent, receipts, liveness by progress, signed distribution verified with Ed25519, and Linux confinement; the bundled Git plugin (
.gitignoreprotection and consented staging). - Cache lifecycle: time-based expiry, a system size cap and a bounded automatic cleaner (
dctx cache status | gc | purge | config | auto). dctx pack: an explicit pack to stdout, the clipboard or--output, without leaving files in the project.- The template system's v2 compiler (a sealed plan IR) and organization ceilings.
crates/dctx: one library facade for the CLI, the desktop app and future bindings.- A new website with changelog and news, and the dctx film (
presentation/video/).
Changed
- Byte-stable map answers: the text header is
# <place> <verb>and JSON no longer carriessnapshot,generationorfreshness.age_s, so answers stay identical across unrelated edits (prompt-cache friendly).--metarestores the old fields. dctx packnever prints env-shaped files (.env,.env.*,*.env,.envrc); they stay in the tree by name with their content omitted.- Strict sensitive-file deny for every command: besides env files,
*.pem,*.key,*.p12,*.pfx,*.jks,*.keystore, SSH private keys (id_rsa,id_ed25519, ...),credentials,credentials.json,secrets.yaml(and other data extensions),.npmrc,.netrc,.pypirc,.pgpass,.htpasswdand.git-credentialsare never read or printed bypack, anydctx mapverb (by id or raw path, with or without--in) ordctx mcp. There is no override flag (see ADR-014). .gitis closed for good: a.gitsegment at any depth is never listed or read by the map verbs and never read bypack, even when.gitignoreor.dctxignoresays!.git/.- No symlink escapes:
FsSourceopens files withO_NOFOLLOW, requires a regular file handle, and refuses symlinked directories, so a symlink swapped in after the stat cannot leak bytes from outside the root. DCTX_INDEX_IGNORED=1(ignore files are not applied) is now documented in ADR-014; the sensitive-file deny, the.gitguard and the symlink rules still apply when it is set.- Total-source ceiling raised from 64 MiB to 1 GiB;
DCTX_MAX_SOURCE_BYTESoverrides it. - The core never reads
.git/, never spawnsgitand never uses VCS object ids; content identity is dctx's own SHA-256 (crates/dctx-hash). - Repository ignore rules are applied before any read on the map path, and
--lines A-Breturns exact line ranges. - Everything in the repository is licensed under Apache-2.0.
Fixed
- Node spans resolve from one newline index per file instead of rescanning the source for every symbol (cold
findon a 3,000-file repository: 141 s → about 6 s). - Queries share one generation instead of cloning it (peak memory down by about 30 % on the same repository).
- One hostile file no longer fails every map verb for the whole repository: a Rust file that is not UTF-8 is indexed as a module with no symbols (like every other language), and a file name the confined path cannot carry (a backslash) is skipped and marks the snapshot
partial, aspackalready did.
Known issues
Measured in the benchmarks and scheduled in the specification's roadmap:
- No incremental indexing: the first query after an edit re-indexes, and each edit adds a full generation to the cache.
- Outline-tier formats carry symbols and
containsedges only; heuristic families are labelledguess.dctx languageslists the tier and confidence of every format. - The 70-question task protocol (run 7: 140/140) was designed by the dctx team; an independently selected protocol (v1 card 6) is pending.
0.25.0
The last release of the first Rust generation, with zero third-party dependencies in the core and the CLI.
Added
- Snapshot, diff and tree modes; clipboard output; an interactive TUI.
- Filters by extension, size, content and visibility; binary detection.
- Ahead-of-time compiled output templates.
- The privacy guarantee: ignored files are never read, not even in debug mode; omit rules list a file without reading its content.
- The desktop app (Tauri) on the shared core.
0.11.0
Added
- A redesigned desktop interface with light and dark modes.
- A sequential, fail-fast CI pipeline.
0.10.0
Added
- Advanced CLI filters and their documentation.
0.1.0
Added
- The Rust rewrite of
dircontxtbegins.
dircontxt 1.0.0
The original tool, written in pure C (legacy-c/).
Added
- One LLM-ready
.llmcontext.txtsnapshot with a manifest and unique ids for every file and directory, plus a binary state file. - Automatic versioning with diffs that carry only the changed files.
- A three-tier ignore system (built-in defaults, a global ignore file and a per-project
.dircontxtignore) and a global configuration file.