Feature: make the pinned arcade reference the authority every build and review checks against - #112
Conversation
|
This pull request touches more than one kind of engine file. Here is what the next update does with each — none of it blocks your merge: Heads-up: this pull request changes engine files the next engine update is set to overwrite. The engine keeps its own machinery current by replacing these files wholesale when you update — so a change you make to them here won't survive the next update; it will quietly revert:
If that was a one-off, this is just so you know. If you want the change to last, the durable home for an edit to engine machinery is upstream in the engine project these files come from ( These engine-internal files are regenerated by the update. The engine rebuilds them from your project's own current state on each update. A change here that reflects a real change in your project — you edited what the file is generated from and regenerated it — is reproduced, not lost. But content typed directly into one of these files, with no matching change to the source it comes from, will not survive: it is rebuilt away on the next update. So if you meant to change what one of these records, edit the source it is generated from (for the settled-criteria record, your
This is a heads-up only — it does not block your merge, and your merge is the decision. |
…ty (claim) Claim commit for issue #111. Opens the draft pull request; no changes yet. The work lands as an ordered commit series behind this claim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add tools/reference_checkout.py: ensure/path/verify a throwaway local clone of jotd666/xevious at the pinned commit, so a build session or CI can open the cited source lines and re-derive the spec data. Hash verification reuses reference_extract.SourceFile (one implementation), and the clone lives in a shared cache outside the repo by default so many worktrees reuse it. Tests run fully offline: a fake five-file checkout with reference_extract EXPECTED_SHA256 patched to the fakes' digests (shared module object, plain import so the patch reaches SourceFile), a real git repo in tempfile for the at-pin no-op and wrong-commit-offline paths, each with a committer identity set inline so CI with no global git identity still passes. .gitignore: ignore an in-repo /.xevious-reference/ when --dir points inside the tree (default is outside); placed in the un-fenced project region. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add tools/reference_citations.py: read every citation in docs/spec and docs/mechanics and check it points at a real label and line range at the pin. A citation resolves when the file is one of the five pinned sources, the label exists, and the range starts at or sits inside that label's block (block extent computed from the label index, never bytes_under_label, which collapses on a code routine). File tokens accept the bare or src/ spelling and are sticky within a parenthetical group; a document declares its default file once. Labelled citations are recognised regardless of surrounding parentheses so a correct citation outside parens is never silently skipped. Mechanics records are scanned only on their reference-provenance line, binding ranges to backticked labels so coordinate bounds and supplementary prose numbers are not mistaken for citations. Fixture tests only (the resolver is not run against the real corpus until the audit lands): one positive per citation shape, one negative per hard failure, against a fake five-file checkout with EXPECTED_SHA256 patched to its digests. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Correct the citations the resolver cannot resolve at the pinned commit — locators only, no gameplay-meaning change: - Nonexistent labels -> their real names at the pin: sub_2_fn_8/_22 gain their __fire_freq_mask_* suffixes (difficulty-and-formations.md, mechanics 022), sub_2_fn_3 gains __inc_enemy_AI_and_flying_enemies (mechanics 020). - Missing file in scope -> declared: player-craft-and-weapons.md and difficulty-and-formations.md each declare their default source file (main and sub respectively); core-game-systems.md and andor-genesis.md gain an explicit file token on the one citation that leaves the surrounding default. - Approximate reference -> exact: area-progression-and-terrain.md's `~514` becomes `main_gameplay_loop` 514-521 (the area-advance / 16->7 loop). Add tests/test_reference_corpus.py: three network-free guards (every reference provenance line names the index pin; every spec citation has a file in scope; no approximate line reference survives), which run in the ordinary test job. The settled-criteria matrix is unchanged (edits fall outside acceptance-criteria cells, verified by regenerating it). Deferred, deliberately: the bare-range -> labelled-citation conversions, which cluster in the draft enemy docs that PR #110 and the upcoming settling slices rewrite; they land there under the new fidelity review rather than conflicting with in-flight work. Touches four settled specs (player-craft-and-weapons, difficulty-and-formations, core-game-systems, area-progression-and-terrain) -> needs guardrail-ack. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…4/6) tools/playtest_package.py: the one command a build session runs to produce the playtest .sb3. It ensures a verified checkout, re-derives the generated data, resolves every citation, and only then builds — refusing to emit a build while any citation is unresolved, so a build that adapted to a wrong spec cannot reach the playtest (the slice-8 gap). The guarded builder is invoked unmodified as a subprocess. Tests stub each step and assert the gate: a failing check stops the build; the build runs only after all checks pass. .github/workflows/reference-fidelity.yml: an advisory workflow (not in the required ruleset) that clones at the pin, re-verifies, and resolves citations on every pull request — a backstop, not the in-session fix, and loud if upstream is unreachable. .engine/operator-guarded-paths.json: guard the pin-deciding files (reference_extract.py, reference_checkout.py) and the new workflow; the maturing resolver and handover tool stay ungated while they settle. Docs: docs/spec/index.md replaces the manual /tmp clone recipe with the tool, drops "run by a person, not CI", and states the citation grammar; docs/mechanics /README.md requires labelled line ranges; docs/principles.md records that citation resolution is engine-checked while prose fidelity is the review's judgment; README.md adds the reference and handover commands; docs/REFERENCE_ POLICY.md reconciles "nothing depends on it" — the reference must now be obtainable at the pin for the fidelity tooling to ground a change (guarded file -> guardrail-ack). Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… 5/6) Add two project-owned review personas sharing the reference-fidelity lens: reference-fidelity-plan (plan gate) and reference-fidelity (pre-submission gate). They are the only reviewers that read the arcade source itself: they obtain a verified checkout, resolve the change's citations, and open the cited source lines to check the spec prose, the derived-behaviour, and the Scratch evidence against what the source does — the source wins, and a "could not ground" is a blocking finding, never a pass. The plan-gate persona additionally requires that any alleged spec divergence be checked against the source before the plan adopts it, the step missing when the Toroid swing was "fixed" to match wrong prose. Wire reference-fidelity into the plan-review and pre-submission lines of the consumed-review-lenses block so lens-consumption stays green, and commit the Codex renders (codex_gen) and the regenerated knowledge graph. Both personas are judgment/opus/high per the model bindings. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…#111, 6/6) .engine/conduct/operator.md: add the standing code conduct-reference-outranks-spec — before accepting a factual claim about the game's behaviour (from the spec, a review finding, or memory), open the cited source lines and read them; where the reference and the spec disagree the reference wins and the spec is corrected, never the build changed to match wrong prose. Worded as grounding posture only — it leaves the review gates and approval untouched (no weakening). CLAUDE.md and AGENTS.md: append an "Arcade reference fidelity" section after the engine-managed fence (preserved across engine updates) so both runtimes load the rule every session — the pin, the checkout and resolver commands, and that a playtest build is produced only through tools/playtest_package.py while every citation resolves. Closes #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…#111) Resolver (tools/reference_citations.py): - Scan the file+range (no-label) citation shape the docstring promised but the scanner never emitted, so citations like `xevious.inc 61-81` and `xevious_ram.68k 161-218` are now checked instead of silently invisible (4 real citations; the resolver total rises from 98 to 102, still 0 unresolved). - Cap a citation range at 256 lines (widest real citation is ~74) so an over-wide range that merely contains the label is rejected rather than accepted as precise. - Resolve --paths to absolute so a relative argument no longer crashes on relative_to(ROOT). Corpus guard (tests/test_reference_corpus.py): strengthen the approximate-line guard to catch a bare `~NNN` anywhere, not only next to a label token, while leaving durations (`~56 frames`, `~12.4 s`) alone. This catches the second `~514` in docs/mechanics/015-area-clock.md, now made exact (514). Checkout (tools/reference_checkout.py): wrap the git init/remote/checkout steps in clone_at_pin so a dirty cache surfaces a clean CheckoutError instead of a raw traceback; add a clone_at_pin test that clones from a local file:// origin and one that forces a prepare failure. New fixture tests cover the file+range shape and the over-wide rejection. Part of #111. Addresses technical-integrity and divergence-hunter findings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…code (issue #111) Two required engine self-tests hardcode the shipped defaults and fail when a deployment uses a documented customization: test_operator_override_ships_empty asserts operator.md carries no conduct codes, and test_lens_consumption asserts an exact nine consumed review lenses. This project adds both a conduct code and the reference-fidelity review persona (both documented as supported), so the tests are relaxed minimally — the conduct file must be well-formed rather than empty, and the stock lenses must be a subset of the consumed set rather than an exact match. These are engine-owned, overlay-overwritten files, so the edits are wiped on each engine update and must be re-applied then. The operator confirmed an engine-fault issue filed in this repo will not reach the engine home, so this is a recurring per-update chore, recorded on issue #113 and in the test comments. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…issue #111) docs/PLAYTEST_CHECKLIST.md: the "before you start" build step now uses tools/playtest_package.py, so the operator's own canonical procedure runs the reference checks before producing the .sb3 instead of pointing straight at the raw builder — closing the contradiction with the CLAUDE.md rule that a playtest build goes only through the handover tool. .github/workflows/reference-fidelity.yml: pin actions/checkout and actions/setup-python to commit SHAs (matching the engine's stricter convention) instead of mutable @v7 tags. Part of #111. Addresses divergence-hunter, product-intent, and security-governance findings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e (issue #111) The engine self-test relaxations reference the upstream bug where it can be fixed (StarshipSuperjam/engine-template#1200) rather than the local record. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…refine guard (issue #111) Rebasing onto main (slice 8, PR #110) surfaced two things the fidelity tooling now covers: - docs/mechanics/023-aiming-and-slot-positions.md cited `cpy_dY_dX_to_obj` by its routine address ($3383) where the convention is a line number; the resolver flagged it. Corrected to the line (5135) so it resolves — the gate catching a real citation slip in freshly-merged work. - The approximate-line guard mis-flagged value suffixes new in slice 8 records (`~128 half-px`, `~40%`). Refined: flag a bare `~NNN` only when it is not followed by a unit word or `%`, so a genuine `~line)` reference is still caught while counts, distances, and percentages are left alone. Resolver: 107 citations checked, 0 unresolved. Full suite (229 tests) green. Part of #111. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3cd1547 to
35be6ed
Compare
Closes #111
Purpose
Make the pinned arcade source the authority every build and review checks the port against, instead of the
docs/spec/prose.Impact: a citation that no longer points where it claims cannot pass unnoticed, and a reviewer reads the arcade source itself before a build is handed over for playtest.
Scope
Tools, a citation audit, a fidelity-gated handover, a CI backstop, two review personas, and a conduct rule — no gameplay code.
tools/reference_checkout.py— a verified throwaway clone ofjotd666/xeviousat the pin, so any session or CI can open the cited source (ensure/path/verify; offline once cached).tools/reference_citations.py— resolves every citation indocs/spec/anddocs/mechanics/to a real label and line range at the pin (102 citations, 0 unresolved).tools/playtest_package.py— the handover gate: it runs the reference checks and refuses to build a playtest.sb3while any citation is unresolved..github/workflows/reference-fidelity.yml— an advisory CI backstop.reference-fidelityreview personas at the plan and pre-submission gates, and aconduct-reference-outranks-speccode, plus an always-loaded section inCLAUDE.md/AGENTS.md.Change profile — the shape of this pull request at a glance:
Impact: the reference becomes the authority mechanically (resolver + handover gate + CI) and by routed judgment (the personas), and every session loads the rule.
Behaviors
The falsifiable capabilities this change delivers, each with the test that exercises it:
tests/test_reference_checkout.py.~NNN, an over-wide range, or a missing file fails —tests/test_reference_citations.py,tests/test_reference_corpus.py.tests/test_playtest_package.py.Out of scope
Deliberately excluded, with reasons.
update_solvalou_sprite_XY,find_idle_and_init_radiating_bullet, and others resolve today); the genuine remainder either maps awkwardly to a single label ("the four angle tables span 6290–6427") or exceeds the span cap. Forcing labels would reduce accuracy, so they stay as prose.aerial-enemies.mdToroid swing prose made explicit ("reverses away", not homing). That draft doc is being rewritten by in-flight PR Feature: Toroid vertical slice — first live flying enemy (slice 8) #110; the clarification belongs there.Impact: the settled-doc edits are held to the genuinely-broken citations, keeping the guardrail-ack surface tight.
Risk
No engine guardrail is weakened; the friction is deliberate consent, and two engine self-tests are hand-edited.
guardrail-ack. This edits four settled specs (core-game-systems,player-craft-and-weapons,difficulty-and-formations,area-progression-and-terrain) and the guardeddocs/REFERENCE_POLICY.md. All are locator-only or a disclosed posture change; none change gameplay meaning. Applyguardrail-ackto clear the product-lock and guarded-path checks.docs/REFERENCE_POLICY.mdposture change, called out distinctly. The policy said "nothing here depends on [the reference clone]." After this, the fidelity tooling depends on the reference being obtainable at the pin (not on a stored copy). Yourguardrail-ackcovers this as a deliberate change, not a typo fix.test_conductandtest_lens_consumptionhardcode the shipped defaults and fail when a project uses a documented feature (a conduct code, a project review persona). They are relaxed minimally. These files are overwritten on each engine update, so the edits must be re-applied then. Filed as Engine fault: required self-tests block documented per-deployment customization (project conduct code and review persona) #113; you noted such an issue won't reach the engine home, so this is a recurring per-update chore.reference-fidelitycheck red but does not block merge. Recorded here as the deliberate choice it is.reference-fidelityline inbuild-orchestration.mdis overwritten on update; the hardlens-consumptioncheck then goes red with a self-describing fix. A recurring one-line chore.Impact: every friction here is a consent gate you clear or a disclosed recurring cost, not a silent weakening.
Validation
Full local suites green; the new CI job passes; two checks stay red pending your
guardrail-ack.python tools/scratch_project.py verifyandreference_extract.py --verifypass;reference_citations.pyreports 102 checked, 0 unresolved against a real clone at the pin;actionlintclean.reference-fidelity,xevious-project,runtime-harness,secret-scan,CodeQL,actionlint, andengine-overlay-disclosureare green.engine-ciandengine-guardstay red until you applyguardrail-ack(the settled-doc / guarded-policy gate).Impact: an approver can rely on the mechanical checks; the two red ones are your consent step, not defects.
Review
A thorough cold review ran at Standard depth: four plan-review passes before building and five pre-submission passes after, plus a blind reference-fidelity replay. Real findings were fixed; two blocking findings were corrected.
bytes_under_label), bare file-token normalization and paren-group scoping, a CI-safe git identity in tests, and the matrix-regen check were all adopted from these passes..inccitation would pass. Now scanned (98 → 102 citations), with a fixture test.~514survived and its guard no-oped (both fixed); unguarded git steps raised raw tracebacks (now cleanCheckoutError); the playtest checklist routed around the handover gate (now through it); CI actions pinned to SHAs.reference_citations.pyandplaytest_package.pyunguarded is your explicit choice (guard the pin-deciding files only); the citation audit fixes are genuine, verified against the source.86f4bef; four fix commits followed (b6ad1d8,41bb604,75ea249, and this body). Net change since the reviewed version: about +190 / −40 lines across the resolver, checkout tool, tests, two engine self-tests, and three docs — a material post-review delta, re-verified by the full suite and a fresh resolver run (102/0).Impact: the engine's own account of the review — your merge is the binding gate.
Demonstration
The slice-8 replay: the reference-fidelity persona, blind to the answer, reads the source and judges the prose.
docs/spec/aerial-enemies.mdlines 41–44 with a checkout present. It openssrc/xevious_main.68ktoroid_toggle_dir3289–3321 and the two swing arms, determines from the source alone that the swing reverses away from the craft (the two arms adjust_dYby ∓1, locked at the trigger), and reports whether the prose is faithful. In this PR's run it correctly found the swing is a reversal and the current wording faithful — the exact read that was missing when slice 8 trusted the prose.python3 tools/reference_citations.py --checkout "$(python3 tools/reference_checkout.py path)"prints102 citations checked, 0 unresolved; break any cited label or range and it prints that citation as unresolved and exits non-zero.Impact: you can watch the gate read the source and catch a wrong citation, rather than trust the prose.
Files of interest
The core is three tools and the resolver logic.
tools/reference_citations.py— the resolver (grammar, scoping, resolution rule).tools/reference_checkout.py,tools/playtest_package.py— the checkout and the handover gate..claude/agents/reference-fidelity*.md— the review personas.docs/spec/*.mdanddocs/mechanics/{020,022,015}.Impact: these most determine whether the reference stays the authority.
AI involvement
Built with Claude Code (Opus 4.8).
Impact: the resolver logic and the citation audit are where AI judgment is load-bearing; the source verification bounds it.
🤖 Generated with Claude Code