Closes the session that took Jarvis from "wired-but-dead-everywhere" to fully-mapped + branded + license-clear + audit-tracked. Highlights: - Round 2/3/4 strict-mode boot health shipped (probes → status panel → severity model + non-dismissible banners + agent self-awareness preamble + red menu-bar icon). Toby fix verified end-to-end mid-dogfood. - facts.source_turn_id FK dropped (a5999e2) — facts persist now. - Xcode 26 ProcessInfoPlistFile build race fixed (1557302). - Dev Overlay shipped with 4 tabs + live log streaming via LogBroadcaster. - 5-agent audit pass at .planning/audit-2026-05-12/ — ~37 findings. - 141 GH issues filed across audit findings + carry-forwards + M-0..M-7 migration epic (54 sub-issues) + comment-cleanup + v1.1 backlog. - TODO.md deprecated. GitHub Issues canonical. - Code-commenting style guide locked + applied to AppDelegate as the P0 exemplar (281b909). - Roadmap at .planning/ROADMAP-2026-05-12.md with 6 milestones bucketing all 141 issues. - MIT license confirmed; LICENSE/SECURITY/CHANGELOG/issue templates/PR template/dependabot all in place. - README rewritten with mermaid diagrams + acknowledgments + culture section. Repo metadata + 12 topics + 3 pinned issues set. Outstanding: PR #149 (BUILDING.md + README MIT cleanup) draft pending review. Repo still PRIVATE — public-flip decision is the user's call. Next session: read this handoff + .planning/ROADMAP-2026-05-12.md, merge PR #149, decide visibility, then start v0.1 fan-out sprint. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
31 KiB
Session State
Last Updated: 2026-05-12 end-of-day (Rounds 2/3/4 + audits + tracking migration + roadmap + branding)
Live state lives in GitHub Issues: https://github.com/KofTwentyTwo/Jarvis/issues
This file preserves session-handoff narrative. The bullet-list pending-work sections have been replaced with crosswalks to issue numbers. Read narrative paragraphs for historical context; check GitHub for current state of any item.
▶ Next Session: read docs/HANDOFF-2026-05-12-end-of-day.md FIRST
develop HEAD: 0cc94c6. 141 open issues across 6 milestones. PR #149 is draft and is first action for next session (BUILDING.md + README MIT cleanup).
Shipped today (delta since this file last said "▶ Next Session: M-0"):
- Rounds 2 + 3 + 4 strict-mode arc — Round 2 boot-phase health probes (NOT FAKED,
687b80b), Round 3 Status… NSPanel (67748f5), Round 4 severity model + non-dismissible banners + agent self-awareness preamble + red menu-bar icon (cfd469f,79955b6,23b4ca7,a9531e6). The "Toby fix" — agent refuses to lie about remembering when memory is degraded — validated mid-dogfood. - Latent fact-persistence FK fix (
a5999e2) — facts.source_turn_id FK incompatible with FNV-hash strategy; dropped FK; facts now persist. - Xcode 26 build race fix (
1557302) — ProcessInfoPlistFile scheduled after pre-codesign verify, silently revertingJarvisEntitlementsVerified. Declared Info.plist as input. - Full audit pass (
.planning/audit-2026-05-12/) — 5 parallel agents, ~37 findings filed as issues. - Dev Overlay built (
8d94c1c→50c2783→6ea2852) — 4-tab AppKit NSPanel + live log stream viaLogBroadcaster/BroadcastLogHandler. - Tracking migration to GitHub Issues — 141 issues filed;
docs/TODO.mddeprecated; CLAUDE.md declares Issues canonical. - Code-commenting style guide (
b763273, 583 lines) + AppDelegate exemplar (281b909). - User-outcome milestone roadmap at
.planning/ROADMAP-2026-05-12.md(v0.1 / v0.2 / v0.5 / v0.8 / v1.0 / v1.1). - MIT license confirmed (
.planning/decisions/license.md) + standard repo files (LICENSE, SECURITY, CHANGELOG, issue/PR templates, dependabot, branding).
Next session actions in order:
- Read
docs/HANDOFF-2026-05-12-end-of-day.md+.planning/ROADMAP-2026-05-12.mdto orient. - Merge PR #149 (BUILDING.md + README MIT cleanup).
- Decide repo visibility (still PRIVATE; marketing pass assumed public).
- Start v0.1 fan-out: Voice CRIT (#28–#36), Memory CRIT (#12–#16), MCP CRIT (#20–#22), Bus/HUD S1 (#40–#42), Vision (#1–#3), B-06 (#51), v1-hole PTT/InputMonitoring/startup (#87/#88/#89).
- After v0.1 lands, M-0 starts on its own feature branch.
The pre-existing M-0..M-7 migration plan is unchanged — still locked at .planning/architecture/JARVIS-API-DESIGN-v0.1.md + v0.2.md; epics #4–#11; M-0 directly on develop, M-1+ on feature branches; ~18.5–25.5 engineer-days remaining.
Repo caveats: 5 stashes accumulated (#63), 2 Dependabot moderate vulns flagged, repo still PRIVATE.
▶ 2026-05-11 morning — B-02 tactical patch
develop advances past 46590cd with one commit closing B-02. Substrate gap discovered + addressed in-scope: the turns table was unwritten (schema present, FTS5 trigger ready, but no INSERT site anywhere). Patch adds MemoryStore.appendTurn writer and wires both sides — orchestrator sessionHistoryLookup closure (read) and AppDelegate turnContent (write piggybacked on existing memory-extraction flush path).
- Patch site (read side):
packages/AgentCore/Sources/AgentOrchestrator/AgentOrchestrator.swift— addsPriorTurnstruct,SessionHistoryLookuptypealias withemptySessionHistoryLookupdefault (preserves pre-B-02 test setups), ctor parameter, hydration logic that prepends prior turns between system prompt and current user message in chronological order. - Patch site (write side):
packages/Memory/Sources/Memory/MemoryStore.swiftappendTurn(sessionId:role:content:source:createdAt:)+MemoryQueries.turnInsertSQL. Single-row INSERT; FTS5 trigger mirrorscontentintoturns_ftsautomatically. - AppDelegate wiring:
App/AppDelegate.swiftconstructssessionHistoryLookupclosure callingrecentTurnsForSession(limit: 10)and reversing DESC → chronological; passes it toAgentOrchestratorinit.turnContentclosure (existing memory-extraction path) gains a side-effect: write the flushed pair viaappendTurnbefore returning. Assistant row offset by +1 ms so DESC + id-tiebreaker preserves user→assistant order. - Regression coverage:
HistoryThreadingRegressionTests.HT-1— three-turn integration; asserts third call's messages array is[system, user("ok"), assistant("ack"), user("yes"), assistant("ack2"), user("why?")].HistoryThreadingRegressionTests.HT-2— empty-history default produces[system, user](pre-B-02 baseline preserved).HistoryThreadingRegressionTests.HT-3— three-turn happy path emits zeroLLMProviderError.streamTruncatedFinalevents. Pins R-006 / Phase E gate behavior — the patch grows the messages array, not the system prompt, soCacheHints.eligibleForSystemPrompt(finalSystem)is unchanged.MemoryStoreAppendTurnTests.AT-1..4— append round-trip, user/assistant pair chronological reconstruction, session scoping, FTS5 trigger fires. Env-gated onJARVIS_VEC0_STUB_PATHper existing MemoryStore-test convention; skip without vec0.dylib.
- Honesty note: in dormant-memory mode (no vec0/no Ollama), turn persistence is also dormant — the
appendTurncall is guarded bymemoryStore != nil. When D-5/D-6 land and memory comes up live, persistence activates without further code changes.
▶ 2026-05-07 evening — Design swarm output
▶ Earlier this session — Design swarm output (2026-05-07 evening)
develop HEAD was b36e8eb (handoff commit) at swarm start. Tonight's commit adds all .planning/architecture/ artifacts and the Tools/jarvis-diag/ skeleton (compiles green; type-signatures only).
Locked decisions:
- UQ-1: runtime gate
JARVIS_HARNESS=1(single binary). - UQ-2: B-02 tactical patch outside migration + regression test; B-04 stays in M-6.
- UQ-3: explicit
Voice.synthesizeTurn(turnId:text:tier:)command (orchestrator-as-driver visible at API). - UQ-4: Settings owns ALL configuration mutation; Voice has only runtime-control verbs;
bargeInmigrates to Turn. - UQ-5: parametric harness mandated — every scenario runs
.inProcessActorAND.jsonRoundTripWebView.
Plus 4 orchestrator-decided defaults (UUIDs for identifiers; ~/Library/Application Support/Jarvis-Harness/ data isolation; Settings._setConfirmationDefault(.deny) default; bus dual-version handshake ["2.3.0", "2.4.0-rc"] during M-0..M-7).
Carry-forward bug status (unchanged tonight; closes during migration per UQ-2 + plan):
- B-02 → tactical patch BEFORE M-1
- B-03 → M-5 (Vision)
- B-04, B-05 → M-6 (Voice)
- B-06 → M-7 (Turn) [DOM observability gap acknowledged; out of harness scope]
- B-07 → deferred (Plan 10-05 re-scope)
- B-08 → M-1 (Self)
▶ 2026-05-07 morning — substrate fixes (pre-pivot)
Current Status (2026-05-07 end-of-session)
develop at 1b7fb81, push pending. Tree clean (only ignorable untracked: .claude/scheduled_tasks.lock, build-devoupload/).
This session's work — substrate fixes for the agent's tool-call pipeline:
260350b..9a59648— Plan 10-02b: tool catalog enumeration (B-01a) — orchestrator now sourcesavailableTools:from the runtime catalog instead of hardcoded[]. Closes the regression that landed silently in commitfdb56d2(Phase 9 Plan 09-01) and silenced ALL tool calls for ~3 days.a75ae0a— Plan 10-02 SUMMARY recording AC-06 PASS / AC-05 FAIL after the live test surfaced B-01.3cf0d39..1b7fb81— Plan 10-02c: dispatch routing (B-01b) —InProcessAwareToolDispatchercomposite routes in-process tool calls (memory + four self-knowledge) throughInProcessToolRegistry.dispatch; preserves confirmation gating. Live-verified: "what mic are you using?" now returns "Sennheiser SDW 5 BS headset (USB) at 48 kHz, with AEC on" with realtool_use/tool_resultround-trip.
Phase 10 status at session-end:
- 10-01 (4 self-knowledge tools) — shipped, AC-01..04 PASS
- 10-02 (system prompt preamble) — AC-06 PASS; AC-05 retroactively PASS via 10-02b/c live verification (SUMMARY's FAIL marker not yet flipped — deferred per handoff)
- 10-02b — shipped, B-01a closed
- 10-02c — shipped, B-01b closed; SUMMARY missing (only PLAN written; deferred to post-design housekeeping)
- 10-03 / 10-04 / 10-05 — DEFERRED. They build diagnostic UI on top of subsystems still dead. Re-scope against new API after design lock.
Why the pivot to API-first design: two days of "fix → test green → relaunch → still broken" produced 7 carry-forward bugs (B-02..B-08 — see TODO.md and the handoff). The verification gate has been "executor self-reports green tests + boundary gates," which cannot detect substrate failures. The architectural pivot dissolves this entire bug class by forcing every behavior through a tested API contract. Stopping individual bug fixes until the API design is locked.
Carry-forward bugs (DO NOT fix piecemeal)
Live evidence collected during today's verification. All re-scope against the new API.
| ID | Symptom |
|---|---|
| B-02 | Conversation continuity broken — prior turn context lost |
| B-03 | HUD camera button click does nothing |
| B-04 | Voice input dead — wake-word + STT silent |
| B-05 | TTS silent — text replies not spoken |
| B-06 | Chat panel doesn't auto-scroll as text streams |
| B-07 | Voice Log menu item missing (Plan 10-05 unrun) |
| B-08 | get_self_state returns correct ID but Claude paraphrases as "Opus 4.5" |
Pre-existing carry-forwards (unchanged today)
- D-5 / D-6 —
libsqlite3.dylib+vec0.dylibbuild-and-bundle (user environment work) - D-7 —
ollama pull nomic-embed-text+qwen2.5-coder:32b - HUMAN-UAT — VOICE-07/09/10/12/13/14 on Release Developer ID archive
- B-7-followup — AudioLevelEmitter production wiring
- TTSInterruptTests.testI3 pre-existing 10s flake
Earlier session — 2026-05-04 (preserved below for context)
develop at 0234eaa, push pending. Tree clean. Track A + Track B-1..7 + Cleanup batch + Track C (vision) + Track D code-work (D-1..D-4 + D-5/D-6 skeletons) + audit-2026-05-04 P0/P1/P2/P3-18 fixes + documentation sweep closed. D-5/D-6 binaries + D-7 model pulls remain on the user (environment work the executor cannot do autonomously).
Documentation sweep (this session, 5 commits)
4e1c8a0— docs: write top-level README.md — replaces the stale "Pre-implementation" stub with a current overview: status table, repo layout, build/test commands, pointers to ARCHITECTURE/CONTRIBUTING.41b506d— docs: write ARCHITECTURE.md — marquee architecture document (~2300 words). Mermaid top-level diagram of the audio-graph fan-out + agent loop + bus, subsystem deep-dives for the 13 packages, cross-cutting concerns (concurrency, TCC, codesign, the 18 boundary gates), audit-derived anti-pattern list, where-things-live cheat sheet, honest gaps & deferred work.508cf92— docs(packages): per-package README files — adds README.md to each of the 13 SPM packages. Each covers purpose, key public types, deps, consumers, invariants, test stack, notable files. Memory README explicitly marks the package functionally OFF until vec0.dylib + Ollama models land.85b14ce— docs(docstrings): add header docstrings to key public types — AppDelegate (preamble + lifecycle + see-also), VoiceController (// MARK block converted to /// with Threading + Anti-patterns), MCPClient (registry + restart-mutex + relationships). Comment-only; verified viaswift build(Voice, MCP) +check-app-builds.sh. Other types listed in the brief already had substantive docstrings — left alone per audit-grade-improvement-only.0234eaa— docs: write CONTRIBUTING.md — dev environment setup, build/test pointers, GSD workflow, boundary-gate discipline, conventional-commit conventions matching the existing log, test-double naming taxonomy, anti-pattern checklist, step-by-step guides for adding an MCP tool / HUD button + bus event, compaction-recovery section for AI agents.
All 18 boundary gates green; App target builds clean; Voice + MCP packages compile after docstring additions.
What Was Done This Session
-
Six-agent deep audit (voice / HUD / vision / memory / LLM / tests) →
.planning/audit-2026-05-03/SYNTHESIS.md. Verdict: nothing worked end-to-end; every modality had ≥1 fatal break. -
Commit
1f8e03e— Track A (text turn + animated rings):- HUD
idlering no longer static (stateUniforms.ts:30). CacheHints.eligibleForSystemPromptgatesextended-cache-ttlon prompts ≥1024 tokens (likely streamTruncated cause).StreamOutcomeclassifier distinguishes 200+0bytes / 200+0frames / 200+EOF / complete.AnthropicAPIKeyProvider.makepropagatesKeychainErrorinstead of swallowing.- 2 new real-WKWebView e2e tests (chat-turn round-trip both directions).
- HUD
-
Commit
ee7f6d2— Track B-1..3 (voice foundations):scripts/copy-voice-models.shbundles ONNX models at runtime pathContents/Resources/Models/{openWakeWord,silero}/. 6 shell tests.WakeWordDAG.swift:93fixed: production now callsfeed(samples:)notfeedTest(). 2 unit tests.TTSEngineActor.orpheusis nowOrpheusTTS?;App/Voice/VoiceOutputWiring.swiftconstructs tier-1 (AVSpeechSynthesizer) without Orpheus weights. 4 unit tests including realAVSpeechSynthesizer.
-
Commit
e9c0a34— Track B-4 (audio graph + STT wiring):AudioGraphOwner.setCancelInFlight/setReleaseORTSessionscross-actor setters (Swift 6 mode requires).- New
PCMBufferBuilder(AudioChunk.pcm16k→AVAudioPCMBuffer+AVAudioConverterresample). Lives outside@available(macOS 26)gate so unit tests run on every supported macOS. +7 tests. LiveSpeechAnalyzerBridge.feed(_:)no longer_ = chunk— full SpeechAnalyzer + SpeechTranscriber wiring: builds analyzer withbestAvailableAudioFormat, opensAsyncStream<AnalyzerInput>pipe, spawns result-drain Task, finalises through end-of-input.installVoiceconstructs AudioGraphOwner, spawns degradation+rebuild consumers BEFOREopen()(so the aec=false retry path is observed), hands ring buffer toWakeWordDAG.start(ring:), setscancelInFlightfor teardown step 1. Fail-soft on graph open failure.- VoiceWiringTests testW1 asserts new
audioGraphOwner/audioGraphDegradationTask/audioGraphRebuildTaskstrong properties.
-
Commit
61aed20— Track B-5 (chunk pump + e2e proof):- VoiceController gains a
chunkPump: @Sendable (AsyncStream<AudioChunk>.Continuation) async -> Voidinit parameter (no-op default for back-compat). startSTTSessionspawns a detachedchunkPumpTask;endSTTSessioncancels it before closing the chunk continuation;shutdowncancels it. No leaked Task on session end.- AppDelegate's production pump reads
audioGraphOwner.ringBufferin 1024-sample windows (~64 ms @ 16 kHz), 10 ms sleep on starve, exits on Task cancel. - VoiceLoopE2ETests (+3): preset-chunks → orchestrator.submit text match (E1); empty pump → no submit + back to idle (E2); pump task exits within 100 ms of pttUp (E3).
- VoiceController gains a
-
Commit
bce725b— Track B-7 (BufferBroadcaster fan-out):- New
BufferBroadcaster(packages/Voice/.../AudioGraph/BufferBroadcaster.swift) fans the audio-graph tap output to per-subscriberRingBuffers; consumers no longer race for samples on the legacy SPSC ring. AudioGraph.swifttap callback callsbroadcaster.publish(buffer); the legacypublic let ringBufferis now a private "primary" subscription soWakeWordDAG.start(ring:)and the overflow watcher keep working without signature changes.AudioGraphOwner.subscribe(capacityFrames:)actor method added — chunk pump in AppDelegate now subscribes per-session via this and unsubscribes on pump exit.- Publish path is wait-free in steady state:
OSAllocatedUnfairLock<[Subscription]>snapshot copy, iterate outside lock; per-subscriberRingBuffer.writeremains lock-free. Real-time tap-thread safe. - 5 new BufferBroadcasterTests (BB-1..5: single sub, multi-sub no theft, unsubscribe stops, late-join skips prior, concurrent stress). All pass.
- Voice swift-testing 17 → 22 (+5 BB). XCTest 84 unchanged. Pre-existing
TTSInterruptTests.testI3baseline 10s flake unchanged. - Anti-patterns enforced: no actor hops on tap thread, NSLock forbidden, T-06-05-03 (no PCM logging) preserved, VOICE-14 single-call-site preserved.
- New
-
Commit
ad93dac— BLOCKER-INT-1 (real bus gateway): replacedNoopBusGatewayinAppDelegate.swiftwithMCPBusGatewayAdapterthat forwardsemitToolCallStart/emitToolCallEndthroughOutboundBatcher. Tool-call cards now reach the webview bus. NewMCPBusGatewayAdapterTestsproves the start→end forward path. -
Commit
6f6617e— F-A2-01 (stale bus world):WebviewBridgeOutboundTests:80asserted retiredJarvisBusWorldname; production switched to.pageinfb41c5f. Test now assertsWKContentWorld.page— load-bearing again. -
Commit
08125a4— tests-audit cleanup (5 tautologies): removed/replacedXCTAssertTrue(true)placeholders per.planning/audit-2026-05-03/tests-audit.mdsection 5. MCPRuntimeWiringTests:260 in-place assertion fix; WebviewBundleLoadTests, InputMonitoringDenialTests, PackageBoundaryTests deleted documentation-as-test funcs; ToolChoiceTests trailing tautology removed (closure compile is the gate). HudStateEnumTests rubber-stamps left as-is (a11y labels are user-facing, load-bearing). -
Commit
5cd46c9— F2 linter (scripts/check-no-leftover-stubs.sh): grep-based gate againstReplaced in 0…,TODO: Plan|0X-…, 2-line stub function bodies, and productionNoop*(/*Stub(instantiations. Self-tested against synthetic fixture; clean on currentdevelop. AllowlistsDormant*(real producer-stream pattern). -
Commit
7a5543a— Track C-1 (CameraCapture AVCapturePhotoCaptureDelegate): replaces the 1×1 black-JPEG hardcode with the real photoOutput delegate path. NewPhotoCaptureProxy(NSObject) bridges the delegate callback into a CheckedThrowingContinuation; retains itself for the lifetime of the capture (AVCapturePhotoOutput holds delegates weakly), breaks the cycle on the first didFinishProcessingPhoto callback. Test seamphotoCaptureOverridemirrorsauthStatusProbe— production tests can exercise captureFrame() end-to-end without hardware. Vision 56 → 59. -
Commit
ea09fd4— Track C-2 (frameStream fan-out): replacesAsyncStream { cont.finish() }with a real fan-out backed byAVCaptureVideoDataOutputSampleBufferDelegate. NewVideoSampleDelegatefans incoming CMSampleBuffers to a UUID-keyed map of registered continuations under anNSLock-guarded snapshot.frameStream(forPresence:)now generates a UUID per subscription, hops into the actor to register against the live delegate, and tears down viacont.onTermination. shutdown() drains the subscription set. Vision 59 → 63. -
Commit
4159d44— Track C-3 (HUD camera button): closes vision-audit §4 "HUD button emitter has zero matches". NewCameraButton.tsxposts{ type: 'frameAttachRequested' }viawindow.jarvisBus.send; rendered next to the chat input's Send button with matching toolbar chrome. JS path:webview/packages/hud/src/chat/CameraButton.tsx:14. Swift handler atApp/AppDelegate.swift:1696-1698already routed it intoFrameAttachController.requestAttach(reason: .hudButton). HUD vitest 94 → 97. -
Commit
df6a4d2— Track C-4 (explicit T2 missing variant): replaces the silentt2Provider: t1AppDelegate hardcode withMissingT2Providerwhosestream(...)finishes withVisionError.t2ProviderUnavailable. Real vllm-mlx wiring (codesigning + binary bundling + feature flag) is downstream work and out of Track-C scope; the bug being fixed here is "silent T1-as-T2 fallback hides intent" — explicit-missing makes the missing wiring debuggable instead of silent. Production callers must gate onevaluatePostResponse(..., t2Available: false)(already do); MissingT2Provider's stream is never actually invoked in the live flow. Vision 63 → 67. -
Commit
eac16c9— Track C-5 (confirmSend wired): closes vision-audit §4 "confirmSend has zero non-test callers".handleChatSubmitandhandleChatCancelAndSubmitnow consultFrameAttachController.hasPendingFrameand, when armed, pull theImageBlockviaconfirmSend(userText:)and route throughsubmit(.withImages(...)). Both submit handlers carry the wiring (WARNING-4 parity with the existing phrase-trigger path). Completes the Track C-3 click flow end-to-end. Vision 67 → 70. -
Commit
19362f6— Track C-6 (real-hardware integration test):CameraCaptureRealHardwareTestsexercises captureFrame() and frameStream() against real AVCaptureSession output. Gated by ALL of:JARVIS_REAL_CAMERA=1env,AVCaptureDevice.default(for: .video)non-nil,authorizationStatus == .authorized. Test does NOT prompt for TCC — headless test runs skip cleanly. Run interactively:JARVIS_REAL_CAMERA=1 swift test --package-path packages/Vision --filter CameraCaptureRealHardwareTests. Asserts: jpeg byte count > 1000, SOI marker, width/height > 1 (so a regression to the 125-byte 1×1 stub trips immediately); frameStream emits a.sampleBufferwithin 2s. Vision 70 → 72 (2 tests, both skip without env+TCC). -
Commit
75a10be— Track D-1 (installMemory cascade): singlereturnafterMemoryStore(databaseURL:)throw left bothmemoryExtractionOrchestratorANDmemoryExtractionCoordinatornil for the process lifetime — extraction was a no-op even though the LLM call to Ollama is independent of SQLite. Restructured: store nil now logs a warning, setsmemorySearchAvailable=false, but extractor + orchestrator + coordinator all construct. ApplyOp closure captures[weak self]and routes to debug log whenmemoryStoreis nil (drain loop survives). NewMemoryInstallWiringTestsproves the cascade is closed. T-06-05-03 preserved: log only turnId hash, never subject/object content. -
Commit
707c45b— Track D-2 (SearchMemoryTool + ForgetFactTool registration): both tools have lived inpackages/MCP/Sources/MCP/InProcess/since Plan 07-03 with zero production registration — agent loop had no way to call memory. NewApp/MCP/InProcessMemoryAdapters.swiftbridges MCP's tool protocols to Memory's actors (HybridSearchAdapterwrapsHybridSearchand translates[FactRef]→[SearchMemoryHit];ForgetFactStoreAdapterwrapsMemoryStore.forgetFact).installMemorybuilds anInProcessToolRegistryand registers conditionally:forget_factwhenmemoryStore != nil,search_memorywhenmemorySearchAvailable && embedder init succeeds. Embedder failure degrades to "writes ok, no search" rather than failing the whole subsystem. -
Commit
51750c1— Track D-3 (priorFacts wiring): pre-fixMemoryExtractionOrchestrator.process(_:)hardcodedpriorFacts: []— extractor was blind to existing facts, only ever ADDed, never UPDATEd. AddedPriorFactsLookuptypealias +priorFactsLookupctor parameter (defaultemptyPriorFactsLookuppreserves pre-D-3 behavior). Lookup throws degrade to empty list with a warning log so the drain task survives. NewMemoryStore.recentActiveFacts(limit:)+ matchingMemoryQueries.recentActiveFactsSQL(server-side cap, active-only). AppDelegate's installMemory passes a closure returning up to 50 recent active facts. Tests:testD3_priorFactsLookupDrivesUpdateOp(stub provider emits UPDATE only when it sees[99]prior fact id in system prompt; assertsapplyOpreceives.update(supersedes: 99, …));testD3_priorFactsLookupErrorDegradesToEmpty(lookup throws, job still applies its ADD op). Memory 86 → 88. -
Commit
c3bd0a5— Track D-4 (remember-Brutus end-to-end): newRememberBrutusEndToEndTests.testExtractionWriteThenSearchFindsBrutusproves the extraction → store → search loop holds. RealMemoryExtractionOrchestrator+MemoryExtractor+HybridSearch; fakes for the vec/Ollama-dependent surfaces (FakeStoreactor conforms to both apply path andMemoryReadStore;StubEmbedderreturns constant 768-dim vector;BrutusProviderreturns one ADD op thenmessageStop). Scenario: turn 1 "My dog Brutus is a Bernese Mountain Dog." → ADD lands in store → turn 2 "What breed is Brutus?" →search.searchFactsreturns one hit with summary"Brutus breed Bernese Mountain Dog". Boundary stops atHybridSearch.searchFacts; MCP-side dispatch covered byInProcessMemoryToolsTestsin the MCP package. Memory 86 → 87 (D-3 added via grouping; total Memory tests now 87). -
Commit
6e249ee— Track D-5/D-6 (deferred build + fetch script skeletons):scripts/build-sqlite-with-extensions.sh(clang flags forSQLITE_ENABLE_LOAD_EXTENSION=1+ FTS5 + RTREE + threadsafe=2; TODO markers for SQLite version, amalgamation URL, SHA256, codesign identity) andscripts/fetch-sqlite-vec.sh(GitHub release tag + SHA256 + asset path; TODO markers for version + hash). Both mode 755, exit 1 with clear "TODO: fill in …" message until pins land — no deceptive successful stub. -
Commits
57847f2/f9cd25d/2d9a25a— audit-2026-05-04 P2 stragglers:57847f2(P2-14, test-seam visibility): VoiceController_forceState/_testFireSpeechEnd/_testCurrentSttSessionId(4 seams) flipped frompublic→internal; MCPClient_testHandle+ MCPServerHandle_testProcessIdentifier(2 seams) flipped to@_spi(Testing) public. Voice tests already use@testable import; MCP tests gain@testable @_spi(Testing) import JarvisMCP; Harness'sMCPCrashRunneropts in via@_spi(Testing) import JarvisMCP. Public ABI no longer leaks test entry points.f9cd25d(P2-15, mock naming): new CLAUDE.md §"Test naming conventions" (line 127) documents Mock/Stub/Fake taxonomy (records-and-scripts / canned-data / realistic-stateful). 15 worst-mismatch stragglers renamed in older corpus: 6Stub*→Mock*(HybridSearchTests StubEmbedder/StubStore, SessionHistoryTests StubStore, InProcessMemoryToolsTests StubHybrid/StubHistory/StubForget — all record calls); 8Mock*→Stub*(STTBackendSwitchTests MockSpeechAnalyzerBridge/MockWhisperKitBridge, VoiceWiringTests Mock*ForW4 ×6 — all canned no-ops); 1Fake*→Mock*(FakeJSEvaluator in two files — comment already said "Records each call for assertion"). Did NOT touch types added in today's P1+P2 fix commits per audit constraint.2d9a25a(P3-18 / security LOW-3):scripts/check-applescript-confirmation.sh— defense-in-depth grep gate. For each non-comment/non-test line containingrun_applescript, asserts the enclosing register-call body (line + up to 5 following lines, terminated at)) containsrequiresConfirmation: true. Verified catches regression: temporarily flippedApp/MCP/MCPRuntimeWiring.swift:119tofalse→ gate FAILed with the file:line citation; reverted; gate PASSes on clean tree. Comment-only references in HudStateIntent.swift:19 + InProcessTool.swift:9 are filtered byis_comment_line.
-
Commit
c7f9ece— Track B-6 (VAD-gated session end):VoiceController.startSTTSessionnow spawns a per-session VAD interceptor task. Pump output flows through it, forwarding every chunk to STT and running Silero VAD per 512-sample window.- New private
runVADInterceptor: tracks armed state on.speechStart, counts consecutive silence chunks after.speechEnd, and triggersendSTTSession()once the hangover threshold (5 chunks ≈ 160 ms) is reached. Mid-utterance speech resumption cancels the pending finalize. endSTTSession()is nowasync;pttUp()awaits it. Single non-VAD caller path preserved.- 512-sample VAD window builder carries over the partial tail between chunks so it works against both the test pump (512-sample chunks) and the production pump (up to 1024-sample chunks).
- Anti-patterns enforced: VAD handler does NOT block on
await analyzer.finish()— finalize fires insideTask { … }to avoid deadlock on the analyzer completion path. T-06-05-03 preserved (no PCM in logs). VOICE-14 singlecancelAndSubmitsite preserved. - VADGatedSessionTests (+4): VAD-1
.speechEnd+ 5×silence → submit; VAD-2 PTT regression with VAD wired; VAD-4 sustained speech → no submit; VAD-5 speech resumption within hangover cancels pending finalize.
Active Branches
| Branch | Status |
|---|---|
develop |
At 2d9a25a, ahead of origin (push pending). Tree clean. |
Pending Work — moved to GitHub Issues
Live tracking has migrated to https://github.com/KofTwentyTwo/Jarvis/issues. Crosswalk for items previously listed here:
- AudioLevelEmitter production wiring — verified done; consumer still dead — #54 + #44
- Track C (vision) — CLOSED 2026-05-04 (commits
7a5543athrough19362f6) - Track D (memory code-work) — CLOSED 2026-05-04 (commits
75a10bethrough6e249ee); environment work #56/#57/#58; memory database now live via48ad8d6 - TTSInterruptTests.testI3 flake — #55
- streamTruncated empirical confirmation — #62
- Migration M-0..M-7 — epics #4 through #11
- Carry-forward bugs B-03..B-08 — #48 through #53
- 2026-05-12 audit findings — see
docs/TODO.mdcrosswalk for the full list
Key Reference
- Audit reports:
.planning/audit-2026-05-03/{SYNTHESIS,voice,voice-audit,hud-audit,vision-audit,memory-audit,llm-audit,tests-audit}.md - Plan:
.planning/AUDIT-AND-FIX-PLAN.md, findings tracker:.planning/AUDIT-FINDINGS.md - Test stack at session end (post P2-14/15/P3-18): Voice 87 XCTest + 23 swift-testing (3 skipped), MCP 85 XCTest, Memory 88 XCTest (19 skipped — vec0/Ollama gating), Bus 58 XCTest, AgentCore 19 + 72 XCTest, Vision 19/72 XCTest, Shell 5+7 XCTest, webview/hud 97 vitest. All 18 boundary gates PASS (17 pre-existing + new check-applescript-confirmation.sh), app builds clean. Pre-existing baseline issues unrelated to this batch:
webview/packages/hud/src/hud/SegmentedRing.tsxtypecheck warnings,TTSInterruptTests.testI310s flake. Flag for follow-up; out of scope here. - Next-session orientation: read
.planning/audit-2026-05-04/SYNTHESIS.mdfirst, then this file, thengit log --oneline 6e249ee..HEADfor the audit P0-P2 fix story.