Parent tracking issue: #141. Phase 5 of 11.
Objective
Persist prompts, action history and recovery receipts without exposing credential-store secrets or duplicating remote work.
Scope
Use a durable local store with versioned records, authenticated encryption and fresh nonces. Bind ciphertext to record/host identity; store data keys in a namespace separate from SSH credentials. Protect DB, WAL, journals, backups and decrypted temporary artifacts; test scans for sentinel plaintext. Keys have explicit create/unlock/recovery/loss behavior: never silently regenerate a missing key over existing ciphertext.
Persist canonical immutable request bytes/digest keyed by stable target/account and UUID, plus alias/config/host-trust snapshot. Give audit events an immutable origin-controller and event identity so another controller can later display synchronized history without claiming that the local store already synchronizes it. Same UUID with changed semantics is refused. Record prepare, dispatch intent, acknowledgment, state updates and confirmed outcomes; the controller receipt alone does not prove remote exactly-once execution (#147).
Include connection/diagnostic attempts, explicit trust enrollment, credential add/change/delete (metadata only), installation/update, prompt submission, cancellation, cleanup and export. #155 adds notification-request/OS-acceptance/unknown-delivery metadata without changing the evidence level of the underlying remote action. Its outbox intent must be atomic with the source event or deterministically recoverable by stable event ID. Future imported history is segregated from operational receipts and cannot drive reconciliation, dispatch or task notifications. Store exact submitted prompt and clearly separate requested, dispatched, agent-reported and independently verified actions. Full agent tool-by-tool evidence is only shown when the provider supplies it; mark unavailable/partial coverage. Never log authentication secrets supplied by the credential store. User-written prompt content may itself be sensitive; it is encrypted, not claimed to be magically secret-free.
No new remote mutation starts if durable pre-action receipt or encryption is unavailable. If storage fails AFTER dispatch, report audit_degraded and block new work, but permit bounded same-ID status and cancellation; never strand a running task because a completion record cannot be written. Reconcile after storage recovers and record gaps without inventing events.
History remains local to this controller until explicit deletion; pagination, bounded diagnostics, encrypted backup/key recovery and explicit export are required. #154 separately owns optional encrypted cross-controller history exchange, including membership, conflicts and revocation. Payload deletion keeps minimal non-replay receipts; local history deletion must not erase remote idempotency evidence or silently authorize a retry. Disclose that source transcripts on the remote PC have their own lifecycle (#146).
The controller is the sole owner of history keys and durable writes. The WebView receives only requested decrypted pages and transient form state. #148 must not persist prompts, passwords, results or drafts in localStorage, IndexedDB, service-worker caches, URL/query strings or console/crash telemetry. Persisted drafts, if provided, go through this encrypted store. Export and user-initiated clipboard copies are explicit plaintext disclosures; identify their destinations and avoid claiming they remain encrypted. Test the real WebView profile and crash/restart artifacts with synthetic sentinels during #148/#150.
An audit-outage exception permits an authenticated same-ID status/cancel attempt using an already-known receipt and available transport. It never bypasses locked vaults, host trust or identity checks. If request mapping or authentication cannot be recovered, report recovery_required/authentication_required; do not guess a target or claim cancellation succeeded.
Acceptance criteria
Validation and evidence level
Go store fault injection, restart/concurrency tests, plaintext artifact scanning and vet/lint/race gates. Backend audit APIs are tested here; full dispatch integration belongs to #147.
Dependencies and risks
Depends on #144.
Out of scope
Claiming exactly-once external effects or complete agent action evidence without a provider transcript.
Delivery boundary
Parent #141 defines the shared product contract. This issue owns one reviewable change and its own validation; do not close the parent from its PR. Keep source implementation, automated checks, installation and observed client behavior distinct. No secrets, real prompts, account identifiers or unredacted device logs belong in GitHub evidence.
Parent tracking issue: #141. Phase 5 of 11.
Objective
Persist prompts, action history and recovery receipts without exposing credential-store secrets or duplicating remote work.
Scope
Use a durable local store with versioned records, authenticated encryption and fresh nonces. Bind ciphertext to record/host identity; store data keys in a namespace separate from SSH credentials. Protect DB, WAL, journals, backups and decrypted temporary artifacts; test scans for sentinel plaintext. Keys have explicit create/unlock/recovery/loss behavior: never silently regenerate a missing key over existing ciphertext.
Persist canonical immutable request bytes/digest keyed by stable target/account and UUID, plus alias/config/host-trust snapshot. Give audit events an immutable origin-controller and event identity so another controller can later display synchronized history without claiming that the local store already synchronizes it. Same UUID with changed semantics is refused. Record prepare, dispatch intent, acknowledgment, state updates and confirmed outcomes; the controller receipt alone does not prove remote exactly-once execution (#147).
Include connection/diagnostic attempts, explicit trust enrollment, credential add/change/delete (metadata only), installation/update, prompt submission, cancellation, cleanup and export. #155 adds notification-request/OS-acceptance/unknown-delivery metadata without changing the evidence level of the underlying remote action. Its outbox intent must be atomic with the source event or deterministically recoverable by stable event ID. Future imported history is segregated from operational receipts and cannot drive reconciliation, dispatch or task notifications. Store exact submitted prompt and clearly separate requested, dispatched, agent-reported and independently verified actions. Full agent tool-by-tool evidence is only shown when the provider supplies it; mark unavailable/partial coverage. Never log authentication secrets supplied by the credential store. User-written prompt content may itself be sensitive; it is encrypted, not claimed to be magically secret-free.
No new remote mutation starts if durable pre-action receipt or encryption is unavailable. If storage fails AFTER dispatch, report audit_degraded and block new work, but permit bounded same-ID status and cancellation; never strand a running task because a completion record cannot be written. Reconcile after storage recovers and record gaps without inventing events.
History remains local to this controller until explicit deletion; pagination, bounded diagnostics, encrypted backup/key recovery and explicit export are required. #154 separately owns optional encrypted cross-controller history exchange, including membership, conflicts and revocation. Payload deletion keeps minimal non-replay receipts; local history deletion must not erase remote idempotency evidence or silently authorize a retry. Disclose that source transcripts on the remote PC have their own lifecycle (#146).
The controller is the sole owner of history keys and durable writes. The WebView receives only requested decrypted pages and transient form state. #148 must not persist prompts, passwords, results or drafts in localStorage, IndexedDB, service-worker caches, URL/query strings or console/crash telemetry. Persisted drafts, if provided, go through this encrypted store. Export and user-initiated clipboard copies are explicit plaintext disclosures; identify their destinations and avoid claiming they remain encrypted. Test the real WebView profile and crash/restart artifacts with synthetic sentinels during #148/#150.
An audit-outage exception permits an authenticated same-ID status/cancel attempt using an already-known receipt and available transport. It never bypasses locked vaults, host trust or identity checks. If request mapping or authentication cannot be recovered, report recovery_required/authentication_required; do not guess a target or claim cancellation succeeded.
Acceptance criteria
Validation and evidence level
Go store fault injection, restart/concurrency tests, plaintext artifact scanning and vet/lint/race gates. Backend audit APIs are tested here; full dispatch integration belongs to #147.
Dependencies and risks
Depends on #144.
Out of scope
Claiming exactly-once external effects or complete agent action evidence without a provider transcript.
Delivery boundary
Parent #141 defines the shared product contract. This issue owns one reviewable change and its own validation; do not close the parent from its PR. Keep source implementation, automated checks, installation and observed client behavior distinct. No secrets, real prompts, account identifiers or unredacted device logs belong in GitHub evidence.