PrintToVeraeTimeStamp/docs/PR-windows-debug.md
George Lambert 41e079a0ad docs: PR body for windows-debug (MSI/CERT/statuslang)
Summarize MSI dual-ship, CERT-01, and statuslang work for the
windows-debug PR. Links OPERATOR-READY and DUAL-SHIP as canonical
operator paths; external sign/notary/VM legs stay org-blocked.
2026-10-14 04:33:41 -04:00

148 lines
9.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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-*-<ver>.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