Commit Graph

3 Commits

Author SHA1 Message Date
Dragan Spiridonov 358990cc01 fix(kernel,learning): namespace-aware reads + timestamp rehydration (#491 Bug 2+3)
Issue #491 — even with the worker→kernel wiring restored (Bug 1/4b),
`mineExperiences` mined 0 for every domain on installs with hundreds
of indexed experiences. Two stacked bugs in the learning read path:

Bug 2 — namespace mismatch (the keystone)
=========================================
LearningCoordinator writes every experience with
`namespace: 'learning-optimization'`, but the MemoryBackend
interface only let writers specify a namespace; reads had no such
option. HybridBackend.get/search/has/delete therefore hard-coded
`defaultNamespace='default'`. The coordinator could not read back
its own data — `learning:experience:index:domain:<d>:*` returned 0
keys even when the DB held 81+ matching rows in the
`learning-optimization` namespace.

Fix:
  - Add `RetrieveOptions { namespace? }` to kernel/interfaces.ts
    (symmetric with the existing `StoreOptions.namespace`).
  - Extend MemoryBackend.get/has/delete/search to accept the option
    (backward-compatible — undefined still routes to defaultNamespace).
  - HybridBackend honors the option in all four methods.
  - InMemoryBackend likewise; its `search` now also scopes the scan
    by namespace prefix when one is supplied, so unit-test fakes
    behave the same as the production hybrid backend.
  - All 15 read sites in LearningCoordinator pass
    `LEARNING_NS = { namespace: 'learning-optimization' }`, matching
    the writes that already specified it.

One pre-existing unit test (memory-backend.test.ts) was calling
`backend.get(key, 'test-ns')` against the undocumented positional
namespace param InMemoryBackend used to accept. Migrated it to the
options form — the positional shape was never part of the
MemoryBackend interface.

Bug 3 — Date vs ISO-string in time-window filter
================================================
`recordExperience` stores `timestamp: new Date()`. JSON.stringify
serializes it to an ISO string and JSON.parse does not rehydrate.
`TimeRange.contains` does `date >= start`; in `string >= Date`, the
string coerces to NaN and every comparison is false — so even with
Bug 2 fixed, the window filter would still silently drop every row.

Fix: in `getExperiencesByDomainAndTime`, coerce
`experience.timestamp` to a real `Date` at the kv-read boundary
before calling `timeRange.contains`. Downstream callers receive a
hydrated Experience with a proper Date. We deliberately fix this at
the boundary rather than making `TimeRange.contains` tolerant of
strings — the bug is "kv round-trip drops the Date type", not "the
value object is wrong", and a tolerant comparator would mask future
type drift everywhere else.

Round-trip integration test:
tests/integration/learning/coordinator-roundtrip.test.ts
pins three assertions:
  1. recordExperience → mineExperiences finds the experience back
     (this returned 0 before either fix).
  2. The mined experience's timestamp is a real Date instance, not a
     string (proves Bug 3 fix is at the boundary).
  3. A time window deliberately in the past still excludes recent
     writes (proves we didn't fix Bug 3 by making the filter a
     no-op).

Verified red→green: with Bugs 2+3 reverted (interface kept), tests
1 and 2 fail with `experienceCount=0` and `rows.length=0` — exactly
the symptoms from the issue. With both fixes in place, 3/3 pass in
~30ms. 466/466 kernel unit tests and 335/335 adjacent suites stay
green; the only test that needed migration is documented above.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 08:46:53 +00:00
Dragan Spiridonov fdd32a42ce fix(tests): add vi.useFakeTimers() to 11 files using real setTimeout (#374 P2)
11 test files used real setTimeout without vi.useFakeTimers(), adding
wall-clock time to sequential CI execution. Converted to fake timers
with vi.advanceTimersByTime() for deterministic, instant execution.

Files fixed:
- error-paths/ (5 files): circuit breaker, workflow timeout, consensus
  timeout, task timeout, concurrent init — ~33 setTimeout patterns
- kernel/ (3 files): TTL expiration tests that waited 1100ms real time
- mcp/metrics (1 file): 7 timing-measurement tests
- cli/progress (1 file): 3 ETA estimator tests
- memory/crdt (1 file): convergence time tracking

Estimated CI time savings: ~10s per sequential run.

11 files intentionally skipped (real I/O, production timer logic):
websocket-transport, mcp-server, adr-040, swarm-skill-validator,
plan-executor, parallel-eval-runner, failover, behavior-tree, etc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:52:46 +00:00
Profa 2253d05618 feat: flatten project structure — archive v2, promote v3 to root
Remove the nested v3/ subdirectory by moving all active source code,
tests, configs, and assets directly to the project root. Archive v2/
(dead code, 847MB) to v2-archive.tar.gz.

Key changes:
- Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/
- Move v3/tsconfig.json, v3/vitest.config.ts to root
- Merge v3/package.json into root package.json (ESM, scripts, deps, exports)
- Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/
- Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes
- Fix all init installer path resolution (3-level-up → 2-level-up)
- Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe"
- Update settings.json ADR/DDD directories to docs/implementation/
- Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks)
- Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces
- Update 15 guidance shards: v3/src/ → src/ path references
- Fix sync interfaces: remove v3/ and v2/ path references
- Fix test path calculations (process.cwd() + '..' no longer needed)
- Fix flaky perf test threshold (500ms → 1000ms for CI environments)
- Fix complexity-analyzer test to match ADR-051 keyword-based eligibility

Build passes, 17,901 tests pass, CLI and MCP bundles verified.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:35:41 +00:00