Skip to content

fix(storage): graceful old-schema snapshot load with actionable error… #199

fix(storage): graceful old-schema snapshot load with actionable error…

fix(storage): graceful old-schema snapshot load with actionable error… #199

Workflow file for this run

# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 Firelock, LLC
name: CI
on:
push:
branches: ["**"]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
# `deprecated` is now ENFORCED (FIR-855): all kin-db call sites of
# kin-model's deprecated ArtifactId::from_path / ::from_file_id were migrated
# to the graph-assigned id via the `artifact_index` lookup. The only remaining
# uses are deterministic legacy-link/migration seed paths carrying local
# `#[allow(deprecated)]` with justification, so -Dwarnings can deny the lint.
RUSTFLAGS: -Dwarnings
jobs:
dco:
name: DCO Sign-off
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check DCO sign-off
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
fail=0
range="${BASE_SHA}..${HEAD_SHA}"
echo "Checking DCO sign-off for commits in ${range}"
for sha in $(git rev-list --no-merges "${range}"); do
author_name=$(git show -s --format='%an' "${sha}")
author_email=$(git show -s --format='%ae' "${sha}")
expected="Signed-off-by: ${author_name} <${author_email}>"
if git show -s --format='%(trailers:key=Signed-off-by)' "${sha}" \
| grep -qiF "${expected}"; then
echo "OK ${sha} ${expected}"
else
echo "FAIL ${sha} missing or mismatched sign-off (expected: ${expected})"
git show -s --format=' author: %an <%ae>%n trailers:%n%(trailers:key=Signed-off-by)' "${sha}"
fail=1
fi
done
if [ "${fail}" -ne 0 ]; then
echo "::error::One or more commits are missing a matching 'Signed-off-by' trailer (DCO). Re-commit with 'git commit -s'."
exit 1
fi
echo "All commits carry a matching DCO sign-off."
check:
name: Check & Test
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.96.0
with:
components: clippy, rustfmt
- name: Cache cargo registry and build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt -- --check
- name: Clippy
# CLIPPY BURN-DOWN ALLOW-LIST (kin-db).
# kin-db is the retrieval stack; during the freeze, behavior-adjacent code
# edits on main are FORBIDDEN, so these pre-existing lints are temporarily
# ALLOW-LISTED here (CI-config only) instead of fixed in code. -D warnings
# still applies to everything else, so no NEW lint can slip in. Burn these
# down one at a time post-freeze (smallest blast radius first); delete each
# -A line as its lint reaches zero.
# PRIORITY REVIEW: clippy::suspicious_open_options — the truncate-cousin
# class (cf. kin-vector .truncate(false) fix); verify open-options intent
# before clearing, do NOT blindly accept a clippy autofix here.
# NOTE: the rustc `deprecated` lint is no longer allow-listed (FIR-855):
# all kin-db call sites were migrated to the graph-assigned ArtifactId via
# the `artifact_index` lookup, so -D warnings now denies it here too.
run: |
cargo clippy --all-targets -- -D warnings \
-A clippy::assertions_on_constants \
-A clippy::blocks_in_conditions \
-A clippy::cloned_ref_to_slice_refs \
-A clippy::field_reassign_with_default \
-A clippy::large_enum_variant \
-A clippy::let_and_return \
-A clippy::let_unit_value \
-A clippy::manual_checked_ops \
-A clippy::needless_borrows_for_generic_args \
-A clippy::needless_return \
-A clippy::redundant_pattern_matching \
-A clippy::suspicious_open_options \
-A clippy::type_complexity \
-A clippy::unnecessary_sort_by \
-A clippy::useless_conversion
- name: Build
run: cargo build --all-targets
- name: Test
# HF_HUB_OFFLINE keeps the run deterministic/offline. These three tests
# construct a real embedder and need HF network + nomic weights, which CI
# cannot fetch — skipped here (CI-config, no test code touched) until an
# offline stub-weights fixture exists (post-freeze item). Everything else
# (graph/storage/search/vector/text) is pure-Rust and runs.
#
# many_vectors_search_quality: its fixture inserts 100 vectors with only 8
# distinct patterns (13 IDENTICAL to the query) and asserts exact-top-1 ==
# the first-inserted duplicate. BISECTED to kin-vector efe77db: it passes
# at efe77db~1 (insertion-order tie-break returns key 0) and fails at
# efe77db (key-hash tie-break deterministically returns key 8). This is a
# CORRECTNESS fix, NOT a recall regression — the returned neighbor is still
# a perfect zero-distance match; only which identical-distance duplicate
# wins changed. The exact-identity assertion is too strict for a
# duplicate-vector fixture. POST-M1: fix the fixture (assert a zero-distance
# match / use distinct vectors) as part of the HNSW key-hash recall audit.
env:
HF_HUB_OFFLINE: "1"
run: >-
cargo test --
--skip process_embedding_queue_without_embeddings_is_noop
--skip default_dimensions_match_default_model
--skip test_vector_index_dimension_mismatch_auto_recovery
--skip many_vectors_search_quality
# Security audit moved to sast.yml (cargo-deny: advisories + licenses + bans + sources)
coverage:
name: Code Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.96.0
- name: Cache cargo registry and build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-tarpaulin-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-tarpaulin-
- name: Install cargo-tarpaulin
run: cargo install cargo-tarpaulin
- name: Run coverage
run: |
if ! cargo tarpaulin --out xml --out stdout; then
echo "::warning::Tarpaulin is currently non-blocking in CI for the public alpha."
fi
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
files: cobertura.xml
token: ${{ secrets.CODECOV_TOKEN }}
slug: firelock-ai/kin-db
fail_ci_if_error: false
notify-downstream:
name: Notify Downstream Repos
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
needs: [check]
runs-on: ubuntu-latest
env:
DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }}
steps:
- name: Trigger kin CI
# No-op until DISPATCH_TOKEN is provisioned (it never has been): without
# the secret, env.DISPATCH_TOKEN is empty so this step skips and the job
# stays green instead of failing on the missing token. Mirrors the fleet
# fix (kin-vector / kin-infer c119b84). Remove the guard once the
# cross-repo PAT is added.
if: ${{ env.DISPATCH_TOKEN != '' }}
uses: peter-evans/repository-dispatch@v3
with:
# Requires a PAT with repo scope stored as DISPATCH_TOKEN secret.
# Create at: GitHub > Settings > Developer settings > Personal access tokens
# Then add to: kin-db repo > Settings > Secrets > Actions > DISPATCH_TOKEN
token: ${{ secrets.DISPATCH_TOKEN }}
repository: firelock-ai/kin
event-type: dependency-updated
client-payload: '{"source": "kin-db", "sha": "${{ github.sha }}"}'