Implement cited question answering over personal activity #81

Merged
lost-rob0t merged 66 commits from agent/issue-26-cited-qa into main 2026-08-22 18:34:24 +00:00
lost-rob0t commented 2026-08-22 16:39:13 +00:00 (Migrated from github.com)

Closes #26.

RAGE scope

Implements cited, evidence-bounded personal-activity question answering over the canonical #24 retrieval boundary. The immutable transaction starts from main a7eb46497de6a0dd14f71015c945b38aff685957 and does not consume any later issue.

Architecture

  • deterministic query planning resolves exactly one explicit/relative time scope with the configured timezone and maps explicit application/workspace selectors into typed retrieval filters;
  • RetrievalService remains the only evidence-selection/decryption authority; answering never opens storage or decrypts records directly;
  • retrieved passages receive request-local opaque evidence labels (E1, E2, …), while canonical record UUIDs/timestamps remain owned by Local Recall;
  • structured generated claims use the closed {kind,text,evidence_ids} schema; unknown/duplicate/missing citations and unsupported observed text reject the whole generation;
  • observed facts and model inference stay separately typed;
  • weak/empty retrieval returns explicit Insufficient evidence. without invoking a model;
  • deterministic rendering adds canonical record/timestamp citations and optional exact activity-span provenance; stale/missing/ambiguous cluster linkage falls back to the canonical record citation;
  • timeline mode orders claims by canonical capture timestamps;
  • QA has no capture/lifecycle/storage/network authority.

Routing and privacy

  • local-only, privacy-strict, and local-first use the existing routing policy and never silently fall back to remote after local failure;
  • remote-explicit requires both retrieval-level remote eligibility and an explicit provider/data-class-bound EgressAuthorization;
  • remote text passes through the existing EgressGate and the remote QA port receives only ApprovedEgressPayload;
  • the answering package imports no capture/lifecycle/storage or provider transport/client implementation;
  • model evidence context uses opaque labels plus already-redacted excerpts, not canonical record IDs;
  • question text, claim text, prompts, and evidence excerpts are excluded from public reprs and sanitized control surfaces.

TDD evidence so far

  • Local service RED: exact head af2cdf06b456b995f63189ae169648b9be1cf330, CI run 32587805311; formatting/Ruff/ShellCheck/Pyright passed, unit collection failed specifically because local_recall.answering.service did not exist.
  • A first production attempt exposed a real strict-Pyright bug in capability collection; production was fixed without weakening the oracle.
  • Local service GREEN: exact head b3ef1267d8d70997d8be6b40de7200a691156998, CI run 32588237495; canonical ./scripts/check passed with 692 tests and all failure/security gates.
  • Renderer RED: after rejecting multiple mechanical lint/format-only failures, exact head f630f3981b0df2b801f982da96b5988edd41ab36, CI run 32588662351, reached 595 passing unit tests and exactly four failures because local_recall.answering.rendering did not exist.
  • Renderer production then passed both Ubuntu matrices, strict typing, unit/contract/integration/security checks, and failure propagation.
  • Remote-explicit RED: exact head 4e943b51a268ce536e26e8bd581e33030388763b, CI run 32588799916; formatting/Ruff/ShellCheck/Pyright passed, 599 unit tests passed, and exactly three tests failed because AnsweringService did not yet expose the remote-provider boundary.

The branch additionally contains an encrypted-storage acceptance fixture for “What was I doing Saturday?”, a structural privacy test for answering dependencies/content-free reprs, and dedicated answering documentation.

Final completion remains gated on the exact final head passing the full repository CI matrix and canonical gate; this PR remains draft until that evidence is observed.

Closes #26. ## RAGE scope Implements cited, evidence-bounded personal-activity question answering over the canonical #24 retrieval boundary. The immutable transaction starts from `main` `a7eb46497de6a0dd14f71015c945b38aff685957` and does not consume any later issue. ## Architecture - deterministic query planning resolves exactly one explicit/relative time scope with the configured timezone and maps explicit application/workspace selectors into typed retrieval filters; - `RetrievalService` remains the only evidence-selection/decryption authority; answering never opens storage or decrypts records directly; - retrieved passages receive request-local opaque evidence labels (`E1`, `E2`, …), while canonical record UUIDs/timestamps remain owned by Local Recall; - structured generated claims use the closed `{kind,text,evidence_ids}` schema; unknown/duplicate/missing citations and unsupported observed text reject the whole generation; - observed facts and model inference stay separately typed; - weak/empty retrieval returns explicit `Insufficient evidence.` without invoking a model; - deterministic rendering adds canonical record/timestamp citations and optional exact activity-span provenance; stale/missing/ambiguous cluster linkage falls back to the canonical record citation; - timeline mode orders claims by canonical capture timestamps; - QA has no capture/lifecycle/storage/network authority. ## Routing and privacy - `local-only`, `privacy-strict`, and `local-first` use the existing routing policy and never silently fall back to remote after local failure; - `remote-explicit` requires both retrieval-level remote eligibility and an explicit provider/data-class-bound `EgressAuthorization`; - remote text passes through the existing `EgressGate` and the remote QA port receives only `ApprovedEgressPayload`; - the answering package imports no capture/lifecycle/storage or provider transport/client implementation; - model evidence context uses opaque labels plus already-redacted excerpts, not canonical record IDs; - question text, claim text, prompts, and evidence excerpts are excluded from public reprs and sanitized control surfaces. ## TDD evidence so far - Local service RED: exact head `af2cdf06b456b995f63189ae169648b9be1cf330`, CI run `32587805311`; formatting/Ruff/ShellCheck/Pyright passed, unit collection failed specifically because `local_recall.answering.service` did not exist. - A first production attempt exposed a real strict-Pyright bug in capability collection; production was fixed without weakening the oracle. - Local service GREEN: exact head `b3ef1267d8d70997d8be6b40de7200a691156998`, CI run `32588237495`; canonical `./scripts/check` passed with 692 tests and all failure/security gates. - Renderer RED: after rejecting multiple mechanical lint/format-only failures, exact head `f630f3981b0df2b801f982da96b5988edd41ab36`, CI run `32588662351`, reached 595 passing unit tests and exactly four failures because `local_recall.answering.rendering` did not exist. - Renderer production then passed both Ubuntu matrices, strict typing, unit/contract/integration/security checks, and failure propagation. - Remote-explicit RED: exact head `4e943b51a268ce536e26e8bd581e33030388763b`, CI run `32588799916`; formatting/Ruff/ShellCheck/Pyright passed, 599 unit tests passed, and exactly three tests failed because `AnsweringService` did not yet expose the remote-provider boundary. The branch additionally contains an encrypted-storage acceptance fixture for “What was I doing Saturday?”, a structural privacy test for answering dependencies/content-free reprs, and dedicated answering documentation. Final completion remains gated on the exact final head passing the full repository CI matrix and canonical gate; this PR remains draft until that evidence is observed.
Sign in to join this conversation.
No description provided.