474 lines
27 KiB
Python
474 lines
27 KiB
Python
"""Data-only mixed CLI reconciliation; run only after parent freezes all gates.
|
|
|
|
Usage: python -I -B inspect_runtime.py REVIEWED_FINAL_SOURCE_SHA
|
|
Runs only read-only Git commands, never Cargo, archived helpers or executables.
|
|
"""
|
|
from pathlib import Path
|
|
import ast
|
|
import hashlib
|
|
import io
|
|
import json
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import zipfile
|
|
|
|
assert not sys.flags.optimize
|
|
assert len(sys.argv) == 2
|
|
source = sys.argv[1]
|
|
assert re.fullmatch(r'[0-9a-f]{40}', source)
|
|
base = Path(__file__).resolve().parents[2]
|
|
root = base / '.local/as3batch'
|
|
folder = base / '.local/analysis-mixed-cli-gates-20260925'
|
|
destination = Path(__file__).with_name('MIXED-CLI-RUNTIME-READBACK.json')
|
|
assert not destination.exists(), 'Preserve prior readback; no overwrite'
|
|
sha = lambda b: hashlib.sha256(b).hexdigest()
|
|
INITIAL_GATE_TEMPLATE = '512dcc82ecb57fa60104d7332ea1cb9798ce1f4919cac6a4e2568d674f3abf1a'
|
|
GATE_TEMPLATE = '0349a19e62b9c57231e6ef3abad30643f39d7ed2fa4ac1fcab4b314159a39d52'
|
|
INITIAL_SOURCE = 'f2324822936374c5b9092518b986375233dc7882'
|
|
ALARM = 'harness/experiments/textual-authoring-20260911/alarm-response.arcadia'
|
|
CLI_HASH = 'a8ae7e9c4cb15a87720e364772c3239eef1fe6f4753b1f74b1f9e5482c7bcdad'
|
|
ARCHIVE_HASH = '1c20b7bffdaee9b1139b0e922d4366f6ac739f8567040e8f4723dc19e3974656'
|
|
BASELINE = 'bab6f96a5b05b37f2b5d67a430aed0f67d783e73'
|
|
MIXED_CLI_HASH = '78b612d631175032c7a7819105e03262e21630a1139be62ae78bbe9b5d387a7b'
|
|
DOC_PREFIX = (r'crates\oa-core\src\language\analysis_source\mixed\project.rs - '
|
|
'language::analysis_source::mixed::project::')
|
|
DOC_POSITIVE = DOC_PREFIX + 'check_mixed_bundle (line 87)'
|
|
DOC_MAPPING = {
|
|
DOC_PREFIX + 'CheckedMixed (line 36) - compile fail': DOC_PREFIX + 'CheckedMixed (line 36)',
|
|
DOC_PREFIX + 'CheckedMixed (line 50) - compile fail': DOC_PREFIX + 'CheckedMixed (line 50)',
|
|
}
|
|
NEW_CORE = {
|
|
'language::analysis_source::mixed::discovery::tests::mixed_discovery_accumulates_work_and_reservations_after_unit_drop',
|
|
'language::analysis_source::mixed::discovery::tests::mixed_discovery_cumulative_entry_boundary_and_terminal_original_failure',
|
|
'language::analysis_source::mixed::discovery::tests::mixed_discovery_numeric_and_reference_work_is_not_restarted_per_unit',
|
|
}
|
|
NEW_FILES = {
|
|
'mixed_files_complete_model_nested_ordinary_scoped_cross_file_and_original_bytes',
|
|
'mixed_files_terminal_syntax_preserves_first_path_and_still_reports_journal',
|
|
'mixed_files_identity_classes_and_malformed_units_are_discovery_errors',
|
|
'mixed_files_include_failures_and_cycles_do_not_become_partial_admission',
|
|
'mixed_files_limits_encoding_nonregular_and_physical_aliases',
|
|
}
|
|
NEW_CLI = {
|
|
'mixed_cli_complete_oa_sa_models_reports_and_unchanged_bytes',
|
|
'mixed_cli_missing_id_classes_and_schema_are_exact_refusals',
|
|
'mixed_cli_final_semantic_refusal_keeps_original_cross_file_coordinates',
|
|
'mixed_cli_disk_discovery_and_cycle_refusals_preserve_every_entry',
|
|
'mixed_cli_usage_and_human_output_never_suggest_an_edit_candidate',
|
|
'mixed_cli_direct_disk_error_uses_existing_operation_error_envelope',
|
|
}
|
|
EXTERNAL = {
|
|
'public_mixed_read_complete_oa_sa_models_and_all_located_warnings',
|
|
'public_mixed_read_scoped_uuid_reuse_and_cross_file_call_are_not_global_collisions',
|
|
'public_mixed_read_explicit_identity_classes_versions_and_long_forms',
|
|
'public_mixed_read_exact_input_file_edge_and_depth_boundaries',
|
|
'public_mixed_read_paths_missing_cycles_and_detached_files_are_errors',
|
|
'public_mixed_read_final_nested_model_limit_is_distinct_from_syntax_entries',
|
|
'public_mixed_read_typed_reference_caller_allowance_has_a_real_positive_control',
|
|
'public_mixed_read_malformed_duplicate_and_wrong_domain_references',
|
|
'public_mixed_read_unicode_columns_are_not_utf8_byte_columns',
|
|
'public_mixed_read_ordinary_parity_uses_an_independent_complete_model',
|
|
}
|
|
SCOPE = ['Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo', 'build', 'crates',
|
|
'assets', 'docs', 'examples', 'harness/fixtures', 'vendor']
|
|
|
|
|
|
def git(*args, data=None):
|
|
return subprocess.check_output(['git', '--no-replace-objects', *args], cwd=root, input=data)
|
|
|
|
|
|
def within(parent, name):
|
|
p = (parent / name).resolve()
|
|
assert p.is_relative_to(parent.resolve()), name
|
|
return p
|
|
|
|
|
|
def rows(raw):
|
|
result = re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)\r?$', raw.decode('utf8'), re.M)
|
|
assert len(result) == len(dict(result)), 'Duplicate runtime name'
|
|
return result
|
|
|
|
|
|
def names(raw):
|
|
result = re.findall(r'^([^\r\n]+): test\r?$', raw.decode('utf8'), re.M)
|
|
assert len(result) == len(set(result)), 'Duplicate listed name'
|
|
return result
|
|
|
|
|
|
def all_passed(raw, count, grouped=False):
|
|
actual = rows(raw)
|
|
assert len(actual) == count and all(status == 'ok' for _, status in actual)
|
|
summaries = re.findall(r'^test result: ok\. (\d+) passed; 0 failed; 0 ignored; 0 measured; (\d+) filtered out;', raw.decode('utf8'), re.M)
|
|
assert summaries and sum(int(x[0]) for x in summaries) == count
|
|
if not grouped:
|
|
assert len(summaries) == 1
|
|
return {name for name, _ in actual}
|
|
|
|
|
|
archive_raw = (base / 'harness/experiments/analysis-public-read-20260925/evidence.zip').read_bytes()
|
|
assert sha(archive_raw) == ARCHIVE_HASH
|
|
archive = zipfile.ZipFile(io.BytesIO(archive_raw))
|
|
assert archive.testzip() is None
|
|
|
|
|
|
def prior(stem):
|
|
r = archive.read('gates/' + stem + '.result.json')
|
|
d = json.loads(r)
|
|
log = archive.read('gates/' + stem + '.log')
|
|
assert sha(log) == d['log_sha256']
|
|
assert rows(log) == [tuple(x) for x in d['outcomes']]
|
|
return d, log
|
|
|
|
|
|
old, old_log = prior('public-read-full-bab6f96-1')
|
|
old_names = all_passed(old_log, 299)
|
|
old_listing, old_list_log = prior('public-read-list-bab6f96-1')
|
|
assert set(names(old_list_log)) == old_names
|
|
old_fmt, old_fmt_log = prior('public-read-fmt-bab6f96-1')
|
|
assert old_fmt['exit'] == 1 and sha(old_fmt_log) == 'c1c6b12861c8117ce6ffc6d6742ebf92618aafb10160ec6f99d370ca72ebab2d'
|
|
environment = dict(old['environment'])
|
|
environment.update(RUSTDOC=None, RUSTDOCFLAGS=None, CARGO_ENCODED_RUSTDOCFLAGS=None)
|
|
assert environment['CARGO_BUILD_JOBS'] == '1' and environment['CARGO_INCREMENTAL'] == '0'
|
|
for key in ['RUSTFLAGS', 'RUSTC', 'RUSTUP_TOOLCHAIN', 'ARCADIA_CODEC_LIFECYCLE_PHASE',
|
|
'RUST_MIN_STACK', 'RUSTDOC', 'RUSTDOCFLAGS', 'CARGO_ENCODED_RUSTDOCFLAGS']:
|
|
assert environment[key] is None
|
|
assert git('rev-parse', 'HEAD').decode().strip() == source
|
|
assert not git('status', '--porcelain', '--untracked-files=all').strip()
|
|
input_cache = {}
|
|
|
|
|
|
def inputs_at(commit, legacy=False):
|
|
key = (commit, legacy)
|
|
if key in input_cache:
|
|
return input_cache[key]
|
|
scope = SCOPE if legacy else SCOPE + [ALARM]
|
|
paths = git('ls-tree', '-r', '--name-only', commit, *scope).decode().splitlines()
|
|
data = git('cat-file', '--batch', data=''.join(f'{commit}:{p}\n' for p in paths).encode())
|
|
stream = io.BytesIO(data)
|
|
result = []
|
|
for path in paths:
|
|
header = stream.readline().split()
|
|
assert header[1] == b'blob'
|
|
raw = stream.read(int(header[2]))
|
|
assert stream.read(1) == b'\n'
|
|
if commit == source:
|
|
assert within(root, path).read_bytes() == raw, path
|
|
result.append({'path': path, 'bytes': len(raw), 'sha256': sha(raw)})
|
|
assert stream.read() == b''
|
|
input_cache[key] = result
|
|
return result
|
|
|
|
|
|
expected_inputs = inputs_at(source)
|
|
assert len(expected_inputs) == 567
|
|
verified = {}
|
|
|
|
|
|
def read_gate(stem, *, current=True):
|
|
receipt_raw = (folder / (stem + '.result.json')).read_bytes()
|
|
d = json.loads(receipt_raw)
|
|
raw = (folder / (stem + '.log')).read_bytes()
|
|
assert sha(raw) == d['log_sha256']
|
|
assert d['source'] == d['head_after']
|
|
assert d['cwd'] == str(root) and d['invocation'] == 'cargo'
|
|
assert d['environment'] == environment
|
|
assert not d['changed_inputs'] and d['source_status_after'] == ''
|
|
manifest = within(folder, d['inputs']).read_bytes()
|
|
assert sha(manifest) == d['inputs_sha256']
|
|
legacy_recipe = d['source'] == INITIAL_SOURCE
|
|
declared = inputs_at(d['source'], legacy_recipe)
|
|
assert len(declared) == (566 if legacy_recipe else 567)
|
|
assert json.loads(manifest) == {'source': d['source'], 'inputs': declared}
|
|
launcher = within(folder, d['launcher_copy']).read_bytes()
|
|
assert sha(launcher) == d['launcher_sha256'] == d['launcher_sha256_after']
|
|
assert launcher.count(d['source'].encode()) == 1
|
|
assert sha(launcher.replace(d['source'].encode(), b'PENDING_REVIEWED_MIXED_CLI_SOURCE')) == (INITIAL_GATE_TEMPLATE if legacy_recipe else GATE_TEMPLATE)
|
|
assert rows(raw) == [tuple(x) for x in d['outcomes']]
|
|
listing = names(raw) if d['mode'] in ('list', 'integration-list', 'doc-list') else []
|
|
assert listing == d['listing_members'] and len(listing) == d['listing_count']
|
|
if current:
|
|
assert d['source'] == source
|
|
assert not d['verification_failures']
|
|
for artifact in d['artifacts']:
|
|
path = Path(artifact['path'])
|
|
assert path.resolve().is_relative_to(Path(environment['CARGO_TARGET_DIR']).resolve())
|
|
binary = path.read_bytes()
|
|
assert len(binary) == artifact['bytes'] and sha(binary) == artifact['sha256']
|
|
verified[stem] = {'source': d['source'], 'exit': d['exit'], 'receipt_sha256': sha(receipt_raw),
|
|
'log_sha256': sha(raw), 'inputs_sha256': sha(manifest),
|
|
'launcher_sha256': sha(launcher), 'outcomes': d['outcomes'],
|
|
'listing': listing, 'artifacts': d['artifacts'],
|
|
'verification_failures': d['verification_failures']}
|
|
return d, raw
|
|
|
|
|
|
def current_gate(mode, command, target=None, selected_filter='', artifact_count=1):
|
|
stem = 'mixed-cli-' + mode + ('-' + target if target else '') + '-' + source[:7] + '-1'
|
|
d, raw = read_gate(stem)
|
|
assert d['mode'] == mode and d['command'] == command
|
|
assert d['test_target'] == target and d['filter'] == selected_filter
|
|
assert d['test_package'] == ('oa-cli' if target in ('mixed_cli', 'source_cli') else 'oa-core' if target else None)
|
|
assert d['exit'] == (1 if mode == 'fmt' else 0)
|
|
assert len(d['artifacts']) == artifact_count
|
|
if artifact_count and mode != 'cli-build':
|
|
running = re.findall(r'Running [^\r\n]+ \(([^\r\n]+\.exe)\)', raw.decode())
|
|
assert len(running) == artifact_count
|
|
assert [(root / n).resolve() for n in running] == [Path(a['path']).resolve() for a in d['artifacts']]
|
|
return d, raw
|
|
|
|
|
|
prefix = ['cargo', 'test', '--locked', '--offline', '-p', 'oa-core', '--lib']
|
|
listing, listing_log = current_gate('list', prefix + ['--', '--list'])
|
|
focused, focused_log = current_gate('focused', prefix + ['mixed_discovery', '--', '--test-threads=1'], selected_filter='mixed_discovery')
|
|
full, full_log = current_gate('full', prefix + ['--', '--test-threads=1'])
|
|
assert all_passed(full_log, 302) == old_names | NEW_CORE
|
|
assert set(listing['listing_members']) == old_names | NEW_CORE
|
|
assert all_passed(focused_log, 3) == NEW_CORE
|
|
assert listing['artifacts'] == focused['artifacts'] == full['artifacts']
|
|
clippy, _ = current_gate('clippy', ['cargo', 'clippy', '--locked', '--offline', '-p', 'oa-core', '-p', 'oa-cli', '--all-targets', '--', '-D', 'warnings'], artifact_count=0)
|
|
fmt, fmt_log = current_gate('fmt', ['cargo', 'fmt', '--all', '--', '--check'], artifact_count=0)
|
|
assert fmt_log == old_fmt_log
|
|
|
|
suites = {'mixed_source_files': '', 'mixed_cli': '', 'source_cli': '', 'mixed_source8_read': '', 'source_project': '', 'source_identity_updates': '',
|
|
'source_nested_updates': '', 'source_files': '', 'r3_migration': '',
|
|
'review_regressions': 'checked_save_',
|
|
'source7_contract': 'source7_source_bundle_migration_is_token_only_and_new_link_stays_with_caller'}
|
|
integration = {}
|
|
for target, selected_filter in suites.items():
|
|
pair = {}
|
|
for mode in ('integration-list', 'integration-suite'):
|
|
package = 'oa-cli' if target in ('mixed_cli', 'source_cli') else 'oa-core'
|
|
command = ['cargo', 'test', '--locked', '--offline', '-p', package, '--test', target]
|
|
if selected_filter:
|
|
command.append(selected_filter)
|
|
command += ['--', '--list' if mode == 'integration-list' else '--test-threads=1']
|
|
if target == 'source7_contract':
|
|
command.append('--exact')
|
|
pair[mode] = current_gate(mode, command, target, selected_filter)
|
|
l, s = pair['integration-list'][0], pair['integration-suite'][0]
|
|
assert l['artifacts'] == s['artifacts']
|
|
assert Path(s['artifacts'][0]['path']).name.startswith(target + '-')
|
|
if target == 'mixed_source8_read':
|
|
expected = EXTERNAL
|
|
elif target == 'mixed_source_files':
|
|
expected = NEW_FILES
|
|
elif target == 'mixed_cli':
|
|
expected = NEW_CLI
|
|
elif target == 'source_cli':
|
|
# Baseline source inventory only: no prior execution is claimed here.
|
|
baseline_cli_source = git('show', BASELINE + ':crates/oa-cli/tests/source_cli.rs').decode('utf8')
|
|
expected = set(re.findall(r'^fn ([a-z_]+)\(', baseline_cli_source, re.M))
|
|
assert len(expected) == 12
|
|
else:
|
|
previous, previous_log = prior(f'public-read-integration-suite-{target}-bab6f96-1')
|
|
expected = all_passed(previous_log, len(previous['outcomes']))
|
|
assert set(l['listing_members']) == expected
|
|
assert all_passed(pair['integration-suite'][1], len(expected)) == expected
|
|
integration[target] = sorted(expected)
|
|
assert sum(len(v) for k, v in integration.items() if k not in ('mixed_source8_read', 'mixed_source_files', 'mixed_cli', 'source_cli')) == 65
|
|
assert 'deep_structural_writeback_runs_on_a_small_thread_stack' in integration['source_nested_updates']
|
|
|
|
doc_prefix = ['cargo', 'test', '--locked', '--offline', '-p', 'oa-core', '--doc']
|
|
doc_list, _ = current_gate('doc-list', doc_prefix + ['--', '--list'], artifact_count=0)
|
|
doc_suite, doc_log = current_gate('doc-suite', doc_prefix + ['--', '--test-threads=1'], artifact_count=0)
|
|
doc_names = set(doc_list['listing_members'])
|
|
assert doc_names == {DOC_POSITIVE, *DOC_MAPPING.values()}
|
|
doc_runtime_names = all_passed(doc_log, 3, grouped=True)
|
|
assert doc_runtime_names == {DOC_POSITIVE, *DOC_MAPPING}
|
|
assert {DOC_MAPPING.get(n, n) for n in doc_runtime_names} == doc_names
|
|
assert re.findall(r'^test result: ok\. (\d+) passed; 0 failed; 0 ignored; 0 measured; (\d+) filtered out;', doc_log.decode('utf8'), re.M) == [('1', '0'), ('2', '0')]
|
|
assert not doc_suite['verification_failures']
|
|
assert doc_suite['doc_name_mapping'] == DOC_MAPPING
|
|
public_docs = {n for n in doc_names if 'CheckedMixed' in n or 'check_mixed_bundle' in n}
|
|
assert len(public_docs) == 3, public_docs
|
|
|
|
build, build_log = current_gate('cli-build', ['cargo', 'build', '--locked', '--offline', '-p', 'oa-cli', '--bin', 'arcadia', '--message-format=json'])
|
|
emitted = []
|
|
for line in build_log.splitlines():
|
|
try:
|
|
row = json.loads(line)
|
|
except (json.JSONDecodeError, UnicodeDecodeError):
|
|
continue
|
|
if row.get('reason') == 'compiler-artifact' and row.get('target', {}).get('name') == 'arcadia' and row.get('executable'):
|
|
assert row['target']['kind'] == ['bin'] and not row['profile']['test']
|
|
emitted.append(row['executable'])
|
|
assert len(emitted) == 1 and Path(emitted[0]).resolve() == Path(build['artifacts'][0]['path']).resolve()
|
|
original = {name: archive.read('gates/cli-fixture-bab6f96/' + name).decode('utf8')
|
|
for name in ['project.arcadia', 'participants.arcadia', 'children.arcadia']}
|
|
after = {'participants.arcadia': original['participants.arcadia'].replace('oa_entity team ', 'oa_entity rescue_team '),
|
|
'children.arcadia': original['children.arcadia'].replace('parent @team;', 'parent @rescue_team;')}
|
|
inventory = {name: {'bytes': len(text.encode('utf8')), 'sha256': sha(text.encode('utf8'))} for name, text in original.items()}
|
|
fixture = folder / ('cli-fixture-' + source[:7])
|
|
assert sorted(p.relative_to(fixture).as_posix() for p in fixture.rglob('*')) == sorted(original)
|
|
for name, text in original.items():
|
|
assert (fixture / name).read_bytes() == text.encode('utf8')
|
|
for operation in ('check', 'rename-alias'):
|
|
stem = f'mixed-cli-ordinary-{operation}-{source[:7]}-1'
|
|
receipt_raw = (folder / (stem + '.cli.json')).read_bytes()
|
|
d = json.loads(receipt_raw)
|
|
stdout = (folder / (stem + '.stdout.json')).read_bytes()
|
|
stderr = (folder / (stem + '.stderr.txt')).read_bytes()
|
|
assert d['source'] == source and d['build_artifact'] == build['artifacts'][0]
|
|
assert d['cwd'] == str(root) and d['environment'] == environment
|
|
assert d['inputs'] == build['inputs'] and d['inputs_sha256'] == build['inputs_sha256']
|
|
assert not d['changed_inputs'] and not d['verification_failures'] and d['exit'] == 0
|
|
assert d['stdout_sha256'] == sha(stdout) and d['stderr_sha256'] == sha(stderr) and stderr == b''
|
|
assert d['expected_input_inventory'] == d['after_inventory'] == inventory
|
|
launcher = within(folder, d['launcher_copy']).read_bytes()
|
|
assert sha(launcher) == d['launcher_sha256'] == CLI_HASH
|
|
entry = str(fixture / 'project.arcadia')
|
|
argv = [build['artifacts'][0]['path'], operation, entry]
|
|
if operation == 'rename-alias':
|
|
argv += ['team', 'rescue_team']
|
|
assert d['argv'] == argv + ['--json']
|
|
report = json.loads(stdout)
|
|
for key, value in {'format_version': 1, 'entry': entry, 'operation': operation,
|
|
'status': 'checked' if operation == 'check' else 'preview',
|
|
'exit_code': 0, 'written': False, 'diagnostics': [],
|
|
'identities_to_stabilize': 0, 'migration': None}.items():
|
|
assert report[key] == value
|
|
if operation == 'check':
|
|
assert report['changes'] == []
|
|
else:
|
|
assert [v['path'] for v in report['changes']] == ['children.arcadia', 'participants.arcadia']
|
|
for v in report['changes']:
|
|
assert v['before'] == original[v['path']] and v['after'] == after[v['path']]
|
|
verified[stem] = {'receipt_sha256': sha(receipt_raw), 'stdout_sha256': sha(stdout),
|
|
'stderr_sha256': sha(stderr), 'launcher_sha256': sha(launcher)}
|
|
|
|
# Read only the reviewed helper's literal fixture; never import or execute it.
|
|
mixed_helper = (base / '.local/run-analysis-mixed-cli-behavior-20260925.py').read_bytes()
|
|
assert sha(mixed_helper) == MIXED_CLI_HASH
|
|
mixed_tree = ast.parse(mixed_helper.decode('utf8'))
|
|
literal = [node.value for node in mixed_tree.body if isinstance(node, ast.Assign)
|
|
and any(isinstance(target, ast.Name) and target.id == 'original' for target in node.targets)]
|
|
assert len(literal) == 1
|
|
mixed_original = ast.literal_eval(literal[0])
|
|
assert set(mixed_original) == {'project.arcadia', 'sub/f.arcadia', 'sub/g.arcadia'}
|
|
mixed_invalid = dict(mixed_original)
|
|
assert mixed_invalid['sub/f.arcadia'].count('body @g(x: $x);') == 1
|
|
mixed_invalid['sub/f.arcadia'] = mixed_invalid['sub/f.arcadia'].replace('body @g(x: $x);', 'body @missing(x: $x);')
|
|
mixed_cli_records = {}
|
|
for label, output in [('valid', 'json'), ('unresolved', 'json'), ('valid', 'human')]:
|
|
stem = f'mixed-cli-actual-{label}-{output}-{source[:7]}-1'
|
|
receipt_raw = (folder / (stem + '.cli.json')).read_bytes()
|
|
d = json.loads(receipt_raw)
|
|
suffix = '.stdout.json' if output == 'json' else '.stdout.txt'
|
|
assert d['stdout_file'] == stem + suffix
|
|
stdout = (folder / (stem + suffix)).read_bytes()
|
|
stderr = (folder / (stem + '.stderr.txt')).read_bytes()
|
|
assert sha(stdout) == d['stdout_sha256'] and sha(stderr) == d['stderr_sha256']
|
|
assert d['source'] == source and d['build_artifact'] == build['artifacts'][0]
|
|
assert d['cwd'] == str(root) and d['environment'] == environment
|
|
assert d['inputs'] == build['inputs'] and d['inputs_sha256'] == build['inputs_sha256']
|
|
assert not d['changed_inputs'] and not d['verification_failures']
|
|
launcher = within(folder, d['launcher_copy']).read_bytes()
|
|
assert launcher == mixed_helper and sha(launcher) == d['launcher_sha256']
|
|
texts = mixed_original if label == 'valid' else mixed_invalid
|
|
fixture = folder / f'mixed-fixture-{label}-{source[:7]}'
|
|
assert d['fixture'] == fixture.name
|
|
inventory = {name: {'bytes': len(text.encode('utf8')), 'sha256': sha(text.encode('utf8'))}
|
|
for name, text in texts.items()}
|
|
assert d['expected_input_inventory'] == d['after_inventory'] == inventory
|
|
assert d['expected_directory_inventory'] == sorted([*texts, 'sub'])
|
|
assert sorted(p.relative_to(fixture).as_posix() for p in fixture.rglob('*')) == sorted([*texts, 'sub'])
|
|
for name, text in texts.items():
|
|
assert within(fixture, name).read_bytes() == text.encode('utf8')
|
|
entry = str(fixture / 'project.arcadia')
|
|
assert d['argv'] == [build['artifacts'][0]['path'], 'check-mixed', entry] + (['--json'] if output == 'json' else [])
|
|
expected_exit = 0 if label == 'valid' else 1
|
|
assert d['exit'] == expected_exit
|
|
if output == 'json':
|
|
diagnostics = []
|
|
if label == 'unresolved':
|
|
text = texts['sub/f.arcadia']
|
|
prefix = text[:text.index('body @missing') + len('body @')]
|
|
start = len(prefix.encode('utf8'))
|
|
diagnostics = [{'severity': 'error', 'code': 'invalid_source',
|
|
'message': "Unknown global reference '@missing'.", 'coordinate_space': 'input',
|
|
'location': {'path': 'sub/f.arcadia', 'start': start, 'end': start + 7,
|
|
'line': prefix.count('\n') + 1, 'column': len(prefix.rsplit('\n', 1)[-1]) + 1},
|
|
'related': [], 'object_id': None, 'field': None}]
|
|
expected = {'format_version': 1, 'entry': entry, 'operation': 'check-mixed',
|
|
'status': 'checked' if label == 'valid' else 'invalid', 'exit_code': expected_exit,
|
|
'written': False, 'diagnostics': diagnostics, 'changes': [],
|
|
'identities_to_stabilize': 0, 'migration': None, 'notes': []}
|
|
assert stderr == b'' and json.loads(stdout) == d['expected_report'] == expected
|
|
else:
|
|
assert d['expected_report'] is None and stdout == b''
|
|
assert stderr == b'checked: mixed source8 check; no files changed\n'
|
|
verified[stem] = {'receipt_sha256': sha(receipt_raw), 'stdout_sha256': sha(stdout),
|
|
'stderr_sha256': sha(stderr), 'launcher_sha256': sha(launcher)}
|
|
mixed_cli_records[stem] = verified[stem]
|
|
|
|
# Preserve all actual earlier gate attempts without calling overwritten artifacts current.
|
|
historical = {}
|
|
for path in sorted(folder.glob('*.result.json')):
|
|
if path.stem.removesuffix('.result') in verified:
|
|
continue
|
|
stem = path.name.removesuffix('.result.json')
|
|
d, raw = read_gate(stem, current=False)
|
|
historical[stem] = verified[stem]
|
|
initial_hashes = {
|
|
'integration-list-mixed_cli': '81e3fab919427cb1e1cf29b6f02711051292cb77594ce3eb50517df388d1a3dc',
|
|
'integration-list-mixed_source_files': '30c88fc4a7606a168a90cb8fd27d61d25208e4c71793700950da224d9d1038d9',
|
|
'integration-list-source_cli': 'd14165609816e1201cdeae773e2689a684e042006cd4d00027e98c8e9865068e',
|
|
'integration-suite-mixed_cli': 'bbe09f3883d6836dc5e2403e5428520d7e0b0f5d07e33ffc0a91ff0104191c25',
|
|
'integration-suite-mixed_source_files': '679c4d11bb4b02d55a263e6c492069f8c1c575fae01ed9abd0583ebce9e76235',
|
|
'integration-suite-source_cli': '0dabf95aed0480ae44233a93d80c6acb3fd3a78e2611ffbcd89d63304ab42542',
|
|
}
|
|
for suffix, digest in initial_hashes.items():
|
|
stem = 'mixed-cli-' + suffix + '-f232482-1'
|
|
initial = historical[stem]
|
|
assert initial['source'] == 'f2324822936374c5b9092518b986375233dc7882'
|
|
assert initial['log_sha256'] == digest
|
|
raw = (folder / (stem + '.log')).read_bytes()
|
|
if suffix == 'integration-suite-source_cli':
|
|
assert initial['exit'] == 101 and len(initial['outcomes']) == 12
|
|
assert {n for n, status in initial['outcomes'] if status == 'FAILED'} == {
|
|
'complete_alarm_example_preview_then_write_and_fixed_point',
|
|
'rename_shows_missing_identity_and_separate_source_migration',
|
|
}
|
|
assert sum(status == 'ok' for _, status in initial['outcomes']) == 10
|
|
assert initial['verification_failures'] == [
|
|
'Every selected integration outcome must actually pass',
|
|
'Expected one complete all-passed selected integration summary']
|
|
else:
|
|
assert initial['exit'] == 0 and not initial['verification_failures']
|
|
if suffix == 'integration-suite-mixed_cli':
|
|
assert all_passed(raw, 6) == NEW_CLI and b'hidden_glob_reexports' in raw
|
|
elif suffix == 'integration-suite-mixed_source_files':
|
|
assert all_passed(raw, 5) == NEW_FILES
|
|
# Exact stack names were independently enumerated in RUNTIME-PLAN; no inference of headroom.
|
|
plan = Path(__file__).with_name('RUNTIME-PLAN.md').read_text(encoding='utf8')
|
|
stack_names = re.findall(r'^- `(language::[^`]+)`$', plan, re.M)
|
|
assert len(stack_names) == len(set(stack_names)) == 11
|
|
assert set(stack_names) <= old_names and all(dict(full['outcomes'])[n] == 'ok' for n in stack_names)
|
|
assert git('rev-parse', 'HEAD').decode().strip() == source
|
|
assert not git('status', '--porcelain', '--untracked-files=all').strip()
|
|
result = {'source': source, 'baseline': BASELINE, 'baseline_archive_sha256': ARCHIVE_HASH,
|
|
'checker_sha256': sha(Path(__file__).read_bytes()), 'plan_sha256': sha(Path(__file__).with_name('RUNTIME-PLAN.md').read_bytes()),
|
|
'inputs': len(expected_inputs), 'prior_passes_preserved': 299, 'new_discovery_names': sorted(NEW_CORE),
|
|
'full_passed': 302, 'external_names': sorted(EXTERNAL), 'integration': integration,
|
|
'doc_names': sorted(doc_names), 'doc_runtime_names': sorted(doc_runtime_names),
|
|
'doc_exact_mapping': DOC_MAPPING, 'doc_recorder_verification_failures': doc_suite['verification_failures'],
|
|
'public_docs': sorted(public_docs), 'stack_controls': stack_names,
|
|
'mixed_cli_records': mixed_cli_records,
|
|
'old_cli_basis': 'Twelve names from baseline source only; current execution is newly verified, not claimed as prior runtime evidence.',
|
|
'initial_input_omission': {'path': ALARM, 'initial_declared_inputs': 566,
|
|
'final_declared_inputs': 567,
|
|
'scope': 'Initial six receipts did not capture this include_str dependency. Final recipe explicitly includes it; historical Git identity does not retroactively establish raw capture.',
|
|
'initial_git_sha256': sha(git('show', INITIAL_SOURCE + ':' + ALARM)),
|
|
'final_git_sha256': sha(git('show', source + ':' + ALARM))},
|
|
'core_artifact': full['artifacts'][0], 'cli_artifact': build['artifacts'][0],
|
|
'environment': environment, 'inherited_fmt_sha256': sha(fmt_log),
|
|
'verified': verified, 'historical': historical,
|
|
'scope': 'Data/Git readback only; no compiler/helper/product execution or publication verification. Finite mixed CLI Windows evidence; no Linux/depth128, GUI or editing adoption.'}
|
|
with destination.open('x', encoding='utf8', newline='\n') as stream:
|
|
json.dump(result, stream, indent=2)
|
|
stream.write('\n')
|
|
print(json.dumps({'source': source, 'full_passed': 302, 'public_external_passed': 10, 'new_files_passed': 5, 'new_cli_passed': 6, 'old_cli_passed': 12,
|
|
'ordinary_integration_passed': 65, 'doctests': len(doc_names),
|
|
'readback_sha256': sha(destination.read_bytes())}))
|