--- type: reference --- # Crosscheck Part of **Project Yukart**, making an old 2008 Mitsubishi Z27AG a bit smarter with modern technologies. Mechanical consistency checks across every yukart repository. A fact stated in more than one repo (a decision's status, a topic, a service list, a path in another repo's docs) is checked against the one place that owns it. No model, no network: plain Python over the tracked files. | Check | Source of truth | Catches | |---|---|---| | `decision` | project-yukart `docs/ARCHITECTURE.md`, decisions table | a decision number that does not exist; a line calling an Accepted decision proposed | | `topic` | contracts `schema/topics.json`, `schema/signals.json` | a `yukart/...` topic matching no pattern; a vehicle, host or gnss signal that is not registered, or has the wrong source | | `docref` | the repos' own trees | `` `FILE.md` `` naming a file that does not exist; relative markdown links that do not resolve | | `binaries` | each repo's `Cargo.toml` and `deploy/*.service` | project-yukart `REPOS.md` missing a deployed binary; `ORIN-RUNTIME.md` missing a deployed service | | `frontmatter` | the docs convention | a `docs/**/*.md` without front matter, or with an unknown `type` | | `copy` | contracts | a file under `assets/contracts/` that is not byte-identical to contracts' `` (or has no source there) | ## Run it ```bash python3 crosscheck.py ~/dev/yukart # the directory holding the repos side by side ``` Findings print as `repo/path:line: [check] message`; exit status 1 if any. ## In CI: every repo, on every push `.gitea/workflows/crosscheck.yml` is a reusable workflow. Each yukart repo carries [`caller/crosscheck.yml`](caller/crosscheck.yml) as its own `.gitea/workflows/crosscheck.yml`. On a push it clones every repo of the org at `master`, puts the pushed repo at the pushed commit, and runs the script. A finding fails that push's run: the commit that made two repos disagree is the one marked. A new repo is checked as soon as it exists in the org; it needs the caller only to trigger checks on its own pushes. - ⚠ **The caller must say `runs-on: halogen`** (the yukart org's runner, `halogen-yukart`). Gitea hands a reusable-workflow call to a runner chosen by the *caller's* `runs-on`; the called workflow's own is not consulted for that. Without it, the instance-wide `pi5-runner` on the Gitea host takes the job, and its jobs see the server as `http://gitea:3000`, which does not resolve. - All yukart repos are public, so cloning needs no token. A private one would need a read-only org secret `YUKART_READ_TOKEN`, which the workflow already uses if set. ## Adding to it - **A false positive** is fixed in the rule, not silenced per line. Shapes that look like topics but are not (Flutter channel names, systemd directories) are listed in `NOT_TOPIC`; test-only topic roots in `IGNORED_TOPIC_ROOTS`. - **A new check** reads a source of truth that already exists in some repo. If the fact has no single owner yet, give it one first; a check between two copies only says that they differ, not which is right.