Skip to content

fix(diagnostics): classify encrypted-database open failures and surface damaged receipt chains - #310

Open
Coding-Dev-Tools wants to merge 2 commits into
mainfrom
fix/receipt-chain-diagnostics
Open

Coding-Dev-Tools wants to merge 2 commits into
mainfrom
fix/receipt-chain-diagnostics

Conversation

@Coding-Dev-Tools

@Coding-Dev-Tools Coding-Dev-Tools commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Why

A user report (discussion #151) shows a forked receipt chain (sqlite3.IntegrityError: receipt chain has no unique structural head) followed by the host marking the provider unavailable with EncryptionError. On current main the receipt failure is already audit-only (since 1.7.6): remember/recall complete with a content-free receipt_warning. Two operator-facing gaps remained:

  • There was no supported way to see receipt-chain damage without reading host logs or calling an MCP tool.
  • Every encrypted-open failure (wrong key, locked file, malformed image, permissions, missing driver) surfaced as EncryptionError with a "wrong key" message, so a damaged database looked like a key problem.

What changed

  • engraphis/backends/encrypted_db.py: EncryptionError gains a machine-readable code. Open failures are classified as database_damaged, database_busy, database_unavailable, key_rejected, key_config_invalid, key_file_empty, key_file_unreadable, and driver_missing. Driver text is still never rendered; classification only inspects stable SQLite phrases.
  • engraphis/core/store.py: receipt_chain_state / verify_receipt_chain are extracted so read-only diagnostics can verify a chain through their own connection. The Store methods delegate to the same implementation; behavior is unchanged.
  • scripts/init.py: engraphis-init --check verifies current-schema receipt chains read-only, bounded to 20,000 receipts and 25 workspace scopes, and reports damage with recovery guidance instead of a bare integrity error.
  • Docs: docs/RECALL_RECOVERY.md gains a receipt-chain recovery runbook and an encryption-code table; docs/SQLITE_DURABILITY.md documents the replace-a-database-under-a-writer hazard.
  • Evidence refresh: the public offline evidence artifact is regenerated (docs/benchmark-evidence/offline-fixtures-receipt-diagnostics-20261103.json, SHA-256 7679701565f8897a12bb9d7f65918d8faa1d694757957b8628ef635b640a9bed), and BENCHMARKS.md, README.md, tests/test_benchmark_evidence.py, and the two rendered report images are updated to that digest. The numeric results are unchanged; only the artifact identity moved.
  • CHANGELOG.md entries under Unreleased.

Notes

  • Behavior is unchanged for healthy databases: receipt-chain damage remains audit-only (receipt: null plus receipt_warning), and memory writes/recall keep working.
  • A structurally damaged chain is still never "repaired" by guessing a predecessor, rewriting hashes, or deleting rows. Verification stays invalid; the documented recovery is to preserve the copy and restore a verified backup.
  • No new dependencies; no plaintext fallback path was added.

Validation

  • ruff check . passed.
  • Focused: python -m pytest tests/test_receipts.py tests/test_init.py tests/test_encryption_dependency.py tests/test_benchmark_evidence.py -q passed.
  • Full local suite: python -m pytest tests/ -q -n 4 with an isolated offline config (no local LLM/config.env, approved index roots) passed; the pytest lastfailed cache was empty afterward.
  • python -m pyright (project venv) passed.
  • eval.harness (sample and codemem), eval.ablation, eval.grounded, eval.adversarial_memory_security, and eval.code_arm passed.
  • PR CI: 30/30 checks successful.
  • Manual: seeded a forked chain and ran engraphis-init --check; it reports [FAIL] operation receipts ... while MemoryService.remember / recall still complete with receipt_warning.

Refs discussion #151. Merge is left to the maintainer; no merge, release, or deployment action is included.

A user-host report showed a forked receipt chain followed by the provider going unavailable with EncryptionError. Since 1.7.6 receipt damage is audit-only, but there was no supported way to see it outside the host log, and every encrypted-open failure was reported as a wrong key.

Extract receipt_chain_state/verify_receipt_chain so the install doctor verifies chains read-only through its own connection and reports damage with recovery guidance, bounded to 20k receipts and 25 scopes. Classify EncryptionError with stable codes; driver text is still never rendered because it can echo paths or the PRAGMA key.

Refresh the checksum-bound offline evidence artifact and its rendered SVG/PNG surfaces because tracked producer files changed.

Refs discussion #151.

Agent: opencode
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-11-03T10:50:50.831732Z
We couldn’t complete this review. Comment @codex review to try again.
8b5cbe4 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Main now carries the 1.7.12 release, the sync/manifest hardening, and the
canonical evidence artifact. Rebind the receipt-diagnostics evidence to the
three producer files main changed (__init__, routes/v2_api, chunking_eval),
recompute the suite digest and artifact SHA, and repin the README, benchmark
guide, tests, and both rendered SVG/PNG pairs.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant