From 5f90486cf04d3b8fcda2b25db1a3e857ad773832 Mon Sep 17 00:00:00 2001 From: chrg6 Date: Fri, 13 Nov 2026 17:25:12 -0500 Subject: [PATCH] Mark the generated modules.c with GENERATED_MARKER, so that check_content.py refuses it in a commit. make_game.py modules_c writes gen/modules.c with the sha256 of the player's ExeFS modules and the install's absolute paths, and wrote it with no comment at all, so check_content.py, which refuses a file by its marker, its suffix, its name or a key line, would have let it into a commit. AGENTS.md wants the marker on every file the generator emits. Its first line now carries the marker and says what wrote it. It costs players one compile of modules.c and a link at their next build: make_game.py is part of the compile key, and every other object comes from the object cache. The other half of the finding, the marker on the lift's layout.h, waits: it is a change to recomp/layout.py and recomp/gen.py, whose digest keys every player's lift (a full lift at the update) and the execution profile's fit, so it belongs to the next release that changes recomp/ anyway. Not reproduced before the change: found by reading the code; the audit's probe showed modules_c without the marker. Checks that passed: tests/launcher_test.py (217 tests; the modules.c test now asserts the marker on its first line and that check_content.problems_for refuses the file, and fails before the change), tests/host_probes_test.py, tests/pgo_build_test.py and tools/check_content.py --staged. Co-Authored-By: Claude Opus 5.5 --- tests/launcher_test.py | 3 +++ tools/make_game.py | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/launcher_test.py b/tests/launcher_test.py index 907d75b2..7695910f 100644 --- a/tests/launcher_test.py +++ b/tests/launcher_test.py @@ -3116,6 +3116,9 @@ class MakeGameTest(Tmp): (out / 'exefs' / name).write_bytes(b'x') (lift / 'layout.json').write_text(json.dumps([{'name': 'main'}])) text = self.mg.modules_c(lift, out, gen).read_text(encoding='utf-8') + import check_content + self.assertIn(check_content.GENERATED_MARKER, text.splitlines()[0]) + self.assertIn('generated from game code', check_content.problems_for(gen / 'modules.c')) # refused in a commit for half in ('\\ud83e', '\\ud842'): # the first surrogate halves of the two characters self.assertNotIn(half, text.lower()) want = 'const char rt_default_exefs[] = "' + str(out / 'exefs').replace('\\', '\\\\') + '";' diff --git a/tools/make_game.py b/tools/make_game.py index 1f79a317..21e77255 100644 --- a/tools/make_game.py +++ b/tools/make_game.py @@ -98,6 +98,7 @@ sys.path.insert(0, str(KIT / 'tools')) import nup # noqa: E402 import mod_files # noqa: E402 import prompt_art # noqa: E402 +from check_content import GENERATED_MARKER # noqa: E402 TITLE_ID = 0x0400486024DEC000 MAIN_BUILD_ID = 'e0f3ccfaf50065ae4ea01eb5aeb13b1a' # main of game 1.1.1 @@ -642,8 +643,12 @@ def c_string(text): def modules_c(lift, out, gen): + """gen/modules.c: the lifted modules' table, the ExeFS's sha256 and this install's folders. It carries + GENERATED_MARKER, which tools/check_content.py refuses in a commit: it is derived from the game and names the + player's paths.""" layout = json.loads((lift / 'layout.json').read_text(encoding='utf-8')) - L = ['#include "dispatch.h"', '#include "host.h"', '#include "layout.h"', ''] + L = [f'/* {GENERATED_MARKER}: module table, written by tools/make_game.py modules_c. Do not edit or commit. */', + '#include "dispatch.h"', '#include "host.h"', '#include "layout.h"', ''] for m in layout: n = m['name'] L += [f'extern const uint64_t {n}_fn_addrs[];', f'extern const GuestFn {n}_fn_ptrs[];',