Skip to content

cce v2.6.8

Choose a tag to compare

@github-actions github-actions released this 08 Jul 10:09
c2f7c6a

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 of EMBED_BATCH_SIZE (64, pinned in src/config.rs), so
    indexing issues ceil(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 and conformance.json are 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 iterative TreeCursor
    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_markdown now 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 and conformance.json are byte-identical.
  • cce search --workspace --package "" now errors loudly instead of silently returning no
    results (#45).
    An empty-but-present --package value ("", ",", 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_scope now lives in
    cce::federation and 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_search package argument 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
    cce binary: a truncated-JSON or binary-junk store makes search/stats exit non-zero with the
    friendly could not load store … message (never a panic); a syntactically broken
    .cce/workspace.yml surfaces invalid workspace.yml: … from search --workspace and
    stats --workspace; non-artifact entries in a sync remote's ref listing are skipped gracefully
    by SyncRemote::list (unit-level — no CLI command reaches the listing parser today); and
    cce dashboard --port 0 --no-open (plus the --workspace variant) binds an ephemeral loopback
    port, prints the URL, and answers /api/health with 200 + valid JSON. Test-only — no behavior
    change.
  • Tests for src/main.rs and a byte-pinned search --json golden (#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_scope comma/whitespace/empty-segment edges, resolve_read_store /
    resolve_metrics_path / metrics_beside_store precedence (explicit --metrics wins, else beside
    the resolved --store, else <root>/.cce/metrics.jsonl) — plus byte-pinned goldens for the
    script-facing results_json / fed_results_json shapes (field order, 6-decimal string scores
    incl. round-half-away-from-zero, query_id: null when metrics are off, trailing newline), and a
    binary-level tests/cli.rs test pinning the parsed --json field set. Test-only — no behavior
    change; all existing goldens and conformance.json unchanged.
  • Automated, tag-driven releases. Pushing a vX.Y.Z tag now re-runs every CI gate on the tagged
    commit, verifies the tag matches Cargo.toml and 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 a SHA256SUMS. Process documented in RELEASING.md;
    README gains a prebuilt-binary install path. (Repo infrastructure — the cce binary is unchanged.)
  • Property-based tests for the chunkers and the pinned token rule (#33). A new proptest suite
    (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_id recomputable from the persisted fields, the pinned max(1, floor(bytes/4)) token rule,
    and markdown section ordering/coverage. Test-only: goldens, conformance.json, and the cce
    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/v1 contract, the context_search source: code|knowledge|both blend, provenance +
    staleness weighting, the knowledge.* config keys) now appears in docs/knowledge.md (M4 section),
    docs/mcp.md (the source schema property), the README, and the getting-started/how-to/
    how-it-works/architecture cross-references; the v2.6.3 gitignore-aware walker (committed
    .gitignore only — builder independence) is documented in the README, guides, architecture, and
    sync's rationale; docs/sync.md states that push always rebuilds from source (v2.6.2);
    docs/workspace.md + docs/architecture.md carry the v2.6.4 --package semantics (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.0 examples,
    the retired built_at CI comment, the --top-k default (10, not 5), and the 416/500 test counts
    (now 540); the Cargo.toml description extends through v2.6 (metadata only). Docs-only — no engine
    change; conformance.json and all goldens are byte-identical.