Releases: Davidslv/cce-rust
Releases · Davidslv/cce-rust
Release list
v2.9.0
Minor release: one backward-compatible feature on top of the full audit-backlog burn-down (36 → 8 bugs).
Added
- Relevance harness v2 (#84, #85): paired significance testing (
cce relevance --compare), line-range anchors + token-level metrics, additivecce.relevance.report/v2schema.
Fixed
- Both crown-jewel secret-exfiltration fixes — served
record_idredaction +cce doctorscrub scan (#144), and same-delimiter / quote-glued / prefix redaction tail-leaks via an explicit quote-aware scanner (#142). - Sync-core hardening: overwrite-guard + atomic marker/rename (#163, #123, #122), push-guard content verify + retention crash-safety (#113, #114, #150), checksum round-trip (#115),
is_dirtyparsing (#117),--commitHEAD guard (#116). - MCP robustness (#124, #125, #143, #132); atomic
index.jsonwrite (#101); memory append guard (#102);cce initfile-safety (#99); input-hardening (#127–#130); walker/workspace (#105, #131, #133); retriever (#107, #109, #110); path-traversal guard (#121); and correctness singletons (#100, #103, #104, #106, #108, #111, #112, #119, #90, #92, #126).
Full detail in CHANGELOG.md.
cce v2.8.0
Added
- Usage visibility (v2.8):
cce usage+ the opt-in MCP result footer (#35).
cce usage [--workspace] [--since 24h|7d|<ISO>] [--source mcp|cli|all] [--json]
is the one-shot, CI-friendly terminal counterpart to the dashboard's
agent-vs-human panel: themcp(agent) vscli(human) split — searches,
tokens saved, savings ratio, quality, latency — the recent queries, and a
by_packagemini-table in workspace mode. Pure projection, zero new
accounting: it reuses the exactaggregate()/ federated aggregation the
dashboard serves (including the #28 workspace-root-log rule), so its numbers
are always identical tocce dashboard's for the same log and window (proven
by tests that run both paths over one fixture).--jsonemits the versioned,
byte-pinnedcce.usage/v1projection (stable field names, the same shapes as
/api/metricswhere they overlap); the human block is byte-pinned too.
Deterministic, offline, read-only;nowis injected below the CLI edge.
Second surface: a per-project.cce/configkeymcp.result_footer: off (default) | on | sessionappends ONE byte-pinned line tocontext_search
results —cce: 5 results from 38,628 chunks · served ~1,204 tok vs ~9,880 baseline · saved ~8,676 (88%)(sessionadds a running per-session clause).
Rendered after all measurement from values already on the recordedsearch
event: toggling it never changes a recorded metric (same query, footer off vs
on ⇒ an identical recorded event, test-proven), and with the footeroffthe
MCP tool-result bytes,conformance.json, and every MCP golden are untouched.
Config-only by design — no runtime tool, so the agent cannot toggle its own
observability. Additive/api/metricsfields feed the new surfaces:
by_source.*.mean_latency_msandrecent_searches[].source. Spec committed
asSPEC-USAGE-VISIBILITY.md; docs indocs/mcp.md,docs/dashboard.md,
anddocs/how-to.md. cce relevance— the retrieval-relevance evaluation harness (#63). The
missing third leg of the measurement story:cce conformanceproves output
stability andcce bench/cce evalmeasure latency and token savings — this
measures ranking quality. Labeled query→expected-result fixture sets
(cce.relevance/v1NDJSON:{query, expected: [file or file#kind anchors], k}
per line — a documented contract like the knowledge feed) run through the REAL
retrieval pipeline at a named backend (bm25= the issue-#30 keyword-only
mode,vector= pure cosine order,hybrid= the full SPEC §6 pipeline
cce searchserves) and are scored with standard IR metrics — precision@k,
recall, MRR, F1 — per query and macro-averaged per backend.
--compare A,Bprints per-query deltas so a proposed ranking change shows
exactly which queries it helps or hurts before it merges. Two starter fixture
sets ship ineval/relevance/(code over the conformance sample corpus;
knowledge-style queries over a small markdown corpus); the hash-path--json
report (cce.relevance.report/v1) is byte-pinned in CI against
test/fixture/relevance/code.golden.json, conformance-style. Measurement
only: zero ranking-behavior changes. Seedocs/relevance.md.- Build fingerprint +
cce doctor— detect config drift before it degrades
retrieval (#62). Every store write (cce index, workspace indexing, the
cce initlocal index, and everycce sync pullinstall) now stamps a small
cce.fingerprint/v1block intofingerprint.jsonbeside the store: engine
version, embedder id + dimensions, the chunker identity (language-pack set,
markdown split budget, nesting limit), the tokenizer rule id, and the redaction
flag — plus a SHA-256 self-checksum over the canonical serialization and a
SHA-256 binding to the exact store bytes it describes (a store rebuilt by an
older binary is detected as stale, never trusted). Additive by construction:
the fingerprint is a separate file old readers never open — the store bytes,
the sync artifact,conformance.json, and every byte-pinned golden are
untouched, and all recorded values derive from pinned constants so the
fingerprint itself is deterministic.cce doctor [--dir|--store]is the
read-only report over it: fingerprint fields vs the running binary's pinned
equivalents, with every mismatch explained ("chunker changed: chunk_ids may
not be reproducible; re-index to realign"; embedder/dimension drift = the #30
meaningless-cosine failure mode); store parse health with the #30
empty-embedding tripwire; the #55 installed-bytes corruption re-hash for
pulled stores (reusing theverify --checksum-onlymachinery verbatim); the
knowledge store's contract version, snapshot id, and data as-of; and a
workspace mode that checks every member (StoreOnly consumers included) and
summarizes. Doctor never mutates; it exits non-zero ONLY on definite
corruption/mismatch — soft findings are distinctadvisorylines, and a
pre-fingerprint store is a graceful re-index notice with exit 0. Hermetic
tests only (no network, no Ollama).
cce v2.7.1
Added
cce update/cce upgrade— checksum-verified self-update from GitHub Releases
(#75). The missing client for the tag-driven release pipeline: resolve the latest
(or a--version vX.Y.Z-pinned) release via oneSHA256SUMSfetch, download the
platform tarball by shelling out tocurl(the house pattern — sync shells out to
git; no HTTP-client dependency), verify it againstSHA256SUMS, and atomically
rename the new binary overcurrent_exe()(symlinks resolved; the running process
keeps its inode). Everything stages in a temp dir, so a corrupt download, checksum
mismatch, or unwritable install location leaves the current install untouched — a
mismatch is a loud refusal, an unwritable location suggestssudo/manual install
(never privilege escalation), an unsupported platform names the four published
targets, and a missing curl points at the manual install.--checkis scriptable
(one line; exit 0 = up to date, exit 10 (pinned) = update available);--version
is the rollback path (downgrades warn but proceed); after updating, the CHANGELOG
sections between old and new print newest-first, capped at 5 with a releases-page
link. Per the settled offline-first posture,updateis explicit-invocation network
ONLY and the sole code path that invokes curl (grep-provable: confined to
src/update.rs); no other command gained any network behavior.SHA256SUMS
verification protects integrity, not authenticity beyond GitHub's TLS — stated
plainly in the docs; detached signatures remain a documented future hardening. The
release asset naming is now a compatibility contract (noted in RELEASING.md). Tests
are fully hermetic: a local HTTP fixture server via the test-only
CCE_UPDATE_BASE_URL/CCE_UPDATE_TARGEToverrides, mutating tests run a staged
copy of the binary, and the delta rendering is byte-pinned. No retrieval surface:
conformance.json, all goldens, andSYNC_FORMAT_VERSIONare untouched.
Fixed
- Repos pushed from a non-
maindefault branch are no longer invisible to consumer
mode (#72).cce sync list,pull --latest, andpull --allresolved the latest
pointer atrefs/mainonly, so a repo whose CI pushes from e.g.mastershowed
latest = -and was warned-and-skipped despite a valid artifact + pointer. Now, when
refs/mainis absent and exactly one otherrefs/<name>pointer exists, it
resolves the latest sha — annotated on every surface (<sha> (master)in the human
listing, an optionalreffield on thecce.synclist/v1JSON row,ref : master/
(ref master)in pull reports); with several non-main refs the skip/-behaviour
stays but the warning names the available refs. Explicit control:cce sync pull --latest --ref <name>(rejected with--all, where repos have different default
branches) and a per-membersync.refconfig key thatpull --allrefreshes honor and
preserve across the config rewrite. All of a repo's refs enumerate in ONE listing call,
never N pointer reads.refs/main-resolved outputs stay byte-identical everywhere
(the existing pinned goldens pass unchanged);SYNC_FORMAT_VERSION,
conformance.json, and the knowledgecurrentpointer family (a different key space)
are untouched — asserted, not assumed.
cce v2.7.0
Added
- Knowledge-corpus sync M5.1+M5.2 — the
.cckartifact andcce knowledge push/pull
(#56, per SPEC-SYNC-KNOWLEDGE). A built knowledge store now travels through the same
content-addressed cache as code indexes.sync::knowledge_artifactowns the canonical,
byte-exact.cckcontainer (manifest + one line per chunk in store order, sorted-keys
compact JSON, the.ccebase64 f64-LE embedding codec, zero provenance fields, checksum
computed withchecksum:"") — a pure function of(feed, corpus_id), with a committed
golden checksum for the shared fixture feed and a refusal of embedding-less Phase-A
stores.cce knowledge push [--corpus <id>] [--remote <url>]exports the current local
store and lands artifact +currentpointer + publishedcorpus.json
(cce.knowledgemeta/v1, carryingpushed_at— deliberately outside the reproducible
artifact; the deterministicdata_as_oflives inside it) in one commit, then applies
per-corpusknowledge.sync.retention(keep-last-<n>prunes oldest by the cache repo's
commit order; thecurrentsnapshot is never pruned; prune failures warn, never fail the
push).cce knowledge pull [--corpus <id>] [--latest | --snapshot <id>] [--force] [--remote <url>]verifies the manifest checksum (a mismatch is a hard failure naming the
key) and installs into.cce/knowledge/byte-identical to a local ingest, recording
the knowledge sync marker (synced.jsonwithinstalled_sha256, the #55 mechanism —
theverify --checksum-onlysurface wires up in M5.3). Guards per the spec: corpus_id is
never derived (explicit--corpusorknowledge.sync.corpus_id, validated
sanitize-stable); pulling a different corpus refuses without--force; the raw feed
never travels and a planted secret arrives redacted in the artifact (knowledge index
has no bypass flag — asserted). Config:knowledge.sync.corpus_id/remote(per-corpus
§4.3 override; defaultsync.remote) /retention.serde_jsongains the
float_roundtripfeature so a loaded store's embeddings parse back to the exact doubles
that were written (push exports the loaded store; without it the.cckdrifted a ULP
from a local ingest). Additive throughout:SYNC_FORMAT_VERSION,conformance.json,
code artifacts, and every existing golden are untouched (asserted, not assumed — a
knowledge corpus beside code artifacts leavessync list --jsonbyte-identical). - Knowledge-corpus sync M5.3+M5.4 — the consumer surface and the ingestion reference
(#56, completing SPEC-SYNC-KNOWLEDGE). Corpora are now first-class on every consumer
surface.cce sync listgrows the §6 knowledge section: a human block after the repos
table (corpus / current / snapshots / LFS-aware bytes / data as-of) and an OPTIONAL
knowledgearray on the unchangedcce.synclist/v1JSON — emitted only when the cache
carries a corpus, so knowledge-free listings stay byte-identical (nullable fields stay
present asnull).cce sync pull --all [--corpus <id>]installs the cache's corpus
into the consumer workspace root.cce/knowledge/via theknowledge pullmachinery
verbatim (store,current, and marker byte-identical to a direct pull): an explicit
--corpuswins, a single-corpus cache auto-installs, several corpora warn-and-skip
naming the ids (one active corpus per root; member pulls never fail because of
knowledge), and refresh is marker-idempotent — an unmoved remotecurrentreports
up-to-datewith no fetch, a moved one refreshes exactly the corpus.cce sync verify --checksum-onlygains the knowledge row: re-hash of the installed snapshot against the
marker'sinstalled_sha256, with member semantics (pass row; a mismatch fails loudly
naming the corpus — plus the honest sharpening that knowledge has NO rebuild-verify
escalation path at all; a marker without the hash is an explicit notice at exit 0), and
a knowledge-only root verifies too. MCPindex_statusgains the §4.4 knowledge block
(corpus or(local ingest), snapshot, records/chunks, data as-of, best-effort
offline-saferemote current/behind remotemirroring the code freshness rules);
reports without a knowledge store are byte-identical. M5.4 ships the reference
scheduled-adapter workflowdocs/ci/cce-knowledge-sync.yml(fetch → emit
cce.knowledge/v1→cce knowledge index(redacts) →cce knowledge push; a builder
job, never a serving process; the feed is ephemeral and never committed; disjoint
source-READ vs cache-WRITE secrets) and the documentation pass: docs/knowledge.md M5
un-deferred with the full sync/consumer/freshness/trust story, docs/sync.md consumer
mode covers corpora inlist/pull --all/verify, docs/mcp.md documents the
index_statusknowledge block, README and llms.txt updated. One pinned surface moved
by design: the #69 additivity test now asserts the M5.3 shape (every pre-existing
listing field byte-stable beside a corpus; the corpus visible only as the new optional
key).
Documentation
- SPEC-SYNC-KNOWLEDGE.md — the normative build spec for M5, knowledge-corpus sync (#56).
The SPEC-SYNC pattern reapplied to the v2.6 knowledge system: a canonical, provenance-free
.cckcorpus artifact (the built, redacted store — never the raw feed) under an additive
knowledge/<contract_version>/<corpus_id>/key space in the same git+LFS cache, with a
currentpointer and a publishedcorpus.jsonper corpus. Settles the six M5 decisions
normatively (corpus identity, the honest trust-the-pusher posture with a code-vs-knowledge
comparison table, access boundary, freshness signals, per-corpus retention, index-time
redaction), specscce knowledge push/pull, thecce sync listknowledge section (still
cce.synclist/v1— additive optional key, knowledge-free listings byte-identical),
pull --allcorpus install at the workspace root, andverify --checksum-onlycoverage,
plus the CI-cron builder reference workflow and milestones M5.1–M5.4. Spec-first: no
implementation in this change;SYNC_FORMAT_VERSION, code artifacts, and all goldens
untouched.docs/knowledge.md's M5 deferral note now points at the spec.
cce v2.6.9
Added
cce sync list [--remote <url>] [--json]— enumerate what a sync cache holds (#53).
The discovery half of consumer mode: one row perrepo_idwith its latest sha (the
refs/<branch>pointerpull --latestreads —-/nullwhen a repo has no pointer yet),
artifact count, and total artifact bytes (LFS-aware: an LFS pointer reports its
recorded artifact size, not the ~130-byte pointer file). Wires up the previously
CLI-unreachableSyncRemote::list(#37/#50), keeping its pinned graceful-skip of
non-artifact cache entries. Read-only — it never mutates the cache or the local.cce/—
and repo-less: a bare directory plus--remote <url>is sufficient. Rows sort byrepo_id;
an empty cache is a friendly message (exit 0); an unreachable remote is a clear non-zero
error.--jsonemits the stable, byte-pinnedcce.synclist/v1shape.
SYNC_FORMAT_VERSION,conformance.json, and every existing golden are untouched.cce sync pull --all --into <dir> [--remote <url>]— the one-command repo-less consumer
workspace (#54). From a bare directory: enumerates the cache (the #53sync list
machinery), pulls everyrepo_id's latest artifact into<dir>/<member>/.cce/, and
synthesizes<dir>/.cce/workspace.ymlplus the root and per-member.cce/config, so
cce search --workspace <dir>andcce mcp --workspace --dir <dir>work immediately —
zero source checkouts, each member federated at its own independent sha. Members are
short-named from the repo_id's last__segment (-2/-3on collision); the full
repo_id lives in the member's config so per-member pulls keep working. Repos without a
latest pointer are warned and skipped, never fatal. Re-runs are idempotent refreshes:
only members whose latest pointer moved are re-pulled, new repo_ids join the workspace,
and vanished ones are warned about but never deleted. Synthesized manifests use the new
neutraltype: store-onlymember type (a member with no source to classify); detection
never emits it and hand-written manifests stay byte-identical. Consumer mode (including
the repo-less single-member--latest/--commitpull) is now documented in
docs/sync.md.SYNC_FORMAT_VERSION,conformance.json, and every existing golden are
untouched.- The self-describing cache — published workspace metadata +
cce sync verify --checksum-only(#55). Consumer mode 3/3.cce sync push --workspacenow also publishes
the canonicalworkspace.ymland the derived cross-memberworkspace-graph.jsonat
well-known keys under the workspace's base repo_id
(hash/<ver>/<base>/workspace.yml/…/workspace-graph.json) — additive by construction
(neither an artifact nor arefs/pointer; SPEC-SYNC §3 now states the additive-keys rule
normatively). The pull paths consume it:pull --workspaceinstalls the published graph,
merges the real member types/packages into the local manifest (matched by name; the local
path wins), and can bootstrap a repo-less consumer with no manifest at all;pull --all
discovers every published manifest via the extendedsync listmachinery, enriches exactly
the members each manifest covers, and installs the merged graphs rewritten to the consumer
member names (member-name collisions across workspaces: first in repo_id order keeps the
bare name, later ones stay at their-2/-3names, warned). Result: a repo-less federated
search regains cross-member graph expansion, byte-identical to the source-side
workspace.cce sync verify --checksum-onlygives consumers a real integrity check with
zero source checkout:pullrecords the SHA-256 of the exactindex.jsonbytes it
installs (an additiveinstalled_sha256field in.cce/synced.json), and verify re-hashes
the on-disk file against it — version-independent ("has this file changed since
pull"), so artifacts pushed by older cce versions verify exactly like current ones
(live-verified against a mixed-version cache; an export-based comparison would false-fail
them). Failures are loud and name the member; a marker written by an older cce (no
recorded hash) is an explicit exit-0 re-pull notice, never a false failure. Documented
caveat: detects corruption, not a malicious build (trueartifact == build(sha)
verification stays with source-holders/CI). Also from live review: apull --allrefresh
now re-adopts a member directory whose.cce/configwent missing (matched by name,
noted in the report) instead of duplicating it as<name>-2. Caches without
published metadata, plain single-member pulls,SYNC_FORMAT_VERSION,conformance.json,
and every existing golden are untouched.
Documentation
- Consumer-mode documentation sweep (pre-v2.6.9). The whole doc surface now tells the
#53/#54/#55 story coherently: a "consume a team cache" recipe indocs/how-to.md(the
flagship repo-less flow), consumer-mode/store-onlycoverage indocs/workspace.md, a
repo-less agent-context note indocs/mcp.md, thelist/pull --allCLI surface in
SPEC-SYNC §5, a "consumer mode over a server" decision entry indocs/DECISIONS.md,
refreshed module-map/llms.txt/README index rows, theCargo.tomldescription, and
current test counts (605) in README/AGENTS/CONTRIBUTING/getting-started/llms.txt.
cce v2.6.8
Changed
- Index-time embedding now batches chunks through
try_embed_batch(#38). The store build
path used to embed one chunk per call — one HTTP request per chunk on the Ollama backend, so a
repo with tens of thousands of chunks cost tens of thousands of sequential round-trips. Chunks
are now embedded in bounded batches ofEMBED_BATCH_SIZE(64, pinned insrc/config.rs), so
indexing issuesceil(chunks / 64)requests instead of one per chunk (measured on a 300-file /
600-chunk synthetic repo against a 10 ms-latency stub: 601 → 11 requests, ~10.2 s → ~0.2 s).
The fail-loud policy (#30) holds at batch granularity: a failed or count-mismatched batch aborts
the index naming the batch's file span, and nothing is persisted — never empty or misaligned
vectors. The hash embedder is untouched (its default batch impl maps the same pure per-text
embed over each batch), so all goldens andconformance.jsonare byte-identical.
Fixed
- The chunkers survive pathologically nested input — iterative tree walks, no SIGSEGV (#49).
A property-suite CI run died with SIGSEGV before proptest could persist the failing seed. Two
crash classes were reproduced deterministically and fixed. (1) The code and markdown chunkers'
per-node recursive AST walks (collect_chunks,visit_pre, the heading/inline walks)
overflowed the thread stack on deeply nested input — measured crash at depth ~219 on a 256 KiB
stack and ~875–1748 (grammar-dependent) at the 2 MiB Rust test-thread default, while tree-sitter
itself parses the same input fine at depth 500k. All walks are now iterativeTreeCursor
loops with identical pre-order emission, so chunk output is byte-identical for every input.
(2) tree-sitter-md's external scanner serializes its open-block stack into tree-sitter's fixed
1024-byte buffer without a bounds check: ~255 simultaneously open blocks (e.g. one line of
255>characters) is an assert-abort in debug and a buffer overrun (SIGSEGV) in release,
independent of stack size and uncatchable from Rust.chunk_markdownnow computes a conservative
per-line upper bound on open-block depth before parsing and degrades estimated-deeper-than-192
input to the existing deterministic whole-doc fallback chunk — fail-safe, never crash. A
deterministic regression suite (tests/deep_nesting.rs) chunks nesting just under and far past
the old thresholds on a 256 KiB thread, and each chunker property case now runs on a 16 MiB
thread so any future crash becomes a persistable proptest counterexample instead of a process
kill. All goldens andconformance.jsonare byte-identical. cce search --workspace --package ""now errors loudly instead of silently returning no
results (#45). An empty-but-present--packagevalue ("",",", whitespace — e.g. an unset
shell variable in--package "$PKG") used to parse to an empty scope, federate over zero members,
and print nothing, bypassing the #26 unknown-token error.parse_scopenow lives in
cce::federationand rejects a scope with no usable token with an actionable message
(--package requires at least one member or package name (e.g. --package app,billing)); the MCP
context_searchpackageargument goes through the same parser, so{"package": ""}gets the
same friendly guidance instead of silent no-results. Valid scopes are byte-identical.
Added
- Binary-level error-path tests: corrupt store, malformed manifest, garbage remote listing,
dashboard CLI (#37). Four real-world corruption scenarios are now pinned by driving the real
ccebinary: a truncated-JSON or binary-junk store makessearch/statsexit non-zero with the
friendlycould not load store …message (never a panic); a syntactically broken
.cce/workspace.ymlsurfacesinvalid workspace.yml: …fromsearch --workspaceand
stats --workspace; non-artifact entries in a sync remote's ref listing are skipped gracefully
bySyncRemote::list(unit-level — no CLI command reaches the listing parser today); and
cce dashboard --port 0 --no-open(plus the--workspacevariant) binds an ephemeral loopback
port, prints the URL, and answers/api/healthwith 200 + valid JSON. Test-only — no behavior
change. - Tests for
src/main.rsand a byte-pinnedsearch --jsongolden (#32). The CLI entry point
(~1,300 lines) previously had zero tests. It now has a unit suite pinning current behavior of the
pure helpers —parse_scopecomma/whitespace/empty-segment edges,resolve_read_store/
resolve_metrics_path/metrics_beside_storeprecedence (explicit--metricswins, else beside
the resolved--store, else<root>/.cce/metrics.jsonl) — plus byte-pinned goldens for the
script-facingresults_json/fed_results_jsonshapes (field order, 6-decimal string scores
incl. round-half-away-from-zero,query_id: nullwhen metrics are off, trailing newline), and a
binary-leveltests/cli.rstest pinning the parsed--jsonfield set. Test-only — no behavior
change; all existing goldens andconformance.jsonunchanged. - Automated, tag-driven releases. Pushing a
vX.Y.Ztag now re-runs every CI gate on the tagged
commit, verifies the tag matchesCargo.tomland that this file has a matching section, builds
release binaries for macOS (arm64/x86_64) and Linux (x86_64/arm64), and publishes a GitHub Release
with this file's section as the notes plus aSHA256SUMS. Process documented inRELEASING.md;
README gains a prebuilt-binary install path. (Repo infrastructure — theccebinary is unchanged.) - Property-based tests for the chunkers and the pinned token rule (#33). A new
proptestsuite
(tests/property_chunkers.rs) generates adversarial-but-legal source for all six language packs
(unicode identifiers, CRLF line endings, trailing whitespace, missing final newline, empty and
comment-only files, deeply nested definitions, raw printable-unicode garbage) and markdown
(ATX/setext headings, preambles, fenced code blocks containing#lines, varied split budgets),
and asserts the chunkers' documented invariants on every input: in-bounds ordered line ranges,
content as an exact byte slice of the input, pre-order nested-or-disjoint emission, determinism,
chunk_idrecomputable from the persisted fields, the pinnedmax(1, floor(bytes/4))token rule,
and markdown section ordering/coverage. Test-only: goldens,conformance.json, and thecce
binary are unchanged.
Documentation
- v2.6 documentation sweep (#34). Re-ran the gapless-docs discipline (#11, last executed at
v2.5.5) over the v2.6.0–v2.6.7 surface. The knowledge track (cce knowledge index, the
cce.knowledge/v1contract, thecontext_searchsource: code|knowledge|bothblend, provenance +
staleness weighting, theknowledge.*config keys) now appears indocs/knowledge.md(M4 section),
docs/mcp.md(thesourceschema property), the README, and the getting-started/how-to/
how-it-works/architecture cross-references; the v2.6.3 gitignore-aware walker (committed
.gitignoreonly — builder independence) is documented in the README, guides, architecture, and
sync's rationale;docs/sync.mdstates that push always rebuilds from source (v2.6.2);
docs/workspace.md+docs/architecture.mdcarry the v2.6.4--packagesemantics (name or
package:field, loud error with the available list) and the v2.6.7 MCP caching instead of the
stale "reloaded per query" claim. Stale pins fixed:cce 2.5.5/--tag v2.3.0/v2.4.0examples,
the retiredbuilt_atCI comment, the--top-kdefault (10, not 5), and the 416/500 test counts
(now 540); the Cargo.tomldescriptionextends through v2.6 (metadata only). Docs-only — no engine
change;conformance.jsonand all goldens are byte-identical.
cce v2.6.7
Changed
- The MCP server caches the single-repo index and the knowledge store across calls (#31). The
long-livedcce mcpserver did O(corpus) work on EVERY tool call: the single-repo path re-read +
JSON-parsed the whole store and rebuilt the entire BM25 index and import graph per request
(Index::load), and the knowledge path additionally re-ran the embedder over legacy chunks and
rebuilt a BM25 index per query. Extending the #26 workspace pattern,McpServernow caches the
loadedIndexand the loaded+embedded knowledge store, keyed by a cheap freshness fingerprint —
store-filemtime+length from onefs::metadatacall per tool call (for knowledge: thecurrent
pointer plus the snapshot artifact it names). A re-index, a knowledge re-ingest, or a
cce sync pull(startup auto-pull or mid-session) invalidates on the next call; a deleted store
drops the cache and serves the friendly missing-index message — never a stale answer. The #26
workspace union cache (previously cached forever) now carries the combined fingerprint of its
in-scope member store files, so a member re-index mid-session is picked up without restarting
cce mcp. Warm calls sit under the #41 per-query embedder choice (BM25-only degradation
unchanged). Perf only — ranked results and MCP result text are byte-identical warm vs cold
(regression-tested), CLI one-shot paths are untouched, andconformance.json+ all goldens are
unchanged. On a synthetic 3.2k-chunk store driven over stdio, a warm MCPcontext_searchdrops
from ~23ms to ~2ms per call (~10×); a warm knowledge query (300 records) from ~6ms to ~1ms (~5×) —
and the win scales with corpus size, since the removed work was O(corpus) per call.
cce v2.6.6
Fixed
- The Ollama embedder fails loud instead of degrading silently (#30). Three compounding silent
failures in the opt-in--embedder ollamapath are gone. (1) Index time: an embedding failure —
Ollama unreachable at start, or dying mid-index — now abortscce indexwith a clear error and
writes no store (previouslyembed_batchswallowed errors into empty vectors, which were persisted
and scored cosine 0 forever, invisible to vector recall). There is deliberately no fallback to the
hash embedder at index time either: that would poison the store's declared embedder space just as
badly. (2) Query time, CLI:cce search(and--workspace) on an ollama-built store with Ollama
down now errors with guidance (start Ollama, or re-index with the default hash embedder) instead
of silently embedding the query with the hash backend — cosine across two unrelated vector spaces is
meaningless. (3) Query time, MCP:context_searchfollows the friendly-error pattern — it does not
crash the session, and now degrades to keyword-only (BM25) results under a pinnedNOTICE:line,
so the agent keeps getting results while the degradation stays visible. TheEmbeddertrait lost its
silent-empty-vector batch path (embed_batch→ fallibletry_embed/try_embed_batch), the endpoint
and model are overridable viaCCE_OLLAMA_URL/CCE_OLLAMA_MODEL(which also keeps the new
failure-policy tests hermetic — a loopback HTTP stub, never a real server), and the docs that
described the silent fallback as a feature are rewritten. The default hash-embedder path, the
knowledge store (hash-only),conformance.json, and all goldens are byte-identical.
cce v2.6.5
Fixed
- The workspace dashboard now shows
cce mcp --workspace(agent) searches (#28). In workspace mode
the MCP server writessearchevents to the workspace-root.cce/metrics.jsonl, but
cce dashboard --workspaceaggregated only the member logs — so agent/MCP searches never appeared in
totals,recent_searches, orby_source, contradictingdocs/mcp.md. The workspace dashboard now
folds the root log into its roll-up (guarded against double-counting a member that points at the root).
These federated searches span members and stay out ofby_packageby design — that panel remains
per-member. Docs aligned; per-package attribution of agent searches is left as a follow-up option.
Changed
- Faster, correcter workspace federation (#26). Member stores load without building per-member
BM25 (federation scores only the union's BM25), removing redundant work — full-workspace search is
~1.3–2× faster (a real 38.6k-chunk workspace: 3.2s→2.4s CLI).--packageshort-circuits to load
only the scoped member(s) (2.08s→1.58s) and now resolves by member name or thepackage:field,
erroring with the available list on no match (previously matched member name only and returned
empty silently). The MCP server caches the assembled union per scope, so repeated
context_searchno longer re-federates (warm call ≈ CLI). Perf/correctness only — ranked results
are byte-identical (regression-tested); keeps exact brute-force cosine (ANN deferred).