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.
9.1 KiB
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 |
Elevated full-product WiX v3 |
platform/windows/scripts/build-full-msi.ps1 |
StageFull → candle/light (exit 1 if WiX missing) |
platform/windows/wix/SILENT_PROPS.md |
Public msiexec property contract (no API keys) |
platform/windows/wix/VeraeTrayShortcuts*.wxs |
Non-elevated per-user tray MSI skeleton |
.github/workflows/windows-msi.yml |
Live unsigned full MSI CI artifact |
.github/workflows/windows-msi-sign.yml.example |
Sign job template (secret names only; gated) |
platform/windows/scripts/enable-printer-cas.ps1 |
Uncomment deferred printer CAs for VM C |
platform/windows/scripts/dual-ship-smoke.ps1 |
Offline A/B/C checklist (+ optional artifact hash) |
platform/windows/scripts/sign-dry-run.ps1 |
Find signtool; print templates; does not sign |
platform/windows/scripts/fill-manifest-sha256.ps1 |
Local SHA-256 → manifest row text (no upload) |
docs/PUBLISH-DIGESTS.md |
Digest paste runbook after CDN upload |
docs/COMMERCIAL-INSTALLER-BACKLOG.md |
Inventory vs still-left commercial gaps |
docs/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 — 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 — printable VM A/B/C tick sheet.
- 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 — 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 — Authenticode / Trusted Signing / notary name tables.
Site 0.3.6 Windows NSIS/MSI rows in 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.
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:
./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 -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.