aicx 0.9.2

Operator CLI + MCP server: canonical corpus first, optional semantic index second (Claude Code, Codex, Gemini)
Documentation
# BACKLOG — append-only

Lista rzeczy *niezrobionych* surfaced ad-hoc w sesjach. Jeden plik dla całego runtime
(aicx-primary, cross-repo gdzie dotyka aicx). **Append-only.** Najnowsze wpisy na dole.
**Nigdy nie truncate.** Gdy item jest done — odznacz `[x]` z datą i refem do commita/PR,
ale wpisu nie usuwaj.

## Protokół

```
- YYYY-MM-DD [scope] one-line of what's undone. Recover: <command|path|decision>. — open|investigating|done(@ref)
```

`scope` legend: `aicx/<area>` · `loctree/<area>` · `loct-io/<area>` · `plugin/<area>` ·
`ops` · `meta`.

Większe sprawy z forensyką → osobny plik w `docs/incidents/<date>_<slug>.md`,
referencowany z wpisu.

Bez ozdobników. Bez hype. Bez "production-ready". Fakty + ścieżka recovery.

---

## 2026-05-12 — surfaced w trakcie aicx vc-init + clipboard fail z CodeScribe

- 2026-05-12 [aicx/cli] `aicx all -H 100` fails na bucket validation `local/.scripts` — regex `[a-z0-9][a-z0-9._-]{0,99}` w `src/store.rs:459` odrzuca segment zaczynający się od kropki. Cały chunk-phase pada po 41.7s, store nieaktualizowany. Recover: znajdź offending session w canonical store (`grep -rn "local/\.scripts" ~/.aicx/store/` lub state.json), albo (a) zmień bucket name na konwencyjny, (b) rozluźnij validator żeby tolerował `<root>/<dotdir>` jako edge-case. — done(@4ef7410 + walidator relax 2026-05-12 — `.scripts`/`.aicx`/`.github`/`_internal` teraz validator-OK directly; xdot-/xunder-/xdash- escape z 4ef7410 wycofany jako nadgorliwy)
- 2026-05-12 [aicx/store] **Recovery z quarantine 20260509_023025**: ~89k chunks (815 MB) odzyskanych z masowego over-quarantine z 9 maja, plus dragon-side history z `div0:/Users/maciejgad/.aicx/store/` i xcia legacy `~/xcia./store/`. Store: 9k → 121k chunks (98 MB → 1.1 GB). Mechanizm: 3× `rsync -av --ignore-existing` dorzucający tylko brakujące pliki, zachowujący fresh state. — done(2026-05-12, no commit — fs-only operacja)
- 2026-05-12 [aicx/validator] **Walidator relax**: `is_valid_repo_bucket_name` z lowercase-only do case-preserving (CamelCase GitHub orgs `LibraxisAI`, `VetCoders`, `Loctree`, `Szowesgad`) plus dot-prefix (`.aicx`, `.github`, `.scripts`) i underscore-prefix (`_internal`) jako allowed leading chars. `canonical_project_slug` lowercase normalization usunięta — case zachowywany. Doctor scan refactor: usunięty `canonicalize_bucket`/`merge_dir_ignore_existing`/`remove_empty_dirs_recursive` (dead code po relaxach), `CorpusBucketScan` struct → flat `Vec<String>`. Plus `--dry-run` flag dla `--fix-buckets`. Re-run doctor: 113 buckets quarantined do `~/.aicx/quarantine/20260512_075826/` (16 MB realnego junk: `${RELEASE_REPO}`, `<YOUR_USERNAME>`, fragmenty extracted-z-tekstu typu `Loctree/loctree.git\ncd`, markdown content jak `gitbutlerapp/gitbutler\n**Stack**:`). 296/296 lib tests pass. — done(pending commit, src/validation.rs +50/-15, src/store.rs net-cleanup, src/doctor.rs +88/-180, src/main.rs +14/-1)
- 2026-05-12 [aicx/doctor] `aicx doctor --fix` jest no-op dla większości warning classes (sidecars, index_consistency, empty_bodies). Wbrew nazwie nic nie naprawia, ten sam raport. UX gap: `--fix` powinien albo (a) faktycznie wywołać odpowiednie recovery commands (`store --full-rescan`, `--prune-empty-bodies`), albo (b) `--fix` powinno być usunięte/zrebrandowane na `--check` jeśli to tylko lint. — open
- 2026-05-12 [aicx/doctor] `--prune-empty-bodies` emit-script-only design jest defensywą z czasów wczesnego AICX, niepraktyczna dla 12k+ chunks (operator nie zrobi review per-line, więc i tak `bash /tmp/prune.sh` blind). Klasyfikacja jest deterministyczna (`chunk_body_is_empty` + 50-char threshold), nie heurystyczna. Realna naprawa: dodać `--apply` modifier który **MOVE'uje** empty chunks do `~/.aicx/quarantine/empty-bodies-<timestamp>/` (analogicznie do bucket quarantine — recoverable rename, nie outright `rm`). Plus integracja z `--fix` gdy severity=Critical. ~30 LOC + tests. — done(@pending commit — `--prune-empty-bodies --apply` move do `quarantine/empty-bodies-<ISO-timestamp>/`, review script też move-not-rm; `--fix` auto-integration zostaje osobnym kontraktem z wpisu `--fix` no-op)
- 2026-05-12 [aicx/corpus] `aicx corpus repair --apply` raportuje `repaired_files: 0, skipped_files: 31248`. Komunikat misleading: jeśli charter ("no inventing/summarizing semantic content") faktycznie zabrania ruszać `internal_thought_frame` (głównej noise class — 31194 z 31248), to repair powinien explicite powiedzieć "skipped because human review required" zamiast pokazywać liczbę kandydatów którzy nigdy nie będą naprawieni. — done(@f4e02de 2026-05-29 wip/consolidated: split `skipped_files` into `skipped_charter_protected` + `skipped_other`; `NoiseClass::is_charter_protected()` routes `InternalThoughtFrame` to its own bucket; repair message now explicitly says "X files skipped because charter requires human review (internal_thought_frame and similar)". Backward-compat: `skipped_files` preserved as sum.)
- 2026-05-12 [aicx/store] `aicx doctor`: 534/113593 chunks bez sidecarów (99% coverage). Recover: `aicx store --full-rescan` (sugerowane przez doctor). — done(2026-05-30 wip/consolidated rescan: `aicx store --full-rescan` z release binary @08f7a5a; doctor po: sidecars 227111/227111 (100%) Green, all 6 corpus_buckets Green. Zero missing sidecars.)
- 2026-05-12 [aicx/store] `aicx doctor`: index_consistency warning — 1714 orphaned tuples + 282 missing tuples w `~/.aicx/index.json` vs canonical store. Sample orphans: `${RELEASE_REPO}/releases/claude/2026_0419` (template placeholder leaked into bucket — separate bug?), `.../rust-memex/claude/2026_0423`, `BerriAI/litellm/claude/2026_0325`. Recover: `aicx store --full-rescan` żeby zreconcilować. — partial (post-restore: 1408 orphaned + 2224 missing — większość orphans to teraz nazwy quarantined w 20260512_075826, missing to restored chunks bez index entry; nadal recoverable via `aicx store --full-rescan`) — pass-2 W-D-2/H-2 verdict @c74deb1: G-3 incremental walk to Layer 2 (embeddings), NIE Layer 1 (index.json ⇄ store); counters unchanged 188 orphan / 40 missing na operator store. Operator-side `aicx store --full-rescan` nadal wymagane, NIE wykonane w pass-2. — partial-substantially-improved(2026-05-30 wip/consolidated: `aicx store --full-rescan` wykonany. Counters po: **37 orphaned / 377 missing** tuples (vs 1714/282 baseline 2026-05-12, vs 188/40 pass-2). Orphan reduction 98%. 377 missing to delta sources w canonical store nie indeksowanych jeszcze (semantic index rebuild in progress on sztudio).)
- 2026-05-12 [aicx/empty-bodies] **CRITICAL** post-restore: empty_body_chunks wzrosły z 3696 do 12788 (5.71%) bo restore dorzucił dużo codex sesji z empty internal_thought frames (frame_kind: internal_thought:8235, user_msg:3547). Recovery: `aicx doctor --prune-empty-bodies` emits cleanup script (NIE applies). Decision: review skript + apply, lub zaakceptować jako known-noise. — done(2026-05-30 wip/consolidated: `aicx doctor --prune-empty-bodies --apply` quarantined 4825 empty-body chunks + 4825 sidecars to `~/aicx/quarantine/empty-bodies-20260530_043840/` (manifest.json written); doctor po: empty_body_chunks 0/227111 (0.00%) Green.)
- 2026-05-12 [aicx/index-freshness] semantic_health Warning: 88135s (24h+) lag w semantic index po massive restore. Recovery: `aicx index --dry-run` żeby zobaczyć diff, potem apply variant żeby refresh. — in-progress(2026-05-30 wip/consolidated: operator switched embedder backend from local F2LLM (gguf 2048-dim) to cloud → sztudio Ollama qwen3-embedding:8b (4096-dim) for better semantic quality. Old `~/aicx/indexed/` (2048-dim) moved to Trash (dim-incompatible with new model). Cloud-from-silver path is structurally too slow (~1.5/s = 85h ETA for 227k chunks via Tailscale RTT), so offloaded to sztudio: `aicx index --full-rescan` running on sztudio with local Ollama call (no network overhead). Expected completion: overnight. Final indexed/ to be rsynced back to silver, or accessed remotely via aicx SSE.)
- 2026-05-12 [aicx/sanitize] **Self-echo filter hardkod**: `SELF_ECHO_PATTERNS` to `const &[&str]` z 21 patternów, **duplikat w `src/sanitize.rs:474` i `crates/aicx-parser/src/sanitize.rs:481`** (DRY violation, bug-in-waiting przy zmianach jednostronnych). Niepełne coverage: brakuje większości CLI subcommandów (`aicx all -H`, `aicx doctor`, `aicx state`, `aicx corpus`, `aicx index`, `aicx warmup`, `aicx wizard`, `aicx config`, `aicx steer`, `aicx tail`, `aicx ingest`, `aicx migrate`, `aicx sources`, `aicx serve`, `aicx extract`), MCP response side (`"result":{...}`), dashboard HTTP responses. Plus zero konfiguracji w `~/.aicx/config.toml` — wymaga recompile dla custom pattern. Realna naprawa: (a) de-dupe z aicx-parser jako single SoT, (b) auto-derive CLI subcommand patterns z `Commands::*` enum, (c) MCP catch-all `"jsonrpc":"2.0"` zamiast per-method, (d) `[extraction] extra_self_echo_patterns = [...]` w config. Skala dziś: 396 entries filtered z 872k to **niski recall** filtra — większość operator's CLI invocations dziś (~10+ `aicx X` commands) wjechała do storu jako treść. — done(@d885a6c 2026-05-29 wip/consolidated: (a) already done @616e6bc 2026-05-20; (b) `CLI_SUBCOMMAND_NAMES` + `RETIRED_CLI_SUBCOMMANDS` covering all 31 `Commands::*` variants + 3 retired (`rank`/`gemini`/`junie`), plus drift gate `cli_subcommand_names_match_commands_enum` in `src/main/tests.rs` walking `Cli::command().get_subcommands()` to fail-build on enum/constant divergence; (c) `MCP_JSONRPC_CATCH_ALL` const matches any `"jsonrpc":"2.0"` envelope including notifications and response-only payloads; (d) `[extraction].extra_self_echo_patterns` loaded from `$AICX_HOME/config.toml` (fallback `~/.aicx/config.toml`) with `OnceLock` cache + fail-safe empty vec on missing/parse-error so a TOML typo never disables hardcoded patterns. Tests: +9 in aicx-parser, all `sanitize_caps`/`noise_filter_e2e`/`is_self_echo` suites stay green. `cargo test --workspace`: 1078 passed, 0 failed.)
- 2026-05-12 [aicx/store] `${RELEASE_REPO}/releases/claude/2026_0419` jako bucket name w canonical store — placeholder template prawdopodobnie wyciekł z workflow. Sprawdzić skąd, dodać validation żeby `${...}` lub niezresolved zmienne nie tworzyły bucketów. — open
- 2026-05-12 [aicx/store] `aicx doctor`: 3696 empty-body chunks (3.25%). Breakdown: agent_reply 474, internal_thought 1282, unknown 61, user_msg 1879. Próbka z codex sessions 2025_0810/0812/0916. Recover: `aicx doctor --prune-empty-bodies` emituje reviewable cleanup script (NIE applies sam). — done(2026-05-30 wip/consolidated: H-1 `--apply` modifier @dc74331 invoked live; 4825 chunks quarantined to `~/aicx/quarantine/empty-bodies-20260530_043840/`; doctor po: 0 empty-body candidates / 227111 chunks (0.00%) Green.)
- 2026-05-12 [aicx/extract] CodeScribe extractor source: `[codescribe] 0 entries` w `aicx all` mimo że codescribe runtime istnieje (binarka 0.10.0 zainstalowana). Albo (a) extractor nie wie skąd brać codescribe sessions, (b) codescribe nie zapisuje sessions w trackable formacie, (c) ścieżka jest nieskonfigurowana w aicx config. Sprawdzić: `aicx config list`, `aicx sources audit`. — done(2026-05-30 wip/consolidated rescan: Maciej's monolith-decomposition refactor split codescribe into its own provider `src/sources/providers/codescribe.rs` (+547 LOC); rescan extracted **14 codescribe entries** (claude 4861 + codex 3754 + gemini 74 + junie 0 + codescribe 14 = 8703 total entries). The 0-entries gap was an extractor-routing issue closed by Maciej's split.)
- 2026-05-12 [aicx/branch] `feat/aicx-extract-improvements`: 48 ahead / 65 behind `origin/develop`, 47 ahead / 0 behind `origin/main`. Decision needed: rebase vs merge vs keep diverged. — open
- 2026-05-12 [aicx/wip] 15 unstaged plików w worktree (Cargo.lock/toml v0.7.x→0.7.x, npm distribution sync, doctor.rs/mcp.rs/search_engine.rs/vector_index.rs error message polish — "embedder init failed" → "semantic embedder unavailable (optional)", `enable_tool_list_changed()` w MCP server, tools/release_sync.py +24 lines). 1 stash @ 1e63b01 (npm distribution sync WIP). Decision: które iść do staging dla v0.7.1, które stash, które zostawić. — open
- 2026-05-12 [aicx/test] AICX active intent z 2026-05-08 (z context atlas, label `AicxFailure`): "Gates 1-6 passed (manifest/fmt/check×2/clippy×2). 3 testy z `runtime_cli_store_contract` failed — kanoniczne lowercase assertions. Fix." Verify: czy te 3 testy ciągle failują na current HEAD (`3237157`), czy zostały naprawione i intent jest stale. — investigating
- 2026-05-12 [meta] Brak tracku undone work była głównym source of frustration. Każdy wypływający item ad-hoc trafia tutaj. Nie do `docs/internal/` (gitignored). Ten plik (`docs/BACKLOG.md`) ma być wersjonowany w git. — open

## 2026-05-11 — CodeScribe 0.10.0 segfault + clipboard regression

- 2026-05-11 19:29:49 PDT [codescribe] CodeScribe.app 0.10.0 segfault: `EXC_BAD_ACCESS (SIGSEGV) KERN_INVALID_ADDRESS at 0x0000145a342d9fe8`, faulting thread 0 (main / `com.apple.main-thread`). Top of stack: `objc_release` → `AutoreleasePoolPage::releaseUntil` → `objc_autoreleasePoolPop` → `_CFAutoreleasePoolPop` → `-[NSAutoreleasePool drain]` → `-[NSApplication run]`. Klasyczny use-after-release w obsłudze NSApp event loop autorelease pool — wskazuje na over-release Rust→ObjC bridge object albo dangling reference do view/scrubber (x28 register: `OBJC_IVAR_$_NSScrubberChangeTransition._view`). macOS 26.5 (25F71), Mac15,9, ARM64 native. Codesign ID `com.codescribe.app`, team `MW223P3NPX`. Forensikę zapisano do `docs/incidents/2026-05-11_codescribe-segfault-0.10.0.md`. — open
- 2026-05-11 [codescribe/overlay] CodeScribe overlay przy paste z buffera wkleja header `------------------------------------- / Translated Report (Full Report Below) / -------------------------------------` przed content użytkownika. Garbage prefix w paste flow — zaśmieca każdy paste-through. Fix: clipboard handler nie powinien dorzucać Apple crash report frame'a do user-paste. — open
- 2026-05-11 [codescribe/overlay] CodeScribe overlay autocorrect/transcription zamienia `plik` (Polish: file) na `blik`. Replikowane niezależnie przez user. Fix: dodać Polish dictionary entries albo wyłączyć aggressive autocorrect dla unrecognized stems. — open

## (cross-repo) Loctree-side undone — referencowane z 0.10-prep PR description

> Te wpisy duplikują `feat/lsp/codelens-live-analyzer` PR description w `loctree-suite`,
> ale lądują tutaj żeby cross-repo undone work miał jeden punkt prawdy. Status update
> w obu miejscach.

- 2026-05-11 [loctree/release] `release-bundles.yml` workflow nigdy nie odpalony na realnym tagu — pierwszy run będzie też testem (oczekiwany failure mode: missing GPG key, wrong artifact paths, AICX 0.7.0 niedostępne na release-time). — open
- 2026-05-11 [loctree/release] 0.9.5 publiczny tarball ma regresję LSP — 5/6 binarek (brak `loctree-lsp`). Fix tylko po wystrzeleniu nowego workflow na 0.10.0. Confirmation via `tar -tzf` na wszystkich 3 platformach. — open
- 2026-05-11 [loctree/lsp] Plan 04 client command dla atlas-card opening — server gotowy, klient `editors/vscode/src/commands.ts` nie ma `loctree.openAtlasCard` rejestracji. Plan 15 quickfix dziedziczy ten gap. — open
- 2026-05-11 [loctree/lsp] Plan 08 full symbol scope semantics — staged. — staged
- 2026-05-11 [loctree/lsp] Plan 14 live external AICX runtime end-to-end — mock/integration only. — staged
- 2026-05-11 [loctree/lsp] Plan 16 Stage 2 refactor language-specific edits + benchmarks. — staged
- 2026-05-11 [loctree/lsp] Plan 19 Stage 2 deeper symbol granularity language coverage. — staged
- 2026-05-11 [loctree/npm] npm publish dla wszystkich 15 paczek (3 wrappery + 12 platform) — scaffold gotowy, registry push nie wykonany. — open
- 2026-05-11 [loctree/gates] `make precheck` / `make test` / `cargo clippy --workspace --all-targets -- -D warnings` całościowy gate dla 0.10-prep branch — NIE RUN świeżo (last audit ran tylko `cargo test -p loctree-lsp` i `cargo test -p loctree context_scope --lib`). — open
- 2026-05-11 [loctree/release] Packaging install smoke (curl install na czystym VM, npm install na 3 OSach). — open
- 2026-05-11 [loctree/docs] Plan 23 — wire HTML layer into real analyzer flow (untracked plan w docs/plans/lsp/). — open
- 2026-05-11 [loctree/docs] Plan 24 — polish HTML generated artifacts UI/UX to loctree-com styling (untracked plan w docs/plans/lsp/). — open
- 2026-05-11 [loctree/docs] CHANGELOG.md sync z faktycznym scope 0.10-prep — touched ale nie verified. — open
- 2026-05-11 [loct-io] install bundle URL bump 0.9.5 → 0.10.0 po release (`loct-io/src/sections/install.rs`). — open
- 2026-05-11 [loctree/tracker] TRACKER.md ma `stage_pass` vs `done` distinction dla tasków 08/14/15/16/19. — open
- 2026-05-11 [loctree/lsp] Plan 03 closure-adjusted (CodeLens używa no-op `Command { command: "" }` zamiast literal `command: None` z original task) — udokumentować w task/tracker zamiast zostawiać jako quiet diff. — open
- 2026-05-11 [loctree/audit] Plan 21 source restore (P1 z 22_task_audit_report) — original task file zaginął, jest reconstruction; jeśli oryginał miał inne kryteria, reconstruction może nie matchować. — open
- 2026-05-21 [aicx/tests] K-1 fake `tests/dashboard_security.rs` removed instead of pretending PATH-safe `run_memex_cli` behavior was tested. Recover: add a real integration test around PATH shim resolution if dashboard command execution becomes public/testable. — done(reason: surface removed; 2026-05-29 wip/consolidated investigation, K-1 is now stale by superseding cut `ffe01dd` "fix(dashboard): strict project filter + drop memex CLI (#27, #28, #30)". The entire dashboard command-execution surface was deleted: `run_memex_cli`, `run_memex_cross_search`, `apply_memex_cli_env`, `MEMEX_CLI_ENV_PASSTHROUGH` allowlist, `memex_cli_path` state field, the timeout config+flag in `src/main.rs`, and the `MemexSearchResponse` / `CrossSearchParams` types are all gone. AICX is the canonical corpus surface (operator decision 2026-05-23); `/api/search/cross` survives only as a 410 Gone stub (`cross_search_gone`, `src/dashboard_server.rs:1386-1401`). There is no remaining PATH-resolution path in the dashboard process — the only `std::process::Command` import in `src/dashboard.rs` is `#[cfg(test)]`-gated for the node inline-markdown test (`src/dashboard.rs:18-19`, `src/dashboard/tests.rs:21`), never built into the dashboard server. The regression is guarded structurally by `tests/dashboard_filter.rs:50-75` (`dashboard_server_source_has_no_memex_cli_fork`), which fails the build if `fn run_memex_cli`, `fn run_memex_cross_search`, or `apply_memex_cli_env` ever resurface in `src/dashboard_server.rs`. A PATH-shim integration test against a non-existent dispatch surface would be a fake test of the exact shape K-1 was created to forbid; if a future cut re-introduces dashboard command execution, the right move is a fresh backlog entry plus a real PATH-resolution test, not re-opening K-1.)
- 2026-05-22 [prview] cargo geiger timeout 600s — upstream issue in prview-rs (out of aicx scope). Recover: track/fix in prview-rs, not this repository. — open
- 2026-05-24 [aicx/pr5] PR #5 SC-01 polarize gate: branch remains a consolidated pass-2/3/4 stabilization PR. The older Node v26 inline-markdown blocker is fixed by `2030d3f`, but local full `make test` is still red on `vector_index::iter3_tests::query_index_recovery_hint_uses_full_rescan_not_fresh` (missing `--full-rescan` recovery hint) and intermittently on `dashboard_server::tests::regenerate_logs_detailed_reason_without_leaking_403_body` under parallel capture. Do not add more scope to PR #5; split release/security/follow-up work into separate PRs and fix the remaining test gates before merge. Recover: `make test` plus PR body/doc alignment from `/Users/maciejgad/.vibecrafted/artifacts/Loctree/aicx/2026_0524/polarize/polr-222423-57363/prism.json`. — done(@abeb7ba pass-6 2026-05-28: both SC-01 test gates now GREEN — recovery-hint fully closed in pass-5 merge `a948d7c`; dashboard log-capture greatly stabilized by `623c65a` but NOT fully fixed (residual parallel flake, see 2026-05-28 [aicx/test] entry below); full local `make test` exit 0 on a clean run. The earlier "make test still red" note was a stale prism.json snapshot. Remaining pre-merge work is doc/PR-body alignment only, not code.)
- 2026-05-28 [aicx/pr5] **Pass-6 merge-readiness verification** (6-agent read-only audit, branch @abeb7ba): code is merge-ready, zero OPEN code blockers; every claim VERIFIED-CLOSED or DEFERRED-BY-DESIGN. Deferred operator follow-ups AFTER merge: (1) H-2 Layer-1 reconcile via `aicx store --full-rescan` — additive-only, backfills `missing` index tuples but does NOT prune `orphaned` ones (last counts 188 orphan / 40 missing on operator store); a true orphan-prune is a separate future cut. (2) BLAKE3 migration: first post-upgrade `aicx store` replays the recent `-H` window once (expected, no data loss). (3) M-13 CSP nonce in a separate scoped PR. — deferred
- 2026-05-28 [aicx/diagnostics] `unknown` extractor bucket: routing is correct (`canonical_extractor_key` default arm → literal `"unknown"`, regression test `src/diagnostics.rs:474`), but (a) the unknown arm is currently unreachable from production (all `record` callers pass `&'static str` literals, `src/sources.rs`) and (b) a populated `unknown` bucket is never emitted in the stderr summary — `EXTRACTOR_ORDER` (`src/diagnostics.rs:63`) excludes `"unknown"`, so it is recorded-but-invisible. Low-severity defense-in-depth gap: add `"unknown"` to the emit loop + a `line_for("unknown")` assertion. — done(pass-6 2026-05-28: `summary_lines` now appends the `unknown` catch-all bucket last, cap-preserving; regression test `diagnostics::tests::unknown_bucket_is_emitted_in_summary_lines`. The unreachable-arm note (a) stays as future-proofing — no production caller flows a dynamic name yet.)
- 2026-05-28 [aicx/extract] `default_session_extract_path` filename hardening is correct and traversal-safe, but "focused coverage" is overstated — missing dedicated edge-case tests: whitespace-only input, unicode weirdness (combining mark / RTL override / zero-width), backslash `\` path separator, and oversized-input-with-extension-like-suffix (the current oversized test uses only `'a'`, never exercising the cap when a `.` survives). Add four tests. — done(pass-6 2026-05-28: added 4 edge-case tests in `src/main.rs` tests — `..._whitespace_only_uses_safe_fallback`, `..._unicode_control_chars_are_stripped`, `..._backslash_is_not_a_path_separator`, `..._oversized_with_extension_like_suffix_is_capped`. Assert safety properties: ASCII-only, no path separators, bounded length, deterministic hash suffix.)
- 2026-05-28 [aicx/locks] Dead-vs-alive holder sidecar scenarios are covered in `src/locks.rs` unit tests (`:772` dead, `:796` alive), NOT in `tests/locks_contention.rs` (3 contention/serialization tests only). Coverage is real; any doc/PR text pointing at the contention file as proof of dead/alive coverage is stale. Optional: relocate/duplicate the scenarios into the integration file. — done-by-decision(pass-6 2026-05-28: NOT relocated. The dead-PID recovery path only fires inside the private `handle_lock_timeout` after a forced flock WouldBlock — a state that cannot arise naturally with a dead holder, since the OS releases the flock when the process dies. The unit tests inject it via the private `ForcedWouldBlockGuard`; an integration test would need either that test-only forcing guard exposed on the public surface (anti-pattern: test-only methods on production) or a flaky multi-process race. Unit-level coverage in `src/locks.rs` is the correct seam.)
- 2026-05-28 [aicx/test] `dashboard_server::tests::regenerate_logs_detailed_reason_without_leaking_403_body` residual flake under full parallel `make test` (observed ~1/3 runs in pass-6; passes in isolation and on retry). `623c65a`'s `CAPTURE_LOGS_LOCK` mutex serializes `capture_logs` callers among themselves but cannot isolate tracing's process-global level/interest cache (`dashboard_server.rs:1773` `with_max_level(WARN)` + thread-local `with_default`) from sibling test threads that emit/install tracing state. Proper fix: assert the 403 reason via the handler response/return value instead of captured tracing logs, OR gate every tracing-capture test behind one shared serial guard. NOT a hard merge blocker (remote CI green, retry-green) — but it must not be claimed as fully fixed. — done(@675dc68 pass-6 2026-05-28: root-caused and fixed differently than the two ideas above. Replaced both thread-local `with_default` capture helpers (dashboard_server + locks) with one shared `src/test_support.rs::capture_logs` over a single process-global subscriber installed once at max level TRACE — so no callsite is ever cached as `never` — routing each event to a thread-local buffer per capture scope. Correct-by-construction + immune to the interest-cache race. Note: an early "regression test" that called the *global* `tracing::callsite::rebuild_interest_cache()` was itself a poison source under parallel runs and was removed. Validation: 0 flakes in 15 full `make test` runs.)
- 2026-06-01 [aicx/search] Hybrid retrieval search-side bugs (B+/A1/B) FIXED. (B+) `aicx search` hard-failed (`RetrievalManifestMissing`/`Stale`) whenever the hybrid manifest was missing or mid-rebuild — including the never-committed case, so a present dense build (operator's ~11.9 GB) was unqueryable / "never worked". (A1) `materialize_hybrid_index` ran unconditionally after each dense commit, full-rebuilding tantivy even on no-op incrementals (98% CPU, 12+ min; forced `aicx-index.plist` UNLOADED). (B) `TantivyAdapter::build` did `remove_dir_all` in place, leaving search an empty dir for the whole rebuild. — done(2026-06-01 wip/consolidated: @10aa791 dense-only degradation reading the PRIMARY committed index directly (label `semantic_dense_only`, typed Missing/Stale match — not a brittle substring) + @052bdfa non-silent `[degraded]` status line + `level=degraded` log; @46d35b9 skip materialize on no-op incremental, guarded by `indexed==0 && failed==0 && manifest dim/model match` (migration F2LLM 2048→qwen3 4096 forces rebuild); @e72270e atomic staging+swap tantivy build (`atomic_swap_dir`, last-good live until rename); @06b4823 `aicx repair` rebuilds hybrid lexical+manifest from committed embeddings WITHOUT re-embed. 14 new tests, `cargo test --workspace` 0 failed x3 runs, clippy/fmt clean. NOT done — follow-up, separate PR: Bug A2 incremental hybrid materialize (`LexicalIndex::insert` per chunk instead of full build), phase separation embed/materialize/validate. FINAL DESIGN + re-enable steps: `~/AI_notes/projects/aicx/specs/2026-06-01_search-bug-patch3-blueprint.md`. Operator-side to re-enable: push + rebuild both hosts (sztudio via `github` remote) + `launchctl load aicx-index.plist`.)
- 2026-06-01 [aicx/test] `diagnostics::tests::summary_skipped_when_no_records` parallel flake: asserted the process-global `Mutex<DiagnosticsState>` extractor map empty, raced by a sibling test recording into the shared global between init and assert. — done(@b2ca802 2026-06-01: holds the lock across reset+assert like `summary_aggregates_per_extractor`; `emit_summary` (read-only) called outside the lock. 0 flakes in 3 full workspace runs.)
- 2026-06-01 [aicx/test] `aicx-embeddings hf_cache::tests::detect_cached_profiles_in_returns_empty_for_empty_base` parallel flake: test-helper `tempdir()` keyed only on pid+nanos collided within a clock tick, so a sibling test's `hydrate_profile_snapshot` polluted the "empty base". — done(@b2ca802 2026-06-01: added a process-wide `AtomicU64` counter to the temp path for guaranteed per-process uniqueness. 0 flakes in 3 full workspace runs.)
- 2026-06-01 [aicx/index] **Bug A2 — incremental hybrid materialize.** `materialize_hybrid_index` (`src/vector_index.rs:1021`) full-rebuilds the entire lexical (tantivy) + dense layer on EVERY index run that adds ≥1 chunk — ~17 min / 97% CPU per increment on the 227k store (proven live: `indexed: 57 → elapsed 1024s`). Krok 2 (skip) only covers no-op runs; real increments still pay a full rebuild. Both adapters already expose per-chunk `insert` (`adapter_tantivy.rs:252`, `adapter_brute_force.rs:287`, `DenseIndex`/`LexicalIndex` traits) — A2 = add `HybridIndex::insert_delta` orchestration + a delta-path in materialize (insert new chunks instead of full build), with fallback to full on inconsistency. Key risk: cross-process tantivy reader reload + manifest `source_hash`/`commit_id` consistency. Paste-ready spec: `~/AI_notes/projects/aicx/specs/2026-06-01_bug-a2-incremental-materialize-blueprint.md`. — open
- 2026-06-01 [aicx/index] **P1 — no-op skip leaves manifest source-hash stale (PR #12 @chatgpt-codex-connector).** `write_index` rewrites + renames `embeddings.ndjson` with a fresh `generated_at` header on EVERY run (`src/vector_index.rs:883,897`), and `observed_source_hash_for_index_path` (`:407`) hashes the whole file — so even a no-op incremental changes the source hash. The Krok 2 skip (`should_skip_hybrid_rebuild`) then leaves the hybrid manifest bound to the OLD hash → next search hits SourceHashDrift in `load_from_manifest` → degrades to dense-only despite zero corpus change. Effect is softened by the dense-only fallback (search still works, just degraded, not broken). Fix options: (a) preserve `generated_at` on no-op AND verify the rewritten file is byte-identical → stable hash → skip safe, or (b) lightly update `manifest.source_hash` to the new primary hash when skipping (no full rebuild). Deferred from PR #12 — needs careful write_index hash-stability verification, not a rushed change to load-bearing indexing. — open
- 2026-06-01 [aicx/cli] **P2 — missing-arg / config-hint pre-parse scans all of argv (PR #12 @chatgpt-codex-connector).** The pre-clap intercepts (`src/main.rs:1517` missing-`--source` for ingest/conversations/sources; `:1600` `aicx config --show` hint) match the target word ANYWHERE in argv, so `aicx search ingest` or `aicx search config --show` are hijacked into the structured error instead of searching for those terms. Restrict each hint to fire only when the matched word is the FIRST non-flag top-level subcommand. Pre-existing (aicx-uniformity Wave D), surfaced on PR #12. — open

---

*𝚅𝚒𝚋𝚎𝚌𝚛𝚊𝚏𝚝𝚎𝚍. with AI Agents by VetCoders (c)2024-2026 The LibraxisAI Team*