diff --git a/docs/PR-windows-debug.md b/docs/PR-windows-debug.md new file mode 100644 index 0000000..b7731d1 --- /dev/null +++ b/docs/PR-windows-debug.md @@ -0,0 +1,148 @@ +# PR — windows-debug (PrintToVeraeTimeStamp) + +**Branch:** `windows-debug` +**Module:** PrintIt desktop / CLI (`PrintToVeraeTimeStamp`) +**HelperVersion:** `0.3.6` (`internal/job.HelperVersion`) +**Audience:** reviewers merging packaging, CERT-01, and statuslang work into `main` + +Paste this file (or the Summary + Test plan sections) as the Forgejo/GitHub PR body. + +--- + +## Summary + +`windows-debug` lands the commercial Windows packaging spine, CERT-01 brand certificate path, and BrandingBook **statuslang** notify strings for PrintIt. Software and dry-runs are complete in-repo. Live Authenticode, Apple notary submit, clean-VM dual-ship sign-off, and CDN digest paste remain **operator external** — blocked only on org secrets / VM (see OPERATOR-READY). + +| Theme | What shipped | Still external | +|-------|--------------|----------------| +| **MSI** | WiX tray (per-user) + full elevated `Product-Full.wxs` + `build-full-msi.ps1`; unsigned CI workflow; silent public props; dual-ship runbooks; dry-run / hash helpers | Org Authenticode / Trusted Signing values; VM C after printer CAs; thin-NSIS cutover | +| **CERT** | CERT-01 PDF (`internal/pdfcert`) + web viewer (`site/printit.verae.ai/certificate.html`); multihash/BLAKE3 only when present; local-first fonts plan; OFL READY package notes | Real OFL woff2 drop-in; full CERT-01.html pixel match; live CDN assets | +| **statuslang** | `internal/statuslang` BrandingBook titles; hold ≠ evidence; tray/menubar/PDF/CERT consume labels | Keep `verae-tray.ps1` inline mirrors in sync on label changes | + +Do **not** claim SmartScreen reputation, notarized macOS ship, dual-ship complete, or thin-NSIS until the external legs in OPERATOR-READY are executed. + +--- + +## MSI / packaging + +### Product shape + +| Channel | Artifact | Role today | +|---------|----------|------------| +| **Tray (no elevated MSI)** | `verae-tray.ps1` + Startup / Start Menu stubs; optional per-user WiX tray MSI | User-level presence; GET `/status` / `/queue` only | +| **NSIS** | `VeraePrintStamp-windows-*-setup.exe` | **Primary** full-product GUI install | +| **Full MSI** | `VeraePrintStamp-windows-*-.msi` via StageFull → candle/light | Fleet path authoring; unsigned until org sign; printer deferred CAs commented by default | + +Version source of truth is always `HelperVersion` via `Get-VeraePackageVersion` / script greps. Smoke: `platform/smoke-packaging-metadata.sh`. + +### Key paths + +| Path | Role | +|------|------| +| [`platform/windows/wix/Product-Full.wxs`](../platform/windows/wix/Product-Full.wxs) | Elevated full-product WiX v3 | +| [`platform/windows/scripts/build-full-msi.ps1`](../platform/windows/scripts/build-full-msi.ps1) | StageFull → candle/light (exit 1 if WiX missing) | +| [`platform/windows/wix/SILENT_PROPS.md`](../platform/windows/wix/SILENT_PROPS.md) | Public `msiexec` property contract (no API keys) | +| [`platform/windows/wix/VeraeTrayShortcuts*.wxs`](../platform/windows/wix/) | Non-elevated per-user tray MSI skeleton | +| [`.github/workflows/windows-msi.yml`](../.github/workflows/windows-msi.yml) | **Live** unsigned full MSI CI artifact | +| [`.github/workflows/windows-msi-sign.yml.example`](../.github/workflows/windows-msi-sign.yml.example) | Sign job template (secret **names** only; gated) | +| [`platform/windows/scripts/enable-printer-cas.ps1`](../platform/windows/scripts/enable-printer-cas.ps1) | Uncomment deferred printer CAs for VM C | +| [`platform/windows/scripts/dual-ship-smoke.ps1`](../platform/windows/scripts/dual-ship-smoke.ps1) | Offline A/B/C checklist (+ optional artifact hash) | +| [`platform/windows/scripts/sign-dry-run.ps1`](../platform/windows/scripts/sign-dry-run.ps1) | Find signtool; print templates; does not sign | +| [`platform/windows/scripts/fill-manifest-sha256.ps1`](../platform/windows/scripts/fill-manifest-sha256.ps1) | Local SHA-256 → manifest row text (no upload) | +| [`docs/PUBLISH-DIGESTS.md`](PUBLISH-DIGESTS.md) | Digest paste runbook after CDN upload | +| [`docs/COMMERCIAL-INSTALLER-BACKLOG.md`](COMMERCIAL-INSTALLER-BACKLOG.md) | Inventory vs still-left commercial gaps | +| [`docs/PACKAGING.md`](PACKAGING.md) | Day-to-day tray / menubar / CERT / statuslang / IPP split | + +macOS menubar: unsigned `.app` builder + **notary dry-run** (`notary-dry-run.sh`, no submit unless `NOTARY_SUBMIT=1`); notarization checklist is docs-only until Apple credentials exist. + +--- + +## Dual-ship + OPERATOR-READY (canonical links) + +**Dual-ship** means NSIS and full MSI may both be built from the same `HelperVersion` tree and validated on separate clean VMs without mid-test channel cross-uninstall. NSIS stays the **site primary** download until the thin-NSIS exit checklist is fully checked. + +- **[platform/windows/wix/DUAL-SHIP.md](../platform/windows/wix/DUAL-SHIP.md)** — NSIS + MSI side-by-side runbook, build both artifacts, clean-VM matrix, CI artifact notes, **thin-NSIS exit checklist** (A–E). +- **[platform/windows/wix/VM-DUAL-SHIP-CHECKLIST.md](../platform/windows/wix/VM-DUAL-SHIP-CHECKLIST.md)** — printable VM A/B/C tick sheet. +- **[platform/windows/wix/VM-C-ONE-PAGER.md](../platform/windows/wix/VM-C-ONE-PAGER.md)** — single page: `enable-printer-cas` → `build-full-msi` → `dual-ship-smoke -VerifyArtifacts` → `sign-dry-run` → `fill-manifest`. +- **[platform/windows/wix/OPERATOR-READY.md](../platform/windows/wix/OPERATOR-READY.md)** — single operator package: secret **names**, copy-paste enable commands, notary, VM C, digest paste. Status: **READY: blocked only on org secret/VM**. +- **[platform/windows/wix/CI-SIGN-NOTARY.md](../platform/windows/wix/CI-SIGN-NOTARY.md)** — Authenticode / Trusted Signing / notary name tables. + +Site **0.3.6** Windows NSIS/MSI rows in [`site/printit.verae.ai/DOWNLOADS-MANIFEST.txt`](../site/printit.verae.ai/DOWNLOADS-MANIFEST.txt) use sha256 **TBD** until signed blobs are on the CDN — do not fill TBD from unsigned CI smoke MSIs. + +--- + +## CERT-01 + +| Surface | Status | +|---------|--------| +| `internal/pdfcert` | CERT-01 plum/gold PDF; final-only banner via statuslang; SHA-256 always when known; BLAKE3/multihash **only when present** (never invented) | +| `site/printit.verae.ai/certificate.html` | Web viewer — brand kit, query/sidecar/sample load, print CSS, live verify link, QR when final | +| Fonts | Local-first `fonts/*.woff2` probe else CDN; fetch example script placeholders only; OFL READY package documented — binaries not forced into git | +| Hold ≠ evidence | Certificates / “Download proof” only for final / already-registered (`statuslang.IsEvidence`); standing copy `statuslang.EvidenceNote` | + +Design mock source: `verae-2026-design` CERT-01.html. Full pixel match and PDF Fraunces embed remain residual (see PACKAGING.md TODO-7 table). + +--- + +## statuslang + +Source: [`internal/statuslang`](../internal/statuslang/status.go). + +Tray, menu bar, helper balloons, PDF CERT banner, and site copy must use BrandingBook short titles — not free-form strings: + +| State key | Notify title | +|-----------|--------------| +| `held` / `signin` | Sign in to finish timestamp | +| `final` / `completed` / `ok` | Final receipt ready | +| (ready path) | Printer ready | +| `pending` | Pending receipt | +| `queued` | Queued offline | +| `hashing` | Hashing on device… | +| `provisional` | Stamped, awaiting blockchain | +| `existing` | Already registered | + +Helpers: `NotifyTitle`, `NotifyBody` (held/pending `extra` = **local hold id**, never a receipt), `NotifyHeldJobs`, `TrayHeadline` / `TrayDetail`, `IsEvidence`, `EvidenceNote`, chain vocabulary (`ChainName`, `ExplorerURL`). + +Windows `platform/windows/scripts/verae-tray.ps1` mirrors labels inline — keep in sync when Go strings change. IPP constraint: tray/menubar are **GET-only** on `/status` and `/queue`; POST remains pure IPP print capture. + +--- + +## Test plan + +From repo root: + +```sh +./platform/smoke-packaging-metadata.sh +go test ./cmd/verae-print -count=1 -run 'Menubar|Packaging|TrayStartmenu|FindRepo' +go test ./internal/job ./internal/pdfcert ./internal/statuslang -count=1 +./platform/macos/menubar/notary-dry-run.sh # exit 0; no submit +``` + +On a Windows builder (optional; tip paths exit 0 without WiX/signtool): + +```powershell +powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\dual-ship-smoke.ps1 +powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\sign-dry-run.ps1 +# Full MSI when WiX present: +powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\build-full-msi.ps1 +``` + +CI: confirm `windows-msi.yml` builds unsigned artifact; do not enable sign workflow until org secrets exist (`OPERATOR-READY` §1). + +--- + +## Merge notes + +- Target: `main` ← `windows-debug` (this branch). +- No secrets, PFX, Apple API keys, or signed production blobs in git. +- After merge, operators follow **OPERATOR-READY** then dual-ship VM matrix before changing site primary download off NSIS. +- Related gallery / OPEN-ISSUES commercial MSI item is software-complete; external legs stay READY packages. + +## Related docs + +- [PACKAGING.md](PACKAGING.md) +- [COMMERCIAL-INSTALLER-BACKLOG.md](COMMERCIAL-INSTALLER-BACKLOG.md) +- [PUBLISH-DIGESTS.md](PUBLISH-DIGESTS.md) +- [OPERATOR-READY.md](../platform/windows/wix/OPERATOR-READY.md) +- [DUAL-SHIP.md](../platform/windows/wix/DUAL-SHIP.md) +- [README.md](../README.md) Packaging section