Files
james.maesandClaude Opus 4.7 5ebe510627 docs: scrub Phase-7 + JarvisBusWorld doc drift (#19, #45) (#195)
* docs(memory): scrub Phase-7 hedge language from MemoryStore (#19)

Audit 2026-05-12 flagged five doc-comment references that mis-described
the implementation state. The cited plans (07-02, 07-03, 07-06) shipped
months ago — the bounded extraction channel, the hybrid FTS5 + vec0 read
path, the ReplayEvent emission, the regression corpus test seams, and
`installMemory`'s replay-sink wiring are all live, not "wires" or
"will replace" promises.

Five touchpoints rewritten to describe the code as it is:

- `MemoryReplaySink` doc: drop the "Plan 07-06" plan reference; the seam
  is just used at startup.
- `MemoryStore` actor doc: replace the "Plan 07-02 wires / Plan 07-03
  wires" sentence with the actual contract (single writer; hybrid search
  through `MemoryReadStore`; `recordRetrieval` emits `memoryRetrieval`).
- Read-path MARK: drop the "Plan 07-03" plan label; keep the
  requirement-ID list (MEM-07 / TEXT-03 / D-02 / D-05) since those are
  still useful for traceability to the audit corpus.
- `recordRetrieval` doc: replace "Mirrors recordMemoryMutation from 07-02"
  with "Mirrors recordMemoryMutation on the write path."
- Test-seams MARK: drop "Plan 07-06" prefix; describe by the test target
  (JARVIS_REAL_MODELS=1 corpus suite) instead.

The 2026-05-11 D-5/D-6 markers and the "Boot policy (changed 2026-05-11)"
doc are preserved unchanged — they document current behaviour, not
historical hedges.

`swift build --package-path packages/Memory` clean.

Closes #19

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(bus): scrub JarvisBusWorld drift + add grep gate (#45)

`fb41c5f` (2026-05-02) unified `Injection.js` and the HUD bundle into the
default `WKContentWorld.page` and retired the prior isolated
`JarvisBusWorld` named world. The doc-comments and test fixtures across
20+ lines kept describing the bug-era topology — pre-existing-bus attach
"because cross-world isolation", message-handler-only-visible-in-named-
world, etc. — for months afterward. Result: a new reader following the
docs would conclude the bus uses two worlds when it actually uses one.

Five rationale rewrites:

- `WebviewBridge.swift` class doc — handler is on the page world, not an
  isolated named world. Page scripts in the loaded HUD bundle address it
  via `window.webkit.messageHandlers.jarvisBus`.
- `Injection.js` header — names the page world explicitly; one-line nod to
  `fb41c5f` for the historical context.
- `bridge.ts` JSDoc + `isJarvisBusShape` rationale — recast the H-02
  attach-to-existing path as a "defensive double-install guard" inside
  ONE page world. Injection.js fires first at document-start; the bundle
  installer fires later as a top-level `main.tsx` side-effect; the guard
  prevents the bundle from clobbering Injection.js's queued early
  messages and captured handshake state. The duck-type `isJarvisBusShape`
  CODE is unchanged — only the comment narrative was misleading.
- `webview/packages/hud/src/main.tsx` — drop the cross-world-isolation
  framing; describe the single-world reality.
- `App/AppDelegate.swift` install comment — page world, not isolated.

Test-side updates (same scrub, plus one latent test bug surfaced):

- `WebviewBridgeTests.test_scriptMessageHandlerIsRegisteredUnderConfigured-
  Name`: was removing from `WKContentWorld.world(name: "JarvisBusWorld")`
  while the bridge registered against `.page` — silent no-op since
  `removeScriptMessageHandler` doesn't throw on absent. Now removes from
  `.page` (the world the bridge actually uses), making the
  "registration-is-evidence-of-success" assertion meaningful again.
- `WebviewBridgeOutboundTests`: comment-only.
- `RealWKWebViewIntegrationTests`: comment-only (forensic narrative kept,
  literal world name replaced with "prior isolated named content world").
- `webview/packages/bus/tests/bridge.test.ts`: H-02 describe-block + one
  it-name rewritten to match the new defensive-double-install rationale.

Infrastructure:

- `scripts/check-no-jarvis-bus-world-references.sh`: new boundary gate.
  Greps for the literal `JarvisBusWorld` in tracked files; excludes
  `.planning/`, `docs/`, `webview/packages/*/dist/`, and this script
  itself. Wired into `CLAUDE.md`'s gate listing; the CI
  `boundary-gates` job auto-discovers all `scripts/check-*.sh`, so no
  workflow edit is needed.
- `webview/packages/bus/package.json`: 0.0.0 → 0.0.1 (per spec —
  comment-only changes still bump patch so consumers can pin).
- `webview/packages/bus/dist/bridge.{js,d.ts}`: rebuilt via `pnpm --filter
  @jarvis/bus build`; NOT committed because `dist/` is not tracked (the
  build phase regenerates on each xcodebuild invocation).

Verified locally:
- `swift build --package-path packages/Bus` clean
- `pnpm --filter @jarvis/bus test` — 37/37 pass
- `bash scripts/check-no-jarvis-bus-world-references.sh` — PASS
- `bash scripts/check-bus-protocol-version.sh` — PASS (v2.3.0)
- `bash scripts/check-bus-harness-parity.sh` — PASS

Closes #45

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:51:03 -05:00
..

Memory

Long-term fact store + extraction pipeline. SQLite (FTS5 + sqlite-vec) at ~/Library/Application Support/Jarvis/jarvis.db; mem0-style ADD/UPDATE/NOOP extraction; hybrid keyword + vector search via Reciprocal Rank Fusion.

Functional state. Memory is code-complete but functionally OFF until vec0.dylib ships (Track D-5/D-6 — user environment work) and ollama pull nomic-embed-text runs (D-7). installMemory degrades gracefully — extractor + orchestrator + coordinator construct even when MemoryStore init throws.

Key public types

Type Purpose
MemoryStore (actor) The only writer of jarvis.db. Opens with WAL, loads vec0.dylib, runs migrations
MemoryExtractionOrchestrator (actor) Bounded-channel + serial-drain extraction Task
MemoryExtractionCoordinator AppDelegate-side coordinator that listens to OrchestratorEvent.turnEnd
MemoryExtractor Calls Qwen 2.5-Coder via Ollama; emits ADD / UPDATE(supersedes:) / NOOP
MemoryPrompts Prompt templates for the extractor
HybridSearch (actor) FTS5 + vec0 RRF SQL; emits ReplayEvent.memoryRetrieval per fact
OllamaEmbeddingClient nomic-embed-text 768-dim embeddings
Fact / FactRef / ExtractionJob Plain-data types
MemoryEvent Stream events — factAdded, factUpdated, factForgotten, retrieval
SessionHistory Session-scoped recent-turn browse (TEXT-03; separate from hybrid search)
MemoryReplaySink (protocol) Test seam over Replay.ReplayLog
PriorFactsLookup Closure type for D-3 — supplies recent active facts to the extractor

Depends on

AgentCore, Replay, Logging. External: swift-log, system SQLite (with custom libsqlite3.dylib carrying SQLITE_ENABLE_LOAD_EXTENSION=1 once D-5 ships).

Used by

App/AppDelegate.installMemory, App/MCP/InProcessMemoryAdapters.swift (bridges to MCP SearchMemoryTool / ForgetFactTool).

Key invariants / contracts

  • MemoryStore is the only writer. All writes go through actor methods.
  • Bounded extraction channel. BoundedAsyncChannel<ExtractionJob>(capacity: 32, policy: .dropOldest). Producers (turnEnd) never block.
  • Single-consumer drain. One serial Task per orchestrator instance.
  • Single-emission grep gates. scripts/check-single-memory-mutated-emit.sh + check-single-memory-used-emit.sh. MemoryStore.recordRetrieval is the only memoryRetrieval emit site.
  • Embedding dim sourced from Constants.swift. scripts/check-embedding-dim-literal.sh forbids hand-typed 768.
  • Temporal validity preserved. UPDATE supersedes by setting valid_to on the prior fact + inserting a new one. No DELETE in the happy path.
  • D-3: priorFacts wiring. MemoryExtractionOrchestrator.process(_:) calls priorFactsLookup (default emptyPriorFactsLookup for back-compat); production wires MemoryStore.recentActiveFacts(limit: 50).
  • T-06-05-03 analog. HybridSearch does NOT log raw query text at debug level (P2-12 fix).

Tests

87 XCTest (19 skipped — vec0/Ollama gating). Includes the RememberBrutusEndToEndTests regression scenario (Track D-4) that proves extraction → store → search end-to-end with fakes.

Notable files

  • Sources/Memory/MemoryStore.swift — actor + SQLite + vec0 loader
  • Sources/Memory/MemoryExtractionOrchestrator.swift — bounded-channel extraction
  • Sources/Memory/HybridSearch.swift — FTS5 + vec0 RRF
  • Sources/Memory/MemoryExtractor.swift — Qwen extractor
  • Sources/Memory/MemoryQueries.swift — SQL definitions