mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
agentics-teams-session
311 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3eb9ccc461 |
fix(qe-browser): Phase 4 — all 9 medium devil's-advocate findings
M1 visual-diff threshold: documented "max difference fraction" convention matching Playwright maxDiffPixelRatio (was inconsistent in docs/code). M2 fixture server bind: default to 127.0.0.1 instead of 0.0.0.0; QE_BROWSER_FIXTURE_HOST=0.0.0.0 opt-in for explicit external access. Codespaces auto-forwards 0.0.0.0 ports — this was an unintentional open server every time the eval ran. M3 path-traversal guard: replaced startsWith() with path.relative() + '..'/absolute check. The old guard false-passed sibling-prefix dirs (/foo vs /foo2) and was fragile on Windows mixed separators. M4 ANSI escape injection: added sanitizeSnippet() that strips C0 controls (0x00-0x1F except \t\n) and DEL (0x7F) from every check-injection finding snippet. Prevents `cat findings.json` from triggering terminal control sequences embedded in malicious page content. M5 parseArgs --key=value: split on first '=' so --threshold=0.05 works alongside --threshold 0.05. Only the first '=' is split so URL/base64 values survive intact. M6 batch.js pre-validation: added validateAllSteps() that walks every step's required fields BEFORE the first vibium call. Step 17 typo now aborts before steps 1-16 execute their side effects. M7 intent-score bare-x regex: anchored \bx\b in close_dialog scorer so "fix", "exit", "extra", "sixteen" no longer match. Unicode × and ✕ unchanged. M8 check-injection --exclude-selector: new flag drops subtrees from the scan. Page text is read from a CLONE of <body> with matching elements removed — live page unchanged. Lets docs sites scan their own pages without self-flagging documentation about prompt injection. M9 09-assets vibium catch: wrapped raw error with actionable recovery guidance (`npm install -g vibium`, then re-run `aqe init`). Hidden bug found and fixed during M2/M3 testing: fixtures/serve-skills.js existed but had never been run because the repo root is ESM and the file uses CommonJS require(). Added scoped fixtures/package.json with "type": "commonjs" matching the existing scripts/package.json pattern. Tests: 86 unit tests across 7 files (was 50). All pass. Smoke test: 9/9 still passing against real Vibium v26.3.18. Mirrored .claude/skills/qe-browser → assets/skills/qe-browser. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
2988cbcc7c |
fix(qe-browser): Phase 2 high-severity fixes from devil's-advocate review
H1: detectVibium reads stderr too, extracts semver
- Many Go CLIs (including some Vibium versions) write --version to stderr.
detectVibium used to read only stdout and silently report 'unknown',
polluting the init log with "vibium unknown (already installed)".
- Fix: read both streams, prefer stdout, extract bare semver via regex
so output is consistent regardless of where the binary printed it.
- Tests: 5 new regression tests covering stderr fallback, stdout
preference, verbose-format extraction, prerelease tags, fallback to
first whitespace token.
- Note: result.version is now bare semver (26.3.18) not v-prefixed.
Two pre-existing tests updated to match the new contract.
H2: instructions_in_html_comment dead-code regex
- TreeWalker(SHOW_COMMENT).textContent yields the inner text without
the <!-- --> delimiters, so the pattern that requires the literal
`<!--` prefix could never fire. Eval tc009 was passing only by
accident (ignore_previous_instructions fired on the same fixture).
- Fix: re-wrap each comment node in `<!-- ... -->` before adding to
the hidden bucket. Pattern can now actually match.
- Tests: 2 new regression tests asserting wrapped form fires AND
unwrapped form does NOT fire (the bug condition).
H4: e2e-flow-verifier frontmatter regression — INVALID FINDING
- Verified against `git show main:` — the skill always had minimal
frontmatter on main (just name + description + user-invocable: true)
and has no evals/, schemas/, or scripts/ directories. It is a
user-invocable runbook-style skill, not trust-tier-3 validated.
No metadata to restore. Marked closed-as-invalid.
H6: log-before-spawn for the 3-minute Vibium install
- spawnSync(npm install -g vibium) blocks the event loop for up to
3 minutes on a cold cache while Chrome for Testing downloads. The
user saw zero output and would Ctrl-C thinking init hung.
- Fix: pre-flight detect call (5s timeout) short-circuits when vibium
is already installed (the common case, no banner). When the install
is actually about to run, log a clear "this can take 1-3 minutes,
downloads Chrome for Testing lazily" message BEFORE the spawn.
H7: scoped scripts/package.json survives npm pack — VERIFIED
- `npm pack --dry-run` confirms both
.claude/skills/qe-browser/scripts/package.json (225B) AND
assets/skills/qe-browser/scripts/package.json (225B)
are included in the published tarball. The CommonJS override that
keeps the helper scripts loadable from an ESM project root will
survive `npm install` after publication. No fix needed.
H8: eval yaml uses unsupported runner fields
- The structured assertion fields I invented (exit_code, json_fields,
severity_at_least, candidate_count_at_least) are NOT understood by
src/validation/parallel-eval-runner.ts which expects must_contain
keyword matching. The yaml as written is unrunnable.
- Honest fix: relabel evals/qe-browser.yaml as `status: design-spec`
with a HONESTY NOTE explaining it's a specification, not a runnable
eval. Two paths to make it runnable documented (extend runner OR
rewrite as must_contain).
- Parallel artifact: scripts/smoke-test.sh — a runnable bash smoke
test against the same pinned httpbin.org fixtures. THIS is the
script that gates PR-reopen per ADR-091 Phase 3.
Bonus from B2/H5 already in Phase 1:
- assert.js now uses ?? instead of || for the `expected` field
Verification:
- 50/50 qe-browser tests pass (was 36 in initial PR; +14 regressions)
- 392/392 init tests pass (was 387; +5 from H1)
- npm run build: clean
- npm pack --dry-run: scoped package.json confirmed in tarball
- eslint on all touched source files: clean
- bash -n smoke-test.sh: syntax OK
Phase 3 (real Vibium smoke test) still gating PR reopen per ADR-091.
Branch intentionally not pushed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
cd4ea7e451 |
feat(skills): add qe-browser fleet skill with Vibium engine
Introduces a new AQE-owned browser automation skill layered over Vibium (WebDriver BiDi, single 10MB Go binary) and migrates 11 browser-using QE skills to use it instead of raw Playwright/Puppeteer. qe-browser ships five helper scripts that add QE primitives Vibium doesn't cover on its own: typed assertions (16 check kinds), batch execution, pixel-diff against stored baselines, prompt-injection scanning, and semantic intent scoring ported from gsd-browser (MIT/Apache). Each script emits a structured JSON envelope matching schemas/output.json so hooks and CI gates can parse results without stdout grep. Vibium installs automatically during `aqe init` via a new graceful browser-engine installer that shells out to `npm install -g vibium` and reports `already-installed`, `installed`, `install-failed`, or `npm-unavailable` without ever failing init. Skills migrated to reference qe-browser: a11y-ally, e2e-flow-verifier, qe-visual-accessibility, security-visual-testing, visual-testing-advanced, testability-scoring, compatibility-testing, accessibility-testing, localization-testing, observability-testing-patterns, enterprise-integration-testing. Ships 36 new unit tests (browser-engine-installer, assert, intent-score, check-injection) with dependency-injected spawners to avoid touching real processes. All 387 existing init tests still pass. Eval harness uses pinned public fixtures (httpbin.org, Vibium docs at a pinned tag) plus a local static server that wraps this repo's own skill docs, per the "no synthetic fixtures" rule. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
05dcfe92dd |
fix(init): release-gate corpus + --json contract (#401)
Addresses the v3.9.1–v3.9.4 init regression series by building the verification layer that #401's post-mortem identified as structurally missing. The load-bearing changes are the real-public-repo corpus, the --json contract, and the restructured error handling in phase 06 that stops lying about success when a non-critical phase fails. What landed ----------- * `aqe init --json` — structured InitResult output with schema version 1, stricter exit code semantics (exit 1 on any step.status='error', not just on critical failures). Stable contract for the gate and other CI consumers. See InitJsonOutput in src/cli/handlers/init-handler.ts. * Phase 06 no longer swallows errors as `{status:'skipped',entries:0}`. Exceptions now propagate to BasePhase.execute() and surface as real step errors in result.steps[]. Fixed a resource leak where kgService and memory handles were leaked on the old throw path — now always released via try/finally. * `tests/fixtures/init-corpus/` — 4 pinned real public repo fixtures: - tiny-ts (developit/mitt@b240473) - mid-ts (sindresorhus/p-queue@55d306b) - multi-lang-real (ruvnet/RuView@2a05378 — contains the exact 28,745 byte / 776 line ruview_live.py that triggered the v3.9.4 hang, sha256-pinned to detect content drift) - self-dogfood (agentic-qe HEAD) * 22 gate assertions per fixture (A1–A22) including per-step JSON error inspection (A10), snapshot-based KG threshold with tolerance (A12), skills/agents/MCP/CLAUDE.md/workers/config.yaml presence (A13–A20), subthreshold stall detection (A21), and a second init pass that exercises the delta-scan path of phase 06 — the actual surface that hung in v3.9.1 ruview, never reached on a first init (A22). * `.github/workflows/npm-publish.yml` — new pre-publish-gate job that runs the corpus against the freshly-built tarball before publish; new tests-on-tag-sha job that re-runs fast unit tests on release events (replaces a buggy gh-api conditional caught by devils-advocate review). * `.github/workflows/post-publish-canary.yml` — fires on real publishes only (not workflow_dispatch dry runs), polls npm CDN via `npm install --dry-run` (actual CDN edge, not just registry metadata), runs the corpus against the published package, opens P0 issue on failure via heredoc-based body. * Watchdog effectiveness unit test (tests/unit/init/phases/code-intelligence-watchdog.test.ts) — 4 cases proving the async-stall branches of runBoundedScan work and documenting the sync-block limitation that requires AQE_SKIP_CODE_INDEX or (future) worker isolation. * `.github/PULL_REQUEST_TEMPLATE.md` — single load-bearing checkbox: every PR failure mode must have a test or tracking issue. Honor-system today; CI enforcement tracked in #408. * AQE_SKIP_CODE_INDEX promoted from "temporary escape hatch" to permanent supported flag in docs, CLI help, and source comments. Verification ------------ * `npm run typecheck` — clean * `npx eslint` on all touched files — clean (plus fixed two pre-existing unused-var warnings in init-handler.ts) * `aqe security --sast` on all touched source + workflows — 0 findings * `tests/unit/init/` — 377/377 pass * `tests/unit/init/phases/code-intelligence-watchdog.test.ts` — 4/4 pass * Local gate against `npm pack`'d tarball — 4/4 fixtures pass all 22 assertions including double-init delta path and sha256 regression marker Failure paths independently verified (F1–F5 injection tests): * F1 wrong sha256 → A3 fires, exit 2, actionable diagnostic * F2 absurd expectedKgEntries → A12 fires, exit 2, shows actual vs expected * F3 expectedElapsedSec=0 → A21 fires on slow fixture, A22 fires on double-init — same `(( elapsed > soft_cap ))` math proven in both paths * F4 injected throw in runCodeIntelligenceScan → reproduces the exact v3.9.3 failure shape (`success:true` at orchestrator level, phase 06 step.status='error'). A7 catches via strict exit code, A10 catches as defense-in-depth via jq inspection. Both layers verified. * F5 expectedSkillsInstalled=999 → A13 fires with OR-logic showing json=84, disk=84 vs expected 999 Deferred with tracking issues ----------------------------- * Phase 06 worker_threads isolation — #407 * PR template CI enforcement — #408 * VERIFICATION.md + release-notes matrix — #409 * Chaos workflow for pathological inputs — #410 * Mirror init-corpus tarballs to GitHub Releases — #411 What is NOT verified -------------------- * The CI workflows have never actually executed in a real Actions run. YAML syntactically validated via js-yaml, job dependency graph traced, but the first real execution is the first push of this branch. * The canary on a real publish is unexecuted. First execution is the first real release after merge. Refs: #401, #407, #408, #409, #410, #411 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
db99c17c7d |
feat(init): warn on stale ./vectors.db post hnswlib-node migration (#399)
Prior to ADR-090, NativeHnswBackend wrapped @ruvector/router's
VectorDb, whose constructor unconditionally wrote a `vectors.db`
redb file to the current working directory — outside .agentic-qe/,
in a non-SQLite format, never read by anything in production
(its HNSW search returned wrong answers anyway). Users who upgrade
from a pre-#399 version will have an orphaned multi-MB file in
their project root.
`aqe init` now detects `./vectors.db` in the project root and logs
a one-time warning identifying it as stale from the @ruvector/router
era and suggesting `rm vectors.db` for cleanup.
The phase does NOT auto-delete the file. Per CLAUDE.md data
protection rules, AQE never overwrites, replaces, recreates, or
removes any .db file without explicit user confirmation. Users who
want to clean up run `rm vectors.db` themselves.
Three new unit tests in `tests/unit/init/phases/database-phase.test.ts`:
- asserts the warning fires when `./vectors.db` is present
- asserts the warning does not fire when it is absent
- asserts the phase never calls fs.unlinkSync or fs.rmSync,
regardless of whether vectors.db exists (data protection guard)
Refs #399, ADR-090.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
da638f9079 |
feat(kernel): migrate NativeHnswBackend from @ruvector/router to hnswlib-node (#399)
@ruvector/router 0.1.28 was found to have four serious bugs that
together broke production code-intelligence semantic search and
forced the v3.9.5 hotfix to disable native HNSW entirely:
1. HNSW search returned essentially random results — recall@10 was
0% on the project's FNV fixture and 10% on textbook unit-Gaussian
random vectors. The graph walk could not even find self-vectors
when querying with a stored vector. Reproduced deterministically
on linux-arm64; matches the linux-x64 GitHub Actions failures
reported in #399.
2. The VectorDb constructor unconditionally wrote a `vectors.db`
redb file to the current working directory, polluting users'
project roots with multi-MB files outside .agentic-qe/, in a
non-SQLite format that no AQE migration or backup tooling knew
about. Direct violation of the unified memory architecture.
3. The redb file held a process-wide exclusive lock — only ONE
VectorDb instance could exist per process. Subsequent constructors
threw "Database error: Database already open. Cannot acquire lock."
4. NAPI dispose did not synchronously release the redb lock (NAPI GC
is not synchronous). The lock outlived dispose() and caused the
v3.9.5 futex deadlock when the indexer tried to recreate after
reset.
NativeHnswBackend is rewritten to wrap hnswlib-node@^3.0.0 — the
canonical Node.js binding for Yury Malkov's reference C++ Hnswlib
implementation, used by Pinecone, Weaviate, Qdrant, LangChain, and
ChromaDB. Empirical verification on the same fixture
(`scripts/diagnose-issue-399*.mjs`):
- hnswlib-node: recall@10 = 100%, top-1 = id 42 ✓
- @ruvector/router: recall@10 = 10%, top-1 = id 999 (random)
Insert is also faster (~324ms vs ~430ms for 1k vectors) and search
is comparable (0.35ms vs 0.21ms with correct vs wrong results).
No new dependency was added — `hnswlib-node` was already a direct
dependency in `package.json` from the legacy code path in
`src/integrations/embeddings/index/HNSWIndex.ts`.
Implementation notes:
- Drops the local `vectorStore` mirror that the previous backend
needed to re-score wrong native results — hnswlib-node returns
correct distances directly.
- Drops the `bruteForceSearch` private fallback — there is no
fallback path because hnswlib-node always returns correct results.
- `clear()` now recreates the underlying HierarchicalNSW from
scratch instead of just markDelete-ing every label. The
tombstone-only approach leaks state across long test runs that
share the singleton HnswAdapter registry, producing duplicate
labels from `searchKnn` after many cycles.
- `search()` overshoots k by 2x and dedups by id as a defensive
measure against any future hnswlib-node duplicate-label edge
case, then truncates back to k.
- `add()` doubles maxElements via `resizeIndex()` when the live id
count fills the current capacity, so callers don't need to know
the final index size at construction time.
- `useNativeHNSW` default flipped back to `true`. Users with large
codebases get sublinear HNSW search by default again.
- All four `@ruvector/router` failure modes have explicit regression
guards in the unit and integration test suites.
The two #399-skipped tests in `phase1-integration.test.ts`
(line 222 and 1185) are un-skipped and now pass green against the
new backend. The three flag-default tests that asserted
`useNativeHNSW: false` (broken by v3.9.5's hotfix) are updated to
assert `true` again.
Stale comments referencing `@ruvector/router`'s lock behavior are
updated in `src/kernel/unified-memory.ts`, `src/init/phases/06-code-intelligence.ts`,
`src/init/phases/10-workers.ts`, and `src/cli/index.ts`. The CLI
status output (`aqe ruvector status`) and the `useNativeHNSW` flag
description are updated to mention `hnswlib-node` instead of
`@ruvector/router`.
Refs #399, ADR-090.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
3a1d9636b3 |
fix(kernel): disable native HNSW by default — deadlocks on certain inputs (v3.9.5)
ROOT CAUSE FOUND for the ruview / ruview_live.py hang.
Investigation
-------------
v3.9.4's per-file log gave the user the exact stalling file:
examples/ruview_live.py from the public RuView project. I downloaded
the file (28 KB, 776 lines, 95 entities — normal-shaped Python),
reproduced the hang locally against v3.9.4, then dumped kernel
state of the hung process via /proc/<pid>/wchan and strace.
Findings:
Main thread: futex(0x3c6ded50, FUTEX_WAIT_PRIVATE, 1, NULL)
(NULL timeout = wait forever)
17 total threads:
- MainThread (blocked in futex)
- V8Worker × 4 (blocked in futex)
- DelayedTaskScheduler (epoll_wait — normal libuv)
- SignalInspector (blocked in futex)
- tokio-runtime-w × 6 (blocked in futex)
- libuv-worker × 4 (blocked in futex)
Native modules loaded:
- ruvector-router.linux-arm64-gnu.node
- ruvector-gnn.linux-arm64-gnu.node
- better_sqlite3.node
The deadlock is reproducible: every run against this file produces
the same futex_wait_queue state. After 7 successful VectorDb.insert()
calls (7 rows visible in the vectors table), the 8th never returns.
This is a futex deadlock inside the @ruvector/router native NAPI
module, triggered by VectorDb.insert() against certain vector content
shapes. The Rust tokio runtime threads inside the module hold a lock
the main thread is waiting for, and never release it. The setTimeout-
based watchdog v3.9.3 added cannot interrupt this — setTimeout
callbacks queue between event loop iterations and the event loop is
frozen inside a kernel futex syscall. That's a Node.js architectural
limitation, not a bug in our watchdog code.
The fix
-------
One-line change: useNativeHNSW feature flag default flipped from
true to false in src/integrations/ruvector/feature-flags.ts. All
HNSW operations now route through ProgressiveHnswBackend instead of
NativeHnswBackend. The native module is still loaded and still
available to anyone who explicitly opts in via
setRuVectorFeatureFlags({ useNativeHNSW: true }) — the default path
just no longer touches the deadlock-prone code.
Why this isn't a regression
---------------------------
ProgressiveHnswBackend was already updated in v3.9.3 commit
|
||
|
|
8dd4040b60 |
feat(init): AQE_SKIP_CODE_INDEX escape hatch + per-file logging (v3.9.4 Fix A+B)
v3.9.3's phase 06 watchdog (Promise.race with setTimeout) cannot
interrupt synchronous native code that blocks the Node event loop.
The ruview codespace hit this: a single kgService.index() call
entered a native call inside @ruvector that never returned, and the
setTimeout timer callback couldn't fire because timers are queued
between event loop iterations. I explicitly flagged this as the
"worst case" in the v3.9.3 PR description — it was unlikely but not
impossible, and it proved real.
The proper fix is to run the indexer in a killable worker_thread
or child_process.fork so the parent can terminate it on timeout
regardless of whether the child is blocked in native code. That
refactor is larger scope and needs thorough review. Tracked as
v3.9.5 scope in a separate issue.
v3.9.4 ships two same-day mitigations:
Fix A: Escape hatch
-------------------
- AQE_SKIP_CODE_INDEX=1 env var: CodeIntelligencePhase.shouldRun()
returns false when set, phase 06 is skipped entirely. Users in
codespaces whose init stalls can run
`AQE_SKIP_CODE_INDEX=1 aqe init --auto` to unblock immediately.
- --skip-code-index CLI flag on `aqe init`: equivalent of the env
var for interactive users. Wired through init-handler.ts (the
actual lazy-loaded handler, not the static createInitCommand in
src/cli/commands/init.ts — both files updated for consistency),
orchestrator.ts, and phase-interface.ts InitOptions type.
- Both paths log an explanatory message: "Code intelligence
skipped (AQE_SKIP_CODE_INDEX=1)" or "(--skip-code-index)" plus
"Run `aqe code index` later to build the KG on demand."
- Lazy on-demand KG indexing via `aqe code index` and
`aqe memory search` still works — the skip only affects the
init-time pre-scan.
Fix B: Per-file progress logging
---------------------------------
runBoundedScan() now logs every file BEFORE it starts processing
it, not every 100 files. Format:
[123/349] src/path/to/file.ts
The log appears immediately before the kgService.index() call for
that file. If a stall happens, the LAST log line names the exact
file the indexer was working on when it froze — which is the
single most important diagnostic for fixing the underlying native
cause in a targeted follow-up.
Paths are made project-relative for readability. For ruview-sized
projects (~349 files) this adds ~349 log lines, which is trivial
for a one-time init command and a large observability win. The
"Indexed N entries" summary at phase end is unchanged.
The removed PROGRESS_LOG_INTERVAL constant is now dead code.
Verification:
- Fresh 2-file fixture: shows `[1/2] src/a.ts` and `[2/2] src/b.ts`
lines before each file, then `* Install governance configuration
(3ms)` on phase 13.
- `AQE_SKIP_CODE_INDEX=1 aqe init --auto`: skips phase 06 with
explanatory log, total time 209 ms.
- `aqe init --auto --skip-code-index`: same behavior as env var.
- All 440 init + kernel + optimizer unit tests pass.
Tracking issue for the killable-worker proper fix: TODO (opened
after this commit lands).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
fed202cc71 |
fix(init): walk up to package root for governance/kiro/sync assets (v3.9.4 Fix C)
Repairs the same chunk-split bundle regression that v3.9.3 Fix 4 fixed for findMcpEntry() — I missed three other installers with the same pattern. Observed in cf-devpod: `x Install governance configuration (1ms)` during aqe init. Bug pattern: governance-installer.ts, kiro-installer.ts, and sync.ts resolved bundled assets via fixed-depth __dirname + '../..' traversals. When esbuild code-splitting (enabled in v3.9.0) bundles these modules into a chunk under dist/cli/chunks/chunk-XXX.js, __dirname points to the chunks directory and both candidate paths land outside the package. The governance-installer constructor throws "Governance assets not found" and phase 13 fails in 1 ms. The same code path had been fixed for skills/agents/opencode/n8n installers in v3.9.1 using findPackageRoot(), but these three sibling installers were missed. Fix: each function now builds a candidate list that includes: 1. Dev tree fixed paths (src/init/, standalone dist/init/) 2. findPackageRoot() walk-up — finds the nearest package.json with name=agentic-qe regardless of bundle depth (correct for all production installs including chunk-split) 3. Consumer node_modules/agentic-qe/assets/... for transitive dep 4. process.cwd() fallback for dev-from-project-root kiro-installer is on the --with-kiro opt-in code path and was not observed failing in the wild but shares the same bug structurally. sync.ts is on the `aqe sync init` manual command path, same situation. Fixed all three to close the class of bug. Verification: - Fresh fixture `aqe init --auto` on v3.9.4 now shows `* Install governance configuration (3ms)` (success asterisk) instead of `x Install governance configuration (1ms)`. - All 440 init unit tests pass locally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
2bd601b071 |
fix(kernel): ProgressiveHnswBackend uses brute-force for cosine search
Production correctness fix for ADR-071's ProgressiveHnswBackend. @ruvector/gnn's differentiableSearch is a softmax-weighted soft-argmax designed for GRADIENT FLOW during neural-network training — it is NOT a correct nearest-neighbour ranking primitive. Its returned candidate set is: 1. Platform-sensitive (native binary version, CPU float rounding). On Codespace devcontainer and my local branch: returns id=42 at top-1 correctly for a query equal to id=42. On GitHub Actions CI Linux runner: returns id=812 (true rank 13, cosine 0.846) at top-1 for the same query. Observed twice on PR #398 CI. 2. Not guaranteed to contain the true nearest neighbour at all. Re-sorting the returned candidates by recomputed exact cosine scores (my first-attempt fix) is insufficient because the true best match may be absent from the candidate set. 3. Designed for softmax ranking: weights in tested range were 2.21e-3 to 2.50e-3 — differences of order 1e-5 relative to mean, meaning the "top-1" picked by softmax depends on bit-exact numerical agreement across platforms. CI and local disagree. The fix: for cosine metric we always use brute-force exact search. For AQE's production KG indexes (typically <10k patterns at 384 dims) brute-force cosine is O(n·d) ≈ a few milliseconds, which is negligible compared to the correctness guarantee. Every real user of KG semantic search now gets platform-independent, provably correct top-k ranking. The differentiableSearch path is retained for euclidean metric and future non-cosine use cases, with the recomputed-score re-sort as an additional correctness safety net in that code path. This also turns out to be the reason the phase1-integration test was flaky across platforms even on v3.9.2 — it was exposing a real production bug that had been masked by the old sine-aliased test generator happening to produce such tightly clustered vectors that all 10 candidates were effectively equivalent. My FNV-1a-seeded generator (previous commit) properly separates vectors and exposed the latent incorrectness. Verification: - tests/integration/ruvector/: 257/257 pass - tests/unit/kernel/native-hnsw-backend.test.ts + hnsw-legacy-bridge + hnsw-unification + hnsw-index + hnsw-index-adapter-migration: combined 144/144 pass - tests/unit/learning/pattern-store.test.ts + rvf-pattern-store + optimization/token-optimizer-service.test.ts + unified-memory: 135/135 pass - Empty-project fixture init: exit 0, 346 ms, no errors. - Build: CLI + MCP bundles both at v3.9.3 clean. Total: 536 targeted tests pass after the fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
8ea578b209 |
fix(init): phase 06 per-file + phase watchdog with progress (v3.9.3 Fix 5)
Primary reliability fix for the ruview hang. v3.9.2 only closed the
specific createPatternStore -> getSharedRvfDualWriter deadlock but did
not cover the case where a single pathological source file — or a
native-layer stall in @ruvector/rvf-node on a Codespace overlay
filesystem — could block the indexer indefinitely with no diagnostic.
Phase 06 now drives indexing file-by-file via a new runBoundedScan()
helper with two hard timeouts:
PER_FILE_TIMEOUT_MS = 30_000 // 30 s per file
PHASE_TIMEOUT_MS = 180_000 // 180 s whole phase
A single pathological file exceeding its 30 s cap is skipped with a
warning ("Skipped <file> — indexing exceeded 30 s") and the rest of
the codebase continues to index. If the whole phase cap fires, the
phase returns status='timeout' with a new `timeoutFile` diagnostic
field naming the file that was being processed; init still exits 0
and every subsequent phase runs.
Progress is logged every PROGRESS_LOG_INTERVAL (100) files:
Scanning 367 source files...
Indexed 100/367 files
Indexed 200/367 files
...
All KG semantic-search features (vector embeddings, hypergraph,
knowledge graph) remain fully enabled. The watchdog is a reliability
guarantee, not a feature reduction. Vector embeddings per entity are
still written to .agentic-qe/memory.db.
Implementation notes:
- The scan calls kgService.clear() once up-front when !incremental,
then drives each file via kgService.index({paths:[file],
incremental:true}). This preserves per-file error isolation and
lets us attach a per-file timeout via Promise.race.
- withTimeout() uses a tagged error prefix (AQE_PER_FILE_TIMEOUT) so
the caller can distinguish timeouts from real failures.
- Timer handles are .unref()'d so they do not keep the event loop
alive when the promise resolves via the fast path.
Verification:
Empty fresh project: 427 ms
200-file fixture: 672 ms with progress at 100/200 and 200/200
15k-entity heavy fixture: 3120 ms, 28050 entries indexed
All exit 0, no errors.
When the watchdog fires on a real project the user will see the exact
file that hung, which is the data we need to fix the underlying native
layer cause in a targeted follow-up.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
e2f9e188cb |
fix(cli): restore findMcpEntry() for chunk-split bundles (v3.9.3 Fix 4)
v3.9.0's esbuild code-splitting (`lazy-load CLI handlers and enable esbuild code splitting`) placed CLI chunks under dist/cli/chunks/ (3+ levels deep), breaking the fixed `__dirname + '..'` paths the MCP command used to locate dist/mcp/bundle.js. Global installs of 3.9.0+ printed "Could not find MCP server entry point" when calling `aqe mcp` or `aqe mcp --help`. This is a regression of the v3.7.10 fix. findMcpEntry() now uses the same walk-up strategy as the skills and agents installers: find the nearest package.json with name="agentic-qe" via findPackageRoot(), then resolve dist/mcp/bundle.js from there. This works regardless of how deep esbuild places the calling chunk. Resolution order: 1. Package root via findPackageRoot(import.meta.url) 2. Legacy sibling paths (__dirname + '..') for dev mode and tsx 3. Extra chunk-split candidate (__dirname + '../..' for chunks dir) 4. Consumer's node_modules/agentic-qe/dist/mcp/bundle.js Verification: `aqe mcp --help` exits 0 with the usage text. Previously: exit 1 with "Could not find MCP server entry point". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
5fce095ea0 |
fix(init): remove phase 10 MCP daemon spawn (v3.9.3 Fix 3)
The workers phase used to spawn `aqe mcp` as a detached child to
"pre-warm" the MCP daemon. This spawn raced the parent init process
for the same RVF / native HNSW file locks, producing the cascade of
errors seen in v3.9.1 and v3.9.2:
[RVF] Shared adapter init failed: RVF error 0x0303: FsyncFailed
VectorDb creation failed: Database error: Database already open
Error: Could not find MCP server entry point
None of these were real failures — the daemon was never needed. The
MCP server is started on demand by Claude Code via .mcp.json (written
by phase 08), which is the canonical production path. Users who want
to run the daemon manually can use the generated
.agentic-qe/workers/start-daemon.cjs helper script or the
`aqe daemon` subcommand.
Changes:
- Remove startDaemon() / findMcpCommand() private methods.
- Remove child_process and readFileSync imports.
- Phase 10 now writes the worker registry and helper scripts and
returns {daemonStarted: false, daemonPid: null}.
Verification: Phase 10 drops from ~1500 ms (waiting on spawn setTimeout)
to ~1 ms (pure config writes). No more spurious error spam on any
fixture. aqe-repro4 (pre-existing .agentic-qe) no longer shows the
"Note: Error: ..." line.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
4ac1919840 |
fix(cli): lazy TokenOptimizerService lifecycle (v3.9.3 Fix 2)
Stops every CLI command from opening patterns.rvf and memory.db at startup. `bootstrapTokenTracking()` used to create an RvfPatternStore (which auto-attached a SQLitePatternStore, which initialized UnifiedMemory) before commander had even parsed argv, so `aqe --version`, `aqe --help`, and `aqe init` all grabbed exclusive file locks they never used. This is what was holding the locks that the spawned workers daemon then fought with in cf-devpod. TokenOptimizerServiceImpl now supports a lazy lifecycle: - initialize() stores memoryBackend reference + config but does NOT create the pattern store. Marks the service as initialized=true. - ensurePatternStoreReady() is a private, idempotent, race-safe method invoked on first use by checkEarlyExit() and storePattern(). Concurrent callers share one readyPromise. Failure leaves the service in a "registered but unready" state that degrades to session-cache-only mode. - Calling initialize() again clears stale readyPromise / patternStore / optimizer state before re-initializing, so tests that poke (service as any).initialized = false work correctly. Consequences for users: - `aqe --version` on a project with an existing .agentic-qe/ directory now prints a single line instead of 6+ lines of bootstrap noise. - Commands that never hit the early-exit path (init, status, health, hooks, daemon) no longer open any files and run faster. - The first command that actually uses patterns (e.g. aqe test generate) is ~100 ms slower on first call due to lazy init. Verification: 17/17 token-optimizer-service tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
394a1e63dc |
fix(kernel): add dispose() contract to HNSW backends (v3.9.3 Fix 1)
Adds proper resource-release plumbing to the unified HNSW stack so tests and explicit shutdown paths can release native resources cleanly. - IHnswIndexProvider: new optional `dispose()` method. - NativeHnswBackend.dispose(): nulls the native VectorDb reference so NAPI garbage collection can reclaim the Rust-side index. Also clears local mirrors so a subsequent clear() on a dead nativeDb is a no-op. - ProgressiveHnswBackend.dispose(): no-op (no native handles held). - HnswAdapter.close(name): now invokes backend.dispose() before removing the registry entry. - UnifiedMemoryManager.close(): documented why it deliberately does NOT cascade dispose into HnswAdapter — the 'qe-memory' adapter is intentionally process-global because @ruvector/router does not allow a second native VectorDb to be created in the same process while the first is still alive. Previous attempt to cascade reintroduced the exact "Database already open. Cannot acquire lock" fallback that cf-devpod was seeing in v3.9.2. Infrastructure for test and explicit shutdown use cases. No behavior change in the normal CLI lifecycle. Verification: 99/99 HNSW tests pass, 53/53 unified-memory tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
76383372da |
fix(init): resolve patterns.rvf deadlock + CLI exit hang (v3.9.2)
Two related fixes for the init flow broken in v3.9.1:
1. aqe init --auto hangs at "Code intelligence pre-scan"
After v3.9.1 flipped useRVFPatternStore to true by default,
AQELearningEngine.initialize() would open patterns.rvf twice in
the same process:
a) createPatternStore() -> _createRvfStore('.agentic-qe/patterns.rvf')
acquires an exclusive native file lock via @ruvector/rvf-node
b) getSharedRvfDualWriter() -> getSharedRvfAdapter() ->
createRvfStore('.agentic-qe/patterns.rvf') tries to acquire the
same exclusive lock -> deadlocks forever
Fix: createPatternStore() now routes through the getSharedRvfAdapter()
singleton. Only one file handle exists per process; subsequent callers
receive the cached instance. RvfPatternStore.dispose() gains a
skipCloseOnDispose option so it won't close a shared adapter.
2. CLI doesn't exit after init completes
Native NAPI handles from @ruvector/rvf-node and @ruvector/router
kept the event loop alive indefinitely. cleanupAndExit() previously
used async dynamic imports for cleanup modules, which loaded more
native bindings before the unref'd 3s force-exit timer could fire.
Fix: cleanupAndExit() is now synchronous — fire-and-forget disposes
followed by immediate process.exit(). Init completes and exits
cleanly in ~7s.
Verification:
- aqe init --auto on fresh project: EXIT=0, ~7s, all 12 phases pass
- Isolated npm pack+install: aqe --version returns 3.9.2
- 65 pattern-store + rvf-pattern-store tests pass
- 15/15 performance gates pass
- Build + typecheck: zero errors
Note: Full unit suite runtime regression (>22min, unrelated to this
fix) tracked separately in #396.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
a6202c39a3 |
chore(release): v3.9.1 (#395)
* feat: implement ADR-062 (StrongDM all 3 tiers) and ADR-087 (RuVector 14/14 capabilities)
ADR-062 StrongDM Software Factory — all 6 actions across 3 tiers:
- Tier 1: Loop detection wired to MCP protocol-server (blocks on strike 3+),
token dashboard (pre-existing)
- Tier 2: Holdout testing (10% FNV-1a selection, filtered in test-execution),
gate ratcheting (monotonic 5-pass/2%/95% cap, persisted to MemoryBackend)
- Tier 3: Progressive context (TF-IDF prediction, reduces availableFiles on spawn),
meta-learning cycle (4 insight types, stored + published as domain events)
ADR-087 RuVector Advanced Capabilities — milestones 1-5:
- EWC++ recordOutcome + backgroundConsolidate wired to 3 domain coordinators
- R1: HDC fingerprinting (10K-bit hypervectors, wired to PatternStore.store())
- R3: Delta event sourcing (sparse encoding, wired to PatternStore.store())
- R13: Cognitive routing (predictive compression, wired to mailbox.send/receive)
- R14: Hyperbolic HNSW (Poincare ball, auto-indexed in PatternStore.store())
Also updates ADR statuses: 059, 060, 061 → Implemented (were already done),
062 → Implemented, 086 → In Progress, 087 → Implemented.
223 new tests across 11 test files, all passing. Zero regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: implement RVF cluster (ADR-065/066/067/071) with native benchmarks
Implements the RVF persistence cluster for persistent HNSW vector storage,
agent memory branching, and HNSW unification foundation.
Key changes:
- RvfPatternStore: IPatternStore backed by @ruvector/rvf-node native HNSW
(1.2ms cold-start, 0.19ms search p50, verified with real native binary)
- AgentMemoryBranch: per-agent COW isolation via derive(), ingest-log merge,
wired into Kernel.initialize() + DefaultAgentCoordinator
- HnswLegacyBridge: adapts old IHNSWIndex to unified IHnswIndexProvider,
wired into PatternStore when useUnifiedHnsw flag enabled
- Factory routing: createPatternStore() returns RvfPatternStore when flag
enabled + native available + data directory exists
- Dream engine: accepts external RVF adapter (no duplicate file handles),
RVCOWBranchManager enhanced with recall validation check
- @ruvector/gnn bumped 0.1.19→0.1.25, 3 new feature flags added
- IPatternStore interface extracted for polymorphic pattern store usage
- 50 new tests (16 RvfPatternStore + 17 AgentMemoryBranch + 12 bridge + 5 benchmarks)
- 1188 tests pass, 0 regressions
ADR status: 066 Implemented, 067 Implemented, 065 Implemented,
069/071 In Progress (honest assessment after brutal-honesty review)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(init): resolve skills/agents paths from package root, not relative to bundle depth
esbuild code-splitting puts installer code into dist/cli/chunks/ (3 levels
deep) instead of dist/init/ (2 levels deep), so the old ../../ traversals
landed at dist/ instead of the package root — causing "Source directory not
found" errors for all global installs.
Replace brittle relative-path resolution in all 4 installers with a shared
findPackageRoot() that walks up to the nearest package.json with
name=agentic-qe. Prioritise assets/ paths (canonical npm source) over
.claude/ paths.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: complete RVF cluster Phases 2-3 (ADR-067/069/071/072) with devil's advocate fixes
Phase 2A (ADR-067): Agent memory branching enabled — useAgentMemoryBranching=true,
BRANCH_DISCARD witness action, recordIngest callback exposed to agents via config.
Phase 2B (ADR-069): Dream RVF COW — useRvfFork driven by isRVFPatternStoreEnabled(),
child adapter stored + temp files cleaned up on merge/discard, 13 tests.
Phase 2C (ADR-071): HNSW unification — useUnifiedHnsw=true, HNSWEmbeddingIndex routes
through HnswAdapter, UnifiedMemory vectorIndex uses UnifiedHnswIndex, HnswLegacyBridge
delegates to adapter string-ID APIs (no duplicate ID maps), addEmbeddingsBatch routed
correctly, saveIndex/loadIndex safe under unified mode.
Phase 3 (ADR-072): RVF primary migration scaffolding — RvfMigrationAdapter (5-stage
routing with write latency tracking), RvfConsistencyValidator (rolling divergence +
compaction), RvfStageGate (go/no-go with witness chain), rvfMigrationStage=1 default,
wired into shared-rvf-dual-writer at stage >= 2, 32 tests.
Cross-cutting fixes from devil's advocate review:
- Shared RVF adapter singleton eliminates dual file handles (kernel + dream engine)
- RvfPatternStore reports honest nativeAvailable=false + rvfInitError on failure
- ESM-safe dynamic import() replaces require() in dream-engine and branch-manager
- quality_assess defaults to src/ instead of cwd to prevent full-project scan hang
- discoverSourceFiles skips .agentic-qe/.claude/.cache dirs, adds maxFiles=5000 cap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: complete RVF cluster plan — Phase 2C decommission, Phase 3 integration, fix 7 pre-existing test failures
Phase 2C (ADR-071) — HNSW decommission:
- Remove RuvectorFlatIndex fallback from unified-memory.ts; always use UnifiedHnswIndex
- Hardcode isUnifiedHnswActive()=true in HNSWEmbeddingIndex (hnswlib-node legacy path is dead code)
- Create HnswShadowValidator for brute-force vs HnswAdapter divergence validation
- Benchmark alias (rvf-pattern-store.bench.ts) for plan compliance
Phase 3 (ADR-072) — RVF Primary Migration integration:
- RvfMigrationCoordinator: wires adapter + validator + gate with real SQLite/RVF handles
- MCP tools: migration_status, migration_check, migration_promote (persistence category)
- Kernel boot wiring: coordinator initializes when rvfMigrationStage >= 2
- RvfMigrationAdapter.setStage(): propagate promotions to routing logic
- Promote default rvfMigrationStage from 1 (hybrid) to 2 (dual-write-sqlite-primary)
- Integration test: 13 tests covering full lifecycle (stage 1→2→3→4), write/read routing,
consistency checks, gate enforcement, fallback, metrics
Test fixes (7 pre-existing failures → 1 remaining):
- code-intelligence-metrics-wiring: spy console.info not console.log (logger routes to console.info)
- mcp-integration: disable ADR-062 loop detection (repeated identical calls are by design)
- dream-cycle-tool (2 tests): RvfPatternStore empty-query branch returns all patterns from SQLite
- coherence-integration (4 tests): RvfPatternStore vector search fallback computes brute-force
cosine over SQLite embeddings when RVF adapter unavailable; getStats() falls back to SQLite count;
auto-attach SQLitePatternStore in initialize() when not explicitly wired
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(release): bump version to v3.9.1
- Version bump in package.json and skills-manifest.json
- Fix "Dynamic require of X is not supported" in ESM bundles by adding
createRequire banner to both CLI and MCP build scripts — every chunk
now has a working require() for Node.js builtins
- Add CHANGELOG.md entry and release notes for v3.9.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(ci): regenerate package-lock.json for npm ci compatibility
The lock file was out of sync with package.json — new transitive
dependencies added on main were missing. All 15 CI checks failed
at `npm ci` with "Missing from lock file" errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(ci): pin Node to 24.13.0 and restore working lock file
Node 24.14.1 ships npm 11.11.0 which enforces stricter lock file
validation than 11.6.x (what 24.13.0 ships). The existing lock file
passes under 11.6.x but fails under 11.11.0 with "Missing from lock
file" for transitive dependencies of private-registry packages.
Pin all 5 workflow files to node-version: '24.13.0' and restore the
lock file from commit
|
||
|
|
c0fd0d845f |
fix(security): escape regex-special chars in glob-to-regex conversions (CWE-1333)
CodeQL flagged regex injection in memory-backend.ts where user-supplied patterns were passed to `new RegExp()` with only `*` → `.*` conversion, leaving other regex metacharacters unescaped. Fixed in all 5 production source files: memory-backend, worker-manager, agui-sync, hooks-shared, and daemon. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
1dcbfa5fb6 |
perf: lazy-load CLI handlers and enable esbuild code splitting
Convert heavy top-level imports (kernel, coordination, workers, unified-memory) to dynamic imports deferred until command execution. Extract workflow command into src/cli/commands/workflow.ts, add lazy-registry for on-demand handler loading, and enable esbuild splitting with chunk output. Reduces CLI startup cost by avoiding eager module resolution for unused commands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
65457ccc84 |
fix: add kill switches, missing tests, and log redirect for CC-internals (IMP-00–10)
Address verification findings from user-perspective review of IMP-00 through IMP-10: - Implement 8 missing env var kill switches (AQE_MICROCOMPACT, AQE_RETRY_DISABLED, AQE_SESSION_DURABILITY, AQE_PROMPT_CACHE_LATCH, AQE_FAST_PATHS, AQE_HOOKS_SSRF_DISABLED, AQE_COMPACTION_DISABLED, AQE_PLUGINS_DISABLED) - Add 5 missing test files: parallel-prefetch, session-durability-middleware, and plugin sources (local, github, npm) — 40 new tests - Add kill switch test coverage for all 8 env vars — 10 new tests - Fix stdout log leak: redirect [ParserRegistry], [ContinueGateIntegration], timestamped logs, and other internal prefixes to stderr - Update plan doc verification matrix with correct test file names (37 files) - Add user-perspective verification report 466 tests pass across 37 IMP test files. Build clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
e82a7240ec |
feat: implement CC-internals improvements IMP-00 through IMP-10 (Waves 0-4)
11 improvements across 4 priority tiers, all integrated into production code paths with 416 new tests across 33 test files. Each wave passed a brutal honesty audit with all findings resolved. Wave 0-2 (P0/P1): Middleware chain, microcompact, tool concurrency, retry engine, session durability, prompt cache latch, startup fast paths, hook security hardening. Wave 3 (P2): 4-tier context compaction pipeline, plugin architecture with local/GitHub/npm sources. Wave 4 (P3): QE Quality Daemon — priority queue, git watcher (with Linux polling fallback), coverage delta analyzer, CI monitor, test suggester, nightly consolidation, notification service with SSRF guard, persistent SQLite-backed memory, CLI commands, MCP startup integration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
f9d7fcba46 |
fix: parameterize LIMIT/OFFSET SQL and replace @faker-js/faker in generators
- witness-chain.ts: LIMIT/OFFSET now use parameterized ? bindings instead of string interpolation (SQL injection fix). Handle offset-without-limit via LIMIT -1, and limit=0 correctly returns zero rows. - Replace @faker-js/faker imports in 7 generator files with lightweight test-value-helpers.ts using only node:crypto — eliminates ~6MB runtime dependency for npm consumers. - Add range guards in test-value-helpers (int/float swap on inverted range). - Add 17 unit tests for test-value-helpers and 3 pagination edge case tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
ca0c6e7c5e |
fix: use CLAUDE_PROJECT_DIR for hook paths and remove ruflo permissions from aqe init
Hook commands using relative paths (node ./dist/...) or git rev-parse
broke when invoked from subfolders. Adopted the CLAUDE_PROJECT_DIR
pattern (sh -c 'exec node "${CLAUDE_PROJECT_DIR:-.}/..."') which
Claude Code sets to the project root.
Also: removed ruflo/claude-flow permissions from _aqePermissions
injected by aqe init — only AQE-specific entries belong in user
settings. Fixed init-wizard-hooks.ts missing union-merge for
permissions (#362 parity).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
4e513b431d |
fix: resolve 3 P0 blockers and CI failures from QE v3.8.13 audit
- Delete dead MCP server.ts (911 lines, never used in production — entry.ts imports MCPProtocolServer). Add legacy aliases in index.ts for backwards compat. - Fix ESLint: rename .eslintrc.js to .eslintrc.cjs (CommonJS in ESM project) - Fix hardcoded version '3.0.0' in protocol-server.ts and http-server.ts — now reads dynamically from package.json - Fix vitest process hang: add worker-level afterAll force-exit (setup-worker.ts) and global teardown safety net. Native modules (better-sqlite3, hnswlib-node) held open handles preventing fork worker exit. - Add test gate to npm-publish.yml — 194 unit test files must pass before publish - Disable benchmark.yml release trigger (benchmarks/suite.ts doesn't exist) - Remove continue-on-error from test steps in optimized-ci.yml (was masking failures) - Add getToolDefinitions() to MCPProtocolServer for test introspection - Update e2e and integration tests to use production server API Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c2f973e792 |
feat: add CLI code intelligence commands (complexity, --incremental, --git-since) and fix stale references
- Add `aqe code complexity` action with cyclomatic/cognitive/Halstead metrics, hotspot detection, batched concurrency - Add `--incremental` and `--git-since <ref>` flags for `aqe code index` - Fix command injection vulnerability: replace execSync with execFileSync (CWE-78) - Fix missing return after cleanupAndExit in complexity action - Add --depth NaN validation - Import shared SOURCE_EXTENSIONS instead of duplicating inline - Fix stale `aqe kg` commands in SKILL.md Quick Start/CLI Examples across .claude/, assets/, .kiro/ - Fix phantom agent names (qe-knowledge-graph, qe-semantic-searcher) in skills, evals, and catalog - Fix `ruflo doctor --fix` references in CLAUDE.md, skill gotchas, and docs → `aqe health`/`aqe init` - Fix `aqe code-intelligence index` → `aqe code index .` in fleet integration guide - Add code intelligence CLI section to README.md - Fix tool-scoping test: add hypergraph_query to all 5 scoped roles - Fix queen-dependency test: correct expectation for agents without inline mcp__ refs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3707d7029b |
feat: restore MCP server initialization as default in aqe init
Most users still rely on MCP and not all tools have CLI parity yet. MCP was made opt-in (--with-mcp) in v3.8.8 but should be default. Now aqe init configures .mcp.json by default; use --no-mcp to skip. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
eeddf4edf6 |
chore(release): bump version to v3.8.12
- Version bump: 3.8.11 → 3.8.12 (package.json, skills-manifest) - Fix HDC pre-filter regression: reorder-only instead of eliminating candidates - CHANGELOG, release notes, and docs/releases index updated Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
eebb76731e |
feat: implement RuVector Phase 5 Milestones 3-4 — Scale, Optimization & Advanced Learning (ADR-087)
Milestone 3 — Scale & Optimization (R7-R10): - R7: Meta-learning enhancements (DecayingBeta, PlateauDetector with CUSUM, ParetoFront, CuriosityBonus) wired into DomainTransferEngine - R8: PageRank pattern importance solver with citation graph pipeline (PatternCitationGraph bootstraps from 129 existing patterns, blended scoring in pattern-promotion.ts) - R9: Spectral graph sparsifier (degree-based leverage heuristic) wired into mincut-wrapper.ts as optional preprocessing - R10: Reservoir replay buffer with coherence-gated admission and CUSUM drift detection, wired into ExperienceReplay (write + read paths) Milestone 4 — Advanced Learning (R11-R12): - R11: E-prop online learning (12 bytes/synapse, eligibility traces, feedback alignment) — RL algorithm #10, extends BaseRLAlgorithm - R12: Granger causality for test failure prediction (VAR + F-test with full statistical math) wired into defect-intelligence coordinator with persistent history accumulation Infrastructure: - 8 feature flags (all default true per opt-out policy), convenience functions, env var support, CLI descriptions - RLAlgorithmType union: 9 → 10 members (added 'eprop') - ADR-087 status: Proposed → Active (M1-4 complete) - 234 new tests across 8 test files, all passing - Performance benchmarks for PageRank, sparsification, reservoir admission - 0 regressions in existing test suite Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
19ba1a8fb7 |
feat: implement RuVector Phase 5 Milestone 2 — Graph Learning (ADR-087)
Implements R4 (GraphMAE), R5 (Modern Hopfield), R6 (Cold-Tier GNN) with full integration wiring into pattern-store and code-intelligence domains. R4 GraphMAE Self-Supervised Learning: - SPSA optimizer for gradient-free training of masked graph autoencoders - Decoder head reconstructs features from embeddings (SCE loss, γ=2) - Per-epoch lossHistory for convergence analysis - Wired into coordinator-gnn.ts:generateGraphMAEEmbeddings() - 21 tests including 1K-node scale test R5 Modern Hopfield Networks: - Exponential-capacity exact pattern recall (Ramsauer 2020) - L2-normalized patterns for consistent softmax attention - Dimension-aware singleton, zero-vector rejection - Wired into pattern-store.ts store()/search() as exact-recall tier - 28 tests including 10K capacity and <2ms benchmark R6 Cold-Tier GNN Training: - LRU-cached mini-batch trainer with memory cap enforcement - FileBackedGraph for real disk-backed larger-than-RAM graphs - Unbiased Fisher-Yates shuffle (rejection sampling) - Wired into coordinator-gnn.ts:trainWithColdTier() - 25 tests including FileBackedGraph round-trip and mode equivalence Shared: - Extracted Xorshift128 PRNG to src/shared/utils/xorshift128.ts - 3 feature flags (default false) with documented activation criteria - Barrel exports for all types, classes, and factories 74 new tests, 0 type errors, 0 regressions across 1030 existing tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
fa28ce6bfa |
feat: implement RuVector Phase 5 Milestone 1 — Pattern Intelligence (ADR-087)
Adds 4 new capabilities with production wiring, 148 tests, and performance baselines: - R1: HDC Pattern Fingerprinting — 10K-bit binary hypervectors with O(1) XOR binding, wired into PatternStore search as Hamming-distance pre-filter - R2: CUSUM Drift Detection — two-sided statistical change-point detection across all 4 coherence gate types (retrieve/write/learn/act), auto-enabled via feature flag - R3: Delta Event Sourcing — pattern version history with rollback via SQLite pattern_deltas table, wired into PatternStore store/recordUsage paths - EWC++ Activation — three-loop protocol (instantAdapt→recordOutcome→backgroundConsolidate) wired in quality-assessment, test-generation, and contract-testing coordinators with double-flag guard (useSONAThreeLoop && useEwcPlusPlusRegularization) Extracts coherence-gate.ts (930 lines) into 4 modules under 500-line limit. All feature flags default true (opt-out) per amended ADR-087 policy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
a2f9365ddc |
feat: implement session reuse with O(1) fingerprint cache for 40-60% token savings (#334)
Imp-15: Session Reuse for Repeated Operations Adds a SHA-256 fingerprint-based operation cache as layer 0 before HNSW early exit. Exact-match lookups run in O(1) before O(log n) similarity search, catching repeated operations instantly. - SessionOperationCache with TTL, capacity eviction, and kv_store persistence - Wired into TokenOptimizerService.checkEarlyExit() as first check - cacheOperationResult() stores results after successful LLM execution - session_cache_stats MCP tool for monitoring hit rates - CLI: aqe token-usage --cache-stats for cache performance - Cross-session persistence via existing kv_store table - 26 new tests covering fingerprinting, TTL, eviction, stats, degradation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
73eab06585 |
feat: implement Six Hats Tier 3 Phase 1 — YAML pipelines, heartbeat CLI, economic routing (#334)
Three strategic features from Issue #334 with full CLI-MCP parity: Imp-9: YAML Deterministic QE Pipelines - Approval gate step type with auto-approve timeout and cancel cleanup - 4 deterministic actions (quality-gate, coverage, pattern-health, routing) with real SQL queries and graceful DB degradation - 7 CLI commands (aqe pipeline load/validate/run/list/status/approve/reject) - YAML loader validation for approval fields Imp-10: Token-Free Heartbeat CLI & MCP - 6 CLI commands (aqe heartbeat status/run-now/history/log/pause/resume) - 3 MCP tools (heartbeat_status/trigger/log) - History persistence, date validation, timeout support Imp-18: Economic Routing Model - EconomicRoutingModel with quality-per-dollar scoring and EMA estimates - Budget-aware tier selection with fallback strategies - Cost-adjusted rewards for neural router (opt-in) - CLI commands (aqe routing economics/accuracy/metrics) - routing_economics MCP tool with kv_store persistence Security: path traversal fix on CLI log reader, config weight validation 71 new tests across 6 test files, all passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
4bd61c27b8 |
fix(coverage): unify coverage data flow from test execution to quality score (#385)
Coverage data never reached quality assessment because of fragmented key
conventions, fabricated fallback values, and missing --coverage flags in
test commands. This commit fixes the entire coverage data pipeline:
- Remove fabricated coverage (up to 95%) when no real data exists
- Unify 5 orphaned key conventions into consistent coverage:latest,
coverage:previous, and coverage:file:{path} keys
- Add --coverage flags to vitest/jest test commands
- Read coverage from disk (coverage-summary.json) when not in stdout
- Store per-file coverage via memory.set() (not storeVector) so
quality-analyzer can read it
- Rotate coverage:previous only in coverage-analyzer (canonical writer)
to prevent double-rotation race conditions
- Fix defect-predictor and defect-investigation orphaned key reads
- Replace hardcoded fake data in coverage-tracker worker with real reads
- Use safeJsonParse and path sanitization in disk coverage reader
- Report coverage: -1 (not 0) when no data available to avoid
false 25-point quality score penalty
Closes #385
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
||
|
|
d43bdfd915 |
fix(security): persist coherence gate witnesses, remove hardcoded signing key (#383)
W-2: Replace hardcoded 'agentic-qe-default-key' in proof-envelope with crypto.randomBytes(32) when no explicit key is provided. The previous default provided no meaningful signing security. W-3: Add governance chain bridge to CoherenceGate. The coherence gate now accepts an optional GovernanceWitnessChain (or PersistentWitnessChain) via setGovernanceChain(). When attached, every validation decision is persisted to the existing witness_chain_receipts SQLite table in addition to the in-memory witness array. No new tables needed — uses existing witness_chain_receipts from governance/witness-chain.ts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c725043631 |
fix(security): replace djb2 hash with SHA-256 in witness adapter, fix Blake3 docs (#383)
Security audit findings: F-1 (CRITICAL): witness-adapter.ts used a 32-bit djb2 non-cryptographic hash for witness records. Replaced with SHA-256 via Node.js crypto. The previous implementation provided no tamper-evidence. W-1 (WARN): Blake3 was referenced in 15+ code comments but never implemented — SHA-256 is the actual algorithm used everywhere. Updated all misleading references to accurately state SHA-256: - coherence-gate.ts module JSDoc and method comments - witness-adapter.ts module JSDoc - ruvector-commands.ts flag description Audit verdict: SHA-256 is sufficient for current use. Ed25519 is already fully implemented in witness-key-manager.ts. Blake3 would be a performance optimization, not a security requirement. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
12216ec1a6 |
fix: address devil's advocate findings — wire language param, fix benchmark output, extend KG (#383)
Fixes from devil's advocate review: - Wire `language` param through MCP coverage tools to parseCoverage() and include detected language/format in CoverageAnalyzeResult - Add language-to-format inference map (LANGUAGE_FORMAT_HINTS) for format detection when only language is specified - Use language hint to distinguish JaCoCo vs Kover XML - Replace void template literals with console.log in benchmarks so data is actually recorded for cross-release comparison - Add Swift and C# to KG matchesLanguage(), Swift to getFileType() - Create #383 tracking remaining dropped items transparently Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
126667257a |
feat: multi-language Phase 5 — coverage parsers, language routing, MCP schemas (#324)
Add 6 multi-language coverage format parsers: - JaCoCo XML (Java/Kotlin) with line/branch/method/instruction counters - dotcover XML (C#/.NET) with statement-level coverage - Tarpaulin JSON (Rust) with trace-based line coverage - Go cover text format with block-level statement tracking - Kover XML (Kotlin/JVM) via JaCoCo-compatible parsing - xcresult JSON (Swift/iOS) with function-level detail Add language-aware agent routing: - New `languages` field on AgentCapabilityProfile - 0.15 score boost for agents matching request language - Configurable language weight in RoutingWeights - Case-insensitive, backward-compatible Update MCP tool schemas: - Add `language` and `coverageFormat` params to coverage analyze/gaps tools - Auto-detect format from filename and content signatures - Extended findAndParseCoverage with multi-language file paths 24 new tests, all passing. 30 existing routing tests unaffected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
233eba3aa0 |
feat(ruvector): add P1 scale benchmarks, concurrency tests, CLI memory display (#355)
Phase A of RuVector P1 items: - Tiered HNSW benchmarks (1K→10K, 100K→500K with RUN_SCALE_BENCH=1) - Migration performance benchmark with compression and rollback - 8-agent coherence gate concurrency test (8 tests, 50-agent stress) - HNSW memory usage display in `aqe ruvector status` - v3.8.8 benchmark baseline for cross-release comparison Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
0f44d7231a |
feat: migrate agents/skills from MCP to CLI, improve skill descriptions, make MCP opt-in
- Standardize 15 QE skill names to kebab-case (matching directory names) - Enrich 18 skill descriptions with third-person voice and trigger terms - Add `aqe memory` CLI command (store/get/search/list/delete/share/usage) with full MCP parity, reusing existing MCP handlers - Migrate all 431 mcp__agentic-qe__* references across 230 agent/skill files (.claude/, assets/, .kiro/) to CLI equivalents (aqe task, aqe agent, aqe fleet, aqe memory, aqe coverage, aqe quality, aqe security, etc.) - Make MCP server opt-in during `aqe init` (--with-mcp flag); CLI commands work without MCP server running - Zero mcp__agentic-qe__* references remain in agent/skill definitions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
2086bafa6b |
feat(parsers): add web-tree-sitter WASM for Python, Java, C#, Rust, Swift (#323)
Integrate tree-sitter WASM as the default parser for 5 languages, replacing regex-only parsing (~97-98%) with AST-based parsing (~100% accuracy). - Add TreeSitterWASMParser implementing ILanguageParser for 5 languages - Bundle only needed WASM grammars in assets/grammars/ (8.5MB vs 50MB) - Add FallbackParser with 3-retry logic before permanent regex degradation - Add per-call parser instances to prevent concurrency races across await - Add cyclomatic complexity computation from AST branching nodes - Add property extraction from class/struct AST nodes - Add AQE_PARSER_REGEX_ONLY=1 env var for opt-out to regex - Replace require() with ESM-compatible dynamic import() in registry - Mark web-tree-sitter as external in CLI/MCP esbuild configs - Amend ADR-076 with decision rationale and alternatives evaluated Alternatives evaluated and rejected: - @ast-grep/napi: npm package only ships JS/TS/CSS/HTML, others need native .so - node-tree-sitter: requires native C compilation via node-gyp Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
0cc11ea05b |
fix: unify hypergraph persistence to memory.db, add CLI/MCP query tools
Eliminates the separate hypergraph.db file — all hypergraph data now lives in the unified .agentic-qe/memory.db alongside other QE tables. Fixes stale v3/ path references in governance shards. Adds user-facing hypergraph query surface via CLI (`aqe hypergraph stats/untested/impacted/gaps`) and MCP (`hypergraph_query` tool). Key changes: - coordinator + coordinator-hypergraph default path: hypergraph.db → memory.db - governance shards: v3/src/domains/ → src/domains/ (12 files + constitution) - init phase 06: now builds hypergraph tables during `aqe init --auto` - coordinator.index(): rebuilds hypergraph on every code_index MCP call - protocol: removed redundant buildHypergraphFromIndex (coordinator handles it) - shared code-index-extractor: async batched I/O, arrow/method/interface patterns - CLI handler: ensureInitialized guard, connection leak fix, path resolution - MCP handler: hypergraph_query tool with stats/untested/impacted/gaps queries - tool-scoping: hypergraph_query added to 5 agent roles - completions: bash/zsh/fish/powershell support for hypergraph subcommands - coordinator: publishes HypergraphDegraded event on init failure - 12 new tests for code-index-extractor Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
004141cc8e |
fix(security): eliminate remaining CodeQL ReDoS vectors
- command-validator: backtick regex `.*` → `[^`]*` (negated class eliminates backtracking between delimiters) - input-sanitizer: UPDATE regex `\S+(?:\.\S+)*` → `[^\s.!]+(?:\.[^\s.!]+)*` (narrowed character class removes ambiguous overlap that caused exponential backtracking on repeated `!.` sequences) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
3d7a2f91dd |
fix(security): resolve 4 CodeQL ReDoS alerts + decompose oversized modules
Security (CodeQL #193-196): - command-validator: replace greedy .* with [^)]* in $() pattern - input-sanitizer: replace .* with \S+(?:\.\S+)* in UPDATE SET pattern - path-traversal-validator: split alternation into two .replace() calls - regex-safety-validator: use [^\]]* and non-greedy variants in detection patterns Flaky test indicators (5 files, 58 real setTimeout calls eliminated): - file-watcher.test.ts: vi.useFakeTimers + advanceTimersByTimeAsync - qcsd-refinement.test.ts: vi.useFakeTimers + advanceTimersByTimeAsync - qcsd-ideation-url.test.ts: vi.useFakeTimers + advanceTimersByTimeAsync - server-client.test.ts: process.nextTick for data callbacks - stream-controller.test.ts: vi.useFakeTimers + advanceTimersByTimeAsync File size discipline (issue #374 P2): - time-crystal.ts (1,714 → 6 files, max 447 lines): time-crystal-types, phase-executor, time-crystal-persistence, time-crystal-analysis, time-crystal-scheduling, time-crystal (controller) - qe-reasoning-bank.ts (1,941 → 7 files, max 738 lines): qe-reasoning-bank-types, pretrained-patterns, agent-routing, embedding-utils, pattern-promotion, qe-reasoning-bank (class) All re-exports preserved for backward compatibility. 536 directly affected tests pass. Build clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
2826dba538 |
refactor(security): move validators to shared/security/ fixing 3 DDD violations (#374 P2)
Domain-agnostic security validators (path traversal, regex safety, command validation, input sanitization, crypto) were in src/mcp/security/ but imported by shared/, domains/, and governance/ — crossing bounded context boundaries. Moved 7 validator files to src/shared/security/: - path-traversal-validator, regex-safety-validator, command-validator - input-sanitizer, crypto-validator, validators-interfaces - validation-orchestrator Updated 5 cross-boundary importers to use shared/security/ directly. Re-export stubs left in src/mcp/security/validators/ for backward compatibility with MCP-internal code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
afccca9f9d |
refactor(domains): replace 401 console.* calls with structured logger (#374 P1 #8)
Migrate all 13 domain directories from raw console.* to LoggerFactory: - 401 console.log/warn/error/debug calls replaced across 64 files - 0 real console.* calls remaining in src/domains/ - Per-file logger instances with domain/service naming convention - Matches format already used by kernel/learning/governance modules Also adds timeout 480 to 4 remaining CI npm-run scripts (contract, code-intelligence, postgres, coverage) that were missed in the initial CI fix — identified by devil's advocate review. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
ffed015086 |
refactor(cli): decompose hooks.ts into 9 per-handler modules (#374 P1 #10)
Split the 1,745-line monolith (CC=100) into focused handler files: - hooks.ts (81 lines) — slim entry point composing all handlers - hooks-shared.ts (296) — state, init, backend creation, output helpers - hooks-dream-learning.ts (341) — dream scheduler, experience persistence - editing-hooks.ts (180), routing-hooks.ts (137), stats-hooks.ts (280) - session-hooks.ts (193), task-hooks.ts (168), command-hooks.ts (273) All 15 subcommands preserved. All files under 500-line project limit. Import flow enforced one-way: handler → hooks-shared → external APIs. Re-exports in hooks.ts preserve the existing public API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
ee723fec0c |
fix(security): add 8 missing tables to SQL allowlist
The P0 SQL safety fix in
|
||
|
|
fc1e86ad2d |
fix(security): resolve P0/P1 issues from v3.8.3 QE swarm analysis
P0 fixes: - Fix command injection (CWE-78) in test-verifier.ts: replace exec() with execFile() + ALLOWED_TEST_COMMANDS allowlist - Unify SQL allowlists: add 5 missing tables to sql-safety.ts, replace local duplicate in unified-memory.ts with canonical validateTableName() - Add validateTableName() to all 7 SQL interpolation sites in ruvector/brain-shared.ts P1 fixes: - Remove 70 process.exit() calls from learning.ts (45) and hooks.ts (25), replacing with return/throw for proper cleanup handler execution - Move @faker-js/faker from dependencies to devDependencies (~8MB savings) - Enable bundle minification: CLI 9.8→6.9MB (-30%), MCP 12→7.2MB (-40%) - Fix no-op verification scripts to perform real checks with non-zero exit codes on failure QE reports: - Add 12 comprehensive QE analysis reports for v3.8.3 covering code quality, security, performance, tests, SFDIPOT, dependencies, API contracts, architecture/DDD, accessibility, and brutal honesty audit Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
475bd61a75 |
fix(learning): purge 15K junk patterns, fix DB corruption, improve quality scoring
- Rebuild corrupted memory.db (82 corrupt pages causing 43% dream cycle failures) - Purge 15,624 benchmark/test artifacts from qe_patterns (bench-*, Dream: novel_association, Test Pattern) - Fix benchmark test isolation: add useUnified: false to prevent prod DB pollution - Improve cli-hook quality scoring: context-aware (source/speed) instead of hardcoded 0.7/0.3 - Fix statusline to show only meaningful patterns (was inflating count with junk + cross-table sum) - Update fallback statusline generator with same meaningful-only query Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
27c5171d9d |
fix: resolve issues #370, #371, #372 — OpenCode schema, infra-healing playbook, fleet init
- #370: opencode.json now uses string[] for command, 'environment' instead of 'env', and no extra 'args' field — matching OpenCode's McpLocal schema - #371: Fallback playbook YAML uses correct field names (healthCheck/verify instead of check/patterns) matching RecoveryPlaybook.parseService() - #372: Root cause (circular PersistentSONAEngine init) already fixed in efccd8c4; LearningOptimizationCoordinator try/catch already in source — v3.8.3 build includes both fixes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |