Skip to content

fix(python-sdk): a decoded record verifies offline (G-85) - #115

Merged
pavancharak merged 1 commit into
mainfrom
fix/python-verify-decoded-record
Oct 2, 2026
Merged

pavancharak merged 1 commit into
mainfrom
fix/python-verify-decoded-record

Conversation

@pavancharak

Copy link
Copy Markdown
Owner

What

Fixes G-85: the Python SDK rejected its own decoded Execution Trust Record when the server sent previousChainHash: null, which every Postgres backed record carries (production, the sandbox).

  • decoder.py: every decoded model keeps the server JSON in _parmana_source_json (not a dataclass field, so equality, repr and fields() are unchanged).
  • encoder.py: a model with a source encodes to a copy of exactly that JSON. A model built by hand, or changed with dataclasses.replace(), is encoded from its fields as before.
  • This also fixes refusal_record verification and Execution Intent verification, which send a decoded model back to the server.

Test

python/tests/test_decoded_record_verifies.py, on the real sandbox record (deploy/sandbox/evidence/check-record.json) with the sandbox public key: the raw JSON verifies, the decoded model now verifies, the model encodes back to the server JSON, encoding returns a copy, and a changed model fails. Full Python suite 166 passed before the new file; ruff, black, mypy clean; full preflight in the hook.

Docs

Python SDK page (next release section, the 1.4.0 warning now says it is fixed next release), Playground note, changelog, G-85 marked fixed in code, REMAINING-WORK. Reaches users with the next Python release; 1.4.0 keeps the bug, so the Playground script still verifies raw JSON.

🤖 Generated with Claude Code

The decoder keeps the server JSON on every decoded model (not a field),
and encode() returns a copy of it, so a decoded model goes back out
exactly as the server sent it. An explicit null, such as
previousChainHash on every Postgres backed record, was dropped before,
which changed the canonical hash: verify_execution_trust_record_offline
rejected intact records, and refusal and intent verification sent the
server a different record. A model changed with dataclasses.replace()
has no source and is encoded from its fields.

Test on the real sandbox record with the sandbox public key. Docs: the
next release section, the 1.4.0 warning, Playground, changelog, G-85.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
parmana-api-real Ready Ready Preview Oct 2, 2026 3:08am UTC
parmana-sandbox Ready Ready Preview Oct 2, 2026 3:08am UTC

@mintlify

mintlify Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
parmanasystems 🟢 Ready View Preview Oct 2, 2026, 3:06 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@pavancharak
pavancharak merged commit fed4bb1 into main Oct 2, 2026
9 checks passed
pavancharak added a commit that referenced this pull request Oct 2, 2026
Resolves docs/REMAINING-WORK.md section K: keeps retention built (this
branch) and G-85 fixed in code (#115).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pavancharak
pavancharak deleted the fix/python-verify-decoded-record branch October 2, 2026 03:33

This branch was successfully deployed

3 active deployments
Preview – parmana-sandbox — 4891e830 Deployed Oct 2, 2026 by vercel[bot]
Preview – parmana-api-real — 4891e830 Deployed Oct 2, 2026 by vercel[bot]
staging - docs/site — 4891e830 Deployed Oct 2, 2026 by mintlify[bot]
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