Make the Text workspace compact and preserve editing context
Replace the oversized header and reference rail with stable editor slots and a retained supporting drawer. Bind diagnostic, result and menu actions to their original publication and visit; preserve effective selections on navigation and dismiss Actions, Find and the drawer one surface per Escape. Retain exact Windows source captures, eight final gates (871 desktop passes), independent reviews, native selection/rename/recovery trials and the original failures. All 526 tested inputs and staged evidence were byte-checked before commit. Combined preview integration and packaging remain with issue 27; Linux remains paused.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
"""Preserve original trial evidence and exact gate capture without runtime binaries."""
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import json
|
||||
import shutil
|
||||
|
||||
base = Path(__file__).resolve().parent
|
||||
root = Path('C:/ar-text-9e8r6t')
|
||||
dest = root / 'harness/experiments/text-workspace-initial-20260913'
|
||||
dest.mkdir()
|
||||
records = []
|
||||
|
||||
def keep(source, relative):
|
||||
target = dest / relative
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
assert not target.exists()
|
||||
shutil.copyfile(source, target)
|
||||
raw = source.read_bytes()
|
||||
assert target.read_bytes() == raw
|
||||
records.append({'path': relative, 'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()})
|
||||
|
||||
trial = base / 'trial-text-1'
|
||||
for source in sorted(trial.rglob('*')):
|
||||
rel = source.relative_to(trial)
|
||||
if source.is_file() and (len(rel.parts) == 1 or rel.parts[0] == 'screenshots' or rel.parts[0].startswith('verification-')):
|
||||
keep(source, 'trial-text-1/' + rel.as_posix())
|
||||
gate = root / '.local/text-workspace-gates-20260912'
|
||||
for attempt in ['attempt-3', 'attempt-4']:
|
||||
for source in sorted((gate / attempt).iterdir()):
|
||||
if source.is_file() and source.suffix in ['.json', '.log', '.zip']:
|
||||
keep(source, attempt + '/' + source.name)
|
||||
for name in ['fixture-manifest.json', 'launch.py', 'verify_saved.py', 'bind_gates.py']:
|
||||
keep(base / name, 'helpers/' + name)
|
||||
keep(gate / 'gate.py', 'helpers/gate.py')
|
||||
keep(Path(__file__), 'helpers/archive_initial.py')
|
||||
with (dest / 'manifest.json').open('x', encoding='utf-8', newline='\n') as stream:
|
||||
json.dump({'scope': 'Original failed native trial and passing attempt4 gates; runtime binaries remain locally preserved by SHA, no native acceptance.', 'files': records}, stream, indent=2)
|
||||
stream.write('\n')
|
||||
print(json.dumps({'directory': str(dest), 'files': len(records), 'bytes': sum(r['bytes'] for r in records), 'manifestSha256': hashlib.sha256((dest / 'manifest.json').read_bytes()).hexdigest()}))
|
||||
@@ -0,0 +1,86 @@
|
||||
"""Bind completed Windows gate inputs and preserved GUI for a development trial."""
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
BASE = Path(__file__).resolve().parent
|
||||
ROOT = Path('C:/ar-text-9e8r6t')
|
||||
attempt = sys.argv[1]
|
||||
assert re.fullmatch(r'attempt-[0-9]+', attempt)
|
||||
gate = ROOT / '.local/text-workspace-gates-20260912' / attempt
|
||||
destination = BASE / (attempt + '-launch-manifest.json')
|
||||
assert not destination.exists()
|
||||
|
||||
def identity(path):
|
||||
raw = path.read_bytes()
|
||||
return {'path': str(path.resolve()), 'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()}
|
||||
|
||||
def read(name):
|
||||
return json.loads((gate / name).read_text(encoding='utf-8'))
|
||||
|
||||
names = ['clippy', 'membership', 'focused', 'tests', 'timing', 'gui']
|
||||
complete = read('complete.json')
|
||||
assert complete['inputsUnchanged'] is True and complete['gates'] == names
|
||||
inputs = read('inputs.json')
|
||||
assert identity(gate / 'inputs.zip')['sha256'] == inputs['archiveSha256']
|
||||
assert subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=ROOT).decode().strip() == inputs['baseCommit']
|
||||
scopes = ['Cargo.toml', 'Cargo.lock', 'crates', 'build', '.cargo', 'docs', 'examples', 'harness/fixtures']
|
||||
raw_names = subprocess.check_output(['git', 'ls-files', '-z', '--cached', '--others', '--exclude-standard', '--', *scopes], cwd=ROOT)
|
||||
current_names = sorted(set(name.decode() for name in raw_names.split(b'\0') if name))
|
||||
assert current_names == [item['path'] for item in inputs['files']]
|
||||
for item in inputs['files']:
|
||||
path = (ROOT / item['path']).resolve()
|
||||
assert path.is_relative_to(ROOT.resolve())
|
||||
measured = identity(path)
|
||||
assert all(measured[key] == item[key] for key in ['bytes', 'sha256'])
|
||||
|
||||
evidence = [identity(gate / name) for name in ['inputs.json', 'inputs.zip', 'environment.json', 'complete.json']]
|
||||
receipts = {}
|
||||
for name in names:
|
||||
receipt = read(name + '-result.json')
|
||||
assert receipt['exitCode'] == 0 and receipt['inputsUnchanged'] is True
|
||||
for stream in ['stdout', 'stderr']:
|
||||
log = identity(gate / (name + '-' + stream + '.log'))
|
||||
assert log['sha256'] == receipt[stream + 'Sha256']
|
||||
evidence.append(log)
|
||||
evidence.append(identity(gate / (name + '-result.json')))
|
||||
receipts[name] = receipt
|
||||
|
||||
membership = receipts['membership']['testMembership']
|
||||
assert not membership['missing'] and membership['diagnosticGuardCount'] == 20
|
||||
assert any('queued_group_toggle_cannot_mutate' in name for name in membership['required'])
|
||||
assert any('all_reference_exceptions_fit_allocated_width' in name for name in membership['required'])
|
||||
test_output = (gate / 'tests-stdout.log').read_text(encoding='utf-8')
|
||||
result = re.search(r'test result: ok\. (\d+) passed; 0 failed; (\d+) ignored;', test_output)
|
||||
assert result and sum(map(int, result.groups())) == membership['listed']
|
||||
timing_output = (gate / 'timing-stdout.log').read_text(encoding='utf-8')
|
||||
assert 'test result: ok. 1 passed; 0 failed;' in timing_output
|
||||
binary_record = receipts['gui']['binary']
|
||||
binary = identity(Path(binary_record['preserved']))
|
||||
assert all(binary[key] == binary_record[key] for key in ['bytes', 'sha256'])
|
||||
artifact = binary_record['artifact']
|
||||
assert Path(artifact['manifest_path']).resolve() == ROOT / 'crates/oa-desktop/Cargo.toml'
|
||||
assert artifact['target']['name'] == 'arcadia-studio'
|
||||
assert artifact['executable'] == binary_record['path']
|
||||
|
||||
manifest = {
|
||||
'atUtc': datetime.now(timezone.utc).isoformat(),
|
||||
'nativeReady': True,
|
||||
'scope': 'Completed Windows source gates authorize development GUI evaluation; native and packaged acceptance remain pending.',
|
||||
'target': 'x86_64-pc-windows-gnullvm',
|
||||
'baseCommit': inputs['baseCommit'],
|
||||
'sourceFiles': len(inputs['files']),
|
||||
'sourceArchiveSha256': inputs['archiveSha256'],
|
||||
'membership': membership,
|
||||
'binary': binary,
|
||||
'evidence': evidence,
|
||||
'helper': identity(Path(__file__)),
|
||||
}
|
||||
with destination.open('x', encoding='utf-8', newline='\n') as output:
|
||||
json.dump(manifest, output, indent=2)
|
||||
output.write('\n')
|
||||
print(json.dumps(identity(destination)), flush=True)
|
||||
@@ -0,0 +1,435 @@
|
||||
{
|
||||
"preparedAtUtc": "2026-09-12T11:17:21.035184+00:00",
|
||||
"oracle_sha256": "967d9ba3c6fb3a7efb410833903ec94556ca2d48a67d5072c8bb160f40a00f9c",
|
||||
"dll_sha256": "f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4",
|
||||
"cases": {
|
||||
"simple": {
|
||||
"original": "valid-baseline",
|
||||
"original_files": {
|
||||
"links.arcadia": {
|
||||
"sha256": "d3229ecf6300804103eb7f85bd5891c022f6f6c194dbdbbdcb54e9550338dc3b",
|
||||
"bytes": 211
|
||||
},
|
||||
"project.arcadia": {
|
||||
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414",
|
||||
"bytes": 277
|
||||
},
|
||||
"救援/assess.arcadia": {
|
||||
"sha256": "d99593537e67b2dfd293623f467ffbd46af4ea259dffae55d1fe9995c86e6992",
|
||||
"bytes": 192
|
||||
},
|
||||
"救援/confirm.arcadia": {
|
||||
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919",
|
||||
"bytes": 92
|
||||
}
|
||||
},
|
||||
"literal_edits": [
|
||||
{
|
||||
"path": "救援/assess.arcadia",
|
||||
"before": "oa_activity assess \"Assess 救援 request\"",
|
||||
"after": "oa_activity assess_damage \"Assess 救援 request\"",
|
||||
"count": 1,
|
||||
"before_snippet_spans_at_edit": [
|
||||
{
|
||||
"start": 47,
|
||||
"end": 89
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "links.arcadia",
|
||||
"before": "; source @assess; target @confirm;",
|
||||
"after": "; source @assess_damage; target @confirm;",
|
||||
"count": 1,
|
||||
"before_snippet_spans_at_edit": [
|
||||
{
|
||||
"start": 127,
|
||||
"end": 161
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expected_files": {
|
||||
"links.arcadia": {
|
||||
"sha256": "c056d46011b3b86ae05dc49b8e6d69cba903f8e7379b06c6d0c5d93639768a09",
|
||||
"bytes": 218
|
||||
},
|
||||
"project.arcadia": {
|
||||
"sha256": "79e26836c048a35aaf98b21ff006ae8ac931160abd9913b9e67b542303215414",
|
||||
"bytes": 277
|
||||
},
|
||||
"救援/assess.arcadia": {
|
||||
"sha256": "8d326ec33370b8ecf73f6d611904875994888baa3495f7c1df4613866e645d03",
|
||||
"bytes": 199
|
||||
},
|
||||
"救援/confirm.arcadia": {
|
||||
"sha256": "591b32db3b1282825750d002d9293cfc450d55252506623302ce36c949fe9919",
|
||||
"bytes": 92
|
||||
}
|
||||
},
|
||||
"changed_files": [
|
||||
"links.arcadia",
|
||||
"救援/assess.arcadia"
|
||||
],
|
||||
"arcadia_files": 4
|
||||
},
|
||||
"representative": {
|
||||
"original": "release1-baseline",
|
||||
"original_files": {
|
||||
"evidence/repair-check.md": {
|
||||
"sha256": "f4db17bdca4ecbb1bf0caef01b2da5f1f7f798ab3152b648ce6dd8696a6a68e5",
|
||||
"bytes": 1419
|
||||
},
|
||||
"expected-diagnostics.json": {
|
||||
"sha256": "3700393d76b940cfc076bf52861bd7b1f43370f8eabce3594531bd0bf1fc851e",
|
||||
"bytes": 288
|
||||
},
|
||||
"model.json": {
|
||||
"sha256": "ef0ef4006c3e09d5db6e1b621256b3f7d6642f3a7b09cc34607cfbcca830c727",
|
||||
"bytes": 134520
|
||||
},
|
||||
"model.rs": {
|
||||
"sha256": "15f30f6bde655808fe754665c26d560e36f2a9bad340f346b09137d0d05045f5",
|
||||
"bytes": 28762
|
||||
},
|
||||
"oa/activities/activity_oa_restore_work.arcadia": {
|
||||
"sha256": "83e73d0a013d5c3e1a4af0d9139ab0cfa362d25a846671fc2dac59181061a9d4",
|
||||
"bytes": 1307
|
||||
},
|
||||
"oa/behavior/process_oa_assessment_procedure.arcadia": {
|
||||
"sha256": "172c32c044ef4b5bc58a1f4635cc81f48dabb4014479b47dce7b25fedf2dbd0d",
|
||||
"bytes": 697
|
||||
},
|
||||
"oa/behavior/process_oa_field_procedure.arcadia": {
|
||||
"sha256": "d2552dc5383e2e91cb302a790364e197f663c2edc013a2ab1978789825c9c324",
|
||||
"bytes": 1781
|
||||
},
|
||||
"oa/behavior/process_oa_response.arcadia": {
|
||||
"sha256": "cf86f46fa5c5d70592ef43f1bc1cb4d968efd8add384ba88036bef6b88aa4abc",
|
||||
"bytes": 3225
|
||||
},
|
||||
"oa/behavior/scenario_oa_conversation.arcadia": {
|
||||
"sha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6",
|
||||
"bytes": 1795
|
||||
},
|
||||
"oa/behavior/scenario_oa_full_scenario.arcadia": {
|
||||
"sha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c",
|
||||
"bytes": 1261
|
||||
},
|
||||
"oa/behavior/state_machine_oa_monitor.arcadia": {
|
||||
"sha256": "447c9ad1359f4a31ecf975ad07c0b08d8e7e03191fb0858e2fc56f377b223cd5",
|
||||
"bytes": 2022
|
||||
},
|
||||
"oa/capabilities.arcadia": {
|
||||
"sha256": "fc8012e5554350b12e1cb80080f8feab80d933c9b33c0f2a7bb500cb7d609936",
|
||||
"bytes": 781
|
||||
},
|
||||
"oa/model.arcadia": {
|
||||
"sha256": "f7cf914766ea73ec53b85e32d117ea9a9dba52d3e038246863541ae7069b1a15",
|
||||
"bytes": 661
|
||||
},
|
||||
"oa/participants.arcadia": {
|
||||
"sha256": "951764c14179f27c10e315acf2ea37d1fff54c77b8441e23addd239e8c715ce3",
|
||||
"bytes": 1834
|
||||
},
|
||||
"oa/types.arcadia": {
|
||||
"sha256": "9d0396fb82dd5733edd8d1cf52f968ca84906927c704f9cf0944a7fae215cf49",
|
||||
"bytes": 788
|
||||
},
|
||||
"project.arcadia": {
|
||||
"sha256": "b2674e6bf77cfe0f6f0ba79c81d2e96d92f39c02ca2c6266d80e91723bfb9fda",
|
||||
"bytes": 1958
|
||||
},
|
||||
"README.md": {
|
||||
"sha256": "113cfb1cf38a98b51bff60442d86a35d636a3d80ef206bece7d53d0aae67f2d5",
|
||||
"bytes": 11137
|
||||
},
|
||||
"sa/behavior/process_sa_assessment_procedure.arcadia": {
|
||||
"sha256": "73928ced61c06cbc08728d7956676a50fd4c05aa5b7f1ff4f29ce27a0b0f2088",
|
||||
"bytes": 706
|
||||
},
|
||||
"sa/behavior/process_sa_field_procedure.arcadia": {
|
||||
"sha256": "886d462af83110cbfa55dd232a667ea1446761234471357cbb878794e98e8768",
|
||||
"bytes": 1790
|
||||
},
|
||||
"sa/behavior/process_sa_response.arcadia": {
|
||||
"sha256": "041785fc22842423822431bd5e6e8d16094ebd0716965e7c765fb8c1d7549e8a",
|
||||
"bytes": 3234
|
||||
},
|
||||
"sa/behavior/scenario_sa_conversation.arcadia": {
|
||||
"sha256": "97276f5757ee9aa12a0dbd9d3ccd58174b3091162bb8bcce357cec20a45f5d85",
|
||||
"bytes": 2127
|
||||
},
|
||||
"sa/behavior/scenario_sa_full_scenario.arcadia": {
|
||||
"sha256": "e12fc406b99d60a2f7768aaa0b25ba560e8605f0b8e37f3a7cdd3b8443562b74",
|
||||
"bytes": 1256
|
||||
},
|
||||
"sa/behavior/state_machine_sa_monitor.arcadia": {
|
||||
"sha256": "05ce29af99424c491c47fe2450dc6f5f8ce995511c01ec7e17bb5855be3c9736",
|
||||
"bytes": 2022
|
||||
},
|
||||
"sa/capabilities.arcadia": {
|
||||
"sha256": "b6912fb3ece439912345fa71724acd462e716a1e5a88203a1058a5c3b2c20a4f",
|
||||
"bytes": 781
|
||||
},
|
||||
"sa/functions/function_sa_audit_thresholds.arcadia": {
|
||||
"sha256": "e5a04325d52183956dca814dd90f4e56c96c6b7db0f4f202f203ecb49c3e0f4f",
|
||||
"bytes": 297
|
||||
},
|
||||
"sa/functions/function_sa_restore_work.arcadia": {
|
||||
"sha256": "fddeb67308051325041fee641fe758ddf43345b7c47b66d433616ad07fdccdd6",
|
||||
"bytes": 2576
|
||||
},
|
||||
"sa/model.arcadia": {
|
||||
"sha256": "d431509251acb859fbb98733b6d18add952495e10a78703fbe8f31e40bc083c4",
|
||||
"bytes": 661
|
||||
},
|
||||
"sa/participants.arcadia": {
|
||||
"sha256": "780d2eb08b217b67b55febb3d34846f727b8ee9018df6c5741748647e36b2ff8",
|
||||
"bytes": 4012
|
||||
},
|
||||
"sa/types.arcadia": {
|
||||
"sha256": "101fc0fbd99f1101514aa7b6da4f8e535aae0bb94c9e2b9e7e6c151135b28660",
|
||||
"bytes": 1227
|
||||
},
|
||||
"traceability.arcadia": {
|
||||
"sha256": "48a96f543456c9b5a5798fc795594e4119147fe45f11a6f109f141b7f514560f",
|
||||
"bytes": 29506
|
||||
},
|
||||
"transition-before.json": {
|
||||
"sha256": "2253e6434f741687e22327c37d520ed15c043bc36025498650bc2366bb6a874d",
|
||||
"bytes": 35801
|
||||
},
|
||||
"transition-request.json": {
|
||||
"sha256": "43b9a22e5f95ad3bc0ebd2478ead0e14406854abc989ae94ded9367b013d812a",
|
||||
"bytes": 4276
|
||||
},
|
||||
"views/diagram_oa_allocation_view.arcadia": {
|
||||
"sha256": "dfc0eb61e0e2aa5bda45524571fbfa3494f44ce19696f3e15e07438074a07bc7",
|
||||
"bytes": 2176
|
||||
},
|
||||
"views/diagram_sa_allocation_view.arcadia": {
|
||||
"sha256": "b78b43a26a82efb8fbd5374b09c329fa341f57b29f635d397b9ef8aede71d389",
|
||||
"bytes": 2173
|
||||
},
|
||||
"views/diagram_sa_capability_view.arcadia": {
|
||||
"sha256": "75e8dc9fb30f25d6f8fd3c6b595593ab4f98958a25798f961e336e0fac557649",
|
||||
"bytes": 1620
|
||||
},
|
||||
"views/diagram_sa_service_view.arcadia": {
|
||||
"sha256": "b08c84f3ea633e7c78dfdad3272f75415f6256cf3614b6d99bfd4f0269076c9b",
|
||||
"bytes": 2209
|
||||
},
|
||||
"views/diagram_sa_state_view.arcadia": {
|
||||
"sha256": "5f42f4c605e57b817d8400ed21f2b14bfc4e1592aebe941ff113767504c2b869",
|
||||
"bytes": 1931
|
||||
}
|
||||
},
|
||||
"literal_edits": [
|
||||
{
|
||||
"path": "oa/activities/activity_oa_restore_work.arcadia",
|
||||
"before": "oa_activity oa_restore_work \"Restore safe pressure\"",
|
||||
"after": "oa_activity oa_restore_pressure \"Restore safe pressure\"",
|
||||
"count": 1,
|
||||
"before_snippet_spans_at_edit": [
|
||||
{
|
||||
"start": 0,
|
||||
"end": 51
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "oa/activities/activity_oa_restore_work.arcadia",
|
||||
"before": " parent @oa_restore_work;",
|
||||
"after": " parent @oa_restore_pressure;",
|
||||
"count": 4,
|
||||
"before_snippet_spans_at_edit": [
|
||||
{
|
||||
"start": 250,
|
||||
"end": 278
|
||||
},
|
||||
{
|
||||
"start": 393,
|
||||
"end": 421
|
||||
},
|
||||
{
|
||||
"start": 539,
|
||||
"end": 567
|
||||
},
|
||||
{
|
||||
"start": 679,
|
||||
"end": 707
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "traceability.arcadia",
|
||||
"before": " oa @oa_restore_work;",
|
||||
"after": " oa @oa_restore_pressure;",
|
||||
"count": 1,
|
||||
"before_snippet_spans_at_edit": [
|
||||
{
|
||||
"start": 26877,
|
||||
"end": 26901
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expected_files": {
|
||||
"evidence/repair-check.md": {
|
||||
"sha256": "f4db17bdca4ecbb1bf0caef01b2da5f1f7f798ab3152b648ce6dd8696a6a68e5",
|
||||
"bytes": 1419
|
||||
},
|
||||
"expected-diagnostics.json": {
|
||||
"sha256": "3700393d76b940cfc076bf52861bd7b1f43370f8eabce3594531bd0bf1fc851e",
|
||||
"bytes": 288
|
||||
},
|
||||
"model.json": {
|
||||
"sha256": "ef0ef4006c3e09d5db6e1b621256b3f7d6642f3a7b09cc34607cfbcca830c727",
|
||||
"bytes": 134520
|
||||
},
|
||||
"model.rs": {
|
||||
"sha256": "15f30f6bde655808fe754665c26d560e36f2a9bad340f346b09137d0d05045f5",
|
||||
"bytes": 28762
|
||||
},
|
||||
"oa/activities/activity_oa_restore_work.arcadia": {
|
||||
"sha256": "8c6cf1e9b6fdd118602659b6fb3ad0f1988ae700fcd548abede259da2c3a29e5",
|
||||
"bytes": 1327
|
||||
},
|
||||
"oa/behavior/process_oa_assessment_procedure.arcadia": {
|
||||
"sha256": "172c32c044ef4b5bc58a1f4635cc81f48dabb4014479b47dce7b25fedf2dbd0d",
|
||||
"bytes": 697
|
||||
},
|
||||
"oa/behavior/process_oa_field_procedure.arcadia": {
|
||||
"sha256": "d2552dc5383e2e91cb302a790364e197f663c2edc013a2ab1978789825c9c324",
|
||||
"bytes": 1781
|
||||
},
|
||||
"oa/behavior/process_oa_response.arcadia": {
|
||||
"sha256": "cf86f46fa5c5d70592ef43f1bc1cb4d968efd8add384ba88036bef6b88aa4abc",
|
||||
"bytes": 3225
|
||||
},
|
||||
"oa/behavior/scenario_oa_conversation.arcadia": {
|
||||
"sha256": "b25be524e98a35ebac5e4481b7609c027b32baf9605e8097f807560f94a77ca6",
|
||||
"bytes": 1795
|
||||
},
|
||||
"oa/behavior/scenario_oa_full_scenario.arcadia": {
|
||||
"sha256": "00a1edf2c9707a0eb62ac070c2d02467874f2c9c1f273cc6ddb53d6d65999a1c",
|
||||
"bytes": 1261
|
||||
},
|
||||
"oa/behavior/state_machine_oa_monitor.arcadia": {
|
||||
"sha256": "447c9ad1359f4a31ecf975ad07c0b08d8e7e03191fb0858e2fc56f377b223cd5",
|
||||
"bytes": 2022
|
||||
},
|
||||
"oa/capabilities.arcadia": {
|
||||
"sha256": "fc8012e5554350b12e1cb80080f8feab80d933c9b33c0f2a7bb500cb7d609936",
|
||||
"bytes": 781
|
||||
},
|
||||
"oa/model.arcadia": {
|
||||
"sha256": "f7cf914766ea73ec53b85e32d117ea9a9dba52d3e038246863541ae7069b1a15",
|
||||
"bytes": 661
|
||||
},
|
||||
"oa/participants.arcadia": {
|
||||
"sha256": "951764c14179f27c10e315acf2ea37d1fff54c77b8441e23addd239e8c715ce3",
|
||||
"bytes": 1834
|
||||
},
|
||||
"oa/types.arcadia": {
|
||||
"sha256": "9d0396fb82dd5733edd8d1cf52f968ca84906927c704f9cf0944a7fae215cf49",
|
||||
"bytes": 788
|
||||
},
|
||||
"project.arcadia": {
|
||||
"sha256": "b2674e6bf77cfe0f6f0ba79c81d2e96d92f39c02ca2c6266d80e91723bfb9fda",
|
||||
"bytes": 1958
|
||||
},
|
||||
"README.md": {
|
||||
"sha256": "113cfb1cf38a98b51bff60442d86a35d636a3d80ef206bece7d53d0aae67f2d5",
|
||||
"bytes": 11137
|
||||
},
|
||||
"sa/behavior/process_sa_assessment_procedure.arcadia": {
|
||||
"sha256": "73928ced61c06cbc08728d7956676a50fd4c05aa5b7f1ff4f29ce27a0b0f2088",
|
||||
"bytes": 706
|
||||
},
|
||||
"sa/behavior/process_sa_field_procedure.arcadia": {
|
||||
"sha256": "886d462af83110cbfa55dd232a667ea1446761234471357cbb878794e98e8768",
|
||||
"bytes": 1790
|
||||
},
|
||||
"sa/behavior/process_sa_response.arcadia": {
|
||||
"sha256": "041785fc22842423822431bd5e6e8d16094ebd0716965e7c765fb8c1d7549e8a",
|
||||
"bytes": 3234
|
||||
},
|
||||
"sa/behavior/scenario_sa_conversation.arcadia": {
|
||||
"sha256": "97276f5757ee9aa12a0dbd9d3ccd58174b3091162bb8bcce357cec20a45f5d85",
|
||||
"bytes": 2127
|
||||
},
|
||||
"sa/behavior/scenario_sa_full_scenario.arcadia": {
|
||||
"sha256": "e12fc406b99d60a2f7768aaa0b25ba560e8605f0b8e37f3a7cdd3b8443562b74",
|
||||
"bytes": 1256
|
||||
},
|
||||
"sa/behavior/state_machine_sa_monitor.arcadia": {
|
||||
"sha256": "05ce29af99424c491c47fe2450dc6f5f8ce995511c01ec7e17bb5855be3c9736",
|
||||
"bytes": 2022
|
||||
},
|
||||
"sa/capabilities.arcadia": {
|
||||
"sha256": "b6912fb3ece439912345fa71724acd462e716a1e5a88203a1058a5c3b2c20a4f",
|
||||
"bytes": 781
|
||||
},
|
||||
"sa/functions/function_sa_audit_thresholds.arcadia": {
|
||||
"sha256": "e5a04325d52183956dca814dd90f4e56c96c6b7db0f4f202f203ecb49c3e0f4f",
|
||||
"bytes": 297
|
||||
},
|
||||
"sa/functions/function_sa_restore_work.arcadia": {
|
||||
"sha256": "fddeb67308051325041fee641fe758ddf43345b7c47b66d433616ad07fdccdd6",
|
||||
"bytes": 2576
|
||||
},
|
||||
"sa/model.arcadia": {
|
||||
"sha256": "d431509251acb859fbb98733b6d18add952495e10a78703fbe8f31e40bc083c4",
|
||||
"bytes": 661
|
||||
},
|
||||
"sa/participants.arcadia": {
|
||||
"sha256": "780d2eb08b217b67b55febb3d34846f727b8ee9018df6c5741748647e36b2ff8",
|
||||
"bytes": 4012
|
||||
},
|
||||
"sa/types.arcadia": {
|
||||
"sha256": "101fc0fbd99f1101514aa7b6da4f8e535aae0bb94c9e2b9e7e6c151135b28660",
|
||||
"bytes": 1227
|
||||
},
|
||||
"traceability.arcadia": {
|
||||
"sha256": "cd3d7ebaf7d6aedf1eaa739afaf0268c487b05cc2685233568425ce0498cf338",
|
||||
"bytes": 29510
|
||||
},
|
||||
"transition-before.json": {
|
||||
"sha256": "2253e6434f741687e22327c37d520ed15c043bc36025498650bc2366bb6a874d",
|
||||
"bytes": 35801
|
||||
},
|
||||
"transition-request.json": {
|
||||
"sha256": "43b9a22e5f95ad3bc0ebd2478ead0e14406854abc989ae94ded9367b013d812a",
|
||||
"bytes": 4276
|
||||
},
|
||||
"views/diagram_oa_allocation_view.arcadia": {
|
||||
"sha256": "dfc0eb61e0e2aa5bda45524571fbfa3494f44ce19696f3e15e07438074a07bc7",
|
||||
"bytes": 2176
|
||||
},
|
||||
"views/diagram_sa_allocation_view.arcadia": {
|
||||
"sha256": "b78b43a26a82efb8fbd5374b09c329fa341f57b29f635d397b9ef8aede71d389",
|
||||
"bytes": 2173
|
||||
},
|
||||
"views/diagram_sa_capability_view.arcadia": {
|
||||
"sha256": "75e8dc9fb30f25d6f8fd3c6b595593ab4f98958a25798f961e336e0fac557649",
|
||||
"bytes": 1620
|
||||
},
|
||||
"views/diagram_sa_service_view.arcadia": {
|
||||
"sha256": "b08c84f3ea633e7c78dfdad3272f75415f6256cf3614b6d99bfd4f0269076c9b",
|
||||
"bytes": 2209
|
||||
},
|
||||
"views/diagram_sa_state_view.arcadia": {
|
||||
"sha256": "5f42f4c605e57b817d8400ed21f2b14bfc4e1592aebe941ff113767504c2b869",
|
||||
"bytes": 1931
|
||||
}
|
||||
},
|
||||
"changed_files": [
|
||||
"oa/activities/activity_oa_restore_work.arcadia",
|
||||
"traceability.arcadia"
|
||||
],
|
||||
"arcadia_files": 30
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
"""Capture exact working inputs and run one serial Windows acceptance attempt."""
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import zipfile
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
BASE = Path(__file__).resolve().parent
|
||||
label = sys.argv[1]
|
||||
if not re.fullmatch(r'attempt-[0-9]+', label):
|
||||
raise RuntimeError('Invalid attempt label')
|
||||
DEST = BASE / label
|
||||
DEST.mkdir()
|
||||
if os.environ.get('CARGO_BUILD_JOBS') != '1':
|
||||
raise RuntimeError('One Windows compiler job required')
|
||||
SCOPES = ['Cargo.toml', 'Cargo.lock', 'crates', 'build', '.cargo', 'docs', 'examples', 'harness/fixtures']
|
||||
def now():
|
||||
return datetime.datetime.now(datetime.timezone.utc).isoformat()
|
||||
def sha(path):
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
def names():
|
||||
data = subprocess.check_output(['git', 'ls-files', '-z', '--cached', '--others', '--exclude-standard', '--', *SCOPES], cwd=ROOT)
|
||||
return sorted(set(p.decode() for p in data.split(b'\0') if p))
|
||||
def write(name, value):
|
||||
with (DEST / name).open('x', encoding='utf-8', newline='\n') as output:
|
||||
json.dump(value, output, indent=2)
|
||||
output.write('\n')
|
||||
inputs = []
|
||||
with zipfile.ZipFile(DEST / 'inputs.zip', 'x', zipfile.ZIP_DEFLATED) as archive:
|
||||
for name in names():
|
||||
raw = (ROOT / name).read_bytes()
|
||||
archive.writestr(name, raw)
|
||||
inputs.append({'path': name, 'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()})
|
||||
def verify():
|
||||
return names() == [row['path'] for row in inputs] and all(sha(ROOT / row['path']) == row['sha256'] for row in inputs)
|
||||
write('inputs.json', {'atUtc': now(), 'baseCommit': subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=ROOT).decode().strip(), 'archiveSha256': sha(DEST / 'inputs.zip'), 'files': inputs})
|
||||
write('environment.json', {'atUtc': now(), 'versions': {name: subprocess.check_output(command, cwd=ROOT).decode() for name, command in [('rustc', ['rustc', '-vV']), ('cargo', ['cargo', '-V'])]}, 'variables': {key: os.environ.get(key) for key in ['RUSTUP_HOME', 'CARGO_HOME', 'RUSTUP_TOOLCHAIN', 'CARGO_TARGET_DIR', 'CARGO_BUILD_JOBS', 'CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_LINKER']}})
|
||||
gates = [
|
||||
('clippy', ['cargo', 'clippy', '--locked', '--offline', '-p', 'oa-desktop', '--all-targets', '--', '-D', 'warnings']),
|
||||
('membership', ['cargo', 'test', '--locked', '--offline', '-p', 'oa-desktop', '--bin', 'arcadia-studio', '--', '--list']),
|
||||
('focused', ['cargo', 'test', '--locked', '--offline', '-p', 'oa-desktop', '--bin', 'arcadia-studio', 'text_workspace', '--', '--nocapture', '--test-threads=1']),
|
||||
('tests', ['cargo', 'test', '--locked', '--offline', '-p', 'oa-desktop', '--bin', 'arcadia-studio', '--', '--test-threads=1']),
|
||||
('timing', ['cargo', 'test', '--locked', '--offline', '-p', 'oa-desktop', '--bin', 'arcadia-studio', 'app::source_rename::timing_tests::accepted_release1_prepare_commit_sync_and_confirm_timing', '--', '--ignored', '--nocapture', '--test-threads=1']),
|
||||
('gui', ['cargo', 'build', '--locked', '--offline', '-p', 'oa-desktop', '--bin', 'arcadia-studio', '--message-format=json-render-diagnostics']),
|
||||
]
|
||||
for name, command in gates:
|
||||
if not verify():
|
||||
raise RuntimeError('Source inputs changed before gate')
|
||||
print(json.dumps({'starting': name, 'command': command}), flush=True)
|
||||
start, clock = now(), time.perf_counter()
|
||||
with (DEST / (name + '-stdout.log')).open('xb') as out, (DEST / (name + '-stderr.log')).open('xb') as err:
|
||||
result = subprocess.run(command, cwd=ROOT, stdout=out, stderr=err)
|
||||
receipt = {'command': command, 'started': start, 'finished': now(), 'seconds': time.perf_counter() - clock, 'exitCode': result.returncode, 'inputsUnchanged': verify(), 'stdoutSha256': sha(DEST / (name + '-stdout.log')), 'stderrSha256': sha(DEST / (name + '-stderr.log'))}
|
||||
if name == 'membership' and result.returncode == 0:
|
||||
listed = {line.removesuffix(': test') for line in (DEST / 'membership-stdout.log').read_text(encoding='utf-8').splitlines() if line.endswith(': test')}
|
||||
required = {
|
||||
'app::text_workspace::tests::document_reset_preserves_popup_token_sequence_and_drops_old_menu_authority',
|
||||
'app::text_workspace::tests::stale_retained_group_can_expand_without_navigating_or_applying_drafts',
|
||||
'app::text_workspace::lifecycle_tests::saved_new_destination_republishes_current_warning_and_refuses_old_primary_and_related',
|
||||
'app::text_workspace::lifecycle_tests::invalid_repair_open_clears_prior_presentation_and_publishes_current_problems_preserving_worker',
|
||||
'views::text_workspace::tests::highlighted_sensor_editor_retains_real_scrolled_buffer_across_panel_rebuilds',
|
||||
'views::text_workspace::tests::drawer_clamps_to_actual_center_allocation_including_oversize_requests',
|
||||
'diagnostic_input::tests::same_publication_new_visit_cancels_armed_rows_without_a_hidden_tree_frame',
|
||||
'app::source_symbols::tests::retained_choices_cannot_replay_after_hide_or_references_problems_references',
|
||||
'app::text_workspace::tests::queued_group_toggle_cannot_mutate_a_reopened_or_rotated_visit',
|
||||
'views::text_workspace::summary_visibility_tests::all_reference_exceptions_fit_allocated_width_with_wide_alias_and_large_counts',
|
||||
}
|
||||
receipt['testMembership'] = {'listed': len(listed), 'required': sorted(required), 'missing': sorted(required - listed), 'diagnosticGuardCount': sum(name.startswith('diagnostic_input::tests::') for name in listed)}
|
||||
if required - listed or receipt['testMembership']['diagnosticGuardCount'] != 20:
|
||||
write(name + '-result.json', receipt)
|
||||
raise RuntimeError('New Text workspace test membership differs; shared-target cache output is not accepted')
|
||||
if name == 'gui' and result.returncode == 0:
|
||||
records = [json.loads(line) for line in (DEST / 'gui-stdout.log').read_text(encoding='utf-8').splitlines() if line.startswith('{')]
|
||||
artifacts = [record for record in records if record.get('reason') == 'compiler-artifact' and record.get('target', {}).get('name') == 'arcadia-studio' and record.get('executable')]
|
||||
if len(artifacts) != 1:
|
||||
raise RuntimeError('Expected exactly one desktop artifact')
|
||||
binary = Path(artifacts[0]['executable'])
|
||||
shutil.copyfile(binary, DEST / 'arcadia-studio.exe')
|
||||
if sha(binary) != sha(DEST / 'arcadia-studio.exe'):
|
||||
raise RuntimeError('Desktop preservation differs')
|
||||
receipt['binary'] = {'path': str(binary), 'preserved': str(DEST / 'arcadia-studio.exe'), 'sha256': sha(binary), 'bytes': binary.stat().st_size, 'artifact': artifacts[0]}
|
||||
write(name + '-result.json', receipt)
|
||||
print(json.dumps(receipt), flush=True)
|
||||
if result.returncode or not receipt['inputsUnchanged']:
|
||||
raise SystemExit(result.returncode or 1)
|
||||
write('complete.json', {'atUtc': now(), 'inputsUnchanged': verify(), 'gates': [name for name, _ in gates], 'scope': 'Windows headless tests/lint/timing/build; no native acceptance'})
|
||||
@@ -0,0 +1,79 @@
|
||||
"""Launch a gate-bound development GUI in a fresh private profile; retain child."""
|
||||
from pathlib import Path
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
BASE = Path(__file__).resolve().parent
|
||||
|
||||
def now():
|
||||
return datetime.now(timezone.utc).isoformat()
|
||||
|
||||
def identity(path):
|
||||
raw = path.read_bytes()
|
||||
return {'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()}
|
||||
|
||||
manifest_path, manifest_hash, label = sys.argv[1:]
|
||||
manifest_path = Path(manifest_path)
|
||||
assert manifest_path.is_absolute() and identity(manifest_path)['sha256'] == manifest_hash
|
||||
manifest = json.loads(manifest_path.read_text(encoding='utf-8'))
|
||||
assert manifest['nativeReady'] is True and re.fullmatch('trial-text-[0-9]+', label)
|
||||
assert manifest['target'] == 'x86_64-pc-windows-gnullvm'
|
||||
for item in [manifest['binary'], *manifest['evidence']]:
|
||||
path = Path(item['path'])
|
||||
assert path.is_absolute() and identity(path) == {key: item[key] for key in ['bytes', 'sha256']}
|
||||
dll = BASE / 'runtime/libunwind.dll'
|
||||
assert identity(dll)['sha256'] == 'f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4'
|
||||
trial = BASE / label
|
||||
trial.mkdir()
|
||||
for name in ['bin', 'profile/roaming', 'profile/local', 'profile/Desktop', 'tmp', 'cwd', 'screenshots']:
|
||||
(trial / name).mkdir(parents=True, exist_ok=True)
|
||||
executable = trial / 'bin/arcadia-studio.exe'
|
||||
shutil.copyfile(manifest['binary']['path'], executable)
|
||||
shutil.copyfile(dll, trial / 'bin/libunwind.dll')
|
||||
assert identity(executable) == {key: manifest['binary'][key] for key in ['bytes', 'sha256']}
|
||||
assert identity(dll) == identity(trial / 'bin/libunwind.dll')
|
||||
shutil.copyfile(manifest_path, trial / 'launch-manifest.json')
|
||||
|
||||
def record(name, value):
|
||||
with (trial / name).open('x', encoding='utf-8', newline='\n') as output:
|
||||
json.dump(value, output, indent=2)
|
||||
output.write('\n')
|
||||
|
||||
inherited = {key.upper(): value for key, value in os.environ.items()}
|
||||
env = {key: inherited[key.upper()] for key in ['SystemRoot', 'SystemDrive', 'ProgramData', 'ALLUSERSPROFILE', 'PUBLIC']}
|
||||
system = env['SystemRoot']
|
||||
env.update({'WINDIR': system, 'PATH': system + '\\System32;' + system,
|
||||
'USERPROFILE': str(trial / 'profile'), 'APPDATA': str(trial / 'profile/roaming'),
|
||||
'LOCALAPPDATA': str(trial / 'profile/local'),
|
||||
'TEMP': str(trial / 'tmp'), 'TMP': str(trial / 'tmp')})
|
||||
with (trial / 'stdout.log').open('xb') as out, (trial / 'stderr.log').open('xb') as err:
|
||||
start = now()
|
||||
child = subprocess.Popen([str(executable)], cwd=trial / 'cwd', env=env, stdout=out, stderr=err,
|
||||
creationflags=subprocess.CREATE_NO_WINDOW)
|
||||
receipt_error = None
|
||||
try:
|
||||
receipt = {'started': start, 'pid': child.pid, 'executable': str(executable),
|
||||
'binary': identity(executable), 'environment': env, 'cwd': str(trial / 'cwd'),
|
||||
'manifestSha256': manifest_hash, 'helper': identity(Path(__file__)),
|
||||
'scope': 'Development GUI launch, not packaged release acceptance.'}
|
||||
record('launch.json', receipt)
|
||||
print(json.dumps(receipt), flush=True)
|
||||
except Exception as error:
|
||||
receipt_error = repr(error)
|
||||
finally:
|
||||
code = child.wait()
|
||||
finished = now()
|
||||
closure = {'finished': finished, 'pid': child.pid, 'exitCode': code,
|
||||
'stdout': identity(trial / 'stdout.log'), 'stderr': identity(trial / 'stderr.log'),
|
||||
'binaryUnchanged': identity(executable) == {key: manifest['binary'][key] for key in ['bytes', 'sha256']},
|
||||
'dllUnchanged': identity(dll) == identity(trial / 'bin/libunwind.dll'),
|
||||
'launchReceiptError': receipt_error}
|
||||
record('closed.json', closure)
|
||||
print(json.dumps(closure), flush=True)
|
||||
sys.exit(0 if code == 0 and receipt_error is None and closure['binaryUnchanged'] and closure['dllUnchanged'] else 1)
|
||||
@@ -0,0 +1,80 @@
|
||||
"""Read-only full saved-model/source and physical-byte comparison after a GUI step."""
|
||||
from datetime import datetime, timezone
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
BASE = Path(__file__).resolve().parent
|
||||
ROOT = BASE.parents[1]
|
||||
trial, case, expected, step = sys.argv[1:]
|
||||
if not re.fullmatch(r'trial-text-[0-9]+', trial):
|
||||
raise RuntimeError('Invalid trial')
|
||||
if case not in ['simple', 'representative'] or expected not in ['baseline', 'expected']:
|
||||
raise RuntimeError('Invalid fixture or expectation')
|
||||
if not re.fullmatch(r'[a-z0-9-]+', step):
|
||||
raise RuntimeError('Invalid step')
|
||||
TRIAL = BASE / trial
|
||||
launch = json.loads((TRIAL / 'launch.json').read_text(encoding='utf-8'))
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
def inventory(folder):
|
||||
return {p.relative_to(folder).as_posix(): {'sha256': sha(p), 'bytes': p.stat().st_size}
|
||||
for p in sorted(folder.rglob('*')) if p.is_file()}
|
||||
|
||||
def now():
|
||||
return datetime.now(timezone.utc).isoformat()
|
||||
|
||||
manifest_path = BASE / 'fixture-manifest.json'
|
||||
if sha(manifest_path) != 'a25651305b23da985eb6d8c637a687a0c4261b5a8c0d8ef84dda95a51fbed931':
|
||||
raise RuntimeError('Authored fixture manifest changed')
|
||||
manifest = json.loads(manifest_path.read_text(encoding='utf-8'))
|
||||
for label, record in manifest['cases'].items():
|
||||
for variant, key in [('baseline', 'original_files'), ('expected', 'expected_files')]:
|
||||
if inventory(BASE / label / variant) != record[key]:
|
||||
raise RuntimeError('Authored expectation changed')
|
||||
oracle = ROOT / '.local/staged-source-oracle-20260911/staged-source-authoring-contract.exe'
|
||||
dll = BASE / 'runtime/libunwind.dll'
|
||||
if sha(oracle) != manifest['oracle_sha256'] or sha(dll) != manifest['dll_sha256']:
|
||||
raise RuntimeError('Oracle or DLL changed')
|
||||
if sha(Path(launch['executable'])) != launch['binary']['sha256']:
|
||||
raise RuntimeError('Native executable changed')
|
||||
|
||||
destination = TRIAL / ('verification-' + case + '-' + step)
|
||||
destination.mkdir()
|
||||
actual = BASE / case / 'work'
|
||||
before = inventory(actual)
|
||||
expectation = manifest['cases'][case]['original_files' if expected == 'baseline' else 'expected_files']
|
||||
system = os.environ['SystemRoot']
|
||||
env = {'SystemRoot': system, 'SystemDrive': os.environ['SystemDrive'], 'WINDIR': system,
|
||||
'PATH': str(dll.parent) + ';' + system + '\\System32;' + system, 'RUST_BACKTRACE': '0'}
|
||||
command = [str(oracle), 'same', str(BASE / case / expected / 'project.arcadia'), str(actual / 'project.arcadia')]
|
||||
started, timer = now(), time.perf_counter()
|
||||
failure = None
|
||||
code = None
|
||||
with (destination / 'stdout.log').open('xb') as out, (destination / 'stderr.log').open('xb') as err:
|
||||
try:
|
||||
result = subprocess.run(command, cwd=BASE, env=env, stdout=out, stderr=err, timeout=55)
|
||||
code = result.returncode
|
||||
except (subprocess.TimeoutExpired, OSError) as error:
|
||||
failure = {'type': type(error).__name__, 'message': str(error)}
|
||||
after = inventory(actual)
|
||||
receipt = {'startedUtc': started, 'finishedUtc': now(), 'seconds': time.perf_counter() - timer,
|
||||
'command': command, 'environment': env, 'exitCode': code, 'failure': failure,
|
||||
'scope': 'Saved disk state only; does not inspect the live unsaved GUI model.',
|
||||
'binarySha256': launch['binary']['sha256'], 'oracleSha256': sha(oracle), 'dllSha256': sha(dll),
|
||||
'expectedVariant': expected, 'actualFiles': after, 'physicalBytesMatch': before == expectation,
|
||||
'actualUnchangedByOracle': before == after,
|
||||
'stdoutSha256': sha(destination / 'stdout.log'), 'stderrSha256': sha(destination / 'stderr.log')}
|
||||
receipt['passed'] = code == 0 and failure is None and before == expectation and after == before
|
||||
(destination / 'result.json').write_text(json.dumps(receipt, indent=2) + '\n', encoding='utf-8')
|
||||
print(json.dumps({'passed': receipt['passed'], 'receipt': str(destination / 'result.json'),
|
||||
'stdout': (destination / 'stdout.log').read_text(encoding='utf-8', errors='replace')}), flush=True)
|
||||
if not receipt['passed']:
|
||||
raise SystemExit(1)
|
||||
Reference in New Issue
Block a user