Skip to content

Product Requirements

Arun Prakash edited this page Aug 14, 2026 · 10 revisions

Canonical source: docs/product/PRODUCT-REQUIREMENTS.md · Snapshot commit: 8affbc19d165

Life in Days Global PRD

Team: Personal Project, Life in Days Author (PM): Arun Prakash, Product Owner; drafted by the Product Council Senior Product Manager Triad Partners (Design, Engineering): Life in Days Product Council — UI/UX, Technical Architecture, and Project Management agents Legal Contact: N/A — private, non-commercial personal project; provider terms and privacy obligations remain Arun's responsibility Applicable Countries: N/A — not customer-facing; one user in India, with planned EU infrastructure locations where explicitly stated Market Segments: N/A — private, non-commercial personal project

Date last edited: 2026-08-13 Doc Status: Draft — requirements frontier complete; explicit shared-understanding confirmation pending Authorization boundary: This PRD does not authorize paid evaluation, implementation, provider configuration, credential collection, DNS/server mutation, deployment, or launch. Those activities remain gated by Arun's explicit confirmation and the post-confirmation gates below. Related Links: Canonical domain language · Confirmed discovery requirements · Proposed shared understanding · Product and integration research · AI text evaluation · AI artwork evaluation · Media storage evaluation


Overview

Context & Insights

  • Arun already creates long-form voice journals in VoiceNotes and already uses Telegram as an easy photo-sharing surface. The missing product is not another writing ritual. It is a dependable bridge from those existing habits into a private, browsable memory archive.
  • The central value is reflective recall: a month of images should act as a visual index into complete, authentic journal material. Selecting a date should make it easy to see the day's real photos, summary, tags, detailed journals, timestamps, and provenance.
  • Trust matters more than generative novelty. Original text and image bytes must remain distinguishable from Corrections and AI-created Derived Artifacts. No generated title, summary, tag, or artwork may silently rewrite or masquerade as source truth.
  • Real photos are documentary evidence and remain private. They, their thumbnails, metadata, identifiers, and descriptions derived from them must never be transferred to an AI provider. Hosted AI may receive only the explicitly approved journal-text inputs.
  • Research on Day One, Rosebud, Five Minute Journal, and Daypix supports an image-first calendar, chronological browsing, full-text/tag retrieval, editable AI outputs, portable export, Trash, and revision history. Coaching, streak pressure, duplicate writing prompts, social features, maps, and native-app complexity do not belong in MVP.
  • VoiceNotes documents webhooks and an official MCP interface, but does not document several material behaviors: webhook tags and creation timestamps, signature/authentication, retries, ordering, payloads for all event types, tag-change events, webhook/MCP identifier equivalence, unattended OAuth refresh, or rate limits. The integration is therefore a hypothesis until a synthetic spike passes.
  • Telegram documents webhook secret validation, stable update/message identifiers, 20 MB bot downloads, photo size variants, and media_group_id. It does not provide an album-complete event or ordinary message-deletion events. Capture must be idempotent and acknowledge only after durable local commit.
  • The existing Hetzner server and Cloudflare tunnel make a zero-incremental-hosting-cost start possible. The server is intentionally a best-effort single-host deployment, so independent encrypted backups, restore drills, disk watermarks, and a launch-blocking Recovery Ceremony are product requirements rather than operational nice-to-haves.
  • Hosted AI text and artwork models are inexpensive at one Journal Day per day, but cost does not establish fidelity, tasteful imagery, privacy behavior, or lifecycle stability. Exact dropdown options remain outcomes of the approved synthetic/blind evaluations, not decisions this PRD may invent.
  • The product processes intensely personal content. There is no third-party analytics or crash reporting in MVP. Local health and audit evidence must be sufficient to establish capture, cost, backup, restore, and storage state without logging journal content or secrets.
  • This is a new personal product at a ready-to-PRD stage. Product behavior is settled; exact AI models, the VoiceNotes contract, and the final no-additional-cost encryption/key design remain explicit post-confirmation gates.

Problem Statement

Arun's journals and daily photos are split across capture tools, which makes revisiting ordinary days fragmented and visually unrewarding. Life in Days will prospectively assemble those authentic sources into private, image-led Journal Days while preserving provenance, revision history, recoverability, and an unambiguous boundary between real memories and AI-derived presentation.


Goals & Metrics

Goals What are the key business and customer goals (quant or qual) of this project?

  1. Operational goal: Establish a low-cost, restorable private archive on Arun's existing server without claiming high availability, end-to-end encryption, zero knowledge, or untested recovery.
  2. Operational goal: Keep incremental recurring AI spend at or below the approved $5 monthly application ceiling while preserving capture, browsing, backup, and export when generation is unavailable.
  3. User goal: Make daily capture effortless by importing eligible prospective VoiceNotes journals and accepting one or more Telegram photos without requiring duplicate journal composition.
  4. User goal: Make a remembered date easy to revisit through an attractive month calendar, timeline, exact search, and detailed Journal Day view.
  5. Trust goal: Preserve every authentic source, timestamp, revision, Correction, deletion intent, and generated-artifact provenance without silent overwrites, auto-merges, fallback providers, or data loss.
  6. Privacy goal: Keep real photos entirely outside AI systems and minimize journal text disclosed to the explicitly selected text and artwork processing paths.

Success Metrics

Metrics are calculated from local test evidence and private operational state. MVP does not add third-party analytics or behavioral tracking.

Primary Metric

  • Trustworthy archive acceptance rate: 100% of accepted end-to-end capture fixtures must produce either (a) a durable, provenance-bound Source Item that can be found, opened, exported, backed up, and restored, or (b) an explicit Needs Date Review/rejection/failure state that preserves recoverable input where the requirements say it must. No accepted scenario may silently lose, overwrite, misdate, or misrepresent source content.

Supporting Metrics

  • Recovery readiness: the launch-blocking Recovery Ceremony succeeds; monthly sampled restores succeed; quarterly full-recovery drills measure against the four-hour acceptance target rather than assuming it.
  • Privacy boundary: zero real-photo bytes, thumbnails, EXIF, Telegram file identifiers, photo captions, photo-derived descriptions, signed URLs, or other photo metadata appear in AI request serialization, provider fixtures, application logs, or telemetry.
  • Text-model quality gate: each enabled model passes all approved hard gates, including at least 95% first-response schema validity, zero accepted critical inventions, no persistent coaching/diagnosis, no prompt-injection obedience, no major-event loss or negation reversal, and at most 1% benign refusals after one controlled retry.
  • Text-model usefulness: a selected default achieves a blinded weighted mean of at least 4.0/5 with no serious worst-case pattern; a more complex/costly challenger is exposed only if it improves by at least 0.2/5 or materially reduces worst-case factual errors.
  • Artwork quality gate: every exposed model passes contract, privacy, lifecycle, 4:5 composition, safety, reliability, permanent-retention, and monthly-budget gates, then completes the approved two-stage blind evaluation.
  • Cost control: no predicted AI request executes if it would exceed the $5 total monthly ceiling, the $4.50 artwork allocation, or the separate one-time $15 combined evaluation ceiling. The $0.50 text reserve never permits total production spend above $5.
  • Accessibility: the supported responsive surfaces meet the WCAG 2.2 AA contrast target, can be operated with a keyboard, expose meaningful focus and labels, and honor reduced-motion preferences in automated and manual acceptance checks.
  • Storage safety: no Original is silently deleted, transformed, or downsampled; threshold alerts occur at the approved watermarks; an emergency threshold rejects new media clearly before filesystem safety is compromised.
  • Source fidelity: every imported source retains its Original Timestamp, origin, content checksum/identity, revision set, and displayed Correction relationship through redating, conflict resolution, Trash, export, and restore scenarios.
  • Owner validation: Arun completes and signs off a pre-launch scenario walkthrough covering capture, review, search, correction, redating, artwork labeling, deletion/restoration, export, and recovery. No broader adoption metric applies to a one-user product.

Non-Goals

  • AI coaching, therapy-like guidance, diagnosis, goal setting, journaling prompts, streaks, motivational nudges, reminders, weekly themes/reports, and habit gamification.
  • Automatic historical VoiceNotes import, including importing a pre-activation note merely because it is later edited or tagged.
  • Multiple users, shared journals, collaboration, public links, social publishing, or anonymous access.
  • A blank browser journal editor; VoiceNotes and uploaded .txt/.md files remain the writing paths.
  • PDF, Word, OCR, or RAW journal/media ingestion; PDF books and printing.
  • Semantic or conversational journal search, journal Q&A, fuzzy memory retrieval, or AI answers over the archive.
  • Year mosaic, media wall, maps/location browsing, and On This Day resurfacing.
  • Native mobile applications, complex offline synchronization, legacy-browser support, or an offline-first web app.
  • Additional VoiceNotes tags, fuzzy tag matching, or broad tags such as Journal in MVP.
  • Immutable/ransomware-resistant export infrastructure beyond the approved encrypted Restic recovery path.
  • High availability, a production SLA, zero-downtime deployment, or a claim that the service is end-to-end encrypted or zero knowledge.
  • Sending real photos or any photo-derived data to AI, even to improve summaries or artwork.
  • Selecting exact production AI models before the approved evaluations pass.

User Personas / Stakeholders

Users

  • Arun — archive owner, sole user, administrator, and data subject:
    • Already writes in VoiceNotes and can send photos through Telegram.
    • Wants capture to disappear into existing habits, while the web experience focuses on reflection and management.
    • Needs to trust that the displayed record is authentic, correctable, private, explainable, and recoverable.
    • Chooses provider settings, supplies runtime credentials through a secure path, resolves date/conflict states, and performs destructive or spend-bearing actions.
    • Is the only human identity authorized to access the product.
  • Secondary users: None. VoiceNotes, Telegram, Cloudflare, Hetzner, selected AI providers, Cloudflare R2, and Backblaze B2 are external systems/processors, not personas or independent product stakeholders.
  • Decision authority: Arun. Product Council agents advise and create artifacts but do not authorize evaluation, implementation, secret use, deployment, or launch.

Requirements

Requirements use stable LID-* identifiers. Each row contains testable acceptance criteria and a source reference. P0 means MVP/launch-blocking; P1 means an explicitly approved follow-on only after MVP; P3/P4 means deferred backlog and must not leak into MVP scope.

Source abbreviations: DISC = confirmed discovery requirements; SHARED = proposed shared understanding; TEXT = AI text evaluation; ART = AI artwork evaluation; STORE = media storage evaluation; CTX = canonical language.

Requirements

Product boundary and canonical record

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want one private archive so that my memories are not exposed or mixed with other users. LID-SCP-001 — Single-user product boundary. The product is named Life in Days, is planned for life.arunp.in, and has exactly one human user. No sharing, invitations, public links, anonymous journal routes, or multi-user records exist.
Acceptance: An unauthenticated or non-allowlisted request cannot access HTML, APIs, media, search, or exports; no UI offers sharing/publication; product copy describes a private memory archive, not a coach.
Source: DISC § Product and audience; DISC § Access, lifecycle, and operations.
Cloudflare Access; owner allow policy Design artifact pending
P0 As Arun, I want every item attached to the correct Indian calendar day while retaining its real capture time. LID-SCP-002 — Journal Day and time semantics. A Journal Day represents one editable Journal Date in fixed Asia/Kolkata. Every Source Item retains an immutable Original Timestamp and origin. A Journal Date change never mutates that evidence.
Acceptance: Date derivation uses Asia/Kolkata, including boundary tests around midnight; displayed en-IN dates and stored instants remain unambiguous; unsupported future Journal Dates are not admitted to the calendar.
Source: DISC § Daily model and provenance; CTX Journal Day, Journal Date, Original Timestamp.
Time library with IANA timezone data Calendar/date-state mockups pending
P0 As Arun, I want authentic memories kept separate from generated presentation so that I always know what is real. LID-SCP-003 — Source/derived separation. Voice Journals, Uploaded Journals, and Daily Photos remain separate Source Items. Titles, summaries, tags, Visual Briefs, and Generated Artwork are versioned Derived Artifacts linked to exact source revisions and never replace source truth.
Acceptance: UI labels origin and AI status; database/export representation distinguishes sources, Corrections, revisions, and derived versions; no derived field is displayed as a transcript or real photo.
Source: DISC § Daily model and provenance; CTX Source Item, Derived Artifact.
Domain model; provenance schema Day-detail mockups pending
P0 As Arun, I want empty shells hidden from reflection while retaining audit history. LID-SCP-004 — Journal Day visibility. A Journal Day with no live Source Items is absent from the ordinary calendar and timeline even if historical Derived Artifacts remain. Its retained history remains reachable from management/history views for audit or restoration.
Acceptance: Removing/restoring the last live source hides/restores the day atomically; search defaults do not surface the hidden day; history view can still locate it by exact date.
Source: DISC § Reflection experience.
Source lifecycle; history view History-state mockup pending

Telegram photo capture

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want only my private bot conversation accepted so that outsiders cannot add photos. LID-TG-001 — Telegram authorization. Accept updates only when Telegram's webhook secret is valid and both the numeric sender ID and private-chat ID exactly match runtime configuration. Reject groups and every other sender/chat. Forwarded photos are eligible only when sent by the configured user in the configured private chat.
Acceptance: Tests reject wrong/missing secret, sender, chat, and group contexts before media download; IDs and bot token are runtime secrets/configuration, never source constants or logs.
Source: DISC § Access, lifecycle, and operations.
Telegram Bot API; runtime secrets Bot response copy pending
P0 As Arun, I want to send normal photos or image documents while understanding Telegram's quality behavior. LID-TG-002 — Telegram message forms. Accept Telegram compressed photo messages and still-image documents. Preserve the exact bytes supplied by Telegram. The UI/bot explains that ordinary photo messages may be recompressed and that image documents are the original-quality path.
Acceptance: The largest documented Telegram photo rendition is fetched for a photo message; document bytes are fetched unchanged; both create Daily Photos with message/update provenance.
Source: DISC § Capture surfaces; RESEARCH § Telegram.
Telegram getFile; content decoder Capture guidance pending
P0 As Arun, I want unsafe or unsupported media rejected clearly rather than corrupting the archive. LID-TG-003 — Image validation and limits. Accept decoded still-image JPEG, PNG, WebP, HEIC, and HEIF documents. Reject animated images, SVG, TIFF, PDF, RAW, files over 20 MB, images over 100 megapixels, and dimensions over 20,000 pixels. Determine format from decoded content, not filename alone.
Acceptance: Every rejection returns a specific Telegram explanation and creates no partial Source Item; malformed/decompression-bomb fixtures are safely contained; accepted Originals retain exact received bytes.
Source: DISC § Capture surfaces.
Sandboxed/resource-limited image decoder Error-state copy pending
P0 As Arun, I want confirmation only after my photo is safely stored. LID-TG-004 — Durable capture acknowledgement. Acknowledge a valid-dated Telegram image only after the encrypted Original, privacy-safe thumbnail, and required metadata commit durably; include the assigned Journal Date and a private link to change it. For an invalid/future explicit date, send a durable-preservation/Needs Date Review notice instead of claiming a Journal Date. Do not automatically delete successfully imported Telegram messages.
Acceptance: A failure before durable commit returns an error and no success/preservation acknowledgement; Needs Date Review notification occurs only after its encrypted media and holding record are durable; retrying the same update is idempotent; links require normal human authentication.
Source: DISC § Capture surfaces; DISC § Access, lifecycle, and operations; STORE § Capture and derivation flow.
Media store; database transaction; app URL Bot acknowledgement pending
P0 As Arun, I want a photo dated automatically or explicitly backdated from its caption. LID-TG-005 — Photo dating and media groups. Default Journal Date comes from Telegram receipt time converted to Asia/Kolkata. A caption beginning with an exact valid YYYY-MM-DD assigns that date to the photo or its Telegram media group. The remaining caption becomes the Photo Caption.
Acceptance: Leading-date parsing is anchored and exact; whitespace handling is deterministic; grouped messages sharing media_group_id receive the instruction consistently without requiring an undocumented album-complete event; receipt and source timestamps remain retained.
Source: DISC § Capture surfaces; RESEARCH § Telegram.
Date parser; media-group/idempotency handling Date-caption examples pending
P0 As Arun, I want mistyped or future dates held safely for correction. LID-TG-006 — Needs Date Review for invalid/future dates. A leading invalid date or future date durably preserves the encrypted photo and an undated holding record in Needs Date Review, excludes it from calendar/timeline, and sends a Telegram explanation. It must not silently fall back to receipt date. Valid historical backdating is allowed.
Acceptance: The holding record can exist without a Journal Day only in Needs Date Review; review exposes preview, source timestamp, proposed text, and date correction; selecting a valid non-future date atomically attaches the Source Item/Daily Photo to its Journal Day; abandoned review items remain recoverable/manageable.
Source: DISC § Capture surfaces; CTX Needs Date Review.
Review queue; date validation Review-state mockup pending
P0 As Arun, I want all photos for a day available in a controllable gallery. LID-TG-007 — Daily Photo gallery and real cover. There is no product-level photo-count limit. Daily Photos initially display chronologically. The first is default Calendar Cover; Arun can reorder photos and select another real-photo cover.
Acceptance: Reordering is persistent; the cover is one live Daily Photo whenever any exists; deleting/redating the cover deterministically selects the next eligible real photo and never silently promotes artwork while another real photo remains.
Source: DISC § Capture surfaces; DISC § AI boundary.
Journal Day gallery; cover selector Calendar/gallery mockups pending
P0 As Arun, I want duplicate protection without preventing a legitimate reuse on another date. LID-TG-008 — Global checksum deduplication. Detect identical plaintext image checksums globally. A same-day resend is acknowledged as already imported and offers Add duplicate anyway; a different-day duplicate warns but is permitted. Duplicate Daily Photos reference one encrypted Media Asset rather than storing bytes twice.
Acceptance: Add Anyway creates a distinct Source Item/reference, not a second physical object; cross-day use is visible; concurrent duplicates cannot race into duplicate physical storage.
Source: DISC § Access, lifecycle, and operations; CTX Media Asset.
Checksum index; Media Asset reference counting Duplicate-warning state pending
P0 As Arun, I want searchable context without sending caption text to AI. LID-TG-009 — Photo Captions. Preserve caption text after an optional leading date, display it with the photo, and include it in exact lexical search. Exclude Photo Captions from all MVP AI input and Visual Brief construction.
Acceptance: Search finds exact caption terms; AI request contract tests prove caption fields are absent; correcting/redating a photo does not discard the caption.
Source: DISC § Capture surfaces; DISC § Reflection experience.
Search index; AI serializer allowlist Caption display pending
P0 As Arun, I want web-friendly images without altering my originals or leaking metadata. LID-TG-010 — Local image derivatives. Preserve each Original unchanged and generate thumbnails locally. Display orientation correctly and remove EXIF/IPTC/XMP from thumbnails. No Original or derivative is sent to AI.
Acceptance: Original checksum remains byte-identical after ingestion/export/restore; derivative metadata inspection finds no source metadata; failures do not overwrite or substitute the Original.
Source: DISC § Capture surfaces; STORE § Capture and derivation flow.
Local media processor; encryption Thumbnail states pending

VoiceNotes journal capture

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want the integration proven before personal journals depend on undocumented behavior. LID-VN-001 — Synthetic integration gate. Before freezing or implementing the production contract, a synthetic spike must prove webhook-to-MCP note identity, payload handling, authoritative retrieval, unattended OAuth renewal, tag/date/transcript access, reconciliation, and relevant error/rate behavior. If a material assumption fails, reopen the affected product/architecture decision; do not improvise a different behavior.
Acceptance: A written spike result records evidence and unresolved gaps; no personal journal is used; failed identity/auth/reconciliation gates block production enablement.
Source: DISC § Capture surfaces; DISC § Decision frontier; RESEARCH § VoiceNotes.
VoiceNotes test account/credentials supplied later N/A — integration evidence artifact
P0 As Arun, I want webhooks to trigger reliable retrieval without treating an incomplete event as source truth. LID-VN-002 — Webhook wake signal and authoritative MCP retrieval. Treat VoiceNotes webhooks only as change notifications. Retrieve exact tags, creation time, and transcript through the official MCP surface validated by the spike. Never assume the webhook transcript is complete.
Acceptance: Duplicate/out-of-order wakeups are idempotent; callback handling does not directly overwrite a source transcript; a failure leaves visible reconciliation state and is recoverable by a later reconciliation.
Source: DISC § Capture surfaces; RESEARCH § VoiceNotes.
Successful LID-VN-001; callback receiver; MCP client System Health/reconciliation state pending
P0 As Arun, I want only intentional prospective notes imported. LID-VN-003 — Exact tag and Integration Activation. Automatically import only notes with the exact tag life-in-days whose VoiceNotes creation timestamp is at or after the recorded Integration Activation instant. Never use fuzzy matching or broad tags. Editing/tagging a pre-activation note never imports it automatically.
Acceptance: Boundary fixtures before/equal/after activation behave deterministically; activation cannot be backdated through settings; explicit manual uploads/backdating remain allowed.
Source: DISC § Capture surfaces; CTX Integration Activation.
Authoritative creation/tag retrieval Integration settings pending
P0 As Arun, I want imported journals assigned by their real creation time, not webhook timing. LID-VN-004 — Voice Journal dating. Initial Journal Date comes from the VoiceNotes creation timestamp converted to Asia/Kolkata. If that timestamp is unavailable or untrusted, the durably retrieved Source Item enters Needs Date Review instead of using webhook receipt time.
Acceptance: Missing-date items retain encrypted content, opaque source identity, and a nullable Journal Day only while in the holding state; no calendar placement occurs before resolution; corrected Journal Date leaves Original Timestamp evidence intact.
Source: DISC § Capture surfaces.
LID-VN-002; Needs Date Review Review-state mockup pending
P0 As Arun, I want missed and duplicate events reconciled without duplicating or deleting memories. LID-VN-005 — Replay-safe reconciliation. Periodically reconcile eligible authoritative notes to recover missed, repeated, or out-of-order wakeups. Use stable opaque source identity and revision identity; never depend on webhook delivery guarantees not documented by VoiceNotes.
Acceptance: Replaying the same state is idempotent; a new upstream version creates one Source Revision; absent/failed pages abort reconciliation rather than treating a partial list as deletion.
Source: DISC § Daily model and provenance; RESEARCH § VoiceNotes.
Proven spike contract; reconciliation scheduler Health/history states pending
P0 As Arun, I want upstream edits, untagging, and deletion visible without silently losing the local memory. LID-VN-006 — Upstream lifecycle. An upstream edit creates a Source Revision. Untagging or deleting an imported note updates its upstream status but never silently erases the local Source Item. Every upstream version remains retained according to local lifecycle rules.
Acceptance: History identifies upstream status and revision timestamps; ordinary day display follows the selected/displayed revision or Correction; reconciliation cannot delete a local item by absence alone.
Source: DISC § Daily model and provenance.
Revision model; reconciliation Revision-history mockup pending
P0 As Arun, I want local deletion to stay deleted even though VoiceNotes remains untouched. LID-VN-007 — Source Suppression and re-import control. Deleting a Voice Journal never edits or deletes VoiceNotes. A local Source Suppression prevents reconciliation from resurrecting it. Restoring from Trash removes suppression. After permanent local deletion, retain only the opaque upstream identifier needed for suppression. Allow re-import explicitly removes it.
Acceptance: Reconciliation respects suppression at every lifecycle stage; export/restore preserves deletion intent; Allow re-import produces a visible confirmation before a later reconciliation can import again.
Source: DISC § Access, lifecycle, and operations; CTX Source Suppression.
Trash; suppression store Destructive-action confirmation pending

Uploaded journals, revisions, and Corrections

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want to add a journal text file globally or from a date. LID-UP-001 — Manual journal upload. Accept UTF-8 .txt and .md files up to 1 MiB. A Journal Day upload inherits that date; a global upload requires an explicit valid Journal Date. Multiple files may belong to one day.
Acceptance: Invalid encoding, extension, oversize input, missing global date, or future date is rejected clearly without partial data; upload is keyboard accessible and available from both entry points.
Source: DISC § Capture surfaces; DISC § Reflection experience.
Authenticated upload; date picker Upload-flow mockup pending
P0 As Arun, I want each uploaded file preserved as its own authentic source. LID-UP-002 — Uploaded Journal preservation. Preserve the original file bytes, filename as source title, Original Timestamp for receipt, checksum, and chosen Journal Date. Do not concatenate multiple files into one source or treat Markdown formatting as generated text.
Acceptance: Export and restore reproduce each original file and metadata; chronological day display keeps sources separate.
Source: DISC § Capture surfaces; CTX Uploaded Journal.
Encrypted file storage; source model Source-list mockup pending
P0 As Arun, I want duplicate-file protection with an explicit override. LID-UP-003 — Uploaded Journal duplicate handling. An exact duplicate upload warns and requires Add Anyway to create another Source Item.
Acceptance: A dismissed warning creates nothing; Add Anyway creates a distinct source reference with no ambiguous overwrite; concurrent submissions are idempotent.
Source: DISC § Capture surfaces.
Checksum index Duplicate-warning state pending
P0 As Arun, I want to correct display text without rewriting evidence. LID-SRC-001 — Corrections and immutable revisions. A Correction may replace displayed journal text or Journal Date while leaving original source content and every Source Revision intact. Corrections record author/time and the source revision they were based on.
Acceptance: History and export can reconstruct source, revisions, and Corrections; UI never labels a Correction as upstream text; removing a Correction restores the selected upstream display without deleting history.
Source: DISC § Daily model and provenance; CTX Correction.
Revision/correction data model Correction editor and diff pending
P0 As Arun, I want a clear choice when VoiceNotes changes after I corrected it. LID-SRC-002 — Source/Correction conflict resolution. Never auto-merge personal journal text. Show differences and exactly three actions: keep the Correction, display the newest upstream revision, or create a new Correction based on both.
Acceptance: Conflict persists until an explicit action; all source revisions and prior Corrections remain; each action has a preview and produces a deterministic displayed version.
Source: DISC § Daily model and provenance.
Diff viewer; revision/correction model Conflict-resolution mockup pending
P0 As Arun, I want to move a photo or journal to another date without losing derived-state integrity. LID-SRC-003 — Atomic redating. Redating updates the old and new Journal Days atomically while preserving Original Timestamp. Recalculate real-photo cover, generated-art cover eligibility, search/day visibility, and stale state on both days.
Acceptance: Transaction failure leaves both days unchanged; untouched text fields may refresh; Protected Fields remain and become stale; artwork bound to a source set no longer on that day leaves active gallery/cover but remains in history.
Source: DISC § Daily model and provenance.
Transaction boundary; stale-state engine Redate preview pending
P0 As Arun, I want obsolete artwork/history retained without confusing staleness with redating. LID-SRC-004 — Source-set binding. Each Derived Artifact binds to an exact ordered source-revision/Correction set. A same-day late journal, Source Revision, or Correction marks affected artwork stale but leaves it visible and labeled as based on an earlier journal version. Only when a bound source no longer belongs to that Journal Day, such as after redating, does the artwork leave the active gallery/cover while remaining in version history.
Acceptance: Concurrent source changes cannot attach an output to the wrong revision; current/stale/historical labels are visible and exported; same-day staleness never hides artwork automatically, while cross-day source removal cannot leave it presented as active for the wrong day.
Source: DISC § Daily model and provenance; TEXT § Production inference contract; ART § Required generation record.
Generation provenance; source hashing History/version mockup pending
P3 As Arun, I may later want more manual writing formats without changing the MVP writing habit. LID-UP-004 — Deferred composition/import. Blank browser composition and PDF, Word, and OCR journal ingestion remain backlog only.
Acceptance: MVP UI and implementation plan contain no hidden editor/OCR scope; unsupported formats state what is accepted.
Source: DISC § Explicitly deferred.
Post-MVP decision N/A

Reflection, browsing, and management

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want a visual month that lets each populated date evoke the day. LID-REF-001 — Image-first month calendar. Show a Monday-first month calendar using en-IN formatting. A populated date uses its Calendar Cover; dates without a live source are visually empty and do not expose historical artifacts as a current day.
Acceptance: Keyboard and touch navigation work across months; cover changes/redating update the correct cell; real-photo cover policy is always enforced; generated covers display an AI artwork label in accessible detail.
Source: DISC § Reflection experience; SHARED § Reflection experience.
Calendar Cover selector; responsive design Primary calendar mockup required
P0 As Arun, I want to browse memories chronologically beyond a single month. LID-REF-002 — Timeline. Provide a chronological visual timeline of live Journal Days using the same cover and source-count semantics as the calendar.
Acceptance: Ordering is by Journal Date in Asia/Kolkata; exact navigation opens the same Journal Day detail; hidden/Trash-only days are excluded.
Source: DISC § Reflection experience.
Journal Day query; covers Timeline mockup required
P0 As Arun, I want exact and predictable retrieval rather than fuzzy AI guesses. LID-REF-003 — Lexical search. Deterministically search currently displayed journal text, title, summary, tags, and Photo Captions by exact text/date/tag criteria. Trash and superseded Source Revisions are excluded by default and included only through Include history.
Acceptance: Result snippets identify field/source and Journal Date; corrections replace source text in default search without deleting source history; no semantic/conversational expansion occurs.
Source: DISC § Reflection experience.
Local search index; lifecycle filters Search/results mockup required
P0 As Arun, I want one complete, trustworthy view of a selected date. LID-REF-004 — Journal Day detail. Present Calendar Cover, real-photo gallery, visibly labeled Generated Artwork, generated title/summary/tags, source journals in chronological order, Photo Captions, original timestamps, source/provider provenance, upload controls, history, and management actions.
Acceptance: Authentic and AI content are visually/semantically distinguishable; all controls expose status and failure states; original source remains readable while generation is pending/failed.
Source: DISC § Reflection experience.
All capture/derived domains Primary detail mockup required
P0 As Arun, I want reflection to feel beautiful without compromising readability or control. LID-REF-005 — Visual system and motion. Use quiet photographic direction, warm paper-like light theme, deep-ink dark theme, restrained typography, and restrained motion. Honor OS reduced-motion settings.
Acceptance: Both themes preserve WCAG 2.2 AA contrast targets; no motion is required to understand state; large text and browser zoom do not hide actions or content.
Source: DISC § Reflection experience.
Design tokens; accessibility review UI/UX council artifact required
P0 As Arun, I want the archive usable from current desktop and phone browsers. LID-REF-006 — Responsive/browser/accessibility support. Support current two major versions of Chrome, Edge, Firefox, and Safari plus current iOS Safari and Android Chrome. All core flows are keyboard operable, focus-visible, screen-reader labeled, and responsive. A Daily Photo may have an optional owner-authored private accessibility description; it is local metadata, is exported, and is never AI-generated or sent to AI.
Acceptance: Browser matrix covers capture management, calendar, search, detail, settings, export, and health; photo controls/names remain operable without an image description; when supplied, the private description is the image's text alternative; legacy browsers and offline use receive no compatibility promise.
Source: DISC § Reflection experience; DISC § AI boundary.
Cross-browser test plan; semantic components; local accessibility annotation Responsive specs required
P0 As Arun, I want irreversible or source-changing actions explicit and understandable. LID-REF-007 — Management safety. Web controls support Correction, redating, cover selection, reordering, deletion/restore, permanent deletion, Allow re-import, artwork generation/regeneration, artwork suppression removal, export, and provider selection with context-appropriate confirmation.
Acceptance: Destructive/spend-bearing actions state effects before confirmation; actions are idempotent; success/failure feedback never implies source/upstream mutation when none occurred.
Source: DISC throughout; SHARED throughout.
Action authorization; lifecycle services Management-state mockups required

AI text derivation and provider control

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want provider choices based on journal-specific evidence rather than reputation. LID-AIT-001 — Text-model evaluation gate. Run the approved 32-fixture, three-repeat, blinded text protocol across gpt-4o-mini-2024-07-18, gpt-5.6-luna, gpt-5.6-terra, gemini-3.1-flash-lite, gemini-3.5-flash-lite, and gemini-3.5-flash; use claude-haiku-4-5-20251001 and claude-sonnet-5 only as external controls. Use synthetic fixtures initially and enforce the shared one-time $15 ceiling with the artwork evaluation. These are evaluation candidates, not selected product options.
Acceptance: Frozen prompts/schema, randomized grading, fact inventories, cost/latency/provenance results, and hard-gate outcomes are recorded; personal journals/photos/identifiers are absent; spend stops before $15; no model is exposed before passing.
Source: DISC § AI boundary; TEXT § Required bake-off.
Explicit shared-understanding confirmation; later test credentials Evaluation scorecard only
P0 As Arun, I want independent, explicit AI processors with no surprise fallback. LID-AIT-002 — Text and Artwork Provider settings. Expose independent dropdowns of approved Text Provider/model and Artwork Provider/model configurations. MVP supports passing OpenAI and Google options only as earned by evaluations. A provider change affects future generations only; never silently fall back to another provider/model.
Acceptance: Disabled/unhealthy/unapproved models cannot be selected; existing artifacts retain provenance; an unavailable provider produces a visible retry/change-provider path and sends no data elsewhere without explicit action. If a provider has no passing model, expose no failing model merely for coverage and return the decision to Arun.
Source: DISC § AI boundary; TEXT/ART selection rules.
Evaluation results; credential-health check Settings mockup required
P0 As Arun, I want a concise factual presentation while the full journals remain available. LID-AIT-003 — Text output contract. For a Journal Day with eligible journal text, create one concise title, one factual 80–140-word summary, 3–7 short unique searchable tags, and a 150–300-token Visual Brief. Output is warm and observational, with no invented facts, coaching, diagnosis, moral judgment, or unstated emotion.
Acceptance: Provider-native structured output is validated atomically; invalid/partial fields do not replace current artifacts; output remains labeled as AI-generated and versioned beside complete sources.
Source: DISC § AI boundary; TEXT § Output schema.
Selected Text Provider; schema validator Generated-content states pending
P0 As Arun, I want automatic generation after my day's text settles, without losing late updates. LID-AIT-004 — Quiet period and final refresh. Automatic title, summary, tags, and Visual Brief generation waits 15 minutes after the latest journal-source change. At 01:00 Asia/Kolkata on the following day, untouched fields receive a final refresh when their source set changed. Later source changes mark artifacts stale and may refresh only unprotected fields.
Acceptance: Repeated changes coalesce; schedules survive restart and are idempotent; Finalization Time does not lock the day against later sources/Corrections; outputs bind to the revision set observed at completion.
Source: DISC § AI boundary; CTX Source Quiet Period, Finalization Time.
Durable scheduler/job queue; stale engine Pending/refresh states pending
P0 As Arun, I want my edits and accepted wording preserved. LID-AIT-005 — Per-field protection and replacement review. Title, summary, and tags are independently editable. Manual edit or explicit accept/select of a generated version protects that field. Later source changes mark it stale and offer a generated replacement for review; never overwrite. Resume automatic updates removes protection for only that field.
Acceptance: Protection state is independent across all fields; keep/current/replacement versions remain traceable; accepting a replacement protects it; resume is explicit and does not affect siblings.
Source: DISC § AI boundary; CTX Protected Field.
Versioned fields; replacement-review UI Field/version mockups required
P0 As Arun, I want the minimum approved personal text sent to the chosen provider. LID-AIT-006 — Text request privacy boundary. Send deterministic, ordered, normalized journal text with source boundaries and only minimum date/language hints. Never send photos, photo derivatives/metadata, captions, Telegram/VoiceNotes account IDs, names added by the application, internal IDs, credentials, or unrelated context. Treat journal text as untrusted quoted data, use stateless requests, disable provider storage/caching where the selected verified surface allows, and use no files/tools/grounding/persistent sessions.
Acceptance: Contract tests inspect serialized requests; configuration health fails if required privacy controls cannot be confirmed; settings accurately describe provider retention without claiming zero retention or India-local processing.
Source: DISC § AI boundary; TEXT § Privacy and production contract.
Provider adapters; allowlisted serializer Privacy disclosure/settings pending
P0 As Arun, I want AI failures visible while my source remains usable. LID-AIT-007 — Text generation failures and provenance. Retry selected-provider timeout/429/transient 5xx up to three times with bounded backoff, jitter, and Retry-After. Retry invalid schema once with the same provider/model. Stop on auth/quota/billing errors. Treat safety refusal, partial output, source-race, and exhaustion as visible non-destructive states.
Acceptance: No failure mutates source or current protected fields; source-hash comparison rejects stale completion; attempt records contain provider/requested-returned model, prompt/schema versions, revision set, request ID, tokens, cost, latency, retry/refusal/error state without raw text/payloads in logs.
Source: TEXT § Failure and safety behavior; DISC § AI boundary.
Async generation jobs; sanitized provenance store Error/retry states required

Generated Artwork

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want artwork models chosen by a blind style and trust test. LID-AIA-001 — Artwork evaluation gate. Run the approved ten-prompt blind stage across gpt-image-2-2026-04-21, gemini-3.1-flash-lite-image, gemini-3.1-flash-image, and gemini-3-pro-image, then a second blind uncurated run for the best passing OpenAI and Google options. Use synthetic prompts only and share the combined $15 evaluation ceiling with text. These are candidates, not selected product options.
Acceptance: Contract/privacy/lifecycle/permanent-retention/4:5 gates run before scoring; originals/provenance/randomization manifests are preserved; no personal journal/photo is used; hard stop occurs before $15. Ship one passing OpenAI and one passing Google option; optional economy/premium entries must earn inclusion under the frozen score/cost/latency rules, and a hard-gate failure returns to Arun.
Source: DISC § AI boundary; ART § Required blind bake-off.
Explicit confirmation; later test credentials Blind review artifact only
P0 As Arun, I want artwork based on a minimized, inspectable description rather than my full journal. LID-AIA-002 — Read-only Visual Brief. The Text Provider creates a source-grounded 150–300-token Visual Brief. It is the sole personal-content input to the Artwork Provider. Display it read-only. Regenerate brief creates a new text-derived version; artwork retries are always explicit. No free-form editing is allowed in MVP.
Acceptance: Artwork request serialization contains only the brief and fixed style/configuration; it excludes raw journal, names, photos, captions, identifiers, and photo-derived descriptions; brief versions bind to source revisions.
Source: DISC § AI boundary; CTX Visual Brief.
Passing Text Provider; artwork adapter Brief/history mockup required
P0 As Arun, I want to request artwork as soon as journal text exists. LID-AIA-003 — Manual Artwork Request. Show Generate artwork now when at least five meaningful journal words exist. From 5–19 words, warn that the source is sparse. At 20+ words, allow without sparse warning. Below five, disable with an explanation. Manual request need not wait for the 15-minute quiet period or 01:00 sweep.
Acceptance: Manual request is available whether or not Daily Photos or prior artwork exist, subject to safety, credential, provider, and budget gates; confirmation shows provider/model and estimated budget effect.
Source: DISC § AI boundary; CTX Artwork Request.
Word-count rule; provider/budget health Artwork action states required
P0 As Arun, I want missed image-less journal days filled automatically without reminders. LID-AIA-004 — 01:00 Artwork Sweep. At 01:00 Asia/Kolkata, scan every eligible post-Integration-Activation Journal Day missed due to outage. Generate only when there are at least 20 meaningful journal words, no live Daily Photo, no Generated Artwork, no Artwork Suppression, an automatic-sweep-eligible approved model, and budget/credential/safety gates pass.
Acceptance: Sweep is idempotent and restart-safe; it does not generate for empty/pre-activation/photo-backed/suppressed/ineligible days; skipped/failed reasons remain visible; no habit reminder is sent.
Source: DISC § AI boundary; CTX Artwork Sweep.
Durable scheduler; eligibility query System/empty-art states required
P0 As Arun, I want generated visuals evocative but never mistaken for documentary photos. LID-AIA-005 — Artwork style and labeling. Generate warm, painterly editorial illustration with restrained texture, quiet symbolic composition, no photorealistic reconstruction, recognizable likeness, readable words, logos, signatures, or imitation of a named living artist. Use a native or exact 4:5 composition without destructive central cropping. Display AI artwork wherever it appears.
Acceptance: Fixed style contract is versioned; original provider file is preserved; near-4:5 accepted output uses neutral non-destructive presentation rather than hidden crop; all calendar/detail/export contexts identify generated status even if C2PA/SynthID metadata is absent or stripped from derivatives.
Source: DISC § AI boundary; ART § Production visual brief/provenance.
Prompt template; visible-label component Visual-language examples required
P0 As Arun, I want safety refusals treated as ordinary missing art, not criticism of my journal. LID-AIA-006 — Artwork failure and safety behavior. Do not auto-retry safety refusals, modify source text, relax safety, or switch providers. Show an ordinary unavailable-artwork state and allow explicit Regenerate brief followed by explicit retry. Retry only transient errors with bounded idempotent behavior.
Acceptance: Raw journal/prompt is absent from operational logs; coarse provider refusal stage/category may be retained; blocked/failed art never affects source accessibility or Calendar Cover correctness.
Source: DISC § AI boundary; ART § Safety behavior.
Attempt state; error copy Refusal/retry mockup required
P0 As Arun, I want to compare and restore prior generated images. LID-AIA-007 — Artwork version lifecycle. Each successful generation/regeneration creates a retained version with complete source/provider/model/configuration/usage/safety/cost provenance. The newest success becomes Active Artwork by default; Arun can select an earlier version. There is no arbitrary count limit beyond budget and safety controls.
Acceptance: Download and checksum the returned original immediately rather than depending on a provider URL; selection does not delete later versions; failed attempts are not presented as versions; export/restore retains originals, derivatives, ordering, active selection, and history.
Source: DISC § AI boundary; ART § Required generation record.
Versioned artifact/media model Artwork-history mockup required
P0 As Arun, I want real photos always prioritized as the day's visual truth. LID-AIA-008 — Calendar Cover precedence. While any live Daily Photo exists, a selected real photo must be Calendar Cover and Generated Artwork cannot be selected as cover. When the first real photo arrives after artwork, it becomes cover; both remain in the gallery with clear labels. Artwork is cover-eligible only with no live Daily Photo.
Acceptance: Cover invariant holds under concurrent upload, redating, Trash, restore, reorder, and artwork selection; no UI action can bypass it.
Source: DISC § AI boundary; CTX Calendar Cover, Active Artwork.
Cover-selection invariant Calendar/gallery mockups required
P0 As Arun, I want deliberate removal of generated art respected by automation without losing my explicit manual action. LID-AIA-009 — Artwork Suppression. Removing all Generated Artwork from a Journal Day creates an Artwork Suppression that blocks only the automatic 01:00 Artwork Sweep. Allow generation removes suppression and re-enables future automatic sweep eligibility. An explicit manual Artwork Request remains available under its normal source, safety, provider, and budget gates and does not silently clear the suppression.
Acceptance: Automatic recreation remains blocked across restart, backup, export, and restore until Allow generation; manual generation remains explicit and traceable; suppression is not confused with Source Suppression; restoration/deletion state preserves intent.
Source: DISC § AI boundary; CTX Artwork Suppression.
Artifact lifecycle; suppression store Suppression confirmation pending
P0 As Arun, I want late journal changes handled without pretending an old image is current. LID-AIA-010 — Artwork staleness after text change. Late journal/Correction changes mark related artwork stale. Artwork regeneration is manual only and creates a new traceable version. Redating removes an artwork whose source set no longer belongs to the day from active gallery/cover but retains it in history until explicit action.
Acceptance: No automatic artwork regeneration occurs from a text change outside the 01:00 no-art eligibility rule; source-revision binding is shown; selecting a historical version does not relabel it as source-current.
Source: DISC § AI boundary; DISC § Daily model and provenance.
Stale engine; version history Stale-art state required
P0 As Arun, I want premium cost controlled by code, not a label. LID-AIA-011 — Approved model configuration. Artwork options are typed approved configurations, not free-form model strings. Persist provider, display label, exact model/snapshot, endpoint/API version, region, size, quality, format, safety, measured unit cost, lifecycle review date, enabled state, and automatic_sweep_eligible. Any premium model is manual-only and must have that flag false.
Acceptance: Moving aliases/unreviewed models cannot be entered from UI; lifecycle/credential-health failure disables new calls without deleting prior art; exact selection follows ART evaluation rules rather than this PRD naming a winner.
Source: DISC § AI boundary; ART § Configuration model/selection rules.
Evaluation result; settings service Provider settings mockup required

Privacy, security, storage, recovery, and operations

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P0 As Arun, I want one strong human access gate without another password database. LID-OPS-001 — Human authentication. Protect life.arunp.in with Cloudflare Access Free using Cloudflare's first-party identity provider, exact account-member allow policy, required MFA, and seven-day session. Validate the signed Access assertion at the application boundary. Do not build a second username/password layer.
Acceptance: Origin is loopback-only behind Tunnel; missing/invalid assertion is rejected; only the exact owner identity passes; session expiry reauthenticates; no journal route is exempted.
Source: DISC § Access, lifecycle, and operations; RESEARCH § Private web authentication.
Cloudflare account/tunnel; post-confirmation configuration approval Access/error screens pending
P0 As Arun, I want machine callbacks isolated from human journal routes. LID-OPS-002 — Callback boundary. Use life-hooks.arunp.in only for opaque Telegram and VoiceNotes callback paths. Serve no human journal route there. Telegram uses its secret plus user/chat allowlist; VoiceNotes authenticity/reconciliation controls depend on the validated spike and must not be invented.
Acceptance: Host/path routing rejects unknown routes/methods, has bounded request sizes/rate protection, and cannot access human media/session routes; callback payloads are sanitized from logs.
Source: DISC § Access, lifecycle, and operations; RESEARCH § Hosting facts.
Cloudflare Tunnel/DNS authorization later; LID-VN-001 N/A — machine interface
P0 As Arun, I want credentials outside code, content, exports, and logs. LID-OPS-003 — Secret management. Bot tokens, webhook secrets, provider credentials, storage keys, encryption keys, recovery material, and account identifiers are runtime-only secrets/configuration. Never hard-code, commit, log, export, send through Telegram, expose to client JavaScript, or store in journal rows. Treat any secret shared in chat/attachments as exposed and unusable.
Acceptance: Secret scanning and fixture inspection find no credentials; process permissions are least-privilege; rotation can occur without rewriting journal history; fresh secrets are requested only at the approved step that requires them.
Source: DISC § Access, lifecycle, and operations; TEXT/ART auth sections.
Secret deployment design ADR N/A
P0 As Arun, I want copied disks and object storage unreadable without my application key. LID-OPS-004 — Application-controlled encryption at rest. Encrypt journal data and every media object with authenticated, versioned application-controlled encryption at no additional service subscription. Runtime keys are server secrets; recovery material remains off server. State explicitly that a compromised running server can decrypt data and the product is not E2EE/zero knowledge.
Acceptance: Copying database/media/object bytes without keys reveals no journal/photo content; key/version metadata supports restore and rotation; no plaintext Original persists on ordinary disk or unencrypted swap.
Source: DISC § Access, lifecycle, and operations; STORE § Capture and derivation flow.
Post-confirmation encryption/key ADR; Recovery Ceremony Privacy/security explanation pending
P0 As Arun, I want image processing bounded on the small server and plaintext removed promptly. LID-OPS-005 — Secure media staging. Stage at most the approved 20 MB input in a bounded service-private memory-backed area, validate/decode in a resource-limited process, allow one media derivation job at a time on the 4 GB host, encrypt Original and thumbnail separately, verify durable ciphertext, then remove plaintext. Refuse startup/health if unencrypted swap is active; provide explicit temporary backpressure when staging is unavailable.
Acceptance: Crash/startup cleanup removes abandoned staging; input/decode limits prevent resource exhaustion; success is impossible before ciphertext verification; source bytes never enter general temp directories or logs.
Source: STORE § Capture and derivation flow; STORE § Approved direction.
Encryption ADR; media worker limits Operational state only
P0 As Arun, I want zero-cost launch storage with safe, testable growth. LID-OPS-006 — Live media storage and watermarks. Launch on encrypted existing-root storage with a 10 GB authoritative/root-resident quota. Warn/start migration at 7 GB media or 18 GB host free; provision/copy/dual-write no later than 8 GB or 15 GB free; direct new writes to target and finish proof at 9 GB or 13 GB free; reject new media at 10 GB while migration is incomplete or 12 GB host free. Never delete/downsample Originals to recover space. After verified object-store cutover, 10 GB is no longer a total archive cap, while the 12 GB host-free safety floor remains.
Acceptance: Use actual filesystem bytes; every threshold is visible in System Health and alerts; emergency stop preserves journal text, reads, backup, export, and deletion recovery; Telegram receives a clear failure.
Source: DISC § Access, lifecycle, and operations; STORE § Capacity controls.
Storage metrics; media-store abstraction Capacity state pending
P0 As Arun, I want live media to scale without coupling primary and backup storage. LID-OPS-007 — R2 migration target and verified cutover. Implement storage-neutral media metadata/API from the outset. Scale to private Cloudflare R2 Standard created in the EU jurisdiction; keep application-layer ciphertext and serve through same-origin authenticated app routes. Use random opaque object keys and no dates, names, journal text, Telegram IDs, filenames, or plaintext checksums in bucket names, keys, or provider metadata. Do not pre-purchase a Hetzner Volume. Cutover only after complete paginated inventory reconciliation, verified hashes/counts, fail-closed remote-to-Restic snapshot/restore, dual-write/copy proof, reversible pointer migration, and seven days of observed target reads.
Acceptance: No partial list is treated as complete; no local authoritative copy is evicted until both live object and Restic recovery copy verify; provider URLs/credentials never reach browser; R2 IA/public r2.dev are not used.
Source: DISC § Access, lifecycle, and operations; STORE § Safe migration sequence.
Storage ADR; R2 account later; Restic remote-source design Migration runbook pending
P0 As Arun, I want private rendering through one authorization boundary. LID-OPS-008 — Media delivery and caching. Use authenticated same-origin routes to stream/decrypt thumbnails and Originals. Return Cache-Control: private, no-store for personal HTML, API, media, downloads, search, and exports; enforce shared-cache bypass for authenticated/personal paths. Only content-hashed application assets with no personal data may be shared-cacheable.
Acceptance: No public bucket/provider URL or decryption key reaches browser; alternate object-store public paths are disabled; query strings/signed URLs are absent from logs.
Source: DISC § Access, lifecycle, and operations; STORE § Read path/cache policy.
Cloudflare cache rules; media proxy Media viewer/download states pending
P0 As Arun, I want deleting one duplicate reference not to destroy another day's photo. LID-OPS-009 — Media Asset reference lifecycle. Delete a live Media Asset only after no live or Trash Daily Photo references it. Trash references keep ciphertext available. Backup copies expire through normal retention rather than selective snapshot rewriting.
Acceptance: Reference counting is transactional under same-day Add Anyway, cross-day duplicate, redating, Trash, restore, and permanent delete; no dangling live reference or premature physical deletion occurs.
Source: DISC § Access, lifecycle, and operations; CTX Media Asset.
Media reference model; Trash Management state pending
P0 As Arun, I want accidental deletion reversible for 30 days. LID-OPS-010 — Trash and permanent live deletion. Deleted content enters Trash for 30 days, is absent from ordinary views/search, and can be restored. After the period, permanent live deletion removes content according to reference/suppression rules. Encrypted backup copies expire under backup retention rather than being selectively rewritten.
Acceptance: Restore returns the item and recalculates day/cover/stale state; permanent deletion requires explicit confirmation; permanently deleted content is not reconstructed by export/restore except the opaque suppression identity.
Source: DISC § Access, lifecycle, and operations; CTX Trash.
Lifecycle scheduler; media references; suppressions Trash/restore mockup required
P0 As Arun, I want an independent encrypted recovery path with proof, not just successful uploads. LID-OPS-011 — Backup and restore. Create application-consistent encrypted Restic snapshots in a private Backblaze B2 EU Central bucket with no Object Lock/lifecycle rule that breaks Restic. Retain 48 hourly, 30 daily, and 12 monthly snapshots. Back up database export, sources/files, all current/historical media/artifacts, manifest, and minimal rebuild configuration without runtime secrets.
Acceptance: Backup failure/repository check failure is visible; monthly restic check plus sampled database/photo restore succeeds; quarterly full drill restores into a disposable environment and measures against four hours; a completed upload alone is never called restore evidence.
Source: DISC § MVP and recovery; RESEARCH § Backup; STORE § Backup interaction.
B2 bucket/key later; backup runbook System Health only
P0 As Arun, I want launch blocked until I can actually recover encrypted content. LID-OPS-012 — Recovery Ceremony. Before production launch, prove two independent off-server recovery-key copies: one in Arun's password manager and one sealed offline. Use the material to restore and decrypt a representative archive sample.
Acceptance: Ceremony records date, sample scope, key-copy locations by non-secret description, restoration result, and owner sign-off; no key value enters Git/docs/logs; launch gate cannot be manually bypassed without a new explicit decision.
Source: DISC § MVP and recovery; CTX Recovery Ceremony.
LID-OPS-004; LID-OPS-011 Recovery checklist pending
P0 As Arun, I want a portable archive that preserves both memories and lifecycle intent. LID-OPS-013 — Restorable export. Produce a ZIP containing JSON, Markdown, browsable HTML, original source files/photos, Generated Artwork, revisions, checksums, and manifest. Clearly separate Trash and Source/Artwork Suppressions. Never reconstruct permanently deleted content; export only the opaque source identifier needed for enduring suppression.
Acceptance: Default export uses AES-256 ZIP with a one-time passphrase never stored; unencrypted export requires explicit privacy warning; server artifact is deleted after first successful download or one hour; an import/restore validation proves the package is internally complete. Before implementation, an export-lifecycle ADR must prove non-persistent passphrase handoff, restart behavior, partial-file cleanup, and the exact server-observable definition of a successful download.
Source: DISC § Access, lifecycle, and operations.
Export lifecycle ADR; lifecycle model; encryption library Export flow required
P0 As Arun, I want local health visibility without surveillance. LID-OPS-014 — System Health. Private System Health shows last successful Telegram capture, VoiceNotes reconciliation, backup, sampled restore, remaining host/root-media/object-store capacity, AI spend/allocation, provider credential health, and relevant staging/swap invariants. It distinguishes unknown, never run, success, delayed, failed, and blocked.
Acceptance: Values come from durable operational evidence, not optimistic job starts; personal content and secrets are absent; stale/failure states link to safe diagnostics/actions.
Source: DISC § Access, lifecycle, and operations; STORE § Capacity.
All job/state domains Health dashboard mockup required
P0 As Arun, I want operational alerts without journaling pressure. LID-OPS-015 — Telegram operational alerts only. Send Telegram alerts only after repeated photo-ingestion, VoiceNotes-reconciliation, or backup failure. Capacity and restore state remain visible in System Health unless a later explicit decision expands the Telegram alert list. Do not send journaling reminders, missing-photo nudges, streak messages, or coaching.
Acceptance: A single transient failure does not spam; repeated failure and recovery transitions are deduplicated; messages contain no journal text, caption, photo, prompt, secret, or signed URL.
Source: DISC § Access, lifecycle, and operations; DISC § MVP and recovery.
Alert state; Telegram allowlist Alert copy pending
P0 As Arun, I want useful diagnostics that never become a shadow copy of my journal. LID-OPS-016 — Logging and analytics boundary. Use no third-party analytics or crash-reporting service. Retain sanitized local structured logs for 30 days containing only timestamps, opaque identifiers, and error classes. Forbid journal text, prompts, captions, images, provider responses, credentials, tokens, auth assertions, and signed URLs.
Acceptance: Log-schema allowlist and redaction tests cover all integrations; retention deletes expired logs; support bundles/exports do not include runtime logs unless separately reviewed.
Source: DISC § Access, lifecycle, and operations.
Structured logger; retention job N/A
P0 As Arun, I want generation costs bounded without disabling the archive. LID-OPS-017 — AI budget enforcement. Enforce $5 total per calendar month, warn at 80%, reserve $0.50 for text/retries, and permit at most $4.50 for artwork. Predicted over-budget requests are blocked; manual art cannot bypass total or artwork limits. Evaluation spend uses a separate one-time $15 ceiling.
Acceptance: Meter every attempt where usage/cost is available; budget rollover follows one documented timezone/accounting rule; exhaustion stops automatic/manual art and over-budget AI calls but leaves capture, browsing, search, export, backup, Corrections, and non-AI management available. Existing-server, independent-backup, and live-storage costs are tracked separately and never consume or expand the AI ceiling.
Source: DISC § Access, lifecycle, and operations; ART § Cost behavior.
Usage ledger; provider pricing records Budget meter/settings required
P0 As Arun, I want honest expectations from a single-server personal service. LID-OPS-018 — Best-effort availability and failure isolation. Reuse the existing Hetzner server with no HA/SLA promise. Integration, AI, artwork, object store, or scheduled-job failure must not make authentic source browsing/correction unavailable when local data is healthy.
Acceptance: Restart recovery resumes idempotent jobs; provider outages remain visible without cross-provider fallback; storage emergency preserves non-media capabilities listed in LID-OPS-006; product copy makes no production-readiness claim before launch gates pass.
Source: DISC § Access, lifecycle, and operations; SHARED § Privacy, recovery, and operations.
Process supervision; durable jobs Offline/error states required

Deferred backlog contracts

Priority User Stories Requirements Dependencies Mock ups & Prototypes
P3 As Arun, I may later want to bring older VoiceNotes into the archive deliberately. LID-DEF-001 — Historical import deferred. No automatic/bulk historical import in MVP. A future capability must be separately specified with preview, exact selection, privacy, deduplication, spend, and rollback controls; current Integration Activation remains unchanged.
Acceptance: No MVP job, route, or setting enumerates/imports pre-activation VoiceNotes in bulk; a future tracker item remains blocked on a new approved requirement.
Source: DISC § Explicitly deferred.
New product decision N/A
P3 As Arun, I may later want optional resurfacing without turning the archive into a coach. LID-DEF-002 — Reflection features deferred. On This Day, weekly themes/reports, and other resurfacing remain backlog. Coaching, diagnosis, streaks, and pressure-based reminders require a new product decision and are not implied by this backlog.
Acceptance: MVP UI/jobs contain none of these surfaces or notifications; backlog wording does not authorize AI analysis of personal history.
Source: DISC § Explicitly deferred; RESEARCH § Product inspiration.
New privacy/UX requirements N/A
P4 As Arun, I may later want richer retrieval. LID-DEF-003 — Advanced search deferred. Semantic/conversational search and journal Q&A remain backlog and may not reuse current AI approval without a new retrieval, citation, disclosure, and cost boundary.
Acceptance: MVP search executes lexical/date/tag matching only and sends no search corpus/query to AI.
Source: DISC § Explicitly deferred.
New AI/privacy evaluation N/A
P4 As Arun, I may later want other visual browsing modes. LID-DEF-004 — Additional views deferred. Year mosaic, media wall, maps, and native/offline applications remain backlog; the MVP calendar/timeline/detail contracts must not be delayed for them.
Acceptance: No location collection, native package, offline cache/sync engine, mosaic, or media-wall deliverable appears in an MVP milestone.
Source: DISC § Explicitly deferred.
New design/architecture decision N/A
P4 As Arun, I may later want more import/export formats. LID-DEF-005 — Format extensions deferred. PDF/Word/OCR ingestion, PDF books/printing, and immutable ransomware-resistant export are not MVP and require separate threat, storage, and rendering decisions.
Acceptance: Unsupported uploads are rejected with the accepted .txt/.md guidance; MVP export offers no PDF/book/immutability claim.
Source: DISC § Explicitly deferred.
New product/security decision N/A
P4 As Arun, I may later want another exact source tag without accidental disclosure. LID-DEF-006 — Tag expansion deferred. Additional exact VoiceNotes tags may be enabled only through a future explicit setting. Fuzzy matching and broad tags remain prohibited unless a new privacy decision replaces that boundary.
Acceptance: MVP eligibility accepts only exact life-in-days; configuration contains no wildcard, substring, fuzzy, or additional-tag path.
Source: DISC § Explicitly deferred.
VoiceNotes contract; new decision N/A

Additional Components & Resources

  • Canonical requirement authority: Confirmed discovery requirements. If an earlier research proposal conflicts with a later confirmed decision, the confirmed decision governs. Example: the Visual Brief is read-only even though an earlier artwork report discussed manual editing.
  • Canonical language: CONTEXT.md. Product, UI, architecture, tests, and operational artifacts should use its terms and avoid listed aliases.
  • Shared-understanding gate: Proposed shared understanding. The requirements frontier is empty, but Arun has not yet supplied the explicit confirmation that unlocks downstream evaluation/design work.
  • Research cut-off: Provider model, pricing, lifecycle, terms, and data-control facts were checked 2026-08-12 and are inherently time-sensitive. Re-open primary sources before evaluation credentials are created and again before launch.
  • Architecture decisions still required after confirmation: no-additional-cost encryption/key design; VoiceNotes spike contract; durable job/scheduler mechanism; database/search choice; R2-to-Restic remote-source backup mechanism; deployment topology; secret delivery; export encryption implementation.
  • Design artifacts still required: month calendar, timeline, Journal Day detail, gallery/cover controls, search, date review, upload, conflict diff, field replacement review, artwork state/history, Trash, export, settings/budget, System Health, responsive behavior, and accessibility annotations.
  • Execution evidence required: synthetic VoiceNotes spike; AI evaluation datasets/manifests/scorecards; privacy-contract tests; threat model; backup/restore runbooks; Recovery Ceremony record; supported-browser/accessibility results; storage migration rehearsal; deployment/rollback checklist.

Provider and Privacy Risk Checklist

Legal and contract checks before any launch:

  • Confirm Arun has the right to submit journal text and generated prompts to each selected commercial API.
  • Revalidate selected provider terms for permanent generated-output retention, training defaults, abuse-monitoring retention, residency claims, and account eligibility.
  • Do not describe provider service as zero retention, India-local processing, E2EE, or zero knowledge without verified contractual and technical evidence.
  • Document Telegram, VoiceNotes, Cloudflare, Hetzner, R2, B2, and selected AI services as distinct processors/trust boundaries.
  • Ensure generated artwork remains labeled and does not imply documentary truth or a recognizable person's likeness.

Legal: Personal Data Processed

Information field Is collection mandatory or voluntary? Storage location Storage: persistent or temporary?
Voice Journal transcript/title and Uploaded Journal files Voluntary source creation; required to create that journal Source Item Planned application-controlled encrypted store on Hetzner; encrypted Restic recovery in B2; selected Text Provider receives only approved request content Persistent locally/backups; provider retention follows verified commercial terms and is not described as zero
Original Daily Photo bytes Voluntary per day Application-encrypted Hetzner root, later private R2 EU; encrypted Restic B2 backup Persistent until Trash/permanent-deletion/backup-retention rules expire
Privacy-safe thumbnails and Generated Artwork files Derived/optional; thumbnails required to display accepted photos Same encrypted live/recovery media stores Persistent/versioned until lifecycle deletion; provider-returned artwork Original retained
Photo Captions Voluntary Encrypted application database/export/backup; never AI input in MVP Persistent with Daily Photo until lifecycle deletion
Journal Date, Original Timestamp, source type, filenames, tags, and display ordering Required for archive behavior/provenance; filename supplied voluntarily with upload Encrypted application data store, export, backup Persistent with source/history
VoiceNotes and Telegram opaque source/message/update identifiers Required for idempotency, reconciliation, and suppression Encrypted application data store; excluded from AI and ordinary logs Persistent while source exists; opaque VoiceNotes identity may persist after permanent deletion solely for suppression
Source Revisions, Corrections, conflict choices, Trash, Source Suppression, Artwork Suppression Created only when relevant actions/events occur; required to preserve audit/deletion intent Encrypted application store/export/backup Persistent per lifecycle; Trash 30 days before permanent live deletion
AI title, summary, tags, Visual Brief, artwork, provider/model provenance, usage/cost, request ID, refusal/error metadata Generated only after provider configuration and eligible source/action Encrypted application store/export/backup; brief sent to selected Artwork Provider Persistent/versioned locally; provider retention follows verified terms
Journal text sent to selected Text Provider Required only for enabled text-generation request In transit to selected commercial API; no provider file/session/vector store Temporary provider processing plus documented abuse-monitoring/cache retention; Life in Days source remains persistent
Read-only Visual Brief sent to selected Artwork Provider Required only for artwork request/sweep In transit to selected commercial API Temporary provider processing plus documented provider retention; local brief/artifact provenance persistent
Cloudflare account identity/assertion Required for human access Cloudflare Access and ephemeral application request context Provider-managed session; application must not persist full assertion in logs
Runtime secrets and recovery keys Mandatory to operate configured integrations/encryption Root-restricted server secret path; password manager and sealed offline copy for recovery Persistent outside journal database/export; never logged/committed
Export one-time passphrase Voluntary when requesting encrypted export User entry and in-memory export operation only Temporary; never stored
Sanitized operational timestamps, opaque IDs, error classes, health/spend/capacity values Mandatory for private operations Local structured logs/System Health Logs retained 30 days; durable health evidence as needed without personal content

Ideal User Experience

User Flows

  1. Send a normal photo: Arun sends a photo or image document in the configured private Telegram chat. The bot validates secret/sender/chat, fetches bytes, validates content, creates a local metadata-safe thumbnail, encrypts and durably commits both assets, then acknowledges the Asia/Kolkata Journal Date with a private change-date link.
  2. Backdate a photo or album: Arun starts the Telegram caption with YYYY-MM-DD, optionally followed by descriptive caption text. The explicit past date applies to the photo/media group; remaining text becomes a searchable Photo Caption. Telegram compression guidance is available without interrupting capture.
  3. Correct a bad date: An invalid or future leading date keeps the photo in Needs Date Review and sends a helpful Telegram explanation. Arun opens the authenticated review screen, selects a valid date, previews the result, and publishes it without losing original timestamp or caption.
  4. Automatic journal arrival: VoiceNotes emits a wakeup for a newly created post-activation note. Life in Days retrieves authoritative data through the spike-validated MCP contract, confirms exact life-in-days tag and creation time, creates/reconciles the Voice Journal, and makes it visible on the correct day. Missing date goes to review rather than an invented day.
  5. Upload a journal: From a Journal Day, Arun uploads .txt/.md and inherits that date. From the global action, Arun selects a date first. The UI validates UTF-8/size/duplicates, preserves the file separately, and shows its filename as source title.
  6. Review the month: The month opens image-first, Monday-first, in the chosen warm light or deep-ink dark theme. Each populated day uses a real photo if available, otherwise labeled Generated Artwork. Keyboard, touch, screen reader, zoom, and reduced motion all preserve the same functionality.
  7. Open a Journal Day: Arun sees cover/gallery, labeled artwork, editable generated fields, every source journal, captions, timestamps, provenance, current/stale states, history, and safe management actions. Pending or failed AI never hides authentic content.
  8. Find a memory: Arun searches an exact phrase/date/tag. Results identify why each day matched. Include history deliberately adds Trash and superseded revision results without blending them into current truth.
  9. Correct a journal: Arun creates a Correction without changing VoiceNotes or original file bytes. If a later upstream edit conflicts, a side-by-side diff offers only keep Correction, display newest upstream, or create a new Correction based on both.
  10. Protect generated wording: Arun edits or accepts a title/summary/tag. A later source update marks only that field stale and offers a replacement. Arun can keep it, select a replacement, or choose Resume automatic updates for that one field.
  11. Generate artwork now: Once at least five meaningful words exist, Arun can generate immediately. Sparse text shows a warning. The UI previews the read-only Visual Brief, selected provider/model, cost/budget state, and generated label. Regenerating the brief and retrying are separate explicit actions.
  12. Automatic missing-art fallback: At 01:00, the sweep repairs all eligible prospective journal days with enough text, no real photo, no artwork, and no suppression. Skips and failures are visible without reminders. A later real photo takes Calendar Cover while artwork remains labeled in the gallery.
  13. Manage artwork history: Each successful regeneration becomes a version. Arun compares/selects prior versions. Removing all art records suppression; Allow generation explicitly reopens sweep eligibility.
  14. Delete and restore: Deletion moves content to Trash for 30 days and explains cover/day visibility effects. Restore recalculates state. Permanent deletion requires confirmation and preserves only an opaque upstream identity when suppression must prevent resurrection.
  15. Export and recover: Arun requests encrypted export, supplies a one-time passphrase, downloads once, and receives current content plus clearly separated history/Trash/suppressions and checksums. System Health shows real backup/restore evidence. Launch cannot occur before the Recovery Ceremony succeeds.
  16. Handle outages safely: Provider, webhook, disk, budget, or backup failures show precise private states and safe next actions. Capture/browsing remain available wherever the failed dependency is not required. No fallback provider or destructive cleanup occurs silently.

Wireframes / Mockups (Optional)

Pending Product Council UI/UX artifact. It must cover all primary surfaces and exceptional states identified in LID-REF-001 through LID-REF-007, LID-AIA-002 through LID-AIA-010, and LID-OPS-010 through LID-OPS-017. A prototype is evidence of interaction intent, not authorization to implement or deploy.


Technical Considerations

  • Domain model: Use CONTEXT.md as the ubiquitous language. Separate Journal Day, Source Item, Source Revision, Correction, Derived Artifact/version, Protected Field, Daily Photo reference, Media Asset, Artwork Request/attempt, suppression, Trash, and export/backup records. Do not collapse source text and AI output into one mutable entry row.
  • Identity and idempotency: Persist stable provider source identity, Telegram update/chat/message/media-group identity, content checksums, and generation idempotency hashes. Uniqueness constraints and transactions must prevent duplicate physical assets and duplicate revisions under concurrent/replayed events.
  • Date model: Store instants unambiguously and derive Journal Date only through fixed Asia/Kolkata rules or explicit owner choice. Future-date exclusion, midnight boundaries, redating, and display locale need dedicated tests.
  • Source transaction boundary: Moving an item must update old/new days, cover selection, search index, day visibility, stale state, and active artwork eligibility atomically. Long-running AI/media jobs use content/revision hashes and reject stale completions.
  • VoiceNotes integration: Do not choose an implementation contract until the synthetic spike establishes documented/observed behavior. A webhook is a wake signal, not authoritative content. Reconciliation must fail closed on partial enumeration and preserve upstream absence as status, not local deletion.
  • Telegram integration: Validate webhook secret and allowlists before download. Use durable idempotency. Handle separate album messages without assuming an undocumented completion event. Fetch provider bytes promptly because file URLs expire.
  • Media security: Decode untrusted images in a constrained worker. Keep plaintext in bounded memory-backed staging only; refuse unencrypted swap. Preserve exact Original, create metadata-free derivatives locally, and use authenticated per-object encryption with versioned envelopes/nonces.
  • Storage abstraction: Database records contain opaque media identity/backend/key rather than provider URL. Minimum backend contract: put, getStream, head, listInventory, delete, and healthCheck; inventory pagination must prove completeness. Root and R2 adapters share this contract.
  • Private read path: Cloudflare authenticates; application authorizes; backend streams ciphertext; application decrypts; response is private/no-store. Storage credentials, object URLs, and decryption keys remain server-side.
  • Backups: Database export and remote-object inventory must be application-consistent. Object-store cutover requires a validated complete remote-source path for Restic; incremental staging-only backups are forbidden because retention could remove the last older copy.
  • AI adapter boundary: Normalize only after provider-native schema validation. Keep separate typed text/art configurations and exact provider/model versions. Use allowlisted request DTOs so forbidden photo/account fields cannot serialize. No hidden provider fallback.
  • AI scheduling: Text quiet-period/final refresh and Artwork Sweep require durable idempotent jobs that survive restart. Jobs carry source-revision sets and recheck eligibility, budget, credential, suppression, and cover state immediately before execution and commit.
  • AI provenance: Persist exact input hash, source revisions, prompt/schema/config versions, requested/returned model, provider request ID, safe usage/cost/latency, refusal/error, and generated artifact. Keep protected journal content in encrypted application storage, not ordinary logs.
  • Search: MVP is local deterministic lexical/date/tag search over displayed fields. Index updates must be transactional or recoverably queued after Correction, redating, Trash, restore, provider refresh, and protection changes. History is a deliberate separate filter.
  • Security boundary: Human Cloudflare Access and machine callback authorization are separate. Origin binds to loopback. Browser receives no integration/provider/storage credentials. Cache bypass is defense in depth, not a claim Cloudflare is absent from transport.
  • Observability: Use an allowlisted structured-event schema, not post-hoc redaction alone. System Health derives from durable completed evidence. Operational IDs are opaque; payloads, prompts, responses, assertions, filenames where sensitive, and signed URLs are forbidden.
  • Performance/capacity: Current host has limited CPU/RAM and shared root storage. Serialize heavy media derivation, bound queues and staging, measure free bytes, and pause/reject safely at thresholds. Do not invent an SLA from provider catalog claims.
  • Portability: Export format and checksums should be implementation-independent. A restore/import validator must prove that source/revision/Correction/derived/suppression relationships and original bytes survive outside the running application.
  • Architecture approval boundary: Stack/database/job-runner/crypto-library choices are not settled by this PRD. The implementation plan must record hard-to-reverse choices in ADRs and cannot weaken the behavioral acceptance criteria above.

Required state contracts

Domain Required states/transitions
Source capture received → validating → durably captured; or Needs Date Review/rejected/failed. Acknowledgement only follows durable capture.
Voice source active upstream → revised/untagged/deleted upstream; local Correction/conflict/suppression remain independent.
Derived text field absent → generating → current; current → Protected Field; source change → stale/replacement available; Resume automatic updates → unprotected.
Artwork attempt requested/scheduled → eligible check → generating → succeeded/refused/failed/skipped/budget-blocked; no automatic provider transition.
Artwork version historical/current Active Artwork/stale/Trash/deleted; cover eligibility is separately derived from existence of live Daily Photos.
Deletion live → Trash (30 days) → restored or permanently deleted; suppression transitions preserve upstream/artwork intent.
Storage migration root authoritative → dual-write/copying → reconciled/backup-proven → target authoritative/observing → old root copy eligible for eviction.
Backup evidence scheduled → snapshot complete → repository checked → sample restored; upload success alone never advances to restored.

Risks & Mitigations

Risk Impact Likelihood Mitigation
Explicit shared understanding is not yet confirmed High High until confirmed Keep all execution blocked; treat this PRD as a draft artifact only.
VoiceNotes webhook and MCP identifiers or auth do not support unattended reconciliation High Medium Synthetic spike before contract freeze; reopen the affected decision instead of inventing behavior.
Missed, duplicate, partial, or out-of-order upstream events create wrong history High Medium Webhook as wake signal; stable identity; idempotent revisions; periodic authoritative reconciliation; fail closed on partial lists.
A Telegram spoof/group/other sender adds content High Low/Medium Validate webhook secret plus exact numeric user/private-chat IDs before media fetch; reject all groups/others.
Telegram compresses an ordinary photo Medium High for photo messages Preserve received bytes, explain quality behavior, recommend document path for original quality; never claim pre-Telegram bytes were preserved.
Malformed image exhausts the small host High Medium Content decode/type/size/pixel/dimension gates; bounded memory staging; one constrained derivation job; clear rejection/backpressure.
Wrong timezone/date silently misfiles a memory High Medium Fixed Asia/Kolkata, exact caption grammar, Needs Date Review, future exclusion, boundary/redating tests, immutable Original Timestamp.
AI invents a plausible false memory or coaching claim High Medium Synthetic fidelity bake-off, zero-critical-invention gate, strict schema/prompt, visible AI labels, authentic source always available, manual review/protection.
Journal prompt injection changes model behavior High Medium Treat journal as quoted untrusted data; frozen instruction hierarchy; adversarial fixtures; hard gate; no tools/grounding.
Real photo data leaks to AI Critical Low if contracted Allowlists/typed serializers, forbidden-field tests, separate text/art payloads, no image input, logs without content, launch privacy test.
Silent fallback discloses text to an unselected provider High Medium under outage No automatic fallback in adapter or job policy; explicit retry/provider choice; persistent provenance.
Provider retention/residency/terms are overstated or change High Medium Accurate UI wording, primary-source revalidation before credentials/launch and on change, no zero-retention/India-processing claim without evidence.
Model alias/lifecycle drift changes output quality High Medium Prefer exact snapshots when available; typed approved configurations; persist returned model; regression evaluation and lifecycle review before changes.
AI spend exceeds owner's limit through retries/regeneration Medium Medium Predictive total/art allocation checks, attempt metering, 80% warning, hard ceilings, premium automatic-sweep flag enforced false.
Disk fills and damages capture/database Critical Medium as archive grows Exact watermarks, projections, System Health/alerts, R2 migration before emergency, explicit media rejection without deletion/downsampling.
R2 migration omits an object or backup sees partial inventory Critical Low/Medium Complete paginated inventory, count/size/hash reconciliation, interrupted-listing test, dual-write, reversible ledger, remote-to-Restic restore proof, seven-day observation.
Live and backup stores share a failure domain High Low with approved direction R2 live in EU jurisdiction and B2 Restic EU Central; no B2-live shortcut without a new explicit correlated-risk decision.
Backup upload is mistaken for recoverability Critical Medium Monthly sample restore, quarterly full drill, four-hour measured target, Recovery Ceremony launch gate.
Recovery key is lost or only on the failed server Critical Low after ceremony Password-manager copy plus sealed offline copy; representative decrypt test; never back up only alongside ciphertext.
Key/secret leaks into Git, logs, export, or chat Critical Medium Runtime-only secret path, least privilege, scanning, allowlisted logs/exports, rotate any exposed value, request fresh credentials only when needed.
Cloudflare cache or public object URL exposes media Critical Low Authenticated same-origin proxy, private/no-store, cache bypass, private buckets, disabled r2.dev, no storage URL/keys in browser/logs.
Single Hetzner host is unavailable Medium Medium Honest best-effort expectation, independent B2 recovery, durable jobs, restart-safe state, no SLA claim.
Local Correction and upstream edit overwrite one another High Medium Immutable revisions/Corrections, conflict state, diff, exactly three explicit resolutions, never auto-merge.
Redating leaves cover/search/artifacts inconsistent High Medium One atomic domain transaction, derived invariant recalculation on both days, stale source binding, concurrency tests.
Deletion is resurrected by reconciliation or export restore High Medium Source Suppression, Trash-aware restore, permanent opaque identity, export suppressions, explicit Allow re-import.
Generated artwork is mistaken for a real photo High Medium Persistent visible label, non-photorealistic style, provenance retention, real-photo cover invariant across every state transition.
Safety refusal feels like judgment or triggers repeated cost Medium Medium Neutral unavailable-art state, no auto-retry/fallback/source edit, explicit Regenerate brief and retry only.
Accessibility regresses under image-heavy responsive UI High Medium Accessibility annotations in design, semantic controls, keyboard/focus/screen-reader/reduced-motion/contrast/browser acceptance gates.
Sanitized logs are insufficient or over-collect personal content High Medium Define allowlisted operational event schema and System Health evidence; 30-day retention; test forbidden values; keep protected data in domain store only.
Export passphrase is lost or artifact remains on server High Medium Explain one-time passphrase, never store it, delete after first successful download/one hour, provide explicit unencrypted warning only by choice.
Scope expands into coaching/social/native features before archive trust works Medium Medium Non-Goals and stable deferred IDs; milestone tracker must keep P3/P4 outside MVP; require new decision for privacy-expanding features.

Life in Days

Home

Product, experience, architecture, and delivery

Discovery and research

Governance and council

Prototype handoffs

Prototype run guides

Prototype councils

QA and audits

Repository and project record

Evidence and maintenance

Clone this wiki locally