Skip to content

Feat/spoken summary confirm loop - #7

Merged
asmuelle merged 3 commits into
mainfrom
feat/spoken-summary-confirm-loop
Jul 5, 2026
Merged

Feat/spoken summary confirm loop#7
asmuelle merged 3 commits into
mainfrom
feat/spoken-summary-confirm-loop

Conversation

@asmuelle

@asmuelle asmuelle commented Jul 5, 2026

Copy link
Copy Markdown
Owner

No description provided.

asmuelle added 3 commits June 27, 2026 11:00
After a recording, optionally speak an on-device recap and ask to keep it:
Keep saves; "Add more" asks one open question and re-records, appending to the
draft (capped rounds). Opt-in, off by default, fully on-device.

Built in four layers, each independently tested:

- TTS boundary: SpeechSynthesisEngine protocol + AVSpeechSynthesizer impl
  (owns the .record->.playback audio-session handoff, the only device-only
  seam) + mock. Non-throwing speak so capture always falls through to the
  on-screen summary.

- Generation: CaptureSummaryProviding + CaptureSummaryPipeline. Same discipline
  as ReflectKit — the crisis gate runs BEFORE the model and BannedTerms +
  length bounds run AFTER, so a recap is never spoken over crisis content and
  raw model text never reaches the user. FoundationModels / deterministic /
  mock providers.

- Orchestration: CaptureCoordinator gains summarizing/confirming/clarifying
  states, confirmKeep()/requestClarification(), and a round cap. Both deps are
  injected optional → nil preserves the existing read-it-back path unchanged.

- App wiring: InwardApp factories + RootView gate the loop behind a new opt-in
  setting (default off) and a localized CrisisGate; SettingsView toggle; 6 new
  user-facing strings translated across all nine languages (native review
  pending).

swift test 216/216 green (incl. localization completeness + banned-terms scan);
just mac-build succeeds. The audio path itself is device-only and unvalidated
in Simulator.
…vacy proof

First tranche of the vetted value roadmap, all on-device and
airplane-mode functional:

- CaptureKit: PersonalLexicon ranks the journal's own people, places,
  and tags into AnalysisContext contextual strings so recognition
  learns the user's names; NLGazetteer seeds the NaturalLanguage
  entity-extraction floor with the same vocabulary.
- JournalStore: Entry.timeZone (v7) stamps the IANA zone at capture so
  local hours stay true across travel; entry_embedding (v8) stores
  sentence vectors, invalidated on edit, cascading on delete.
- ReflectKit: DayPart/TimeRhythm derive a deterministic "when you
  wrote" line for the weekly review, computed in each entry's own
  captured zone; timeline rows wear a day-part glyph.
- RecallKit: TextEmbedding seam with SentenceTextEmbedder (bundled
  NLEmbedding models - no download, offline from first launch),
  EmbeddingRecallIndex (vDSP cosine), and OnThisDay echo selection.
- App: timeline search (literal matches first, semantic neighbors
  after), "entries that feel like this one" in the entry detail,
  dismissable on-this-day card, background EmbeddingIndexer, and a
  user-scheduled weekly-review notification (passive, content-free,
  lock-respecting deep link).
- PaywallKit: inverted paywall - capture, reading, and export are free
  in every state; Pro gates the insight layer (weekly-review synthesis,
  mind map, tag suggestions, spoken recap) with the deterministic
  themes-only review as the free floor.
- Privacy proof: live NWPathMonitor state in onboarding and a standing
  Settings Proof screen with offline capture demo and honest App
  Privacy Report guidance.
- Fix: register navigationDestination(for: Entry.self) in RootView -
  weekly-review citation links previously had no destination on iPhone.

All ~30 new user-facing strings localized across the nine languages.
Core suite: 249 tests green (33 new); app suite green on simulator;
iOS + macOS builds clean. Device-only validation still pending for
ASR biasing strength and notification tap-through.
@asmuelle
asmuelle merged commit eb00305 into main Jul 5, 2026
2 of 3 checks passed
@asmuelle
asmuelle deleted the feat/spoken-summary-confirm-loop branch July 5, 2026 06:12
asmuelle added a commit that referenced this pull request Jul 5, 2026
The thebrowsercompany/GRDB.swift fork's tags are not comparable semver:
"3.0.1" vendors GRDB 7.4.1 + SQLCipher 4.7.0, while "6.6.0" vendors the
older upstream GRDB 6.6.0, whose C-string calls (strcmp) no longer compile
on Swift 6.2. Dependabot's tag-order "bump" (#6) therefore downgraded the
at-rest crypto layer and broke CI and CodeQL autobuild on main, while the
PR #7 head (still on 3.0.1) built green on the same runner.

Revert the pin and ignore this dependency in dependabot; bump it manually
after a local build only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant