Skip to content

Repository files navigation

OpenPhysics Baton

Orchestration repository for the OpenPhysics organization. Baton owns the operational side of the org: the reusable CI/CD workflows every simulation calls, the cross-repo automation scripts, the Dependabot templates, the machine-readable repository catalog, and the GitHub Pages simulation landing page.

Community-health defaults (license, contributing, code of conduct, security policy, issue/PR templates, org profile) live in OpenPhysics/.github — GitHub requires those in the special .github repo so they are inherited org-wide.

Contents

Path Purpose
.github/workflows/ci.yml Reusable CI workflow (audit, lint, type-check, test, build)
.github/actions/security-audit/action.yml Composite action used by ci.yml: npm audit summary, blocks only on high/critical in direct deps
.github/workflows/deploy.yml Reusable GitHub Pages deploy workflow
.github/workflows/shared-codeql.yml Reusable CodeQL analysis
.github/workflows/shared-dependency-review.yml Reusable dependency review
.github/workflows/shared-compliance-check.yml README and repo-structure compliance audit
.github/workflows/pages.yml Build and deploy the org simulation index to GitHub Pages
.github/workflows/optimize-assets.yml Regenerate WebP card thumbnails from screenshots and commit them back
.github/workflows/refresh-screenshots.yml Weekly/manual refresh of card screenshots from live Pages → WebP thumbnails + docs/index.html (opens a PR)
.github/workflows/fleet-exec.yml Fan a command across many repos and open one PR each (manual dispatch)
.github/workflows/fleet-health.yml Weekly lint / type-check / build / test of every simulation, reported as a table
.github/workflows/sync-dependabot.yml Validate the Dependabot templates
.github/workflows/baton-selfcheck.yml Validate Baton's own invariants (skills, catalog schema, Node-version sync, script syntax)
scripts/ Repo catalog tools, compliance checks, Dependabot/metadata sync, screenshots
config/ Canonical Dependabot + Claude-settings templates synced to member repos
structure/repos.json Machine-readable catalog of org repositories
structure/repos.schema.json JSON Schema for the catalog (schemaVersion 1.1.0)
CONVENTIONS.md Shared codebase structure every SceneryStack sim must follow
ACCESSIBILITY.md Shared accessibility pattern for SceneryStack sims
skills/ SceneryStack development reference docs for AI assistants
.claude-plugin/ Marketplace + plugin manifests that package skills/ as the scenerystack@openphysics Claude Code plugin
docs/ Generated landing page (openphysics.github.io/Baton)
doc/add-simulation.md Checklist for adding a sim to the catalog and landing page
doc/fleet-git.md Cheat sheet: everyday git across local checkouts (pull/push/status all)
doc/fleet-auth.md Setting up the FLEET_PAT / GitHub App that lets fleet-exec open PRs

Claude Code plugin

This repo doubles as a Claude Code marketplace. It publishes one plugin, scenerystack, that bundles the skills/ reference docs so any sim repo can load them as a unit instead of vendoring copies. The repo root is the plugin (.claude-plugin/plugin.json); its skills/ are auto-discovered.

Member repos enable it from their .claude/settings.json (the canonical keys live in config/claude-settings.json):

{
  "extraKnownMarketplaces": {
    "openphysics": { "source": { "source": "github", "repo": "OpenPhysics/Baton" } }
  },
  "enabledPlugins": { "scenerystack@openphysics": true }
}

Or interactively: claude plugin marketplace add OpenPhysics/Baton then claude plugin install scenerystack@openphysics. Validate manifest changes with claude plugin validate .claude-plugin/marketplace.json.

Roll it out across the fleet with scripts/sync-claude-settings.sh, which merges those keys into every SceneryStack repo's settings without clobbering existing config.

Shared CI

Each simulation's .github/workflows/ci.yml calls the reusable workflows from this repo:

jobs:
  ci:
    uses: OpenPhysics/Baton/.github/workflows/ci.yml@main
  dependency-review:
    if: github.event_name == 'pull_request'
    uses: OpenPhysics/Baton/.github/workflows/shared-dependency-review.yml@main
  codeql:
    uses: OpenPhysics/Baton/.github/workflows/shared-codeql.yml@main

Optional compliance checking:

  compliance:
    uses: OpenPhysics/Baton/.github/workflows/shared-compliance-check.yml@main
    with:
      repo-name: ${{ github.event.repository.name }}

ci.yml runs the test step automatically when the caller defines a test npm script — no per-repo flag needed. Pass run-tests: "true" to force it on (e.g. before a test script exists) or run-tests: "false" to opt out.

Pages deploy (sims that publish to GitHub Pages):

jobs:
  deploy:
    uses: OpenPhysics/Baton/.github/workflows/deploy.yml@main
    permissions:
      contents: read
      pages: write
      id-token: write

Compliance workflow

shared-compliance-check.yml runs weekly (Mondays 06:00 UTC) and on manual dispatch. It reads structure/repos.json, clones each simulation repo, and runs scripts/check-repo-compliance.sh. The gate enforces (FAIL unless marked (warn)):

  • Legal & README — no root CONTRIBUTING.md / LICENSE (org defaults from OpenPhysics/.github); README.md has the six sections in order with no extras (Features → Quick Start → Scripts → Tech Stack → License → Contributing).
  • CI wiring.github/workflows/ci.yml calls this repo's reusable ci.yml plus shared-dependency-review.yml and shared-codeql.yml; .github/dependabot.yml present.
  • Node pinsengines.node is >=24 and @types/node major is 24 (matching the fleet Node version); a .nvmrc / .node-version, if present, agrees.
  • SceneryStack structure (sims only) — the five-file bootstrap chain with main.ts importing ./brand.js first; <Prefix>Namespace.ts, <Prefix>Colors.ts, and *Constants.ts at the src/ root; the preferences/ trio; i18n/ with StringManager.ts + en/es/fr locales; a *KeyboardHelpContent.ts; .claude/settings.json enabling the scenerystack plugin; no tests co-located under src/; no top-level src/model or src/view (warn).
  • Tests & hookstests/memory-leak.test.ts + a vitest.config.ts that sets --expose-gc; .githooks/{pre-commit,pre-push} activated via the prepare script.
  • Docs & toolingdoc/model.md + doc/implementation-notes.md present and filled (warn if stub); biome.json $schema version matches the pinned @biomejs/biome.
  • GitHub security (when gh is authenticated) — Dependabot vulnerability alerts + security updates, and secret scanning on public repos.

Simulation READMEs use the fixed six-section outline above. Items marked (warn) — plus hardcoded colors and nested constants — surface as warnings, not failures: document each as a carve-out under ## Compliance carve-outs in the sim's CLAUDE.md.

Run locally against a checkout:

scripts/check-repo-compliance.sh /path/to/sim-repo

Repository catalog

structure/repos.json lists all OpenPhysics repositories with metadata (displayName, lineage, upstream, framework, deployed URL, physics topics, status, etc.). Schema: structure/repos.schema.json (validated by scripts/check-repos-catalog.sh). The compliance workflow, Pages landing page, and the catalog scripts consume this file. Ground-truth upstream references for sims live in the sibling Baseline repo (also listed here as type: tool). See scripts/README.md for the tooling:

scripts/check-repos-catalog.sh
scripts/parse-repos.sh names --simulation
scripts/parse-repos.sh names --lineage phet
scripts/list-repos.sh --json
scripts/sync-github-metadata.sh --dry-run

Adding a new simulation (create from template, catalog, screenshot, WebP, Pages, OpenPhysics README): run scripts/create-sim.sh --onboard (add --pr to open PRs), then see doc/add-simulation.md for any remaining hand edits (.github profile tallies). The webpage is generated from repos.json + screenshots/ — there is no separate Markdown card list to edit.

Scripts assume the Baton repo lives beside member repos in a shared workspace; set OPENPHYSICS_WORKSPACE or pass --catalog /path/to/repos.json if your checkout differs.

Fleet operations

Cross-repo automation, all driven from the catalog:

  • Batch changesscripts/fleet-exec.sh clones each selected repo, runs a command, and (with --apply) opens one PR per repo. Dry-run by default. The fleet-exec.yml workflow exposes it as a manual dispatch (e.g. bump a shared dependency, run npm run fix, apply a codemod). Opening PRs in other repos needs a FLEET_PAT secret with write access — the default GITHUB_TOKEN is scoped to Baton only. Setup steps (fine-grained PAT or GitHub App): doc/fleet-auth.md.
  • Health reportfleet-health.yml runs weekly, fanning out one matrix job per active simulation (npm download cache reused across runs) to run lint, type-check, build, and test, then publishing a pass/fail table to the job summary. Read-only; surfaces sims broken by a shared-workflow or dependency change.
  • Compliance auditshared-compliance-check.yml audits README structure and CI wiring across the org. The dispatch/schedule run fans out one matrix job per sim and aggregates a single pass/fail table (see above).
  • Everyday git fan-outdoc/fleet-git.md is a cheat sheet for running git across your local checkouts (pull all, push all, status all), built on parse-repos.sh paths. Use it for ad-hoc local work; use fleet-exec.sh to land the same change as PRs.
  • Add a simulationscripts/create-sim.sh bootstraps from SceneryStackTemplate; doc/add-simulation.md covers catalog entry, screenshot capture, WebP thumbnails, and regenerating the Pages index.

Node version

The default Node version for the fleet is "24", declared in every Baton workflow that runs setup-node — bump them together:

scripts/check-node-version.sh enforces that they stay in sync (run in CI by baton-selfcheck.yml), so a half-done bump fails fast instead of drifting silently. When sibling member checkouts are present (local OpenPhysics workspace), it also asserts each package.json matches the same major.

Member repos must keep:

  • engines.node: >=24 (floor matching the workflow major)
  • @types/node: major 24 (Dependabot ignores @types/node major bumps — bump SceneryStackTemplate and repos together when CI node-version changes; see config/dependabot-npm.yml)

scripts/check-repo-compliance.sh fails a sim if those pins drift. Prefer no .nvmrc / .node-version; if present, the major must match the fleet.

About

coordinating and orchestrating multiple repositories

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages