Hindsight Reqwest Client & Deterministic Document Identity #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement the direct Rust
reqwestadapter for Hindsight, enforcing deterministic document identity (life-event:<event_id>), canonical SHA-256 item tags (life-item:<hash>), typed retain requests, and strict replace semantics.Background & Technical Rationale
Life incorporates Hindsight as a semantic memory and context backend. To maintain architectural purity and rock-solid reliability, the system defines unambiguous authority and identity boundaries:
Hindsight owns semantic context—user preferences, explanations, interpersonal relationships, decisions, and meaningful rationales. It is NEVER authoritative for current calendar or task state. Current schedule, task completion, and deadlines are owned strictly by CalDAV / Radicale. If Hindsight is completely unavailable, calendar operations and agenda queries proceed without interruption.
The integration uses a direct, pooled
reqwest::Clientwithrustlscommunicating over HTTP/HTTPS with the configured Hindsight bank. No external Python, Node.js, or TypeScript sidecar processes or generic agent SDK frameworks are used.When Life retains a memory derived from a Life event, it must derive a stable, deterministic document ID: Every retain request MUST set
update_mode: "replace". Naive retain implementations that append or generate random document UUIDs cause memory duplication, fragmented knowledge bases, and hallucinated conflicting contexts. Re-retaining the same event replaces the existing document rather than accumulating duplicate memories.To scope memories to specific tasks or events, Life derives an item tag: The canonical JSON array MUST be serialized without superfluous whitespace (e.g.
["personal","fictional-demo-uid"]). This tag deliberately covers the entire recurring series. Occurrence-specific details are recorded as string metadata and verified locally by Life.When the user captures pure context or decision rationales not tied to a calendar item, Life uses the stable tag
life-contextand the source event ID, without inventing a fake calendar UID.Retain requests configure
observation_scopes: "combined"over the stable item tag, allowing Hindsight to consolidate observations across time for that item without tag fragmentation.Exact Technical References & Specifications
Upstream Endpoint & Responsibility Matrix
From
docs/technical/hindsight.md(lines 9–14):Normative Retain Request Payload
From
docs/technical/hindsight.md(lines 25–27):Normative identity rules (
hindsight.md, lines 17–22):Verification Matrix Scenario I01
From
docs/technical/verification.md(lines 113–115):Section Citations
docs/technical/hindsight.md: Section Authority and adapter (lines 5–16), Section Identity and retain (lines 17–30), Section Compatibility requirements and sources (lines 53–57).docs/technical/verification.md: Section Integration scenarios (lines 113–115, Scenario I01).docs/technical/timeline-consistency.md: Section Context delivery and correction (lines 160–165).What to Build
1. Deterministic Identity Derivation (
src/hindsight/identity.rs)derive_document_id(event_id: &str) -> String:format!("life-event:{}", event_id).derive_item_tag(collection_id: &str, uid: &str) -> String:[&collection_id, &uid]viaserde_json::to_string.sha2::Sha256.format!("life-item:{}", hex).derive_context_tag() -> &'static str:"life-context".["personal", "fictional-demo-uid"]must yield predictable, whitespace-independent SHA-256 hex digest.2. Upstream OpenAPI 0.10.1 Data Models (
src/hindsight/models.rs)3. Authenticated Hindsight Client (
src/hindsight/client.rs)HindsightClient:authorization_file(or token file).docs/technical/hindsight.md:7).retain(&self, request: RetainRequest) -> Result<RetainResponse, HindsightError>:POST /v1/default/banks/{bank_id}/memories.Content-Type: application/json.poll_operation(&self, operation_id: &str) -> Result<OperationStatusResponse, HindsightError>:GET /v1/default/banks/{bank_id}/operations/{operation_id}.HindsightError::Unauthorized, 404 toHindsightError::NotFound, 429/503 toHindsightError::Unavailable(retry_after).4. Conformance Test Suite (
tests/hindsight_client_tests.rs)RetainRequestand assert exact JSON match withhindsight.mdnormative example.life-event:evt_demo.life-event:evt_demoa second time with modified content.update_mode: "replace"and identicaldocument_id.Acceptance Criteria
document_idis strictly and deterministically formatted aslife-event:<event_id>.update_mode: "replace",observation_scopes: "combined", and string metadata values matching OpenAPI 0.10.1 (Scenario I01).life-item:plus lowercase SHA-256 of the UTF-8 canonical JSON array[collection_id, uid]without whitespace sensitivity.life-contexttag and source event ID without fabricating a fake UID.document_idand replace semantics without creating duplicate memories (Scenario I01).Notes
verify_compatibilityinto startup belongs with #17/#18.Cargo.tomlauthors chore stays pending.Blocked by
Issue #016: Hindsight Reqwest Client & Deterministic Document Identityto Hindsight Reqwest Client & Deterministic Document Identity