Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .cargo/mutants.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# cargo-mutants configuration for uteke
#
# Usage (from workspace root):
# cargo mutants --file crates/uteke-core/src/jaccard.rs # single file
# cargo mutants --output mutants-run.out # custom output dir
# cargo mutants -j 4 --timeout 60 # parallel jobs + timeout
#
# This is a LOCAL-ONLY tool — not in default CI.
# Pre-release validation: run manually before tagging a new version.
# CI integration (if added): only on develop→main PRs as a pre-release gate.
#
# Exclude modules that require external services (SQLite DB, embedding API, etc.)
# Focus mutation testing on pure logic — the code most prone to silent bugs.

# Files to EXCLUDE from mutation testing.
# These are excluded because they require I/O, external services, or are
# thin wrappers around stdlib/third-party calls — not pure logic worth mutating.
exclude_globs = [
# Embedding backends — require external API/network
"crates/uteke-core/src/embed/*.rs",
# SQLite-backed modules — require on-disk database
"crates/uteke-core/src/memory/*.rs",
# Import/export — I/O heavy
"crates/uteke-core/src/import_export.rs",
# Update check — network fetch
"crates/uteke-core/src/update_check.rs",
"crates/uteke-cli/src/commands/update_check.rs",
]

# Equivalent mutants — PROVEN equivalent (behavior-identical, unkillable by any
# test). Do not count against the mutation score. Reviewed & verified:
# chunker.rs:282:24 (< → <=) — is_char_boundary(text.len()) is always true,
# so the loop-guard condition is identical either way.
# chunker.rs:425:25 (&& → ||) — invariant: in_block == !current_lines.is_empty()
# always holds when reached (set together at ~line 435), so both
# operands always have the same truth value.
# chunker.rs:443:17 (&& → ||) — same invariant as above, at the final flush.
exclude_re = [
"chunker.rs:282:24: replace < with <=",
"chunker.rs:425:25: replace && with \\|\\|",
"chunker.rs:443:17: replace && with \\|\\|",
]
10 changes: 3 additions & 7 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,14 @@ jobs:
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
cache-dependency-path: docs/package-lock.json
- uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: npm ci
run: bun install --frozen-lockfile
working-directory: docs

- name: Build
run: npm run build
run: bun run build
working-directory: docs

- name: Verify build output
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/mutation-testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Mutation testing — pre-release validation only.
#
# This workflow runs ONLY on PRs from develop → main, serving as a pre-release
# quality gate. It is NOT part of the default CI pipeline.
#
# Mutation testing validates test quality: cargo-mutants modifies source code
# (operator mutations, boundary changes, etc.) and checks if existing tests
# catch the mutation. "Missed mutants" = tests that pass on buggy code.
#
# Usage:
# - Runs automatically on develop → main PRs
# - Can be triggered manually via workflow_dispatch
# - Results are informational — they don't block merge by default
#
# To fix missed mutants, see the pattern in:
# crates/uteke-core/src/salience_recency.rs (mutation-killing test comments)
# Reference: nginjen project (78% missed-mutant reduction)

name: Mutation Testing

on:
pull_request:
branches: [main]
workflow_dispatch:

# Cancel in-progress runs for the same PR
concurrency:
group: mutation-testing-${{ github.ref }}
cancel-in-progress: true

jobs:
mutation-test:
name: Cargo Mutants
runs-on: ubuntu-latest
# Only run on PRs from develop (pre-release validation)
if: |
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' && startsWith(github.head_ref, 'develop'))
steps:
- uses: actions/checkout@v7

- uses: dtolnay/rust-toolchain@stable

- name: Install cargo-mutants
run: cargo install cargo-mutants --locked

- name: Run cargo-mutants on core logic
working-directory: crates/uteke-core
run: cargo mutants --timeout 120 -j 2
continue-on-error: true

- name: Upload mutant results
if: always()
uses: actions/upload-artifact@v4
with:
name: mutant-results
path: crates/uteke-core/mutants.out/
retention-days: 30
9 changes: 9 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,23 @@ jobs:
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} -p uteke-core --allow-dirty
continue-on-error: true

- name: Wait for crates.io index propagation
run: sleep 60

- name: Publish uteke-mcp
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} -p uteke-mcp --allow-dirty
continue-on-error: true

- name: Wait for crates.io index propagation
run: sleep 30

- name: Publish uteke-cli
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} -p uteke-cli --allow-dirty
continue-on-error: true

- name: Wait for crates.io index propagation
run: sleep 30

- name: Publish uteke-server
run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} -p uteke-server --allow-dirty
continue-on-error: true
Expand Down
26 changes: 4 additions & 22 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
/target/
*.swp
*.swo
*~
.DS_Store
.idea/
.vscode/
*.pdb
__pycache__/
milestone*.md

# Runtime index files
uteke_index.keys
uteke_index.usearch
.fusion/
progress.md
.cora/
scripts/demo-record.sh

# Internal docs — never commit to public repo
internal/

# Benchmark results (large, ephemeral — commit RESULTS.md summaries, not raw data)
benchmarks/longmemeval/results_*/

# cargo-mutants output (local only — run before release)
mutants*.out/
mutants*.out.old/

# VitePress build artifacts (keep config.ts, not lock files)
docs/package-lock.json
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
# Changelog

## [0.14.1] — 2026-08-14

Patch release: two chunker bug fixes found by mutation testing, plus test-suite hardening. No API or behavior changes beyond the fixes.

### Fixed

- **Markdown heading duplicated in oversized sections** — When a markdown section exceeded `max_chunk_chars`, its heading appeared twice in the first sub-chunk: once from `split_by_headings`, then again from the sub-chunking loop. Every oversized markdown document was quietly producing corrupted chunk content, which flows directly into embedding input and degrades retrieval quality. The dead re-prepend path is removed entirely (#1024).

- **Infinite loop on multi-byte text with small chunk sizes** — The zero-progress guard in `split_long_text` advanced by raw byte offsets that could land inside multi-byte UTF-8 characters (CJK, emoji), flooring back to the start position forever. `chunk_markdown("日本語", 2)` would hang. The guard now advances to the next valid character boundary (#1024).

### Changed

- **cargo-mutants configuration moved to `.cargo/mutants.toml`** — The previous config at `crates/uteke-core/mutants.toml` used the key `exclude_files`, which is not a valid field in cargo-mutants v27 and was silently never applied. Migration to `.cargo/mutants.toml` (the location cargo-mutants actually reads) with the correct v27 schema (`exclude_globs`, `exclude_re` as arrays) and workspace-root-relative glob paths. This release is the first where mutant exclusions actually work.

- **Chunker test suite grew from 20 to 60 tests** — Mutation score improved from 50% to 97% (149/164 mutants caught, 0 missed non-equivalent). 3 proven-equivalent mutants are excluded with documented reasoning.

## [0.14.0] — 2026-08-14

Minor release: hybrid recall as default strategy, scene-segmented extraction, memory tools guide, lifecycle introspection, and source provenance. One behavior change (recall default).
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [
]

[workspace.package]
version = "0.14.0"
version = "0.14.1"
edition = "2024"
license = "Apache-2.0"
repository = "https://github.com/codecoradev/uteke"
Expand Down
2 changes: 1 addition & 1 deletion crates/uteke-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ name = "uteke"
path = "src/main.rs"

[dependencies]
uteke-core = { path = "../uteke-core", version = "0.14.0", features = ["onnx"] }
uteke-core = { path = "../uteke-core", version = "0.14.1", features = ["onnx"] }
clap = { version = "4", features = ["derive"] }
serde_json = "1"
tracing = "0.1"
Expand Down
Loading
Loading