1761 Commits

Author SHA1 Message Date
Dragan Spiridonov 55ab90c898 chore(release): v3.12.3 — atomic RVF export + self-healing stores (#563)
chore(release): v3.12.3 — atomic RVF export + self-healing stores (#563)
v3.12.3
2026-07-17 18:05:31 +02:00
Dragan Spiridonov 871d6c81af chore(release): bump version to v3.12.3
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 13:20:03 +00:00
Dragan Spiridonov 272c74f8e8 test(kernel): make llm-router hermeticity real (COGNITUM_API_KEY)
The two "no provider available" tests save and clear provider keys to be
hermetic, but the list went stale when ADR-123 (v3.12.2) added the cognitum and
claude-code providers. Any developer with COGNITUM_API_KEY exported got a
HybridRouter where the test expected undefined — failing locally while passing
in CI, where none of these are set.

Adds COGNITUM_API_KEY, CLAUDE_API_KEY, and ANTHROPIC_AUTH_TOKEN to both
clear-lists. Verified: 17/17 pass with COGNITUM_API_KEY still exported.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 13:19:43 +00:00
Dragan Spiridonov b04f0fdace fix(rvf): atomic brain export + recovery from unusable stores (#563)
An export killed mid-write (hook timeout, session teardown, SIGKILL) left a
store created but never completed. It could neither be opened (0x0106
ManifestNotFound) nor created over (0x0303 FsyncFailed, path exists), so the
RVF backend stayed silently disabled for the life of the project.

Export is now atomic: build at `<path>.tmp.<pid>`, close, then rename over the
final path. An interrupted export leaves the previous good store untouched.
Stale tmps are swept, skipping any whose owning pid is still alive.

Recovery is wired into all three open paths (dual-writer/brain.rvf, shared
adapter/patterns.rvf, pattern-store ladder): when open AND create both fail the
file is provably unusable, so it is quarantined aside — not deleted — and the
derived cache is rebuilt.

Recovery is deliberately NOT keyed on the signature reported in the issue.
Measured against @ruvector/rvf-node 0.1.8: `FLVR` is the lock record's own
magic (the store's is `SFVR`), so a 104-byte FLVR lock is an ordinary stale
lock, not leaked store bytes; and a valid empty store is exactly 162 bytes,
the size reported as "truncated". Keying on either would quarantine healthy
stores out from under live processes. The lock record does carry its owner's
pid (u32 LE at offset 4), which now guards recovery and also fixes a
pre-existing hazard: stale-lock cleanup previously unlinked locks
unconditionally, breaking live peers.

Also converts three require() calls of source modules to static imports. They
resolve in the esbuild bundle but throw under the test runner, so tests were
silently exercising a different code path than production.

Tests: real SIGKILL mid-export reproduction (previously truncated the store to
162 bytes + stale lock, matching the report), fault-injected export failure,
and recovery through each open path. All fail without the fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 12:57:58 +00:00
Dragan Spiridonov fbf0fc1e79 Merge pull request #562 from proffesor-for-testing/feat/flywheel-platform-witness-key
feat(flywheel): sign receipts with the Cognitum platform witness identity (bridge, qe-harness#7)
2026-07-16 17:59:53 +02:00
Dragan Spiridonov 98206bcc1a feat(flywheel): sign receipts with the Cognitum platform witness identity (witness-key bridge)
The flywheel signed evolve receipts with a self-generated key, so its lineage
could not be attributed to the platform identity that qe-harness evidence bundles
chain to. This wires the bridge:

- platform-signer.ts: platformSigner() derives the deterministic Ed25519 seed from
  QE_WITNESS_SIGNING_KEY (JSON {publicKey,privateKey}, the Secret Manager shape
  qe-harness Stage-B reads) and hands it to createSigner — reproducing the exact
  platform keypair. Graceful: null when the env is absent/malformed (keeps the
  self-generated-key behaviour). Env-reading stays out of the receipt.ts core.
- receipt.ts keyIdOf now trims the PEM, matching the platform witness fingerprint
  scheme (sha256(pem.trim()) truncated to 16 hex — qe-harness witness.ts /
  meta-llm qe-witness.ts). So a platform-signed receipt's keyId equals the
  allowlist fingerprint.

Verified against the REAL QE_WITNESS_SIGNING_KEY (no key material logged): the
derived signer's keyId == f1ac28607da49ec1, it is in the real
QE_WITNESS_PUBLIC_KEYS_JSON allowlist, and a signed receipt verifies (tamper
rejected). Tests: +5; existing flywheel suite (34) green; tsc clean.

Refs cognitum-one/qe-harness#7.

Co-Authored-By: Ruflo & AQE
2026-07-13 17:16:00 +02:00
Dragan Spiridonov adf56c8230 Merge pull request #560 from proffesor-for-testing/feat/issue-557-billing-aware-llm
chore(release): v3.12.2 — billing-aware LLM execution (ADR-123, #557)
v3.12.2
2026-07-13 14:26:23 +02:00
Dragan Spiridonov 9943c0c2d0 chore(release): bump version to v3.12.2
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 11:49:37 +00:00
Dragan Spiridonov b9a4b4c6e8 feat(llm): billing-aware execution — subscription provider, enforced budgets, real eval (ADR-123)
Closes the structural gap from issue #557: AQE could only bill the paid
Anthropic API even for Pro/Max subscribers, and its budget caps were never
enforced.

- claude-code provider: run QE via `claude -p` on the user's subscription;
  child env strips API-billing keys so it can't revert to API billing
- Enforced cross-process spend caps (--max-budget-usd / AQE_MAX_BUDGET_USD),
  persisted to memory.db (llm_spend); enforced on the ProviderManager AND
  HybridRouter paths; over-budget aborts with COST_LIMIT_EXCEEDED
- cognitum provider: OpenAI/Anthropic-compatible gateway with per-request
  cost receipts, embeddings, and a server-side hard cap
- Billing-mode taxonomy + startup notice + `aqe health` LLM Billing section
- config-store: honor explicit `enabled: false` over env key presence;
  AQE_LLM_PROVIDER selector
- Fix: `aqe eval run` no longer scores fabricated mock responses — real
  provider by default, hard-error when none configured, `--mock` opt-in
- Consensus verification path prints a billing warning (deferred full port)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 11:49:28 +00:00
Dragan Spiridonov 194273409a Merge pull request #559 from proffesor-for-testing/fix/test-db-isolation
test(learning): isolate DB-backed tests from the real memory.db
2026-07-13 09:04:31 +02:00
Dragan Spiridonov 8fc5c9423b test(learning): isolate DB-backed tests from the real .agentic-qe/memory.db
Two flaky tests depended on shared/real SQLite state, causing failures only
in the full parallel suite run:

- metrics-tracker.test.ts opened the REAL project .agentic-qe/memory.db via
  createLearningMetricsTracker(process.cwd()). A live-DB read threw "database
  is locked" under the bind-mounted/parallel runner (and risked corrupting the
  project's learning data). Now uses an isolated temp projectRoot with an
  empty-but-valid memory.db, exercising the real getDashboardData* code paths
  (the tracker probes sqlite_master, so an empty DB returns zeroed metrics).
  Adds an explicit "Database not found" test against a missing temp DB.

- sona-persistence.test.ts used a fixed /tmp path, so persisted kv_store state
  (the request counter) leaked between tests and flaked the "starts at 0"
  assertion. Each test now gets a unique mkdtemp dir, cleaned up in afterEach.

Full unit suite: 17639 passed, 0 failed (previously 5 failed / 2 files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 06:53:21 +00:00
Dragan Spiridonov 721c65ada2 Merge pull request #558 from proffesor-for-testing/working-july
chore(release): v3.12.1
v3.12.1
2026-07-13 08:12:13 +02:00
Dragan Spiridonov e06a975d46 chore(release): bump version to v3.12.1
Non-destructive `aqe init` for `.claude/settings.json`: merge instead of
overwrite, preserve user-owned config (custom statusLine, explicit
includeCoAuthoredBy, AQE_* env overrides, other tools' hooks such as ruflo /
Claude Flow), deep-merge v3 sections, and back up the pristine original before
writing (mirroring CLAUDE.md.backup).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 16:44:21 +00:00
Dragan Spiridonov 4ace7d81e0 Merge pull request #556 from proffesor-for-testing/working-july
chore(release): v3.12.0
v3.12.0
2026-07-11 09:10:38 +02:00
Dragan Spiridonov 613ddd4669 fix(security): replace every '*' when parsing wildcard redirect patterns
Follow-up to 961f3feb. The structural rewrite removed the regex sink (the 9
incomplete-hostname-regexp alerts cleared) but introduced one new alert:
`allowed.replace('*', MARKER)` replaces only the FIRST '*' (CodeQL
js/incomplete-sanitization, "Incomplete string escaping or encoding",
routes.ts:709).

Use the global form `allowed.replace(/\*/g, MARKER)` so every '*' is substituted.
A multi-wildcard pattern is still rejected safely: its suffix then contains the
placeholder label, which no real host can end with. Adds a regression test for a
multi-star pattern.

All 10 validateRedirectUri cases pass; tsc 0 errors; build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:34:58 +00:00
Dragan Spiridonov 961f3feb5d fix(security): validate redirect URIs structurally, not via URL-derived regex
Follow-up to 2d63c88c. Bounding the wildcard to `[^./]+` fixed the open-redirect
bypass, but CodeQL's js/incomplete-hostname-regexp still flagged every hostname
allow-list literal that flows into `new RegExp` (it does not model the custom
escaping), so the alert count grew to 9 as the new regression tests added more
`*.example.com` literals.

Remove the RegExp sink entirely: validateRedirectUri now compares parsed URL
components. For a wildcard entry, only the single leftmost subdomain label may be
wildcarded — it must be a non-empty, dot-free label — and protocol/port must match
with an exact-or-prefix path match. This is strictly more secure (a host can never
be spoofed via extra dots or path segments) and eliminates the CodeQL finding at
its root (no URL string is ever compiled into a regex).

All 9 validateRedirectUri cases pass unchanged (6 original + 3 bypass regressions);
tsc 0 errors; build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:22:56 +00:00
Dragan Spiridonov 2d63c88c98 fix(security): bind redirect-URI wildcard to a single label (open-redirect / CodeQL)
validateRedirectUri expanded an allow-list wildcard with `.replace(/\*/g, '.*')`,
so `https://*.example.com/cb` compiled to `^https://.*\.example\.com/cb$`. Because
`.*` also matches `.` and `/`, an attacker-controlled host could satisfy the
pattern by carrying the allowed suffix in the URL PATH — e.g.
`https://evil.com/x.example.com/cb` validated as allowed → open redirect. This is
the CodeQL js/incomplete-hostname-regexp finding (6 alerts, #214–219) surfaced by
the new a2a auth route tests.

Fix: expand the wildcard to `[^./]+` so it binds to a single subdomain label and
cannot span dots or slashes. Exact, same-origin, path-prefix, and single-label
wildcard matches are preserved; only the previously-exploitable path-injection
spoof and multi-level-wildcard span are now rejected (standard wildcard-cert
semantics). Adds regression tests for the path-injection, multi-label, and
embedded-slash bypasses.

Scope: grepped all `.replace(/\*/g, '.*')` sites — the others are glob→regex
matchers for memory keys / event names / worker patterns (not hostname
validation) where `.*` is intended; only the auth redirect validator is affected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 20:00:25 +00:00
Dragan Spiridonov ad30937ed8 chore(release): bump version to v3.12.0 2026-07-10 19:28:03 +00:00
Dragan Spiridonov 7537fefb4e feat(doe): definitive 27/27 DoE re-run via OpenRouter — real F-tests + persisted raw data
Completes and supersedes the 2026-07-09 directional DoE (which was 25/27 cells, had
no F-test, and — the reproducibility gap found this session — never persisted its raw
data). Re-run full under the CRIT-2 design (N=5 stochastic replicates of fixed item
A1-inRange, real within-cell error term), qwen local $0 + anthropic/claude-haiku-4.5
+ anthropic/claude-opus-4.8 via OpenRouter. $1.538 total, well under the $11 budget.

Results (real main-effects ANOVA, 135 observations, first real data the aggregator
has ever consumed — previously stub-only):
- scaffold: none 1.000 >> plan-and-solve 0.311 >> reflexion 0.067
    F(2,108)=218.9, p=1.0e-38, 71.9% of variance — DOMINANT and strongly NEGATIVE.
    Both scaffolds DROP. retort's "more harness lowers reliability", now overwhelming.
- model: qwen3-coder:30b 0.644 > haiku-4.5 0.400 > opus-4.8 0.333
    F(2,108)=25.1, p=1.1e-9 — local qwen best & free; opus 5x+ cost = negative value.
    (Complete 27/27 reverses the prior unequal-n haiku>opus>qwen ordering, significantly.)
- retrieval: off 0.480 > on 0.433  F(1,108)=1.5, p=0.22 NOT significant, slightly
    negative — the ADR-118 flywheel feature-on-trial formally fails as `beads`.
    EXPLAINED by the 2026-07-10 coupling finding: A1-inRange is a no-headroom item
    the models know cold, so a retrieved exemplar has nothing to add.
- prompt: TDD 0.533 > ATDD 0.467 > neutral 0.378  F(2,108)=5.7, p=4.5e-3.

Changes:
- scripts/doe-run.ts: cloud path rewired from raw Anthropic fetch to OpenRouter
  (vendor/model ids, opus-4.8 not opus-4-7, exact per-call cost from usage.cost).
- docs/implementation/doe-run-2026-07-10.jsonl: raw per-cell data persisted IN-REPO
  (fixes the gap that lost the 2026-07-09 run's data).
- DOE-HARNESS-SCREEN-DESIGN.md §Results (DEFINITIVE) + ADR-122 status/history updated;
  prior directional run retained, marked SUPERSEDED.

Verified: tsc 0 errors; $0 --stub and --smoke pipelines green before the metered run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:28:55 +00:00
Dragan Spiridonov 68c8914f92 feat(learning-integrity): live coupling validation closes CRIT-1 — mechanism real but headroom-gated
Runs the CRIT-1 coupling experiment live on qwen3-coder:30b (Ollama, $0) and
characterizes EXACTLY when the ADR-118 flywheel's retrieval helps generated tests.

Result (N=5/condition, mutation-oracle graded, end-to-end "runs∧kills" response):
- POSITIVE CONTROL (POS-reserved — an arbitrary system-specific rule the model
  cannot know a priori, a proxy for project-specific corpus knowledge):
    NONE 0.00 / IRRELEVANT 0.00 / RELEVANT 1.00  →  gain +1.00  COUPLING VALIDATED.
  Without the exemplar qwen can't even write a passing test; with it, a perfect one.
- TEXTBOOK (B4-isLeapYear — the century/400 rule):
    NONE 1.00 / RELEVANT 1.00  →  NO HEADROOM (the model knows the trap cold).

Conclusion: the coupling mechanism is REAL (the harness demonstrably detects it, so
its nulls are live measurements) but HEADROOM-GATED — retrieval improves tests iff
the corpus supplies knowledge the base model lacks. Generic QE edge cases are
already known to code models (30b AND 7b), which is WHY the ADR-122 DoE rated
retrieval `beads`. This explains the prior honest nulls rather than contradicting them.

Getting here required fixing three measure-the-measurement traps that had produced a
FALSE "no coupling" verdict on the first run:
- baseline floored by 500-token truncation (→ 1400) and empty-input over-reach;
- spec leaked the trap (anchor inputUnderTest spells out the edge) → no headroom →
  switched to UNDER-SPECIFIED specs graded against the frozen trap-encoding reference;
- metric conditioned on baseline, hiding retrieval's strongest effect (rescuing a
  test that otherwise can't be written) → switched to end-to-end usable-quality.

Also:
- OpenRouter wired as the cloud path (vendor/model ids; anthropic/claude-haiku-4.5
  et al. confirmed reachable), replacing the rate-limited Anthropic-direct fetch.
- coupled-anchor.test.ts: adds an honest AQE_LIVE_COUPLING-gated end-to-end test that
  fails loudly (never fabricates a pass) rather than asserting the mechanism the
  scripted unit test only assumes.
- ADR-118 status → "INFRASTRUCTURE WITH A CHARACTERIZED SIGNAL": the flywheel's
  retrieval-tuning pays off iff qe_patterns holds knowledge the base model lacks.

Verified: tsc 0 errors; coupled-anchor 1 passed + 1 skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 14:40:45 +00:00
Dragan Spiridonov df183d1ea4 fix(learning-integrity): remediate brutal-honesty-review findings on ADR-117..122
Addresses the CRITICAL/HIGH/MED findings from the brutal-honesty review of the
learning-integrity cluster. The theme: the machinery was real but several claims
outran the evidence. This makes the claims honest and the evidence falsifiable.

CRIT-1 / HIGH-3 (flywheel gated vapor / toy anchor can't move):
- verification/anchors/qe-anchor-v2.json — 5 oracle-verified DISCRIMINATING items
  (13 mutants), each with a trap edge a happy-path test misses, so the anchor CAN
  actually move. v1's items were too easy to discriminate a retrieval effect.
- scripts/coupling-experiment.ts — falsifiable NONE/IRRELEVANT/RELEVANT controlled
  test (N reps, temp>0, $0 mutation-oracle grading). Live run remains blocked on
  model availability; the harness refuses to fabricate a verdict.

CRIT-2 (DoE "stats" were a range proxy):
- scripts/doe-run.ts — N real replicates of a FIXED item at temp=0.6 (was 5
  different items x1 at temp=0), per-replicate seed, plus a deterministic $0 --stub.
- scripts/doe-aggregate.mjs — real main-effects factorial ANOVA: within-cell error
  term, F-test via dependency-free regularized incomplete beta; beads verdict now
  gates on p<0.05, not an eyeballed mean delta.
- tests/unit/scripts/doe-aggregate.test.ts — F-CDF + incomplete-beta vs closed
  forms/R, planted-effect recovery (p<0.001), null factor (p>0.5), unbalanced cells.

HIGH-4 / MED-6 (over-claimed gate guarantees):
- ADR-120 gains a "Threat model and limits (honest)" section: gateReExecutes
  catches a lying log, not a buggy gate (same-process seal+rule).
- ADR-118 status reframed to "infrastructure awaiting a validated signal."
- tests/unit/validation/rule-consistency.test.ts — property test scoping what the
  gate actually guarantees (determinism, stable fingerprints, flipped-verdict).
- DOE-HARNESS-SCREEN-DESIGN.md — unequal-n note.

HIGH-5 / MED-7 (self-fulfilling test / brittle scripts):
- tests/unit/learning/mmr-scaling.test.ts — FALSIFIABLE regression for the real
  O(n^4) scoreHeldOut hang the MMR_POOL_SIZE cap fixed (96s->420ms at n=300).
- coupled-anchor.test.ts de-faked: relabeled as a MECHANISM/wiring test, documents
  that the scripted generator hardcodes the outcome and the real model was an
  honest null — no longer readable as evidence that coupling helps.
- tests/unit/validation/sealed-hash-roundtrip.test.ts — regression for the
  canonicalJson undefined-key seal bug.

Verification: tsc 0 errors; 33/33 new remediation tests + 290/290 full
validation+flywheel cluster green. No live model run (Ollama offline + Anthropic
account at usage limit) — coupling live-validation surfaced as the one honest
open item, not faked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 14:12:31 +00:00
Dragan Spiridonov e26ad5557a fixing memory issues 2026-07-10 13:46:41 +00:00
Dragan Spiridonov 5ba27ba697 chore: gitignore ruflo audit-worker reports + WAL-monitor artifacts
The ruflo daemon's audit worker (now disabled) dumped 9 inconsistently-named
LLM-generated SECURITY_AUDIT_*.json / security-audit-*.json reports to the repo
root — headline "hardcoded secrets" was a false positive (public SauceLabs demo
creds), the rest unverified/inconsistent LLM noise. Ignore the pattern so future
stray reports don't clutter git status. Also ignore the option-C WAL-monitor
local artifacts (.agentic-qe/wal-monitor.*, *.moncopy-*).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 20:47:19 +00:00
Dragan Spiridonov 7694f69258 fix(doe): handle unclosed code fences in doe-run stripFence
The reflexion critique-and-revise step sometimes emits an opening ```javascript
fence with no closing ```; the old match-a-closed-block regex then left the fence
line in the generated test → a syntax error → false baseline failure. Strip fence
lines directly so unclosed fences no longer inflate cell failures. Verified
2026-07-09: does not change the ADR-122 scaffold verdict (reflexion's hit is a
genuine over-iteration effect), only removes cross-cell noise.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 19:09:44 +00:00
Dragan Spiridonov 0a8254f7a9 feat(learning): ADR-117..122 learning-integrity cluster (frozen anchor, two-gate judge, gate-reexecute, provenance tiers, receipt-gated flywheel, DoE)
Adopts the receipt-gated self-improvement discipline from the 2026-07 cross-repo
analysis of ruflo (flywheel), MetaHarness (gateReExecutes), and retort (two-gate
spec conformance + DoE). All DI'd and unit-tested (178 tests); run end-to-end on
real qe_patterns; every limitation honestly scoped.

- ADR-117 frozen oracle anchor: hash-pinned, constant-denominator eval set that
  no promotion may regress; loader throws on drift (verification/anchors/qe-anchor-v1.json).
- ADR-118 receipt-gated QE-policy flywheel: generational loop over qe_patterns,
  conjunctive frozen accept(), Ed25519-signed receipts + compounding lineage,
  durable persistence (flywheel_receipts), corpus + semantic-retriever coupling.
- ADR-119 two-gate quality verdicts: mechanical gate + frontier judge, three-valued
  (pass/fail/inconclusive) with preflight; new `aqe quality-gate` CLI + `qe/quality/gate` MCP tool.
- ADR-120 gateReExecutes: re-execute a versioned frozen rule on sealed inputs;
  catches the A8-EXT forged-promote class; retrofit onto pattern-promote + dream-apply.
- ADR-121 provenance tiers: only oracle:test-exec evidence changes fleet behavior;
  additive, conservative-backfill migration.
- ADR-122 DoE screen: model x prompt x retrieval x scaffold, run on real data
  (25/27 cells, $1.25) — scaffolding (esp. reflexion) and retrieval degrade
  reliability (the retort `beads` signature); simplest+cheapest stack wins.
- safe-db: AQE_DISABLE_WAL / AQE_JOURNAL_MODE env-gate (macOS virtiofs bind-mount
  WAL corruption mitigation; default behavior unchanged).

Honest nulls documented: the flywheel lift is on a self-supervised proxy with the
anchor held flat; making the coupled anchor move needs harder items + a relevant
corpus (an ADR-117 re-freeze), not a retriever change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 10:26:54 +00:00
Dragan Spiridonov ce1222a7c4 fix(learning): stop brain-export hook leak + harden DB backups on virtiofs mount
Real-time hook learning-capture was failing on this macOS Docker bind mount
with `Failed to initialize UnifiedMemoryManager: database is locked`, and a
brain-checkpoint hook was leaking deadlocked `brain export` subprocesses
(4 found, ~1.5GB RSS). Root cause is SQLite concurrency on a WAL-hostile
virtiofs mount, NOT a native-binary mismatch (better-sqlite3 loads fine).

- brain-checkpoint.cjs: add AQE_DISABLE_BRAIN_CHECKPOINT env / marker-file kill
  switch (opt-in; shipped installs unaffected). The export spawns a native RVF
  writer that deadlocks in a futex and ignores the SIGTERM the timeout sends,
  so orphaned exporters piled up. Disabling stops the leak at the source.
- aqe-hook.cjs: make the FATAL health-log fix-hint conditional. Only suggest
  `npm rebuild better-sqlite3` for real native markers; lock-contention
  failures now point at the actual cause instead of sending users down the
  wrong path.
- feature-flags.ts: add the missing RUVECTOR_USE_RVF_PATTERN_STORE env override
  (the only RuVector flag lacking one) so an RVF FsyncFailed can fall back to
  the SQLite HNSW PatternStore. Activates after build.
- scripts/aqe-db-backup.sh: consistent VACUUM INTO snapshots (safe with
  concurrent writers), integrity-verified before promotion, rotating + daily,
  to the host mount so they survive container loss. Restore round-trip tested.
- devcontainer.json: auto-restart the backup loop (postStartCommand) and set
  bind-mount env mitigations (remoteEnv: AQE_DISABLE_WAL,
  RUVECTOR_USE_RVF_PATTERN_STORE=false, AQE_DISABLE_BRAIN_CHECKPOINT).
- learning-config.json: clear the stale rebuildMode flag (no src reader; on
  since 2025-12).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:22:43 +00:00
Dragan Spiridonov 3a5cfd4201 Merge pull request #555 from proffesor-for-testing/working-july
chore(release): v3.11.5
v3.11.5
2026-07-07 10:18:31 +02:00
Dragan Spiridonov 235ed8df0f chore(release): bump version to v3.11.5
Bumps package.json + package-lock + skills-manifest fleetVersion to
3.11.5. Also fixes .claude-plugin/plugin.json and
assets/skills/skills-manifest.json fleetVersion, which had drifted
stale at 3.11.0 across the last 4 releases (found via full-repo
version-string audit).
2026-07-07 07:47:50 +00:00
Dragan Spiridonov a454889099 chore: clean up dead DB rows, fix pre-existing GOAP lint errors, track remaining work
- Backup-verified cleanup of .agentic-qe/memory.db: 200/200 degenerate
  mincut_snapshots rows, 501/501 degenerate mincut_history rows, 530/530
  test-fixture execution_results rows, 705/705 test-fixture executed_steps
  rows (all confirmed 100% junk before deleting); corrected 72
  dream_insights.applied rows corrupted by the now-fixed counter bug back
  to the correct boolean value. Full backup + before/after row counts +
  integrity check per data-protection policy.
- Fixed 4 unused-vars lint errors in goap-planner.ts/goap-execute.ts
  (2 pre-existing + 1 that surfaced after removing the first + 1 in
  goap-execute.ts). Left two genuinely unimplemented stub params
  (updateActionStats duration tracking, findSimilarPlan fuzzy matching)
  honestly marked rather than scope-expanded.
- Filed proffesor-for-testing/agentic-qe#554 to track everything from the
  system-integrity remediation that's deliberately deferred, so it isn't
  silently dropped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 17:18:19 +00:00
Dragan Spiridonov f8ab72a320 fix(learning): fix pattern-usage double-write, id desync, and non-monotonic stats
Three compounding bugs in the recordOutcome()/storePattern() path, found
while chasing a flaky qe_pattern_usage-count test:

- recordOutcome() wrote pattern usage twice per outcome: once via
  patternStore.recordUsage() (which already persists to the wired
  SQLitePatternStore) and again via an explicit direct SQLite call added
  only to carry metrics/feedback (which the interface didn't accept).
  Threaded metrics/feedback through IPatternStore.recordUsage() instead
  and removed the redundant write — every outcome was inflating
  qe_pattern_usage row counts and qe_patterns.usage_count by 2x.

- PatternStore.store() (in-memory backend) never applied the #447 fix
  that RvfPatternStore already had: when ON CONFLICT(name, qe_domain,
  pattern_type) preserves an existing row's id, the in-memory indices
  kept using the discarded id, so every later recordUsage()/promote()/
  delete() call silently failed against SQLite with "Pattern not found".

- SQLitePatternStore.storePattern() resolved the ON CONFLICT-preserved id
  AFTER the insert transaction, but inserted the embedding using the
  discarded id INSIDE the transaction — violating the
  qe_pattern_embeddings -> qe_patterns(id) foreign key whenever a pattern
  name collided with an existing row. Now resolves the actual id before
  the embedding insert, in the same transaction.

- QEReasoningBank.getStats() only consulted the DB aggregate when the
  in-memory counter was exactly zero, so reported totals regressed the
  moment in-memory ticked past zero mid-session (a cold-start call
  correctly showed the historical DB total; the next call after one
  recordOutcome() dropped to reporting "1"). Since qe_pattern_usage is
  written synchronously, the DB aggregate is always >= the in-memory
  counter — now takes the max of the two, keeping the number monotonic.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 13:43:58 +00:00
Dragan Spiridonov b7d575461d fix(learning): source RvfPatternStore.getStats() from SQLite, not RVF vector count (#553)
qe_patterns is the source of truth for pattern count and domain/tier
breakdown; the RVF/HNSW vector index only covers patterns that have
been embedded, so getStats() silently hid any pattern stored without
a matching embedding (aqe learning stats reported the vector count as
Total, and "By Domain" was hardcoded empty).

Also fixes the rvf-pattern-store.test.ts Stats test to attach an
isolated non-unified SQLite store per test — needed once getStats()
started reading real SQLite data, since the auto-attached ADR-046
unified store is a process-wide singleton shared across test files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 13:07:40 +00:00
Dragan Spiridonov 53ee377aec fix(learning): close system-integrity audit gaps in dream engine, witness chain, mincut, GOAP executor, and SONA
Full remediation of docs/analysis/SYSTEM-INTEGRITY-AUDIT-2026-07-04.md's
P0-P2 findings, tracked in docs/plans/SYSTEM-INTEGRITY-REMEDIATION-GOAP-PLAN-2026-07-04.md.

Highlights:
- Dream engine: real pattern creation on insight apply, error/outcome
  concept nodes from real ADR-110 data, and a follow-up fix ensuring the
  concept refresh actually runs on the real automatic path (not just via
  test wrappers); persistTaskOutcome now genuinely promotes pending
  insights instead of blindly incrementing an applied counter
- Witness chain: Ed25519 signing wired via persistent key directory,
  archival/append-after-archival bug fixed, CI verification gate added
- Mincut: real event-bus wiring (was a no-op stub) and scaffold-vertex
  detection fixes
- GOAP: real domain-API dispatch executor replacing the always-mock one
- SONA: EWC++ cold-start deadlock fixed via independent request-count
  persistence
- ADR-110 pattern-nulls wired into the real production capture path
- Daemon/snapshot visibility, TTL unit bugs, and 8 ADRs re-statused with
  additive verification notes

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 12:18:00 +00:00
Dragan Spiridonov a010038834 Merge pull request #552 from proffesor-for-testing/feat/local-model-improvements
chore(release): v3.11.4
v3.11.4
2026-07-01 09:50:51 +02:00
Dragan Spiridonov a92d25847a fix(security): eliminate two ReDoS regexes flagged by CodeQL
CodeQL flagged 'polynomial regular expression on uncontrolled data' in two
branch-new files:

- ollama-url.ts: trailing-slash strip `/\/+$/` backtracks O(n^2) on many
  '/'. Replaced with a linear charCodeAt scan.
- pattern-cache.ts: block-comment strip `/\/\*[\s\S]*?\*\//g` backtracks
  O(n^2) on unterminated '/*' (46s on a 300k adversarial input). Replaced with
  a single-pass indexOf('*/') scanner.

Both are behavior-identical to the originals on all normal/edge cases (verified)
and now run in <5ms on the adversarial inputs. 14 affected tests pass; typecheck
clean. Fixes code-scanning alerts 212 & 213.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 07:24:33 +00:00
Dragan Spiridonov e058c94fa5 chore(release): bump version to v3.11.4
3.11.4 = the local-model-improvements branch (LLM/Ollama plumbing, free-tier
local test-gen, proof-gate ADR-116) + the already-merged dependency-security
system (ADR-115). Merged origin/main in first so the release carries the
grpc-js HIGH fix and moderate-CVE reductions rather than regressing them.

Bumps package.json + package-lock + skills-manifest fleetVersion to 3.11.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 06:38:12 +00:00
Dragan Spiridonov 9ca2c128ef Merge remote-tracking branch 'origin/main' into feat/local-model-improvements 2026-07-01 06:24:12 +00:00
Dragan Spiridonov f2742c8651 docs(adr): add ADR-116 for proof-gate + cross-ref from code
The proof-gate work cited only upstream RuVector 'ADR-194' — which is not an
AQE in-repo ADR. Adds ADR-116 (the AQE-side integration decision: port the
hash-chain to TS, opt-in/fail-soft/single-store wiring, and why NOT to depend
on the @ruvector npm packages — backed by the verified ruvllm mock-mode/demo
findings) and cross-references it from the four source/test files that cite
ADR-194, so the in-repo decision is discoverable from the code.

Comment/docs only — no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 06:22:43 +00:00
Dragan Spiridonov ef20d868d0 Merge pull request #551 from proffesor-for-testing/feat/dependency-security-system
feat(deps): dependency-security system + fix grpc-js HIGH (ADR-115)
2026-06-30 16:52:00 +02:00
Dragan Spiridonov 75286a146d chore(deps): apply in-range security updates — moderates 29 -> 7 (ADR-115)
Runs the new `npm run deps:update` (security mode: npm audit fix
--package-lock-only) — the system applied to its own repo. Fixes the
@opentelemetry/* advisory family (W3C Baggage unbounded-memory) and bumps
the @claude-flow/* alpha chain, all within existing semver ranges.

In-repo audit: moderate 29 -> 7; high/critical stay 0.
Large diff is npm dedup: the @claude-flow/memory bump (alpha.14 -> alpha.21)
collapsed nested duplicate transitive trees (844 -> 807 lock entries).
Optional @ruvector platform deps verified intact (15/15) by the updater guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 12:20:02 +00:00
Dragan Spiridonov 6dcb919aee feat(deps): dependency-security system + fix grpc-js HIGH (ADR-115)
Closes the gap that let @grpc/grpc-js@1.14.3 (CVE-2026-48068/48069, HIGH)
sit undetected: every existing dependency check only fires on dep-file
changes, so a CVE disclosed against a frozen pin was invisible.

Adds:
- scripts/dependency-audit.mjs    in-repo + consumer-POV audit, severity gate
- scripts/dependency-update.mjs   security-first in-range updater with a guard
                                  that refuses to drop optional @ruvector
                                  platform deps (the Dependabot lockfile bug)
- dependency-audit.yml            daily consumer-POV scan -> tracking issue
- dependency-update.yml           weekly in-range security PR (gh CLI)
- docs/guides/dependency-security-policy.md + ADR-115
- tests/unit/scripts/dependency-security.test.ts (11 hermetic tests)
- npm scripts: deps:audit[:consumer], deps:update[:all]

Also bumps @grpc/grpc-js 1.14.3 -> 1.14.4 in-range (HIGH 1 -> 0); optional
platform deps preserved (90 -> 90).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 12:18:21 +00:00
Dragan Spiridonov d9d853de45 feat(integrity): wire proof-gate into the live memory.db kv path (ADR-194)
Wires the HashChainGate primitive into UnifiedMemoryManager so kv writes can
be cryptographically audited end-to-end. Design is audit-only and safe for the
production path:

- OPT-IN: off by default; enable per audit window via enableProofGate() or
  AQE_PROOF_GATE=1 (the chain grows O(n) with writes, so it is meant for
  bounded sync/migration/publish windows, not permanent always-on use).
- FAIL-SOFT: kvSet/kvDelete admit a content-bound receipt AFTER the row is
  written, wrapped so an audit failure can never break or alter the write.
- NO RE-ENTRANCY: the chain persists via a direct write to a reserved
  namespace (__proofgate__), never through kvSet, and that namespace is never
  itself audited.
- UNIFIED STORE: the chain serializes into the same memory.db (kv_store), no
  second store; it restores on the next process so audits survive restarts.

verifyMemoryIntegrity() re-derives the chain from genesis, turning the
"verify row counts before/after, never claim a sync succeeded without proof"
mandate into a tamper-evident guarantee. 7 tests: no-op-when-disabled,
one-receipt-per-write, reserved-ns-not-self-audited, root-advances,
persist+restore across restart, mutated-chain detection, and env auto-enable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 11:45:11 +00:00
Dragan Spiridonov de4b7b089b feat(integrity): proof-gate hash-chain audit (ruvector reuse) + coder bench data
Adds a dependency-free TS port of ruvector-proof-gate's HashChainGate
(ADR-194): admit one tamper-evident receipt per memory.db operation;
verifyIntegrity() cryptographically re-derives the chain to prove no
admitted entry was mutated, reordered, or dropped — turning the project's
"verify row counts before/after, never claim a sync succeeded without
proof" mandate into a guarantee. Uses Node crypto only, opens no DB (chain
serializes via toJSON/fromJSON for persistence through the unified store).
7 tests mirror the Rust crate's tamper cases + a persistence round-trip.
Delivered as a primitive; NOT yet wired into live memory.db paths.

Also records the 2026-06-29 small-coder oracle measurements in
value-score.ts: qwen2.5-coder:7b=0.50 (4/8, beats general 8B at 38%) and
1.5b=0.08 — the curve motivating a PEFT-on-7B spike.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:51:28 +00:00
Dragan Spiridonov db2db9dab8 feat(free-tier): default local test-gen model qwen3:30b-a3b -> qwen3-coder:30b
2026-06-29 oracle bench (8 fixtures, mutation>=60%) on the same Mac Ollama:
qwen3-coder:30b and qwen3:30b-a3b score IDENTICALLY (both 6/8, 75% avg
mutation kill, same fixtures pass/fail) — same 30B MoE class and RAM — but
the code-tuned model is ~14x faster wall-clock (5.2s vs 71.1s/gen) because
it does not spend ~70s "thinking" before answering.

Records both measurements in value-score.ts (incl. stock qwen2.5-coder:1.5b
= 1/8, confirming size still dominates coder-tuning at tiny scale). qwen3:8b
stays off-default (3/8 across the same fixtures).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 13:16:40 +00:00
Dragan Spiridonov 36b506aea5 feat(free-tier): ruvLLM-style pattern-cache skip for test-gen (#6)
Adds TestGenPatternCache (exact normalized-source match + cosine-similarity
tiers, injectable embedder, in-memory — no new DB, respects the unified
memory ADR) and wires it into the free-tier executor as an opt-in gate.

Safety: a cache hit is only a candidate — it is re-verified by the same
objective oracle before use, so a stale/wrong hit falls through to real
generation and can never bypass the gate. Only verified outputs are cached.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 11:39:55 +00:00
Dragan Spiridonov b61e19188b feat(llm): register qwen3 models + capability-aware tool routing guard (#1)
Registers qwen3:8b, qwen3:30b-a3b, qwen3-coder:30b in model-mapping
(so normalizeModelId resolves the tags) and model-registry with correct
capability flags (coder = tool-capable, non-thinking).

Adds modelSupportsTools() (fail-open on unknown ids) and a guard in the
hybrid router: when a request requires tools, candidates KNOWN to be
tool-less are skipped (with a warning) instead of silently dropping tool
definitions. Never strands a request — falls open if no candidate qualifies.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 11:39:55 +00:00
Dragan Spiridonov 6174652c57 feat(llm): unified AQE_OLLAMA_URL + adaptive Ollama timeouts (#2, #3)
#2: single resolveOllamaBaseUrl() knob (AQE_OLLAMA_URL > OLLAMA_URL >
each call-site default) wired into all local clients — chat provider,
consensus provider, local judge, embeddings, free-tier. Unset = identical
behavior; one var now repoints every client at a remote/host Ollama.

#3: size each Ollama request timeout from num_predict and the model's
observed tok/s (EMA) instead of a fixed 120s, so slow dense/thinking
models (~15 tok/s measured) no longer silently time out mid-generation.
Explicit/configured timeouts still win.

Adds scripts/oracle-model-bench-local.ts (local mutation-oracle bench).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 11:39:55 +00:00
Dragan Spiridonov 219664780c Merge pull request #548 from proffesor-for-testing/feat/oracle-evals-and-conservation-guard
chore(release): v3.11.3
v3.11.3
2026-06-28 08:55:45 +02:00
Dragan Spiridonov eead05dbbf chore(release): bump version to v3.11.3
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 16:27:58 +00:00
Dragan Spiridonov 0f418231c9 feat(conservation): gate plugins (strict mirror) + .kiro (presence); add --sync resync
Close the biggest remaining drift gap (ADR-114 follow-up).

- skill-parity now gates plugins/agentic-qe-fleet/skills as a strict body-mirror alongside
  assets/skills; reconcileBody + `check-skill-parity --sync` resync drifted mirrors while
  preserving each tree's frontmatter (used to fix the plugins qe-quality-assessment drift)
- .kiro/skills is an intentionally divergent 86-skill variant (qe- prefixed, some large
  .kiro-only bodies) — gated by PRESENCE via the conservation guard's kiro-skills surface,
  not body-equality (which would destroy the divergence)
- both guards (verify:skill-parity blocking, verify:conservation non-blocking) wired into
  invariant-check.yml with plugins/.kiro paths; policy doc updated
- tests: reconcileBody/splitFrontmatter covered; 16 validation tests pass

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 15:56:52 +00:00
Dragan Spiridonov af4140efb9 feat(quality): oracle evals, durable-first tests, conservation guard + provider fixes
Apply Phoenix Architecture principles to AQE — regenerate internals, conserve the interface.

ADR-113 (evals are oracles, durable-first tests, mutation-score gate):
- src/validation/oracle-eval.ts grades a generated test by running it against a
  reference impl + operator mutants (reuses qe-arena, ADR-104); rejects assertion-less output
- oracle mode wired into scripts/run-skill-eval.ts (skips under the simulating runner; runs live)
- qe-test-generation rewritten durable-first; its eval flipped to oracle
- src/feedback/regenerability-gate.ts: mutation-score + regenerability gate (warn-default, opt-in block)
- live-validated: Claude sonnet-4-6 clears the oracle 5/5; weak local-model output correctly fails

ADR-114 (conservation layer, Phoenix essay 14):
- src/validation/conservation-guard.ts + scripts/conservation-guard.ts guard CLI commands,
  output schemas, and dashboard API against breaking removals (deprecation registry exempts)
- policy doc + baselines in verification/conservation/; wired into invariant-check.yml non-blocking

LLM provider fixes:
- OpenRouterProvider.type was 'openai' but registered under 'openrouter' -> ProviderManager
  failover never found it; fixed to 'openrouter' end-to-end
- Gemini default model gemini-1.5-pro was retired -> gemini-2.5-flash; models/pricing refreshed
  from the live Gemini ListModels API
- scripts/provider-health.ts (npm run providers:health)

Cheaper-model eval lanes:
- scripts/oracle-model-bench.ts + openrouter-models.ts; openai/gpt-oss-120b clears the oracle
  ~50-70x cheaper than Claude Sonnet; guide in docs/guides/cheaper-model-eval-lanes.md

Verification: npm run build ok; 115 new+touched tests pass; 724 LLM tests pass; lint + parity clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 15:37:46 +00:00