From 67d50279df1a49d2bcd6847459d0f61c9066cfa7 Mon Sep 17 00:00:00 2001 From: EHotwagner Date: Wed, 14 Oct 2026 12:33:59 +0200 Subject: [PATCH] build: prepare only the authenticated empty HighBar gitlink slot --- containers/barc-stock-headless/README.md | 2 +- containers/barc-stock-headless/build-image.py | 19 +++++++++++++++++ containers/barc-stock-headless/test_source.py | 21 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/containers/barc-stock-headless/README.md b/containers/barc-stock-headless/README.md index 0adcd8a..bd6b1f4 100644 --- a/containers/barc-stock-headless/README.md +++ b/containers/barc-stock-headless/README.md @@ -19,7 +19,7 @@ This source preparation has not built or run an image. Image creation and native The old `hydrate-bar-assets.sh` downloads an unhashed moving byar-chobby.sdz. This recipe uses the owned exact Rapid game selection instead. The selected downloader comes from the hash-verified official engine archive. Its pinned source09a1f37c… confirms filesystem-writepath, rapid-download, validate-sdp and rapid-validate. The exact .sdp is authenticated by SHA256; its complete pool is acquired and validated by the upstream downloader. SDP record count/declared expanded size and actual downloaded population are bounded. Rapid pool validation is its existing MD5/CRC contract, not a stronger signed content provenance claim. -The existing HighBar build script generates the plugin with HIGHBAR_STOCK_RECOIL=ON and three compiled source controls. Generated protobuf/gRPC C++ uses the qualified local protoc/plugin, avoiding moving remote Buf plugins. The complete official engine payload and game graph are retained. No engine/game startup or useful-play proof runs during image creation. Exact-header compilation and source controls do not establish actual loaded ABI compatibility or gameplay. +Before fetching accepted HighBar, the recipe verifies the tracked Recoil BARb slot is an unmodified gitlink and removes only Git’s empty checkout placeholder. Links or any existing content refuse replacement. The existing HighBar build script generates the plugin with HIGHBAR_STOCK_RECOIL=ON and three compiled source controls. Generated protobuf/gRPC C++ uses the qualified local protoc/plugin, avoiding moving remote Buf plugins. The complete official engine payload and game graph are retained. No engine/game startup or useful-play proof runs during image creation. Exact-header compilation and source controls do not establish actual loaded ABI compatibility or gameplay. ## Repository-owned toolchain bootstrap diff --git a/containers/barc-stock-headless/build-image.py b/containers/barc-stock-headless/build-image.py index 8dbedbe..e963daf 100644 --- a/containers/barc-stock-headless/build-image.py +++ b/containers/barc-stock-headless/build-image.py @@ -69,6 +69,24 @@ def source(row, target, seconds): actual = subprocess.check_output(['git', '-C', str(target), 'rev-parse', expression], text=True).strip() require(actual == expected, 'fetched source identity differs') +def prepare_highbar_slot(recoil, highbar): + relative = 'AI/Skirmish/BARb' + require(highbar == recoil / relative, 'HighBar source slot differs') + row = subprocess.check_output(['git','-C',str(recoil),'ls-files','--stage','--',relative], text=True).strip().split('\t') + require(len(row) == 2 and row[1] == relative, 'HighBar slot is not one tracked gitlink') + fields = row[0].split() + require(len(fields) == 3 and fields[0] == '160000' and fields[2] == '0' and bool(COMMIT.fullmatch(fields[1])), 'HighBar slot gitlink metadata differs') + tracked = subprocess.check_output(['git','-C',str(recoil),'ls-tree','HEAD','--',relative], text=True).strip().split('\t') + require(len(tracked) == 2 and tracked[1] == relative and tracked[0].split() == ['160000','commit',fields[1]], 'HighBar gitlink index differs from authenticated HEAD') + require(not highbar.is_symlink(), 'HighBar slot is linked') + if highbar.exists(): + require(highbar.is_dir(), 'HighBar slot is not a directory') + with os.scandir(highbar) as entries: + require(next(entries, None) is None, 'HighBar slot is populated; refusing replacement') + # Git checkout materializes an empty gitlink directory. Removing only + # that placeholder keeps the tracked Recoil tree and foreign data intact. + highbar.rmdir() + def check_listing(records, max_files, max_bytes): seen = set(); total = 0 for record in records: @@ -212,6 +230,7 @@ def build(pins): path = line.split(maxsplit=1)[1] if path != 'AI/Skirmish/BARb': run(['git', '-C', str(recoil), 'submodule', 'update', '--init', '--recursive', '--', path], budget['gitFetchSeconds']) + prepare_highbar_slot(recoil, highbar) source(pins['sources']['highbar'], highbar, budget['gitFetchSeconds']) source(pins['sources']['fsbar'], fsbar, budget['gitFetchSeconds']) require(sha(highbar / 'contracts/barc-stock-queue-v1/contract.json', 1024 * 1024) == pins['stockContractSha256'], 'stock ABI/wire contract differs') diff --git a/containers/barc-stock-headless/test_source.py b/containers/barc-stock-headless/test_source.py index 6210742..b4edd29 100644 --- a/containers/barc-stock-headless/test_source.py +++ b/containers/barc-stock-headless/test_source.py @@ -6,6 +6,7 @@ import json import pathlib import struct +import subprocess import tempfile import unittest @@ -32,6 +33,26 @@ def test_wrong_game_selection_is_refused(self): def test_nonfinite_deadline_is_refused(self): changed = copy.deepcopy(pins); changed['budgets']['downloadSeconds'] = 0 with self.assertRaises(ValueError): module.check_inputs(changed) + def test_real_gitlink_placeholder_and_nonempty_refusal(self): + with tempfile.TemporaryDirectory() as directory: + root = pathlib.Path(directory); repo = root / 'parent'; checkout = root / 'checkout' + subprocess.run(['git','init','-q',str(repo)], check=True) + subprocess.run(['git','-C',str(repo),'config','user.name','fixture'], check=True) + subprocess.run(['git','-C',str(repo),'config','user.email','fixture@example.invalid'], check=True) + subprocess.run(['git','-C',str(repo),'update-index','--add','--cacheinfo', + '160000,1111111111111111111111111111111111111111,AI/Skirmish/BARb'], check=True) + subprocess.run(['git','-C',str(repo),'commit','-qm','fixture'], check=True) + subprocess.run(['git','clone','--quiet','--no-hardlinks',str(repo),str(checkout)], check=True) + slot = checkout / 'AI/Skirmish/BARb' + self.assertTrue(slot.is_dir()) + module.prepare_highbar_slot(checkout, slot) + self.assertFalse(slot.exists()) + slot.mkdir(); payload = slot / 'existing'; payload.write_bytes(b'preserve') + with self.assertRaisesRegex(ValueError, 'populated'): module.prepare_highbar_slot(checkout, slot) + self.assertEqual(payload.read_bytes(), b'preserve') + payload.unlink(); slot.rmdir(); slot.symlink_to(repo, target_is_directory=True) + with self.assertRaisesRegex(ValueError, 'linked'): module.prepare_highbar_slot(checkout, slot) + with self.assertRaisesRegex(ValueError, 'slot differs'): module.prepare_highbar_slot(checkout, repo) def test_archive_paths_links_population_and_size(self): module.check_listing([{'Path':'spring-headless','Size':'5'}], 2, 10) for rows in ([{'Path':'../escape','Size':'5'}], [{'Path':'/escape','Size':'5'}],