FIELD NOTES//LOG 04 · LANGUAGES

Per-symbol drift, beyond TypeScript

codument's drift detection began as a TypeScript feature. It now reads Python, Go, Rust, C#, Java, Kotlin, and single-file components the same way, and the site can only claim what the installed release ships.

2026-07-134 MIN READLANGUAGESRELEASE
← All field notes

One parser was never going to be enough

codument's whole trick is that it does not diff text. It resolves a change down to the symbol: which function moved, whether its signature changed, whether the doc that owns it needs to move too. That resolution needs a real parser for the language, not a regex. So for a long time it meant one language. TypeScript.

That was an honest limit, and also a narrow one. Teams do not ship one language. The checkout is Python, the sync engine is Go, the mobile core is Kotlin, the widget is a single .vue file. A gate that understands only one of those is a gate you route around on every other file.

The same resolution, across the stack

The per-symbol engine now runs on a parser per language. Same anchors, same drift analysis, same verdict path. codument doctor prints the roster it will actually judge:

TERMINAL
  gate languages: TypeScript (per-symbol) · Python (per-symbol) · Go (per-symbol) · Rust (per-symbol) · C# (per-symbol) · Java / Kotlin (per-symbol) · Vue / Svelte / Astro (blocks)

Nothing about the analysis changed when the language did. Here is a Python checkout file whose apply_discount grew a cap. One symbol changed; the sibling above it did not:

TERMINAL
  Changed by feature
    pricing — src/pricing.py

  Stale docs (source changed, mapped doc did not)
    ⚠ pricing: docs/features/pricing.md (changed: src/pricing.py)

  Symbol drift — resolve each: update the doc, or ack a contract-neutral move
    • apply_discount (changed) in pricing [signature changed]
        contract changed → update docs/features/pricing.md at intent altitude
        signature move  → the symbol's signature changed — the doc's contract needs an update, not an ack

It named the function, saw that the signature moved, and pointed at the one doc that now owes an update. line_total, untouched, is nowhere in the report. That is what symbol grain buys you: the blast radius is the symbol, not the file.

The honest edges

Per-symbol holds where a real parser reaches. Single-file components (Vue, Svelte, Astro) resolve at block grain, because that is the honest unit there. Everything past the shipped languages is still tracked, just at file grain: registered, drift-detected across the whole file, never judged symbol by symbol. codument reports that gap instead of papering over it.

And the claim cannot outrun the code. The "works with your stack" strip on the landing page is generated at build time from the installed release's own language manifest, and a check fails the build if the page names a language the package does not ship. The roster you read is the roster you get.

What changed

Not the idea. The reach. The same defensible, per-symbol verdict codument always produced for TypeScript now covers the languages a real team actually merges in a day.

SEE THE CATCH HAPPEN · 30 SECONDS