Kajar notes of ChronoRET, rebuilding Chrono Trigger one matched routine at a time

Last updated: October 15, 2026

CI Setup

The GitHub Actions workflow at .github/workflows/match.yml in the code repo runs on every pull request to main and every push to main. It has two jobs.

Readability standard (no ROM needed)

  1. python3 tools/lint_readability.py: every routine outside tools/readability_baseline.txt must meet the readability standard (the header checks that need the ROM are skipped here and run in the second job).
  2. python3 tools/validate_functions.py: the review log in symbols/reviews/ is well formed.
  3. python3 tools/progress.py --check: the generated files (symbols/functions.csv, symbols/progress.json) are not tracked, and no doc carries a generated number.

Reassemble and diff (needs the ROM)

  1. Fetch the ROM from the private ct-rom repository with the ROM_TOKEN secret (see below).
  2. Build asar 1.91 from source and run python3 tools/check_env.py.
  3. make diff: the reassembled ROM must equal the original, byte for byte.
  4. python3 tools/verify.py: every byte the source claims is really emitted by it.
  5. python3 tools/progress.py --update: regenerate symbols/ from the source.
  6. python3 tools/lint_readability.py again, now with the ROM (header and caller checks).
  7. python3 tools/validate_functions.py and python3 tools/progress.py --check again.

First-time setup

The ROM cannot be committed to the public repo, and it cannot go in a secret either: GitHub caps secrets at 48 KB and the ROM is 4 MB. So it lives in a private repository, ThisIsAkill/ct-rom, as Chrono Trigger (USA).sfc at the root, and CI downloads it with a read-only token.

1. Create the token

  1. GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token
  2. Repository access: Only select repositories → ct-rom
  3. Permissions → Repository permissions → Contents: Read-only (nothing else)
  4. Pick an expiry, generate, and copy the token.

2. Add it as a secret on the code repo

  1. In ChronoRET: Settings → Secrets and variables → Actions → New repository secret
  2. Name: ROM_TOKEN
  3. Value: the token

The job downloads the ROM to roms/chrono_trigger.sfc and checks it against rom.sha256 in the code repo, failing on a mismatch. The expected hash is also on Target ROM. When the token expires, the download fails with an error naming ROM_TOKEN; make a new one and replace the secret.

3. Verify

Re-run the latest Byte-exact match check run, or open a pull request; the Reassemble and diff job should now run every step instead of skipping.

If the secret is not set

The second job degrades gracefully: it emits a warning and skips everything after fetching the ROM, so it won't fail. Pull requests from forks never get secrets, so they always skip it. The first job always runs. Contributors without the secret can still run everything locally.

Local workflow (no CI needed)

Shell
python3 tools/check_env.py   # confirm asar + python3 present
make gate                    # make diff, make verify and make lint in one go
python3 tools/progress.py    # print the current numbers by level and bank