Commit Graph

1441 Commits

Author SHA1 Message Date
Dragan Spiridonov 04063c42c1 Merge remote-tracking branch 'origin/main' into fix/windows-install-439
# Conflicts:
#	package-lock.json
2026-05-08 13:05:16 +00:00
Dragan Spiridonov bea25f036f Merge pull request #441 from proffesor-for-testing/dependabot/npm_and_yarn/npm_and_yarn-4db41a3a8f
chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates
2026-05-08 15:04:23 +02:00
Dragan Spiridonov c09343c92a chore(release): bump version to v3.9.21
Bumps version + fleetVersion across package.json, plugin.json, and the
two skills-manifest.json copies. Adds CHANGELOG entry and release notes.

Includes one fix discovered during the release-prep e2e: stale-lock
recovery in shared-rvf-adapter's openOrCreateRvf ladder. The native
@ruvector/rvf-node binding leaves a `<file>.lock` artifact when a
process exits without calling close() — a behaviour that frequently
happens in CLI flows and that the previous always-create code path
masked. With open-or-create, those stale locks now surfaced as
`LockHeld` errors. The ladder now detects that, removes the stale
lock file, and retries open exactly once. E2E confirms RVF native
recovers cleanly across init → CLI invocation boundaries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:55:36 +00:00
Dragan Spiridonov 5d187de2a1 fix(install,rvf,hypergraph): unblock Windows install, fix RVF FsyncFailed, synthesize covers edges
Bundles fixes for issue #439 (Windows install) and Jordi RUFLO patches
P020 (RVF init) + P220 (hypergraph blindness).

Windows install (#439):
- Move hnswlib-node from dependencies to optionalDependencies so
  installs no longer fail on Windows boxes without VS C++ Build Tools;
  HnswAdapter already routes around a missing native binary at runtime.
- Replace HNSWIndex.ts top-level static `import hnswlib from
  'hnswlib-node'` with a lazy require so package load survives the
  optional dep being absent.
- README + preinstall.cjs: document toolchain requirement and disclose
  that the JS fallback degrades to O(N) brute-force when @ruvector/gnn
  is also unavailable (Windows default — no win32 prebuilds ship).
- ADR-090 amendment reconciling the move with ADR-081's optional-dep +
  JS-fallback intent.

RVF init (Jordi P020):
- Root cause: shared-rvf-adapter and pattern-store factory always called
  RvfDatabase.create(), which throws `0x0303 FsyncFailed` when the .rvf
  file already exists from a prior init phase. Reproduced and confirmed
  against both 0.1.7 and 0.1.8 native binaries — not a version
  regression.
- Fix: race-tolerant open-or-create ladder (try open → fall back to
  create → retry open on create-race) with dim() verification after
  open. Mismatched-dim files are closed and the caller degrades rather
  than corrupting silently.

Hypergraph (Jordi P220):
- Drop the original flushEdgesToHypergraph (wrote `call`/`extends`
  edges that no production query reads — devil's-advocate review caught
  it as dead infrastructure).
- Add HypergraphEngine.synthesizeTestCoverage that re-tags test files
  type='test' and writes `covers` edges from each test file to
  functions in the source files it imports. This is the shape
  findUntestedFunctions / findImpactedTests actually filter on.
- E2E verified: untested correctly excludes covered functions;
  impacted-tests returns the right test file.

Verification:
- `npm run build` clean
- 276/276 tests pass across HNSW, RVF, KG, coordinator, hypergraph
  suites (5 new synthesizeTestCoverage tests; replaced 4 obsolete
  flush tests)
- E2E on fresh project: aqe init clean, hooks stats shows
  nativeAvailable: true, code index logs `Test coverage synthesized`,
  hg untested + hg impacted return useful results

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 12:22:58 +00:00
dependabot[bot] 8dd292a9ba chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 2 updates in the / directory: [hono](https://github.com/honojs/hono) and [ip-address](https://github.com/beaugunderson/ip-address).


Updates `hono` from 4.12.14 to 4.12.18
- [Release notes](https://github.com/honojs/hono/releases)
- [Commits](https://github.com/honojs/hono/compare/v4.12.14...v4.12.18)

Updates `ip-address` from 10.1.0 to 10.2.0
- [Commits](https://github.com/beaugunderson/ip-address/commits)

---
updated-dependencies:
- dependency-name: hono
  dependency-version: 4.12.18
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: ip-address
  dependency-version: 10.2.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-08 11:05:32 +00:00
Dragan Spiridonov b3ee2d6b74 Merge pull request #440 from proffesor-for-testing/fix/jordi-wire-gap-patches-330-420
chore(release): v3.9.20
v3.9.20
2026-05-08 11:11:38 +02:00
Dragan Spiridonov bd6164c031 test(trajectory-judge): unit coverage for env-gate, schema check, and parsing
New file from patch 420 had no tests. Adds tests/unit/mcp/handlers/
trajectory-judge.test.ts with 7 cases:

  • no-op when ANTHROPIC_API_KEY is unset (env-var gate)
  • no-op when feedback column is absent (schema-presence check)
  • happy path writes structured {quality, reasoning, improvement}
  • quality clamped to [0,1] and fenced ```json``` parses correctly
  • malformed responses don't write partial feedback
  • batch cap at 5 rows even when more are unscored
  • ANTHROPIC_BASE_URL is honored for the fetch target (patch 380 wiring)

Mocks getUnifiedMemory + globalThis.fetch — never reaches Anthropic.

Caught during pre-PR gap audit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:18:55 +00:00
Dragan Spiridonov b763ca9b13 fix(task-orchestrate): patternHints also flow into workflow execution branch
handleTaskOrchestrate has two execution paths: workflowOrchestrator.
executeWorkflow() (line 388) when the task type maps to a registered
workflow, and queen.submitTask() (line 428) otherwise. The initial
patch 360 wiring only added patternHints to the submitTask payload —
the workflow branch routes through the same task_orchestrate request
but with a separate workflowInput object, so it was still routing
blind to the long-term pattern catalog.

Symmetric mapping now: both branches receive the same patternHints
array (patternId, name, description, confidence, similarity, canReuse)
derived from the single searchPatterns call we already do once per
request.

Caught during pre-PR gap audit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:17:30 +00:00
Dragan Spiridonov 3ef5fdbd7c docs(release): add v3.9.20 entry to CHANGELOG and releases index
Caught during pre-PR gap audit: per CLAUDE.md release rule, version
bumps must update every hardcoded reference. Missed CHANGELOG.md and
docs/releases/README.md in the initial bump commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:16:53 +00:00
Dragan Spiridonov 1a4a7ff9fb chore(release): bump version to v3.9.20
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:47:01 +00:00
Dragan Spiridonov 855d2d62bd fix(trajectory): route TrajectoryBridge to unified memory.db (ADR violation)
src/adapters/claude-flow/trajectory-bridge.ts:184 opened a separate
.agentic-qe/trajectories.db with its own `trajectories` schema —
unrelated to qe_trajectories on memory.db, and a direct violation of
the project's "Unified persistence system: all data goes through
SQLite (better-sqlite3) — one DB, one schema" rule from CLAUDE.md.
Symptom: feedback written via TrajectoryBridge.endTrajectory() never
showed up in any of the queries that read qe_trajectories.

persistTrajectory() now opens the unified memory DB via getUnifiedMemory(),
maps the bridge's columns onto qe_trajectories (started_at/completed_at
epoch ms → ISO datetime), and writes the same row everyone else reads.
Feedback column is added defensively in case TrajectoryTracker.ensureSchema
hasn't run yet on a fresh install.

Also rewords stale references in patches 420 (task-handlers.ts comment +
trajectory-judge.ts file header) that described the broken state as
"the hook-created rows are unreachable from the bridge" — with this fix
those rows are reachable, the bridge writes to the same table the judge
reads.

The trajectories.db path is kept in init.ts:330 reset --all list so
upgraded installs still get the legacy file cleaned up; comment notes
it's no longer a live writer target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:44:47 +00:00
Dragan Spiridonov 0b687da39d feat(trajectory): opt-in LLM judge for unscored qe_trajectories rows
TrajectoryBridge writes feedback into a separate trajectories.db, so
the hook-created rows (cli-hook-post-task and friends) that land in
the unified memory.db are unreachable from it. Result: 719 hook-
created trajectories observed in one session, 0 with feedback.

Adds a fire-and-forget judge that runs at the end of handleTaskOrchestrate.
Picks the 5 most-recent rows where feedback IS NULL AND ended_at IS NOT
NULL, asks Claude Haiku for a structured {quality, reasoning,
improvement} verdict, and writes the JSON into qe_trajectories.feedback.
Quality is embedded in the JSON since the canonical schema has no
quality column — avoids a schema migration.

Opt-in behind AQE_TRAJECTORY_JUDGE=1 because each call costs real
money. Uses the proxy-aware base URL from patch 380. Bounded to 5
rows per task_orchestrate call so cost is predictable. PRAGMA-checks
the feedback column first (TrajectoryTracker may not have migrated
yet on a fresh install) — no-ops gracefully otherwise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:37:56 +00:00
Dragan Spiridonov c03e420468 fix(hooks): emit recordUsage() update on per-pattern post-task fan-out
SQLitePatternStore.recordUsage() updates qe_patterns.{usage_count,
successful_uses, success_rate, quality_score} but is only invoked
through the HandleTaskOutcomeRecord MCP path. The hook flow that
already fans out per-pattern experience_applications rows (patches
160+300) never called it — quality_score stayed pinned at the
bootstrap value (~0.30 floor in observed data, with 88/89 patterns
never crossing into long-term).

Added inline SQL inside the persistTaskOutcome bridge loop, after the
experience_applications insert per pattern_id. Uses the same formula
as recordUsage(): confidence * 0.3 + min(usage_count/100, 1) * 0.2 +
success_rate * 0.5. Reads confidence from the pattern row first
because UPDATE expressions can't reference it directly.

Fail-soft per pattern — a deleted-but-referenced pattern_id won't
break the rest of the loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:35:45 +00:00
Dragan Spiridonov 6ae10a5b5a fix(hooks): write embeddings on hook-side captured_experiences inserts
Two sites in hooks-dream-learning.ts write captured_experiences rows
without computing an embedding:
  • persistCommandExperience (sources: cli-hook-post-command,
    cli-hook-post-edit) — the entry point for editing-hooks.ts and
    command-hooks.ts post-command writes
  • persistTaskOutcome (source: cli-hook-post-task) — patch 060 path
    for the post-task hook

In a recent pulse 1203/1902 (63%) captured_experiences rows had
embeddings; ~85% of new writes since v3.9.19 came through these two
hook paths and contributed zero embeddings, leaving HNSW C cold for
hook-driven workloads. Patch 350 backfills on next boot, but new rows
were unsearchable until restart.

Both writers now fire a no-await IIFE after the INSERT (after txn()
in the post-task case) that imports computeRealEmbedding, computes
text=`${domain}: ${task}`.slice(0,512), and UPDATEs the row in place
through the same DB handle. Fail-soft — the row is already persisted,
so a missed embedding is recoverable by patch 350 on next boot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:34:37 +00:00
Dragan Spiridonov 7b0218c353 fix(task-orchestrate): include HNSW A pattern hints in submitTask payload
handleTaskOrchestrate already calls reasoningBankService.getExperienceGuidance()
to surface relevant past trajectories (HNSW C). The catalog of consolidated
long-term patterns (HNSW A on qe_patterns) was never consulted on the request
path — only HNSW C influenced routing.

Adds a parallel searchPatterns(task, {limit:5, domain}) call and forwards
the top hits as `patternHints` on submitTask payload (patternId, name,
description, confidence, similarity, canReuse). canReuse=true when the
pattern is in the long-term tier.

Fail-soft: empty array on error so a misbehaving HNSW A path can't
break task orchestration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:32:52 +00:00
Dragan Spiridonov 8ab4e07c92 fix(experience-replay): boot-time embedding backfill for qe_trajectories
TrajectoryTracker.endTrajectory() writes the qe_trajectories row with
embedding=NULL and there's no follow-up worker that fills it in.
Hook-side trajectory inserts (cli-hook-post-task) leave the column
NULL too. With 719 hook-created rows and 0 embeddings observed, kNN
over historical trajectories collapses to "no candidates" and
ReasoningBank can't surface similar past runs.

Adds a second fire-and-forget IIFE in ExperienceReplay.initialize()
adjacent to patch 350, scoped to qe_trajectories. PRAGMA-checks the
embedding column first since TrajectoryTracker.ensureSchema() is what
adds it — the backfill no-ops gracefully if it hasn't run yet. Cap=200
per boot.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:30:55 +00:00
Dragan Spiridonov 59a0b4410c fix(experience-replay): boot-time embedding backfill for captured_experiences
ExperienceReplay.initialize() loaded the HNSW index from rows with
embeddings, but most hook-side INSERT paths (cli-hook-post-command,
patch-060-post-task, etc.) wrote captured_experiences rows without
calling computeRealEmbedding(). Result: HNSW C index stayed cold —
in one observed pulse 1203 of 1902 rows (63%) had embeddings; 85% of
new writes since v3.9.19 had none, so kNN recall converged on the
same handful of points.

Adds a fire-and-forget IIFE in initialize() after loadEmbeddingIndex()
that selects up to 200 ghost rows (embedding IS NULL AND
consolidated_into IS NULL), computes embeddings with the same
real-embeddings config the canonical writer uses, UPDATEs the row, and
adds the vector to the live HNSW index so it's immediately searchable
without restart. Cap=200/boot to bound work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:28:41 +00:00
Dragan Spiridonov f4870f32d1 fix(mcp): pre-warm ReasoningBankService at MCP boot
The ReasoningBankService singleton + EnhancedReasoningBankAdapter +
HNSW A index population happened lazily on first task_orchestrate
call. Result: the first routing decision after a cold MCP start paid
the full HNSW build cost on the request path, and any racing call
returned before the HNSW A index was ready, falling through to
context-only matches.

Fire-and-forget IIFE after CrossPhaseHooks eager init so the warm-up
runs in parallel with the rest of MCP startup. No await — boot is not
blocked. Logs `[MCP] ReasoningBank prewarmed` on success or a WARNING
on failure (non-fatal; service will still lazy-init on first call).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:27:40 +00:00
Dragan Spiridonov 5b3e614385 fix(dream): apply 60s busy_timeout to DreamEngine DB handle (ADR-001 Option C)
checkAndTriggerDream() dynamically imports createDreamEngine, which
opens a fresh DB handle via getUnifiedPersistence(). The hook-side
(patch 260) and worker-side busy_timeout pragmas never reached this
dynamically-imported path, so cycles ran with the platform default 0ms
timeout. Under concurrent MCP-worker contention on the WAL write-lock,
SQLITE_BUSY hit immediately and cycles were marked failed. Observed
failure rate: 199/279 (71%) in a single session.

Aligns with the 60s asymmetric prioritization the hook subprocesses
already use — workers fail fast, dream cycles wait patiently.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:26:33 +00:00
Dragan Spiridonov 2c029595c5 fix(providers): Claude providers respect ANTHROPIC_BASE_URL env var
Both Claude provider implementations hardcoded the api.anthropic.com
fallback when no baseUrl was passed in config, ignoring the
ANTHROPIC_BASE_URL environment variable that proxies (Claude Max Proxy,
LiteLLM, etc.) rely on. Result: AQE LLM calls bypassed configured
proxies and went straight to Anthropic.

Mirrors the env-var precedence already used by
context/compaction/llm-caller-adapter.ts:23.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:25:58 +00:00
Dragan Spiridonov af970feeb6 fix(mcp): aqe_health calls vectorCount(), not getVectorCount()
The handler probed `getVectorCount` on the unified memory manager, but
the method is `vectorCount()` (unified-memory.ts:755). The mismatch made
the typeof check fail silently, so `aqe_health` returned hnswStats
with vectorCount stuck at 0 even when the vectors table had hundreds of
rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 07:25:27 +00:00
Dragan Spiridonov 61b91db359 Merge pull request #438 from proffesor-for-testing/dependabot/npm_and_yarn/npm_and_yarn-ac20752053
chore(deps): bump axios from 1.15.1 to 1.16.0 in the npm_and_yarn group across 1 directory
2026-05-06 11:28:05 +02:00
dependabot[bot] 133549e096 chore(deps): bump axios in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.15.1 to 1.16.0
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.15.1...v1.16.0)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.16.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-05 17:57:04 +00:00
Dragan Spiridonov 84efff4397 Merge pull request #437 from proffesor-for-testing/fix/jordi-wire-gap-patches
chore(release): v3.9.19
v3.9.19
2026-05-05 19:55:53 +02:00
Dragan Spiridonov ec451c419f chore(release): bump version to v3.9.19 2026-05-05 16:53:24 +00:00
Dragan Spiridonov ae50f7d3f6 fix(statusline): correct ADR directory path
ADR_DIR pointed at `implementation/adrs` but the ADR files actually live
under `docs/implementation/adrs`. Both the bash statusline and its CJS
helper looked in the wrong place, so adrCount was always 0 in the
statusline output. Updated both to the correct path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:22:38 +00:00
Dragan Spiridonov 9e95f17a91 chore(comments): drop external patch-source attributions
Comments referenced an external patch series identifier and
a contributor's first name. Those refs aren't useful to anyone reading
this repo on its own and rot quickly. Replaced with the underlying ADR
references (ADR-058 embedding-locality, etc.) where they apply.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:07 +00:00
Dragan Spiridonov 39febbb35d fix(hooks): apply 60s busy_timeout pragma at hook DB opens (ADR-001 Option C)
Hook subprocesses (`npx aqe hooks ...`) opened the shared memory.db with
the platform default 5s busy_timeout. Under contention from MCP-daemon
workers holding the WAL write-lock during dream-cycle / pattern-promotion
(which can block writers for several seconds), hook writes failed with
SQLITE_BUSY.

Added `applyHookBusyTimeout(db)` in hooks-shared.ts that runs
`PRAGMA busy_timeout = 60000` on a connection. Hook subprocesses are
short-lived, so the longer timeout is bounded to that lifetime and
doesn't affect the MCP daemon's own connections.

Workers in MCP keep the platform default (5s) so they fail fast and
retry on the next tick, yielding the lock to hooks under contention —
the asymmetric prioritization ADR-001 Option C requires.

Wired at every hook handler db-open site:
  • task-hooks.ts pre-task
  • command-hooks.ts post-command
  • routing-hooks.ts route persistence
  • hooks-dream-learning.ts (5 db handle sites incl. persistTaskOutcome,
    updateHookRouterQValue, updateRoutingOutcomeQuality)

Also bumps the busyTimeout in createHybridBackendWithTimeout from 5000
to 60000 so HybridMemoryBackend consumers in hook subprocesses get the
same patient timeout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:07 +00:00
Dragan Spiridonov 4f000463a8 fix(code-intelligence): persist file→entity contains edges + resolve relative imports
Two related fixes in HypergraphEngine.buildFromIndexResult — the path
that turns a code index result into hypergraph_nodes/_edges rows.

1) Phase 2 (entity nodes) now also writes a `contains` edge from each
   file node to each contained entity (function, class, interface, etc).
   Previously only Phase 3 imports edges were persisted, so
   hypergraph_edges held import edges only and queries like
   `findUntestedFunctions`, `findImpactedTests`, `findCoverageGaps`
   returned empty regardless of indexing activity.

2) Phase 3 (import edges) now resolves relative import specifiers
   (`./foo`, `../bar/baz`) against the source file's directory and
   probes common TS/JS/Python extensions plus `/index.ext` for
   directory imports. Previously a relative import never matched any
   hypergraph_nodes row and was silently skipped — only bare-module
   imports could match, which excluded most intra-repo imports.

Schema: extends EdgeType with 'contains' and adds it to the stats
aggregator's Record initializer so getStats() compiles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:07 +00:00
Dragan Spiridonov 39020c83a7 fix(coordination): use 6-dim quality formula in task-executor outcome
task-executor.ts:445 hardcoded `qualityScore: success ? 0.8 : 0.2` when
recording routing outcomes via QualityFeedbackLoop. That produced only
two distinct quality_score values across all task outcomes, defeating
the point of treating quality_score as a learnable signal.

Replaced with the same 6-dim formula used by the post-task hook UPDATE
path: 0.25 * success + 0.325 baseline + 0.10 * duration_tier (where
duration_tier is a stepped function of execution time). Yields 6+
distinct quality bands per success/fail × duration combination.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:06 +00:00
Dragan Spiridonov 9b489a346b fix(mcp): eagerly initialize CrossPhaseHooks at startup
The CrossPhaseHooks singleton in hooks/cross-phase-hooks.ts is created on
first use, but its initialize() (config-load + memory wiring) only runs
when explicitly called. Result: under sustained queen-event-handlers
traffic, kv_store / qcsd-memory rows did not grow because the executor's
config was never parsed.

Calling getCrossPhaseHookExecutor().initialize() right after the MCP
server is Ready means hook events fire through a fully-initialized
executor from the first request.

Also drops the patch-source attribution from the existing patch-250
comment block to keep comments evergreen for downstream readers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:06 +00:00
Dragan Spiridonov d5051576b4 feat(hooks): wire pre/post-task to full experience + routing pipeline
Wires task-hooks.ts both
sides:

PRE-TASK now emits and persists:
  • selectedPatternIds: top-5 pattern UUIDs from routing.patterns (050)
  • historicalBest: agent + avgQuality + n from past success=1 rows (090)
  • priorVerdicts: kv_store namespace='verdicts' last 7d (100)
  • estimatedTokenSavings: SUM(average_token_savings) for selected
    patterns from qe_patterns (300)
  • lowConfidence: confidence < 0.5 flag (320)
  • bridgeKey: hash of description; identifies the kv_store task-bridge
    entry written for post-task to consume (160 + 280)
  • routing_outcomes sentinel row (success=0, quality_score=-1) for
    post-task UPDATE (150 split-write)

The kv_store task-bridge entry payload now carries the full structural
state (taskType, priority, domain, complexityBucket) plus
estimatedTokenSavings — the q-learning integration in post-task derives
state_key from this without recomputing.

POST-TASK now wires three helpers (defined in hooks-dream-learning.ts):
  • persistTaskOutcome — writes captured_experiences + per-pattern
    experience_applications + qe_trajectories single+multi-step +
    dream_insights.applied bump (060/110/120/160/180/300)
  • updateRoutingOutcomeQuality — UPDATEs the sentinel from pre-task
    with 6-dim outcome quality (150)
  • updateHookRouterQValue — Bellman update at the structural
    state_key from the bridge (280)

End-to-end smoke verified: pre-task writes sentinel, post-task UPDATEs
to quality=0.635 (0.25*1 + 0.325 + 0.10*0.6 for 850ms duration),
lowConfidence flag preserved across the UPDATE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:06 +00:00
Dragan Spiridonov 64407db60c fix(hooks): align aqe hooks route writer with split-write semantics (patch 150)
routing-hooks.ts wrote routing_outcomes with quality_score = routing
confidence — semantically inconsistent with the rest of the hook flow,
which now treats quality_score as "outcome quality after task ran"
(6-dim formula). Routing confidence stays in decision_json where it
belongs.

Now writes a sentinel (success=0, quality_score=-1) so post-task can
UPDATE it with the actual outcome quality. lowConfidence flag (patch
320) is captured in decision_json and the error column for diagnostic
visibility.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:06 +00:00
Dragan Spiridonov 3f434723a3 feat(hooks): persistTaskOutcome + Q-learning + routing-quality helpers
New helpers in hooks-dream-learning.ts (re-exported via hooks-shared.ts):

persistTaskOutcome — rolls related fixes
into one transaction:
  • captured_experiences row (source='cli-hook-post-task')
  • experience_applications base row + 1 per pattern_id from bridge
  • Reads + deletes kv_store namespace='task-bridge' (one-shot)
  • Distributes estimatedTokenSavings/N across per-pattern apps (300)
  • Single-step qe_trajectories row (120)
  • Multi-step stitch from siblings sharing taskId in last 1h (180)
  • dream_insights.applied += 1 for top-3 actionable rows on success (110)
Returns experienceId, qualityScore, bridge payload, and counters for
the q-learning integration to consume.

updateHookRouterQValue — patch 280: Bellman update with proper column
semantics per ADR-061/087:
  • algorithm='q-learning' (not 'asymmetric-hebbian'; that label is
    for ReasoningBank confidence updates, NOT Q-learning state-action)
  • agent_id='aqe-hook-router' (per-instance partition; doesn't collide
    with canonical RuVector q-router agent_id='q-router')
  • state_key='${taskType}|${priority}|${domain}|${complexityBucket}'
    (structural; verbatim q-learning-router.ts:591)
  • action_key=agent name; id schema 'q-learning:aqe-hook-router:...'
  • Q ← Q + α(r + γ·max_a' Q(s',a') − Q), α=0.1, γ=0.9
  • Asymmetric reward: success +0.1, failure −1.0

updateRoutingOutcomeQuality — patch 150: UPDATEs the most-recent
routing_outcomes row with quality_score=-1 sentinel, applying the
6-dim formula 0.25*success + 0.325 + 0.10*duration_tier. Prefers rows
matching the actual used_agent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:06 +00:00
Dragan Spiridonov c9931174ce fix(hooks): gate noise captures + add test_outcomes/coverage_sessions writers
Test outcome wiring (patches 070, 170, 310 — all in command-hooks.ts post-command:

Patch 310: persistCommandExperience was called unconditionally for every
Bash command, flooding captured_experiences with noise from git/ls/etc.
The framework regex `isTestCmd` was computed at line 200 but never gated
the persistence call. Now gated to test/build/lint commands. The original code
observed 875+ noise rows at 8.2% success rate diluting pattern signal —
this closes that flood.

Patch 070: when a recognized test framework runs, INSERT a test_outcomes
row capturing framework, language, pass/fail, and execution time.
Provides raw signal for the 6-dim quality calculator.

Patch 170: when coverage/coverage-summary.json is present (Istanbul),
parse and INSERT a coverage_sessions row with after_lines/branches/
functions, reusing the prior session's after_* values as before_* so
delta is calculable.

reasoningBank.recordOutcome remains unconditional — it's the broader
metric path, not the pattern-specific captured_experiences write.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:06 +00:00
Dragan Spiridonov 8867095888 fix(learning): load embeddings into unified HNSW + lazy-init for stats
PatternStore.initializeHNSWInternal() had the embedding-load loop only
in the legacy fallback branch. When useUnifiedHnsw=true (our default per
ADR-071), the function returned at the unified-bridge branch BEFORE the
load loop ran. Result: existing qe_pattern_embeddings rows were never
ingested into the unified HNSW backend on first init; routing fell back
to context-only matches (cosine score 0).

PatternStore.getStats() reported the pre-init zero state because it
explicitly skipped lazy-loading. So `aqe hooks stats --json` returned
nativeAvailable:false, vectorCount:0 even on a populated store.

Patch 030: extracted loadEmbeddingsIntoHNSW() and call it from both the
unified-bridge path AND the legacy path. Cap respected (maxElements).
Logs `[PatternStore] Loaded N embeddings into HNSW (skipped M)`.

Patch 040: getStats() now awaits ensureHNSW() before reading state, so
stats reflects the actual HNSW backend (paying the bounded lazy-init
cost — the contract a stats command should fulfill).

Together these close the unified-HNSW boot gap that left routing
defaulting to context-only matches with vectorCount:0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:05 +00:00
Dragan Spiridonov c78011a1d4 fix(learning): unify pattern-embedding writers
Three live writers in our codebase write to qe_patterns:
  1. learning/sqlite-persistence.ts:497   SQLitePatternStore.storePattern (canonical)
  2. cli/.../hooks-dream-learning.ts:305  consolidateAgentPatterns (bypass)
  3. workers/.../learning-consolidation.ts:412  createPatternsFromCandidates (bypass)

Only the canonical writer paired the row with a qe_pattern_embeddings
row (via computeRealEmbedding inside RealQEReasoningBank.storeQEPattern).
Writers 2 & 3 produced "ghost" patterns: rows with no vector that load
into in-memory cache but stay invisible to HNSW pattern recall.
Observed symptom: vectorCount: 0 reported even after 79 patterns
load, because 10 ghosts had no embedding.

Adds src/learning/embed-and-insert-pattern.ts with ensurePatternEmbedding(),
a fail-soft helper that:
- Builds text = `${name} ${description} ${tags.join(' ')}`
- Calls computeRealEmbedding(text) (Xenova/all-MiniLM-L6-v2, 384-dim)
- Writes qe_pattern_embeddings row alongside the existing qe_patterns INSERT
- Logs at debug level on failure (pattern row already persisted —
  embedding can be backfilled later)

Routes both bypass writers through the helper so all 3 writers speak
the same embedding-config "lingua franca" (per ADR-058 locality).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:05 +00:00
Dragan Spiridonov fff194cc6a fix(hooks): expand Task matcher to ^(Task|Agent)$
Claude Code dispatches subagent tools as both `Task` (legacy) and `Agent`
(current). Our PreToolUse/PostToolUse hook matchers only matched `^Task$`,
so AQE pre-task and post-task hooks never fired on real Agent dispatch.
Result: 0 deltas in captured_experiences / experience_applications /
qe_trajectories on actual subagent invocation.

Updated:
- src/init/phases/07-hooks.ts (template that ships to users via aqe init)
- .claude/settings.json (this project's working config)

Empirically verified by upstream Tier-A e2e: pre-fix 0 deltas, post-fix
full delta set across patches 060/110/120/130/150/180/190.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:05 +00:00
Dragan Spiridonov 9e4f23e3bc fix(mcp): restore getDaemon() autostart default
src/mcp/entry.ts:211 explicitly overrode getDaemon({autoStart:false}),
neutering workerManager.startAll() — the only call path that schedules
per-worker setInterval timers. The "[MCP] Background workers started
(11 workers)" log reads totalWorkers (registered count), not scheduled
count, so the 11 background workers register but never tick in any
process spawned from this entry (Claude Code MCP, start-daemon.cjs,
manual node bundle.js).

DEFAULT_CONFIG.autoStart=true (workers/daemon.ts:53) is the canonical
default. The shutdownDaemon() call at entry.ts:44 already uses the
default; this aligns the startup path with it.

Diagnosed via external investigation — see ADR-001
"AQE workers WAL contention strategy". gitnexus impact: LOW risk,
1 affected caller.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 16:20:04 +00:00
Dragan Spiridonov 78ff75f462 Merge pull request #436 from proffesor-for-testing/release/v3.9.18
chore(release): v3.9.18 — 4 MCP fixes + agentic-qe-fleet plugin
v3.9.18
2026-04-30 17:24:16 +02:00
Dragan Spiridonov 8b4e54fd8e docs(plugin): publish as Claude Code marketplace + add README install section
Mirrors the ruvnet/ruflo pattern (verified live in ~/.claude/plugins/marketplaces/ruflo/):

- .claude-plugin/marketplace.json — required manifest that lists agentic-qe-fleet
  with relative source path, making this repo a valid Claude Code marketplace
- .claude-plugin/plugin.json — top-level metadata (engines, MCP server,
  keywords) so the marketplace itself can be referenced
- .claude-plugin/README.md — picker-surface description with install command
  and plugin overview
- README.md — new "Claude Code Plugin (Alternative Install)" section showing
  /plugin marketplace add path and plugin-vs-aqe-init comparison; removed the
  "once published" caveat now that the marketplace files exist

Users can now install via:
  /plugin marketplace add proffesor-for-testing/agentic-qe
  /plugin install agentic-qe-fleet

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 14:50:11 +00:00
Dragan Spiridonov cf1072370f docs(readme): add agentic-qe-fleet plugin install + usage section
User-facing instructions for the plugin shipped in v3.9.18:
- Install paths (local checkout via --plugin-dir, marketplace once published)
- What's bundled (11 agents, 9 commands, 9 skills, auto MCP)
- Usage examples (slash commands, Task tool agent invocation)
- Plugin vs aqe init comparison table

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 14:46:19 +00:00
Dragan Spiridonov 25b6bd732a chore(release): v3.9.18
Bundles 4 MCP bug fixes + new agentic-qe-fleet plugin.

Fixed:
- coverage_analyze_sublinear and other domain MCP tools blocked by governance
  after 1-2 calls (synthetic token-slope estimate replaced with 0; throttle
  decisions are no longer treated as hard blocks)
- test_generate_enhanced framework=jest produced unrunnable tests (now emits
  @jest/globals imports instead of invalid 'jest' package import)
- generated test imports referenced /tmp/aqe-temp-* paths (importPathOverrides
  plumbed through IGenerateTestsRequest end-to-end)
- qe/coverage/gaps error message misled callers about which input failed
  (distinguishes coverageFile-empty vs autodiscovery-miss)

Added:
- test_generate_enhanced schema exposes framework, filePath, coverageGoal,
  aiEnhancement, detectAntiPatterns parameters
- agentic-qe-fleet Claude Code plugin (11 agents, 9 commands, 9 skills)
- scripts/smoke-test-fixes.sh and scripts/plugin-load-test.sh

Verification:
- 1301 MCP unit tests pass (zero regressions)
- 734 targeted unit tests pass across changed code
- aqe init --auto in fresh project succeeds (85 skills, 60 agents)
- End-to-end MCP smoke test passes 5/5
- qe-coverage-specialist agent re-spawn confirms NO_GOVERNANCE_BLOCK
- Plugin structural validation: 14/14 checks pass

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 14:39:10 +00:00
Dragan Spiridonov 90dd17218a Merge pull request #435 from proffesor-for-testing/fix/userpromptsubmit-stdin-routing
fix(hooks): UserPromptSubmit reads stdin event JSON for routing (v3.9.17)
v3.9.17
2026-04-27 08:54:58 +02:00
Dragan Spiridonov 087caf41dd docs(release): add v3.9.17 release notes
Per /release skill §4b — release notes file at docs/releases/v3.9.17.md
plus index row at the top of docs/releases/README.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 06:28:12 +00:00
Dragan Spiridonov 5f711b5b3e fix(hooks): UserPromptSubmit reads stdin event JSON for routing (v3.9.17)
The shipped `aqe init` template wired the UserPromptSubmit hook to
`npx agentic-qe hooks route --task "$PROMPT" --json`, but Claude Code
never exposed `$PROMPT` as an env var — only stdin event JSON. The
shell expanded `"$PROMPT"` to `""`, so every prompt routed as empty
and `routing_outcomes.task_json` was persisted as `{"description":""}`,
silently breaking the routing learning loop.

- routing-hooks.ts: demote --task to optional, read stdin (500ms
  timeout) and extract prompt/user_prompt/command/tool_input.{prompt,
  description}; explicit error when neither source has content
- 07-hooks.ts and init-wizard-hooks.ts: drop --task "\$PROMPT", let
  the CLI read stdin directly. isAqeHookEntry still matches both
  shapes, so existing projects upgrade on `aqe init --upgrade`
- tests/unit/cli/commands/hooks-routing.test.ts: 10 unit tests
  covering all event shapes, fallback ordering, malformed JSON, and
  empty-field skip

Verified end-to-end: piped a Claude Code-shaped event into a fresh
project's configured route command and confirmed task_json captures
the real prompt instead of "". Backward-compat manual --task usage
preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 06:19:05 +00:00
Dragan Spiridonov 19e8796dcb Merge pull request #434 from proffesor-for-testing/dependabot/npm_and_yarn/npm_and_yarn-e9ce4f7be9
chore(deps): bump uuid from 9.0.1 to 14.0.0 in the npm_and_yarn group across 1 directory
2026-04-25 16:28:41 +02:00
dependabot[bot] 099b1588dc chore(deps): bump uuid in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [uuid](https://github.com/uuidjs/uuid).


Updates `uuid` from 9.0.1 to 14.0.0
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v9.0.1...v14.0.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 14.0.0
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-24 12:50:56 +00:00
Dragan Spiridonov 9ed1bda600 Merge pull request #433 from proffesor-for-testing/feat/brain-search-and-diff
chore(release): v3.9.16
v3.9.16
2026-04-24 14:49:25 +02:00
Dragan Spiridonov baecaf9865 chore(release): bump version to v3.9.16
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:20:33 +00:00