Verify compact Process removal workflow and record failure boundary
This commit is contained in:
@@ -112,8 +112,11 @@ and explicit coverage limits; default-branch integration remains separate.
|
||||
|
||||
The [Process removal policy](process-group-removal-policy-20260925.md) defines
|
||||
local occurrence/link admission, cascade normalization, implicit-order and
|
||||
caller consequences, and captured one-step removal. It is a development policy;
|
||||
its existence does not establish App, native or integration acceptance.
|
||||
caller consequences, and captured one-step removal. Its
|
||||
[Windows App/native evidence](process-group-removal-app-20260925.md) and
|
||||
[compact review follow-up](process-removal-compact-20260925.md) identify the
|
||||
tested source and bounded acceptance. Default-branch integration remains open;
|
||||
the policy alone does not establish implementation or runtime acceptance.
|
||||
|
||||
## Acceptance and dependencies
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Process aggregate removal — App implementation and verification, 2026-09-25 UTC
|
||||
|
||||
Local-only contribution for issue 29. Source `572e96ba03522cfb822b13fe4abb50e857a5de48` builds and runs on Windows. Process/FunctionalChain aggregate removal has source review, filtered regression checks and a native OA model/source/history/reopen receipt. Compact-window acceptance remains open. No integration, release or remote publication is claimed.
|
||||
Local-only contribution for issue 29. Source `572e96ba03522cfb822b13fe4abb50e857a5de48` builds and runs on Windows. Process/FunctionalChain aggregate removal has source review, filtered regression checks and a native OA model/source/history/reopen receipt. The [compact follow-up](process-removal-compact-20260925.md) additionally verifies the bounded removal review at 1102x732. No integration, release or remote publication is claimed.
|
||||
|
||||
## Behavior and reviewed corrections
|
||||
|
||||
@@ -86,6 +86,6 @@ python -B harness/process-group-removal-evidence-20260925/native/verify.py harne
|
||||
|
||||
## Remaining scope and publication
|
||||
|
||||
This native receipt covers OA derived layout and the bounded fixture. SA/qualified paths, cascades, stale input races and command-failure preservation have separate filtered-test evidence. Actual Process source-budget failure, native Shift-click, compact layout, comprehensive accessibility, full-suite and Linux acceptance are unclaimed. Preserve these limits when integrating; no issue closure is justified by this branch alone.
|
||||
This original native receipt covers OA derived layout and the bounded fixture. SA/qualified paths, cascades, stale input races and command-failure preservation have separate filtered-test evidence. The [follow-up](process-removal-compact-20260925.md) closes the compact review gap for this fixture. Actual Process source-budget failure, native Shift-click, comprehensive accessibility, full-suite and Linux acceptance remain unclaimed. Static investigation found no valid source-growth case for the admitted Process removal; see the [evaluator boundary](process-group-removal-evidence-20260925/source-failure-investigation.md). This is not a formal monotonicity proof or actual Process source-write-failure coverage. Preserve these limits when integrating; no issue closure is justified by this branch alone.
|
||||
|
||||
Fresh guarded push was rejected with `remote unpack failed: unable to create temporary object directory`; a Gitea MCP issue-comment write also failed. Read operations work, main AGENTS remains blob e76647f49913b314e1543c4464f6199533909bae, and the remote contribution branch remains 43340b94. WSL DNS still timed out after ten seconds; Linux builds remain explicitly user-paused. These are observed failed attempts, not a newly verified disk-full root cause. Pending Scenario follow-up and this Process contribution remain local-only. Reconcile and publish the buffered issue-29 handoff when writes recover; do not overwrite remote history. Historical local paths inside copied reviews identify their original context, not peer-accessible deliverables.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Compact Process native follow-up, 2026-09-25 UTC
|
||||
|
||||
Run 3 uses the unchanged Windows Studio executable built from source
|
||||
572e96ba03522cfb822b13fe4abb50e857a5de48. PID 6252; normal Alt+F4 close,
|
||||
exit 0, empty logs and unchanged immutable inputs. Parent Computer Use actions
|
||||
below are observations, not an instrumented input log.
|
||||
|
||||
- Captures 01–16: prepare a fully visible 1102x732 window. Initial window was
|
||||
partly off-screen. Title-bar movement and edge dragging were unreliable;
|
||||
one edge attempt scrolled the Home view. Native System menu > Size, Right,
|
||||
pointer placement at x1100 set width; Size, Down, placement at y730 set height.
|
||||
Failed eval-based helper loading was rejected before execution; capture
|
||||
function was then defined directly. These are automation/setup limitations.
|
||||
- 17–26: native Open picker for this run's working.arcadia. UIA set_value failed
|
||||
(property absent from CacheRequest), then fresh observation, file-name click
|
||||
and literal typing entered the path. UIA Open click did not close the picker;
|
||||
reobservation plus Return loaded the correct model. The accessibility focus
|
||||
field said Search Box while the visible caret/text were in File name. No
|
||||
model data was typed into another editor or external destination.
|
||||
- 27–34: select Assessment, Behavior, Fit (59%), then select Action @a and use
|
||||
context Add on Control @c and SequenceLink @approved. Count 3, link primary.
|
||||
Native Shift-click is not claimed. Canvas palette uses narrow abbreviations;
|
||||
full canvas/palette accessibility and compact authoring are outside this test.
|
||||
- 35: header review at 1102x732, title, 3 removed/1 updated, 10 effects, search,
|
||||
paging, fixed Cancel and explicit Remove all visible.
|
||||
- 36: scroll page 1 to the explicit-before / implicit-after order rows; footer
|
||||
remains visible. 37: page 2 displays @e1 then @e2 and full direct @caller and
|
||||
transitive @outer names/aliases, without clipping the confirmation controls.
|
||||
- 38–40: search @outer finds one caller; append -missing gives zero results
|
||||
with recovery guidance. The review remains open and footer stays reachable.
|
||||
- 41–42: Cancel preserves count 3 and @approved primary; Save all, exact
|
||||
compact-cancelled snapshot equals all 2609 baseline bytes.
|
||||
- 43–45: fresh header review resets search; explicit Remove succeeds, group
|
||||
clears, owner selected, two exchange cards connected implicitly. Save all;
|
||||
compact-removed snapshot equals all 2258 independent v2 oracle bytes.
|
||||
- 46–47: one Ctrl+Z restores all four cards/authored link. Save all;
|
||||
compact-undo snapshot equals all 2609 baseline bytes. Then Alt+F4; supervisor
|
||||
confirms normal closure. No additional Redo/reopen claim from this run;
|
||||
original runs 1–2 retain that evidence separately.
|
||||
|
||||
Scope: OA derived Process and this fixture's compact removal review. This is
|
||||
not SA native acceptance, full keyboard-only navigation, native Shift-click,
|
||||
comprehensive accessibility, a full-suite rerun or a release. No production
|
||||
source changed and no Linux build/check ran.
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,300 @@
|
||||
"""Offline archive/source/receipt checks. Never executes archived helpers or native binaries."""
|
||||
from pathlib import Path, PurePosixPath, PureWindowsPath
|
||||
import argparse
|
||||
import datetime
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import zipfile
|
||||
|
||||
KIND = 'process-aggregate-removal-native-evidence'
|
||||
PHASES = {'baseline': 'baseline.arcadia', 'removed': 'expected-removed.arcadia'}
|
||||
V2 = 'process-removal-v2-preserved-trivia'
|
||||
|
||||
|
||||
def pin(data):
|
||||
return {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
|
||||
|
||||
|
||||
def safe_name(name):
|
||||
p = PurePosixPath(name)
|
||||
assert name and not p.is_absolute() and str(p) == name, 'Unsafe member: ' + name
|
||||
assert '\\' not in name and ':' not in name and not any(x in ('.', '..', '') for x in name.split('/')), 'Unsafe member: ' + name
|
||||
|
||||
|
||||
def check_oracles(files, fixture, prefix='fixtures/'):
|
||||
revision = fixture['fixture_revision']
|
||||
assert revision in ('process-removal-v1-literal', V2)
|
||||
assert fixture['selection'] == fixture['removed'] == ['a', 'c', 'approved']
|
||||
assert fixture['changed'] == ['assessment']
|
||||
assert fixture['caller_definitions'] == ['caller', 'outer']
|
||||
assert fixture['remaining_implicit_order'] == ['e1', 'e2']
|
||||
assert set(fixture['files']) == set(PHASES.values()), 'Wrong fixture inventory'
|
||||
for name, expected in fixture['files'].items():
|
||||
assert pin(files[prefix + name]) == expected, 'Fixture pin mismatch: ' + name
|
||||
baseline = files[prefix + 'baseline.arcadia']
|
||||
assert pin(baseline) == {'bytes': 2609, 'sha256': '9965f4024584d64ac81442724aeb77b018b0cfae94e50bd412c5dcbbac49f6bf'}
|
||||
actual = files[prefix + 'expected-removed.arcadia']
|
||||
if revision != V2:
|
||||
# Preserve the original incorrect oracle as history, never acceptance.
|
||||
assert pin(actual) == {'bytes': 2186, 'sha256': '117b550f0c10753f53febb3ca6beb2c8088688ffa707f21eac654573e4a3d29c'}
|
||||
return
|
||||
text = baseline.decode('utf-8')
|
||||
assert '\r' not in text
|
||||
pattern = r'(?m)^ (?:oa_occurrence (?:a|c) |sequence_link approved )[^\n]*'
|
||||
# Independent fixture-specific lexical rules; never execute archived code.
|
||||
def trivia(line):
|
||||
return re.sub(r'\S', '', re.sub(r'"(?:\\.|[^"\\])*"', '', line))
|
||||
rows = re.findall(pattern, text)
|
||||
assert [trivia(row) for row in rows] == [' ' * 22, ' ' * 20, ' ' * 16]
|
||||
expected = re.sub(pattern, lambda m: '\n\n' + trivia(m.group()) + '\n\n', text)
|
||||
assert expected.count('steps [@a,@e1,@c,@e2]') == 1
|
||||
expected = expected.replace('steps [@a,@e1,@c,@e2]', 'steps [@e1,@e2]')
|
||||
assert actual == expected.encode('utf-8'), 'V2 differs from independently specified delta'
|
||||
assert pin(actual) == {'bytes': 2258, 'sha256': 'b4a2b07ad4c796f555c61945ca42b1c221b454b35488c60fefc86f96f7aa71ba'}
|
||||
|
||||
|
||||
def check_source(files, actual, phase, prefix='fixtures/'):
|
||||
assert phase in PHASES, 'Unknown source phase'
|
||||
assert actual == files[prefix + PHASES[phase]], 'Exact full source differs from ' + phase
|
||||
|
||||
|
||||
def verify(root):
|
||||
manifest = json.loads((root / 'manifest.json').read_text(encoding='utf-8'))
|
||||
assert manifest['kind'] == KIND, 'Wrong package kind'
|
||||
assert pin((root / 'native-evidence.zip').read_bytes()) == manifest['archive'], 'Archive pin mismatch'
|
||||
with zipfile.ZipFile(root / 'native-evidence.zip') as archive:
|
||||
names = archive.namelist()
|
||||
assert len(names) == len(set(names)) and set(names) == set(manifest['members']), 'Archive member inventory mismatch'
|
||||
for name in names:
|
||||
safe_name(name)
|
||||
assert ((archive.getinfo(name).external_attr >> 16) & 0o170000) != 0o120000, 'Symlink member'
|
||||
files = {name: archive.read(name) for name in names}
|
||||
for name, data in files.items():
|
||||
assert pin(data) == manifest['members'][name], 'Member pin mismatch: ' + name
|
||||
assert PurePosixPath(name).suffix.lower() not in ('.exe', '.dll'), 'Unexpected archived binary'
|
||||
for name in manifest['excluded_binary_bytes']:
|
||||
safe_name(name)
|
||||
assert name not in files and PurePosixPath(name).suffix.lower() in ('.exe', '.dll'), 'Invalid omitted binary entry'
|
||||
assert (root / 'verify.py').read_bytes() == files['helpers/native-evidence-verify.py'], 'External verifier differs from pinned helper'
|
||||
|
||||
def js(name):
|
||||
return json.loads(files[name].decode('utf-8-sig'))
|
||||
|
||||
def present_pin(name):
|
||||
return pin(files[name]) if name in files else manifest['excluded_binary_bytes'].get(name)
|
||||
|
||||
def build_binding(prefix, source):
|
||||
receipt = js(prefix + 'result.json')
|
||||
proof = js(prefix + 'source-proof.json')
|
||||
inputs = js(prefix + 'inputs.json')
|
||||
assert receipt['exitCode'] == 0 and receipt['inputsUnchanged'] is True, 'Build not successful/unchanged'
|
||||
assert proof['status'].startswith('PASS') and proof['result'] == pin(files[prefix + 'result.json']), 'Build proof result binding'
|
||||
assert proof['inputMap'] == receipt['inputs'] == pin(files[prefix + 'inputs.json']), 'Build input-map binding'
|
||||
assert proof['inputCount'] == receipt['inputCount'] == len(inputs), 'Build input count'
|
||||
assert proof['commit'] == receipt['head'] == source and re.fullmatch('[0-9a-f]{40}', source), 'Build source identity'
|
||||
return receipt
|
||||
|
||||
fixture = js('fixtures/fixture-manifest.json')
|
||||
check_oracles(files, fixture)
|
||||
for name in files:
|
||||
if name.startswith('oracle-revisions/') and name.endswith('/fixture-manifest.json'):
|
||||
check_oracles(files, js(name), name.removesuffix('fixture-manifest.json'))
|
||||
derivation = 'oracle-revisions/oracle-v2/derive-source-oracle-v2.ps1'
|
||||
assert pin(files[derivation]) == js('oracle-revisions/oracle-v2/fixture-manifest.json')['derivation']
|
||||
config = js('review-config.json')
|
||||
final_source = config['final_source']
|
||||
assert re.fullmatch('[0-9a-f]{40}', final_source)
|
||||
assert config['runs'] == manifest['runs'] and config['preflights'] == manifest['preflights']
|
||||
for entries, prefix, pattern in [(config['runs'], 'runs', r'run-[0-9]+'), (config['preflights'], 'preflight', r'fixture-preflight-[0-9]+')]:
|
||||
assert entries and len({x['name'] for x in entries}) == len(entries)
|
||||
assert all(re.fullmatch(pattern, x['name']) and type(x['accepted']) is bool for x in entries)
|
||||
assert {name.split('/')[1] for name in files if name.startswith(prefix + '/')} == {x['name'] for x in entries}, 'Undeclared archived attempts'
|
||||
|
||||
gates = config['gates']
|
||||
assert len(gates) == len(set(gates)) and {'process-removal-tests-1', 'process-removal-tests-2'} <= set(gates)
|
||||
assert all(re.fullmatch(r'process-removal-(?:tests|format|clippy|build)-[0-9]+', g) for g in gates)
|
||||
assert {n.split('/')[1] for n in files if n.startswith('gates/')} == set(gates)
|
||||
gate_reports = []
|
||||
for gate in gates:
|
||||
prefix = 'gates/' + gate + '/'
|
||||
result, proof, inputs = (js(prefix + f) for f in ('result.json', 'source-proof.json', 'inputs.json'))
|
||||
assert result['inputsUnchanged'] is True and 'finish' in result
|
||||
assert proof['status'].startswith('PASS') and proof['result'] == pin(files[prefix + 'result.json'])
|
||||
assert proof['inputMap'] == result['inputs'] == pin(files[prefix + 'inputs.json'])
|
||||
assert proof['inputCount'] == result['inputCount'] == len(inputs)
|
||||
assert proof['commit'] == result['head'] and re.fullmatch('[0-9a-f]{40}', result['head'])
|
||||
for stream in ('stdout', 'stderr'):
|
||||
assert result[stream] == pin(files[prefix + stream + '.log'])
|
||||
gate_reports.append({'gate': gate, 'source': result['head'], 'exitCode': result['exitCode']})
|
||||
# The original failed gates must remain failed historical facts.
|
||||
for gate, source in [('process-removal-tests-1', 'fe637dcd277b17653139ffa234e601b29775c565'),
|
||||
('process-removal-tests-2', 'f20497b29bf637619bc35ffe41274fc0f66c387b')]:
|
||||
receipt = js('gates/' + gate + '/result.json')
|
||||
assert receipt['head'] == source and receipt['exitCode'] == 101
|
||||
|
||||
reports, preflights = [], []
|
||||
accepted_cli_bindings = set()
|
||||
for entry in config['preflights']:
|
||||
prefix = 'preflight/' + entry['name'] + '/'
|
||||
problems = []
|
||||
try:
|
||||
current = js(prefix + 'result.json')
|
||||
started = js(prefix + 'started.json')
|
||||
fixture_name = prefix + 'evidence/fixture-manifest.json'
|
||||
current_fixture = js(fixture_name)
|
||||
check_oracles(files, current_fixture, prefix + 'fixtures/')
|
||||
revision = current_fixture.get('fixture_revision', 'removal-v1-source-derived')
|
||||
if 'fixture_revision' in current:
|
||||
assert current['fixture_revision'] == revision and current['fixture_manifest'] == pin(files[fixture_name]), 'Preflight fixture revision binding'
|
||||
assert current['fixture_comparator'] == pin(files[prefix + 'evidence/verify-captured.py']), 'Preflight comparator pin'
|
||||
assert started['checks'] == [] and all(current[key] == started[key] for key in started if key != 'checks'), 'Preflight started/result changed identity'
|
||||
assert current['status'].startswith('PASS') and current['cliUnchanged'] is True, 'Preflight not passed'
|
||||
receipt = build_binding(prefix + 'evidence/', current['source'])
|
||||
assert current['receipt'] == pin(files[prefix + 'evidence/result.json']) and current['proof'] == pin(files[prefix + 'evidence/source-proof.json']), 'Preflight proof pins'
|
||||
cli = [a for a in receipt['artifacts'] if a['cargo']['target']['name'] == 'arcadia' and not a['cargo']['profile']['test']]
|
||||
assert len(cli) == 1 and cli[0]['readback'] == current['cli'] == present_pin(prefix + 'bin/arcadia.exe'), 'CLI artifact binding'
|
||||
assert len(current['checks']) == len(PHASES) and {x['fixture'] for x in current['checks']} == set(PHASES.values()), 'Incomplete fixture preflight'
|
||||
for check in current['checks']:
|
||||
name = check['fixture']
|
||||
assert check['exitCode'] == 0 and check['json_report'] is True and check['fixtureUnchanged'] is True, 'Fixture check failed: ' + name
|
||||
assert check['stdout'] == pin(files[prefix + name + '.stdout.json']) and check['stderr'] == pin(files[prefix + name + '.stderr.log']), 'CLI output pins'
|
||||
assert pin(files[prefix + 'fixtures/' + name]) == current_fixture['files'][name], 'Preflight fixture differs'
|
||||
raw = js(prefix + name + '.stdout.json')
|
||||
assert raw['operation'] == 'check' and raw['exit_code'] == 0 and raw['written'] is False and not any(x['severity'] == 'error' for x in raw['diagnostics']), 'Raw CLI report rejects fixture'
|
||||
for runtime in current['runtime']:
|
||||
assert present_pin(prefix + 'bin/' + PureWindowsPath(runtime['source']).name) == {k: runtime[k] for k in ('bytes', 'sha256')}, 'CLI runtime pin'
|
||||
except (AssertionError, KeyError, ValueError, TypeError) as error:
|
||||
problems.append(str(error))
|
||||
preflights.append({'preflight': entry['name'], 'reviewer_accepted': entry['accepted'], 'checks_pass': not problems, 'problems': problems})
|
||||
if entry['accepted']:
|
||||
assert current_fixture['fixture_revision'] == V2, 'Historical v1 cannot be accepted'
|
||||
assert current['source'] == final_source, 'Accepted preflight source differs'
|
||||
assert not problems, json.dumps(preflights[-1])
|
||||
accepted_cli_bindings.add((current['source'], pin(files[fixture_name])['sha256']))
|
||||
|
||||
for entry in config['runs']:
|
||||
prefix = 'runs/' + entry['name'] + '/'
|
||||
problems, captures, sources = [], 0, []
|
||||
# Report the actual discovered count even when an earlier historical
|
||||
# source failure prevents the remaining per-run checks from passing.
|
||||
for name in files:
|
||||
if name.startswith(prefix) and name.endswith('.json'):
|
||||
try:
|
||||
record = js(name)
|
||||
captures += int(isinstance(record, dict) and 'images' in record)
|
||||
except (ValueError, UnicodeError):
|
||||
pass
|
||||
try:
|
||||
prepared, started, finished = (js(prefix + name + '.json') for name in ('prepared', 'started', 'finished'))
|
||||
fixture_name = prefix + 'evidence/fixture-manifest.json'
|
||||
run_fixture = js(fixture_name)
|
||||
check_oracles(files, run_fixture, prefix + 'evidence/')
|
||||
revision = run_fixture.get('fixture_revision', 'removal-v1-source-derived')
|
||||
if 'fixture_revision' in prepared:
|
||||
assert prepared['fixture_revision'] == revision and prepared['fixture_manifest'] == pin(files[fixture_name]), 'Run fixture revision binding'
|
||||
assert started['prepared'] == pin(files[prefix + 'prepared.json']), 'Started/prepared binding'
|
||||
for rel, expected in prepared['immutable'].items():
|
||||
safe_name(rel)
|
||||
assert present_pin(prefix + rel) == expected, 'Immutable pin: ' + rel
|
||||
assert prepared['helper'] == pin(files[prefix + 'evidence/native-harness.py']), 'Native helper binding'
|
||||
for helper in ('capture.js', 'verify-captured.py'):
|
||||
rel = 'evidence/' + helper
|
||||
assert prepared['immutable'].get(rel) == pin(files[prefix + rel]), 'Captured observation/source helper is not immutable: ' + helper
|
||||
for name in [*run_fixture['files'], 'fixture-manifest.json']:
|
||||
assert prepared['immutable'].get('evidence/' + name) == pin(files[prefix + 'evidence/' + name]), 'Run oracle is not immutable: ' + name
|
||||
receipt = build_binding(prefix + 'evidence/', prepared['source'])
|
||||
gui = [a for a in receipt['artifacts'] if a['cargo']['target']['name'] == 'arcadia-studio' and not a['cargo']['profile']['test']]
|
||||
assert len(gui) == 1 and gui[0]['readback'] == prepared['artifact'] == present_pin(prefix + 'bin/arcadia-studio.exe'), 'GUI artifact binding'
|
||||
for runtime in prepared['runtime_sources']:
|
||||
assert present_pin(prefix + 'bin/' + PureWindowsPath(runtime['path']).name) == {k: runtime[k] for k in ('bytes', 'sha256')}, 'GUI runtime pin'
|
||||
assert started['command'] == prepared['command'] and started['cwd'] == prepared['cwd'], 'Launch command/cwd changed'
|
||||
identity = started['identity']
|
||||
assert identity['pid'] == started['pid'] and identity['created_filetime'] > 0 and identity['running'] is True, 'Missing initial live process identity'
|
||||
assert PureWindowsPath(identity['image']) == PureWindowsPath(prepared['command'][0]), 'Wrong process image'
|
||||
assert finished['exitCode'] == 0 and finished['immutableUnchanged'] is True, 'Normal exit/immutability not established'
|
||||
for stream in ('stdout', 'stderr'):
|
||||
assert finished[stream] == pin(files[prefix + 'app.' + stream + '.log']), 'Final log binding'
|
||||
assert finished['working'] == pin(files[prefix + 'working.arcadia']), 'Final source binding'
|
||||
assert prepared.get('initial_pin', started['workingBefore']) == started['workingBefore'], 'Initial source pin changed'
|
||||
origin = entry.get('reopen_from')
|
||||
if prefix + 'reopen-origin.json' in files:
|
||||
old = js(prefix + 'reopen-origin.json')
|
||||
declared = {'run': old['from_run'], 'file': old['from_file']}
|
||||
assert origin is None or origin == declared, 'Contradictory reopen origins'
|
||||
origin = declared
|
||||
assert old['from_pin'] == old['copied_pin'] == started['workingBefore'], 'Reopen-origin pins disagree'
|
||||
if origin:
|
||||
assert origin['run'] != entry['name'] and origin['run'] in {x['name'] for x in config['runs']}, 'Unknown/self reopen origin'
|
||||
safe_name(origin['file'])
|
||||
assert pin(files['runs/' + origin['run'] + '/' + origin['file']]) == started['workingBefore'], 'Reopen source is not the exact captured copy'
|
||||
else:
|
||||
assert started['workingBefore'] == run_fixture['files']['baseline.arcadia'], 'Nonbaseline start needs explicit reopen_from'
|
||||
phases = entry.get('source_phases', {})
|
||||
actual_sources = [name for name in files if name.startswith(prefix) and name.endswith('.arcadia') and '/evidence/' not in name and name != prefix + 'baseline.arcadia']
|
||||
assert set(phases) <= {name[len(prefix):] for name in actual_sources}, 'Phase config references missing source'
|
||||
for name in actual_sources:
|
||||
rel = name[len(prefix):]
|
||||
sidecar = name[:-8] + '.json'
|
||||
phase = phases.get(rel)
|
||||
if sidecar in files and 'phase' in js(sidecar):
|
||||
saved = js(sidecar)
|
||||
assert phase is None or phase == saved['phase'], 'Contradictory snapshot phase'
|
||||
phase = saved['phase']
|
||||
assert saved['pin'] == pin(files[name]) and saved['exitCode'] == 0, 'Snapshot check/pin failed'
|
||||
evaluated = js(name[:-8] + '.evaluator.stdout.json')
|
||||
assert evaluated['status'] == 'PASS' and evaluated['phase'] == phase and evaluated['sha256'] == pin(files[name])['sha256'], 'Raw source evaluator report mismatch'
|
||||
assert not files[name[:-8] + '.evaluator.stderr.log'], 'Source evaluator stderr is nonempty'
|
||||
check_source(files, files[name], phase, prefix + 'evidence/')
|
||||
sources.append({'file': rel, 'phase': phase})
|
||||
start_time = datetime.datetime.fromisoformat(started['started'])
|
||||
finish_time = datetime.datetime.fromisoformat(finished['finished'])
|
||||
assert start_time <= finish_time, 'Reversed process lifetime'
|
||||
for name in files:
|
||||
if not name.startswith(prefix) or not name.endswith('.json'):
|
||||
continue
|
||||
record = js(name)
|
||||
if not isinstance(record, dict) or 'images' not in record:
|
||||
continue
|
||||
assert record['images'], 'Empty capture record'
|
||||
assert record['window']['app'].casefold() == ('process:' + identity['image']).casefold(), 'Capture uses a different executable surface'
|
||||
observed = datetime.datetime.fromisoformat(record['time'])
|
||||
assert start_time <= observed <= finish_time, 'Capture is outside process lifetime'
|
||||
for image in record['images']:
|
||||
safe_name(image['file'])
|
||||
assert prefix + image['file'] in files and image['width'] > 0 and image['height'] > 0, 'Missing/invalid capture image'
|
||||
assert captures > 0, 'No captured native observations'
|
||||
if entry['accepted']:
|
||||
assert run_fixture['fixture_revision'] == V2, 'Historical v1 cannot be accepted'
|
||||
assert prepared['source'] == final_source, 'Accepted native source differs'
|
||||
assert (prepared['source'], pin(files[fixture_name])['sha256']) in accepted_cli_bindings, 'No accepted current-source/current-oracle CLI fixture preflight'
|
||||
except (AssertionError, KeyError, ValueError, TypeError) as error:
|
||||
problems.append(str(error))
|
||||
reports.append({'run': entry['name'], 'reviewer_accepted': entry['accepted'], 'checks_pass': not problems, 'problems': problems, 'capture_records': captures, 'source_checks': sources})
|
||||
if entry['accepted']:
|
||||
assert not problems, json.dumps(reports[-1], indent=2)
|
||||
return {
|
||||
'status': 'PASS offline archive, exact source and receipt consistency checks',
|
||||
'gates': gate_reports,
|
||||
'runs': reports,
|
||||
'preflights': preflights,
|
||||
'accepted_run_count': sum(entry['accepted'] for entry in config['runs']),
|
||||
'limitations': [
|
||||
'Human visual, keyboard, selection and interaction claims are not inferred from screenshots.',
|
||||
'Omitted executable/DLL bytes cannot be rehashed offline.',
|
||||
'Build proof/input map consistency checked; Git blobs are not independently available offline.',
|
||||
'accepted=false failures are retained and reported, never silently promoted.',
|
||||
'No native history-depth introspection, usability acceptance, release or publication assertion.',
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('directory', type=Path)
|
||||
args = parser.parse_args()
|
||||
print(json.dumps(verify(args.directory.resolve()), indent=2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,235 @@
|
||||
{
|
||||
"status": "PASS",
|
||||
"audited_at": "2026-09-25T04:10:10.690609+00:00",
|
||||
"scope": "Independent exhaustive byte-level original/member mapping, recursive run/preflight/gate inventories, omitted local executable/DLL pins, historical preservation and report review; no GUI/Cargo/Git/Gitea/source mutation",
|
||||
"archive": {
|
||||
"bytes": 9190152,
|
||||
"sha256": "02ef32920cb76e12da8b2e41cdecd0d5eea5526371df6425462195c30b564250"
|
||||
},
|
||||
"manifest": {
|
||||
"bytes": 77836,
|
||||
"sha256": "e4b02304f6f7d4113e4799b6c96d6a5a6d663cde0b32a472d7b31d8a19ca8a75"
|
||||
},
|
||||
"members": 461,
|
||||
"mapped_original_files": 460,
|
||||
"normalized_config": 1,
|
||||
"member_groups": {
|
||||
"fixtures": 3,
|
||||
"gates": 70,
|
||||
"helpers": 13,
|
||||
"oracle-revisions": 5,
|
||||
"preflight": 15,
|
||||
"preparation": 7,
|
||||
"review-config.json": 1,
|
||||
"review-notes": 8,
|
||||
"runs": 339
|
||||
},
|
||||
"attempts": {
|
||||
"run-1": {
|
||||
"archived_files": 156,
|
||||
"excluded_binaries": 2,
|
||||
"capture_records": 43
|
||||
},
|
||||
"run-2": {
|
||||
"archived_files": 52,
|
||||
"excluded_binaries": 2,
|
||||
"capture_records": 10
|
||||
},
|
||||
"run-3": {
|
||||
"archived_files": 131,
|
||||
"excluded_binaries": 2,
|
||||
"capture_records": 46
|
||||
},
|
||||
"fixture-preflight-1": {
|
||||
"archived_files": 15,
|
||||
"excluded_binaries": 2,
|
||||
"capture_records": 0
|
||||
}
|
||||
},
|
||||
"omitted_binaries_rehashed": 8,
|
||||
"historical_preservation": {
|
||||
"old_archive_pin_matches_prior_audit": true,
|
||||
"old_members": 327,
|
||||
"identical_members": 326,
|
||||
"changed_members": [
|
||||
"review-config.json"
|
||||
],
|
||||
"missing_members": [],
|
||||
"explanation": "Only normalized top-level review-config.json extends accepted runs with run-3; original per-run config, bytes, old package and failures are retained."
|
||||
},
|
||||
"errors": [],
|
||||
"standalone_verifier": {
|
||||
"command": [
|
||||
"C:\\Users\\User\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe",
|
||||
"-B",
|
||||
"C:\\ar-scenario-9e8r6t\\harness\\process-group-removal-evidence-20260925\\compact-native\\verify.py",
|
||||
"C:\\ar-scenario-9e8r6t\\harness\\process-group-removal-evidence-20260925\\compact-native"
|
||||
],
|
||||
"exit_code": 0,
|
||||
"stderr": "",
|
||||
"result": {
|
||||
"status": "PASS offline archive, exact source and receipt consistency checks",
|
||||
"gates": [
|
||||
{
|
||||
"gate": "process-removal-tests-1",
|
||||
"source": "fe637dcd277b17653139ffa234e601b29775c565",
|
||||
"exitCode": 101
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-tests-2",
|
||||
"source": "f20497b29bf637619bc35ffe41274fc0f66c387b",
|
||||
"exitCode": 101
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-tests-3",
|
||||
"source": "d93c0a801249f361d95721fb0fc239a95159af5c",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-tests-4",
|
||||
"source": "572e96ba03522cfb822b13fe4abb50e857a5de48",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-format-1",
|
||||
"source": "fe637dcd277b17653139ffa234e601b29775c565",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-format-2",
|
||||
"source": "f20497b29bf637619bc35ffe41274fc0f66c387b",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-format-3",
|
||||
"source": "572e96ba03522cfb822b13fe4abb50e857a5de48",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-clippy-1",
|
||||
"source": "d93c0a801249f361d95721fb0fc239a95159af5c",
|
||||
"exitCode": 101
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-clippy-2",
|
||||
"source": "572e96ba03522cfb822b13fe4abb50e857a5de48",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"gate": "process-removal-build-1",
|
||||
"source": "572e96ba03522cfb822b13fe4abb50e857a5de48",
|
||||
"exitCode": 0
|
||||
}
|
||||
],
|
||||
"runs": [
|
||||
{
|
||||
"run": "run-1",
|
||||
"reviewer_accepted": true,
|
||||
"checks_pass": true,
|
||||
"problems": [],
|
||||
"capture_records": 43,
|
||||
"source_checks": [
|
||||
{
|
||||
"file": "snapshots/cancelled-baseline.arcadia",
|
||||
"phase": "baseline"
|
||||
},
|
||||
{
|
||||
"file": "snapshots/redo.arcadia",
|
||||
"phase": "removed"
|
||||
},
|
||||
{
|
||||
"file": "snapshots/removed.arcadia",
|
||||
"phase": "removed"
|
||||
},
|
||||
{
|
||||
"file": "snapshots/undo.arcadia",
|
||||
"phase": "baseline"
|
||||
},
|
||||
{
|
||||
"file": "working.arcadia",
|
||||
"phase": "removed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"run": "run-2",
|
||||
"reviewer_accepted": true,
|
||||
"checks_pass": true,
|
||||
"problems": [],
|
||||
"capture_records": 10,
|
||||
"source_checks": [
|
||||
{
|
||||
"file": "snapshots/reopened.arcadia",
|
||||
"phase": "removed"
|
||||
},
|
||||
{
|
||||
"file": "working.arcadia",
|
||||
"phase": "removed"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"run": "run-3",
|
||||
"reviewer_accepted": true,
|
||||
"checks_pass": true,
|
||||
"problems": [],
|
||||
"capture_records": 46,
|
||||
"source_checks": [
|
||||
{
|
||||
"file": "snapshots/compact-cancelled.arcadia",
|
||||
"phase": "baseline"
|
||||
},
|
||||
{
|
||||
"file": "snapshots/compact-removed.arcadia",
|
||||
"phase": "removed"
|
||||
},
|
||||
{
|
||||
"file": "snapshots/compact-undo.arcadia",
|
||||
"phase": "baseline"
|
||||
},
|
||||
{
|
||||
"file": "working.arcadia",
|
||||
"phase": "baseline"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"preflights": [
|
||||
{
|
||||
"preflight": "fixture-preflight-1",
|
||||
"reviewer_accepted": true,
|
||||
"checks_pass": true,
|
||||
"problems": []
|
||||
}
|
||||
],
|
||||
"accepted_run_count": 3,
|
||||
"limitations": [
|
||||
"Human visual, keyboard, selection and interaction claims are not inferred from screenshots.",
|
||||
"Omitted executable/DLL bytes cannot be rehashed offline.",
|
||||
"Build proof/input map consistency checked; Git blobs are not independently available offline.",
|
||||
"accepted=false failures are retained and reported, never silently promoted.",
|
||||
"No native history-depth introspection, usability acceptance, release or publication assertion."
|
||||
]
|
||||
}
|
||||
},
|
||||
"report_review": {
|
||||
"file": "harness/process-removal-compact-20260925.md",
|
||||
"material_overclaims": [],
|
||||
"limits_preserved": [
|
||||
"One OA derived fixture at 1102x732; compact removal review only",
|
||||
"Parent action account distinct from capture/source receipts",
|
||||
"Context Add rather than untested native Shift-click",
|
||||
"General canvas clipping/small labels/abbreviated palette remain",
|
||||
"No keyboard-only/full accessibility/SA-native/full-suite/Linux acceptance",
|
||||
"Redo/reopen evidence comes from original runs1/2",
|
||||
"Static source-budget investigation found no candidate; no actual Process source-write-failure claim",
|
||||
"Local-only, no integration/issue-closure/release claim"
|
||||
],
|
||||
"review_basis": "Direct image review and source/lifecycle checks in compact-review.md; report compared to that review, compact-actions.md and separate static investigation. No new native execution or formal byte-monotonicity proof."
|
||||
},
|
||||
"limits": [
|
||||
"Offline verifier cannot resolve Git blobs or rehash omitted binaries; this audit additionally rehashed locally available omitted binaries.",
|
||||
"Archive consistency does not establish new gesture/usability claims.",
|
||||
"Gate source capsules inputs.zip are intentionally omitted here; receipt pins and original checks package preserve their separate provenance."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
# Independent compact Process review — 2026-09-25 UTC
|
||||
|
||||
Reviewer: `compact_process_review`, bounded evidence review only. No GUI, Cargo,
|
||||
Git, Gitea or production-source mutation. Parent action account is
|
||||
`compact-actions.md`; capture JSON records states, not an instrumented input log.
|
||||
|
||||
**Finding:** no correctness or usability blocker identified for this fixture's
|
||||
OA derived Process aggregate-removal review at 1102×732. This is acceptance of
|
||||
the bounded compact review evidence, not general compact authoring/accessibility.
|
||||
|
||||
## Direct visual inspection
|
||||
|
||||
Viewed actual images 16, 28, 29 and every image 34–47 with `view_image`.
|
||||
|
||||
- 16 establishes the visible compact window. 34 shows 3 selected, both same-name
|
||||
Review gate cards outlined and the authored link selected; the inspector
|
||||
distinguishes primary `@approved`. Selection gestures come from the parent's
|
||||
report, not filenames or screenshot inference.
|
||||
- 35 shows a contained dialog with readable title, 3 removed / 1 updated,
|
||||
separate affected-definition counts, search, page controls and fixed Cancel /
|
||||
explicit Remove controls. The explanation distinguishes local contributions
|
||||
from preserved referenced definitions and warns that complete caller graphs
|
||||
are not computed. Same-name selected cards are distinguished by `@a` / `@c`.
|
||||
- 36 shows the first page scrolled to the explicit-before / implicit-after
|
||||
summaries while both action buttons remain fully visible. The partial line at
|
||||
the scroll viewport's upper edge is normal scrolling, not inaccessible content.
|
||||
- 37 shows page 2 with full `@e1` then `@e2` order entries and both `@caller` and
|
||||
transitive `@outer` names/aliases. Previous is enabled and Next visibly disabled.
|
||||
Search and action buttons remain in place, with no review-specific clipping.
|
||||
- 38 shows the search caret. 39 shows `@outer`, one match and its full affected
|
||||
caller entry. 40 shows `@outer-missing`, zero matches and recovery guidance;
|
||||
the three-selection title/counts remain, clearly separating filtering from the
|
||||
pending operation. Confirmation still represents the entire selected group.
|
||||
- 41 shows cancellation feedback, original graph, selection count 3 and retained
|
||||
primary alias; 42 shows saved status. 43 is a fresh unfiltered review. 44–45
|
||||
show removal feedback, cleared selection, Process owner in the inspector and
|
||||
surviving exchange cards joined by implicit order, then saved status. 46–47
|
||||
show the restored four-card/authored-link graph, Undo feedback then saved state.
|
||||
Undo does not restore the earlier selection; no such guarantee is asserted.
|
||||
|
||||
## Source and lifecycle checks
|
||||
|
||||
Independently compared complete byte arrays: `compact-cancelled.arcadia`,
|
||||
`compact-undo.arcadia`, and final `working.arcadia` all equal pinned oracle-v2
|
||||
`baseline.arcadia` (2609 bytes, SHA256
|
||||
`9965f4024584d64ac81442724aeb77b018b0cfae94e50bd412c5dcbbac49f6bf`).
|
||||
`compact-removed.arcadia` equals oracle-v2 `expected-removed.arcadia` (2258 bytes,
|
||||
SHA256 `b4a2b07ad4c796f555c61945ca42b1c221b454b35488c60fefc86f96f7aa71ba`).
|
||||
All three snapshot sidecars record evaluator exit 0. The source delta removes
|
||||
`@a`, `@c`, `@approved`, updates Assessment steps to `[@e1,@e2]`, and preserves
|
||||
referenced OA work/exchanges, caller references, SA sentinels and remaining bytes.
|
||||
|
||||
Rehashed all 12 prepared immutable entries, including the local executable,
|
||||
DLL, source-proof/input-map/build receipts, exact oracle and comparator copies:
|
||||
all byte lengths and SHA256 pins match. The executable's pin matches its build
|
||||
receipt for `572e96ba03522cfb822b13fe4abb50e857a5de48`; the captured source-proof
|
||||
receipt reports exact source/input agreement. This review did not rerun Git blob
|
||||
verification. The started receipt correctly pins prepared.json and identifies
|
||||
PID 6252 and the isolated executable. All 46 capture timestamps lie between
|
||||
03:58:20.104404 and 04:05:21.991314 UTC; snapshot timestamps also lie within that
|
||||
interval. Finished receipt reports exit 0, unchanged immutable inputs and final
|
||||
baseline pin. Actual stdout/stderr files are empty. Parent reports normal Alt+F4.
|
||||
|
||||
## Limits and non-blocking observations
|
||||
|
||||
At 100% the compact canvas crops the graph (28); Fit exposes it at 59% (29), with
|
||||
small labels. The narrow palette uses abbreviations, and the inspector/explorer
|
||||
require scrolling for more content. These are general compact UI observations,
|
||||
not modal clipping or blockers for the demonstrated removal sequence. Broader
|
||||
compact authoring remains unevaluated.
|
||||
|
||||
Evidence covers this OA derived-layout fixture, mouse/context-add selection,
|
||||
header review, scrolling/paging/search/empty result, Cancel, explicit Remove,
|
||||
Save and one parent-reported Ctrl+Z. No native Shift-click, keyboard-only modal
|
||||
navigation, screen-reader usability, full accessibility, SA native workflows,
|
||||
source-budget failure or arbitrary smaller windows are accepted here. Captured
|
||||
native accessibility exposes only the top-level window/title-bar tree. This run
|
||||
does not add Redo or fresh-process reopen evidence; original runs 1–2 remain
|
||||
separate and unchanged. Screenshots cannot establish exact keystrokes, timing or
|
||||
all intermediate states. No new full-suite, Linux, integration or release claim.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Process aggregate removal source-budget investigation
|
||||
|
||||
Scope: local branch `codex/scenario-multiselect-9e8r6t-20260924`, parent-provided baseline `7323a80e`. Static investigation only; no Cargo, GUI, Gitea, commit, or runtime experiment performed. No production or test source edited.
|
||||
|
||||
## Finding
|
||||
|
||||
No legitimate source-growth case was found for an admitted Process / Functional Chain aggregate removal. Do not transplant the Scenario lifeline budget fixture by giving Process contributions invalid references, alter a prepared command to perform unrelated growing changes, or reduce private Document limits after loading. Those would test a different operation or an invalid model.
|
||||
|
||||
The existing Process regression (`crates/oa-desktop/src/app/process_removal/tests.rs:205`) replaces the admitted plan with Delete(existing) + Delete(nonexistent). It evaluates atomic engine failure and App recovery, **not an actual source update failure**. Keep that evidence boundary explicit.
|
||||
|
||||
## Evidence and excluded candidates
|
||||
|
||||
- `behavior/topology/group_removal.rs:176` admits only listed local contributions or locally maintained SequenceLink / ContextualLink. `behavior/topology.rs:395` restricts contributions to Action, Exchange, Control and SequenceReference occurrences. Removing a reused contribution does not remove its referenced definition or the referenced work/exchange.
|
||||
- `oa-core/src/references.rs:325` cascades ownership, incident relations, contextual references, diagram nodes, traces and artifact links. A contextual link referencing a removed occurrence is deleted, not rewritten to a longer reference. No new identities are introduced by the removal plan (`group_removal.rs:263`).
|
||||
- `references.rs:459` removes records and prunes surviving steps, constraint lists, view options, routes and Scenario layout references. Process occurrence and maintained-link identities cannot be valid targets of the optional work, sequence, scenario, lifeline, supertype, operation-allocation or exchange fields that become `none` when their targets disappear.
|
||||
- The plausible remaining optional occurrence reference, `reply_to`, cannot reference an admitted Process contribution: `validation.rs:1626` rejects Call/reply semantics outside Scenario; `validation.rs:1688` requires the target Call to belong to the same Scenario. State trigger fallback text likewise requires Event or work targets (`validation.rs:2619`), not occurrence or maintained-link targets.
|
||||
- `view_options.rs:96` retains explicit empty selection variants and only filters their identity lists; no longer enum is substituted.
|
||||
- `source_project.rs:1516` uses identity keys for surviving reference list entries, preserving surviving syntax/trivia and stripping deleted tokens. `item_key` at approximately 1695 keys references, routes and semantic rows. `trivia` at 1127 filters input tokens without adding bytes. Structural deletion in `source_project/source_structure.rs` retains trivia of deleted declarations and does not create/move surviving records for this cascade. There was no credible canonical-format expansion candidate in the paths inspected.
|
||||
|
||||
These are reviewed code-path observations, not a formal proof that every possible accepted source spelling is byte-monotone. No claim of an exhaustive runtime search is made. OA and SA share these admission and cascade rules; saved views add record/list pruning, not a discovered growth mechanism.
|
||||
|
||||
## Better evaluator
|
||||
|
||||
1. Retain the existing Process injected engine-failure test with its precise scope. It already checks snapshot identity, exact model/bundle, editor/workspace, selection targets/primary, camera and usable redo. Future strengthening may add revision/clean state, selection generation and navigation, but cannot turn that test into source-write-failure evidence.
|
||||
2. Use `app/scenario_removal/tests.rs:199` as the genuine source-budget failure evaluator: valid lifeline removals rewrite many short `@a` / `@b` references in surviving messages to `none`, prove unrestricted exact-model success and net source growth, and fail through public `Document::from_bundle` limits. That test covers the shared Document transactional source-write boundary plus Scenario App recovery.
|
||||
3. If explicit Process source-write failure branch coverage is required, introduce a narrowly scoped test fault at the Document source writer, and label it an injected source-writer failure. That is more honest than a semantically invalid growth fixture, but adds a test seam and is outside the delegated tests-only scope. A meaningful non-fault alternative is a public input-sized-budget **successful** Process removal test over the literal native fixture; it checks that deletion remains possible at the admitted source budget, not failure atomicity.
|
||||
4. Revisit if Process semantics gain surviving optional references to contributions or if source editing changes to insert replacement syntax during removal.
|
||||
@@ -0,0 +1,71 @@
|
||||
# Process removal compact review follow-up
|
||||
|
||||
The unchanged Windows build from `572e96ba03522cfb822b13fe4abb50e857a5de48`
|
||||
supports the bounded OA derived Process removal workflow at **1102x732**.
|
||||
This closes the compact review gap in the [original report](process-group-removal-app-20260925.md).
|
||||
The contribution remains local-only pending recovery of Gitea writes; no
|
||||
integration, issue closure or release is claimed.
|
||||
|
||||
## Observed behavior
|
||||
|
||||
Run 3 opened an isolated copy of the original fixture. Fit made its four cards
|
||||
and authored link visible. Context Add formed the exact group Action @a,
|
||||
Control @c and SequenceLink @approved, with the link primary. The review's
|
||||
title, aggregate counts, search, paging and fixed Cancel/Remove buttons fit
|
||||
within the window. Scrolling page 1 exposes the explicit-before/implicit-after
|
||||
order changes without losing the footer. Page 2 shows both remaining exchange
|
||||
positions and full direct/transitive caller names and aliases. Search finds
|
||||
@outer; a nonmatching query displays recovery guidance.
|
||||
|
||||
Cancel preserves all three selected members and the link primary. Save gives
|
||||
the complete 2609-byte baseline. A fresh review resets search; explicit Remove
|
||||
leaves two exchange cards with their implicit connection and clears selection.
|
||||
Save equals the independently specified 2258-byte v2 result. One Ctrl+Z and
|
||||
Save restores every original byte. The normal close exits 0, with empty logs
|
||||
and all twelve immutable file pins unchanged. Redo and fresh reopen retain
|
||||
their original runs 1–2 evidence; they were not rerun here.
|
||||
|
||||
- Baseline SHA256: `9965f4024584d64ac81442724aeb77b018b0cfae94e50bd412c5dcbbac49f6bf`.
|
||||
- Removed SHA256: `b4a2b07ad4c796f555c61945ca42b1c221b454b35488c60fefc86f96f7aa71ba`.
|
||||
|
||||
See the [parent action record](process-group-removal-evidence-20260925/compact-actions.md)
|
||||
and [independent review](process-group-removal-evidence-20260925/compact-review.md).
|
||||
Actions reported by the parent are distinguished from screenshots and source
|
||||
receipts. The setup record preserves ineffective edge drags, the unsupported
|
||||
UIA value operation and picker-focus reporting inconsistency. None is counted
|
||||
as successful application interaction.
|
||||
|
||||
## Evidence and limitations
|
||||
|
||||
The new [native evidence snapshot](process-group-removal-evidence-20260925/compact-native/native-evidence.zip)
|
||||
includes all three closed runs and the original failed gate history. It does
|
||||
not overwrite the earlier two-run package. Its [manifest](process-group-removal-evidence-20260925/compact-native/manifest.json)
|
||||
pins every included member and identifies omitted executable/DLL bytes.
|
||||
The standalone verifier passes: 461 members, eight omitted binary payloads,
|
||||
three accepted closed native runs, and the retained preflight/gate history.
|
||||
ZIP size is 9,190,152 bytes; SHA256
|
||||
`02ef32920cb76e12da8b2e41cdecd0d5eea5526371df6425462195c30b564250`.
|
||||
The [independent archive audit](process-group-removal-evidence-20260925/compact-package-audit.json)
|
||||
compares all members with original records, rehashes omitted local binaries,
|
||||
confirms preservation of the original two runs, and separately runs the verifier.
|
||||
Recheck with Python 3.11+:
|
||||
|
||||
```text
|
||||
python -B harness/process-group-removal-evidence-20260925/compact-native/verify.py harness/process-group-removal-evidence-20260925/compact-native
|
||||
```
|
||||
|
||||
This is compact **removal review** acceptance for one OA derived fixture, not
|
||||
complete compact authoring or accessibility acceptance. At 100% zoom the narrow
|
||||
canvas crops the graph; Fit reduces label size. The narrow tool palette uses
|
||||
abbreviated labels. Native Shift-click, keyboard-only navigation, equivalent SA
|
||||
native acceptance, full-suite and Linux checks remain unclaimed. No production
|
||||
source changed and no new Cargo build was needed for this native trial.
|
||||
|
||||
A [separate static investigation](process-group-removal-evidence-20260925/source-failure-investigation.md)
|
||||
found no legitimate growing-source Process removal for a genuine size-budget
|
||||
failure. Valid removals prune admitted contributions, links and references;
|
||||
Scenario's optional-reference expansion fixture does not transfer to Process.
|
||||
The existing Process test exercises an injected engine failure. The genuine
|
||||
Scenario test covers the shared Document source-budget boundary. Neither is
|
||||
relabeled as actual Process source-write-failure coverage, and no artificial
|
||||
fixture or production fault seam was introduced.
|
||||
Reference in New Issue
Block a user