docs: PACKAGING.md for tray, menubar, CERT, and statuslang
Document HelperVersion packaging paths and evidence rules.
This commit is contained in:
parent
66900f3951
commit
c2c87274be
2 changed files with 262 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ PrintIt desktop/CLI path: stamp documents via Verae edge billing (xVerae keys).
|
|||
- [Background](#background)
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [Packaging](#packaging)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
|
||||
|
|
@ -48,6 +49,12 @@ verae-print pending --html # offline queue page
|
|||
# Direct chain only with VERAE_ALLOW_DIRECT_VERAE=1
|
||||
```
|
||||
|
||||
## Packaging
|
||||
|
||||
Tray, menu bar, CERT-01 digests, version stamps (`HelperVersion` **0.3.6**), and IPP GET vs POST split:
|
||||
|
||||
- [docs/PACKAGING.md](docs/PACKAGING.md) — Windows tray (no elevated MSI), macOS LaunchAgent / unsigned `.app` / notarization (docs only), `pending` / `tray-status` / `menubar`, statuslang notify titles, hold ≠ evidence.
|
||||
|
||||
## Contributing
|
||||
|
||||
Questions: open an issue on the project Forgejo/GitHub remote, or contact Verae engineering.
|
||||
|
|
|
|||
255
docs/PACKAGING.md
Normal file
255
docs/PACKAGING.md
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
# PrintIt packaging (tray, menubar, CERT)
|
||||
|
||||
Desktop packaging for PrintToVeraeTimeStamp: version stamps, Windows tray /
|
||||
Start Menu presence (no elevated MSI), macOS menu bar / LaunchAgent /
|
||||
optional unsigned `.app`, CERT-01 digests, statuslang notify titles, and the
|
||||
split between pure GET status routes and the IPP POST print path.
|
||||
|
||||
## Version source of truth
|
||||
|
||||
| Item | Value / location |
|
||||
|------|------------------|
|
||||
| Constant | `internal/job.HelperVersion` = **`0.3.6`** |
|
||||
| File | [`internal/job/job.go`](../internal/job/job.go) |
|
||||
| Sidecar field | `"helper_version"` on every `.verae.json` |
|
||||
|
||||
All packaging metadata must resolve from that constant (or fall back to the
|
||||
same string when `job.go` is not on disk):
|
||||
|
||||
- Windows: `platform/windows/scripts/common.ps1` → `Get-VeraePackageVersion`
|
||||
(fallback `"0.3.6"`). Used by `verae-tray.ps1`, `install-tray-startup.ps1`,
|
||||
`build-tray-startmenu.ps1`.
|
||||
- macOS: `platform/macos/menubar/build-menubar-app.sh` reads `job.go` when
|
||||
`VERSION` is unset; stamps `CFBundleShortVersionString` /
|
||||
`CFBundleVersion`, `Contents/Resources/VERSION`, and
|
||||
`packaging-metadata.txt`.
|
||||
- Binary build: `scripts/build-win-linux.sh` greps `HelperVersion` from
|
||||
`job.go`.
|
||||
- Smoke: `platform/smoke-packaging-metadata.sh` fails if tray/menubar scripts
|
||||
drift from `HelperVersion`.
|
||||
|
||||
Override for a one-off stamp: `VERSION=x.y.z` (env) on the build/install
|
||||
scripts. Do not invent a second version constant.
|
||||
|
||||
## Windows tray (no elevated MSI)
|
||||
|
||||
User-level presence only. **No elevated MSI**, no admin rights, no WiX
|
||||
requirement for the tray stub.
|
||||
|
||||
| Script | Role |
|
||||
|--------|------|
|
||||
| [`platform/windows/scripts/verae-tray.ps1`](../platform/windows/scripts/verae-tray.ps1) | STA NotifyIcon; polls **GET `/status`**; menu opens **GET `/queue`** |
|
||||
| [`platform/windows/scripts/install-tray-startup.ps1`](../platform/windows/scripts/install-tray-startup.ps1) | Startup-folder shortcut (`Verae Tray.lnk`) that runs `verae-tray.ps1` |
|
||||
| [`platform/windows/scripts/build-tray-startmenu.ps1`](../platform/windows/scripts/build-tray-startmenu.ps1) | WiX-free Start Menu folder stub; also installs Startup unless `-NoStartup` |
|
||||
|
||||
CLI entry points (same behavior):
|
||||
|
||||
```bat
|
||||
verae-print menubar
|
||||
verae-print menubar --install
|
||||
verae-print menubar --uninstall
|
||||
```
|
||||
|
||||
Or invoke the scripts directly:
|
||||
|
||||
```powershell
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -STA -File platform\windows\scripts\verae-tray.ps1
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\install-tray-startup.ps1
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\build-tray-startmenu.ps1
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- Package version in shortcut description / tooltip = `HelperVersion`.
|
||||
- Full product installer (NSIS) is separate: see Windows README /
|
||||
`installer-windows.nsi` when present. Tray packaging does **not** depend on it.
|
||||
- Hold count in the tray is a **local queue handle**, never evidence
|
||||
(`statuslang.EvidenceNote`).
|
||||
|
||||
More detail: [`platform/windows/README.txt`](../platform/windows/README.txt).
|
||||
|
||||
## macOS menu bar
|
||||
|
||||
NSStatusItem that polls helper **GET `/status`** and opens **GET `/queue`**.
|
||||
Does not touch IPP POST.
|
||||
|
||||
| Asset | Role |
|
||||
|-------|------|
|
||||
| `platform/macos/menubar/verae-menubar.swift` | NSStatusItem source |
|
||||
| `platform/macos/menubar/run-menubar.sh` | Compile-or-interpret entry |
|
||||
| `platform/macos/menubar/com.verae.timestamping.menubar.plist` | LaunchAgent template |
|
||||
| `platform/macos/menubar/build-menubar-app.sh` | Optional **unsigned** `.app` builder |
|
||||
| `platform/macos/menubar/README.txt` | Runbook + **notarization steps (docs only)** |
|
||||
|
||||
### Run / install
|
||||
|
||||
```sh
|
||||
verae-print menubar
|
||||
verae-print menubar --foreground
|
||||
verae-print menubar --install # LaunchAgent at login
|
||||
verae-print menubar --uninstall
|
||||
./platform/macos/menubar/run-menubar.sh
|
||||
```
|
||||
|
||||
`--install` copies durable assets to
|
||||
`~/Library/Application Support/Verae/menubar/` and writes
|
||||
`~/Library/LaunchAgents/com.verae.timestamping.menubar.plist`
|
||||
(`launchctl bootstrap`, fallback `load -w`). Prefer LaunchAgent over Login
|
||||
Items for headless reliability.
|
||||
|
||||
### Unsigned `.app`
|
||||
|
||||
```sh
|
||||
./platform/macos/menubar/build-menubar-app.sh
|
||||
./platform/macos/menubar/build-menubar-app.sh ~/Applications/Verae\ Menubar.app
|
||||
VERSION=0.3.6 ./platform/macos/menubar/build-menubar-app.sh
|
||||
```
|
||||
|
||||
- `LSUIElement=true` (menu bar only, no Dock).
|
||||
- Bundle id: `ai.verae.timestamping.menubar`.
|
||||
- **Not codesigned or notarized by default** — local/dev use.
|
||||
- Builder copies `platform/macos/pkg/entitlements.plist` into
|
||||
`Contents/Resources/` for optional signing; it does not apply `codesign`
|
||||
and never embeds secrets.
|
||||
|
||||
### Codesign + notarization (document only)
|
||||
|
||||
Requires Apple Developer Program + Developer ID Application cert in the
|
||||
keychain. This repo does **not** ship secrets or `signing.env` values.
|
||||
When certs are available (steps also in
|
||||
[`platform/macos/menubar/README.txt`](../platform/macos/menubar/README.txt)):
|
||||
|
||||
1. Build unsigned app:
|
||||
`./build-menubar-app.sh ~/Applications/Verae\ Menubar.app`
|
||||
2. Codesign hardened runtime + entitlements:
|
||||
```sh
|
||||
APP="$HOME/Applications/Verae Menubar.app"
|
||||
ENT="$APP/Contents/Resources/entitlements.plist"
|
||||
codesign --force --deep --options runtime --timestamp \
|
||||
--entitlements "$ENT" \
|
||||
--sign "Developer ID Application: YOUR ORG (TEAMID)" \
|
||||
"$APP"
|
||||
codesign --verify --deep --strict --verbose=2 "$APP"
|
||||
```
|
||||
3. Zip: `ditto -c -k --keepParent "$APP" /tmp/VeraeMenubar.zip`
|
||||
4. Notarize: `xcrun notarytool submit /tmp/VeraeMenubar.zip --keychain-profile "verae-notary" --wait`
|
||||
5. Staple: `xcrun stapler staple "$APP"` then `xcrun stapler validate "$APP"`
|
||||
6. Optional signed `.pkg`: `platform/macos/pkg/build-pkg.sh` (Developer ID
|
||||
Installer + `productbuild`) — separate from the menu-bar stub.
|
||||
|
||||
Gatekeeper: unsigned app needs right-click → Open once, or
|
||||
`xattr -dr com.apple.quarantine "Verae Menubar.app"`. Do not paste API keys,
|
||||
app-specific passwords, or `.p12` material into the repo.
|
||||
|
||||
## CLI surface: pending / tray-status / menubar
|
||||
|
||||
| Command | Purpose |
|
||||
|---------|---------|
|
||||
| `verae-print serve` | IPP helper + loopback **GET `/queue`**, **GET `/status`**, **GET `/`** (health) |
|
||||
| `verae-print tray-status` | Offline/online held · key · helper snapshot (`statuslang` headlines) |
|
||||
| `verae-print tray-status --open` | Open live `http://127.0.0.1:8631/queue` (or temp HTML if helper down) |
|
||||
| `verae-print menubar` | PT-W3 / PT-06: Windows tray or macOS menu bar |
|
||||
| `verae-print menubar --install` / `--uninstall` | Login presence (Startup / LaunchAgent) |
|
||||
| `verae-print pending --html` | Offline queue page (same HTML family as live `/queue`) |
|
||||
|
||||
Default loopback: `127.0.0.1:8631` (`VERAE_IPP_ADDR` overrides).
|
||||
|
||||
## CERT-01: multihash / blake3 when present
|
||||
|
||||
Branded certificate path: `internal/pdfcert` (CERT-01 plum/gold, final-only
|
||||
wording). Job path always prefers local CERT-01 over upstream attach PDF.
|
||||
|
||||
| Digest | When shown | Multihash form |
|
||||
|--------|------------|----------------|
|
||||
| SHA-256 | Always when stamp hash is known | `f1220` + 64 hex (`pdfcert.ContentMultihash`) |
|
||||
| BLAKE3 | **Only** when `Options.Blake3` / upstream provides it | `f1e20` + 64 hex; omit fields when empty |
|
||||
|
||||
Rules:
|
||||
|
||||
- **Never invent** digests. Empty blake3 → omit `blake3` /
|
||||
`blake3_multihash` on sidecar and CERT.
|
||||
- Job does **not** hash file bytes for blake3; it only passes through an
|
||||
upstream digest.
|
||||
- Sidecar always stamps `"helper_version": HelperVersion`.
|
||||
- **Hold ≠ evidence.** Local hold / pending ids are queue handles only.
|
||||
Certificates, “Download proof”, and legal claims are allowed only for
|
||||
final / already-registered states (`statuslang.IsEvidence`). Standing
|
||||
copy: `statuslang.EvidenceNote`.
|
||||
|
||||
## statuslang notify titles
|
||||
|
||||
Source: [`internal/statuslang`](../internal/statuslang/status.go). Tray,
|
||||
menu bar, and helper balloons must use these 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` |
|
||||
| `failed` / `action` | failed / action chip strings |
|
||||
| `existing` | `Already registered` |
|
||||
|
||||
Helpers:
|
||||
|
||||
- `NotifyTitle(state)`, `NotifyBody(state, title, extra)` — for held/pending,
|
||||
`extra` is a **local hold id** (never a receipt).
|
||||
- `NotifyHeldJobs(n)` — cancel / still-waiting banner.
|
||||
- `TrayHeadline` / `TrayDetail` — persistent tray line (held count, key OK,
|
||||
helper up, package version on Windows scripts).
|
||||
|
||||
Windows `verae-tray.ps1` mirrors the same brand strings inline; keep them
|
||||
in sync with `statuslang` when labels change.
|
||||
|
||||
## IPP: GET status pure; POST print separate
|
||||
|
||||
Same loopback port hosts two concerns. They must not couple.
|
||||
|
||||
| Method / path | Role | Consumers |
|
||||
|---------------|------|-----------|
|
||||
| **GET** `/status` | JSON helper snapshot (held, key, health) | tray, menubar, `tray-status` |
|
||||
| **GET** `/queue` | HTML job queue (PT-04/W4) | tray “Open queue”, browser |
|
||||
| **GET** `/` | Health | probes |
|
||||
| **POST** (IPP Print-Job / send-document) | Actual print capture → stamp pipeline | OS print spooler only |
|
||||
|
||||
Constraints:
|
||||
|
||||
- Tray / menubar / install scripts **GET only**. No IPP POST, no
|
||||
`Print-Job`, no document send from presence UI.
|
||||
- `serve` wires `ServeQueue` / `ServeStatus` as extra handlers beside the
|
||||
IPP server; **POST remains pure IPP** so Windows/macOS print clients are
|
||||
unaffected (`cmd/verae-print/serve.go`).
|
||||
- Smoke `platform/smoke-packaging-metadata.sh` checks tray scripts for
|
||||
accidental IPP POST coupling.
|
||||
|
||||
## Verification
|
||||
|
||||
```sh
|
||||
# From apps/PrintToVeraeTimeStamp
|
||||
./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
|
||||
```
|
||||
|
||||
Expect: HelperVersion match, no elevated MSI path required, IPP pure on
|
||||
tray/menubar assets.
|
||||
|
||||
## Related paths
|
||||
|
||||
| Path | Notes |
|
||||
|------|--------|
|
||||
| `internal/job/job.go` | `HelperVersion`, sidecar digests |
|
||||
| `internal/pdfcert/` | CERT-01 build + multihash helpers |
|
||||
| `internal/statuslang/` | Brand notify titles + evidence rules |
|
||||
| `cmd/verae-print/serve.go` | IPP + GET `/queue` `/status` |
|
||||
| `cmd/verae-print/traystatus.go` | `tray-status` CLI + HTTP handlers |
|
||||
| `cmd/verae-print/menubar.go` | cross-platform menubar install |
|
||||
| `cmd/verae-print/pending.go` | pending queue HTML |
|
||||
| `platform/windows/scripts/` | tray / Startup / Start Menu |
|
||||
| `platform/macos/menubar/` | Swift menubar + LaunchAgent + `.app` |
|
||||
| `platform/macos/pkg/build-pkg.sh` | optional signed `.pkg` (certs required) |
|
||||
| `platform/smoke-packaging-metadata.sh` | A4 packaging smoke |
|
||||
Loading…
Reference in a new issue