Skip to content

Move PR preview builds and hosting into Web Simulator - #8

Open
schnuartz-ai wants to merge 46 commits into
cryptoadvance:mainfrom
schnuartz-ai:codex/paired-preview-service
Open

schnuartz-ai wants to merge 46 commits into
cryptoadvance:mainfrom
schnuartz-ai:codex/paired-preview-service

Conversation

@schnuartz-ai

@schnuartz-ai schnuartz-ai commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Move the complete Specter DIY pull-request preview service into this repository, paired with [Specter DIY PR #440](cryptoadvance/specter-diy#440).

The Web Simulator handles PR validation, firmware and browser builds, integration tests, artifact verification, GitHub Pages hosting, preview lifecycle management, and automated PR comments through a dedicated GitHub machine-user account.

The Specter DIY dispatcher does not poll for results or update PR comments. It validates the request, dispatches the build, and exits.

Architecture

  1. The Specter DIY dispatcher sends exact PR metadata and a unique request ID using workflow_dispatch.
  2. The Web Simulator independently validates the live PR, repositories, branches, and exact commit SHAs.
  3. An untrusted build job compiles firmware and the WebAssembly browser payload from the PR head SHA.
  4. A separate trusted job builds JavaScript from the exact validated PR base SHA.
  5. A clean runner verifies browser compatibility, network restrictions, Virtual Host behavior, USB transport, and build provenance.
  6. The trusted finalizer validates artifacts without executing untrusted code.
  7. The finalizer publishes the immutable preview through GitHub Pages.
  8. A dedicated machine user creates or updates a single PR comment.

Failed or cancelled builds preserve the last successfully published preview.

Machine-user PR comment reporting

Instead of a GitHub App with broad PR write permissions, the service uses a dedicated GitHub account, specter-preview-bot, without repository write access.

The trusted reporter:

  • Verifies the authenticated GitHub username through GET /user.
  • Revalidates the live PR and published preview state before writing.
  • Creates exactly one marked preview comment if none exists.
  • Updates that comment in place using PATCH, preserving its comment ID and preventing duplicate timeline entries.
  • Only edits or deletes comments authored by the configured machine user that contain <!-- specter-web-simulator-preview -->.
  • Never modifies other contributors' comments or PR metadata.
  • Removes its own preview comments when the PR closes.
  • Rejects stale builds and invalid preview URLs.
  • Updates existing comments when their previews are removed because of GitHub Pages storage limits.

Comment layout

The compact comment contains:

  • Specter PR Build with short commit SHA and build status.
  • Collapsible Build provenance showing source, base and simulator commits and build logs.
  • Open browser simulator link.
  • Download firmware from the same commit link.
  • Prominent warning against entering real seed phrases, using real funds, or flashing development firmware onto production hardware.

Security model

Untrusted build jobs:

  • Run with contents: read.
  • Receive no repository secrets or write-capable tokens.
  • Cannot publish GitHub Pages or modify PR comments.

Trusted JavaScript runtime:

  • Builds on a separate runner from the exact validated PR base SHA.
  • Does not execute PR-controlled JavaScript tooling.

Trusted finalizer:

  • Validates artifacts, paths, hashes, manifests and provenance.
  • Rejects unexpected or malicious archive contents.
  • Never executes untrusted build artifacts.
  • Holds the machine-user token only during trusted reporting.
  • Publishes validated browser artifacts and manages preview cleanup.

The machine user must not receive write, triage or admin access to cryptoadvance/specter-diy.

Its classic PAT uses public_repo, which is broader than comment-only access, but cannot grant permissions beyond those of the account itself.

The trusted Web Simulator default branch remains security-critical and requires branch protection and maintainer review.

Simulator footer improvement

The device footer now displays the actual firmware version and the exact Specter DIY source commit:

GitHub · v1.10.5 · abc1234

The abbreviated SHA is shown even when optional PR metadata is unavailable. The footer links directly to the exact source commit rather than merely the repository homepage.

A browser regression test verifies the version, SHA, separator and hyperlink.

Preview lifecycle

  • Commit-specific URLs: /pr/<number>/<full-head-sha>/.
  • Latest successful preview retained per PR.
  • Previous successful preview preserved after failed builds.
  • Stale workflow results cannot overwrite newer state.
  • Superseded firmware artifacts are removed after successful replacement.
  • PR closing triggers preview and firmware cleanup.
  • GitHub Pages capacity limits are handled through controlled eviction and comment updates.

Required production configuration

Before production deployment:

  1. Enable GitHub Actions and GitHub Pages using the GitHub Actions deployment source.
  2. Protect main with required maintainer reviews, passing CI, and restrictions on direct and force pushes.
  3. Create a new production Personal Access Token (classic) using specter-preview-bot, with public_repo scope.
  4. Configure the Web Simulator Actions secret SPECTER_PREVIEW_BOT_TOKEN.
  5. Configure the Web Simulator Actions variable SPECTER_PREVIEW_BOT_LOGIN with value specter-preview-bot.
  6. Configure the separate WEB_SIMULATOR_DISPATCH_TOKEN in Specter DIY, scoped to Actions access on the paired Web Simulator repository.
  7. Verify the organization's pull_request_target Actions policy.

Do not reuse the fork-test PAT in production.

No GitHub App installation or PR-write repository permission is required for the machine user.

See [the full setup and security guide](docs/browser-simulator.md).

Validation

Successfully tested:

  • Python reporter, ownership and stale-state tests.
  • Machine-user authentication and PR write-denial tests in the fork.
  • Single-comment creation and in-place updating.
  • Compact comment formatting and collapsible provenance.
  • Browser footer commit-link regression test.
  • Firmware and WebAssembly builds.
  • Browser compatibility, network policy, Virtual Host and USB transport.
  • GitHub Pages publication and cleanup.
  • Full fork end-to-end integration.

Relevant successful runs:

Still pending: Production repository secret/variable configuration and a controlled upstream end-to-end test using the production bot credential.

Merge order

  1. Configure and protect the Web Simulator repository.
  2. Merge Web Simulator PR Move PR preview builds and hosting into Web Simulator #8.
  3. Configure production bot credentials and verify a controlled upstream comment.
  4. Merge Specter DIY PR #440.
  5. Verify the complete production workflow with a final test PR.

@Schnuartz

Schnuartz commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

[To Do]

  1. activate GitHub Actions inside of this repo
  2. activate GitHub Web Pages inside of this repo
  3. Settings: Set Approval Policy for main branch

@Schnuartz

Copy link
Copy Markdown
Collaborator

@al-munazzim could you review this?

@al-munazzim

Copy link
Copy Markdown

I reviewed this paired service PR alongside the Specter-side dispatcher PR.

The important security shape looks right to me: the Web Simulator validates the live PR metadata before building, checks out the exact head SHA, keeps the untrusted build job read-only/no secrets, and does the Pages/status update in a separate trusted finalizer that treats artifacts as data. The additional provenance, stale-result, and preview cleanup tests are also the right coverage for this flow.

I do not see a code-level blocker here. Before merging/deploying, the repo-level setup items still matter:

  1. enable GitHub Actions in this repository;
  2. enable GitHub Pages with GitHub Actions as the source;
  3. ensure the default branch / approval policy is set as intended, since this repo becomes the stronger trust root for previews;
  4. after the paired Specter dispatcher is configured, run one upstream test PR to verify dispatch → build → Pages status JSON → PR comment update in the cryptoadvance org, not only in forks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants