Skip to content

feat: smart-place auto QR placement + &p= page tags + document-payload verify [HELD FOR MIKE'S GO] - #21

Merged
ValidPay-io merged 1 commit into
mainfrom
feat/smart-place
Jul 20, 2026
Merged

feat: smart-place auto QR placement + &p= page tags + document-payload verify [HELD FOR MIKE'S GO]#21
ValidPay-io merged 1 commit into
mainfrom
feat/smart-place

Conversation

@ValidPay-io

@ValidPay-io ValidPay-io commented Jul 20, 2026

Copy link
Copy Markdown
Owner

HELD FOR MIKE'S GO — do not merge without explicit approval

Smart-place (Mike-approved) + two approved scope additions (page tags, document-payload verify). One of THREE cross-linked PRs plus a keyhalve-website display PR — links below.

1. Smart-place: placement: "auto" for sealDocument

Automatic clear-space QR placement, computed locally — the page content never leaves the process (blindness preserved). Shared contract, BYTE-IDENTICAL across the three ValidPay repos:

file git blob sha256
src/smartPlace.ts 4e6c53fed872ccbd0a1bf675fda6928024cfc10606892b507276334719ead91b
src/pdfObstacles.ts 868e1e7e4ca30629800afb641da97818c3696c3567fa72661490fde2da0ee944

(Hashes are of the committed git blobsgit cat-file blob HEAD:src/smartPlace.ts | sha256sum — immune to autocrlf working-tree drift.)

Contract (chooseClearRect): deterministic candidate ladder — preferred corner (default bottom-right) → remaining corners in fixed order → bottom-center/top-center → three equal shrink steps 72→66→60→54 pt → fallback = preferred corner at 54 pt with fallback: true. FREE = candidate rect expanded by the 8 pt clearance strictly overlaps no obstacle (touching edges stay free; zero-area boxes are lines and still block).

Obstacle coverage (this surface, via optional peer pdfjs-dist): text runs (getTextContent, baseline + one font-height), images (all paintImage ops under a save/restore/transform-tracked CTM), vector paths where pdf.js exposes [minX,minY,maxX,maxY] bounds (verified present in pdfjs-dist 5.7.x for pdf-lib-drawn rects). NOT covered: annotations, shading patterns, clip subtraction; boxes covering ≥90% of the page are treated as background. pdfjs-dist is an optional peer (same pattern as pdf-lib/qrcode) — clear missing_dependency error naming the peer, thrown BEFORE any reservation is spent.

Result gains autoPlacement (per-page {x, y, widthPt, anchorTried, shrunk, fallback, obstacleCount}).

2. Display-only page tags (&p=) + sealed page count

  • Multi-page allPages seals stamp each page's QR URL with &p=<page> (after ?t/&m, before #key=). Single-page docs/placements stay byte-identical untagged. Result gains pageVerifyUrls; canonical verifyUrl stays untagged.
  • Pre-flight gate (PASSED) before building this: (a) static — the attested engine parser reads only searchParams.get('m') + pathname id + hash key, unknown params ignored; (b) dynamic — live verify.keyhalve.com engine driven headless on vp_8vw5lin43xu0 with and without &p=7: byte-identical verdict text and identical request sequences (tenant 200 → intent 200 → rail piece 403 MAC-gate → fragment 200; the fail-closed MAC path, since no live key exists to produce a green A/B). The attested bundle was not touched.
  • metadata.page_count (total pages) now disclosed on every seal; caller-supplied page_count field wins.
  • A page tag is a DISPLAY-ONLY orientation aid ("scanned from page N") — never a security claim; the attested engine ignores it.

3. Document-payload verify (field-found bug fix)

verifyIntent failed on v0.2 document seals with invalid_payload: "Decrypted payload is not valid JSON" — those intents carry the raw stamped PDF. Now: JSON parse failure AND file metadata on the intent (file_content_type/file_size_bytes, per the live vp_lm0fqvitp3zt shape) → payloadKind: "document" + document: {contentType, byteSize, declaredByteSize, sha256} (sha256 of the decrypted bytes = the distributable artifact's fingerprint). JSON payloads unchanged; genuine non-JSON non-document payloads still throw invalid_payload. Applied to verifySplitKeyIntent too.

Tests / verification

  • 182 vitest tests green (39 new: contract exhaustive incl. edge-touching/lines/fallback/small pages, extraction with mocked pdf.js op streams, auto-seal integration on synthetic PDFs with real pdfjs extraction, URL shapes with/without p, peer-missing, binary round-trip + JSON regression).
  • npm run build (tsc) clean. Auto pipeline empirically verified in plain Node (pdfjs-dist 5.7 legacy build, no canvas).

Cross-links

🤖 Generated with Claude Code

…oad verify

- placement: "auto" for sealDocument via shared byte-identical contract
  (src/smartPlace.ts chooseClearRect + src/pdfObstacles.ts extraction);
  pdfjs-dist as OPTIONAL peer, all computed locally (blindness preserved)
- multi-page allPages seals stamp per-page &p= display-only page tags
  (after ?t/&m, before #key); result gains pageVerifyUrls; buildVerifyUrl
  gains page, embedQr gains pageTag
- sealed metadata discloses page_count (caller-supplied field wins)
- verifyIntent/verifySplitKeyIntent: document payloads (raw stamped file
  bytes + file metadata on the intent) return payloadKind "document" with
  {contentType, byteSize, declaredByteSize, sha256} instead of
  invalid_payload; JSON payloads unchanged

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ValidPay-io
ValidPay-io merged commit 30c079a into main Jul 20, 2026
1 check passed
@ValidPay-io
ValidPay-io deleted the feat/smart-place branch July 20, 2026 04:17
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