2 Commits
Author SHA1 Message Date
315a3fe6a5 fix(sign/goja): enforce SEQUENTIAL signing order + route PDFs through the blob seam (RED M7/M8) (#9)
M7 — SEQUENTIAL was declared but never enforced: documentsSend marked all
recipients SENT and signField/signComplete let anyone sign in any order. Add
assertTurn(doc,r): in SEQUENTIAL mode a recipient may only act once every
signer/approver ahead of them (listRecipients order: signing_order ASC,
created_at ASC) has SIGNED. Gated in signField and signComplete. PARALLEL
unchanged.

M8 — PDF bytes no longer live inline in the per-tenant SQLite (document_data.data
held 32 MiB base64, bloating the tenant DB and copied on every read). They now go
through the gojabase __blob object-storage seam (same VFS/S3 plane dataroom uses):
- documentsCreate: __blob.put(original) → store the blob KEY (type 'BLOB_KEY').
- maybeSeal: read original via __blob.get, seal, __blob.put(sealed) to a new key,
  point document_data.data at it (initial_data keeps the original key).
- signView/documentsDownload: __blob.get(dd.data) to return pdfBase64.
Keys are tenant-scoped by the host; the bundle handles base64 only.

Consumed by hanzoai/cloud clients/sign (RED consolidation review #117 M7/M8);
gojabase gains a Config.Blob seam + __blob global, sign leaf passes deps.VFS.

Claude-Session: https://claude.ai/code/session_016yg7GPhYdWCh9vpp4HEwLZ

Co-authored-by: hanzo-dev <dev@hanzo.ai>
2026-07-10 14:49:50 -07:00
5b32922f39 feat(goja): embed ESM-free e-signature bundle for in-process cloud fold (task #100) (#8)
* feat(goja): embed ESM-free e-signature bundle for in-process cloud fold

Port the Hanzo Sign server-side domain (documents, recipients, fields, signing
flow/state, audit trail, completion) to a self-contained goja bundle exposing
globalThis.handle(req), plus a std-lib-only Go embed module (Bundle()). This is
the HIP-0106 (task #100) fold: the unified hanzoai/cloud binary runs the sign
flow as TS-on-goja backed by Hanzo Base/SQLite — no Next.js/Remix, no Prisma,
no Postgres. Persistence (globalThis.db) and the PDF/PKI seal primitives
(globalThis.pdf) are injected by cloud/clients/sign as Go host-functions.

Claude-Session: https://claude.ai/code/session_016yg7GPhYdWCh9vpp4HEwLZ

* docs(llm): note the in-process cloud goja fold (task #100)

Claude-Session: https://claude.ai/code/session_016yg7GPhYdWCh9vpp4HEwLZ

* refactor(goja): run on the reusable gojabase RW-Base host (__db/__newId/__now/__pdf)

Retarget the bundle to the clients/gojabase contract the captable pilot (#96)
established: handle({route,params,query,orgId,body}); persistence via
__db.query/__db.exec + __newId/__now (one txn per dispatch, commits iff
status<400); the PDF/PKI seal via __pdf.stamp/__pdf.sign injected through
gojabase Config.HostFns. One binding, not two. No behavior change to the flow.

Claude-Session: https://claude.ai/code/session_016yg7GPhYdWCh9vpp4HEwLZ

---------

Co-authored-by: hanzo-dev <dev@hanzo.ai>
2026-07-10 03:06:24 -07:00