Commit graph

312 commits

Author SHA1 Message Date
Trevon
e4b32e98bd
fix: fence enrichment completion and reconcile promotion prerequisites (#157)
Some checks failed
Secret scan / gitleaks (push) Failing after 8s
Mirror source to Forgejo / mirror (push) Has been skipped
Release Candidate / Validate promotion and preview release (push) Has been cancelled
Tests / Static Analysis (push) Has been cancelled
Tests / Warm Conan & ccache (linux-arm64) (push) Has been cancelled
Tests / Warm Conan & ccache (macos-arm64) (push) Has been cancelled
Tests / Warm Conan & ccache (linux-x86_64) (push) Has been cancelled
Tests / Warm Conan & ccache (macos-x86_64) (push) Has been cancelled
Tests / Warm Conan & ccache (windows-x86_64) (push) Has been cancelled
Tests / warm (push) Has been cancelled
Tests / Tests (linux-arm64) (push) Has been cancelled
Tests / Tests (macos-arm64) (push) Has been cancelled
Tests / Tests (linux-x86_64-asan) (push) Has been cancelled
Tests / Tests (linux-x86_64-ubsan) (push) Has been cancelled
Tests / Tests (linux-x86_64) (push) Has been cancelled
Tests / Tests (windows-x86_64) (push) Has been cancelled
* test(ci): stabilize main matrix (#112)

Signed-off-by: trvon <me@trevon.dev>

* ci(release): preview experimental promotion (#111)

Signed-off-by: trvon <me@trevon.dev>

* ci(release): reconcile draft promotion safely (#113)

* ci(release): reconcile draft promotion

Create promotion visibility independently of release readiness.
Leave existing PRs untouched to preserve concurrent maintainer edits.
Validate against current main without masking candidate rejection.

Signed-off-by: trvon <me@trevon.dev>

* ci: isolate hook Git environments

Prevent temporary Git fixtures from modifying the calling worktree.
Clear repository-local hook variables before the unchanged build gates,
and isolate validator and fixture Git subprocesses from caller overrides.
Exercise linked-worktree config, ref and index preservation offline.

Signed-off-by: trvon <me@trevon.dev>

---------

Signed-off-by: trvon <me@trevon.dev>

* fix(ci): reject invalid candidate evidence

Explain missing main history without mutating refs or weakening promotion validation. Match experiment boolean and aggregation parsing, respect candidate-limit precedence, and return issues for malformed configuration or metric values.

Signed-off-by: trvon <me@trevon.dev>

* fix: preserve completion and retrieval contracts

Propagate derivation SQL failures, invalidate KG status caches, and avoid unused preview reads. Align explicit hash validation and export standalone client dependencies. Keep secret exceptions fixture-scoped and remove undefined behavior from status fixtures.

Signed-off-by: trvon <me@trevon.dev>

* fix: fence asynchronous enrichment completion

Coordinate graph and NL commits before acknowledging enrichment. Atomically classify embedding reuse, fence repair status writes, and preserve newer vectors on old failures. Upgrade content readiness triggers and keep repository counters coherent. Six affected ASan suites pass; this does not provide restart replay or generation-scoped vector storage.

Signed-off-by: trvon <me@trevon.dev>

* fix: bound semantic graph output reservation

Use retained neighbors for admission and node capacity instead of mixing corpus and pair counts. Preserve single-neighbor output and avoid quadratic reservation. Characterization regression fails three assertions before the fix; full component ASan suite passes afterward.

Signed-off-by: trvon <me@trevon.dev>

* fix: fence standalone embedding repair completion

Mint attempt tokens before reading canonical repair input and publish only current persisted document embeddings. Do not skip stale physical vectors. Make SQLite preparation fault injection connection-local and deterministic. Full component and metadata ASan suites pass.

Signed-off-by: trvon <me@trevon.dev>

* fix: preserve enrichment failure reporting

Admit pending embedding attempts before provider failures while preserving completed results. Route title no-op acknowledgement through the writer so flush reports SQL failures and duplicate jobs can retry. Four affected full ASan suites pass; host configuration hashes unchanged.

Signed-off-by: trvon <me@trevon.dev>

* test: align explicit hash prefix boundaries

Reject five characters and accept the supported six-character minimum. Full hybrid_search suite passes. Separate daemon shutdown sanitizer failure remains under investigation despite a passing targeted rerun.

Signed-off-by: trvon <me@trevon.dev>

* test: align UI hash validation boundary

Signed-off-by: trvon <me@trevon.dev>

---------

Signed-off-by: trvon <me@trevon.dev>
2026-09-12 18:53:12 -06:00
Trevon
60855b7b78
[11/14] Separate status presentation and centralize shared query helpers (#151)
Some checks failed
Secret scan / gitleaks (push) Failing after 12s
Mirror source to Forgejo / mirror (push) Has been skipped
Tests / Static Analysis (push) Has been cancelled
Tests / Warm Conan & ccache (linux-arm64) (push) Has been cancelled
Tests / Warm Conan & ccache (macos-arm64) (push) Has been cancelled
Tests / Warm Conan & ccache (linux-x86_64) (push) Has been cancelled
Tests / Warm Conan & ccache (macos-x86_64) (push) Has been cancelled
Tests / Warm Conan & ccache (windows-x86_64) (push) Has been cancelled
Tests / warm (push) Has been cancelled
Tests / Tests (linux-arm64) (push) Has been cancelled
Tests / Tests (macos-arm64) (push) Has been cancelled
Tests / Tests (linux-x86_64-asan) (push) Has been cancelled
Tests / Tests (linux-x86_64-ubsan) (push) Has been cancelled
Tests / Tests (linux-x86_64) (push) Has been cancelled
Tests / Tests (windows-x86_64) (push) Has been cancelled
* refactor(daemon): one table for repair operation wire codes

The code published under repair_current_operation_code was defined in
three places: a name->code chain in RepairService.cpp, an enum->name
switch beside it, and a code->label switch in the CLI. The two daemon
tables agreed with each other but the CLI copy had already drifted in
wording, and nothing tied the three together.

metric_keys.h now carries the single code<->name table next to the
metric key it describes, with constexpr lookups in both directions.
RepairService's name->code chain delegates to it; the enum->name
switch stays because it is keyed by the private enum. The CLI copy
goes in the next commit with the status renderer.

Signed-off-by: trvon <me@trevon.dev>

* refactor(cli): extract the daemon status renderer

showStatus() in daemon_command.cpp was 1,762 lines: two RPCs, a
bootstrap-file fallback, and two ~400/1,100-line render bodies that
wrote straight to std::cout from inside the command class, reachable
only through a live daemon. The render bodies read nothing from the
command except the expected data directory, the explicit-socket flag,
and a memory-sync fetch they triggered mid-render.

The bodies now live in src/cli/commands/daemon_status_render.cpp as
free functions over StatusResponse plus a small DaemonStatusRenderContext
(configured data dir, explicit-socket flag, optional MemorySyncResponse)
writing to an ostream. The readiness/label helpers that only they used
(humanizeToken, classifyReadiness, isEphemeralDataDir,
daemonDataDirFromStatus, paintStatus, neutralText) move with them.
DaemonCommand keeps the RPCs and the bootstrap fallback; the memory-sync
fetch becomes fetchMemorySyncStatus() and runs just before rendering
instead of in the middle of it, so the section prints in the same place
with the same bounded 3 s timeout.

The move is verbatim: after the mechanical substitutions
(std::cout -> os, expectedDataDir() -> ctx.configuredDataDir, the
memory-sync call, the explicit-socket flag, and the repair label
function) the two bodies match the originals character for character
modulo whitespace. The CLI's private repair-operation switch is gone;
the label now comes from the shared table in metric_keys.h with
underscores rendered as spaces, which reproduces the previous wording
("stuck docs", "block refs", "path tree").

tests/unit/cli/daemon_status_render_catch2_test.cpp drives both
renderers and the memory-sync section from synthetic responses:
overview rows, blockers with init progress, last error, data-dir
mismatch (and its suppression under --socket), temporary data dir,
the active repair operation label, every detailed section, and the
started/not-started memory-sync gate.

daemon_command.cpp: 4,082 -> 2,341 lines; daemon_status_render.cpp:
1,642 lines.

Signed-off-by: trvon <me@trevon.dev>

* refactor(app): one home for hash predicates, path aliasing, and metadata qualifiers

Three small helpers had grown parallel copies with quietly different
rules:

- "does this look like a hash" existed four times: search_service
  (8-64 hex), document_service (6-63), cat_command (6-64), plus a
  never-defined utils::looksLikeHash declaration in services.hpp. The
  8 vs 6 threshold is deliberate (D3): a bare query token must reach
  8 hex characters before it stops being text, while an explicit hash
  argument may be 6. yams/common/hash_predicates.h now names the two
  predicates apart (looksLikeHashQueryToken, looksLikePartialHashArgument)
  over one isHexDigits; document_service's 6..63 bound was deliberate
  for the name resolver (a full 64-hex name must not resolve as a prefix
  and delete by hash), so its two resolver sites now guard size() != 64
  explicitly, as the partial-hash resolution site already did.

- macOS /private aliasing had three incompatible policies: search
  appended the alias of /var only, grep canonicalized /var and /tmp
  to the /private spelling, and the delete resolver displayed
  /private/var as /var. yams/common/fs_utils.h now carries one alias
  table ({/var,/tmp} <-> /private/...) with three lexical policies over
  it (otherSpelling, canonicalSpelling, displaySpelling) and the
  platform-gated wrappers callers use. Declared behavior change, macOS
  only: search patterns under /tmp now also match their /private/tmp
  spelling, and the resolver displays /private/tmp/... as /tmp/....

- Inline key=value metadata filters were parsed twice: SearchService's
  extractStructuredMetadataQuery (exactly one '=', no quoting/grouping
  characters, deduplicated by key) and SearchEngine's
  parseMetadataFiltersFromQuery (any '=' token, duplicates kept). The
  stricter, tested parser moves into yams/search/query_qualifiers.hpp
  and both call it. Declared behavior change for the hybrid metadata
  component: tokens like name="x" or a=b=c stay in the query instead
  of becoming filters, and repeated keys collapse to the last value.

Tests: hash_predicates_catch2_test.cpp pins both thresholds and the
64-character bound; path_alias_catch2_test.cpp pins the alias table,
the three policies, and the platform gating; query_qualifiers_catch2_test.cpp
gains the structured-metadata cases (split, dedupe, malformed tokens,
filters-only). search_service, document_service, grep_service,
service_utilities, and resolve_submodule pass unchanged. Portability
allowlist anchors reflowed for the four files whose lines moved.

Signed-off-by: trvon <me@trevon.dev>

* fix(cli): flush status before optional collection

Render useful primary status before waiting for memory-sync details.
Keep both brief and detailed paths behind the tested ordering seam.

Signed-off-by: trvon <me@trevon.dev>

---------

Signed-off-by: trvon <me@trevon.dev>
2026-09-12 10:09:21 -04:00
Trevon
946944f79c
[10/14] Move large inline implementations into translation units (#150)
* test(memory-sync): give the CLI fixture the shared corpus scope it needs

94e948c6 made createMemorySyncService fail closed unless
memory_sync.corpus_scope is "shared" and updated the service-manager
test, but not the p2p CLI fixture, whose eight cases have failed at
construction ever since ("replication requires
memory_sync.corpus_scope=shared"). The fixture now sets the scope; the
cases run again and pass.

Signed-off-by: trvon <me@trevon.dev>

* refactor(memory_sync): move MemorySyncLoop bodies into a translation unit

include/yams/memory_sync/memory_sync.h was a 3,527-line header-only
class: 120 inline method definitions, 2,900 lines of implementation,
pulled into every translation unit that includes daemon.h or the p2p
protocol header. The memory-sync subsystem had no source directory at
all.

MemorySyncLoop's bodies now live in src/memory_sync/memory_sync.cpp,
compiled once into a new yams_memory_sync static library that follows
the yams_wal pattern. The header keeps the declarations, the nested
types, the constructor, one-line accessors, and the YAMS_TESTING hooks
(those must stay inline because the library is not built with the
testing define). The daemon library and its declared dependency link
the new library, as do the five memory-sync test binaries.

Zero semantic change: the move is mechanical (a scripted split that
copies each body verbatim, drops default arguments and static from the
definitions, and qualifies nested return types). All seven memory-sync
test binaries and the service-manager suite pass unchanged.

memory_sync.h: 3,527 -> 569 lines.

Signed-off-by: trvon <me@trevon.dev>

* refactor(daemon): move TuneAdvisor method bodies out of the header

TuneAdvisor.h was 3,345 lines, almost all of it the bodies of ~300
static accessors and setters, included by 60 translation units. Each
of them recompiled the whole policy surface on every touch, and any
change to one knob rebuilt most of the daemon.

The bodies now live in src/daemon/components/TuneAdvisor.cpp (which
previously held only the system-memory probe). The header keeps the
declarations, the static inline override slots (unchanged, so the
ODR story for process-wide tuning state is exactly what it was), the
YAMS_TESTING hooks, and the two methods whose bodies are
preprocessor-conditional on YAMS_TESTING; those must stay inline
because the library is not built with the testing define and moving
them would silently switch tests to the production branch.

Mechanical move by the same scripted split used for memory_sync.h:
bodies copied verbatim, static and default arguments dropped from the
definitions, nested return types qualified. The one template
(readConfiguredOverridesSnapshot) stays in the header because three
other translation units instantiate it.

The header is included well outside src/daemon (vector, repair, app
services, MCP, the CLI doctor, the ONNX plugin), and those targets do
not link yams_daemon. They used to get the bodies for free from the
header, so the move needs a home they can all link: the new
yams_tune_advisor static library (src/daemon/tune_advisor/meson.build)
builds TuneAdvisor.cpp alone, and yams_daemon, yams_vector,
yams_repair, yams_app_services, yams_mcp, yams_cli, the ONNX plugin,
and the standalone snapshot test depend on it.

Executables compiled with -DYAMS_TESTING link a second build of the
same file, yams_tune_advisor_testing, ahead of the production archive.
Under that define compatibilityEnvironment() reads the process
environment live instead of the startup snapshot, which every
env-driven tuning test relies on; before the split each such TU
instantiated the inline bodies itself with the define. Meson emits
dependencies in list order and the first archive defining a symbol
wins, so the order is load-bearing: test_deps, the benchmark
dependency lists, and the mobile ABI test all put the testing archive
first, and tests/meson.build says so. The testing archive is built
under the same predicate that enters tests/ (a plain debug configure
included), so `meson setup --buildtype=debug` keeps working. The
standalone snapshot test keeps the production build on purpose.

No behavior change; a full debug compile is clean and the tuning
suites pass unchanged.

TuneAdvisor.h: 3,345 -> 1,170 lines.

Signed-off-by: trvon <me@trevon.dev>

---------

Signed-off-by: trvon <me@trevon.dev>
2026-09-12 10:09:20 -04:00
Trevon
6b5b6647bd
[04/14] Repository hygiene and reviewable configuration/retrieval contracts (#144)
* chore(repo): land the retrieval contract and drop root cruft

Lands work that had been sitting uncommitted in the working tree:

- docs/architecture/retrieval_contracts.md plus its executable form,
  tests/benchmarks/retrieval_contract.py and test_retrieval_contract.py,
  now registered in meson as retrieval_contract_unit (suite: policy).
  .gitignore keeps them tracked beneath the tests/benchmarks/*.py ignore.
- AGENTS.md: the Development Memory section, and the product default
  recorded as hybrid_assist + shadow with topology-off as the control,
  which is what search_topology_stage already does.
  docs/benchmarks/index.md gains the matching search_shadow_cost plan.
- .gitleaks.toml, and a Secret scan workflow that actually runs it on
  push and pull requests (nothing in .github invoked gitleaks before).

Deletes three root files with zero references anywhere in the tree:
bench_profile.json (ad-hoc profiling leftover), CppProperties.json
(Visual Studio config; the repo standardises on Meson), and spdlog.pc
(a hand-copied spdlog 1.12 pkg-config with prefix=/usr/local that would
mislead any PKG_CONFIG_PATH lookup; spdlog comes from Conan).

docs/plans/ (two p2p designs already shipped in 5a53cdfa and d012d95b)
was ingested into YAMS with task=desloppification source=plan, hydrated
via yams cat and byte-compared before removal, per the new AGENTS.md
rule; tests/scripts/analyze_simeon_adaptivity.py no longer points at a
plans directory.

Also reflows two stale line anchors in raw_environment_allowlist.txt
for tools/yams-cli/main.cpp (shifted by 11c39157) so the policy suite
passes again; no new environment writes.

Not included: the external/yams-repo submodule pointer in the working
tree was a stale local clone two commits behind, not an intended bump.

Signed-off-by: trvon <me@trevon.dev>

* test(policy): make the configuration-authority ratchet bidirectional

check_configuration_authority.py only reported keys and TOML readers
present in code but missing from the allowlists, so the reviewed
YAMS_* surface could grow but never shrink: production_environment_keys.txt
even said removals "may remain grandfathered". An allowlist that only
accretes stops describing the code.

The policy now also fails on allowlist entries with no remaining
occurrence in src/, include/, or tools/, naming the lines to delete.
Key removals in later commits therefore have to update the allowlist in
the same change, and the count in the success banner becomes a real
measure of the environment surface (432 today).

stale_entries() exposes the two stale sets for tooling; three unit
tests cover stale key, stale reader, and the returned names.

Signed-off-by: trvon <me@trevon.dev>

* tools(policy): report where every configuration key is referenced

Adds tests/scripts/report_config_key_usage.py: for each YAMS_* key in
production_environment_keys.txt and each dotted TOML key literally
resolved in ConfigResolver.cpp, count whole-token references per tree
bucket (src, test, bench, docs, plugin; build output and the allowlists
themselves excluded) and assign a verdict: KEEP when anything outside
product code exercises or documents the key, CANDIDATE when only
product code mentions it, NOT_IN_SRC when the allowlist is stale.

The report is evidence, not a decision. From here on a key deletion
must paste its CANDIDATE rows into the change description; the first
audit pass hand-listed keys that turned out to have bench and test
consumers, which is exactly the mistake a mechanical inventory avoids.

Today: 432 env keys (215 CANDIDATE, 217 KEEP), 117 TOML keys
(103 CANDIDATE, 14 KEEP). Registered as config_key_usage_report_unit.

The report counts only files git tracks (git ls-files) when the root is a
work tree, so an ignored local bench harness cannot turn a CANDIDATE into a
KEEP on one machine and not another; outside a work tree it falls back to
scanning the directory, which is what the synthetic-tree test exercises.

Signed-off-by: trvon <me@trevon.dev>

---------

Signed-off-by: trvon <me@trevon.dev>
2026-09-12 10:09:18 -04:00
trvon
390431dbd6
fix(ingest): preserve extractor metadata through enrichment
Signed-off-by: trvon <me@trevon.dev>
2026-09-05 11:53:10 -06:00
trvon
11c391579c
fix(cli): preserve content bytes during hash hydration
Signed-off-by: trvon <me@trevon.dev>
2026-09-05 11:52:46 -06:00
trvon
67d2a6a9b1
fix(retrieval): preserve content identities in JSON results
Signed-off-by: trvon <me@trevon.dev>
2026-09-05 11:52:46 -06:00
trvon
618bd5e0c0 ci: isolate experimental package repositories
Signed-off-by: trvon <me@trevon.dev>
2026-09-04 17:14:43 -06:00
trvon
0ab39df476
ci: attest experimental release artifacts
Signed-off-by: trvon <me@trevon.dev>
2026-09-03 21:39:17 -06:00
trvon
4778c9154b
ci: pin experimental release source
Signed-off-by: trvon <me@trevon.dev>
2026-09-03 21:39:16 -06:00
trvon
8639893fad
ci: mirror approved refs to Forgejo
Signed-off-by: trvon <me@trevon.dev>
2026-09-03 21:39:16 -06:00
0xkite
000863e664
docs: replace SourceHut with Forgejo mirror (#91)
Signed-off-by: trvon <me@trevon.dev>
Co-authored-by: trvon <me@trevon.dev>
2026-09-03 17:16:57 -06:00
trvon
5d967b9708
feat(metrics): surface WAL data-system optics in daemon status
WalMetricsProvider::getStats() was wired (attachWalManager) but never
consumed anywhere: WAL active/pending/total entries, bytes, and log-file
count were invisible to operators. Close the optics gap:

- MetricsSnapshot: add walActiveTransactions/PendingEntries/TotalEntries/
  TotalBytes/LogFileCount (detailed snapshot only).
- DaemonMetrics::enrichDetailedSnapshot: populate from
  ServiceManager::getWalMetricsProvider() (cheap atomic reads).
- request_dispatcher_status: emit wal_* requestCounts on detailed status.
- metric_keys.h: kWAL* keys (wal_active_transactions, ...).
- status_command --json: render a 'wal' object when counters are nonzero.
- tests: WalMetricsProvider pass-through unit tests (zeros without a
  manager; forwards WALManager stats; reset on null manager).

Validated: build/debug suite (ConfigResolver 42 cases, metrics core/status,
new WAL provider tests) plus brick (0 new cycles on touched files) and fold
(0 findings on added lines).
2026-09-01 13:55:44 -06:00
Trevon
9c19452e7d
test(p2p): add direct control fuzz harnesses (#74)
Add libFuzzer/AFL++ harnesses for the direct-P2P handshake/state/history and
delta/bootstrap control parsers. Fuzzers invoke the same production parser
seams as the live wire path, so coverage cannot drift from real validation. A
protocol-v3 seed exercises exact-version rejection after the v4 upgrade. Bound
noninteractive AFL++ campaigns with AFL_FUZZ_SECONDS and register focused
fuzz-smoke tests without duplicating broad protocol/delta registrations.
Clarify that peer/cycle status is local health telemetry rather than global
convergence, and document the remaining decision-grade live-performance gate.

Signed-off-by: trvon <git@trevon.dev>
2026-08-30 11:27:11 -06:00
Trevon
dbe7aea900
fix(p2p): resume bounded history catch-up (#70)
Signed-off-by: trvon <git@trevon.dev>
2026-08-30 11:27:09 -06:00
Trevon
5a53cdfa90
feat(p2p): add authenticated direct replication (#68)
* fix(memory-sync): keep replication responsive

Skip poisoned blobs without wedging backfill and publish immutable status snapshots so daemon IPC does not block on an active reconciliation cycle.

Reconstructed from ff62d3f8, 8e232721, and e60f513d.

Signed-off-by: trvon <git@trevon.dev>

* feat(p2p): add authenticated direct transport

Require TLS 1.3 mutual identity and bind the authenticated certificate, node, corpus, and epoch before replication state is exchanged.

Reconstructed from 96f9db88 and c46de77b.

Signed-off-by: trvon <git@trevon.dev>

* feat(p2p): exchange causal deltas

Persist peer pins and causal resume state before visibility so reconnects continue bounded authenticated replication without becoming remote query proxies.

Reconstructed from 1b8be146 and 41883338.

Signed-off-by: trvon <git@trevon.dev>

* feat(p2p): integrate direct sync services

Wire listener, reconnect, IPC, CLI, peer persistence, and daemon lifecycle around the authenticated direct transport.

Reconstructed from a19aaa44.

Signed-off-by: trvon <git@trevon.dev>

* fix(p2p): apply replicated document state

Index authenticated remote winners, propagate document tombstones, and keep service/test wiring complete across daemon paths.

Reconstructed from 4ca660c6, 443253f1, 3e9db24d, and 4b2ddcc5.

Signed-off-by: trvon <git@trevon.dev>

* test(p2p): register direct sync gates

Replace the superseded internal contract with operator-facing direct-sync guidance and register daemon integration coverage in the standard test layout.

Reconstructed from 360b9115 and 89416ccb.

Signed-off-by: trvon <git@trevon.dev>

* fix(p2p): require bounded peer enrollment

Bound aggregate sessions and worker lifetimes, create owner-only identity keys atomically, and reject unknown inbound peers until operators pin their mTLS identity.

Reconstructed from f91be528, 79de8e48, 4fb1e4b8, dc30a6c0, and b329edd3.

Signed-off-by: trvon <git@trevon.dev>

* fix(p2p): persist quarantine and deletes

Persist full-history writer commitments before invalidating forked state, and order local deletion through a durable authenticated outbox so tombstones survive crashes and reconnects.

Reconstructed from 74ce01e0 and 19888604.

Signed-off-by: trvon <git@trevon.dev>

* feat(p2p): add authenticated cold bootstrap

Install bounded zero-state snapshots only from previously operator-pinned peers, bind them to exact frontiers and full-history commitments, and recover staged journals before replication can resume.

Reconstructed from 8a9f5acf.

Signed-off-by: trvon <git@trevon.dev>

---------

Signed-off-by: trvon <git@trevon.dev>
2026-08-30 11:27:08 -06:00
trvon
a83897eeb9
test(ci): normalize Windows expectations 2026-08-19 05:25:52 -06:00
trvon
780c602d50
feat(daemon): wire bounded sync lifecycle 2026-08-17 21:43:11 -06:00
trvon
ed8778163e
feat(cli): add yams p2p publish/read/status
Thin p2p command over the memory-sync service: publish <key> <value|@file>,
read <key>, and status (merged index summary + backend identity). Binary
values are hex-encoded in JSON output; config resolves from [memory_sync]
with --backend/--path/--node-id overrides.
2026-08-13 12:20:02 -06:00
trvon
347da90df4
feat(memory-sync): add daemon config + service factory
Typed MemorySyncDaemonConfig parsed from the [memory_sync] TOML section
(enabled, node_id, backend, path, sync_interval_ms) plus
createMemorySyncService() which resolves filesystem/s3 backends and
constructs the service. No YAMS_* env knobs.
2026-08-13 12:20:02 -06:00
trvon
b5d50bf9e6
feat(memory-sync): add periodic sync service
Daemon-facing service owns the backend + sync loop and reconciles on a
configurable interval via a stoppable worker thread. Typed
MemorySyncConfig (nodeId, syncIntervalMs); start/stop idempotent and
stop noexcept-safe. Backend injected so filesystem and S3/R2 resolution
stay with the caller.
2026-08-13 08:17:01 -06:00
trvon
24a15e67d3
feat(memory-sync): add backend-agnostic sync loop
Publish memory records as content-addressed blobs plus a
version-vector-tagged index record per write; sync lists the index,
pulls records, and LWW-merges to a deterministic winner per logical
key. Backend injected (filesystem / S3-R2 interchangeable).
2026-08-13 08:13:44 -06:00
trvon
91c64d6192
feat(memory-sync): add version-vector + LWW data model
Version vector (element-wise max merge, dominates/concurrent partial
order) plus hybrid timestamp and LWW resolution: causally-later writes
win, concurrent writes resolve deterministically by (ts, origin). JSON
serialization via nlohmann. Header-only, no library deps.
2026-08-13 08:05:01 -06:00
trvon
b7eaea8263
test: move stress cases to slow suite
Stress-tagged cases ran in the default unit lane because only ~[slow]
was filtered. Tag them [slow] and add ~[slow]/[slow] splits to the five
binaries (mcp_submodule, work_coordinator, daemon_background,
plugin_infrastructure, hybrid_search) so they run in the slow suite.
2026-08-12 20:36:16 -06:00
trvon
b34bfcf508
test(portability): add cross-platform lint gate
Catch Windows/Linux/macOS-only defect classes before push: raw
std::jthread, sqlite3_open* via bare path.c_str(), and raw getenv
reads outside the config boundary. Wired into pre-commit and the
unit/policy suite; 575 reviewed sites allowlisted.
2026-08-12 19:54:02 -06:00
trvon
7485b482f8
fix(build): restore clean test and benchmark links 2026-08-06 09:59:07 -04:00
trvon
fb7e76bb39
test(policy): gate configuration authority 2026-08-05 20:53:19 -04:00
trvon
30618eb113
refactor(config): consolidate runtime tuning 2026-08-05 20:53:18 -04:00
trvon
9c9e19199e
refactor(test): consolidate daemon harness 2026-08-05 20:53:18 -04:00
trvon
424d91f771
refactor(metadata): extract content transaction seams 2026-08-05 20:53:18 -04:00
trvon
4d7f15dd5c
refactor(bench): isolate benchmark controls 2026-08-05 20:53:18 -04:00
trvon
e85339ac30
refactor(config): unify flat TOML lookups 2026-08-05 20:53:17 -04:00
trvon
5066fc0893
test: isolate process environment 2026-08-04 21:31:39 -04:00
trvon
34a799d10e
refactor(config): unify environment policy 2026-08-04 14:35:10 -04:00
trvon
3f017dd47a
bench(ingestion): validate Simeon lifecycle 2026-08-03 17:52:58 -04:00
trvon
745818e67d
perf(topology): streamline artifact construction
Reuse admitted relations and dense splitter state while preserving deterministic identities, centroids, and the 64-document safety cap.

Add corpus-shaped benchmarks so construction regressions stay measurable.
2026-08-03 17:52:58 -04:00
trvon
9ff5aa7ba1
perf(storage): slice-by-8 CRC32 on all crc paths, 13.7x faster
Profiling running daemon: bit-by-bit CRC32 top CPU consumer (2289
samples/15s during grep). Same algorithm/polynomial, byte-identical
output (oracle test 0..512 len), stored checksums stay valid.

Applies slice-by-8 everywhere crc ran:
- yams::common::crc32 (+ crc32Update seeded variant for mid-stream)
- compression::calculateCRC32/updateCRC32 delegate to it
- storage-local duplicate copy removed (dead scope)
- WAL entry checksum copy removed

Also restructures sizeof arithmetic in WAL size math so opengrep does
not misread it as pointer arithmetic.
2026-08-01 00:12:32 -04:00
trvon
728a304f29
refactor(cli): share time filters between get/list
Same 6-field time filter logic copy-pasted in GetCommand and ListCommand
(~72 lines each). Extract to yams::cli::applyDocTimeFilters + DocTimeFilters,
wire both commands, add unit test.
2026-08-01 00:12:31 -04:00
trvon
3b1c86f490
refactor: deduplicate trim/escapeRegex/hasWildcard helpers
The same string helpers were copy-pasted across CLI and service code:
trim/trimCopy in 5 files, escapeRegex in 3, hasWildcard in 2, and the
regex meta-char table in 2. Move canonical versions to
yams::common::string_utils.h (trimCopy, hasWildcard, escapeRegex,
isRegexMetaChar) and wire all call sites to them; daemon_helpers'
trim_copy now delegates. Add a Catch2 test for the shared helpers.

Kept isTransientMetadataError and annotateResultRelations untouched:
they have semantically different implementations and need a separate
review, not a mechanical merge.
2026-08-01 00:12:31 -04:00
trvon
25bce22f15
fix(build): restore MSVC and Apple libc++ portability
- replace GCC/Clang-only __builtin_{add,sub,mul}_overflow calls with
  yams/core/checked_arithmetic.h helpers (addOverflow/subOverflow/
  mulOverflow/narrowOverflow); MSVC lacks these builtins, breaking the
  Windows build introduced by #61
- port the reviewed helper + unit tests from bugfix/review-findings
- detect floating-point std::from_chars availability at compile time
  (some Apple libc++ versions only provide the integral overload) and
  fall back to a strict strtod parser; template indirection keeps the
  missing overload from being diagnosed in the discarded branch
- add config_parse_utils and checked_arithmetic test targets
2026-07-31 16:40:15 -04:00
Trevon
0dd3985db4
refactor: simplify runtime paths and harden retrieval (#61)
* refactor(tuning): prune dormant runtime knobs

Remove unused tuning controls and adaptive search budget state. Extract testable ONNX slot reconciliation and search telemetry hydration seams, and correct the Apple Silicon sysctl value width.

* refactor(vector): retire dormant backends

Remove unused FAISS, model-infrastructure, VectorIndexManager, and TurboQuant paths while keeping Simeon PQ and float-vector storage.

Migrate unused V2.2 quantized schemas transactionally to V2.3. Databases containing non-default quantized formats or packed-code blobs fail closed with recovery guidance and no mutation.

* refactor(plugins): remove legacy SDK tooling

Remove the Ghidra and SDK submodules, their bespoke tests, and stale scan exclusions. Retain generic PluginProcess coverage against the repository mock fixture.

* build(vector): remove stale FAISS overrides

* refactor(ipc): remove dormant FSM snapshots

* refactor(ingest): unify bounded KG enqueue

* fix(plugins): harden allocation contracts

Keep ABI outputs null or fully initialized when allocations fail, and represent empty object payloads without relying on malloc(0).

* fix(storage): define empty object reads

Return a null buffer with zero length for successful empty-object reads instead of treating malloc(0) as an allocation contract.

* refactor(storage): trim through string views

* test: prune dormant harness helpers

Remove unused readiness and fixture helpers, and keep benchmark client-count doubling in a wide integer domain.

* chore(cpp): initialize analyzer-facing locals

* build(simeon): advance analyzer cleanup

* refactor(config): drop dead daemon client keys

* refactor(ipc): inject daemon client transport

Socket and in-process execution now share DaemonClient request dispatch, so CLI fallbacks do not need alternate service paths.

* refactor(retrieval): route CLI through daemon

Search and grep now use the same daemon handlers over socket or in-process transport. Live grep remains an explicit freshness inspection.

* refactor(graph): move CLI scope into daemon

Graph CLI requests now share daemon handlers across socket and in-process transports. CWD filtering occurs before pagination so scoped totals and pages stay correct.

* build: isolate test-only runtime controls

* refactor(metadata): decouple lock telemetry

* fix(services): return on request timeout

* fix(retrieval): enforce workspace scope

* fix(graph): scope nodes before pagination

* fix(grep): drop binary result lines

* fix(daemon): bound checkpoint wait

* fix(repair): use KG health checks

* fix(storage): always verify compressed CRC

* perf(vector): skip unchanged PQ snapshots

* build(zyp): exclude bench from default build

* build: protect Meson files from formatter

* refactor: remove unreachable production APIs

* refactor(daemon): remove dormant runtime state

* fix(vector): harden daemon provider calls

Timed-out coroutines must own their client and requests. Provider discovery must also fail instead of returning synthetic embeddings in production.

* refactor(storage): remove unusable adapters

* fix(cli): unify in-process add requests

* fix(tsan): preserve async worker progress

* test(cli): isolate daemon-dependent suites

* fix(repair): expose queue backoff progress
2026-07-31 14:16:45 -04:00
trvon
e290deb944
test(daemon): isolate sanitizer lifecycle fixtures 2026-07-29 22:30:32 -04:00
trvon
a23038f589
refactor: remove dead code and duplicate helpers
Make FAISS index ownership explicit and remove unused Rabin tables.
2026-07-29 16:17:10 -04:00
trvon
a3fd678f82
chore(bench): keep xplan local
Stop shipping the experiment harness and compatibility wrappers while preserving them as gitignored local tooling. Remove stale Meson registrations and mark recorded benchmark numbers as historical.
2026-07-27 18:10:38 -04:00
trvon
8d447f1a89
fix(grep): bound final result window
Keep per-file max-count independent from the daemon final window. Preserve raw totals and expose selection telemetry for agent-memory output benchmarks.
2026-07-27 17:45:17 -04:00
Trevon
3f37e8f564
Sync experimental into main: Search retrieval improvements (#60)
* fix(graph): handle qualified C++ symbols

Signed-off-by: trvon <me@trevon.dev>

* refactor(vector)!: remove dead transition APIs

Split Simeon vector and retrieval linkage so consumers inherit only the runtime surface they use.

BREAKING CHANGE: remove unused async/model/config helpers and the undefined vector-backend factory from public headers.

Signed-off-by: trvon <me@trevon.dev>

* fix(vector): harden PQ snapshot lifecycle

Validate and atomically install persisted generations, revalidate after races, and fall back to exact search when a snapshot is stale. Add the exact-scan reference lane and distinguish observed work counters from unavailable backend metrics.

Signed-off-by: trvon <me@trevon.dev>

* feat(topology): expose route coordinates

Persist chart distortion and local-dimension evidence, retain pre-scalarization route axes, and emit detailed trace rows without treating unavailable vector work as zero.

Signed-off-by: trvon <me@trevon.dev>

* feat(xplan): add vector decision gates

Track binary and corpus identity, preserve missing-work semantics, and add repeated PQ routing, crossover, and rerank plans with quality and cost summaries.

Signed-off-by: trvon <me@trevon.dev>

* feat(topology): formalize coordinate routing

Separate chart geometry from route-risk admission and prove candidate-stage recall and strict-focus boundaries. Record the measured atlas limitations and literature basis for the next construction experiment.

Signed-off-by: trvon <me@trevon.dev>

* fix(search): serialize SymSpell readers

SQLite-backed lookups reuse mutable prepared statements, so shared-reader locking is unsafe. Advance the owned SymSpell revision for batched delete insertion and cover concurrent root lookups under TSAN.

Signed-off-by: trvon <me@trevon.dev>

* fix(vector): make mutations atomic

Preserve stored vectors on replacement and commit failures, reject cross-thread writes during explicit transactions, and restore exact reranking for quantized-primary PQ rows.

* fix(search)!: surface SymSpell write errors

Propagate persistent dictionary failures through metadata ingestion, roll back failed batches, and make clear remove stored terms.

BREAKING CHANGE: SymSpellSearch mutations now return Result values.

* feat(topology): formalize candidate expansion

* feat(vector): add coordinate-aware embeddings

* feat(topology): preserve protected relation cover

* feat(search): add graph candidate rescue

* feat(daemon): expose retrieval hydration telemetry

* feat(xplan): add rescue and hydration gates

* refactor(content): dedupe media handlers

Reuse shared graph presenter helpers and centralize repeated audio/video/archive buffer processing, validation, lifecycle, and stats helper logic.

* feat(lifecycle): prune stale corpus data

Keep cleanup preview-first while retention stays opt-in and long prune work no longer holds IPC responses open.

* feat(search): add topology candidate rescue

Preserve high-value routed candidates across vector backends while keeping exact rerank diagnostics explicit.

* feat(search): expose evidence paths

* docs: define mobile host contract

* formal: model bounded candidate rescue

* fix(prune): inspect extensionless signatures

* fix(prune): tolerate stale extensions

---------

Signed-off-by: trvon <me@trevon.dev>
2026-07-24 19:00:22 -04:00
Trevon
7df64b1161
perf(search): bound topology routing and harden runtime paths (#59)
* fix: address review build issues

* perf(search): bound topology routing

Cache route membership, shortlist centroids with static ANN, and route SPQ through explicit allowed-document budgets.

* test(xplan): measure routed vector work

Pin benchmark binary identity and export route, cache, and phase costs for repeated equal-budget comparisons.

* test(search): use portable jthread wrapper

* fix(daemon): serialize detached cancellation

* fix(cli): honor pinned daemon sockets

* fix(xplan): support Windows contract imports

* fix(list): apply metadata filters before paging

* docs(prompts): require memory hydration

Treat search results as candidates and hydrate selected artifacts before use. Quote argument hints for strict YAML loaders.

* test(cli): keep add on pinned daemon

* test(metadata): isolate performance timing

* fix(graph): tolerate stale snippet ranges

Source files may change before persisted symbol metadata is refreshed. Omit stale snippets instead of aborting graph exploration.

* test(daemon): await request readiness

Reuse the retrying list probe before asserting post-shutdown error quality under sanitizer load.

* ci(release): use hosted cmake

Resolve Conan CMake tool requirements from PATH so cold ARM64 caches do not depend on cmake.org. Default BUILD_DIR for failure cleanup.
2026-07-19 14:53:10 -04:00
Trevon
a3d065dd8d
feat(search): make topology-assisted retrieval the default (#57)
* fix(release): repair package repo publish

Arch repo metadata and R2 uploads need to be reproducible from CI, with retry hardening for transient Cloudflare failures.

* fix(daemon): stop shutdown log storm

Init waiter must treat ShuttingDown as terminal so daemon shutdown tests do not flood Meson logs while the daemon is stopping.

* refactor(cli): delegate serve to MCP binary

Keep yams serve UX while removing MCP server linkage from yams-cli. The standalone MCP binary owns stdio serving and exits on stdin EOF.

* refactor(cli): move daemon path helpers

Keep CLI path resolution out of YamsDaemon so later link cuts can separate CLI and daemon internals. Full yams_daemon removal still needs a socket-only daemon-client split.

* refactor(daemon): split embedded client

* perf(search): add lean-guided benchmark gates

Add Lean topology/search models, ingestion ablation docs, and focused regression tests for topology and compression threshold behavior.

Extract search observability, keep benchmark-only ablation controls, and make retrieval quality benchmarks default to Simeon while preserving explicit ONNX opt-in.

* refactor(config): move daemon policies

* refactor(daemon): extract plugin runtime

* refactor(daemon): untangle service coordinators

Untangle CLI/MCP from daemon service coordinators and the daemon static lib.

- MetadataRepository uses a daemon-neutral tree-diff callback. The
  GraphComponent wrapper moves to src/daemon/components/metadata_graph_bridge.cpp,
  owned by the daemon library.
- WriteCoordinator moves to a dedicated build-only yams_write_coordinator
  static lib. Drop ResourceGovernor coupling inside the writer loop; batch
  sizing still respects config.maxBatchSize.
- AppContext gains enqueuePostIngest callback. ServiceManager wires it to
  its own enqueuePostIngest; app services no longer call ServiceManager
  directly.
- Embedding repair uses BulkIngestLease/BeginBulkIngestCallback instead of
  concrete VectorIndexCoordinator::BulkScope. Daemon dispatchers provide a
  lease factory backed by the real coordinator.
- CLI daemon_command uses config helpers instead of YamsDaemon::getXDGRuntimeDir.
- Remove explicit dependency('yams_daemon') from src/cli and tools/yams-mcp.
- Declare missing yams_extraction/yams_ingest deps on yams_app_services so
  app services link cleanly without daemon.

Validated:
  meson compile -C build/release -j4 yams-daemon yams-cli yams-mcp-server
  ninja -C build/release -t commands tools/yams-cli/yams-cli tools/yams-mcp/yams-mcp-server | grep -c libyams_daemon.a -> 0
  yams-cli --version, yams-mcp-server init, yams serve --help smoke tests

Size drop on macOS release: yams-cli 41M -> 32M, yams-mcp-server 37M -> 22M.

* fix(cli): keep stdin add local fallback

No embedded daemon now. When yams add - buffers stdin and daemon IPC is missing, store via local app services instead of failing socket_missing.

Validated:
  meson compile -C build/debug -j4 yams-cli catch2_cli_commands
  MESON_BUILD_ROOT=/Users/trevon/work/tools/yams/build/debug build/debug/tests/catch2_cli_commands 'AddCommand - reads from piped stdin and stores content'
  MESON_BUILD_ROOT=/Users/trevon/work/tools/yams/build/debug build/debug/tests/catch2_cli_commands
  meson compile -C build/release -j4 yams-cli yams-mcp-server
  meson compile -C build/asan-api -j2 yams-cli catch2_cli_commands
  MESON_BUILD_ROOT=/Users/trevon/work/tools/yams/build/asan-api ASAN_OPTIONS=halt_on_error=1:abort_on_error=1:print_summary=1 build/asan-api/tests/catch2_cli_commands 'AddCommand - reads from piped stdin and stores content'
  ninja -C build/release -t commands tools/yams-cli/yams-cli tools/yams-mcp/yams-mcp-server | grep libyams_daemon.a -> no output

* feat(bench): add xplan multi-arm experiment harness

Unified plan runner, ablation axes, REPORT/ablation docs, and
KPI snapshot so optimization loops stop living in shell matrices.

* feat(formal): expand topology/search Lean contracts

Boundary models for search provenance, construction gates,
and cluster/route objectives so Lean guides correctness while
xplan ranks performance levers.

* feat(search,topology): construction purity + graph expansion path

Raise topology build defaults (min edge 0.25, max component 64) and
split oversized CC pieces so hybrid assist is quality-positive on
scifact. Add GraphNeighbors expansion with medoid-anchor fallback,
structured helpers instead of nested session logic, and BEIR-default
xplan plans. Search engine extraction (fanout/classic pipeline) rides
along as the integration surface for routing.

* feat(topology): add KMeans engine and SGC identity contracts

Register kmeans in the factory with deterministic spherical k-means
over embeddings, and enforce SGC document-identity invariants in
debug builds with matching unit coverage.

* feat(daemon): topology readiness gates and selectable reranker

Drive topologyReady from published epoch/freshness/rebuild/dirty
ingest state (not just KG drain), surface those fields in search
stats, and wire onnx|simeon|auto|none cross-reranker selection.

* chore(search): drop meta_path tuner knobs

Meta-path routing is gone; remove dead TunedParams fields and the
ConfigResolver test for [search.meta_path].

* feat(bench): add topology_purity_validate plan

Repeats=3 validation matrix for construction-purity winners vs
topo_off so MRR deltas can clear run-to-run noise.

* chore: format add_command and config include order

Mechanical clang-format / include reorder only; no behavior change.

* feat(bench): decision-grade xplan loop for search engine

Document search-engine measurement in AGENTS; harden xplan with
repeats=3 plans, quality×latency primaries, mechanism metrics from
debug.jsonl, multi-rep log promotion, and archive superseded topology
plans.

* feat(graph): denser product semantic_neighbor topK

Raise default YAMS_GRAPH_SEMANTIC_TOPK fallback from 4 to 8 so product
graphs leave fewer degree-0 docs for GraphNeighbors expansion.

* feat(search): extract topology assist and cross-rerank seams

Pull topology assist into search_topology_stage (seed merge, skip
reasons, optional vector seed probe default 0). Extract cross_rerank
compute from search_engine. Wire probe via typed config/ConfigResolver.

* feat(bench): product-path search engine ablation plans

Add topology-off component, vector-weight, and tiered-execution xplan
plans (repeats=3) and wire them into the AGENTS measurement loop table.

* fix(ci): repair pre-push fallbacks

* feat(bench): lock-free mid-run builds + multi-corpus gates

xplan skips meson rebuild when the quality binary exists (flock +
YAMS_BENCH_FORCE_BUILD override) to stop multi-arm link races. Add
graph_vector weight and nfcorpus transfer-gate plans; document in AGENTS.

* fix(daemon): keep SearchEngine alive via shared_ptr cache

getCachedEngine previously published a raw pointer that metrics polling
used through rebuild, racing destructor of SearchEngine::Impl (TSAN).
Store and return a shared_ptr snapshot so diagnostic readers pin the
engine for the duration of getConfig/health checks.

Also adds the cautious vectorWeight 0.30→0.20 multi-corpus xplan plan.

* feat(search): route vectors through cached topology

Build and reuse validated topology snapshots, rank routed members by query similarity, and narrow the vector leg to the accepted document set with explicit work diagnostics.

Remove the retired HDBSCAN engine and vendor dependency, preserve typed topology policy through search tuning, and cover the runtime/configuration contracts.

* feat(bench): consolidate search decision plans

Enforce deterministic experiment identity and declared baselines, expose routed/global vector work metrics, and register the focused benchmark contracts.

Promote the compact repeats=3 routing-budget gate, archive superseded topology mechanism screens, and add multi-corpus product calibration plans.

* feat(search): refine topology vector routing

* fix(search): propagate daemon readiness

* feat(bench): measure generalized memory health

* fix(cli): honor in-process fallbacks

* ci: harden smolvm debug builds

* perf(search): route topology through filtered ANN

* feat(bench): measure read-write pressure

* perf(metadata): index symbol lookups on read pool

* fix(daemon): isolate startup reads and maintenance

* feat(bench): replay isolated generalized corpora

* feat(search): add evidence routing pipeline

Replace the blocking smolvm pre-push path with host ASan/TSan validation, harden sanitizer-sensitive smoke tests, and add recovery cleanup for malformed SQLite WAL sidecars.

* refactor(search): unify topology evidence path

Remove classic and sidecar fusion lanes so topology augments the recall-preserving ANN and lexical candidate pool through one product path.

* refactor(bench): prune superseded search lanes

Measure the topology-plus-ANN product path with stable experiment identity and remove obsolete sidecar and tiered controls.

* docs(search): retire stale experiment notes

Keep the benchmark handoff focused on the topology-plus-ANN product lane and its active decision plans.

* refactor(search): prune dead search surfaces

Remove unused fusion, reranker, policy, and router abstractions.
Bound topology materialization and keep document trace payloads opt-in.

* fix(cli): clear build warnings

* fix(xplan): reject stale run identity

* refactor(search)!: remove legacy query stack

Replace the unused AST/ranker/post-processor surface with focused facet aggregation used by product search.

BREAKING CHANGE: removes query parser, result ranker, search filter, and SearchResults container APIs from yams_search.

* refactor(search): type value stage traces

Remove synthetic ComponentResult markers for embedding and concept stages. Preserve failure and timeout states instead of overwriting them with fake successful results.

* refactor(search): isolate benchmark env overlays

Move test-only search environment parsing behind an injectable internal adapter. Keep all existing overlay keys and tuner pin semantics while restoring SearchEngineBuilder to composition.

* refactor(search): unify topology routing options

Snapshot topology policy once at the assist boundary and pass it through routing sessions and diagnostics. Remove repeated scalar copying without changing routing behavior or metric keys.

* fix(search): unify tuner config ownership

Use one complete config-to-params overlay for runtime seeding and no-tuner policy resolution. Reseed attached tuners on setConfig so reported and executed configuration cannot diverge.

* fix(search): snapshot tuner state per query

Read tuned config, params, and state under one lock before routing. Add a TSAN correlation test so adaptive observation cannot produce a torn logical query snapshot.

* fix(search): enforce topology routing contract

Generated configs must preserve hybrid-assist shadow routing, while daemon-backed search must abstain when published topology artifacts are stale. Keep standalone validation and global ANN recall intact.

* fix(daemon): let SQLite reclaim its file

Directly resizing a live database from sampled page counts can truncate pages allocated by concurrent writers. VACUUM must remain the only file-reclamation mechanism.

* fix(metadata): tolerate missing symbol FTS

Readiness lookups can race an unavailable optional FTS migration. Retain the indexed fast path, but retry against the base table when prepare or cached-statement execution proves the capability absent.

* build(fuzz): drop removed query parser target

The optional AFL build still referenced the deleted legacy query parser API and could no longer compile.

* fix(bench): include writes in drain oracle

A zero post-ingest queue is not durable drain while coordinated writes remain queued or in flight.

* fix(daemon): vacuum padded WAL databases safely
2026-07-13 20:26:43 -04:00
trvon
903e29ab55
test(metadata): add corruption fixture + suites: page smash (header
+ cell tail, not free space), torn WAL, truncation, crash snapshot,
salvage row-by-row fallback, writer promise draining, pool behavior.
Runs green on libsql and stock sqlite.
2026-07-01 20:11:03 -04:00
trvon
568902817a
fix(windows): unblock build and flaky tests
- use real Python and Scoop executables under SSH and CI
   - prefer python over python3 on Windows Meson probes
   - keep forced socket mode pinned for both socket env names
   - make forced-socket smoke test deterministic on Windows
   - clean sqlite WAL/SHM sidecars and randomize temp DB names
   - make video header parsing MSVC-safe and reject false MP4 hits
   - give integrity_catch2 more time on Windows runners
2026-07-01 18:21:19 -04:00