119 lines
8.2 KiB
Python
119 lines
8.2 KiB
Python
"""Original-host evidence copy recipe. Does not launch saved helpers or applications."""
|
|
from pathlib import Path
|
|
import hashlib, json, subprocess, sys
|
|
|
|
if sys.flags.optimize:
|
|
raise SystemExit('Optimized Python forbidden')
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
WORK = ROOT / '.local/rse'
|
|
REL = Path('harness/experiments/rename-scroll-feab202-20260913')
|
|
OUT = WORK / REL
|
|
SOURCE = 'feab2020d8e5b6bfdb59c86ab4aee161617b8b6f'
|
|
BASE = '9e51cd72ba05d37482c5bc258e284804058a1475'
|
|
OLD = '3c22fe2629fc242714d32805790262fa2c4e33b9'
|
|
TRIAL = '.local/native-qa/rename-scroll-feab202-20260913-01'
|
|
GATES = '.local/rename-scroll-gates-20260913'
|
|
PREP = '.local/rename-scroll-gate-preparation-r3-20260913'
|
|
|
|
def require(value, message):
|
|
if not value:
|
|
raise ValueError(message)
|
|
|
|
def identity(data):
|
|
return {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
|
|
|
|
def read(path):
|
|
return json.loads(path.read_bytes())
|
|
|
|
def git(*args):
|
|
return subprocess.check_output(['git', '-c', 'core.longpaths=true', *args], cwd=WORK)
|
|
|
|
require(git('rev-parse', 'HEAD').decode().strip() == BASE, 'Wrong documentation base')
|
|
require(not git('status', '--porcelain'), 'Documentation worktree not clean')
|
|
require(not OUT.exists(), 'Refusing overwrite archive')
|
|
require(read(ROOT / TRIAL / 'closure.json')['exit'] == 0, 'Native process not closed')
|
|
selected = set()
|
|
for folder in [TRIAL, GATES, PREP, '.local/rename-scroll-gate-preparation-20260913']:
|
|
for p in (ROOT / folder).rglob('*'):
|
|
relative = p.relative_to(ROOT).as_posix()
|
|
if p.is_file() and not p.is_symlink():
|
|
if folder == TRIAL and any(part in ('profile', 'temp', 'working-directory', 'source-work') for part in p.relative_to(ROOT / TRIAL).parts):
|
|
continue
|
|
if p.suffix.lower() not in ('.exe', '.dll', '.pdb', '.rlib', '.rmeta'):
|
|
selected.add(relative)
|
|
|
|
for pattern in ['rename-scroll-native-*', 'navigation-preview*scroll*', 'rename-scroll-checkpoint-proof-feab202.json']:
|
|
selected.update(p.relative_to(ROOT).as_posix() for p in (ROOT / '.local').glob(pattern) if p.is_file())
|
|
selected.update([
|
|
'.local/rename-scroll-feab202-native-independent-review-20260913.md',
|
|
'.local/rename-scroll-feab202-native-independent-audit-20260913.json',
|
|
'.local/native-qa/rename-scroll-stage-feab202-20260913-01/manifest.json',
|
|
])
|
|
expected = read(ROOT / PREP / 'expected.json')
|
|
selected.update(expected['baseline_and_original_helper_pins'])
|
|
preparation = read(ROOT / TRIAL / 'preparation.json')
|
|
old_manifest = read(ROOT / 'harness/experiments/navigation-native-440-20260913/manifest.json')
|
|
old_by_original = {r['original']: r for r in old_manifest['files'] if 'original' in r}
|
|
references = []
|
|
omitted = []
|
|
for original, bound in preparation['records'].items():
|
|
original = original.replace('\\', '/')
|
|
require(identity((ROOT / original).read_bytes()) == bound, 'Original preparation mismatch: ' + original)
|
|
if Path(original).suffix.lower() in ('.exe', '.dll'):
|
|
omitted.append({'original': original, **bound, 'reason': 'Binary identity retained; executable/runtime omitted'})
|
|
elif original in old_by_original:
|
|
row = old_by_original[original]
|
|
data = git('show', OLD + ':' + row['path'])
|
|
require(identity(data) == bound and (WORK / row['path']).read_bytes() == data, 'Historical archive mismatch')
|
|
references.append({'path': row['path'], 'commit': OLD, 'original': original, **bound})
|
|
else:
|
|
selected.add(original)
|
|
selected.difference_update(r['original'] for r in references)
|
|
OUT.mkdir(parents=True)
|
|
rows = []
|
|
for original in sorted(selected):
|
|
source = ROOT / original
|
|
require(source.is_file() and not source.is_symlink(), 'Missing original ' + original)
|
|
data = source.read_bytes()
|
|
destination = REL / 'raw' / original.removeprefix('.local/')
|
|
target = WORK / destination
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
with target.open('xb') as stream:
|
|
stream.write(data)
|
|
require(source.read_bytes() == data == target.read_bytes(), 'Copy mismatch ' + original)
|
|
rows.append({'path': destination.as_posix(), 'original': original, **identity(data)})
|
|
|
|
# Record the three source seams without copying an unrelated production tree.
|
|
changes = git('diff', '--name-only', '44095f78c28b79d6d085863dc928adba8e24d955', SOURCE, '--', 'crates').decode().splitlines()
|
|
require(len(changes) == 3, 'Unexpected source delta')
|
|
for path in changes:
|
|
data = git('show', SOURCE + ':' + path)
|
|
target = OUT / 'source' / path
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_bytes(data)
|
|
rows.append({'path': target.relative_to(WORK).as_posix(), 'source_commit': SOURCE, 'source_path': path, **identity(data)})
|
|
for name, source in [('archive-builder.py', Path(__file__)), ('verify.py', ROOT / '.local/verify-rename-scroll-feab202.py')]:
|
|
data = source.read_bytes()
|
|
(OUT / name).write_bytes(data)
|
|
rows.append({'path': (REL / name).as_posix(), **identity(data)})
|
|
readme = '''# Closed feab Details/Preview evidence
|
|
|
|
Tested source **feab2020d8e5b6bfdb59c86ab4aee161617b8b6f**. This archive supports the narrow native Details/Preview restoration, explicit reset and Cancel/Save unchanged-byte workflow. It is not full rename, Text-union, package or optimized-release acceptance.
|
|
|
|
- [Independent review](raw/rename-scroll-feab202-native-independent-review-20260913.md) and [read-only audit](raw/rename-scroll-feab202-native-independent-audit-20260913.json).
|
|
- [Twenty original JPEGs and notes](raw/native-qa/rename-scroll-feab202-20260913-01/evidence), [closure](raw/native-qa/rename-scroll-feab202-20260913-01/closure.json), and [six-file checkpoint](raw/native-qa/rename-scroll-feab202-20260913-01/checkpoints/cancel-save/result.json).
|
|
- [Closed gates and GUI metadata](raw/rename-scroll-gates-20260913), including original bebf4/1 failure; [test correction review](raw/navigation-preview-scroll-test-correction-independent-review-20260913.md).
|
|
- [Pinned preparation](raw/rename-scroll-gate-preparation-r3-20260913) and [source seams](source/crates/oa-desktop/src).
|
|
- Original440 failure043-045 remains in [the immutable existing archive](../navigation-native-440-20260913/raw/trial/evidence) at commit3c22fe2629fc242714d32805790262fa2c4e33b9. The manifest references its exact original bytes.
|
|
|
|
From a checkout containing feab and3c22, run `python -B harness/experiments/rename-scroll-feab202-20260913/verify.py --git-ref HEAD`. Before commit, omit `--git-ref`; `--index` verifies staged archive blobs. The standard-library verifier checks membership/hashes, original references, source615/gate581 scope, actual closed outcomes and native checkpoint bindings. It executes only Git reads; no saved launcher, compiler or application runs. `archive-builder.py` is historical original-host provenance, not a portable launch instruction.
|
|
|
|
Original receipts retain absolute local paths and earlier UNRUN statements as history. Portable links are this README and the manifest original-path map. Executables/runtime/cache/profile/temp are omitted; their exact recorded identities remain in receipts and the independent audit. The final source-work tree was independently checked identical to the included baseline/checkpoint; it is omitted as redundant. The private Desktop picker warning, operator input/capture retries and frame003 stale title metadata remain disclosed in the review. No original failures or image bytes were rewritten.
|
|
'''
|
|
for name, data in [('README.md', readme.encode()), ('.gitattributes', b'* -text\n')]:
|
|
(OUT / name).write_bytes(data)
|
|
rows.append({'path': (REL / name).as_posix(), **identity(data)})
|
|
manifest = {'schema': 'rename-scroll-feab-evidence-v1', 'source': SOURCE, 'publication_base': BASE, 'files': rows, 'references': references, 'omitted': omitted + [{'original': TRIAL + '/source-work', 'reason': 'Six exact files duplicate included baseline and checkpoint; read-only audit records equality'}, {'original': 'GUI and test executables, private profile/temp/cwd', 'reason': 'No runnable package or personal runtime state included'}]}
|
|
(OUT / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\n', encoding='utf-8', newline='\n')
|
|
print(json.dumps({'archive': str(OUT), 'files': len(rows), 'references': len(references), 'manifest': identity((OUT / 'manifest.json').read_bytes())}))
|