Remaster twenty-nine original pictures with reproducible artwork tools

This commit is contained in:
raptorreplica committed 2026-10-18 21:59:49 +11:00
1 parent 6e4008c62f
commit 668b3ff86d
253 files changed
+670875 -79

No files matched your search

@@ -0,0 +1,327 @@
"""Private SHIP15G1 complete3 component registration; not artistic approval.
Genuine generated RGB is sampled only from the same phase/material. Literal
Source support supplies derived alpha; exactly29 declared logical cells supply
baked Original RGB. Parent PNG/Source files are never changed. This file is
prepared code only until Root releases an actual recipe execution.
"""
from __future__ import annotations
import argparse
from collections import deque
import hashlib
import io
import json
import math
from pathlib import Path
import platform
import numpy as np
from PIL import Image, __version__ as PILLOW_VERSION
METHOD = 'derived-generated-ship15-component-mast-pods-wake-source-support-v1'
DECODER_SHA = '66184a4758027dadbadb5e20fe90b2add2b9fc218b7810304b1a1ea2de74f58e'
CAPS = dict(metal_max_logical_distance=1.0, metal_max_missing_fraction=0.13,
wake_max_logical_distance=2.75, wake_max_missing_fraction=0.18)
AXES = {
'main_machinery_mast_hull': ([36, 39, 42, 53], [4, 7, 15, 18]),
'left_pod': ([21, 29], [7, 15]),
'right_pod': ([55, 63], [7, 15]),
'teal_wake': ([0, 21, 29, 36, 53, 55, 63, 72], [2, 4, 7, 15, 18, 20]),
}
def sha(data):
return hashlib.sha256(data).hexdigest()
def exact_keys(value, keys, label):
if type(value) is not dict or set(value) != set(keys):
raise ValueError(f'{label}: unknown/missing fields')
def checked(binding, base):
exact_keys(binding, {'path', 'sha256'}, 'input binding')
if type(binding['path']) is not str or not binding['path'] or type(binding['sha256']) is not str:
raise ValueError('input path/hash types')
path = Path(binding['path'])
if not path.is_absolute():
path = Path(base) / path
data = path.read_bytes()
if sha(data) != binding['sha256']:
raise ValueError(f'input hash mismatch: {path}')
return path.resolve(), data
def finite_number(v):
return type(v) in (int, float) and math.isfinite(v)
def validate_model(model, name, width, height):
exact_keys(model, {'source_x', 'raw_x', 'source_y', 'raw_y', 'donor_bounds'}, name)
expected_x, expected_y = AXES[name]
for key, expected in [('source_x', expected_x), ('source_y', expected_y)]:
if type(model[key]) is not list or model[key] != expected or any(type(v) is not int for v in model[key]):
raise ValueError(f'{name}: Source knots differ')
for source_key, raw_key, maximum in [('source_x', 'raw_x', width), ('source_y', 'raw_y', height)]:
values = model[raw_key]
if (type(values) is not list or len(values) != len(model[source_key]) or
any(not finite_number(v) for v in values) or
not all(0 <= v <= maximum for v in values) or
not all(b > a for a, b in zip(values, values[1:]))):
raise ValueError(f'{name}: nonfinite/nonmonotone/outside raw knots')
bounds = model['donor_bounds']
if (type(bounds) is not list or len(bounds) != 4 or any(type(v) is not int for v in bounds) or
not (0 <= bounds[0] < bounds[2] <= width and 0 <= bounds[1] < bounds[3] <= height)):
raise ValueError(f'{name}: invalid donor bounds')
if not (bounds[0] <= model['raw_x'][0] <= model['raw_x'][-1] <= bounds[2] and
bounds[1] <= model['raw_y'][0] <= model['raw_y'][-1] <= bounds[3]):
raise ValueError(f'{name}: knots escape same-component donor bounds')
def nearest_owners(trusted):
"""Raster seeds, N/W/E/S BFS; owners always refer to initial trusted pixels."""
if not trusted.any():
raise ValueError('no genuine parent donors for component/material')
h, w = trusted.shape
distance = np.full((h, w), np.iinfo(np.int32).max, np.int32)
owner_y = np.full((h, w), -1, np.int32)
owner_x = np.full((h, w), -1, np.int32)
seeds = np.argwhere(trusted)
todo = deque()
for y, x in seeds:
y, x = int(y), int(x)
distance[y, x] = 0
owner_y[y, x], owner_x[y, x] = y, x
todo.append((x, y))
while todo:
x, y = todo.popleft()
n = int(distance[y, x]) + 1
for nx, ny in ((x, y-1), (x-1, y), (x+1, y), (x, y+1)):
if 0 <= nx < w and 0 <= ny < h and distance[ny, nx] > n:
distance[ny, nx] = n
owner_y[ny, nx], owner_x[ny, nx] = owner_y[y, x], owner_x[y, x]
todo.append((nx, ny))
return distance, owner_y, owner_x
def sample_component(parent, source_mask, model, name, scale, caps):
"""Nearest genuine raw RGB at declared inverse-map coordinates, no gains."""
h, w = source_mask.shape
output_mask = np.repeat(np.repeat(source_mask, scale, axis=0), scale, axis=1)
yy, xx = np.nonzero(output_mask)
if len(xx) == 0:
raise ValueError(f'{name}: empty Source component')
u = np.interp((xx+0.5)/scale, model['source_x'], model['raw_x'])
v = np.interp((yy+0.5)/scale, model['source_y'], model['raw_y'])
px, py = np.floor(u).astype(int), np.floor(v).astype(int)
l, t, r, b = model['donor_bounds']
if np.any(px < l) or np.any(px >= r) or np.any(py < t) or np.any(py >= b):
raise ValueError(f'{name}: mapped sample outside donor bounds')
# Donor tests are performed on an untouched crop of this exact phase only.
patch = parent[t:b, l:r]
rgb = patch[:, :, :3].astype(np.int16)
trusted = patch[:, :, 3] >= 128
if name == 'teal_wake':
trusted &= (rgb[:, :, 1] > rgb[:, :, 0]+10) & (rgb[:, :, 2] > rgb[:, :, 0]+10)
kind = 'wake'
else:
trusted &= rgb.max(axis=2)-rgb.min(axis=2) <= 18
kind = 'metal'
distance, oy, ox = nearest_owners(trusted)
qx, qy = px-l, py-t
d = distance[qy, qx].astype(float)
direct = trusted[qy, qx]
minimum_raw_per_logical = min(
min(np.diff(model['raw_x'])/np.diff(model['source_x'])),
min(np.diff(model['raw_y'])/np.diff(model['source_y'])))
logical_distance = d/minimum_raw_per_logical
missing_fraction = float((~direct).mean())
if missing_fraction > caps[f'{kind}_max_missing_fraction'] + 1e-12:
raise ValueError(f'{name}: genuine donor missing fraction exceeds cap')
if float(logical_distance.max()) > caps[f'{kind}_max_logical_distance'] + 1e-12:
raise ValueError(f'{name}: genuine donor distance exceeds cap')
sy, sx = oy[qy, qx], ox[qy, qx]
if not np.all(trusted[sy, sx]):
raise AssertionError('owner is not an original genuine donor')
# No interpolated/new pixel can become a donor; all reads use the parent.
values = patch[sy, sx, :3].copy()
return output_mask, values, dict(component=name, Source_cells=int(source_mask.sum()),
output_samples=len(xx), direct_genuine_samples=int(direct.sum()),
nearest_parent_extension_samples=int((~direct).sum()),
missing_fraction=missing_fraction,
max_raw_Manhattan_distance=float(d.max()),
max_equivalent_logical_distance=float(logical_distance.max()),
same_phase_material_and_bounds=True, cascading_fill=False)
def validate_recipe(recipe):
exact_keys(recipe, {'format_version', 'label', 'decoder_module', 'palette', 'parent_raw',
'output_scale', 'caps', 'frames'}, 'recipe')
if type(recipe['format_version']) is not int or recipe['format_version'] != 1:
raise ValueError('recipe format version')
if type(recipe['label']) is not str or not recipe['label'].strip():
raise ValueError('recipe label')
if type(recipe['output_scale']) is not int or recipe['output_scale'] != 8:
raise ValueError('this complete3 recipe requires declared8x master')
exact_keys(recipe['caps'], CAPS, 'caps')
if any(not finite_number(recipe['caps'][k]) or recipe['caps'][k] != v for k, v in CAPS.items()):
raise ValueError('caps must equal reviewed proposed hard limits')
frames = recipe['frames']
if type(frames) is not list or len(frames) != 3:
raise ValueError('complete3 required')
for i, frame in enumerate(frames):
exact_keys(frame, {'asset', 'frame', 'source', 'logical_canvas', 'origin', 'raw_crop',
'components', 'functional_original_cells'}, 'frame')
if (frame['asset'] != f'{0x1030b+i:05x}' or type(frame['frame']) is not int or frame['frame'] != i or
frame['logical_canvas'] != [72, 24] or any(type(v) is not int for v in frame['logical_canvas']) or
frame['origin'] != [0, 0] or any(type(v) is not int for v in frame['origin'])):
raise ValueError('Source family/order/native/origin changed')
exact_keys(frame['components'], AXES, 'components')
return frames
def render_family(recipe, base):
frames = validate_recipe(recipe)
decoder_path, decoder_bytes = checked(recipe['decoder_module'], base)
if sha(decoder_bytes) != DECODER_SHA:
raise ValueError('unreviewed decoder module')
decoder_namespace = {'__name__': '_verified_ship15_decoder', '__file__': str(decoder_path)}
exec(compile(decoder_bytes, str(decoder_path), 'exec'), decoder_namespace)
decode = decoder_namespace['_indices']
palette_path, palette_bytes = checked(recipe['palette'], base)
if len(palette_bytes) != 768 or max(palette_bytes) > 63:
raise ValueError('literal256 six-bit palette required')
palette = np.frombuffer(palette_bytes, np.uint8).reshape(256, 3).astype(np.uint16)
palette = ((palette << 2) | (palette >> 4)).astype(np.uint8)
parent_path, parent_bytes = checked(recipe['parent_raw'], base)
if len(parent_bytes) > 32*1024*1024:
raise ValueError('parent exceeds32MiB')
with Image.open(io.BytesIO(parent_bytes)) as opened:
if (opened.format != 'PNG' or opened.width != opened.height or opened.height % 3 or
opened.width*opened.height > 4_194_304 or opened.width < 72):
raise ValueError('parent must be a bounded square three-full-strip PNG')
parent = np.array(opened.convert('RGBA'))
if parent[:, :, 3].min() != 0:
raise ValueError('parent must have genuine transparent alpha')
height, width = parent.shape[:2]
strip_height = height//3
sources, input_hashes = [], {str(parent_path): sha(parent_bytes), str(palette_path): sha(palette_bytes)}
for i, frame in enumerate(frames):
crop = frame['raw_crop']
if (type(crop) is not list or crop != [0, i*strip_height, width, strip_height] or
any(type(v) is not int for v in crop)):
raise ValueError('only three literal full strips permitted, no crop fit')
path, payload = checked(frame['source'], base)
sw, sh, indices = decode(payload)
if [sw, sh] != [72, 24]:
raise ValueError('Original canvas differs')
source = np.asarray(indices, np.uint16).reshape(sh, sw)
if not np.all((source < 32) | ((source >= 144) & (source <= 157)) | (source == 255) | (source == 256)):
raise ValueError('Source class outside exact declared family partition')
if np.any((source[:2] < 256)) or np.any((source[20:] < 256)):
raise ValueError('Source painted support outside declared full wake region')
if np.argwhere(source == 255).tolist() != [[10, 37], [11, 37]]:
raise ValueError('Source255 indicator changed')
for name, model in frame['components'].items():
validate_model(model, name, width, strip_height)
sources.append(source)
input_hashes[str(path)] = sha(payload)
gray = sources[0] < 32
if any(not np.array_equal(s < 32, gray) for s in sources[1:]):
raise ValueError('stationary Source gray footprint changed')
phase_cells = np.any(np.stack(sources) != sources[0], axis=0) & gray
if int(phase_cells.sum()) != 12:
raise ValueError('Source phase12 tone coordinates changed')
arrays, reports = [], []
yy, xx = np.indices((24, 72))
gray_regions = dict(main_machinery_mast_hull=(xx >= 36)&(xx < 53)&(yy >= 4)&(yy < 18),
left_pod=(xx >= 21)&(xx < 29)&(yy >= 7)&(yy < 15),
right_pod=(xx >= 55)&(xx < 63)&(yy >= 7)&(yy < 15))
gray_region_union = np.logical_or.reduce(list(gray_regions.values()))
if np.any(gray & ~gray_region_union):
raise ValueError('gray Source support outside three declared components')
for i, (frame, source) in enumerate(zip(frames, sources)):
occupied = source < 256
functional = (source == 31) | phase_cells | (source == 255)
expected = [[int(x), int(y)] for y, x in np.argwhere(functional)]
cells = frame['functional_original_cells']
if (type(cells) is not list or cells != expected or len(cells) != 29 or
any(type(cell) is not list or len(cell) != 2 or any(type(v) is not int for v in cell) for cell in cells)):
raise ValueError('exact row-major29 explicit Original cells required')
masks = {name: (source < 32)&region for name, region in gray_regions.items()}
masks['teal_wake'] = (source >= 144)&(source <= 157)
assigned = np.logical_or.reduce(list(masks.values())) | (source == 255)
if not np.array_equal(assigned, occupied):
raise ValueError('Source support partition mismatch')
rgba = np.zeros((192, 576, 4), np.uint8)
parent_phase = parent[i*strip_height:(i+1)*strip_height]
counts = []
for name, mask in masks.items():
outmask, values, record = sample_component(parent_phase, mask, frame['components'][name], name, 8, recipe['caps'])
rgba[:, :, :3][outmask] = values
counts.append(record)
alpha = np.repeat(np.repeat(occupied, 8, axis=0), 8, axis=1)
rgba[:, :, 3][alpha] = 255
before_functional = rgba.copy()
functional8 = np.repeat(np.repeat(functional, 8, axis=0), 8, axis=1)
source_rgb8 = np.repeat(np.repeat(palette[np.minimum(source, 255)], 8, axis=0), 8, axis=1)
rgba[:, :, :3][functional8] = source_rgb8[functional8]
if (not np.array_equal(rgba[:, :, 3] == 255, alpha) or np.any(rgba[~alpha]) or
not np.array_equal(rgba[:, :, :3][functional8], source_rgb8[functional8]) or
not np.array_equal(rgba[~functional8], before_functional[~functional8])):
raise AssertionError('Source alpha/functional/outside-original support invariant failed')
arrays.append(rgba)
reports.append(dict(asset=frame['asset'], frame=i, logical_canvas=[72, 24], origin=[0, 0],
component_donor_metrics=counts, Source_occupied_cells=int(occupied.sum()),
baked_Original_cells=cells, baked_Original_RGBA_pixels=29*64,
generated_detail_not_claimed_for_baked_Original=True,
alpha_contract='Literal SourceNN8 occupied support, not OriginalScaleNx alpha',
Source_alpha_and_outside_support_exact=True,
functional_Original_RGB_exact=True, outside_29_functional_RGBA_unchanged=True))
report = dict(method=METHOD, input_hashes=input_hashes, frames=reports,
decoder_module=dict(path=str(decoder_path), sha256=sha(decoder_bytes)),
python_version=platform.python_version(), python_implementation=platform.python_implementation(),
numpy_version=np.__version__, pillow_version=PILLOW_VERSION,
scope='Derived geometry/RGB registration only; no native QA or artistic approval',
generated_RGB_never_replaced_by_SourceRGB_outside_declared29=True,
parent_and_Source_unchanged=True, output_scale=8)
return arrays, report
def run_recipe(recipe_path, output):
recipe_path, output = Path(recipe_path), Path(output)
if output.exists() or output.is_symlink():
raise ValueError('output exists; never overwrite prior artwork')
data = recipe_path.read_bytes()
arrays, report = render_family(json.loads(data), recipe_path.resolve().parent)
files = []
for pixels, frame in zip(arrays, report['frames']):
buffer = io.BytesIO()
Image.fromarray(pixels).save(buffer, format='PNG', compress_level=9)
payload = buffer.getvalue()
name = frame['asset']+'-derived.png'
frame['output'] = dict(file=name, sha256=sha(payload), bytes=len(payload), RGBA_sha256=sha(pixels.tobytes()))
files.append((name, payload))
report['execution'] = dict(status='success', method=METHOD, recipe_sha256=sha(data),
tool_sha256=sha(Path(__file__).read_bytes()),
source_sha256={f['asset']: f['source']['sha256'] for f in json.loads(data)['frames']},
parent_raw_sha256=sorted({json.loads(data)['parent_raw']['sha256']}),
output_sha256={f['asset']: f['output']['sha256'] for f in report['frames']})
output.mkdir(parents=True, exist_ok=False)
for name, payload in files:
(output/name).write_bytes(payload)
(output/'derived-provenance.json').write_text(json.dumps(report, indent=2, sort_keys=True)+'\n')
return report
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('recipe', type=Path)
parser.add_argument('output_new_directory', type=Path)
args = parser.parse_args()
report = run_recipe(args.recipe, args.output_new_directory)
print(json.dumps(dict(execution=report['execution'])))
if __name__ == '__main__':
main()
@@ -0,0 +1,261 @@
"""Synthetic only: no actual SHIP15 image, Source or recipe is rendered."""
from pathlib import Path
import copy
import importlib.util
import json
import struct
import tempfile
import unittest
from unittest.mock import patch
import numpy as np
from PIL import Image
HERE=Path(__file__).resolve().parent
spec=importlib.util.spec_from_file_location('private_ship15', HERE/'ship15_component_cleanup.py')
tool=importlib.util.module_from_spec(spec)
spec.loader.exec_module(tool)
DECODER=HERE.parent.parent/'tools/hd_frame_policy.py'
TONE=[(38,7,7,6),(42,7,3,1),(43,7,4,3),(46,13,31,30),(47,13,30,28),(48,13,29,27),
(49,13,28,26),(50,13,29,27),(51,13,27,24),(42,14,27,25),(43,14,29,27),(44,14,27,25)]
def binding(p):
return dict(path=str(p),sha256=tool.sha(p.read_bytes()))
def encode_source(arr):
out=bytearray(struct.pack('<5i',0,2,18,72,24))
for y in range(24):
x=0
while x<72:
if arr[y,x]==256:
x+=1
continue
end=x+1
while end<72 and arr[y,end]<256:end+=1
out.extend(struct.pack('<4i',x,y,y*72+x,end-x))
out.extend(bytes(arr[y,x:end].tolist()))
x=end
out.extend(struct.pack('<4i',0,0,-1,0))
return bytes(out)
class SyntheticFamily(unittest.TestCase):
def setUp(self):
self.temp=tempfile.TemporaryDirectory()
self.root=Path(self.temp.name)
self.palette=np.zeros((256,3),np.uint8)
for i in range(32):self.palette[i]=63-2*i
self.palette[144:158]=[5,25,30]
self.palette[255]=[54,54,54]
pp=self.root/'PALETTE';pp.write_bytes(self.palette.tobytes())
base=np.full((24,72),256,np.uint16)
base[2:20]=144
base[7:15,36:53]=10
base[4:7,39:42]=10
base[15:18,39:42]=10
base[7:15,21:29]=10
base[7:15,55:63]=10
base[10:12,37]=255
tone_set={(x,y)for x,y,_,_ in TONE}
black=[]
for y,x in np.argwhere(base<32):
if (int(x),int(y))not in tone_set:
black.append((int(x),int(y)))
if len(black)==15:break
for x,y in black:base[y,x]=31
self.sources=[]
self.raw=np.zeros((144,144,4),np.uint8)
frames=[]
for i in range(3):
s=base.copy()
for x,y,v0,v1 in TONE:s[y,x]=v0 if i==0 else v1
self.sources.append(s)
p=self.root/f'SOURCE{i}';p.write_bytes(encode_source(s))
alpha=np.repeat(np.repeat(s<256,2,axis=0),2,axis=1)
gray=np.repeat(np.repeat(s<32,2,axis=0),2,axis=1)
yy,xx=np.indices(alpha.shape)
phase=np.zeros((48,144,4),np.uint8)
phase[:,:,:3][alpha]=np.stack([10+xx%5,90+yy%10,110+xx%10],axis=2)[alpha]
neutral=(60+xx%70+yy%11+i*7).astype(np.uint8)
for c in range(3):phase[:,:,c][gray]=neutral[gray]
phase[:,:,3][alpha]=255
self.raw[i*48:(i+1)*48]=phase
comps={}
for name,(sx,sy)in tool.AXES.items():
comps[name]=dict(source_x=sx,raw_x=[v*2 for v in sx],source_y=sy,raw_y=[v*2 for v in sy],
donor_bounds=[sx[0]*2,sy[0]*2,sx[-1]*2,sy[-1]*2])
frames.append(dict(asset=f'{0x1030b+i:05x}',frame=i,source=binding(p),logical_canvas=[72,24],origin=[0,0],
raw_crop=[0,i*48,144,48],components=comps,functional_original_cells=[]))
phases=np.any(np.stack(self.sources)!=self.sources[0],axis=0)&(self.sources[0]<32)
for f,s in zip(frames,self.sources):
f['functional_original_cells']=[[int(x),int(y)]for y,x in np.argwhere((s==31)|phases|(s==255))]
self.assertEqual(len(f['functional_original_cells']),29)
self.parent=self.root/'parent.png'
Image.fromarray(self.raw).save(self.parent)
self.recipe=dict(format_version=1,label='SYNTHETIC ONLY',decoder_module=binding(DECODER),palette=binding(pp),
parent_raw=binding(self.parent),output_scale=8,caps=copy.deepcopy(tool.CAPS),frames=frames)
def tearDown(self):
self.temp.cleanup()
def save_parent(self):
Image.fromarray(self.raw).save(self.parent)
self.recipe['parent_raw']=binding(self.parent)
def save_source(self,i):
p=self.root/f'SOURCE{i}';p.write_bytes(encode_source(self.sources[i]));self.recipe['frames'][i]['source']=binding(p)
def assert_fails_without_output(self,recipe,pattern):
rp=self.root/'bad-recipe.json';rp.write_text(json.dumps(recipe))
out=self.root/'MUST-NOT-EXIST'
with self.assertRaisesRegex((ValueError,AssertionError),pattern):tool.run_recipe(rp,out)
self.assertFalse(out.exists())
def test_identity_preserves_genuine_RGB_alpha_and29_Original_only(self):
arrays,report=tool.render_family(self.recipe,self.root)
pal=((self.palette.astype(np.uint16)<<2)|(self.palette.astype(np.uint16)>>4)).astype(np.uint8)
for i,(s,out)in enumerate(zip(self.sources,arrays)):
alpha=np.repeat(np.repeat(s<256,8,axis=0),8,axis=1)
self.assertTrue(np.array_equal(out[:,:,3]==255,alpha))
self.assertFalse(out[~alpha].any())
yy,xx=np.indices(alpha.shape);expected=self.raw[i*48+(yy//4),xx//4,:3]
f=np.zeros((24,72),bool)
for x,y in self.recipe['frames'][i]['functional_original_cells']:f[y,x]=True
fm=np.repeat(np.repeat(f,8,axis=0),8,axis=1)
srgb=np.repeat(np.repeat(pal[np.minimum(s,255)],8,axis=0),8,axis=1)
self.assertTrue(np.array_equal(out[:,:,:3][alpha&~fm],expected[alpha&~fm]))
self.assertTrue(np.array_equal(out[:,:,:3][fm],srgb[fm]))
self.assertEqual(sum(m['nearest_parent_extension_samples']for m in report['frames'][i]['component_donor_metrics']),0)
self.assertFalse(np.array_equal(arrays[0],arrays[1]))
def test_nonuniform_left_pod_transform_keeps_own_genuine_donor(self):
for i in range(3):
ph=self.raw[i*48:(i+1)*48]
original=ph[14:30,42:58].copy()
ph[14:30,42:60,:3]=[10,95,115]
ph[14:30,42:60,3]=255
ph[14:30,44:60]=original
m=self.recipe['frames'][i]['components']['left_pod']
m['raw_x']=[44,60];m['donor_bounds']=[44,14,60,30]
self.save_parent()
arrays,_=tool.render_family(self.recipe,self.root)
# An ordinary non-functional bottom-right pod point reads translated raw.
x,y=28*8+2,14*8+2
self.assertNotIn([28,14],self.recipe['frames'][0]['functional_original_cells'])
self.assertEqual(arrays[0][y,x,:3].tolist(),self.raw[28,58,:3].tolist())
self.assertEqual(int(arrays[0][y,x,3]),255)
def test_malformed_knots_and_relaxed_caps_fail_before_output(self):
mutations=[('raw_x',[72,78,78,106]),('raw_y',[8,float('nan'),30,36]),('source_x',[36,39,42,54]),
('raw_x',[True,78,84,106]),('donor_bounds',[73,8,106,36])]
for key,value in mutations:
with self.subTest(key=key,value=value):
r=copy.deepcopy(self.recipe);r['frames'][0]['components']['main_machinery_mast_hull'][key]=value
self.assert_fails_without_output(r,'knots|bounds')
r=copy.deepcopy(self.recipe);r['caps']['metal_max_logical_distance']=2
self.assert_fails_without_output(r,'caps')
r=copy.deepcopy(self.recipe);r['caps']['metal_max_logical_distance']=True
self.assert_fails_without_output(r,'caps')
def test_missing_alpha_no_donor_and_wrong_material_fail(self):
original=self.raw.copy()
self.raw[14:30,42:58,3]=0;self.save_parent()
self.assert_fails_without_output(self.recipe,'no genuine')
self.raw=original.copy();self.raw[14:30,42:58,:3]=[0,130,150];self.save_parent()
self.assert_fails_without_output(self.recipe,'no genuine')
self.raw=original.copy();self.raw[:,:,3]=255;self.save_parent()
self.assert_fails_without_output(self.recipe,'transparent alpha')
def test_donor_fraction_and_distance_are_separate_hard_stops(self):
original=self.raw.copy()
self.raw[14:30,42:46,3]=0;self.save_parent()
self.assert_fails_without_output(self.recipe,'missing fraction')
self.raw=original.copy();self.raw[18:24,86:92,3]=0;self.save_parent()
self.assert_fails_without_output(self.recipe,'distance exceeds')
def test_Original_selectors_and_Source_support_are_fail_closed(self):
for value in [self.recipe['frames'][0]['functional_original_cells'][:-1],
self.recipe['frames'][0]['functional_original_cells']+[self.recipe['frames'][0]['functional_original_cells'][0]]]:
r=copy.deepcopy(self.recipe);r['frames'][0]['functional_original_cells']=value
self.assert_fails_without_output(r,'Original cells')
original=self.sources[0].copy()
self.sources[0][1,20]=144;self.save_source(0)
self.assert_fails_without_output(self.recipe,'support outside')
self.sources[0]=original.copy();self.sources[0][10,37]=10;self.save_source(0)
self.assert_fails_without_output(self.recipe,'indicator changed')
self.sources[0]=original.copy();self.sources[0][5,5]=10;self.save_source(0)
self.assert_fails_without_output(self.recipe,'footprint changed|support outside')
self.sources[0]=original.copy();self.sources[0][5,5]=100;self.save_source(0)
self.assert_fails_without_output(self.recipe,'class outside')
def test_source_tone12_family_order_and_full_crop_not_optional(self):
r=copy.deepcopy(self.recipe);r['frames'][0]['frame']=False
self.assert_fails_without_output(r,'order')
r=copy.deepcopy(self.recipe);r['frames'][1]['raw_crop']=[0,49,144,47]
self.assert_fails_without_output(r,'full strips')
for i in (1,2):
self.sources[i]=self.sources[0].copy();self.save_source(i)
self.assert_fails_without_output(self.recipe,'phase12')
def test_hash_check_precedes_any_output_and_preserves_parent(self):
before={p:tool.sha(p.read_bytes())for p in self.root.iterdir()if p.is_file()}
r=copy.deepcopy(self.recipe);r['parent_raw']['sha256']='0'*64
self.assert_fails_without_output(r,'hash mismatch')
for p,sha in before.items():self.assertEqual(tool.sha(p.read_bytes()),sha)
def test_nearest_ties_are_raster_seeded_and_never_cascade(self):
trust=np.zeros((5,5),bool);trust[0,0]=True;trust[4,4]=True
distance,oy,ox=tool.nearest_owners(trust)
self.assertTrue(np.all(trust[oy,ox]))
self.assertEqual((int(oy[2,2]),int(ox[2,2])),(0,0))
self.assertEqual(int(distance[2,2]),4)
for y in range(5):
for x in range(5):self.assertEqual(int(distance[y,x]),min(x+y,8-x-y))
def test_verified_decoder_bytes_execute_after_temporary_path_replacement(self):
# Only a temporary decoder copy is replaced; no shared input is changed.
decoder_copy=self.root/'copied_decoder.py'
verified_bytes=DECODER.read_bytes()
decoder_copy.write_bytes(verified_bytes)
self.recipe['decoder_module']=binding(decoder_copy)
expected,_=tool.render_family(self.recipe,self.root)
checked_original=tool.checked
replaced=[]
malicious=b"raise RuntimeError('UNVERIFIED_TEMP_DECODER_MUST_NOT_EXECUTE')\n"
def verify_then_replace(binding_value,base):
path,data=checked_original(binding_value,base)
if path==decoder_copy.resolve():
self.assertEqual(data,verified_bytes)
self.assertEqual(tool.sha(data),tool.DECODER_SHA)
path.write_bytes(malicious)
replaced.append(path)
return path,data
with patch.object(tool,'checked',side_effect=verify_then_replace):
actual,report=tool.render_family(self.recipe,self.root)
self.assertEqual(replaced,[decoder_copy.resolve()])
self.assertEqual(decoder_copy.read_bytes(),malicious)
self.assertEqual(report['decoder_module']['sha256'],tool.DECODER_SHA)
for before,after in zip(expected,actual):
self.assertTrue(np.array_equal(before,after))
self.assertFalse(any(p.name.endswith('-derived.png')for p in self.root.iterdir()))
def test_deterministic_recipe_receipts_and_new_output_only(self):
rp=self.root/'recipe.json';rp.write_text(json.dumps(self.recipe,sort_keys=True))
before={p:tool.sha(p.read_bytes())for p in self.root.iterdir()if p.is_file()}
first=tool.run_recipe(rp,self.root/'first')
second=tool.run_recipe(rp,self.root/'second')
self.assertEqual(first,second)
self.assertEqual(set(first['execution']),{'status','method','recipe_sha256','tool_sha256','source_sha256','parent_raw_sha256','output_sha256'})
self.assertEqual(first['decoder_module']['sha256'],tool.DECODER_SHA)
self.assertIn('numpy_version',first)
for name in ['1030b-derived.png','1030c-derived.png','1030d-derived.png','derived-provenance.json']:
self.assertEqual((self.root/'first'/name).read_bytes(),(self.root/'second'/name).read_bytes())
with self.assertRaisesRegex(ValueError,'output exists'):tool.run_recipe(rp,self.root/'first')
for p,sha in before.items():self.assertEqual(tool.sha(p.read_bytes()),sha)
if __name__=='__main__':unittest.main()