Files
tool-crosscheck/README.md
T
2026-10-13 11:12:43 +09:00

3.1 KiB

type
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 or host signal that is not registered, or has the wrong source
docref the repos' own trees <repo> `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/<path> that is not byte-identical to contracts' <path> (or has no source there)

Run it

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 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.