Phase Q3-release — Desktop installers (Thinking freeze)
Status: Reviewed → pass (QR-r3). Q3-release Thinking is spec-only and must not land
CI workflows, signing config, or installer binaries in this phase. The Q3-release Auto build
({step}b) is cleared only after this document is reviewed → pass; it is the only phase that
writes release-pipeline files. Do not re-derive this contract during the Auto build. Do not
reopen Track Q engine/API surfaces (docs/archive/phases/PHASE-TRACK-Q-Q0-OVERSEER-APP.md, Q1–Q3 packaging
ground truth).
phase: Q3-RELEASE
outputs:
- id: q3-release-desktop-installers
path: docs/archive/phases/PHASE-Q3-RELEASE-DESKTOP-INSTALLERS.md
frozen: true
frozen_inputs:
- id: kit-spec-cli
path: docs/OVERSEER-KIT-SPEC.md#5
- id: freeze-ceremony
path: docs/OVERSEER-KIT-SPEC.md#6
- id: kit-boundary
path: AGENTS.md
- id: track-q-q0-distribution
path: docs/archive/phases/PHASE-TRACK-Q-Q0-OVERSEER-APP.md
- id: track-q-q2a-ok-entrypoint
path: docs/archive/phases/PHASE-TRACK-Q-Q2A-OK-CLI-ENTRYPOINT.md
- id: q3-desktop-runbook
path: docs/TRACK-Q-DESKTOP-OPERATOR-RUNBOOK.md
- id: q3-desktop-readme
path: desktop/README.md
- id: q3-desktop-tools
path: tools/desktop/constants.py
- id: q3-bundle-script
path: scripts/bundle-desktop-kit.sh
- id: decision-tiers
path: policy/tiers.yaml
- id: test-tiers
path: policy/test-tiers.yaml
- id: roadmap-q3-release-row
path: docs/ROADMAP.md
review_stamp:
reviewed_at: '2026-07-14T00:58:04Z'
verdict: pass
reviewer_mode: agent
reviewer_model: thinking-high
reviewer_provider: local
kit_version: 0.1.0
artifact_digest: sha256:91d39951c9cd391c22245c918a0369ab9c0bb03c21a074925298a531bc0ae7db
Downstream edge: the Q3-release Auto build treats this document as ground truth without
re-deriving it (SPEC §6 mandatory reviewed freeze). Track Q Q0–Q3 (ok app, Tauri shell,
tools/desktop/, scripts/bundle-desktop-kit.sh) remain inputs — Auto may wire CI around
them; Auto must not rewrite launcher, bind, auth, or api/* contracts.
Review record (§6.2): every freeze-review finding MUST cite file+line per SPEC §6; uncited
findings are invalid and are discarded. Fixes applied during the loop are Tier 1 (feature branch);
merge to main is Tier 3 and is never part of this loop.
| Round | Reviewer | Verdict | Resolution |
|---|---|---|---|
| QR-r1 | Freeze-review loop (checklist + thinking, thinking-high) |
findings | CLI checklist dry-run pass (0 findings). Semantic findings (non-escalating): R1-M1 §QR.4.3 missing Auto v1 arch freeze; R1-M2 no publish allowlist vs Tauri targets: all; R1-M3 Release upload + Actions token permissions unspecified; R1-M4 soft-skip wording vs fail-closed; R1-M5 Windows cloud-signer alternate underspecified; R1-M6 bundle copy allowlist / .env refuse not frozen; R1-N1 Q3 DONE prerequisite + thin frozen_inputs. No escalation categories. |
| QR-r1 fix | Author (cited items only) | — | R1-M1 arches. R1-M2 §QR.4.5 allowlist. R1-M3 §QR.4.6. R1-M4 fail-closed. R1-M5 §QR.5.2. R1-M6 §QR.6.3. R1-N1 frozen_inputs. |
| QR-r2 | Freeze-review loop (checklist + thinking, thinking-high) |
findings | CLI blocked on C4 false positive (OIDC permission key prose tripped SECRET_RE). Semantic: R2-M1 Path C honesty omitted system-Python prerequisite; R2-M2 macOS hardened-runtime / timestamp missing; R2-M3 macOS runner not pinned; R2-M4 Apple API-key notarization secret names missing; R2-N1 embed-Python not in rejection table; R2-N2 workflow_dispatch inputs incomplete. No true escalation (C4 = false positive). |
| QR-r2 fix | Author (cited items only) | — | R2-C4 rephrased OIDC permission prose. R2-M1 §QR.0/§QR.2/§QR.9 Python honesty. R2-M2 §QR.5.1 hardened runtime + timestamp. R2-M3 pin macos-14. R2-M4 §QR.6.2 API-key names. R2-N1 rejection + out-of-scope. R2-N2 §QR.4.2 inputs. |
| QR-r3 | Freeze-review loop (checklist + thinking, thinking-high) |
pass | CLI checklist gate clean (0 findings, dry-run). Semantic re-read confirmed R1/R2 RESOLVED: arches + publish allowlist; Release permissions (OIDC prose safe for C4); fail-closed signing; dispatch inputs; Python 3.11+ runtime honesty; hardened runtime + timestamp; pinned macos-14/macos-15; Apple API-key secret names; closed bundle allowlist; rejection table; credential boundary; seven-tier matrix complete; Track Q engine boundary held; no security/irreversible/real_money/gates_tier3 escalation. Stamp written by ok review --freeze. |
§QR.0 — Simple summary
Today Path C (Tauri desktop) only works if you install Rust, Node, and Python and build from
source. Operators who want a native window without that toolchain are stuck on Path A (docs +
terminal) or Path B (ok app in a browser).
Q3-release freezes how continuous integration builds, signs, and publishes macOS .dmg,
Windows .msi, and Linux .AppImage installers for the same Q3 Tauri shell — so Path C can
mean “download a signed installer,” not only “compile Rust/Node.”
Frozen runtime honesty: Auto v1 installers still require system Python 3.11+ on PATH
(or a usable interpreter the bundled cli/ok shim can exec). The installer removes the
Rust/Node build toolchain requirement; it does not embed a Python interpreter. Embedding
Python is deferred (§QR.1 out of scope / §QR.10).
Technical summary: freeze CI matrix + artifact contract; OS code-signing + notarization /
Authenticode boundary; secret names as GitHub Actions secrets only (never in-repo); release
manifest with checksums and honest signing status; rejection table; Auto deliverables under
.github/workflows/ + templates/ci/ + tools/desktop_release/; seven-tier matrix. Spec-only —
no workflow YAML or secrets in Thinking.
§QR.1 — Scope
In scope (freeze only — this phase writes no code):
- Product goal vs Path A / B / C honesty (§QR.2).
- What exists now / verified baseline (§QR.3).
- CI publish surface: triggers, runners, artifact types (§QR.4).
- Signing + notarization contract per platform (§QR.5).
- Credential / secret boundary (§QR.6).
- Release manifest + publish destination (§QR.7).
- Version alignment rules (§QR.8).
- Boundary + capability table (§QR.9).
- Rejection table (§QR.10).
- Auto build deliverables (§QR.11).
- Fail-closed / error behavior (§QR.12).
- Seven-tier test matrix for Auto (§QR.13).
- Hard stops + tier linkage (§QR.14).
- Definitions of Done (§QR.15).
Out of scope (explicit non-goals — prevent creep):
- Any Track Q engine / API rewrite. No changes to
tools/app/, closedapi/*, bind/auth, exit codes, orok appsemantics. Q3 shell (desktop/,tools/desktop/) stays packaging. - In-app auto-updater / update CDN. Publishing installers is in scope; shipping a live updater endpoint, forced auto-update, or updater UI is deferred to a later freeze.
- App Store / Microsoft Store / Flathub / Snap submission. GitHub Releases only for Auto v1.
- Hosted governance dashboard / Track O / Track P redesign. Untouched.
- Embedding consumer product runtimes (Scooling
src/phase9a/, Knowtation vault, etc.). - Embedding a Python interpreter / PyInstaller / uv-managed runtime inside the installer. Auto v1 ships the Q3 resource kit + Tauri shell only; end hosts need Python 3.11+ (§QR.0).
- Committing signing certificates, private keys, Apple/Windows secrets, or
.p12/.pfxfiles. - Tier-3 merge, staging push, live capability flips, or operator secret vault mutations — this freeze never authorizes them.
- Claiming Muse content-addressed provenance for binary blobs. Muse remains canonical for source; GitHub Releases are a distribution channel for installers (§QR.7.2).
- Thinking phase shipping workflows, binaries, or runbook “installers are live” claims.
§QR.2 — Product identity (frozen)
| Concern | Q3-release (this phase) | Not this phase |
|---|---|---|
| What it is | CI pipeline that builds + signs + publishes Q3 Tauri installers | New desktop engine or second UI |
| Path C today | Build-from-source (npm run tauri build) |
— |
| Path C after Auto DONE + live secrets + tag | Download signed .dmg / .msi / .AppImage (no Rust/Node build); still needs Python 3.11+ |
Embed Python / zero-dependency binary |
| Path A / Path B | Remain fully valid without installers | — |
| Authority | Same local ok app engine inside the bundle |
Remote governance SaaS |
| Distribution host | GitHub Releases on the kit GitHub mirror repo | MuseHub binary store (none) |
Frozen one-liner: Q3-release is packaging/distribution CI for the existing Tauri shell — frontend/distribution of governance, never a runtime redesign.
Honesty rule (frozen): until a GitHub Release actually publishes platform artifacts with
signing.status: signed (or platform-equivalent per §QR.5), operator docs MUST continue to say
pre-built installers are not available. Auto MUST update docs/TRACK-Q-DESKTOP-OPERATOR-RUNBOOK.md
§Release vs dev to describe the pipeline and the “secrets configured + tag cut” operator gate —
not invent a false “download now” claim before a live release exists. Auto MUST also state that
signed installers require Python 3.11+ on the host (same shim contract as cli/ok) and MUST
NOT claim a zero-dependency / non-technical install until a later freeze embeds a runtime.
§QR.3 — What exists now (verified, do not redesign)
| Element | Current shape | Source |
|---|---|---|
| Local web UI | ok app stdlib loopback; port 8765; Bearer + CSRF |
Track Q / Q1 |
| Canonical launcher name | ok (+ overseer compat shim) |
Track Q / Q2b |
| Tauri shell | desktop/ spawns ok app, loads loopback UI |
Track Q / Q3 |
| Python launcher contract | tools/desktop/ constants + banner parse |
Q3 |
| Bundle script | scripts/bundle-desktop-kit.sh → desktop/src-tauri/resources/kit/ |
Q3 |
| Bundle targets | Tauri bundle.targets: "all"; product Overseer Kit; id com.overseer.kit.desktop |
desktop/src-tauri/tauri.conf.json |
| Kit version string | 0.1.0 in VERSION, mirrored in desktop package/Cargo/tauri conf |
tree |
| Path C docs | Build-from-source; signed installers “not automated in CI yet” | docs/TRACK-Q-DESKTOP-OPERATOR-RUNBOOK.md |
| Kit GitHub Actions | No .github/workflows/ in-repo today; only templates/ci/freeze-review-github-actions.yml |
tree |
| Signing config | None in tauri.conf.json / Cargo features |
tree |
Q3-release must not change Q1–Q3 runtime semantics. It adds a release pipeline around the
existing npm run tauri build / bundle-desktop-kit.sh path.
§QR.4 — CI publish surface (frozen)
§QR.4.1 — Workflow files (Auto deliverables)
| Path | Role |
|---|---|
.github/workflows/desktop-release.yml |
Kit dogfood workflow — builds, signs (fail-closed without §QR.6.2 secrets on publish), uploads release assets |
templates/ci/desktop-release-github-actions.yml |
Vendored example for documentation parity with K11 freeze-review template (may be identical or a documented subset) |
Prerequisite (frozen): Track Q / Q3 Tauri packaging is DONE (build-verified). Auto must not reopen Q3 launcher/API work; it only adds the release pipeline around the shipped tree.
Auto MAY add a second workflow .github/workflows/desktop-build-smoke.yml (PR / workflow_dispatch)
that builds one Linux AppImage without OS code-signing secrets for CI smoke — must never
upload to a GitHub Release labeled as signed.
§QR.4.2 — Triggers (frozen)
Release job (publishes installers) runs only on:
pushof an annotated or lightweight tag matchingv*where the tag name (without leadingv) equals the kitVERSIONfile contents after trim, orworkflow_dispatchwith the frozen inputs below.
workflow_dispatch inputs (frozen):
| Input | Required | Default | Rule |
|---|---|---|---|
version |
yes | — | Must equal VERSION (trim); else fail closed |
| publish | no | true | When true, upload to GitHub Release after signing. When false, build + sign may
still run (operator secret check) but MUST NOT attach assets to a GitHub Release |
| allow_partial | no | false | See §QR.4.3 |
Tag-push triggers imply publish: true and allow_partial: false.
Signing MUST NOT be soft-skipped when publish: true (tag push or dispatch).
Forbidden triggers for the publish job: pull_request, push to feature branches, schedule.
Those may only run the optional unsigned smoke workflow.
§QR.4.3 — Runner matrix + arches (frozen)
| Runner | Artifact(s) required | Auto v1 arch | Notes |
|---|---|---|---|
macos-14 or macos-15 (not unpinned macos-latest) |
.dmg |
aarch64 (arm64 runner native) |
Pin a known arm64 image so arch does not silently flip; codesign + notarization required (§QR.5.1) |
windows-latest |
.msi |
x86_64 |
Authenticode required for release publish (§QR.5.2) |
ubuntu-22.04 or ubuntu-24.04 (prefer LTS pin over floating ubuntu-latest) |
.AppImage |
x86_64 |
Detached signature required for release publish (§QR.5.3) |
Multi-arch deferred: universal macOS DMG, Windows arm64, and Linux aarch64 are out of Auto
v1. Manifest platform remains OS-level (macos/windows/linux); arch is recorded in the
actual filename and MAY be added as an optional arch field by Auto without a new freeze if
values stay within {aarch64, x86_64}.
All three matrix legs MUST succeed before the release is considered complete. Partial publish
(only one OS) is fail-closed for the orchestrating “finalize” job unless the operator
explicitly dispatches with frozen input allow_partial: true (default false) — and even then
the release notes MUST list missing platforms as unavailable (never as signed).
§QR.4.4 — Build steps (frozen contract, not shell paste)
Each matrix leg MUST, in order:
- Checkout the tagged commit (immutable SHA for that tag).
- Set up Python 3.11+, Node (LTS), Rust per
desktop/src-tauri/rust-toolchain.toml(1.88+). - Run
./scripts/bundle-desktop-kit.sh(or rely on TauribeforeBuildCommandthat invokes it — both are acceptable; tests assert the script remains the single copy path intoresources/kit/). cd desktop && npm ci && npx tauri build(ornpm run tauri -- build).- Locate bundle outputs under
desktop/src-tauri/target/release/bundle/(platform-specific subdirs). - Apply platform signing (§QR.5).
- Compute SHA-256 of each published file; emit manifest fragment (§QR.7).
- Upload artifacts to the GitHub Release for tag
v{VERSION}(§QR.4.6 / §QR.7.2).
Pinned tools: Auto documents exact action versions (actions/checkout@v4, etc.) in the
workflow; bumping major action versions after DONE needs a follow-up change, not silent drift in
this freeze.
§QR.4.5 — Publish allowlist (frozen)
Tauri bundle.targets may remain "all" or Auto MAY narrow it to the explicit set that produces
the three installer types. Regardless of what the build emits, GitHub Release assets for Auto
v1 are restricted to this allowlist:
| Allowed Release asset | Notes |
|---|---|
*.dmg |
macOS only |
*.msi |
Windows only |
*.AppImage |
Linux only |
*.AppImage.minisig or *.AppImage.asc |
Detached Linux signature sidecar |
overseer-kit-desktop-{VERSION}-manifest.json |
§QR.7.1 |
SHA256SUMS.txt |
§QR.7.3 |
Must not attach to the Release (even if built): unsigned copies, .deb, .rpm, raw .app
zips, NSIS .exe (unless Authenticode-signed and a later freeze adds them to this allowlist),
workflow logs, or any file matching secret patterns in §QR.6.3.
§QR.4.6 — Release create/upload + token permissions (frozen)
| Rule | Requirement |
|---|
| Mechanism | Create or update the GitHub Release for tag v{VERSION} via gh release upload or
softprops/action-gh-release (or documented equivalent). Auto picks one and tests assert it. |
| Contents | Release body is a short operator-facing note: version, SHA, link to runbook verify steps;
no secrets, certs, or env dumps. |
| permissions | Workflow permissions MUST be least-privilege: contents: write (releases/tags assets)
and Actions OIDC identity permission set to write only if a documented cloud signer
requires OIDC; default is OIDC identity permission omitted. No actions: write, no
pull-requests: write, no repository-projects. |
| Token | Default Actions GITHUB_TOKEN only for Release upload; never a PAT with repo-admin scope in
workflow YAML. |
§QR.5 — Signing contract (frozen)
“Signed installer” means platform-appropriate code signature as defined below. A Release MUST
NOT mark an artifact signing.status: signed unless that platform’s rules are met.
§QR.5.1 — macOS (.dmg)
| Rule | Requirement |
|---|---|
| Identity | Apple Developer ID Application certificate |
| Codesign | Required on the .app / .dmg produced by Tauri |
| Hardened runtime | Required (codesign with hardened runtime enabled) for notarization eligibility |
| Secure timestamp | Required (Apple timestamp authority) on the signed binary / disk image |
| Notarization | Required (notarytool / Tauri notarization integration) before publish |
| Stapling | Required when Apple returns a staple-able ticket |
| Fail-closed | Missing Apple secrets on a release job → job fails; do not upload unsigned .dmg to the Release |
§QR.5.2 — Windows (.msi)
| Rule | Requirement |
|---|
| Identity (primary) | Authenticode certificate as PFX consumed via WINDOWS_CERTIFICATE +
WINDOWS_CERTIFICATE_PASSWORD (§QR.6.2) |
| Identity (alternate) | Azure Trusted Signing (or equivalent cloud Authenticode) only when the
runbook documents the exact Actions OIDC identity steps and still produces a verifiable
Authenticode signature on the .msi; method in manifest remains authenticode |
| Sign | Required on the .msi before publish |
| Fail-closed | Missing Windows secrets / cloud signer config on a release job → job fails; do not
upload unsigned .msi |
NSIS .exe bundles are not on the §QR.4.5 publish allowlist for Auto v1.
§QR.5.3 — Linux (.AppImage)
Linux has no Gatekeeper/Authenticode equivalent in Auto v1. Frozen definition of “signed” for
.AppImage:
| Rule | Requirement |
|---|---|
| Detached signature | Minisign or GPG detached signature over the AppImage bytes |
| Public key | Published in-repo as a public key file under desktop/keys/ (e.g.
desktop/keys/release.minisign.pub or desktop/keys/release.gpg.asc) — public material only |
| Fail-closed | Missing Linux signing private-key secret on a release job → job fails; do not upload
unsigned AppImage as signed |
| Honesty | Runbook MUST state AppImage signing is detached cryptographic signature, not OS
vendor notarization |
Tauri updater private key (TAURI_SIGNING_PRIVATE_KEY) is out of scope for Auto v1 (no
updater). Do not conflate updater keys with §QR.5.3.
§QR.5.4 — Cross-cutting signing rules
- Release jobs NEVER soft-skip signing when
publish: true. - Optional smoke workflows MAY build unsigned artifacts for CI only; artifact names MUST include
unsignedor live only as workflow artifacts (not GitHub Release assets). - Operator docs MUST NOT call unsigned smoke builds “official installers.”
§QR.6 — Credential / secret boundary (frozen)
§QR.6.1 — Where secrets live
| Store | Allowed | Forbidden |
|---|---|---|
| GitHub Actions repository secrets (and optional environments) | Yes — sole store for private signing material in Auto v1 | — |
| Kit git tree / Muse commits / governance docs / test fixtures | — | Never private keys, .p12, .pfx, Apple app-specific passwords, notarization credentials |
| Workflow YAML | References ${{ secrets.NAME }} / ${{ vars.NAME }} only |
Literal secret values, base64 cert blobs, PEM private keys |
| Release assets / manifest JSON | Public keys, checksums, signing status enums | Private keys, cert passwords |
Configuring or rotating these secrets is Tier 3 (policy/tiers.yaml — secrets and credential
changes). Auto lands workflow references; Auto does not write secret values.
§QR.6.2 — Frozen secret names (contract for Auto + tests)
Auto MUST use these exact GitHub Actions secret names (or document a single additive alias map in the runbook — default is these names):
| Secret name | Platform | Purpose |
|---|---|---|
APPLE_CERTIFICATE |
macOS | Base64 Developer ID Application .p12 / cert blob |
APPLE_CERTIFICATE_PASSWORD |
macOS | Certificate password |
APPLE_ID |
macOS | Apple ID for notarization |
APPLE_TEAM_ID |
macOS | Team ID |
APPLE_APP_SPECIFIC_PASSWORD |
macOS | App-specific password (password mode only — see alternate modes below) |
APPLE_SIGNING_IDENTITY |
macOS | Codesign identity string (e.g. Developer ID Application: …) |
WINDOWS_CERTIFICATE |
Windows | Base64 PFX (or provider-specific blob documented in runbook) |
WINDOWS_CERTIFICATE_PASSWORD |
Windows | PFX password |
LINUX_SIGNING_KEY |
Linux | Minisign/GPG private key material for detached signature |
LINUX_SIGNING_KEY_PASSWORD |
Linux | Optional passphrase; empty allowed if key is unencrypted |
Apple notarization auth — two frozen alternatives (exactly one configured per repo):
| Mode | Required secrets | Notes |
|---|---|---|
| App-specific password (default) | APPLE_ID + APPLE_TEAM_ID + APPLE_APP_SPECIFIC_PASSWORD |
Matches table above |
| App Store Connect API key | APPLE_API_KEY (.p8 contents or base64) + APPLE_API_KEY_ID + APPLE_API_ISSUER + APPLE_TEAM_ID |
Prefer this in CI; do not also require APPLE_APP_SPECIFIC_PASSWORD when this mode is active |
Auto’s runbook MUST document which mode the kit dogfood uses. Mixing both modes in one job without a documented precedence is forbidden. Auto must not invent additional Apple auth env names without amending this freeze.
§QR.6.3 — Refuse rules (frozen)
- Workflow lint / unit tests MUST fail if workflow files match private-key PEM headers
(
BEGIN PRIVATE KEY,BEGIN RSA PRIVATE KEY), PFX magic committed as blobs, or hard-coded password assignments. tools/desktop_release/helpers MUST treat any attempt to write secret values into the repo tree as refuse (used by tests; not a runtime daemon).- Bundle script (
scripts/bundle-desktop-kit.sh) MUST keep a closed copy allowlist (today:adapters,cli,tools,policy,templates,cursor,VERSION,pyproject.toml). Auto MUST NOT expand the allowlist to.env*, consumer.overseer/secrets,*.p12,*.pfx, private keys, or credential files. Security tests assert those paths are absent from a fresh bundle destination. - Private key files under
desktop/keys/(if ever present locally) MUST be gitignored; only public key material is committed.
§QR.6.4 — Least privilege
| Credential | Allowed use | Forbidden use |
|---|---|---|
| Apple / Windows / Linux signing secrets | Sign release artifacts in CI | Commit, log, echo to stdout, attach to Release, use for git push / muse / deploy |
GITHUB_TOKEN (Actions default) |
Upload assets to the Release for the triggering tag | Force-push main, delete repos, mutate unrelated workflows |
| Any signing secret | — | Model provider calls, OpenRouter, hosted-dashboard tokens |
§QR.7 — Release manifest + publish destination (frozen)
§QR.7.1 — Manifest artifact
Every complete release MUST attach overseer-kit-desktop-{VERSION}-manifest.json with at least:
{
"schema_version": 1,
"product": "Overseer Kit",
"identifier": "com.overseer.kit.desktop",
"version": "0.1.0",
"git_tag": "v0.1.0",
"git_sha": "<40-char-hex>",
"artifacts": [
{
"platform": "macos",
"filename": "Overseer Kit_0.1.0_aarch64.dmg",
"sha256": "<64-hex>",
"signing": { "status": "signed", "method": "developer_id_notarized" }
},
{
"platform": "windows",
"filename": "Overseer Kit_0.1.0_x64_en-US.msi",
"sha256": "<64-hex>",
"signing": { "status": "signed", "method": "authenticode" }
},
{
"platform": "linux",
"filename": "Overseer Kit_0.1.0_amd64.AppImage",
"sha256": "<64-hex>",
"signing": { "status": "signed", "method": "minisign_detached" }
}
]
}
Frozen enums:
| Field | Allowed values |
|---|---|
artifacts[].platform |
macos | windows | linux |
artifacts[].signing.status |
signed | unsigned | unavailable |
artifacts[].signing.method |
developer_id_notarized | authenticode | minisign_detached | gpg_detached | none |
Rules:
status: signedrequires a non-nonemethod from the matching platform row in §QR.5.unsigned/unavailableMUST NOT appear on a GitHub Release that operator docs call “signed installers available” — finalize job fails closed if any required platform is notsigned(unlessallow_partial: true, which forces explicitunavailablerows and forbids marketing language in auto-generated release notes).
Exact Tauri-generated filenames may vary by arch; Auto’s manifest builder records the actual filename produced. Tests use fixtures, not live Tauri output, for schema validation.
§QR.7.2 — Publish destination
| Destination | Role |
|---|---|
GitHub Release on the kit’s GitHub remote, tag v{VERSION} |
Sole Auto v1 binary distribution channel |
| MuseHub | Canonical source history only — no binary publish API in this freeze |
| npm / PyPI / Homebrew / winget | Out of scope Auto v1 |
Regime note (muse+git-mirror): cutting a GitHub Release does not replace Muse as canonical
source; it does not authorize SD-14 mirror shortcuts or main merges. Release publish is
orthogonal to Muse↔Git alignment gates (KH2). Operators SHOULD cut release tags from commits that
already exist on both Muse canonical history and the GitHub mirror tip — Auto documents this in
the runbook; Auto does not automate Muse tag creation in v1.
§QR.7.3 — Checksums
In addition to the manifest, Auto MUST attach a plain SHA256SUMS.txt (or equivalent) listing
sha256 filename lines for every installer asset. Manifest sha256 fields MUST match that
file.
§QR.8 — Version alignment (frozen)
Before publish, Auto MUST verify equality (string trim) of:
- Root
VERSIONfile desktop/package.json→versiondesktop/src-tauri/Cargo.toml→package.versiondesktop/src-tauri/tauri.conf.json→version- Git tag
v{VERSION}(orworkflow_dispatchversioninput)
Mismatch → fail closed (exit non-zero in the version-check step); no upload.
§QR.9 — Boundary & capability table (frozen)
| Concern | Q3-release Auto | Runtime / operator |
|---|---|---|
| Build Tauri installers in CI | Yes | Configures secrets; cuts tag |
| Sign / notarize | Yes (CI + secrets) | Owns Apple/Windows/Linux credentials |
| Provide Python on end-user hosts | Never (Auto v1) | Installs Python 3.11+; later freeze may embed |
Change ok app / api/* |
Never | — |
Merge to main |
Never | Tier-3 human |
| Hosted multi-repo dashboard | Never (separate product) | — |
| Auto-update installed apps | Never in Auto v1 | Later freeze |
| Path A / B without installers | Unaffected | Still recommended where appropriate |
| Capability | git-only |
muse+git-mirror / muse-only |
|---|---|---|
| Consume published installers | Full (download from GitHub Releases) | Full |
| Kit source canonical | GitHub main |
MuseHub |
| Release tag cut | Operator on GitHub | Operator; prefer Muse-aligned SHA (§QR.7.2) |
§QR.10 — Rejection table (frozen)
| Proposal | Verdict |
|---|---|
Rewrite Track Q engine / add api/* routes for “installer mode” |
Reject |
Commit Apple/Windows/Linux private keys or .p12/.pfx into the repo |
Reject |
Publish unsigned .dmg/.msi/.AppImage on a Release labeled signed |
Reject |
| Soft-skip signing when secrets missing on release publish | Reject |
| In-app auto-updater / update CDN in Auto v1 | Reject (deferred) |
| App Store / Microsoft Store / Flathub submission in Auto v1 | Reject |
| Embed a Python interpreter / claim zero-dependency Path C in Auto v1 | Reject (deferred; honesty: Python 3.11+ still required) |
| Embed Scooling/Knowtation product runtime into the installer | Reject |
Claim Muse SHA provenance for binary blobs as ledger verification_evidence without a later freeze |
Reject |
| Thinking phase ships workflow YAML / binaries | Reject |
This freeze authorizes merge to main |
Reject (Tier 3) |
| This freeze configures live GitHub secrets | Reject (Tier 3 — operator) |
| Replace Path A as the only supported normie path | Reject (installers additive) |
| MuseHub-only installer distribution (no GitHub Release path) | Reject (K7 baseline — GitHub distribution required) |
| PR-triggered publish to GitHub Releases | Reject (§QR.4.2) |
§QR.11 — Auto build deliverables (frozen)
After freeze pass, the Auto build ships only:
- GitHub Actions workflow
.github/workflows/desktop-release.ymlimplementing §QR.4–§QR.8. - Optional smoke workflow
.github/workflows/desktop-build-smoke.yml(unsigned Linux-only or documented subset) — must not publish signed Releases. - Template copy
templates/ci/desktop-release-github-actions.yml(K11-style vendored example). - Library
tools/desktop_release/— version-align checker, manifest schema builder/validator, secret-pattern refuse helpers, checksum helpers (pure Python; no network required for unit tests). - Public key path
desktop/keys/with README stating public-only; placeholder or real public key file for Linux detached verify (private key never committed). - Operator runbook update — extend
docs/TRACK-Q-DESKTOP-OPERATOR-RUNBOOK.md§Release vs dev + new §Signed installers (download, verify sha256 + Linux detached sig, secret setup checklist for operators, honesty about AppImage method, Python 3.11+ host prerequisite). .gitignore/.museignoreentries for local signing material patterns (*.p12,*.pfx,*.key,apple-api-key.json, etc.) if not already covered.- Seven-tier tests per §QR.13.
- SPEC §5 — additive note that desktop installers are an optional distribution channel for
the existing
ok app/ Tauri shell (no new CLI subcommand required for Auto v1).
No new top-level ok subcommand is required for Auto v1. If Auto adds a read-only helper
(e.g. ok desktop-release --validate-manifest PATH), it MUST be inert/read-only and allocated
only if tests need a CLI seam — default is library + workflow only.
§QR.11.1 — Runbook checklist Auto must document (operator, not Auto execution)
- Create Apple Developer ID + notarization credentials; store under §QR.6.2 names.
- Create Windows Authenticode cert; store under §QR.6.2 names.
- Generate Linux minisign/GPG keypair; commit public key only; store private key as
LINUX_SIGNING_KEY. - Ensure
VERSIONand desktop version fields match. - Align Muse + GitHub tips; cut
v{VERSION}tag; confirm Release assets + manifest.
§QR.12 — Fail-closed / errors (frozen)
| Condition | Behavior |
|---|---|
| Version mismatch (§QR.8) | Fail job; no upload |
| Missing required signing secret on release publish | Fail job; no upload for that platform; finalize fails unless allow_partial (still honest) |
tauri build non-zero |
Fail job |
| Bundle script missing / non-executable | Fail job |
| Manifest schema invalid | Fail finalize; do not mark Release complete |
| Smoke workflow | May upload unsigned workflow artifacts only; never GitHub Release |
| Secret-looking material in git diff of release files | Unit/security tests fail the Auto build locally |
No new process-level ok exit code is allocated by this freeze unless Auto adds an optional CLI
validator — if added, reuse exit 2 for validation refuse (no new number without amendment).
§QR.13 — Seven-tier test matrix (Auto build must satisfy)
The Auto build ships all seven tiers green locally before DONE (policy/test-tiers.yaml).
Live Apple/Windows notarization and live GitHub Release upload are not required for DONE —
those need operator secrets (Tier 3). Tests use fixtures + workflow static analysis.
| Tier | Proves |
|---|---|
| unit | Version-align checker accepts equal VERSION/package/Cargo/tauri strings and refuses mismatch; manifest schema accepts valid fixture and refuses unknown platform / signing.status / signing.method; signed + method: none refused; secret-pattern scanner flags PEM/PFX-like blobs and passes clean workflow fixtures; checksum helper matches known vectors; public-key path rules (private key filenames refused under desktop/keys/). |
| integration | Workflow YAML parses; release workflow declares macOS/Windows/Linux matrix and tag/workflow_dispatch triggers only; macOS runner is pinned macos-14 or macos-15 (not bare macos-latest); workflow permissions omit elevated scopes beyond §QR.4.6; smoke workflow (if present) has no Release-publish step; template under templates/ci/ exists and references §QR.6.2 secret names (including Apple API-key alternate names when documented); bundle-desktop-kit.sh still listed as the kit copy path with closed allowlist; tools/desktop_release builds a manifest from fixture artifact names; publish-allowlist helper rejects .deb/.rpm/unsigned names. |
| e2e | Fixture “release finalize” path: given three platform artifact fixtures + signatures metadata → writes manifest + SHA256SUMS.txt → validates round-trip; simulated missing Apple secret → finalize refuse; runbook contains Path C download section, AppImage honesty sentence, and Python 3.11+ host prerequisite; no mutation of Track Q tools/app API allowlists; fresh bundle destination contains no .env fixture planted outside allowlist. |
| stress | Manifest builder handles ≥ 50 artifact filename entries without unbounded memory growth (documented cap or streaming hash); checksum of multi-megabyte fixture file completes without loading entire file twice unboundedly if streaming API exists — otherwise document single-pass bound. |
| data-integrity | Twin manifest builds from identical fixtures → byte-identical JSON (canonical key order frozen by builder); sha256 in manifest matches SHA256SUMS.txt; re-validate after rewrite succeeds; version-align is pure (no writes). |
| performance | Version-align + manifest validate on fixture completes within a documented bound (e.g. ≤ 2s on CI-sized fixture); workflow YAML scan of secret patterns bounded to release workflow paths (no full-repo secret hunt as the only path). |
| security | No private key / cert password literals in workflow or template files; .gitignore covers *.p12 *.pfx signing patterns; release workflow does not echo secret values; pull_request cannot publish Releases; permissions match §QR.4.6; Track Q launcher still invokes ok app only; no new non-loopback bind defaults; security tests assert rejection-table items that are mechanically checkable (unsigned labeled signed refused by validator; non-allowlisted asset types refused). |
§QR.14 — Hard stops + tier linkage (frozen)
| Action | Tier | Rule |
|---|---|---|
| Feature-branch commits for this freeze / Auto | Tier 1 | SD-1 / SD-17 |
git push feature branch / open PR |
Tier 1 | No merge |
| Confirm Linux detached-sig algorithm choice if Auto needs GPG vs minisign default | Tier 2 | Freeze default = minisign; GPG is allowed alternate via method: gpg_detached — record ADR only if changing default |
| Configure / rotate GitHub signing secrets | Tier 3 | Operator only |
Merge to main |
Tier 3 | Human only — not authorized here |
| Staging push / live capability flip | Tier 3 | Human only |
| Cut first public signed Release | Operator | Requires secrets + tag; not authorized by this Thinking freeze alone |
Escalation categories for freeze review remain: security, irreversible, real_money,
gates_tier3.
§QR.15 — Definitions of Done
§QR.15.1 — Thinking freeze (this phase)
- [x] This document reviewed →
passvia/freeze-review-loop+ok review --freeze - [x] Review-record table stamped;
review_stampfilled - [x]
docs/ROADMAP.md— Q3-release promoted from exploration backlog; Thinking DONE; Auto TODO - [x]
docs/OVERSEER-HANDOVER.mdNEXT regenerated for Q3-release Auto (SD-17) - [x] No workflow / binary / signing-secret material landed in Thinking
- [x] No Tier-3 merge performed
§QR.15.2 — Auto build (later)
- [x] Mechanical implementation matches §§QR.4–QR.12 and §QR.11
- [x] Seven-tier matrix §QR.13 green
- [x]
/build-verification-review→passbefore ROADMAP Auto → DONE - [x] Governance sync (ROADMAP + HANDOVER) in the closing commit
- [x] Feature-branch push / PR only; merge remains Tier 3
- [x] Track Q engine/API surfaces unchanged
- [x] Live Apple/Windows notarization not required for Auto DONE (secrets are operator Tier 3)