-
code-index v0.27.0
StableAll checks were successfulCI / cargo fmt (push) Successful in 47sCI / OSS corpus tier-3 scale (nightly) (push) Has been skippedCI / Grammar rebuild from source (nightly) (push) Has been skippedCI / cargo doc (intra-doc links) (push) Successful in 4m53sCI / cargo test (abi, 32-bit + wasm32) (push) Successful in 5m18sCI / cargo deny (push) Successful in 5m15sCI / cargo clippy (push) Successful in 5m47sCI / cargo check (windows-gnu) (push) Successful in 6m12sCI / cargo check (MSRV 1.98) (push) Successful in 5m51sCI / OSS corpus (tier 1) (push) Successful in 25m24sCI / cargo test (push) Successful in 30m14sCI (Windows) / fmt + clippy + build + test (windows) (push) Successful in 40m59sCI / cargo test (daemon transport) (push) Successful in 12m54sCI / Plugin path cost + pool throughput (nightly) (push) Has been skippedRelease Build / Generate Version (push) Successful in 27sRelease Build / Required CI green (push) Successful in 1m1sRelease Build / Build linux-aarch64 (push) Successful in 12m25sRelease Build / Build linux-x86_64 (push) Successful in 15m33sRelease Build / Build linux-x86_64-musl (push) Successful in 15m42sRelease Build / Pack the XAML reference package (push) Successful in 50sRelease Build / Build windows-x86_64 (push) Successful in 20m23sRelease Build / Windows archive smoke (msvc) (push) Successful in 8sRelease Build / Create Forgejo Release (push) Successful in 2m54sreleased this
2026-09-08 20:57:30 +02:00 | 330 commits to master since this releasecode-index v0.27.0
Build: v0.27.0+679
Four-binary release:
code-index-mcp(MCP stdio bridge — the usual entry),code-index-daemon(long-lived watcher + RPC server, auto-spawned),code-index-plugin-host(bounded worker for plugin packages, spawned by the daemon), andcode-index(CLI: init, index, watch, doctor, link, plugin).The runtime plugin architecture becomes usable end to end; the Windows archive is
rebuilt on a linkage where a guest trap is actually intercepted rather than
fatal; and a round of dogfooding against this release candidate fixed eleven
findings — ten places where a tool reported a state it had not measured, and one
operator-facing measurement that had gone stale.A second package,
de.h-dv.timeline, exists in this tree and is graded by CI —
itsextractor.wasmis rebuilt from source and byte-compared on every run — but
it is NOT published as a release asset here. The only.cipthis release
ships is the XAML reference package. An operator who wants the TimeLine package
must pack it themselves from the source tree; a signed asset for it is planned
for the next release.Two further findings from that round are filed and NOT fixed here — an index that
cannot see a git worktree's own edits, and a corpus bless writer with no arm for a
record whose measurement reproduced while its conditions moved.149 commits since v0.26.1.
Upgrading: existing conformance verdicts must be re-run
This release records the WASM engine identity with the execution knobs it pins
(epoch,fuel,stack,rsimd,rsimd_det,multimem,backtrace), not the
wasmtime version alone. Those knobs decide how a package actually runs, so a C1
verdict recorded without them is not provably transferable to this host — and every
verdict recorded by v0.26.1 or earlier was recorded without them.On any machine that already holds conformance verdicts,
code-index plugin doctor
reports them as not current and WARNs, andplugin statusshowsnot run here.
Nothing is broken and no package changed; the record is simply less precise than
the check now requires. A fresh install is unaffected — it has no prior verdict.Remedy, once per installed package:
code-index plugin check <digest>plugin doctornames this case explicitly ("recorded before this host began
pinning engine knobs — samewasmtime <version>") rather than reporting it as
another engine, so the wording does not send you looking for a wasmtime change
that did not happen.Upgrading: the first run after this release re-parses your code files
A schema migration widens the recorded annotation region so a position inside a
symbol's documentation resolves to the symbol it documents. That lower bound comes
out of the parser and cannot be derived from stored rows, so the migration
invalidates everycoderow and the next index pass re-parses them.Nothing is lost and no action is needed. The daemon answers throughout, and
project_overviewdiscloses the window while it runs —state: "reconciling"with
aSCHEMA-UPGRADE REBUILDdetail naming how many files still carry the
invalidation sentinel. Counters read during that window describe rows being
replaced, and the payload says so rather than letting you read them as settled.Text and metadata rows (Markdown, TOML, SQL, and the rest) are deliberately NOT
invalidated — they carry no extraction, so re-hashing them would cost time and
change nothing.Cost is proportional to code files, not to repository size on disk. A full
re-parse of a large index has been measured at about ninety minutes; a few hundred
files is seconds.The Windows archive is built natively now, and a guest trap is actually caught
Until this release the Windows archive was CROSS-BUILT on Linux for
x86_64-pc-windows-gnuand linked against the legacymsvcrtC runtime. On
that linkage a WASM guest trap was not intercepted: instead of
host.worker_trappedin milliseconds, the worker took 33 seconds and then
died withabi.frame_truncated, leaving the host with a dead worker and no
usable diagnosis. Every other platform we ship intercepts the same trap
immediately and keeps the worker alive.The archive is now built natively on Windows with the MSVC toolchain, on the
same runner that already smoke-tests it. Measured on the shipping
configuration, one variable at a time:linkage trap verdict worker MSVC, static CRT (shipped now) 67.6 ms host.worker_trappedsurvives gnu + msvcrt (shipped through v0.26.1) 33,293 ms abi.frame_truncateddead Those timings are first-request figures and include worker spawn; steady-state
repeat traps on the surviving configurations measured around 10 ms. The claim
worth taking from the table is not the millisecond count — it is that the trap
is intercepted at all and the worker is still alive to answer the next request.The archive name does not change, and neither does anything else you may
have pinned: release archives are named<os>-<arch>, never by target triple,
so the Windows asset iscode-index-<tag>-windows-x86_64before and after.It depends on no redistributable. The C runtime is linked statically, so the
binaries import only DLLs present on a stock Windows 10 or later install. That
is checked rather than assumed: a plain MSVC build importsvcruntime140.dll,
which ships with the Visual C++ Redistributable and is not on a clean machine,
and the release now REFUSES to publish an archive importing anything outside the
stock set. Trading a trap bug for "the program can't start because
VCRUNTIME140.dll is missing" would have been the worse regression, on the one
path where the user has no toolchain.What this does not claim. The root cause is the C runtime, not the
toolchain. Agnubuild against UCRT also intercepts the trap and keeps the
worker, and the one wasmtime build flag that looked like a suspect
(__USE_MINGW_SETJMP_NON_SEH, which wasmtime defines for every
target_env = "gnu"Windows build) is present in the working configuration too,
so it cannot be the cause on its own. With that held constant the CRT is the
only variable that moved. We ship MSVC because it is a supported configuration
on a runner we already have — not because the gnu toolchain is at fault. UCRT on
the gnu target does work, but it needs a UCRT-CONFIGURED mingw toolchain,
headers andlibmingwexincluded; swapping only the CRT import library is not
enough and fails at wasmtime's ownsetjmp. Measured, with every attempt and
its exact failure, in #231.Upgrading: the XAML package is 0.2.0 and its digest has MOVED
de.h-dv.xamlis now 0.2.0, published asde.h-dv.xaml-0.2.0.cip, and its
digest has moved to
sha256:7b572f5cc32ffcd5af550900a451bbef37e255804776d7e3e3e71d2dd7d0aa79.Re-pin it:
code-index plugin install de.h-dv.xaml-0.2.0.cip \ --sha256 sha256:7b572f5cc32ffcd5af550900a451bbef37e255804776d7e3e3e71d2dd7d0aa79An operator who does not re-pin gets a bare
digest_mismatchand no other
explanation. Theextraction_identitymoved too, so every project with this
package enabled re-extracts its.xamlfiles once — which is the point: files
that were reportedextract.truncated_treeare now indexed whole.Why it moved. The extractor's walk budget cut real markup at roughly 64-80 KB
of source, depending on density — measured on a 14,056-file production repository
where about fifty files were affected, including every theme dictionary. Symbols
past the cut were missing fromfile_outline,search_symbols,find_references
andchange_impact, disclosed per file but easy to miss.All three budgets are now derived from the largest file the indexer will hand any
extractor (2 MiB) rather than from the corpus of the day: the walk budget is 16 MiB
of serialized tree, the output budgets 48,000 facts and 2 MiB of fact bytes. At
2 MiB of dense markup the extractor emits 29,845 facts and reports nothing. Both
truncation codes still fire, still mean different things, and are still
distinguishable throughindex_coverage.The instrument, not just the fix
The bug itself is one line of linkage. What let it ship in every release
carrying a Windows archive is that the tested binary and the shipped binary
were different builds, and nothing compared them. CI built its own gnu
binaries natively and ran the plugin smoke against those; the archive users
downloaded was cross-built and, until this cycle, had never executed a wasm
guest at all.So the durable part of this change is not the CRT:
- the archive is smoked with its own shipped bytes before publication, and
the release job waits on that; - the smoke refuses to grade an artifact whose linkage does not match what
the build leg declared — the refusal that turned this investigation into a
finding instead of a confident wrong number, and it has correctly blocked
publication twice; - linkage is now reported on two axes, toolchain and C runtime, because
after this change both toolchains can import the sameapi-ms-win-crt-*set
and a two-valued verdict would start lying in the opposite direction; - CI's own Windows smoke builds the same linkage as the shipped archive, so
the two cannot drift apart again.
Plugins
A package can now be located, verified, installed, conformance-checked, enabled
with an explicit capability grant, rolled back, disabled, removed and garbage
collected, with every mutating command disclosing what it is about to do first.- A package may displace a builtin's claim, with consent recorded in
[[displaces]]and the operator told what it costs. An undeclared intersection
is still refused. - The package lifecycle is a committed number, ratcheted one rung at a time
rather than asserted. - A refused package reaches an agent as a reason code, not as silence.
- Reproducible guest wasm, byte-comparable from any directory.
- A migrating daemon is distinguishable from a wedged one, and a wedged
project has an exit.
The architecture is proven on a real language rather than on markup alone: the
full-language migration parity gate (#84) is closed.Honesty fixes found by dogfooding this candidate
Eleven findings, filed and fixed against the release candidate itself.
doctorno longer renders "could not measure" as a verdict.PRAGMA integrity_checkreturning "unable to validate … : database is locked" said the
check did not run and was reported as corruption — hardest exactly when an
operator was most likely to run it, mid-reconcile. The opposite direction was
also wrong: an error mid-iteration reported an all-clear.doctor's freshness check counted never-indexable files as staleness — 35 of 35
on this repository — producing a permanent WARN that hid real drift. It now
splits the disk side by the same classifierindex_coverageuses, and asks the
project's own extractor set, so the two surfaces give the same verdict.context_packshipped over-budget responses withbudget_exceeded: false. Six
of eleven budgets were over; the block attached above the router was outside the
arithmetic. The flag and the number are now one measurement of the bytes shipped.changed_symbolsreported a bareref_count: 0for symbol kinds this index
measures as having no use channel, where four other surfaces disclosed it. The
counter and its basis are now a single value, so no surface can render one
without the other.direct_callersgained a basis of its own.review_diff's same-package counterevidence was unreachable in every workspace
and monorepo layout, because the root segment was stripped only when leading.- A declaration's leading DOCUMENTATION block is now part of it, in the six
languages that mark one.get_symbolon a///line answeredsymbol_not_found
while the same query on a#[test]line one file over resolved, and a commit
whose entire deliverable in a file was a correction to a recorded measurement
reportedsymbols: []. Python and Ruby are excluded with reasons and tests:
Python's docstring is already inside the span, and Ruby marks no comment as
documentation — RDoc reads the same#syntax as# frozen_string_literal: true. partial_sourcesnow answers the sentence that cites it. The list of partial
files was suppressed whenever a reply named none of them, so every reply carried
a disclosure pointing at a field that was not there. An empty list is now the
measurement that this reply names none.- One helper decides AND words the engine-drift distinction, across the three
surfaces that render it. A verdict recorded before this host began pinning
engine knobs is no longer reported as another engine. search_text(whole_word=true)graded a different query from the one the daemon
ran. Boolean and prefix expressions were matched as literal source characters and
the resultingtotal: 0was described as exact; ASCII-only matching lost Unicode
case folding, socafémissed a standaloneCAFÉwhilefixmatched inside
préfixé; and the census restated the matching rules a second time, sototal,
matches_in_fileand the returned line numbers could describe different
predicates. One compiled matcher now serves admission, census and line numbers,
and an expression the post-filter cannot honour is refused with a reason instead
of answered with a confident zero. Whole-word pagination also minted unstamped
cursors, bypassing the stale-generation rejection.- The promotion-lock ceiling
plugin enablediscloses to operators was wrong at
the 100k shape. Re-measured, with the cause established by removal rather than by
reading, and the rollup census it pays for is now graded.
One reported defect was refuted rather than fixed, and the counterexample is
pinned so it cannot be quietly re-implemented: a builtin'sauto-generated
exclusion is NOT package-independent, because a consented[[displaces]]covers
exactly the files the builtin excluded.Honest limits
The plugin ABI and the
.cippackage format are EXPERIMENTAL and may change
incompatibly in any release. A package is pinned to one thing — the host fact-ABI
major it brackets in[abi].host_min/host_max— and to nothing else. No
compatibility is promised or implied by this project's semantic version, in either
direction.Epic #75 is not closed by this release. #80's final end-to-end gate has steps
1–11 implemented and green and step 13 done, and step 12 has moved: the Windows
archive is now BUILT natively and executed by a job whose verdict gates
publication, so the platform is no longer cross-built and graded elsewhere.
aarch64 remains UNMET by decision — there is no runner — and that is
declared rather than silently skipped. #41 and #45 remain open.The TimeLine package's ACROSS-DIRECTORY reproducibility is unmeasured.
de.h-dv.timeline'sextractor.wasmis rebuilt from source and byte-compared
wherever the suite runs, CI included — an absent wasm32 target is a failure
there, not a skip. What is NOT measured is the across-directory leg: cargo
derives-C metadatafrom an absolute path, so proving it needs a comparison
between two checkouts, which no singlecargo testcan perform. That state is
"not measured", which is not the same as "measured and bad".Packing determinism is verified separately and independently: the same
checked-in bytes produce
sha256:150ceb22ed9757a660d5a2bf58b80c81b60043cc419e5da5dde559d5d6fc9c9fon two
different machines, directories and host binary builds.Package conformance is bounded evidence, not proof of semantic correctness.
C1 stages a package alone with no capability grant; passing it says the package
runs and responds within budget on its own fixtures.The promotion-lock constant is a flat rate over a cost that climbs with scale.
It is sized to over-predict, which is the direction it is allowed to be wrong in,
and at small generations it over-predicts by more than twice.lock_estimateis
labelled PREDICTED at every call site.Downloads
Four platforms are built for every release. The table below says which ones THIS release published.
Platform Archive Linux x86_64 (glibc) code-index-v0.27.0-linux-x86_64.tar.gz Linux x86_64 (static/musl) code-index-v0.27.0-linux-x86_64-musl.tar.gz Linux ARM64 code-index-v0.27.0-linux-aarch64.tar.gz Windows x64 code-index-v0.27.0-windows-x86_64.zip XAML plugin package
de.h-dv.xaml-0.2.0.cipmakes.xamlfiles carry symbols and references instead of being text-only:x:ClassandClick=handlers bind into the paired C# code-behind,x:Namebecomes a searchable declaration, and{Binding …}stays unresolved because no bridge can reach it.It is NOT installed by installing code-index. Packages are installed into a user-controlled store and approved per project, and installing grants nothing —
enableis the grant.Download
de.h-dv.xaml-0.2.0.cipstoo and keep the.cipsbeside the.cip. Packages are signed and an unsigned one is refused (signature_missing) with no flag that accepts it. You do NOT need to anchor us first: this release's publisher key is compiled into the binary, so the install below works on a machine that has anchored nobody.code-index plugin trust listshows it, marked[BUILTIN], andcode-index plugin trust remove sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72cwithdraws it — see About that key.code-index plugin install de.h-dv.xaml-0.2.0.cip --sha256 sha256:7b572f5cc32ffcd5af550900a451bbef37e255804776d7e3e3e71d2dd7d0aa79 code-index plugin check sha256:7b572f5cc32ffcd5af550900a451bbef37e255804776d7e3e3e71d2dd7d0aa79 code-index plugin enable sha256:7b572f5cc32ffcd5af550900a451bbef37e255804776d7e3e3e71d2dd7d0aa79 \ --capabilities bridge_source \ --bridges 'de.h-dv.xaml/xaml:type->csharp:class,de.h-dv.xaml/xaml:call->csharp:method'The digest above is the one this release packed and it is what
--sha256pins;de.h-dv.xaml-0.2.0.cip.digest.txtcarries it and the extraction identity. A digest that changes between releases means the package changed — re-pin, and read the notes.Only
.xamlis claimed..datasetand other markup remain text-only (searchable, no symbols).About that key
sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72cis a long-lived Ed25519 key held as a secret in this project's CI, used to sign released packages automatically, and it is compiled into the binaries in this release. That trusts this project's release pipeline, not only its maintainers: anyone who can run a release workflow here can produce a package that verifies under it. It adds nothing you had not already granted — the bytes are inside the program you are running, so forging that anchor means forging the binary — but you are entitled to know it is there before a package installs rather than after.There is no expiry — deliberately, because offline installations must not break on a timer — and withdrawal is on your side and works:
code-index plugin trust remove sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72c. A compiled-in key has no file to delete, so that writes one instead, carryingdenied = true; the key stops verifying at the next load,plugin trust listshows it marked[DENIED], and deleting that file (the command prints its path) is the only undo. If the key is ever rotated, the new fingerprint is published here and intests/packages/first-party.fingerprint, and a build that predates the rotation will not trust it.You may anchor it yourself instead —
code-index plugin trust add code-index-publisher.pub --fingerprint sha256:1cb03259a8c870b6db02360abd9351e17e67724d1f8c3509d85c4bf6b06fa72c --name 'a label you choose', withcode-index-publisher.pubfrom this release's assets. Your file replaces the compiled-in entry, and the--nameis a label YOU choose: nothing in the package, the key file or the signature can name its own publisher.macOS is not currently built. No
x86_64-apple-darwinoraarch64-apple-darwinarchive is published — macOS users should build from source (cargo build --release). This is a deliberate deferral, tracked in #59; no date is promised.Wire into Claude Code
{ "mcpServers": { "code-index": { "command": "/usr/local/bin/code-index-mcp", "args": ["--root", "/path/to/your/project"] } } }SHA256 checksums (.sha256 files) available for every archive.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
- the archive is smoked with its own shipped bytes before publication, and