PHASE-Q3-RELEASE-DESKTOP-INSTALLERS.md markdown
659 lines 37.2 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 2 days ago

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/, closed api/*, bind/auth, exit codes, or ok app semantics. 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/.pfx files.
  • 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.shdesktop/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:

  1. push of an annotated or lightweight tag matching v* where the tag name (without leading v) equals the kit VERSION file contents after trim, or
  2. workflow_dispatch with 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:

  1. Checkout the tagged commit (immutable SHA for that tag).
  2. Set up Python 3.11+, Node (LTS), Rust per desktop/src-tauri/rust-toolchain.toml (1.88+).
  3. Run ./scripts/bundle-desktop-kit.sh (or rely on Tauri beforeBuildCommand that invokes it — both are acceptable; tests assert the script remains the single copy path into resources/kit/).
  4. cd desktop && npm ci && npx tauri build (or npm run tauri -- build).
  5. Locate bundle outputs under desktop/src-tauri/target/release/bundle/ (platform-specific subdirs).
  6. Apply platform signing (§QR.5).
  7. Compute SHA-256 of each published file; emit manifest fragment (§QR.7).
  8. 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 unsigned or 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: signed requires a non-none method from the matching platform row in §QR.5.
  • unsigned / unavailable MUST NOT appear on a GitHub Release that operator docs call “signed installers available” — finalize job fails closed if any required platform is not signed (unless allow_partial: true, which forces explicit unavailable rows 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:

  1. Root VERSION file
  2. desktop/package.jsonversion
  3. desktop/src-tauri/Cargo.tomlpackage.version
  4. desktop/src-tauri/tauri.conf.jsonversion
  5. Git tag v{VERSION} (or workflow_dispatch version input)

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:

  1. GitHub Actions workflow .github/workflows/desktop-release.yml implementing §QR.4–§QR.8.
  2. Optional smoke workflow .github/workflows/desktop-build-smoke.yml (unsigned Linux-only or documented subset) — must not publish signed Releases.
  3. Template copy templates/ci/desktop-release-github-actions.yml (K11-style vendored example).
  4. 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).
  5. Public key path desktop/keys/ with README stating public-only; placeholder or real public key file for Linux detached verify (private key never committed).
  6. 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).
  7. .gitignore / .museignore entries for local signing material patterns (*.p12, *.pfx, *.key, apple-api-key.json, etc.) if not already covered.
  8. Seven-tier tests per §QR.13.
  9. 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 VERSION and 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 → pass via /freeze-review-loop + ok review --freeze
  • [x] Review-record table stamped; review_stamp filled
  • [x] docs/ROADMAP.md — Q3-release promoted from exploration backlog; Thinking DONE; Auto TODO
  • [x] docs/OVERSEER-HANDOVER.md NEXT 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-reviewpass before 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)
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 2 days ago