10 Commits
Author SHA1 Message Date
Joseph MattielloandClaude Fable 5.1 313a18d70b ci(release): attest, sign and gate every release asset (#1151, #1152)
One `stage` job in release.yml now flattens the artifacts, writes
SHA256SUMS.txt, signs it with the project minisign key
(SHA256SUMS.txt.minisig; public key docs/release-signing.pub once the
maintainer generates it) and attests build provenance for every file with
actions/attest-build-provenance.  A `verify-signatures` gate on a macOS
runner then checks each asset against its expected signing state
(scripts/release/verify.sh: macOS Developer ID + notarized, Windows
`unsigned` until #1150 flips one line, AppImage and checksum signatures once
their public keys are committed, attestation on everything), strict on tags
and release/**, warn-only on develop so an outage cannot withhold the core
nightly.  Its per-artifact table (signed, notarized, attested) replaces the
signing prose in the release body and the job summary.  The macOS and
AppImage signing steps write signing-status sidecars for the facts the gate
cannot re-derive from a file (Apple's ticket on a bare Mach-O).

AppImages: make-appimage.sh passes --sign --sign-key to appimagetool when
VJ_APPIMAGE_SIGN_KEY is set (app-package.yml imports APPIMAGE_GPG_PRIVATE_KEY
into a throwaway GNUPGHOME; the passphrase goes through
APPIMAGETOOL_SIGN_PASSPHRASE).  appimagetool 1.9 has no verifier, so
app/packaging/linux/verify-appimage.py re-hashes the image with the
signature sections zeroed and runs gpg --verify.

Installers: tools/install.sh and install.ps1 verify SHA256SUMS.txt's
minisign signature (pinned key) or, with gh, its attestation before
trusting it; a bad one aborts, a release that predates signing warns;
--no-verify / -NoVerify skips the step.  Both hermetic suites cover it with
fake minisign/gh.  New release-scripts.yml tests the stage/sign/verify
scripts (Linux also signs a real AppImage).  A `dry_run` dispatch input on
release.yml runs everything up to the gate on any branch and publishes
nothing.

Docs: key generation and secret commands in app/packaging/README.md
(SignPath "dormant" text removed), release-process.md, SECURITY.md, the
site's Download page (public key once committed), the nightly tracker text,
and the stale "signing service" known-issue line in the v3.11.0 notes.

Closes #1151
Closes #1152

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-11-02 21:36:57 -05:00
Joe Mattiello a5593e55d9 test(tom): preserve Atari Karts HC regression coverage and doc correction (#1096)
* test(tom): guard Atari Karts racing line after HC fix (#1085)

* ci: allow scoped temporary Linux runners for Karts validation
2026-10-26 10:06:58 -04:00
e7009c440a ci: trim develop-push runs, debounce nightly, route macOS to Studio runner (#1074)
* ci: stop re-running PR-covered workflows on develop pushes; debounce nightly; route macOS to Studio runner

Drop develop from push: in c-cpp, app, regression-test, acid-test, installer,
jaguar-demos, microbench, jaguar-toolchain and cheat-import (PRs already ran
them); ignore develop in pull-request.yml. release.yml's nightly waits 10 min
in its guard job so a merge burst builds once. macOS rows of c-cpp/app/
regression and the unsigned iOS/tvOS nightly rows use the self-hosted Studio
runner on trusted events only, with a VJ_STUDIO_RUNNER=off kill switch.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

* ci(spm): find blitter_simd objects independent of SwiftPM build layout

Xcode 26 SwiftPM keeps objects under .build/out/Intermediates.noindex/...
instead of <triple>/debug/virtualjaguar.build, which broke the vtable check on
the Studio runner. Search by object name and fail loudly if one is missing.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>

---------

Co-authored-by: dry <dry@x>
Co-authored-by: Claude Sonnet 5.5 <[email protected]>
2026-10-22 23:24:46 -04:00
Joseph Mattiello 3c683169ef ci(core): share compile-only release builds and preserve CI artifacts 2026-10-20 18:39:49 -04:00
Joseph Mattiello 2165519e97 ci: allow ref-scoped temporary runners for lightweight checks 2026-10-20 17:34:02 -04:00
Joe Mattiello 998dee625c docs: make AGENTS.md the shared Codex and Claude guide (#1032) 2026-10-19 17:35:29 -04:00
Joseph MattielloandClaude Opus 5.5 3539fbb65b feat(tools): corpus gate -- matrix_diff.py, never-backward cart rule, pre-tag checklist (#749)
test/tools/matrix_diff.py OLD.md NEW.md compares two cart or CD boot
matrices per row. Stage rank (low->high): -1 ?(core_error|build_mismatch|
no_reg), 0 LOAD_FAIL, 1 HARNESS_HANG/?/?(pc_escape|timeout|BIOS band),
2..6 BIOS_INTRO, BOOT_STUB, GAME_CODE, MENU, IN_GAME. At equal rank a new
crash-watchdog signature (from the notes/Watchdog cell) is backward.
Prints regressed / still-asymmetric / improved / added / removed; exits
1 on any backward move, 2 on parse error. test/test_matrix_diff.sh (43
checks) runs in make test. The cart matrix header (generator + doc) now
carries the never-backward rule; docs/release-process.md gains the
pre-tag checklist (regenerate both matrices on the RC on the corpus
machine, diff vs the previous tag, a backward row blocks the tag until
ticketed and deferred, improved list feeds release notes).

Sanity: cart v3.7.0 -> v3.7.1 shows 5 regressed cells (Music Demo BIOS
GAME_CODE -> ?(pc_escape); inframe_hang newly visible on 4 homebrew).

Closes #749

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 14:36:59 -04:00
Joseph MattielloandClaude Opus 5.5 b563b2c38b ci(release): check-info-version.sh checks all three version copies
The version lives in the Makefile, dist/info and src/core/version_fallback.h.
The script compared only the first two; v3.6.1's stale fallback header was
caught by a different CI job ('duplicated lists in sync') instead. Now it
fails naming the fallback file when that one drifts. Verified: passes on
develop (all v3.6.1), fails with exit 1 when the fallback says v3.6.0.
docs/agent/github.md's release step lists all three.

Fixes #734

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 05:59:36 -04:00
Joe Mattiello 7b66c02018 ci(pr-issue-link): create the link from a body tag instead of demanding a manual step (#644)
* ci(pr-issue-link): create the link from a body tag instead of demanding a manual step

Every new PR here went red on creation for a step that cannot be performed
until after the PR exists: the linked-issue check failed, and the fix was a
manual click in the Development panel that does not re-trigger the job.

The premise behind that was stale. This job's own comment -- and
docs/agent/github.md -- asserted "there is no public API to create that
link, so it has to be done in the UI" and "don't burn time on a gh flag or
GraphQL mutation". The mutation exists:

  addCloseIssueReferences -- "Adds one or more pull requests as manually
  linked closing references on an issue."

That is exactly the Development-panel relationship, and it is idempotent
(verified against PR #641/#632, already linked: re-running changed nothing;
and end-to-end against #642/#633 by unlinking, re-linking from a body tag,
and confirming the result).

So the job now makes the link rather than complaining that nobody did:

  * scripts/pr-link-issue.sh <pr> [issue] [--repo o/n] does the work and is
    runnable by hand. No issue argument -> scan the PR body for a tag.
    Already linked -> no-op, so it is safe to run unconditionally.
  * The workflow runs it and only fails when there is no tag to act on. Its
    failure summary now says to edit the description, because `edited`
    re-runs the job and it links then -- no push required.

Accepted tags, case-insensitive:

  Closes #123 / Fixes #123 / Resolves #123 / Refs #123
  <!-- link-issue: #123 -->      invisible in the rendered body

The hidden form wins over the keywords, so a PR can discuss one issue in
prose and link a different one deliberately. The keywords still do nothing
on GitHub's own side here -- GitHub honours them only when the PR targets
the default branch, which is `master` while PRs target `develop`. They are
markers for this job.

Security: the job runs pull_request_target with a write token, so it checks
out the BASE ref (actions/checkout's default for that event) and never the
PR head -- the script it executes is the trusted copy from the target
branch, not one the PR could have edited. The only untrusted input is the
body, parsed to an integer and validated to be an existing issue (not a PR)
before use. Permissions widened by exactly one: issues: write, which is what
the mutation needs.

Refs #643

* fix(pr-link-issue): ignore link tags inside code blocks

Caught by the feature's own PR. #644 documents the accepted tag syntax with
a fenced example:

    Closes #123    Fixes #123    Resolves #123    Refs #123
    <!-- link-issue: #123 -->

The scan matched that example before reaching the real `<!-- link-issue:
#643 -->` at the bottom of the same body, and linked the PR to issue #123 --
a closed OP performance spike with nothing to do with it. Any PR that
explains this feature would have done the same, which makes it exactly the
kind of body the parser has to survive.

Strip fenced blocks and inline code spans before scanning. Anything inside
code is a sample, not an instruction.

Verified: re-running against #644 now yields "PR #644 -> linked to #643",
and a synthetic body with an inline `Refs #111`, a fenced `Closes #222` and
`<!-- link-issue: #333 -->`, plus a real `<!-- link-issue: #444 -->` outside
any code, selects 444.

Refs #643
2026-08-26 22:04:04 -04:00
Joseph MattielloandClaude Opus 4.8 1ced42b14d docs: split CLAUDE.md into on-demand agent reference docs
CLAUDE.md loaded ~10K tokens on every message and into every subagent at
startup. Slim it to load-bearing always-on rules (~2K) plus an index, and
move the catalogs and how-to detail into docs/agent/*.md that load only when
read:

- docs/agent/build.md    — build cmds, C89 exempt list, TEST_EXPORTS relink,
                           build-identity guard, stale-.o hazard
- docs/agent/hardware.md — processor model, memory map, clocks, source
                           layout, distilled JTRM index
- docs/agent/testing.md  — harness catalog, vjtrace, audio-test requirements,
                           crash-watchdog signatures, acid gating, profiling
- docs/agent/github.md   — PR-issue linking, Copilot/Kimi, release process,
                           site publishing

Safety rules (C89, branch-off-develop, DEVELOPER_DIR, audio-test pair,
PR-issue link, private-ROM / git clean danger, shell-alias trap) stay inline
so no agent can miss them without opening a doc. Removed the duplicated
build-identity-guard block; compressed language to shorthand. No content
dropped — verified the tripwire facts (MMULT fix, PR #170, closingIssues,
ROM-symlink rules) survived the move.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AiMAfypdq7ASvQWK6vQ5hW
2026-08-20 21:52:50 -04:00