# Agent handover — KBQR 1.0

## User goal and delivered architecture

User requested a ZIP folder, no build, standalone static demo, ES module,
printable and animated QR transfer and camera reconstruction. First caller is
KPOP's literal `KPOPBACKUP1 <base64>` line. No access to KPOP source was provided;
integration is demonstrated at the string transport boundary only.

- index.html / styles.css / app.js: dependency-free browser demo; file:// classic
  scripts, A4 pagination, SVG print export, animation, camera ROI, photo fallback,
  manual decoded frame ingestion, verified text download.
- kbqr-core.js: one shared implementation. Synchronous UTF-8 framing, SHA-256,
  strict parser, transactional accumulator, identity and resource limits.
- kbqr.js: ES module facade over the same core. Exports encode, Decoder,
  parseFrame, sha256, limits. Intentionally independent of QR encoder/reader.
- qr-adapter.js: explicit symbology extension point. Matrix, integer-module
  canvas, SVG, jsQR image decoding. Classic-script global KBQR_QR.
- vendor/: untouched pinned qrcode-generator 1.4.4 and jsQR 1.4.0 sources,
  license texts and SHA-256 provenance.
- tests/run.mjs: no test dependencies; Node crypto reference, parser/accumulator
  checks, real QR raster decoding, density comparison and deterministic vector.

Read FORMAT.md before changing protocol. KBQR1 is deliberately not UR; the full
prior-art decision is in PRIOR-ART.md. Do not rename it UR, add a `ur:` prefix,
or claim wallet compatibility. If UR becomes required, use a maintained library
and add actual peer interoperability tests with a defined KPOP application type.
That changes the dependency budget and should be an explicit feature decision.

## Tests and evidence

Run `node tests/run.mjs` on Node 20+ from the folder. No npm install.
It refreshes tests/results.json, tests/known-vector.json and tests/kpop-sample.txt.
TESTING.md separates verified results from hardware/browser acceptance work.
Do not turn synthetic optical success into a claim of physical print testing.

## Integration guidance

Use one Decoder per set. It locks to the first valid frame or an expectedId.
Catch errors and display the existing progress. Never apply backup contents
until complete is true. Preserve the returned text verbatim and let KPOP check
its prefix, base64 validity, encryption/authentication and application schema.
Do not automatically execute restored text or insert it as HTML. The demo uses
textContent/value for payloads and escapes label text in printable HTML.

Core UTF-8 round-trips CRLF and arbitrary well-formed Unicode exactly. A browser
textarea can normalize pasted/newline-containing text; integrate from the exact
source string or TextDecoder output when original line endings matter. Payload
limits are explicit, not an unlimited arbitrary-size file transfer claim.

## Remaining acceptance work (no physical devices available here)

1. On target Chrome/Edge desktop and Android browser, open the extracted page
   via file:// and localhost/HTTPS. Confirm CSP permits local scripts in each
   target browser. Module imports need a static origin, not browser flags.
2. Transfer tests/kpop-sample.txt screen-to-phone at 250 ms. Join mid-loop,
   deliberately miss frames, pause on a missing frame, and compare output SHA.
   Repeat at 400/750 ms under difficult lighting. Check camera permission denial,
   no-camera state, Stop during a pending permission request, and tab hiding.
3. Print the sample on the intended inkjet at A4/100%, headers/footers off.
   Check all captions and white margins on every sheet. Scan in random order,
   index 0 last, then compare the downloaded UTF-8 bytes to the original.
4. Check 200% zoom, narrow mobile view, long Unicode labels and print pagination
   at 45/65/85 mm. The adapter emits vector print codes; layout is CSS paginated.
5. For archival use keep a known-good decoder copy with the paper backup and
   make a second full paper set. There is no missing-sheet recovery.

## Known engineering boundaries

- Camera and photo paths read one QR at a time. No whole-sheet segmentation.
- No hardware camera timing benchmark, browser UI automation or actual inkjet
  validation was performed in this environment. Automated optical evidence is
  raster-based, not a substitute for that acceptance work.
- Animation creates/caches QR canvases as frames are visited. Generation and
  scanning share the browser main thread; actual timing can exceed the chosen
  interval, especially on low-end phones or dense codes. A worker, pre-rendering
  or requestVideoFrameCallback could be added after measurement.
- Late manifest allows collection before index 0; final text still requires it.
  There is no per-data-frame cryptographic checksum beyond QR ECC. A corrupt
  frame detected at final SHA verification requires reset/rescan. Existing frames
  are never silently overwritten by conflicts.
- Core caps data at 1 MiB/4096 frames, UI at 64 KiB. Progress returns a missing
  array; optimize UI diff updates if supporting very large animated sets.
- The synchronous SHA-256 is locally implemented, tested against Node crypto
  including block-padding boundaries. It is for corruption detection, not keyed
  authentication. Prefer vetted platform cryptography for future security work.
- Full SHA per frame adds density. Wire changes require a new version.
- No persistence/resume after reload, compression, encryption, audio transfer,
  UR interoperability, service worker or alternate symbologies.
- CSP allows no network connections. If embedding in another app, its CSP and
  memory/privacy behavior are the host's responsibility.
- Globals: KBQR, KBQR_QR, qrcode, jsQR. Avoid collisions in the host application.

## Source/style notes

No compilation/minification step for authored files. Vendor files are untouched.
Prefer simple JavaScript, no statement-ending semicolons and omit braces for
simple one-line bodies where practical. Retain third-party license notices.
