diff --git a/.gitattributes b/.gitattributes index 6f32b754..e802d7eb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -15,6 +15,7 @@ harness/scenario-selection-evidence-20260924/** -text whitespace=cr-at-eol harness/scenario-group-spacing-evidence-20260924/** -text whitespace=cr-at-eol harness/scenario-reorder-interaction-evidence-20260924/** -text whitespace=cr-at-eol +harness/scenario-group-removal-evidence-20260925/** -text whitespace=cr-at-eol # Exact source/recovery oracles and archived ledgers retain their measured bytes. # Keep ordinary text diffs; only disable checkout/check-in newline conversion. diff --git a/harness/multiselect-contract-20260923.md b/harness/multiselect-contract-20260923.md index 39be17bb..2302b24d 100644 --- a/harness/multiselect-contract-20260923.md +++ b/harness/multiselect-contract-20260923.md @@ -104,6 +104,12 @@ is refused with an explanation. Never act on only the primary object while the interface depicts a group. Alignment, distribution and duplication are separate capabilities to assess after this foundation; no speculative semantics are adopted. +The [Scenario removal policy](scenario-group-removal-policy-20260925.md) defines +whole-set local admission, aggregate impact and one-step history. Its +[Windows App/native evidence](scenario-group-removal-app-20260925.md) records the +tested source, mixed participant/message workflow, exact saved-source recovery +and explicit coverage limits; default-branch integration remains separate. + ## Acceptance and dependencies 1. Prove simultaneous geometry planning with unrelated roots/internal routes, diff --git a/harness/scenario-group-removal-app-20260925.md b/harness/scenario-group-removal-app-20260925.md new file mode 100644 index 00000000..48fd38b5 --- /dev/null +++ b/harness/scenario-group-removal-app-20260925.md @@ -0,0 +1,54 @@ +# Scenario aggregate removal: Windows implementation and verification + +Implemented and tested at `43340b94a13f192c3b5d3c3112dbe87246790a44` on `codex/scenario-multiselect-9e8r6t-20260924`, following the [removal policy](scenario-group-removal-policy-20260925.md) and [multiple-selection contract](multiselect-contract-20260923.md). This is branch-specific evidence, outside the delivered issue-37 prerelease. Default-branch integration, a new release and all issue-29 acceptance are not asserted. + +Scenario groups now have one captured local removal operation through the header, contextual menu and mounted canvas Delete/Shift+Delete route. The review shows selected and additional removals separately from changed surviving records, searches full labels/aliases and pages the complete impact. One explicit confirmation executes one Document transaction. Native Windows checks establish cancellation, mixed participant/message removal, exact saved source, one Undo/Redo, compact review expiry/recovery and fresh-process reopening for the fixture below. + +## Behavior and review boundaries + +Every original typed target must exist, belong to the active Scenario and be reachable through actual owner/branch lists; the App also checks actual visibility, exact document/revision/view/visit, selection generation/membership/primary and clean input ownership. Admission occurs before collapsing selected descendants covered by a selected ancestor. Cross-parent local occurrences and mixed participant/occurrence groups share one removal meaning. A missing, stale, hidden, foreign or unsupported member refuses the complete set. + +The planner constructs one deterministic Batch of core Delete commands and evaluates the final candidate. Impact is the actual removed identity set and changed surviving records, including references, parent lists, placements, artifact/trace records and affected saved layouts. Reusable engineering definitions and counterparts are preserved under the established core deletion contract. A removed call can leave a warning-admitted reply with its call reference cleared; it is not silently deleted. Candidate state is not retained as an extra long-lived Project clone. + +The App intercepts captured Begin and modal events before ordinary selection/source handling. Begin retires the old canvas epoch and captures a fresh review context. Confirmation, Cancel, search and paging carry the exact review token; old packets cannot disturb a newer review. Confirmation rechecks complete selection/context and edit eligibility before executing once. Expired reviews show a disabled Remove action and an explicit recovery message. Successful removal selects the Scenario owner and clears removed transient selection. Model Undo restores source/model, not transient selection. Legacy singleton deletion remains refused while a group is depicted. + +Source review found a repeated visibility-enumeration cost, corrected to one enumeration per admission. Strict Clippy led to boxing the large captured Begin snapshot; the final delta changes representation only. [Adapter review](scenario-group-removal-evidence-20260925/adapter-review.md) records independence limits: its reviewer authored the view, which was excluded from independent source review and separately inspected in the actual native workflow. + +## Closed Windows gates + +Rust/Cargo 1.98.1, project GNU/LLVM toolchain, one Cargo job and incremental compilation disabled. Each of the eleven recorded attempts has 823 unchanged captured inputs and an exact Git-blob source proof. Final-source input-map SHA256 is `839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f`. See [portable evidence](scenario-group-removal-evidence-20260925/README.md) for raw streams, commands, source capsules, proofs and offline verification. + +| Final gate | Command | Result | +| --- | --- | --- | +| `removal-app-scenario-4` | `cargo test -p oa-desktop scenario --message-format=json -- --nocapture` | 333 passed, 0 failed, 1 existing ignored timing diagnostic, 1296 filtered | +| `removal-app-removal-2` | `cargo test -p oa-desktop removal --message-format=json -- --nocapture` | 53 passed, 0 failed, 0 ignored, 1577 filtered | +| `removal-app-format-2` | `cargo fmt --all -- --check` | exit 0 | +| `removal-app-clippy-2` | `cargo clippy -p oa-desktop --all-targets --message-format=json -- -D warnings` | exit 0 | +| `removal-app-build-1` | `cargo build -p oa-desktop -p oa-cli --message-format=json` | exit 0, Studio and CLI artifacts | + +The filters overlap; their counts must not be added as unique tests. The ten new planner test functions cover OA/SA exact transactions, mixed references/both views, calls/replies, selected ancestors, separate operands, ScenarioUse preservation, placements/artifacts/traces, complete typed admission/reachability and invalid baseline/Redo refusal. Eight new App functions cover Derived/Saved transactions, stale modal packets, context/selection ABA, cancel with Redo, competing operations, contextual subject preservation, dirty/legacy refusal and mounted Delete/Shift+Delete/repeat routing. + +Retained development failures: scenario-1 at `ed6eaaa73ee409857b8d9bab81b9134981daca30` failed compilation for missing model_menu imports; scenario-2 at `81db58c8b3a94c7f3fcc2a17d9400dfcd38f6574` compiled with331 passes/two incorrect fixtures/one ignore; the strict group-menu expectation had not admitted the new aggregate action, and the cancel/Redo fixture failed to reselect after Undo changed its primary. Both fixtures were corrected without relaxing whole-selection/stale checks. Scenario-3 and removal-1 pass at `35be9ae133f3a32434c4d84edcdb0764044b7539`; format-1 passes there but clippy-1 fails large_enum_variant. Final43340 boxes the snapshot and all five gates above pass. Three failed runs remain failures in the archive. + +## Native removal and persistence + +The copied GUI is 120,067,072 bytes, SHA256 `e118e7f0a2ff53ac9c22a73d07555929d11e1ad917d430a7ae88d469aaa91155`; explicit libunwind DLL is 190,976 bytes, SHA256 `f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4`. Each process uses a fresh bin/cwd and a restricted system PATH. Current-source CLI preflight checks both original and expected-removed sources successfully; warning-admitted incomplete messages remain allowed. Native source oracle was derived before executing the product writer and needed no revision or whitespace normalization. + +Run1 uses three reusable OA activities, three local participants, eight identical message display names with aliases a–h, and two independently authored saved layouts. Click plus contextual Add selects intake_lane and a. Header Remove and the contextual group action show exactly2 removals/10 updates across12 affected records: the two selected bodies are removed, owner sequence/seven surviving sender references/two saved layouts updated. Search distinguishes h, absent search shows an explicit empty state, and Enter does not confirm. Cancel preserves selection and the full original source. + +Explicit Remove produces two surviving participants and seven visible unfinished-message bodies; the view explains that saved positions are retained until endpoints are complete. All three reusable activity definitions, seven receiver references, remaining identities/names/kinds/order, both view identities and all surviving authored coordinates are preserved. One Ctrl+Z restores the entire original file. After reselection, window resizing expires review and disables removal; Escape and explicit Cancel retain the group. The fresh compact review remains readable with a fixed footer at1102x732 (capture dimensions). Page2 remains discoverable after scrolling and shows both affected views. One Ctrl+Y still redoes the original transaction after those UI-only steps. Saved B also opens with its surviving contents. + +| Full-byte phase | Run1 snapshots | Bytes | SHA256 | +| --- | --- | --- | --- | +| baseline | 01-baseline, 02-cancel, 04-undo | 4389 | `70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a` | +| removed | 03-removed, 05-redo | 3856 | `1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f` | + +Run2 is a fresh process explicitly initialized from run1 snapshot05-redo. File Open, Scenario navigation and Saved A display the persisted remaining participants/messages. Save snapshot01-reopened and final working source equal all3856 expected bytes. Both processes close normally with exit0, empty stdout/stderr and unchanged prepared immutable files. Fresh reopen establishes source persistence, not selection/history persistence. + +The archive retains original captures and [detailed observation notes](scenario-group-removal-evidence-20260925/native-observation-notes.md), including input/capture recoveries. Initial nonmaximized navigation misses recovered after maximize; file picker focus metadata disagreed with the visible filename field, and one typing attempt required refocus. One screenshot-less scroll returned16x16 bounds; one Restore capture reported minimized and recovered through activation. Capture35's filename misleadingly says Delete opens review, but the image shows no operation because canvas keyboard focus was not established. It does not count as successful native Delete entry. These limitations were recorded before package acceptance. + +## Limits + +No full desktop-suite, native Shift-click, successful focused native Delete entry, keyboard-only confirmation, broad screen-reader support, arbitrary long-alias/paging stress, native Fragment/SA/reuse-expansion or Linux claim. Accessibility capture exposes mainly window chrome. Tests cover additional semantic/input cases separately from native observations. A real App source-write-failure fixture remains a runtime coverage gap; source inspection and Document atomicity evidence do not replace executing that error branch. Source/model success, cancellation, stale refusal and history coverage are bounded as described above. + +Windows Gitea read/write/push networking works. Ubuntu26.04 starts, but the latest WSL curl to the crates index timed out resolving DNS after10seconds; no Linux build/check was attempted. Linux remains user-paused. Integration must fetch this delivered branch, reconcile other contributions and verify the combined source; these records do not imply that has occurred. diff --git a/harness/scenario-group-removal-evidence-20260925/README.md b/harness/scenario-group-removal-evidence-20260925/README.md new file mode 100644 index 00000000..ee17cf83 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/README.md @@ -0,0 +1,27 @@ +# Scenario aggregate removal evidence + +Tested source: `43340b94a13f192c3b5d3c3112dbe87246790a44`, Windows GNU/LLVM Rust/Cargo1.98.1. The [implementation report](../scenario-group-removal-app-20260925.md) defines acceptance and coverage limits. This package is branch-specific verification evidence, not a runnable release or an integrated acceptance claim. + +- [Source/adapter review](adapter-review.md), including final boxed-snapshot delta and reviewer independence limits. +- [Native observations](native-observation-notes.md), including unsuccessful actions and recovery. +- [Native evidence review](native-review.md), independently inspected original images and exact bytes, with planner/fixture self-review limits. +- [Final report audit](final-report-review.md). +- [Captured checks](checks/README.md): eleven closed attempts, three retained failures, eleven exact823-input source proofs, four deduplicated source capsules. +- [Native archive](native/native-evidence.zip) and [standalone verifier](native/verify.py): two closed native runs and current CLI preflight, original captures, helpers, source/oracle bytes, lifecycle and immutable readback receipts. + +Run standalone verifiers using Python3.11+; they need no checkout, Cargo, Git or network and do not execute the product or archived helpers: + +```text +python -B checks/verify.py +python -B native/verify.py native +``` + +`checks/evidence.zip`: **13,144,614 bytes**, SHA256 `cc4703a21853988d5b833a817a9f6331a98fc4e3d117e74a8f85733ad57d4cc0`. The checks verifier validates the logical-file map, nested captured-source archives, original result/stream/proof relationships and all recorded exits. Its PASS is consistency, not success of the three failed attempts. Exact Git-source comparison was separately performed when each gate closed; offline validation does not recreate Git trust. + +`native/native-evidence.zip`: **6,942,333 bytes**, SHA256 `9eb28f970d256160238234279fa91ad60e404e8b11d8d7e6d55178999919e2b1`, 305 members. Run1 contains 62 capture records and five exact snapshots; run2 contains 15 capture records and its exact reopened snapshot. Both runs and the current CLI preflight are explicitly accepted only within the report's scope. + +The parent ran both standalone verifiers successfully. Separate direct audits compared all88 original checks-run files and all304 original native members byte for byte; the generated native configuration matched semantically. All six omitted GUI/CLI/runtime files were independently rehashed against their pins while still locally available. Original failed checks and native input/capture recovery attempts retain their actual outcomes. + +The first staged-byte check detected Git newline conversion in the native manifest. A scoped `.gitattributes` rule now preserves this evidence directory verbatim; the manifest and archived originals were not normalized or rewritten. + +The native archive excludes executable/DLL bytes, retaining their explicit build/copy/readback pins. Offline validation cannot rehash omitted binaries or independently infer which keys were sent. The parent action record, original captures, exact file states, lifecycle records and independent review jointly support the reported bounded workflows. Native Shift-click, focused Delete success, keyboard-only confirmation, broad accessibility and real App source-write failure are not established. Linux remains user-paused. diff --git a/harness/scenario-group-removal-evidence-20260925/adapter-review.md b/harness/scenario-group-removal-evidence-20260925/adapter-review.md new file mode 100644 index 00000000..a465f120 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/adapter-review.md @@ -0,0 +1,70 @@ +# Scenario aggregate removal independent source review + +Reviewed source: `ed6eaaa73ee4` (parent-supplied frozen gate identity). Read-only inspection; no Git, Cargo, native UI, or gate execution. The reviewer authored `app/scenario_removal/view.rs`; that file and its visual behavior are explicitly excluded from this review. + +## Result + +No blocking correctness defect established in the reviewed planner, App adapter, or entry routes. This is a source review, not a passing-test or native-acceptance claim. + +One bounded performance issue is confirmed: `scenario_removal_matches` calls `multiselect_target_visible` for each captured target, regenerating the Scenario presentation per member. Parent has already identified this and plans one `selection::visible` enumeration per admission followed by whole-set membership checks after the frozen gate closes. This review does not claim that future patch is present or verified. + +## Semantic transaction + +- `group_removal::prepare` rejects non-Scenario targets, duplicate identities, empty sets, invalid baseline models, missing/foreign subjects and reusable definitions. It validates complete actual sequence/operand reachability, parent and layer consistency before reducing selected descendants covered by selected ancestors. Cross-operand groups are admitted without importing semantic reorder's same-parent restriction. +- The command is one Batch of deterministic root Deletes. `execute_batch` clones the project, applies the commands, finishes deferred cascades and validates the final candidate. The adapter later sends that Batch through one Document execution. There is no series of singleton Document changes or partially admitted selection. +- Core cascade inspection (`references::deletion_impact_inner`, `remove_objects`) confirms that local occurrence/participant removal follows owned descendants and incoming dependents rather than deleting the reusable definitions those occurrences refer to. Surviving references are cleared, owner lists are pruned, and saved-view layout entries are pruned. Removing a call can retain its reply as a warning-admitted draft; this is explicitly tested rather than silently recast as automatic reply deletion. +- Impact is computed from actual before/candidate identity sets. Changed surviving records are compared across elements, relations, diagrams, artifact links, traces and embedded placements; containing diagrams also account for layout/route changes. A final selected-subset-of-removed check prevents a partial result from reaching review. + +## Captured admission and lifetime + +- Begin checks exact Scenario Context and full Selection snapshot, actual visibility, group size, clean edit state, Select tool and exclusive input ownership before the shared source boundary. It retires the canvas epoch and captures fresh context/snapshot for the review. An older Begin cannot reopen over a later review. +- Review confirmation is stamped with the menu sequence token. App dispatch rejects mismatched confirmation tokens before shared handling and intercepts group confirmation before legacy singleton deletion. Stamped Cancel, Query and Page target only the matching aggregate review. Legacy unstamped CancelDelete is prevented from closing a current group review. +- Confirmation checks exact document/revision/epoch/representation/visit, selection generation/membership/primary, selected subject, dirty editor guards, busy state and competing reorder/spacing/tool state. An expired matching review closes without executing its command and retires its epoch. Stale different-token confirmation does not close a newer review. +- Success updates the selection owner only after Document execution, syncs and reconciles removed selection identities. Failure leaves the model/source/selection transition unperformed; only the review lifetime and status are retired. Cancellation leaves source/history/selection unchanged. Exact source-history assertions exist for success/Undo/Redo, but no real App source-write failure was executed or established by this review. + +## Entry routes + +- Header Remove is available for a group and uses a captured Begin. Canvas Delete/Shift+Delete require Select mode, editable ownership, no pending gesture, and `repeat: false`; group dispatch carries the entire Scene snapshot. The singleton remove path is bypassed for groups. +- Group menu entry uses the captured current selection even when the right-clicked subject is outside it. Menu Invoke removes/validates the menu, then routes ScenarioRemoval directly before the ordinary clicked-object selection path. This avoids primary replacement or an unselected-subject deletion. +- Begin's keyboard-owner eligibility blocks existing menus/modals, dirty editors and busy/competing operations. Modal handling blocks ordinary authoring commands while review is open. Passive resize or loaded revision can expire the review, and exact confirmation validation prevents applying its old plan. +- Mounted test source exercises actual canvas Delete and Shift+Delete, checks full captured targets/primary, rejects singleton emissions, and checks repeat does not confirm. No automatic destructive Enter handler was added in these reviewed routes. Visual panel controls are outside this reviewer’s independence scope. + +## Evidence and remaining boundaries + +Read planner tests for OA/SA message removal, mixed lifeline/message reference clearing, both saved views, calls/replies, nested ancestor/descendant selection, independent operands, ScenarioUse definition preservation, placement/artifact/trace impact, malformed/foreign/duplicate input, and existing redo preservation. The shared test helper compares literal expected whole projects, reopened authored source, one Undo and one Redo, rather than testing only counts. + +Read adapter tests for Derived/Saved exact transactions, stale modal packets across a new review, document/revision/epoch/visit/selection-ABA expiration, cancellation with redo, competing live reorder/spacing, selected/unselected contextual subjects, dirty properties, legacy singleton refusal, and mounted Delete/repeat routing. These are inspected assertions only while the parent gate runs; their runtime outcome is not asserted here. + +Native compact layout, review search/paging usability, true source-write failure recovery, and broader platform execution remain separate validation work. No production files were changed during this review. + +## Addendum: closed gates at 35be9ae133f3a32434c4d84edcdb0764044b7539 + +Inspected the read-only Git diff from `ed6eaaa73ee4` to this tested commit. The single visibility enumeration fix has landed: identity/context/snapshot mismatch returns first, then one `selection::visible` result is checked against every original target. Whole-set admission is retained and the repeated presentation construction noted above is resolved. No planner change occurred in this diff. + +The other changes preserve the acceptance boundary. The legacy singleton refusal now directs users to Reorder or Remove. The strict menu test permits exactly one additional aggregate action, requires its exact Begin variant, current Context and complete Snapshot, and continues rejecting other singleton model actions. The redo/cancel fixture now restores the real two-member group through production Selection events after Rename/Undo changed the inspected subject, explicitly verifies redo still exists, then performs the original cancellation/history assertions. Stale-token and context/selection-ABA tests were not relaxed. + +Independently read the existing closed result, stdout, stderr and source-proof files in: + +- `.local/scenario-group-gates/removal-app-scenario-3`: exit 0; stdout reports **333 passed, 0 failed, 1 ignored, 1296 filtered**. The ignored test is the existing diagnostic-only spacing timing test. Named stale-modal, expiration, contextual-menu and redo/cancel tests report `ok`. +- `.local/scenario-group-gates/removal-app-removal-1`: exit 0; stdout reports **53 passed, 0 failed, 0 ignored, 1577 filtered**. + +Both receipts identify the full commit above, `inputsUnchanged: true`, and 823 captured inputs. Both source-proof records report `PASS exact captured input inventory and Git blob bytes` at that commit. The shared input-map SHA-256 is `fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4`; captured archive is 3,289,235 bytes, SHA-256 `ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd`. This reviewer additionally rehashed each run's stdout, stderr and inputs.json and checked byte counts against its result receipt; all six pairs matched. The existing source comparator was read, not rerun. + +These are verified recorded outcomes from parent-run gates, not tests run by this reviewer. No new blocking source finding arose. Native validation is still pending, and the source-write failure and platform limitations above remain. The authored view remains excluded from independent self-review. + +## Final delta and limited panel self-review at 43340b94 + +Before reviewing, read-only Git commands reported branch `codex/scenario-multiselect-9e8r6t-20260924`, HEAD `43340b94a13f192c3b5d3c3112dbe87246790a44`. Inspected the complete source delta from `35be9ae133f3a32434c4d84edcdb0764044b7539`: four files, five insertions/five deletions. Begin now holds `Box`; both production constructors and the fixture constructor wrap the same captured snapshot, and the menu assertion dereferences it. Admission comparisons, selection capture, token handling, command construction and Document execution are unchanged. No new blocking correctness issue is established by this delta. This inspection does not extend the earlier commit's recorded test results into an unverified claim about final-commit gates. + +At parent's request I also reread the current panel. **This is self-review, not independent review:** I authored `app/scenario_removal/view.rs`. The source enumerates every removed and changed identity, distinguishes selected/additional removal from preserved-but-updated records, searches full labels/aliases, clamps page index, renders six rows per page, and keeps overall impact counts separate from filtered matches. The fixed footer uses stamped Cancel and validity-gated Confirm; there is no query submit handler. Long row labels use WordOrGlyph and the scroll body reserves an 8px gutter. The 732px window calculation gives 570px content plus 52px modal padding; actual layout remains a native observation, not established by arithmetic alone. + +Concrete native checks suggested to the integration owner: + +1. At 1104×732, inspect long unbroken aliases at the right scroll edge, the fixed Cancel/Remove footer and the expiry notice together; verify scrolling never clips or hides actions. +2. Scroll an impact page to the bottom, then choose Next/Previous or change search. The persistent scroll widget may retain its offset, so verify the first matching row remains discoverable and no page appears falsely empty. +3. Search for one record and for no matches. Confirm that the title and total removed/updated counts still communicate the entire operation; filtering is review-only and must not be mistaken for deleting only matches. +4. Resize with a live review and observe disabled Remove plus the explicit expiry notice, then cancel and reopen. Confirm cancellation preserves both the selected group and preexisting Undo/Redo history. +5. From a focused query, try Enter and repeated Delete, then Escape. These must not perform removal; an explicit enabled confirmation is required. Ordinary Iced footer buttons do not provide the custom canvas Control focus integration, so no keyboard-only confirmation accessibility claim is made. +6. Compare one mixed participant/message or nested-parent impact against saved source after confirmation and one Undo, including additional removed dependents and updated views/references rather than only visible selected bodies. + +No source edits, build, commit, or GUI operation were performed for this final review. Parent native work remains in progress; its results must be attached separately. diff --git a/harness/scenario-group-removal-evidence-20260925/checks/README.md b/harness/scenario-group-removal-evidence-20260925/checks/README.md new file mode 100644 index 00000000..7fe3c556 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/checks/README.md @@ -0,0 +1,25 @@ +# Scenario aggregate removal: captured checks + +Create-only packaging for explicitly named, closed `removal-app-*` runs under `CHECKOUT/.local/scenario-group-gates`. Python 3.11+ standard library; no Cargo, Git, network, source execution or native process is used. Adapted from the reviewed semantic-reorder checks tools; input capsules remain deduplicated by SHA-256, with every original logical run path retained. + +```text +python -B prepare.py --root CHECKOUT --runs removal-app-scenario-1 removal-app-scenario-2 --check-only +python -B prepare.py --root CHECKOUT --runs CLOSED_RUN_NAMES --output NEW_DIRECTORY +python -B NEW_DIRECTORY/verify.py +``` + +Replace `CLOSED_RUN_NAMES` with the explicit complete set intended for delivery, including failed attempts. The tool does not silently discover or select runs. It refuses a pre-existing output directory, active/incomplete runs, changed-input runs and runs missing an exact source-proof receipt. It validates all selected data in memory before creating output. The supplied two-run example is historical demonstration, not a complete final delivery inventory. Do not package an active run. + +Output contains `evidence.zip`, `manifest.json`, `files.json`, the packager, standalone verifier and this README. Raw stdout/stderr, started/process/result receipts, input maps/ZIPs and source proofs retain exact bytes. Measured capture helpers and the source comparator are included as data. Supply repeatable `--helper PATH` or `--comparator PATH` when a historical measured helper is no longer at its default checkout path. + +Verification checks outer file and ZIP inventories/hashes, safe member paths, exact nested input ZIP membership and bytes against its map, dynamic input counts (currently 823), unchanged closed-run receipts, command/time/process consistency, executable Cargo-record relationships, proof result/map/count/name bindings and comparator provenance. The existing capture contract includes all 71 tracked patched-widget vendor files. Every recorded exit code is printed; failures remain failures regardless of package consistency PASS. + +Captured `head` and the proof's named commit retain distinct meanings. The offline verifier validates the proof's metadata and pinned comparator, but does not execute it, read Git objects, establish that captured source matches Git, or rehash omitted executable bytes. The archived source bytes are the independently hash-checkable input witness. Source attribution ultimately relies on the separately performed source comparison. Neither successful packaging nor a source proof establishes test success, hermetic builds, native usability, integration, release acceptance or issue completion. + +Maintainer selfcheck (only closed runs; fresh scratch output beneath this tools directory): + +```text +python -B selfcheck.py --root CHECKOUT --runs removal-app-scenario-1 removal-app-scenario-2 --output TOOLS_DIRECTORY/selfcheck-package-1 +``` + +It verifies exact original raw equality, refuses existing output, and mutates only in-memory copies to test corruption rejection. It never edits the original captures or executes archived helpers. Run the standalone verifier again after copying a final package to its delivery location. Published outer pins provide integrity, not an external signature or trust anchor. diff --git a/harness/scenario-group-removal-evidence-20260925/checks/evidence.zip b/harness/scenario-group-removal-evidence-20260925/checks/evidence.zip new file mode 100644 index 00000000..9cdabacf Binary files /dev/null and b/harness/scenario-group-removal-evidence-20260925/checks/evidence.zip differ diff --git a/harness/scenario-group-removal-evidence-20260925/checks/files.json b/harness/scenario-group-removal-evidence-20260925/checks/files.json new file mode 100644 index 00000000..315ae0d9 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/checks/files.json @@ -0,0 +1,22 @@ +{ + "prepare.py": { + "bytes": 6320, + "sha256": "c643f42840df075e89a3fc0dc912baa42c51e9ceaa507fd1c96b751dca92ac1a" + }, + "verify.py": { + "bytes": 11525, + "sha256": "35470ea415156e9001c8ab2fb7d6b108179382d0456490e2caffc242c4f17643" + }, + "README.md": { + "bytes": 3306, + "sha256": "ae5b9595d3e9063ed9a8f4fcc9c16e27708d0e3e3989617de560d75b71a2143c" + }, + "manifest.json": { + "bytes": 30705, + "sha256": "10f0174fe9b64627bca1ccc8934083ed8362e88bfb758b958d86a4fdd035ddb5" + }, + "evidence.zip": { + "bytes": 13144614, + "sha256": "cc4703a21853988d5b833a817a9f6331a98fc4e3d117e74a8f85733ad57d4cc0" + } +} diff --git a/harness/scenario-group-removal-evidence-20260925/checks/manifest.json b/harness/scenario-group-removal-evidence-20260925/checks/manifest.json new file mode 100644 index 00000000..56df76a8 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/checks/manifest.json @@ -0,0 +1,672 @@ +{ + "schema": 1, + "kind": "scenario-aggregate-removal-cargo-gates", + "runs": { + "removal-app-scenario-1": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "scenario", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "ed6eaaa73ee409857b8d9bab81b9134981daca30", + "exitCode": 101, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "ed6eaaa73ee409857b8d9bab81b9134981daca30", + "pin": { + "bytes": 601, + "sha256": "36cb123c80dfbfbe653370706a52a0064a423de41709abdfc3e8a96a422e96d9" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-scenario-2": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "scenario", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "81db58c8b3a94c7f3fcc2a17d9400dfcd38f6574", + "exitCode": 101, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "81db58c8b3a94c7f3fcc2a17d9400dfcd38f6574", + "pin": { + "bytes": 601, + "sha256": "9ad5ace43e03bc99174bb4af6950dc5afa6c8441ce78a981a8caa5c423c82ed4" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-scenario-3": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "scenario", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "pin": { + "bytes": 601, + "sha256": "c7d3a48571aa4100b94c083f9dcce1630f8fad0f8e698cfe55cc50f53b14ad5b" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-scenario-4": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "scenario", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "pin": { + "bytes": 601, + "sha256": "71719bc542efdc35337773056f87dddff61af64a4ff59fb5d5158f6fee655755" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-removal-1": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "removal", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "pin": { + "bytes": 600, + "sha256": "19b9d547f39abbebefb45d8cf443e4ef09322f245ace12dd3ed8c9ab8b95dd51" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-removal-2": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "removal", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "pin": { + "bytes": 600, + "sha256": "e36a67dbea645d338a7e8e3913a8c9257968dc6a1262d58b2b017ff5fa1b7bd9" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-format-1": { + "command": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "head": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "pin": { + "bytes": 599, + "sha256": "3d58c97b003181a55ea6e52a844e1679170173a364bfa30449eb86d0df74ed8f" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-format-2": { + "command": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "head": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "pin": { + "bytes": 599, + "sha256": "65046ae3b59f685d38499daa61324bd5e38a9be2fe9cf84f6dedc21f6dba10ff" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-clippy-1": { + "command": [ + "cargo", + "clippy", + "-p", + "oa-desktop", + "--all-targets", + "--message-format=json", + "--", + "-D", + "warnings" + ], + "head": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "exitCode": 101, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "35be9ae133f3a32434c4d84edcdb0764044b7539", + "pin": { + "bytes": 599, + "sha256": "5d22f3c69744af5bf0eefa1654ab6da8842237c3c6ccaaac0494f0e923583cca" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-clippy-2": { + "command": [ + "cargo", + "clippy", + "-p", + "oa-desktop", + "--all-targets", + "--message-format=json", + "--", + "-D", + "warnings" + ], + "head": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "pin": { + "bytes": 599, + "sha256": "bcd5192b82f005ac2f58d08c7a0b61670a45a7a11f7bf442f35973b13b53c27a" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "removal-app-build-1": { + "command": [ + "cargo", + "build", + "-p", + "oa-desktop", + "-p", + "oa-cli", + "--message-format=json" + ], + "head": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "exitCode": 0, + "inputCount": 823, + "helper": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "sourceProof": { + "commit": "43340b94a13f192c3b5d3c3112dbe87246790a44", + "pin": { + "bytes": 598, + "sha256": "b548459a93f6510422eb8dd8542c9eadfc92604c137bf73b3ffaca4c8d9edffe" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + } + }, + "captureHelpers": { + "gate.py": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "source-proof.py": "helpers/c86f51d9b8465341dab73d045923ec306b15ebabf7c97b81beac7afe73bd72a1.py" + }, + "logicalFiles": { + "cargo/removal-app-build-1/inputs.json": "capsules/839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f.json", + "cargo/removal-app-build-1/inputs.zip": "capsules/d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578.zip", + "cargo/removal-app-build-1/process.json": "cargo/removal-app-build-1/process.json", + "cargo/removal-app-build-1/result.json": "cargo/removal-app-build-1/result.json", + "cargo/removal-app-build-1/source-proof.json": "cargo/removal-app-build-1/source-proof.json", + "cargo/removal-app-build-1/started.json": "cargo/removal-app-build-1/started.json", + "cargo/removal-app-build-1/stderr.log": "cargo/removal-app-build-1/stderr.log", + "cargo/removal-app-build-1/stdout.log": "cargo/removal-app-build-1/stdout.log", + "cargo/removal-app-clippy-1/inputs.json": "capsules/fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4.json", + "cargo/removal-app-clippy-1/inputs.zip": "capsules/ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd.zip", + "cargo/removal-app-clippy-1/process.json": "cargo/removal-app-clippy-1/process.json", + "cargo/removal-app-clippy-1/result.json": "cargo/removal-app-clippy-1/result.json", + "cargo/removal-app-clippy-1/source-proof.json": "cargo/removal-app-clippy-1/source-proof.json", + "cargo/removal-app-clippy-1/started.json": "cargo/removal-app-clippy-1/started.json", + "cargo/removal-app-clippy-1/stderr.log": "cargo/removal-app-clippy-1/stderr.log", + "cargo/removal-app-clippy-1/stdout.log": "cargo/removal-app-clippy-1/stdout.log", + "cargo/removal-app-clippy-2/inputs.json": "capsules/839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f.json", + "cargo/removal-app-clippy-2/inputs.zip": "capsules/d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578.zip", + "cargo/removal-app-clippy-2/process.json": "cargo/removal-app-clippy-2/process.json", + "cargo/removal-app-clippy-2/result.json": "cargo/removal-app-clippy-2/result.json", + "cargo/removal-app-clippy-2/source-proof.json": "cargo/removal-app-clippy-2/source-proof.json", + "cargo/removal-app-clippy-2/started.json": "cargo/removal-app-clippy-2/started.json", + "cargo/removal-app-clippy-2/stderr.log": "cargo/removal-app-clippy-2/stderr.log", + "cargo/removal-app-clippy-2/stdout.log": "cargo/removal-app-clippy-2/stdout.log", + "cargo/removal-app-format-1/inputs.json": "capsules/fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4.json", + "cargo/removal-app-format-1/inputs.zip": "capsules/ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd.zip", + "cargo/removal-app-format-1/process.json": "cargo/removal-app-format-1/process.json", + "cargo/removal-app-format-1/result.json": "cargo/removal-app-format-1/result.json", + "cargo/removal-app-format-1/source-proof.json": "cargo/removal-app-format-1/source-proof.json", + "cargo/removal-app-format-1/started.json": "cargo/removal-app-format-1/started.json", + "cargo/removal-app-format-1/stderr.log": "cargo/removal-app-format-1/stderr.log", + "cargo/removal-app-format-1/stdout.log": "cargo/removal-app-format-1/stdout.log", + "cargo/removal-app-format-2/inputs.json": "capsules/839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f.json", + "cargo/removal-app-format-2/inputs.zip": "capsules/d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578.zip", + "cargo/removal-app-format-2/process.json": "cargo/removal-app-format-2/process.json", + "cargo/removal-app-format-2/result.json": "cargo/removal-app-format-2/result.json", + "cargo/removal-app-format-2/source-proof.json": "cargo/removal-app-format-2/source-proof.json", + "cargo/removal-app-format-2/started.json": "cargo/removal-app-format-2/started.json", + "cargo/removal-app-format-2/stderr.log": "cargo/removal-app-format-2/stderr.log", + "cargo/removal-app-format-2/stdout.log": "cargo/removal-app-format-2/stdout.log", + "cargo/removal-app-removal-1/inputs.json": "capsules/fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4.json", + "cargo/removal-app-removal-1/inputs.zip": "capsules/ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd.zip", + "cargo/removal-app-removal-1/process.json": "cargo/removal-app-removal-1/process.json", + "cargo/removal-app-removal-1/result.json": "cargo/removal-app-removal-1/result.json", + "cargo/removal-app-removal-1/source-proof.json": "cargo/removal-app-removal-1/source-proof.json", + "cargo/removal-app-removal-1/started.json": "cargo/removal-app-removal-1/started.json", + "cargo/removal-app-removal-1/stderr.log": "cargo/removal-app-removal-1/stderr.log", + "cargo/removal-app-removal-1/stdout.log": "cargo/removal-app-removal-1/stdout.log", + "cargo/removal-app-removal-2/inputs.json": "capsules/839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f.json", + "cargo/removal-app-removal-2/inputs.zip": "capsules/d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578.zip", + "cargo/removal-app-removal-2/process.json": "cargo/removal-app-removal-2/process.json", + "cargo/removal-app-removal-2/result.json": "cargo/removal-app-removal-2/result.json", + "cargo/removal-app-removal-2/source-proof.json": "cargo/removal-app-removal-2/source-proof.json", + "cargo/removal-app-removal-2/started.json": "cargo/removal-app-removal-2/started.json", + "cargo/removal-app-removal-2/stderr.log": "cargo/removal-app-removal-2/stderr.log", + "cargo/removal-app-removal-2/stdout.log": "cargo/removal-app-removal-2/stdout.log", + "cargo/removal-app-scenario-1/inputs.json": "capsules/ebb7a1f556efb40caf72dac05e1966b819571e586258dd6a1d97e163aa0246d6.json", + "cargo/removal-app-scenario-1/inputs.zip": "capsules/47aaa60a092e270d60764e67ec105ea1790756998c16c0745d5cc0a4aba5477d.zip", + "cargo/removal-app-scenario-1/process.json": "cargo/removal-app-scenario-1/process.json", + "cargo/removal-app-scenario-1/result.json": "cargo/removal-app-scenario-1/result.json", + "cargo/removal-app-scenario-1/source-proof.json": "cargo/removal-app-scenario-1/source-proof.json", + "cargo/removal-app-scenario-1/started.json": "cargo/removal-app-scenario-1/started.json", + "cargo/removal-app-scenario-1/stderr.log": "cargo/removal-app-scenario-1/stderr.log", + "cargo/removal-app-scenario-1/stdout.log": "cargo/removal-app-scenario-1/stdout.log", + "cargo/removal-app-scenario-2/inputs.json": "capsules/346cbaaab47741ce778ce94efe20479c52472a1d5e7c44b77ff0bb6191914013.json", + "cargo/removal-app-scenario-2/inputs.zip": "capsules/16389428b10c8d59fb7dccdb886db2e1de937cdf876071b4ad297e21983b00ae.zip", + "cargo/removal-app-scenario-2/process.json": "cargo/removal-app-scenario-2/process.json", + "cargo/removal-app-scenario-2/result.json": "cargo/removal-app-scenario-2/result.json", + "cargo/removal-app-scenario-2/source-proof.json": "cargo/removal-app-scenario-2/source-proof.json", + "cargo/removal-app-scenario-2/started.json": "cargo/removal-app-scenario-2/started.json", + "cargo/removal-app-scenario-2/stderr.log": "cargo/removal-app-scenario-2/stderr.log", + "cargo/removal-app-scenario-2/stdout.log": "cargo/removal-app-scenario-2/stdout.log", + "cargo/removal-app-scenario-3/inputs.json": "capsules/fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4.json", + "cargo/removal-app-scenario-3/inputs.zip": "capsules/ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd.zip", + "cargo/removal-app-scenario-3/process.json": "cargo/removal-app-scenario-3/process.json", + "cargo/removal-app-scenario-3/result.json": "cargo/removal-app-scenario-3/result.json", + "cargo/removal-app-scenario-3/source-proof.json": "cargo/removal-app-scenario-3/source-proof.json", + "cargo/removal-app-scenario-3/started.json": "cargo/removal-app-scenario-3/started.json", + "cargo/removal-app-scenario-3/stderr.log": "cargo/removal-app-scenario-3/stderr.log", + "cargo/removal-app-scenario-3/stdout.log": "cargo/removal-app-scenario-3/stdout.log", + "cargo/removal-app-scenario-4/inputs.json": "capsules/839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f.json", + "cargo/removal-app-scenario-4/inputs.zip": "capsules/d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578.zip", + "cargo/removal-app-scenario-4/process.json": "cargo/removal-app-scenario-4/process.json", + "cargo/removal-app-scenario-4/result.json": "cargo/removal-app-scenario-4/result.json", + "cargo/removal-app-scenario-4/source-proof.json": "cargo/removal-app-scenario-4/source-proof.json", + "cargo/removal-app-scenario-4/started.json": "cargo/removal-app-scenario-4/started.json", + "cargo/removal-app-scenario-4/stderr.log": "cargo/removal-app-scenario-4/stderr.log", + "cargo/removal-app-scenario-4/stdout.log": "cargo/removal-app-scenario-4/stdout.log", + "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py", + "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py": "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py", + "helpers/c86f51d9b8465341dab73d045923ec306b15ebabf7c97b81beac7afe73bd72a1.py": "helpers/c86f51d9b8465341dab73d045923ec306b15ebabf7c97b81beac7afe73bd72a1.py" + }, + "members": { + "capsules/16389428b10c8d59fb7dccdb886db2e1de937cdf876071b4ad297e21983b00ae.zip": { + "bytes": 3288941, + "sha256": "16389428b10c8d59fb7dccdb886db2e1de937cdf876071b4ad297e21983b00ae" + }, + "capsules/346cbaaab47741ce778ce94efe20479c52472a1d5e7c44b77ff0bb6191914013.json": { + "bytes": 138269, + "sha256": "346cbaaab47741ce778ce94efe20479c52472a1d5e7c44b77ff0bb6191914013" + }, + "capsules/47aaa60a092e270d60764e67ec105ea1790756998c16c0745d5cc0a4aba5477d.zip": { + "bytes": 3288901, + "sha256": "47aaa60a092e270d60764e67ec105ea1790756998c16c0745d5cc0a4aba5477d" + }, + "capsules/839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f.json": { + "bytes": 138269, + "sha256": "839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f" + }, + "capsules/ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd.zip": { + "bytes": 3289235, + "sha256": "ae89bbdfe2d81b977ceb81ae834178a3f7d9891005d376bda8c4795c2698abfd" + }, + "capsules/d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578.zip": { + "bytes": 3289264, + "sha256": "d75cbb2b7667a50ea5c361547cbfc45f5876ab2d856cd8cfe70d86910194f578" + }, + "capsules/ebb7a1f556efb40caf72dac05e1966b819571e586258dd6a1d97e163aa0246d6.json": { + "bytes": 138269, + "sha256": "ebb7a1f556efb40caf72dac05e1966b819571e586258dd6a1d97e163aa0246d6" + }, + "capsules/fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4.json": { + "bytes": 138269, + "sha256": "fb5d17f3841c3a525109136cd71a07d56db26602e3b49e6f92fbf6112b7b66a4" + }, + "cargo/removal-app-build-1/process.json": { + "bytes": 153, + "sha256": "e4b9aa160177768659fbaebf76d862e53a9d5ca48f2e51cc81640f861db4947b" + }, + "cargo/removal-app-build-1/result.json": { + "bytes": 4454, + "sha256": "539b7536236430b955e2657dd1e5b9ff905c029e5d1d10c2ac194d7d7847464a" + }, + "cargo/removal-app-build-1/source-proof.json": { + "bytes": 598, + "sha256": "b548459a93f6510422eb8dd8542c9eadfc92604c137bf73b3ffaca4c8d9edffe" + }, + "cargo/removal-app-build-1/started.json": { + "bytes": 1527, + "sha256": "8badef41781b1aebee818939b60e268f25c34de6419f3833604d42dee5592b16" + }, + "cargo/removal-app-build-1/stderr.log": { + "bytes": 134, + "sha256": "df5af908cea87828bdb61632f8ecb5442f2a010f93a304efb00069b0f6939f37" + }, + "cargo/removal-app-build-1/stdout.log": { + "bytes": 285562, + "sha256": "0a347c109a23a6bba5a08a54b2c2939b0921f3b78e78ba3376b66edf31ba8cc8" + }, + "cargo/removal-app-clippy-1/process.json": { + "bytes": 179, + "sha256": "953a67aaae91a084bd1548d8970dbec20dee51511b3f18b1e249eff03217ff3c" + }, + "cargo/removal-app-clippy-1/result.json": { + "bytes": 1960, + "sha256": "281b5642d7cbdcba5ba0babdb3d55cd4696301a8d61d153a7930c497419ee47e" + }, + "cargo/removal-app-clippy-1/source-proof.json": { + "bytes": 599, + "sha256": "5d22f3c69744af5bf0eefa1654ab6da8842237c3c6ccaaac0494f0e923583cca" + }, + "cargo/removal-app-clippy-1/started.json": { + "bytes": 1563, + "sha256": "28e5b4b072c3d9704082b2e270480832dcc4027abeb1f9c41b5a0dcfe1382749" + }, + "cargo/removal-app-clippy-1/stderr.log": { + "bytes": 163, + "sha256": "6cd1a10aa8ce9ee8a5ac74fd1dacd158709abeeb9483b49fc61c272157cbfc6d" + }, + "cargo/removal-app-clippy-1/stdout.log": { + "bytes": 272736, + "sha256": "d606135330413b7555c8e5c674aa832a1d21127b835a54f6495fdb4f281edc1a" + }, + "cargo/removal-app-clippy-2/process.json": { + "bytes": 179, + "sha256": "0d32ef12d3e0f2b457fec0d328ad15f352877327eca3d336c998bacaba791f64" + }, + "cargo/removal-app-clippy-2/result.json": { + "bytes": 1958, + "sha256": "339c98d171c5e4eba1affa4030d36e19c6e9483ff489ef560fb439f0d26cd6f5" + }, + "cargo/removal-app-clippy-2/source-proof.json": { + "bytes": 599, + "sha256": "bcd5192b82f005ac2f58d08c7a0b61670a45a7a11f7bf442f35973b13b53c27a" + }, + "cargo/removal-app-clippy-2/started.json": { + "bytes": 1563, + "sha256": "b37ee5d68352a33450351c2fac8291b64a73f46a7a7c04ec1a47ed1c27892036" + }, + "cargo/removal-app-clippy-2/stderr.log": { + "bytes": 134, + "sha256": "bc524ebe318a2ae7ef09a7065b358c45de4523c2efcd104f8a20a8d35b80eda6" + }, + "cargo/removal-app-clippy-2/stdout.log": { + "bytes": 269431, + "sha256": "07c7d8af5eb5b5d8e9e305b0bd7a504eafa63f89ae1d0b99e2e2bfe7da5a56de" + }, + "cargo/removal-app-format-1/process.json": { + "bytes": 116, + "sha256": "c5f7ef95cd3296baded0b425e366c3aab845d4ac8ad987df52a24e526b35a909" + }, + "cargo/removal-app-format-1/result.json": { + "bytes": 1868, + "sha256": "eb2b6dbc0f4f666ad0295aa478603f573bd1fc62ba314f5dd8a773d0aa39fca7" + }, + "cargo/removal-app-format-1/source-proof.json": { + "bytes": 599, + "sha256": "3d58c97b003181a55ea6e52a844e1679170173a364bfa30449eb86d0df74ed8f" + }, + "cargo/removal-app-format-1/started.json": { + "bytes": 1480, + "sha256": "f4be4ad88262fc9c1786af94f6ef4d81abdecfb867e44a2ed4eb92955721e909" + }, + "cargo/removal-app-format-1/stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/removal-app-format-1/stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/removal-app-format-2/process.json": { + "bytes": 116, + "sha256": "ad83e91dc44bdb2fc5a6fe2ecdf9e7d6d4419da274c20d09f2ebfc94921b989c" + }, + "cargo/removal-app-format-2/result.json": { + "bytes": 1868, + "sha256": "ce02718f3bbaa13981a0781d530a8f658016620c6c69cf9b22f68546660e1097" + }, + "cargo/removal-app-format-2/source-proof.json": { + "bytes": 599, + "sha256": "65046ae3b59f685d38499daa61324bd5e38a9be2fe9cf84f6dedc21f6dba10ff" + }, + "cargo/removal-app-format-2/started.json": { + "bytes": 1480, + "sha256": "9f14741673fe08d3a46977b04d49898fb43121f2878a5d38a0c77beb723f615c" + }, + "cargo/removal-app-format-2/stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/removal-app-format-2/stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/removal-app-removal-1/process.json": { + "bytes": 168, + "sha256": "69ac50e49f1f4ecb951768b130b963d0976a046c3da474c9ee5d321e431541fc" + }, + "cargo/removal-app-removal-1/result.json": { + "bytes": 3271, + "sha256": "622ead59b458a4194e50f77eba91366077a0a051157e03606db9dd43a8efb8f2" + }, + "cargo/removal-app-removal-1/source-proof.json": { + "bytes": 600, + "sha256": "19b9d547f39abbebefb45d8cf443e4ef09322f245ace12dd3ed8c9ab8b95dd51" + }, + "cargo/removal-app-removal-1/started.json": { + "bytes": 1547, + "sha256": "048fafc7f4003953af651fcf054e58ee7c0038c32178e6b2b0cfe4a8e18790fe" + }, + "cargo/removal-app-removal-1/stderr.log": { + "bytes": 210, + "sha256": "92b1f3a96398813bd920f97309f7ee41e7d3cb97c9f83852cc700b4638a76357" + }, + "cargo/removal-app-removal-1/stdout.log": { + "bytes": 299526, + "sha256": "fc091e38ddb6d4e4584a8c3e97c5a90d95c73386c97f8ed388c2159d352ad0e5" + }, + "cargo/removal-app-removal-2/process.json": { + "bytes": 168, + "sha256": "40b2b2e326875414ecd574b7ba4160c74410b1d06cb1aac6af24f15603223b61" + }, + "cargo/removal-app-removal-2/result.json": { + "bytes": 3272, + "sha256": "cd3e62a3d9398b3522ebbedad3eba581e6ca29e3a91ae88d68573045a0d820ae" + }, + "cargo/removal-app-removal-2/source-proof.json": { + "bytes": 600, + "sha256": "e36a67dbea645d338a7e8e3913a8c9257968dc6a1262d58b2b017ff5fa1b7bd9" + }, + "cargo/removal-app-removal-2/started.json": { + "bytes": 1547, + "sha256": "63d638cadf7848667e91095ce9e3f898a6342281f35898b85ee350ba4778bef2" + }, + "cargo/removal-app-removal-2/stderr.log": { + "bytes": 210, + "sha256": "6e3def5e3f44edcfe8342322c245f5bc0996d7c8bcdeb90f38f5b2c4b41fddea" + }, + "cargo/removal-app-removal-2/stdout.log": { + "bytes": 299526, + "sha256": "38dffa5fca44377fdfd98228e16b50293e54eecbb7b5c888239528ba86fa7222" + }, + "cargo/removal-app-scenario-1/process.json": { + "bytes": 169, + "sha256": "7e1e62c6b30cb7d91c8effc5c8c696b29682626085b63a8d54edc5bb488d5b78" + }, + "cargo/removal-app-scenario-1/result.json": { + "bytes": 1946, + "sha256": "59e33db18f50333da85959efd54226807964e03b8fd48f3b0eabedd3337eba36" + }, + "cargo/removal-app-scenario-1/source-proof.json": { + "bytes": 601, + "sha256": "36cb123c80dfbfbe653370706a52a0064a423de41709abdfc3e8a96a422e96d9" + }, + "cargo/removal-app-scenario-1/started.json": { + "bytes": 1548, + "sha256": "6d8233f8d4165c9980712430e711b927be91e9e0d0fb60cb19672569409638ce" + }, + "cargo/removal-app-scenario-1/stderr.log": { + "bytes": 164, + "sha256": "2d2e27b63b97344eae6d15a4df7bf461c4465eac49675f214a75859f068df234" + }, + "cargo/removal-app-scenario-1/stdout.log": { + "bytes": 343460, + "sha256": "04ed44f179f3ff138e7c01e4e9672752166d3b58b16e5b27adedfbcd6a45db81" + }, + "cargo/removal-app-scenario-2/process.json": { + "bytes": 169, + "sha256": "c879fb156bd2f1ab36b3a547b6fe213a5025e5a60eb3c5c0cadaf16a6de7d280" + }, + "cargo/removal-app-scenario-2/result.json": { + "bytes": 3277, + "sha256": "1661196bf0116ca838bc39ace55fb767e112d62e6d32488598a7ad365d087e3b" + }, + "cargo/removal-app-scenario-2/source-proof.json": { + "bytes": 601, + "sha256": "9ad5ace43e03bc99174bb4af6950dc5afa6c8441ce78a981a8caa5c423c82ed4" + }, + "cargo/removal-app-scenario-2/started.json": { + "bytes": 1548, + "sha256": "d56ea685c7ef6b6a470c9cf95672cd78c314a977c181e464873ac542cea620ee" + }, + "cargo/removal-app-scenario-2/stderr.log": { + "bytes": 1238, + "sha256": "3eec550b4cd86b13566407490315884e57c3ac2d3a44db1afc90f9d4a8ad76e0" + }, + "cargo/removal-app-scenario-2/stdout.log": { + "bytes": 334991, + "sha256": "85c26f01c9b676779936027529a9a8c2af5dc784935e85a13d329830f8dd619f" + }, + "cargo/removal-app-scenario-3/process.json": { + "bytes": 169, + "sha256": "4fea4ff6b0b123d42ab0c78db4a2aff552ed60d35c15441530c5299d1ef6349b" + }, + "cargo/removal-app-scenario-3/result.json": { + "bytes": 3274, + "sha256": "5b36fc538e7a1aca5c2c11874d130b3d4ec101a8a95d5229e26a52c70aadae4d" + }, + "cargo/removal-app-scenario-3/source-proof.json": { + "bytes": 601, + "sha256": "c7d3a48571aa4100b94c083f9dcce1630f8fad0f8e698cfe55cc50f53b14ad5b" + }, + "cargo/removal-app-scenario-3/started.json": { + "bytes": 1548, + "sha256": "7741d9c4996509be56a522e735b82d423a03148adaef88a91975468d57cb53cc" + }, + "cargo/removal-app-scenario-3/stderr.log": { + "bytes": 627, + "sha256": "86bf71f295a1164bb789fb0cf4d550df2b6155c931a55d84ab22614b635724be" + }, + "cargo/removal-app-scenario-3/stdout.log": { + "bytes": 334746, + "sha256": "5ada0abaf540afdf35e1113620a887774b3a6208b2a2e51ea594453bb2ce625c" + }, + "cargo/removal-app-scenario-4/process.json": { + "bytes": 169, + "sha256": "97a3802dd0f015870cea22c47493c392a606b3ec305a531b70484d73f87013d7" + }, + "cargo/removal-app-scenario-4/result.json": { + "bytes": 3274, + "sha256": "f64e762ca98b7ea84adc5432b1ba74322573d533db29f56a0ba04c89e481950d" + }, + "cargo/removal-app-scenario-4/source-proof.json": { + "bytes": 601, + "sha256": "71719bc542efdc35337773056f87dddff61af64a4ff59fb5d5158f6fee655755" + }, + "cargo/removal-app-scenario-4/started.json": { + "bytes": 1548, + "sha256": "ab6519777443606df82e304b90e557eb14163ad37119355dc9fdcad5e8b4a255" + }, + "cargo/removal-app-scenario-4/stderr.log": { + "bytes": 625, + "sha256": "550ec93faf55a99fafea3b5d33f6a618d89263eff510fee7b598248b8738de24" + }, + "cargo/removal-app-scenario-4/stdout.log": { + "bytes": 334746, + "sha256": "b3b648a29d06c232ba15a472c549e092b903c67f3ce85994373c0bad3d3b0a86" + }, + "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": { + "bytes": 10094, + "sha256": "7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a" + }, + "helpers/3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2.py": { + "bytes": 3778, + "sha256": "3e4cd38fd3807a4010a5a7102354f9139cab236ca55163c96090e416161e5fd2" + }, + "helpers/c86f51d9b8465341dab73d045923ec306b15ebabf7c97b81beac7afe73bd72a1.py": { + "bytes": 1396, + "sha256": "c86f51d9b8465341dab73d045923ec306b15ebabf7c97b81beac7afe73bd72a1" + } + } +} diff --git a/harness/scenario-group-removal-evidence-20260925/checks/prepare.py b/harness/scenario-group-removal-evidence-20260925/checks/prepare.py new file mode 100644 index 00000000..857bafce --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/checks/prepare.py @@ -0,0 +1,110 @@ +"""Package explicitly selected closed gate captures without running Cargo.""" +from pathlib import Path +import argparse +import json +import zipfile +from verify import RAW_FILES, pin, parsed, need, run_name, verify_data, verify_package + +HERE = Path(__file__).resolve().parent + + +def collect(root, runs, helpers, comparators=()): + gates = root / ".local/scenario-group-gates" + candidates = [gates / name for name in ("gate.py", "source-proof.py")] + helpers + helper_bytes = [path.read_bytes() for path in candidates] + comparator_paths = [root / ".local/process-source-evidence-tools/verify.py", *comparators] + comparator_bytes = [path.read_bytes() for path in comparator_paths if path.is_file()] + payload, logical, specs = {}, {}, {} + def add(name, data): + stored = ("capsules/" + pin(data)["sha256"] + Path(name).suffix + if name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"} else name) + need(stored not in payload or payload[stored] == data, "deduplication collision") + payload[stored] = data + logical[name] = stored + helper_catalog = {} + for name, data in zip(("gate.py", "source-proof.py"), helper_bytes): + helper = "helpers/" + pin(data)["sha256"] + ".py" + add(helper, data) + helper_catalog[name] = helper + for run in runs: + folder = gates / run + need(folder.is_dir(), "run directory missing: " + run) + paths = list(folder.iterdir()) + names = {path.name for path in paths} + need(all(path.is_file() and not path.is_symlink() for path in paths) + and names == RAW_FILES | {"source-proof.json"}, "exact closed raw files and source proof required: " + run) + raw = {path.name: path.read_bytes() for path in paths} + result = parsed(raw["result.json"]) + need("finish" in result and result["inputsUnchanged"] is True, "unfinished/changed run refused: " + run) + matches = [data for data in helper_bytes if pin(data) == result["helper"]] + need(bool(matches), "exact historical helper unavailable for " + run + "; supply --helper PATH") + helper = "helpers/" + result["helper"]["sha256"] + ".py" + add(helper, matches[0]) + for name, data in sorted(raw.items()): + add("cargo/" + run + "/" + name, data) + specs[run] = {key: result[key] for key in ("command", "head", "exitCode", "inputCount")} + specs[run]["helper"] = helper + if "source-proof.json" in raw: + proof = parsed(raw["source-proof.json"]) + matches = [data for data in comparator_bytes if pin(data) == proof["comparator"]] + need(bool(matches), "exact source comparator unavailable for " + run + "; supply --comparator PATH") + comparator = "comparators/" + proof["comparator"]["sha256"] + ".py" + add(comparator, matches[0]) + specs[run]["sourceProof"] = {"commit": proof["commit"], "pin": pin(raw["source-proof.json"]), "comparator": comparator} + manifest = {"schema": 1, "kind": "scenario-aggregate-removal-cargo-gates", "runs": specs, + "captureHelpers": helper_catalog, + "logicalFiles": dict(sorted(logical.items())), + "members": {name: pin(data) for name, data in sorted(payload.items())}} + summary = verify_data(manifest, payload.__getitem__) + return payload, manifest, summary + + +def write_json(path, value): + with path.open("xb") as output: + output.write((json.dumps(value, indent=2) + "\n").encode("utf-8")) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True, help="checkout holding .local/scenario-group-gates") + parser.add_argument("--runs", nargs="+", required=True, help="explicit run names, including failures to retain") + parser.add_argument("--helper", type=Path, action="append", default=[], help="additional exact historical helper (repeatable)") + parser.add_argument("--comparator", type=Path, action="append", default=[], help="additional exact historical source comparator (repeatable)") + parser.add_argument("--output", type=Path, help="fresh, nonexistent package directory (required unless --check-only)") + parser.add_argument("--check-only", action="store_true", help="validate raw captures in memory without creating an archive") + args = parser.parse_args() + need(all(run_name(run) for run in args.runs) and len(args.runs) == len(set(args.runs)), "unique safe run names required") + need(args.check_only or args.output is not None, "--output is required unless --check-only") + if not args.check_only: + need(not args.output.exists(), "output must be a fresh directory: " + str(args.output)) + payload, manifest, summary = collect(args.root.resolve(), args.runs, args.helper, args.comparator) + if args.check_only: + print("PASS raw consistency; no package written:", summary) + return + out = args.output.resolve() + out.mkdir(parents=True, exist_ok=False) + for name in ("evidence.zip", "manifest.json", "files.json"): + need(not (out / name).exists(), "existing package output refused: " + name) + for name in ("prepare.py", "verify.py", "README.md"): + data = (HERE / name).read_bytes() + destination = out / name + if destination.exists(): + need(destination.read_bytes() == data, "different existing package tool: " + name) + else: + with destination.open("xb") as output: + output.write(data) + with zipfile.ZipFile(out / "evidence.zip", "x", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: + for name, data in sorted(payload.items()): + info = zipfile.ZipInfo(name, date_time=(2026, 9, 23, 0, 0, 0)) + info.compress_type = zipfile.ZIP_DEFLATED + info.external_attr = 0o100644 << 16 + archive.writestr(info, data) + write_json(out / "manifest.json", manifest) + names = ("prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip") + write_json(out / "files.json", {name: pin((out / name).read_bytes()) for name in names}) + need(verify_package(out) == summary, "written package differs from validated captures") + print("PASS package readback:", out, summary) + + +if __name__ == "__main__": + main() diff --git a/harness/scenario-group-removal-evidence-20260925/checks/verify.py b/harness/scenario-group-removal-evidence-20260925/checks/verify.py new file mode 100644 index 00000000..71570429 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/checks/verify.py @@ -0,0 +1,195 @@ +"""Offline consistency checks only; never execute or extract archived inputs.""" +from pathlib import Path, PurePosixPath +from datetime import datetime +import argparse +import hashlib +import io +import json +import math +import re +import stat +import zipfile + +RAW_FILES = {"started.json", "process.json", "result.json", "stdout.log", "stderr.log", "inputs.json", "inputs.zip"} +OUTER_FILES = {"prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip"} + + +def need(condition, message): + if not condition: + raise ValueError(message) + + +def pin(data): + return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()} + + +def valid_pin(value): + return (isinstance(value, dict) and set(value) == {"bytes", "sha256"} + and type(value["bytes"]) is int and value["bytes"] >= 0 + and isinstance(value["sha256"], str) + and re.fullmatch(r"[0-9a-f]{64}", value["sha256"]) is not None) + + +def safe(name): + return (isinstance(name, str) and bool(name) and "\\" not in name and ":" not in name + and all(ord(char) >= 32 for char in name) + and not PurePosixPath(name).is_absolute() + and all(part not in ("", ".", "..") for part in name.split("/"))) + + +def run_name(name): + return isinstance(name, str) and re.fullmatch(r"removal-app-[A-Za-z0-9][A-Za-z0-9._-]*", name) is not None + + +def parsed(data): + def pairs(items): + result = {} + for key, value in items: + need(key not in result, "duplicate JSON key: " + key) + result[key] = value + return result + def constant(value): + raise ValueError("nonfinite JSON constant: " + value) + return json.loads(data, object_pairs_hook=pairs, parse_constant=constant) + + +def inventory(archive, expected): + names = archive.namelist() + need(len(names) == len(set(names)) and set(names) == set(expected), "exact ZIP membership") + for entry in archive.infolist(): + need(safe(entry.filename) and not entry.is_dir(), "unsafe ZIP member: " + entry.filename) + need(not stat.S_ISLNK(entry.external_attr >> 16), "ZIP symlink: " + entry.filename) + need(valid_pin(expected[entry.filename]), "invalid member pin: " + entry.filename) + need(entry.file_size == expected[entry.filename]["bytes"], "ZIP recorded size: " + entry.filename) + + +def ordered_times(*values): + times = [datetime.fromisoformat(value) for value in values] + return all(value.utcoffset() is not None for value in times) and times == sorted(times) + + +def verify_data(manifest, read): + """Shared read-only verifier for packaged bytes or prepare's in-memory payload.""" + need(manifest["schema"] == 1 and manifest["kind"] == "scenario-aggregate-removal-cargo-gates", "manifest schema") + runs, logical, stored = manifest["runs"], manifest["logicalFiles"], manifest["members"] + helpers = manifest["captureHelpers"] + need(isinstance(helpers, dict) and set(helpers) == {"gate.py", "source-proof.py"}, "capture helper names") + need(all(isinstance(name, str) and re.fullmatch(r"helpers/[0-9a-f]{64}\.py", name) + for name in helpers.values()), "capture helper mapping") + need(isinstance(runs, dict) and bool(runs) and all(run_name(run) for run in runs), "explicit run inventory") + need(all(safe(name) for name in logical) and all(safe(name) for name in stored), "unsafe manifest path") + need(set(logical.values()) == set(stored), "unreferenced or absent stored members") + for name, expected in stored.items(): + need(valid_pin(expected) and pin(read(name)) == expected, "stored member hash: " + name) + expected_logical = {"cargo/" + run + "/" + name for run in runs for name in RAW_FILES} + expected_logical.update(spec["helper"] for spec in runs.values()) + expected_logical.update(helpers.values()) + for run, spec in runs.items(): + need("sourceProof" in spec, run + ": source proof required") + if "sourceProof" in spec: + proof_spec = spec["sourceProof"] + need(set(proof_spec) == {"commit", "pin", "comparator"}, run + ": exact source proof spec") + need(isinstance(proof_spec["commit"], str) and re.fullmatch(r"[0-9a-f]{40}", proof_spec["commit"]), run + ": named full source commit") + need(valid_pin(proof_spec["pin"]), run + ": source proof pin") + need(isinstance(proof_spec["comparator"], str) and re.fullmatch(r"comparators/[0-9a-f]{64}\.py", proof_spec["comparator"]), run + ": comparator path") + expected_logical.update({"cargo/" + run + "/source-proof.json", proof_spec["comparator"]}) + need(set(logical) == expected_logical, "exact logical raw/helper inventory") + for name, destination in logical.items(): + if name.startswith("cargo/") and name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"}: + expected = "capsules/" + stored[destination]["sha256"] + PurePosixPath(name).suffix + need(destination == expected, "input capsule mapping: " + name) + else: + need(destination == name, "only input maps/archives may be deduplicated: " + name) + def raw(name): + return read(logical[name]) + for name, helper in helpers.items(): + need(helper == "helpers/" + pin(raw(helper))["sha256"] + ".py", "named helper hash: " + name) + seen_capsules = set() + for run, spec in runs.items(): + prefix = "cargo/" + run + "/" + start = parsed(raw(prefix + "started.json")) + process = parsed(raw(prefix + "process.json")) + result = parsed(raw(prefix + "result.json")) + required_start = {"start", "command", "cwd", "head", "scope", "inputs", "archive", + "inputCount", "environment", "helper", "cargo", "rustc"} + need(required_start <= start.keys(), run + ": incomplete start receipt") + need(all(result.get(key) == value for key, value in start.items()), run + ": start/result relationship") + command = result["command"] + need(isinstance(command, list) and command and command[0] == "cargo" + and all(isinstance(arg, str) for arg in command), run + ": Cargo command") + need(command == process["command"] == spec["command"], run + ": command relationship") + need(result["head"] == spec["head"] and re.fullmatch(r"(?:[0-9a-f]{40}|[0-9a-f]{64})", result["head"]), run + ": HEAD") + need(type(result["exitCode"]) is int and result["exitCode"] == spec["exitCode"], run + ": recorded exit") + need(result["inputsUnchanged"] is True, run + ": changed inputs refused") + need(type(result["seconds"]) in (int, float) and math.isfinite(result["seconds"]) + and result["seconds"] >= 0, run + ": duration") + need(type(process["pid"]) is int and process["pid"] > 0, run + ": process identity") + need(ordered_times(start["start"], process["observed"], result["finish"]), run + ": completed timestamp order") + for field, filename in [("inputs", "inputs.json"), ("archive", "inputs.zip"), ("stdout", "stdout.log"), ("stderr", "stderr.log")]: + need(result[field] == pin(raw(prefix + filename)), run + ": " + field + " pin") + need(valid_pin(result["helper"]) and result["helper"] == pin(raw(spec["helper"])), run + ": helper pin") + need(spec["helper"] == "helpers/" + result["helper"]["sha256"] + ".py", run + ": helper mapping") + inputs = parsed(raw(prefix + "inputs.json")) + need(isinstance(inputs, dict) and all(safe(name) for name in inputs), run + ": safe input inventory") + need(type(result["inputCount"]) is int and len(inputs) == result["inputCount"] == spec["inputCount"], run + ": input counts") + if "sourceProof" in spec: + proof_spec = spec["sourceProof"] + proof_bytes = raw(prefix + "source-proof.json") + proof = parsed(proof_bytes) + need(pin(proof_bytes) == proof_spec["pin"], run + ": source proof pinned bytes") + need(proof["run"] == run and proof["commit"] == proof_spec["commit"], run + ": proof run/commit identity") + need(proof["status"] == "PASS exact captured input inventory and Git blob bytes", run + ": source proof status") + need(proof["inputCount"] == len(inputs) and proof["inputMap"] == result["inputs"], run + ": proof input relationship") + need(proof["result"] == pin(raw(prefix + "result.json")), run + ": proof result relationship") + need(ordered_times(result["finish"], proof["verified"]), run + ": proof time after closed gate") + comparator = proof_spec["comparator"] + need(valid_pin(proof["comparator"]) and pin(raw(comparator)) == proof["comparator"], run + ": comparator bytes") + need(comparator == "comparators/" + proof["comparator"]["sha256"] + ".py", run + ": comparator identity") + need(sum(name.startswith("crates/vendor/iced_widget/") for name in inputs) == 71, run + ": vendor count") + capsule = (logical[prefix + "inputs.json"], logical[prefix + "inputs.zip"]) + if capsule not in seen_capsules: + with zipfile.ZipFile(io.BytesIO(raw(prefix + "inputs.zip"))) as source: + inventory(source, inputs) + for name, expected in inputs.items(): + need(pin(source.read(name)) == expected, run + ": source hash " + name) + seen_capsules.add(capsule) + artifacts = [] + for line in raw(prefix + "stdout.log").decode("utf-8", errors="replace").splitlines(): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("reason") == "compiler-artifact" and value.get("executable"): + artifacts.append(value) + need(isinstance(result["artifacts"], list), run + ": artifact records") + need(artifacts == [record["cargo"] for record in result["artifacts"]], run + ": Cargo JSON artifact relationship") + for record in result["artifacts"]: + need(set(record) == {"cargo", "readback"} + and (record["readback"] is None or valid_pin(record["readback"])), run + ": artifact readback pin") + print(run, "recorded exit", result["exitCode"], "inputs", len(inputs), "executable records", len(artifacts)) + return {"runs": len(runs), "recordedFailures": sum(spec["exitCode"] != 0 for spec in runs.values()), + "logicalFiles": len(logical), "storedMembers": len(stored), "sourceCapsulePairs": len(seen_capsules), + "captureHelpers": helpers, "sourceProofs": sum("sourceProof" in spec for spec in runs.values())} + + +def verify_package(root): + files = parsed((root / "files.json").read_bytes()) + need(set(files) == OUTER_FILES, "outer file inventory") + for name, expected in files.items(): + need(valid_pin(expected) and pin((root / name).read_bytes()) == expected, "outer hash: " + name) + manifest = parsed((root / "manifest.json").read_bytes()) + with zipfile.ZipFile(root / "evidence.zip") as archive: + inventory(archive, manifest["members"]) + return verify_data(manifest, archive.read) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("package", nargs="?", type=Path, default=Path(__file__).resolve().parent) + args = parser.parse_args() + print("PASS offline consistency:", verify_package(args.package)) + print("Historical receipts only; no source/binary execution or native acceptance claim.") + + +if __name__ == "__main__": + main() diff --git a/harness/scenario-group-removal-evidence-20260925/final-report-review.md b/harness/scenario-group-removal-evidence-20260925/final-report-review.md new file mode 100644 index 00000000..1252f908 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/final-report-review.md @@ -0,0 +1,14 @@ +# Final removal report evidence audit + +Reviewed `harness/scenario-group-removal-app-20260925.md` against source `43340b94a13f192c3b5d3c3112dbe87246790a44`, the eleven raw removal gate result/source-proof records, relevant raw test summaries, current CLI preflight, both native process completion receipts, fixture manifest, six actual saved source snapshots and parent native observation notes. + +**Finding: no blocking unsupported implementation/validation claim, count/source mismatch or contradiction identified within this audit's scope.** + +- The five final gates identify source43340 and input-map SHA256 `839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f`; all record exit0, unchanged823 inputs and exact Git-blob proof PASS. Raw final summaries match333/0/1/1296filtered and53/0/0/1577filtered. Eleven attempts and three retained failures are correct. The earlier scenario331/2/1 result and four-source history match the records. Filters are explicitly overlapping rather than summed. +- Source contains ten planner and eight App test functions as reported. The boxed-snapshot-only final delta preserves the captured snapshot and admission semantics. The single visibility enumeration fix is present. Full-set transaction, model/source Undo versus transient selection, stale-token refusal and explicit review confirmation descriptions agree with the inspected source. +- Build receipt agrees with the reported120,067,072-byte GUI hash. Current CLI preflight identifies source43340 and successful checks of both fixtures, with the stated libunwind pin. Both process completion receipts record exit0, empty logs and unchanged immutable inputs. +- Independently rehashed all six actual snapshot files: baseline/cancel/Undo are4389 bytes with the reported70c32355… hash; removed/Redo/reopened are3856 bytes with the reported1cb04cba… hash. Counts2removed/10updated and the12-record impact agree with the predeclared manifest and parent observation notes. Compact capture dimensions1102×732 agree with those notes and are correctly described as capture dimensions. +- The report explicitly distinguishes mounted Delete/Shift+Delete routing from the unsuccessful native Delete attempt at capture35. Native additive selection is contextual rather than Shift-click. Keyboard-only confirmation, broad accessibility, long-alias stress, native SA/Fragment/reuse, Linux and full-suite acceptance remain excluded. A real App source-write-failure execution remains an explicit runtime gap; static atomicity is not substituted for it. +- Input and capture recovery failures remain described, and fresh reopen is expressly limited to source persistence. No default-branch integration, release or full issue29 closure is asserted. + +Independence limits: this reviewer authored the removal panel and previously reviewed the adapter/planner; panel source observations are self-review, not independent UI acceptance. No screenshots were interpreted in this audit: independent original-image review belongs to Herschel. ZIP completeness/offline verification belongs to Godel; the evidence README/package links were still being finalized when inspected, so this audit is not a package-verification claim. The peripheral Windows networking/WSL DNS paragraph is parent operational reporting and was not independently re-executed here. No tests, builds, GUI interactions, Git writes or production edits were performed; only this report was written. diff --git a/harness/scenario-group-removal-evidence-20260925/native-observation-notes.md b/harness/scenario-group-removal-evidence-20260925/native-observation-notes.md new file mode 100644 index 00000000..eac01af5 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/native-observation-notes.md @@ -0,0 +1,32 @@ +# Scenario group removal: parent native observations + +Source `43340b94a13f192c3b5d3c3112dbe87246790a44`; Windows GNU/LLVM desktop/CLI build `removal-app-build-1`. Observed with Computer Use `@oai/sky` on 2026-09-25 UTC. Original captures and unsuccessful input attempts remain in the run directories. No production changes occurred during either run. + +## Run 1 + +PID 7904, closed normally at 02:09:03.784416 UTC, exit 0, empty stdout/stderr, immutable inputs unchanged. Generated working copy only; original fixture and oracle were not edited. + +- Captures 01–17: Home, file picker and baseline Saved A. The initial nonmaximized 1442x816 view had navigation clicks miss their visible targets. Reobservation and activation did not resolve that; maximizing to 1605x872 allowed navigation. File picker UIA focused-element text reported the search box while the visible filename caret and typed path were in the filename field. Enter opened the verified path. Baseline Save matched all 4389 original bytes. +- Captures 18–23: 100% zoom placed the participant headers above the viewport. A scroll attempt without screenshotId failed with a 16x16 bounds error; the repeated screenshot-bound attempt did not pan. Fit restored the full sequence. These attempts do not establish successful panning or readable 100% header navigation. +- Captures 24–26: click Intake participant, right-click first message, Add to selection. Exactly two selected; Properties identifies primary alias `a`, participant alias `intake_lane`. This is contextual additive selection, not native Shift-click coverage. +- Captures 27–32: header Remove opens review for 2 selected removals and 10 updated preserved records, 12 matches in two pages. First page shows intake_lane, a, review_flow, b/c/d; second shows e/f/g/h and saved_a/saved_b. Repeated display names have distinct readable aliases. Search `@h` returns only preserved h; `@h_absent` shows explicit no-match text. Overall impact stays 2/10. Enter in focused search does not confirm. Footer remains visible. +- Captures 33–34: explicit Cancel preserves two-member selection and exact baseline source after Save. +- Capture 35: Delete after cancel/save did not open review; canvas keyboard focus was not established. The filename says `delete-opens-review` but the image shows no review. Do not claim native Delete entry success. Mounted Scene tests supply separate input-routing evidence. +- Captures 36–39: selected-message contextual menu exposes one group removal action; it opens the same whole-set review. Explicit Remove applies once. Selection clears, status identifies 2 removed in one change and preserved definitions. Both surviving participant headers and seven unfinished message bodies remain; Saved A states seven unfinished positions retained until endpoints complete. Save matches the independently pinned 3856-byte expected removed file exactly. +- Captures 40–41: one Ctrl+Z followed by Save exactly restores the baseline. Transient selection stays empty; this is expected and distinct from model Undo. +- Captures 42–45: reselect the same participant/message by click/context Add; open review while original removal remains available to Redo. +- Capture attempt 46: UIA Restore led to a minimized-window capture error. Activation and returned-window recovery produced capture47 at1442x816, showing expiry notice and disabled Remove. Native system menu sizing (48–55) produced1102x732. Compact expired review keeps its notice, Cancel and disabled Remove visible; impact body scrolls. No proof of exact client-area dimensions is claimed; these are capture sizes. +- Capture56: Escape dismisses expired review, retaining two selected. Captures57–59: fresh compact review has enabled explicit action, readable aliases and fixed footer; scroll then Next exposes page2 including both saved views. All rows in this fixture remain discoverable. This is not an arbitrarily long-alias or large-scale paging stress test. +- Capture60: explicit Cancel leaves the group unchanged. Capture61: one Ctrl+Y successfully redoes the original removal after resize/expiry/reselection/cancellation. Capture62 Save exactly matches expected removed bytes. Captures63–64 open preserved Saved B; its two participants and seven unfinished messages remain. + +Exact snapshots: `01-baseline` and `02-cancel` and `04-undo` equal baseline SHA256 `70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a` (4389 bytes). `03-removed` and `05-redo` equal removed SHA256 `1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f` (3856 bytes). Every comparison was full bytes without normalization and passed on its first saved-source comparison. No oracle revision was needed. + +## Run 2 + +Fresh PID6756, prepared explicitly from run1 `snapshots/05-redo.arcadia`, same exact build/runtime. Closed normally at02:12:09.320969 UTC, exit0, empty stdout/stderr and unchanged immutable inputs. + +Captures01–10 show fresh launch and File Open. The first filename typing attempt was not visible after fresh observation; Alt+N refocused it, second typing became visible, and Enter opened the exact run2 working path. Captures11–14 navigate the persisted Scenario and Saved A: three reusable OA activities still listed, two participants and seven unfinished messages retained. Capture15 Save and snapshot `01-reopened` match the removed file exactly. This verifies source persistence, not history or transient-selection persistence. + +## Bounded judgment + +Parent accepts both runs and current CLI fixture-preflight-1 for these bounded workflows, subject to independent evidence review before publication. No native Shift-click, successful focused Delete entry, keyboard-only confirmation, screen-reader completeness, long unbroken alias stress, native Fragment/SA/reuse expansion, real App source-write failure, Linux, default-branch integration or release acceptance is established. Native accessibility tree exposes mostly window chrome. Core/planner and mounted App tests remain separate evidence for cases not exercised here. Operational capture/input recoveries above are retained and do not count as successful actions. diff --git a/harness/scenario-group-removal-evidence-20260925/native-review.md b/harness/scenario-group-removal-evidence-20260925/native-review.md new file mode 100644 index 00000000..84a810f9 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/native-review.md @@ -0,0 +1,51 @@ +# Bounded native evidence review — Scenario group removal + +Reviewed 2026-09-25 UTC. Captured source: `43340b94a13f192c3b5d3c3112dbe87246790a44`, build `removal-app-build-1`. **No blocker found for accepting the two documented native runs as bounded evidence of this fixture/workflow.** This is not acceptance of every #29 interaction, default-branch integration, or a release. + +## Reviewer independence and method + +This reviewer authored the pure group-removal planner, preparation fixture, source-derived byte oracle, and initial provenance helpers. Therefore this is self-review of those parts, not an independent correctness endorsement of their shared assumptions. Other agents authored the App/view/input integration; review of its captured presentation and operation is independent of that implementation. The parent performed the native interactions. I inspected existing original images and records, independently recomputed hashes and direct whole-file equality in a read-only Python script, and did not run the product, archived helpers, Cargo, Git, or GUI automation. Only this review document was written. + +Records examined: `native-observation-notes.md`; root fixture manifest and both source files; each run's `prepared.json`, `started.json`, `finished.json`, all twelve prepared immutable files, captured build `result.json`/`source-proof.json`/`inputs.json`, all saved-source snapshot receipts and evaluator outputs, all capture JSON records and existence of their listed images; `fixture-preflight-1/result.json`, both CLI reports/logs/fixture copies and its CLI executable. I checked the captured proof-to-build/input bindings, not a fresh reconstruction of Git blob provenance or the current checkout. Packaging/archive validation is outside this review. + +## Original images inspected + +All names below are within `run-1` unless stated otherwise. I inspected the full original image, using `-1.jpg` where the capture also contains the 16×16 window icon; `-0.jpg` is the full image for the compact/nonmaximized captures. + +| Captures | Direct visual result | +| --- | --- | +| `27-review-page-one`, `28-review-page-two` | Review says 2 Scenario objects, 2 removed / 10 updated, 12 matches, two pages. The pages expose intake_lane, a, review_flow, b–h, saved_a and saved_b with distinct aliases despite repeated message names. Disposition labels distinguish removed selected objects from updated preserved records. Both footer actions are visible. | +| `30-alias-filter`, `31-empty-filter`, `32-enter-keeps-review` | `@h` shows only preserved h; `@h_absent` shows the explicit no-match state. The total impact remains 2/10. Capture 32 still shows the open review and unchanged empty query result. This corroborates the parent's reported Enter attempt, but screenshots alone do not prove which key was delivered or its focus route. | +| `33-canceled`, `35-delete-opens-review` | No review; two selected remain, including primary alias a and highlighted participant/message. Capture 33 reports cancellation. **Capture 35's filename is inaccurate: it provides no evidence that Delete opened a review.** The notes correctly exclude native focused-Delete success. | +| `38-confirmed-removal` | Selection becomes zero; Intake participant/a disappear, two participant headers and seven unfinished message bodies remain. Status says two selected Scenario objects removed in one change, definitions preserved. The three operational activities remain listed. Saved A explains that seven unfinished positions are retained until endpoints are complete. | +| `40-undo` | Three participant headers and eight message arrows return; status says model change undone; selection remains zero. This corroborates the model transition, not restoration of transient selection. | +| `47-size-recovery`, `55-compact-review-expired` | Expiry text is explicit and Remove is disabled; Cancel remains enabled and visible. The compact image is 1102×732 including window chrome. Its body scrolls while the notice/footer remain visible. | +| `56-escape-cancel`, `57-compact-valid-review`, `59-compact-second-page` | After the reported Escape, the review is gone and two selected remain. A fresh compact review has an enabled explicit Remove action. Both pages retain readable aliases; page two exposes e–h and both saved views. The footer is visible. This supports this fixture's compact layout, not arbitrary alias length, scale, or keyboard/screen-reader completeness. | +| `61-redo`, `64-saved-b-preserved` | Redo status and the removed model recur with zero selected. Saved B remains navigable and shows its two participants/seven unfinished messages. | +| `run-2/14-reopened-saved-a`, `run-2/15-reopen-saved` | Fresh-process source shows Saved A, two participants, seven unfinished messages, and all three reusable operational activities. Capture 15 reports all source files saved. | + +The full compact captures are genuinely 1102×732 images; they do not establish that the client area has those dimensions. I did not infer successful panning, 100%-zoom header usability, or reliable initial nonmaximized navigation from the failed/recovered attempts described in the notes. + +## Exact source, immutable inputs, and lifecycle readback + +Independent direct byte comparisons passed, without invoking the comparator or normalizing whitespace: + +- Run 1 `01-baseline`, `02-cancel`, `04-undo`: exact original **4389 bytes**, SHA256 `70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a`. +- Run 1 `03-removed`, `05-redo` and Run 2 `01-reopened`: exact original removal oracle **3856 bytes**, SHA256 `1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f`. +- Both final working copies also equal that removal oracle. Every snapshot receipt pins the actual file, records exit 0, and has a matching PASS evaluator report and empty evaluator stderr. All snapshot timestamps fall within their recorded process lifetimes. + +These complete-file comparisons substantiate the intended two deletions, seven sender clears, owner-list update, and pruning of only the deleted rows in both layouts, including preservation of all other source content/trivia. They also demonstrate that the source-derived oracle needed no post-observation revision. They do not replace an independent core semantics specification review. + +Both runs' twelve prepared immutable files match their recorded hashes now, including the exact **120067072-byte** GUI executable SHA256 `e118e7f0a2ff53ac9c22a73d07555929d11e1ad917d430a7ae88d469aaa91155` and pinned `libunwind.dll`. GUI artifact hashes match the captured build receipt. Build/proof/input pins agree on source 43340b94…, **823 inputs**, successful exit, and unchanged captured inputs. Run 2's initial pin and actual initial source equal Run 1's saved `05-redo` bytes. + +Run 1 PID 7904: started `01:55:58.923381`, finished `02:09:03.784416` UTC. Run 2 PID 6756: started `02:09:43.998114`, finished `02:12:09.320969` UTC. Both supervisors record exit 0, `immutableUnchanged: true`, and zero-byte stdout/stderr; these hashes recompute correctly. Started receipts bind their prepared records, executable paths, process creation identities and initial sources. All discovered capture records identify the corresponding run executable and have timestamps within its lifetime. This is recorded lifecycle evidence, not a fresh query of already-exited OS processes. + +Run 1 has **62 capture records / 101 referenced image files**; Run 2 has **15 / 29**. Every image referenced by a saved capture record exists. No `46*` record or image exists. The reported capture46 failure therefore has no image to inspect; its error/recovery description is the parent's operational account. It must remain a failed attempt, never be counted as a successful capture or replaced with capture47. This is consistent with discovery-based packaging; numeric labels are not a promise of a contiguous screenshot inventory. + +The CLI preflight's two fixture copies, captured report/log pins and CLI executable pin match. Both reports say `checked`, exit 0, `written: false`; warnings are present. This establishes recorded parser/check success, not zero diagnostics or a full-model JSON export. + +## Acceptance boundary + +The evidence supports contextual additive group selection, whole-set impact review/search/paging, explicit cancellation, explicit removal through the documented review, exact source restoration/reapplication after the reported Undo/Redo, safe expired-review presentation after resizing, compact review discoverability for these twelve rows, both surviving saved views, and persistence after fresh-process reopening. + +The one-Undo/one-Redo claim combines the parent's action account, UI status/captures and exact source states. I did not directly introspect the history stack or independently replay the keys. Likewise, no screenshot proves rejection of every stale packet. Native Shift-click, successful focused Delete entry, keyboard-only confirmation, complete accessibility, larger/longer-label stress, Fragment/SA/reference-expansion cases, actual source-write failure, other platforms, integration and release acceptance remain outside these runs. Separate mounted/core tests must be cited under their own scope. With these limits retained, I recommend the parent accept the two runs for their stated bounded workflows and proceed to package verification. diff --git a/harness/scenario-group-removal-evidence-20260925/native/manifest.json b/harness/scenario-group-removal-evidence-20260925/native/manifest.json new file mode 100644 index 00000000..17192d50 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/native/manifest.json @@ -0,0 +1,1287 @@ +{ + "kind": "scenario-aggregate-removal-native-evidence", + "archive": { + "bytes": 6942333, + "sha256": "9eb28f970d256160238234279fa91ad60e404e8b11d8d7e6d55178999919e2b1" + }, + "members": { + "fixtures/baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "fixtures/expected-removed.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "fixtures/fixture-manifest.json": { + "bytes": 882, + "sha256": "2c7b8996b0bcfadfce727e013c4520ecf41e6b6d3ba1e874057a16df2a4a43b0" + }, + "helpers/NATIVE-EVIDENCE.md": { + "bytes": 3038, + "sha256": "74e680cc458e2821124dcbe9918f2d6251d1ff5e40ddab6e1b6b9bc96d30e2f1" + }, + "helpers/README.md": { + "bytes": 8350, + "sha256": "52f4283be0c027c1b0419461ebdcfe7c192d12087e0b139f889148c51c78a2e8" + }, + "helpers/capture.js": { + "bytes": 1589, + "sha256": "71c2ee3c0fbcd6f6d756ba65f732d51500257e6052a35890615af4d3aef2c476" + }, + "helpers/cli-preflight.py": { + "bytes": 5661, + "sha256": "f7f6ceb2686fc5d17929f842952596919f08b7212a25a209cd835989670255d3" + }, + "helpers/independent-native-review.md": { + "bytes": 9370, + "sha256": "12f4491a636a76f3c53d116927ad2901e5df301838ccf89e88c50f2ca3823eca" + }, + "helpers/native-evidence-package.py": { + "bytes": 6013, + "sha256": "0dea3b02bd4390cc36968f4e3b7a929774b30e170a0d5b3fbd240d910019a8df" + }, + "helpers/native-evidence-selfcheck.py": { + "bytes": 3221, + "sha256": "c0de1578f44fe733460319741299a45afa2599c7225afe7d862e5d640ae9421a" + }, + "helpers/native-evidence-verify.py": { + "bytes": 19313, + "sha256": "03b6b941580ca0c5149f7751e9aa3a8ca2e58aad98d589626029905de04c51a2" + }, + "helpers/native-harness.py": { + "bytes": 13148, + "sha256": "7db4a634633e50a94f7f9b20370688955e7f00c137a7036d9c2ab7a8bea59004" + }, + "helpers/native-observation-notes.md": { + "bytes": 6151, + "sha256": "facffadb45ecbba5e88184e6e7558965b893b4f788b9736876e1b45f3ecd3d7d" + }, + "helpers/packaging-audit-notes.md": { + "bytes": 848, + "sha256": "d76c7b73747d79e49cd78be123377fea2c7fe1720ad9f5cecee60a998452495c" + }, + "helpers/prepare-fixtures.py": { + "bytes": 4887, + "sha256": "532a8ddca6e26918d071c5a66825560a48ba82b2adc6ce1bfc800ce712c97c66" + }, + "helpers/selfcheck.py": { + "bytes": 2654, + "sha256": "4d6a5e58ad5f49b977e0c3525cdaf6804e594c4e89321f4642f20823e10101cc" + }, + "helpers/verify-captured.py": { + "bytes": 2019, + "sha256": "32078fe720f00f6c123daa3d7d0cbbd4d296211d3610eb33dec4f74c5be2f573" + }, + "preflight/fixture-preflight-1/baseline.arcadia.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "preflight/fixture-preflight-1/baseline.arcadia.stdout.json": { + "bytes": 6752, + "sha256": "3bee31a8bd9109974b6e38ef5817d198027ad37f5a204710f52aabc68521a842" + }, + "preflight/fixture-preflight-1/evidence/cli-preflight.py": { + "bytes": 5661, + "sha256": "f7f6ceb2686fc5d17929f842952596919f08b7212a25a209cd835989670255d3" + }, + "preflight/fixture-preflight-1/evidence/fixture-manifest.json": { + "bytes": 882, + "sha256": "2c7b8996b0bcfadfce727e013c4520ecf41e6b6d3ba1e874057a16df2a4a43b0" + }, + "preflight/fixture-preflight-1/evidence/inputs.json": { + "bytes": 138269, + "sha256": "839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f" + }, + "preflight/fixture-preflight-1/evidence/native-harness.py": { + "bytes": 13148, + "sha256": "7db4a634633e50a94f7f9b20370688955e7f00c137a7036d9c2ab7a8bea59004" + }, + "preflight/fixture-preflight-1/evidence/result.json": { + "bytes": 4454, + "sha256": "539b7536236430b955e2657dd1e5b9ff905c029e5d1d10c2ac194d7d7847464a" + }, + "preflight/fixture-preflight-1/evidence/source-proof.json": { + "bytes": 598, + "sha256": "b548459a93f6510422eb8dd8542c9eadfc92604c137bf73b3ffaca4c8d9edffe" + }, + "preflight/fixture-preflight-1/evidence/verify-captured.py": { + "bytes": 2019, + "sha256": "32078fe720f00f6c123daa3d7d0cbbd4d296211d3610eb33dec4f74c5be2f573" + }, + "preflight/fixture-preflight-1/expected-removed.arcadia.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "preflight/fixture-preflight-1/expected-removed.arcadia.stdout.json": { + "bytes": 9306, + "sha256": "986d89f8098db95d42dee75fea11f407aef314e90f0ca020201365503f10b73d" + }, + "preflight/fixture-preflight-1/fixtures/baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "preflight/fixture-preflight-1/fixtures/expected-removed.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "preflight/fixture-preflight-1/result.json": { + "bytes": 3338, + "sha256": "6f155edb913549cdb29834839433290bffaff0c86205735a1fb7d7591ad3f855" + }, + "preflight/fixture-preflight-1/started.json": { + "bytes": 1800, + "sha256": "d710a8539aacc6c48c335177376088617ad07cf7856e07743f25950e0272ccb6" + }, + "preparation/native-evidence-preparation.json": { + "bytes": 975, + "sha256": "668da9ba4c636c1c9c23c6052941996f9646a625e5b0c903287e48e1033a986a" + }, + "preparation/preparation-selfcheck.json": { + "bytes": 1563, + "sha256": "5e5726e7edb92eb583318f9699602fdfd35d1ee4eecd52e30d3e3382383cdf59" + }, + "preparation/review-config.json": { + "bytes": 338, + "sha256": "c3d91eb3c723fc3777a09a657a8d05ace8d71b337839aaefca005ce06ee8ffef" + }, + "review-config.json": { + "bytes": 474, + "sha256": "50d4802f1d0f92509e31dd785825e0c36a83b6bfa89719619bf5884844844d7d" + }, + "runs/run-1/01-start-0.jpg": { + "bytes": 105138, + "sha256": "b74ba8ef97e80450dca264e9917f5d467fc757de7785ad4bf0f4a10c9828e48d" + }, + "runs/run-1/01-start.json": { + "bytes": 908, + "sha256": "cb72f571fe3ff731df95f92d25d9161197533f4bc0114e755f326be757419cee" + }, + "runs/run-1/02-open-0.jpg": { + "bytes": 101554, + "sha256": "f397d802e671bc82318678c12b24cb7e2140317e41640043e3bd9f4068ac52e2" + }, + "runs/run-1/02-open.json": { + "bytes": 907, + "sha256": "1aa34835b9233bf127294a68f6f8e3d3375563f27595993c93c31ec18bcadb67" + }, + "runs/run-1/03-open-dialog-0.jpg": { + "bytes": 674, + "sha256": "5a2387a1a593a32ea169b56b9a3e59333936ee1da95164564e4d9be61bf5a24b" + }, + "runs/run-1/03-open-dialog-1.jpg": { + "bytes": 99666, + "sha256": "b74321102ec2e14d3f70f5bcabf045773a94437818505202e5855ed27677c03f" + }, + "runs/run-1/03-open-dialog.json": { + "bytes": 10042, + "sha256": "b5ff82e7008c4e11b60e7482b56f6de5fcf01d1f2cd2bd334c68e6fc81b65660" + }, + "runs/run-1/04-filename-focus-0.jpg": { + "bytes": 674, + "sha256": "5a2387a1a593a32ea169b56b9a3e59333936ee1da95164564e4d9be61bf5a24b" + }, + "runs/run-1/04-filename-focus-1.jpg": { + "bytes": 99842, + "sha256": "c7faab11050606f1104f2714af18351153d2ef05b18ff6f987c07545ac306ca9" + }, + "runs/run-1/04-filename-focus.json": { + "bytes": 10048, + "sha256": "96aee118aeda6f495d295929d41f56337b9f94c6704c4698faacaade33c1fc00" + }, + "runs/run-1/05-filename-focus-0.jpg": { + "bytes": 674, + "sha256": "5a2387a1a593a32ea169b56b9a3e59333936ee1da95164564e4d9be61bf5a24b" + }, + "runs/run-1/05-filename-focus-1.jpg": { + "bytes": 99927, + "sha256": "75c008f0f493e01358f13038c4f55e0608618d0dfc9f4385bbcf489c8239752b" + }, + "runs/run-1/05-filename-focus.json": { + "bytes": 10048, + "sha256": "56838a32b9ec7fae946846f1f3e1100843afb176ac8a7abcd01f05fb1e8cf2cc" + }, + "runs/run-1/06-file-path-0.jpg": { + "bytes": 674, + "sha256": "5a2387a1a593a32ea169b56b9a3e59333936ee1da95164564e4d9be61bf5a24b" + }, + "runs/run-1/06-file-path-1.jpg": { + "bytes": 102688, + "sha256": "6d576322735d313499d8e2f8578ab6a565e34a5702b191b598deaf0726ea3592" + }, + "runs/run-1/06-file-path.json": { + "bytes": 10038, + "sha256": "550cd6f529d773f85f66172a6608f2e050c87bcffede4435ee8bb12c37080978" + }, + "runs/run-1/07-open-enter-0.jpg": { + "bytes": 88124, + "sha256": "942ac6b9817136a21b87a0f60cad7df1c58557f4003190ad1f10101bc65db175" + }, + "runs/run-1/07-open-enter.json": { + "bytes": 961, + "sha256": "dcb05b3ce2cad707b9c969b772956e0206db2de847b8a073c39a9c76a101508d" + }, + "runs/run-1/08-scenario-0.jpg": { + "bytes": 88113, + "sha256": "3c8b03b7b691c79ca820ad41ecfde9a3f1d273ffbdc9e5030744367ed82c0723" + }, + "runs/run-1/08-scenario.json": { + "bytes": 971, + "sha256": "0e2932fec2d09eb6c428048072c19f4a3cbe80e7a668911c9632928402a150ce" + }, + "runs/run-1/09-scenario-loaded-0.jpg": { + "bytes": 88174, + "sha256": "65dcdb074363700d44d0a13eb01a9823c5bdb5a92f4ee04c2097a27b1130d000" + }, + "runs/run-1/09-scenario-loaded.json": { + "bytes": 978, + "sha256": "73099ff265859750b3192e9f8dbafbe5b897628a7375981558eda967dab11b43" + }, + "runs/run-1/10-active-main-0.jpg": { + "bytes": 88402, + "sha256": "f1ace02882a3c16ef419f69d619905fa66c28549f93609bb9e843e43709cd838" + }, + "runs/run-1/10-active-main.json": { + "bytes": 974, + "sha256": "edfe9e297ac4f96df8e2a2da9b5fe84157557daee79f7d06b85536e70524f1fe" + }, + "runs/run-1/11-scenario-coordinate-0.jpg": { + "bytes": 88362, + "sha256": "77fdfda8ae5063f40be19dedcfc1040e48e6b0b5bf42577b6f7ef3b499b1af81" + }, + "runs/run-1/11-scenario-coordinate.json": { + "bytes": 982, + "sha256": "ef14f0ddee9de187edadc4ae1797ad9587559ed7463c5f4b2a6da56edb82c205" + }, + "runs/run-1/12-maximize-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/12-maximize-1.jpg": { + "bytes": 94339, + "sha256": "acaef42377a368c46d67863fbefab1c834cffb478d3a2486d864fff00df0693e" + }, + "runs/run-1/12-maximize.json": { + "bytes": 1084, + "sha256": "5c7a3f3b60cf1b1d9f35f5bcc8876045dce27fa00900136147939ada3a6245f7" + }, + "runs/run-1/13-scenario-open-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/13-scenario-open-1.jpg": { + "bytes": 103848, + "sha256": "36edcee78a0592da51089f5db9605c7da4ab7e52508ac8685131f8626c1abdc1" + }, + "runs/run-1/13-scenario-open.json": { + "bytes": 1094, + "sha256": "243ba72908a07e534d4b8e8f2e66ab4b691c4a879d4f1fc174390b6f7c71b93a" + }, + "runs/run-1/14-behavior-workspace-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/14-behavior-workspace-1.jpg": { + "bytes": 129936, + "sha256": "2dd3f2a2d5b020b8112b831c5168ccdfbf762978e0b6b29891475e916d8b539f" + }, + "runs/run-1/14-behavior-workspace.json": { + "bytes": 1104, + "sha256": "ee8b83a6332f96c460c57cba2ea16bc149eb3a20a9e7fee51cda9425accf35d7" + }, + "runs/run-1/15-arrangements-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/15-arrangements-1.jpg": { + "bytes": 130529, + "sha256": "807bf1cd90f2d07b93ef312664548643a6401d361896e46931c6b71a7b89e9f1" + }, + "runs/run-1/15-arrangements.json": { + "bytes": 1092, + "sha256": "5d4ecd49bd94a88e1cb645eb58a231de531b41c2c51c3cc2700fb864f105aa91" + }, + "runs/run-1/16-saved-a-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/16-saved-a-1.jpg": { + "bytes": 123269, + "sha256": "ca000c2c3414e75be95849a861b1fadc932d3afbf26b7f96b3c78868da144c65" + }, + "runs/run-1/16-saved-a.json": { + "bytes": 1082, + "sha256": "a126dc7cab928918c21c93e15e88e18bf89b1c9dbd342607d8bd5ebe310049a3" + }, + "runs/run-1/17-baseline-saved-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/17-baseline-saved-1.jpg": { + "bytes": 121674, + "sha256": "f0384e611b63fd28807f5d92145d724441632b1e562f1d1132dcec2c8d53ac85" + }, + "runs/run-1/17-baseline-saved.json": { + "bytes": 1096, + "sha256": "4f11acd1b0bd6f2a6f59b35dc226936402fe970f3ab39d1035176e966167fd50" + }, + "runs/run-1/18-readable-scale-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/18-readable-scale-1.jpg": { + "bytes": 128794, + "sha256": "6d8737989a7cb0e57d09ba9f07c62df88f554bcdc2ce6fe58cdae6653feee8ec" + }, + "runs/run-1/18-readable-scale.json": { + "bytes": 1096, + "sha256": "c06ef506903283cab984de5f60484093d1d11464f31a729b50ed5431790d35e8" + }, + "runs/run-1/20-refresh-pan-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/20-refresh-pan-1.jpg": { + "bytes": 128878, + "sha256": "be1ee386d05de68d49bc799286120e21c051f5b617855a333fd4dd8e6fa0200a" + }, + "runs/run-1/20-refresh-pan.json": { + "bytes": 1090, + "sha256": "7dca54c75136fe373a0069253840f4cc8abf9165bfe3b8642d6b948506e0e2f6" + }, + "runs/run-1/21-pan-headers-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/21-pan-headers-1.jpg": { + "bytes": 126757, + "sha256": "17660b7a7f48e8fffeef8aa58ed742fe97b839b9532e78d829802e743af04774" + }, + "runs/run-1/21-pan-headers.json": { + "bytes": 1090, + "sha256": "cb9f430e4120b202978960aa59a4dc27e021cc7d0ed9f2b51030cdae575c74f2" + }, + "runs/run-1/22-after-pan-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/22-after-pan-1.jpg": { + "bytes": 126835, + "sha256": "071bac2e3faa2c20feaf1761352b90d9b6576b99405e0a6fae91dca8babc8340" + }, + "runs/run-1/22-after-pan.json": { + "bytes": 1086, + "sha256": "e6d47c1b3a3a3480f8594057f2a75fa9b33d2bd9bf47f03246e92b0fb80cb3cb" + }, + "runs/run-1/23-fit-selection-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/23-fit-selection-1.jpg": { + "bytes": 124511, + "sha256": "a2f451f68e2d3e8b5f4a9cf2976c444e6f44cf601d0de04ac65bb52fc2ddc3cc" + }, + "runs/run-1/23-fit-selection.json": { + "bytes": 1094, + "sha256": "5546179e7fa8a2483681ac096151bf8e5898825a4c9f0fd13f17b4c4d59f667c" + }, + "runs/run-1/24-select-participant-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/24-select-participant-1.jpg": { + "bytes": 123575, + "sha256": "91d24f3d9cfba1f2468a89ddab85666c70fc38a6b65d381906baf427eb1ede64" + }, + "runs/run-1/24-select-participant.json": { + "bytes": 1104, + "sha256": "8641317e67f3914f71f47982523816c5485ca41c89d5d20dc25b454b81ffbca1" + }, + "runs/run-1/25-message-context-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/25-message-context-1.jpg": { + "bytes": 130870, + "sha256": "9e60d21d72597153b57c17124c1cb6d3b059767bd97b24a2779fec40b8203415" + }, + "runs/run-1/25-message-context.json": { + "bytes": 1098, + "sha256": "1f01c5890b491b7b73e2a01425ad640bc289ca7bb2963bd931b17133807b321c" + }, + "runs/run-1/26-two-selected-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/26-two-selected-1.jpg": { + "bytes": 130974, + "sha256": "219dba4c29ba6388afe2cf06c8b7a9bb7795f441399171c277522bc29e9160a1" + }, + "runs/run-1/26-two-selected.json": { + "bytes": 1092, + "sha256": "546694c9ae53201e0689c58b219afb63a2c00139ba0d143cd86b93fb81637e65" + }, + "runs/run-1/27-review-page-one-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/27-review-page-one-1.jpg": { + "bytes": 146269, + "sha256": "2765deb473d9b0c45cc0cd8faa66bcfbbf9b6d88b21b4a10d6907f2c9a09fc42" + }, + "runs/run-1/27-review-page-one.json": { + "bytes": 1098, + "sha256": "9e1ea8eba8fd1dec9c890611249feaf3fa39789c88fd66cc3aa60eac628494b2" + }, + "runs/run-1/28-review-page-two-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/28-review-page-two-1.jpg": { + "bytes": 145917, + "sha256": "dd80dbd8704306b502757e8f17fdd258c7f1f9f04ce63b543b0d360c70502584" + }, + "runs/run-1/28-review-page-two.json": { + "bytes": 1098, + "sha256": "9b643dce5ef1a42117e69d0e57e0eef832adba08271e3793067bf547ee4173de" + }, + "runs/run-1/29-search-focus-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/29-search-focus-1.jpg": { + "bytes": 146547, + "sha256": "4fb3eb063de4864b3c888bf6a881ba77b426b7e059bbe5ff7bb295ef9c30f564" + }, + "runs/run-1/29-search-focus.json": { + "bytes": 1092, + "sha256": "ca35b224bda75636f54d2f5c0cb660388ce9eede8740e415913e5f9e13d0a6aa" + }, + "runs/run-1/30-alias-filter-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/30-alias-filter-1.jpg": { + "bytes": 132933, + "sha256": "90a740d25b34014ab826e67ee8ba4f2d028b9611c8b65c5ba261a30a6f746391" + }, + "runs/run-1/30-alias-filter.json": { + "bytes": 1092, + "sha256": "fc33ccebe5a9a3eb13706c0744beef260c10a739dc56e3f308510da77d531cec" + }, + "runs/run-1/31-empty-filter-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/31-empty-filter-1.jpg": { + "bytes": 132037, + "sha256": "f660b7d9834f6e6b9539a0e36470979653474f4149fa8ce2674565a220273159" + }, + "runs/run-1/31-empty-filter.json": { + "bytes": 1092, + "sha256": "5c615b59c94137e475d3fb01d8922cde2ac64b63996a3592f960b31b1694c6bc" + }, + "runs/run-1/32-enter-keeps-review-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/32-enter-keeps-review-1.jpg": { + "bytes": 132037, + "sha256": "f660b7d9834f6e6b9539a0e36470979653474f4149fa8ce2674565a220273159" + }, + "runs/run-1/32-enter-keeps-review.json": { + "bytes": 1104, + "sha256": "596d742629c83d083c65c6b3b447a57f569618acf69b996545e5e622c900715c" + }, + "runs/run-1/33-canceled-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/33-canceled-1.jpg": { + "bytes": 132118, + "sha256": "61356a770821e28f28d47b2f4c10858b59ff21a30fbd2fa9b65aad7ecfba4d39" + }, + "runs/run-1/33-canceled.json": { + "bytes": 1084, + "sha256": "98ba8b09c2429929309bea9d52361cb1f72c0f1e0626d1246fbc35ed164b9704" + }, + "runs/run-1/34-cancel-saved-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/34-cancel-saved-1.jpg": { + "bytes": 131110, + "sha256": "6195d8f734e28f1bd6cdedb88e38f97aa2040b49c0316b35c4853f601fa85dc4" + }, + "runs/run-1/34-cancel-saved.json": { + "bytes": 1092, + "sha256": "0e6b20bedd5e44e76423a6d20616864a731be2c2aba3e0286c763c6a10c3ac9d" + }, + "runs/run-1/35-delete-opens-review-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/35-delete-opens-review-1.jpg": { + "bytes": 131110, + "sha256": "6195d8f734e28f1bd6cdedb88e38f97aa2040b49c0316b35c4853f601fa85dc4" + }, + "runs/run-1/35-delete-opens-review.json": { + "bytes": 1106, + "sha256": "d596672cadc7df0a34f487b9a8cb52ce3a14ea41f932fe4affcb9c2c80a874f0" + }, + "runs/run-1/36-group-context-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/36-group-context-1.jpg": { + "bytes": 139191, + "sha256": "658b301946dba7ce4c973e2feac65bac5f01dfad9b439a319bd5b9a215db9d26" + }, + "runs/run-1/36-group-context.json": { + "bytes": 1094, + "sha256": "53adc8dc6323ae6886add87805e023147a452d862b0d08c9b4789cd9234c6ea7" + }, + "runs/run-1/37-menu-review-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/37-menu-review-1.jpg": { + "bytes": 146406, + "sha256": "f09cd8349e7d6eca3ff38cdbdb0150d1f0908c5e67d3096443008612b8e33a37" + }, + "runs/run-1/37-menu-review.json": { + "bytes": 1090, + "sha256": "91fec302a7ec5925d8634583b0f8156c59bc879954aff6c9a3d6b187abd52e3f" + }, + "runs/run-1/38-confirmed-removal-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/38-confirmed-removal-1.jpg": { + "bytes": 144786, + "sha256": "fd4dc73dd0bc0aaa6663b5b4f9a505dd3b35a69ab996c8e1a3a44885b284473f" + }, + "runs/run-1/38-confirmed-removal.json": { + "bytes": 1110, + "sha256": "755bf927dbea4b92f5ae039d49214afec9d7f822829bb2d3df8c640e4b893556" + }, + "runs/run-1/39-removal-saved-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/39-removal-saved-1.jpg": { + "bytes": 141462, + "sha256": "c2e7faa13eb73397987dc77716a79323361b7257724783970f2b61402bf76eeb" + }, + "runs/run-1/39-removal-saved.json": { + "bytes": 1094, + "sha256": "f46fa03dd38bd9460f4a07e739d41eab63675937fc5f9558d2cd5fc85a86d58a" + }, + "runs/run-1/40-undo-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/40-undo-1.jpg": { + "bytes": 127889, + "sha256": "08ebefd0a2382f9ad143c827d5e7ff30061d94d34b6c3872f513a22b63a4d13a" + }, + "runs/run-1/40-undo.json": { + "bytes": 1086, + "sha256": "beb9d82eaf47647aa8c0da61e20f2a06f5f44efd465fb51fdbca5213d208a5f6" + }, + "runs/run-1/41-undo-saved-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/41-undo-saved-1.jpg": { + "bytes": 127843, + "sha256": "f329c3dc3c9a99faf669a79d56f59db29b74fe1ff232132101f53aba4d883ab2" + }, + "runs/run-1/41-undo-saved.json": { + "bytes": 1088, + "sha256": "cc3bc21fc3579972e158bb74bc048fd4122c463f06b249b5433e6c42ec4e9d74" + }, + "runs/run-1/42-reselect-participant-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/42-reselect-participant-1.jpg": { + "bytes": 130906, + "sha256": "852bcec7a9eadbe99d133c3690393d01c12bfa2f59c2e0ebb82d6eaa5bef8420" + }, + "runs/run-1/42-reselect-participant.json": { + "bytes": 1108, + "sha256": "09c5081b4c72a35c9e80a7212662d665035c12f15cc59a29f010b6f05c7c5e34" + }, + "runs/run-1/43-restored-message-menu-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/43-restored-message-menu-1.jpg": { + "bytes": 138101, + "sha256": "23114fbb788ec3c4c403346397f1011fe200669d7468a9db7a74a7b8ac8addd2" + }, + "runs/run-1/43-restored-message-menu.json": { + "bytes": 1110, + "sha256": "ccb02edf9ceb494263b622faeb68fa7dd54e0fb2faa83f98d1488f143ec234f5" + }, + "runs/run-1/44-restored-group-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/44-restored-group-1.jpg": { + "bytes": 130914, + "sha256": "1bf4d8db32c185008622b456c5b01666dd32f644e00d74a3a388071294f6fef8" + }, + "runs/run-1/44-restored-group.json": { + "bytes": 1096, + "sha256": "6b716bac48d8a5fd9bb327ab9b274252d8338885f7b4292275ac81cee287256c" + }, + "runs/run-1/45-resize-review-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-1/45-resize-review-1.jpg": { + "bytes": 146234, + "sha256": "4dd6aa69cb3ad3968ab00f713cdd45482b4e2a038bb1fa6d1448ad19d9f49965" + }, + "runs/run-1/45-resize-review.json": { + "bytes": 1094, + "sha256": "e958d396dc13a8606973571ae141f5cec84f0788a6397eb37da61bb662dff108" + }, + "runs/run-1/47-size-recovery-0.jpg": { + "bytes": 144528, + "sha256": "d447888d7227414a9c0db9617080468556139073bb0fbca20c3169d3148bcd6d" + }, + "runs/run-1/47-size-recovery.json": { + "bytes": 976, + "sha256": "1b7debd1c2ac8f2a0f4da57598cf7c90c25459c88d2d3235d77080c1d784f86f" + }, + "runs/run-1/48-window-menu-0.jpg": { + "bytes": 143791, + "sha256": "a64107adc31f7e5f94b15a9efff16cecc582dc0dfd6d30df6572e730dcb9d94b" + }, + "runs/run-1/48-window-menu-1.jpg": { + "bytes": 4956, + "sha256": "1b33fc34741438282edbd352299d4844fb6762b3ed434365e302e03f408dfc04" + }, + "runs/run-1/48-window-menu.json": { + "bytes": 1593, + "sha256": "706714ed7850005a1b66b5d2d6648359066894ef67dd9086f1b925fe3de63a38" + }, + "runs/run-1/49-size-mode-0.jpg": { + "bytes": 144528, + "sha256": "d447888d7227414a9c0db9617080468556139073bb0fbca20c3169d3148bcd6d" + }, + "runs/run-1/49-size-mode.json": { + "bytes": 972, + "sha256": "9039a8b8fa703a47471a6239ad38fdbc0624dd24c8d4afe5c8346909e16e8fb0" + }, + "runs/run-1/50-size-edge-0.jpg": { + "bytes": 144528, + "sha256": "d447888d7227414a9c0db9617080468556139073bb0fbca20c3169d3148bcd6d" + }, + "runs/run-1/50-size-edge.json": { + "bytes": 972, + "sha256": "c9ba40687e30bfefc93e3dea55262e0941e7164435fec259036dafd50788ee56" + }, + "runs/run-1/51-compact-width-0.jpg": { + "bytes": 116542, + "sha256": "cb98090373f6fc247d6b8d83dfae3e6b01cff47ff077ff69883c1451bae22dfd" + }, + "runs/run-1/51-compact-width.json": { + "bytes": 976, + "sha256": "fe1536f030d615d74b6c0e01e05bd6638f3d68b313a0408c978d4bf643cca72a" + }, + "runs/run-1/52-height-menu-0.jpg": { + "bytes": 115771, + "sha256": "cf84510902c292b4dfd59405ff9620777135862cb91569c3430316b37af6727b" + }, + "runs/run-1/52-height-menu-1.jpg": { + "bytes": 4956, + "sha256": "1b33fc34741438282edbd352299d4844fb6762b3ed434365e302e03f408dfc04" + }, + "runs/run-1/52-height-menu.json": { + "bytes": 1599, + "sha256": "ca886d872856fffd54b9fa873a387ab931b20775f2022eaa6776ad5a1c1d769a" + }, + "runs/run-1/53-height-size-0.jpg": { + "bytes": 116542, + "sha256": "cb98090373f6fc247d6b8d83dfae3e6b01cff47ff077ff69883c1451bae22dfd" + }, + "runs/run-1/53-height-size.json": { + "bytes": 974, + "sha256": "45f07a73e15905b1cb3da9d3bc831e134d85fe1bf731e6c7d2a0191d7ad632f1" + }, + "runs/run-1/54-bottom-edge-0.jpg": { + "bytes": 101972, + "sha256": "8654ea06e50ef897c21fa31dd31538c97c78266aed23e076bbbe784f416fd211" + }, + "runs/run-1/54-bottom-edge.json": { + "bytes": 974, + "sha256": "ddb41541bcc644453280ec92ce2171b1b735a3ded3afe5a079e72705a25d0dd4" + }, + "runs/run-1/55-compact-review-expired-0.jpg": { + "bytes": 101417, + "sha256": "2e08860cfe264823d510ad244330fe753716594219898c5b64b8099a00519c76" + }, + "runs/run-1/55-compact-review-expired.json": { + "bytes": 985, + "sha256": "a5b0144f993c9205e986748a981a19c915f3f0d77d2c73528b43981a18134692" + }, + "runs/run-1/56-escape-cancel-0.jpg": { + "bytes": 104118, + "sha256": "ece760ab6d3e1245d60318c41f8308cbde9b66c43ce606c430a1d42cf15f71b8" + }, + "runs/run-1/56-escape-cancel.json": { + "bytes": 976, + "sha256": "53d005f9f6b4271142c17a3bb54cfab0e842e7db8b77b375bb65bb1bce76ff13" + }, + "runs/run-1/57-compact-valid-review-0.jpg": { + "bytes": 103829, + "sha256": "2aa04ebd289118deb73379b5201583c754c1bbf6539dfc9e9f6a9bce36f9c69c" + }, + "runs/run-1/57-compact-valid-review.json": { + "bytes": 983, + "sha256": "72d4388b961adc5bad110d47baad1656875e272bee6c48a5f13cd1e003bc9316" + }, + "runs/run-1/58-compact-scroll-0.jpg": { + "bytes": 103999, + "sha256": "dab90f8f40a626e9b70679b9717e91f0ee13f966d0ac1c7213cc347e90ca7db1" + }, + "runs/run-1/58-compact-scroll.json": { + "bytes": 977, + "sha256": "ca161a32cb2835b4ece7004b0a8f937f86c77a3a20d00b0360afc5df1efd650d" + }, + "runs/run-1/59-compact-second-page-0.jpg": { + "bytes": 103239, + "sha256": "1ac4faf6558cd055f35c7b207afe4ef3181837c0c9a08e7ea2634b2eb55a091f" + }, + "runs/run-1/59-compact-second-page.json": { + "bytes": 982, + "sha256": "5eaf3b4e7eaf6b97dffbc0d0d43b2368ed5f1d761800bca17946ef51d6f06022" + }, + "runs/run-1/60-compact-cancel-0.jpg": { + "bytes": 105641, + "sha256": "0e1c9caafba5e991bf1ffd0bfbcefef34c94755e137e2b57fa0e68b5e5f7da0e" + }, + "runs/run-1/60-compact-cancel.json": { + "bytes": 977, + "sha256": "87282ea17b9978a5c984f4082a8bbf8ce5521ecde85a6b4cf77f3ee8946ea292" + }, + "runs/run-1/61-redo-0.jpg": { + "bytes": 110644, + "sha256": "4171b99160f74da64ef83592f8e1abd3ba42ca60ea2e69e19153ea7575ffb7df" + }, + "runs/run-1/61-redo.json": { + "bytes": 977, + "sha256": "0dc82a4c99746aab00a906e726f4ff96cd587694e1a786367de63c76a9f80d16" + }, + "runs/run-1/62-redo-saved-0.jpg": { + "bytes": 110380, + "sha256": "471eec1fc925bb485764ffe54876637eab9a73119e218daea47a446466e970ed" + }, + "runs/run-1/62-redo-saved.json": { + "bytes": 975, + "sha256": "fb7b6767ab711d53d1aebc323f85c4e54b6deed8182f257fabac7574a904604f" + }, + "runs/run-1/63-arrangement-after-removal-0.jpg": { + "bytes": 112359, + "sha256": "46ee7bb5487c3510489d747f46cb46b99eb2d4d918ba303cb5a851e16db0d593" + }, + "runs/run-1/63-arrangement-after-removal.json": { + "bytes": 988, + "sha256": "aae3c8a7a3bfd7e8da22a71204955d6744a3c4dc0c3e11bdb4987c7a04b74c88" + }, + "runs/run-1/64-saved-b-preserved-0.jpg": { + "bytes": 110490, + "sha256": "b0043653aac99c0378c26c7c3c7249dbbee79df160d48e19bcf64ce65e512a8f" + }, + "runs/run-1/64-saved-b-preserved.json": { + "bytes": 980, + "sha256": "e1b6f50fd6fce70cb42f78d871d0caef0e295fab2391173af153f6c3132ede77" + }, + "runs/run-1/app.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/app.stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-1/cwd/%SystemDrive%/ProgramData/Microsoft/Windows/Caches/cversions.2.db": { + "bytes": 16384, + "sha256": "de800ec458c404e412158787a7bc6660fe54a2bc3b6903b31d07a661325056f0" + }, + "runs/run-1/cwd/%SystemDrive%/ProgramData/Microsoft/Windows/Caches/{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000001.db": { + "bytes": 307760, + "sha256": "8c39c0f94044df6360f160a936cdebdd957dacf8da660cca02951181775ed226" + }, + "runs/run-1/cwd/%SystemDrive%/ProgramData/Microsoft/Windows/Caches/{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000001.db": { + "bytes": 660376, + "sha256": "2b67a249b6048fe0d0ccf1d8623de840b17bc8579c75fcb8f2689f6c19115c31" + }, + "runs/run-1/evidence/baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-1/evidence/capture.js": { + "bytes": 1589, + "sha256": "71c2ee3c0fbcd6f6d756ba65f732d51500257e6052a35890615af4d3aef2c476" + }, + "runs/run-1/evidence/expected-removed.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "runs/run-1/evidence/fixture-manifest.json": { + "bytes": 882, + "sha256": "2c7b8996b0bcfadfce727e013c4520ecf41e6b6d3ba1e874057a16df2a4a43b0" + }, + "runs/run-1/evidence/inputs.json": { + "bytes": 138269, + "sha256": "839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f" + }, + "runs/run-1/evidence/native-harness.py": { + "bytes": 13148, + "sha256": "7db4a634633e50a94f7f9b20370688955e7f00c137a7036d9c2ab7a8bea59004" + }, + "runs/run-1/evidence/result.json": { + "bytes": 4454, + "sha256": "539b7536236430b955e2657dd1e5b9ff905c029e5d1d10c2ac194d7d7847464a" + }, + "runs/run-1/evidence/source-proof.json": { + "bytes": 598, + "sha256": "b548459a93f6510422eb8dd8542c9eadfc92604c137bf73b3ffaca4c8d9edffe" + }, + "runs/run-1/evidence/verify-captured.py": { + "bytes": 2019, + "sha256": "32078fe720f00f6c123daa3d7d0cbbd4d296211d3610eb33dec4f74c5be2f573" + }, + "runs/run-1/finished.json": { + "bytes": 452, + "sha256": "2918d7977dfb45ba3ddc5ea307291e04482856b23ce4773b8bef45bf7acc3a65" + }, + "runs/run-1/prepared.json": { + "bytes": 3756, + "sha256": "50f60170972ee71551873b7c561183b7a23272c035db8f35a85ee23c4cc95cff" + }, + "runs/run-1/snapshots/01-baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-1/snapshots/01-baseline.evaluator.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/snapshots/01-baseline.evaluator.stdout.json": { + "bytes": 345, + "sha256": "704ca55418e980704b7b959a7d0c194587d370173e9c5655dc7c5a3c6b62b251" + }, + "runs/run-1/snapshots/01-baseline.json": { + "bytes": 770, + "sha256": "524dd694310f72e6f87c81caac58d3a0e9090ad20705856e4b4e5c205759c437" + }, + "runs/run-1/snapshots/02-cancel.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-1/snapshots/02-cancel.evaluator.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/snapshots/02-cancel.evaluator.stdout.json": { + "bytes": 343, + "sha256": "b297dcef93d1f7f4801a5cc6cd74a055072edf3acc847e16727936dd99e70b09" + }, + "runs/run-1/snapshots/02-cancel.json": { + "bytes": 768, + "sha256": "b25019bc68042bef217d0a631d7fc55cb3c7761c5e7e3e50238afa30b504d8b1" + }, + "runs/run-1/snapshots/03-removed.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "runs/run-1/snapshots/03-removed.evaluator.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/snapshots/03-removed.evaluator.stdout.json": { + "bytes": 343, + "sha256": "5513f01ad12213dc54dde737f839f8d9a9a4b591ad899f78bfccf2c8e3e4c164" + }, + "runs/run-1/snapshots/03-removed.json": { + "bytes": 767, + "sha256": "fa94861b469ff2d53b4337a15028c33774222ac87c50740baa933972c83c3ee8" + }, + "runs/run-1/snapshots/04-undo.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-1/snapshots/04-undo.evaluator.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/snapshots/04-undo.evaluator.stdout.json": { + "bytes": 341, + "sha256": "c38efee5fbec56ad769fa63af22b048c0f0620f35a3bd4154bbdaa183cf27d4e" + }, + "runs/run-1/snapshots/04-undo.json": { + "bytes": 766, + "sha256": "e02b74f895a2737c34554f18afe70ece5995e2a9e4a4bd6d132c199790ea0b45" + }, + "runs/run-1/snapshots/05-redo.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "runs/run-1/snapshots/05-redo.evaluator.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-1/snapshots/05-redo.evaluator.stdout.json": { + "bytes": 340, + "sha256": "def6774d0d4763737e5400f7c0f4585b13287a7b41fa3bac1ee20204d5952c38" + }, + "runs/run-1/snapshots/05-redo.json": { + "bytes": 764, + "sha256": "c1b7bc9f8680e745c65a0668dafbc99a274b978553c29aee2b013dcb72a1b371" + }, + "runs/run-1/started.json": { + "bytes": 740, + "sha256": "46b011eca23d208123b676ab7c8c376ceac0ea18da5955856c8db3982a67e09e" + }, + "runs/run-1/working.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "runs/run-2/01-fresh-start-0.jpg": { + "bytes": 99741, + "sha256": "05b83fc6a0560858b3b8c6b9df3d4dfd62d488923d7f78b0b5fb2ff158136059" + }, + "runs/run-2/01-fresh-start.json": { + "bytes": 915, + "sha256": "d225aee5a0f57fd00ce08e0db2949089e9120a74a3a9d20fafff2f9aba342880" + }, + "runs/run-2/02-maximized-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/02-maximized-1.jpg": { + "bytes": 107217, + "sha256": "c2f2a2321517770c864b3dcb3ead82216d9f61fd63882755ffd6cac471afe977" + }, + "runs/run-2/02-maximized.json": { + "bytes": 1027, + "sha256": "a33c804a6b5a806f7eea70e1b97627c23f61f7544be0580cc2a72bfe7aece501" + }, + "runs/run-2/03-open-request-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/03-open-request-1.jpg": { + "bytes": 105395, + "sha256": "c8c6252997c3ebf977202bb06d15d90247092edab3f1bffdbbda3b5ecaa49d50" + }, + "runs/run-2/03-open-request.json": { + "bytes": 1033, + "sha256": "874e35384f34e34fcade46cb653769a1affce8d818754b5495b9c96694ddf0a0" + }, + "runs/run-2/04-file-picker-0.jpg": { + "bytes": 696, + "sha256": "1c553708713a77fe378f38300c5e1888c4bb165058359b8b5739b84f7d1f97e7" + }, + "runs/run-2/04-file-picker-1.jpg": { + "bytes": 97798, + "sha256": "224b8ce766ded2297821c59ebf0671e5847dcc4d18f4340c409edd783da60756" + }, + "runs/run-2/04-file-picker.json": { + "bytes": 10026, + "sha256": "0afde77ac0ce1780088f2477f4d2a215803b33d35381a46d3a904dc4dc8c6c30" + }, + "runs/run-2/05-filename-focus-0.jpg": { + "bytes": 696, + "sha256": "1c553708713a77fe378f38300c5e1888c4bb165058359b8b5739b84f7d1f97e7" + }, + "runs/run-2/05-filename-focus-1.jpg": { + "bytes": 98144, + "sha256": "eb6c5f06dff658e5b0388501d7ba5a180593ce7a72f6c11efa76ba469036c88a" + }, + "runs/run-2/05-filename-focus.json": { + "bytes": 10032, + "sha256": "f4f189660553d0f8d22720f7d05133cd3df13c002d75f79351c96d35ec781cf3" + }, + "runs/run-2/06-reopen-path-0.jpg": { + "bytes": 696, + "sha256": "1c553708713a77fe378f38300c5e1888c4bb165058359b8b5739b84f7d1f97e7" + }, + "runs/run-2/06-reopen-path-1.jpg": { + "bytes": 98144, + "sha256": "eb6c5f06dff658e5b0388501d7ba5a180593ce7a72f6c11efa76ba469036c88a" + }, + "runs/run-2/06-reopen-path.json": { + "bytes": 10026, + "sha256": "c9acc362dd688f7954ad55b047a4e4fc4f46bef3b35d2fa67dce22c4b75c3f63" + }, + "runs/run-2/07-path-observed-0.jpg": { + "bytes": 696, + "sha256": "1c553708713a77fe378f38300c5e1888c4bb165058359b8b5739b84f7d1f97e7" + }, + "runs/run-2/07-path-observed-1.jpg": { + "bytes": 98144, + "sha256": "eb6c5f06dff658e5b0388501d7ba5a180593ce7a72f6c11efa76ba469036c88a" + }, + "runs/run-2/07-path-observed.json": { + "bytes": 10030, + "sha256": "e3443582ceeb1d55f6840c7e5fb6fe47db6993fcfc5dde58cd687c7f0de270ff" + }, + "runs/run-2/08-filename-key-focus-0.jpg": { + "bytes": 696, + "sha256": "1c553708713a77fe378f38300c5e1888c4bb165058359b8b5739b84f7d1f97e7" + }, + "runs/run-2/08-filename-key-focus-1.jpg": { + "bytes": 98144, + "sha256": "eb6c5f06dff658e5b0388501d7ba5a180593ce7a72f6c11efa76ba469036c88a" + }, + "runs/run-2/08-filename-key-focus.json": { + "bytes": 10040, + "sha256": "b044c1ed2bca881bd1d9e2bb92cd2d10cc689654c551a2619f6ffbc22d50fbbd" + }, + "runs/run-2/09-reopen-path-retry-0.jpg": { + "bytes": 696, + "sha256": "1c553708713a77fe378f38300c5e1888c4bb165058359b8b5739b84f7d1f97e7" + }, + "runs/run-2/09-reopen-path-retry-1.jpg": { + "bytes": 100873, + "sha256": "cb36dd99dde5147366fb836c798e02a7ea2a898793a5472532101f679d0a1d96" + }, + "runs/run-2/09-reopen-path-retry.json": { + "bytes": 10038, + "sha256": "3392763f491b3511898c89b03a6ef20fcfe44c332af1bf3c8ecb36dcabfa2af5" + }, + "runs/run-2/10-reopened-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/10-reopened-1.jpg": { + "bytes": 94735, + "sha256": "365d6b8c0698f347c8b2959a0fb9ecb7949c9f64ee266e7317074f97388cf043" + }, + "runs/run-2/10-reopened.json": { + "bytes": 1025, + "sha256": "1c9b9f07e8ee24798a1f9b39266be83ced75ba38c68092d5af75c5c4185a7608" + }, + "runs/run-2/11-reopen-scenario-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/11-reopen-scenario-1.jpg": { + "bytes": 103658, + "sha256": "5e4ee5b62808846f585abb4ad15a7dbc71618ca3ba6013ddd6473f92fee4118f" + }, + "runs/run-2/11-reopen-scenario.json": { + "bytes": 1099, + "sha256": "3f9c30fef32d2e51f37366364c51964c4d6c8aae4b0ac260aee16050334d2740" + }, + "runs/run-2/12-reopen-behavior-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/12-reopen-behavior-1.jpg": { + "bytes": 142643, + "sha256": "5a84e17ae7b4de812edced3594cb75f449fa479d10ee1b7a2aa34d9d40bc888c" + }, + "runs/run-2/12-reopen-behavior.json": { + "bytes": 1099, + "sha256": "82d881ad767318e520131c914b177ca47fb253f14f617fbb947e4fa9b9414db3" + }, + "runs/run-2/13-reopen-arrangements-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/13-reopen-arrangements-1.jpg": { + "bytes": 144330, + "sha256": "c74ab8c11af8648d14ab6e8b8784f26e7b5a2e587e6207a9be8234ac0e409069" + }, + "runs/run-2/13-reopen-arrangements.json": { + "bytes": 1107, + "sha256": "cbea13b26edadb6ac0f4013140e814990a9e7953482b3a008070d9c66d236441" + }, + "runs/run-2/14-reopened-saved-a-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/14-reopened-saved-a-1.jpg": { + "bytes": 140299, + "sha256": "538379b873927ab145dc30c2da0c40f93ed87d85c8831fb779ac35933d54b25d" + }, + "runs/run-2/14-reopened-saved-a.json": { + "bytes": 1101, + "sha256": "7319a472db7fd09b86d946426f874ab710b12badfe40d50e604583f128b9b899" + }, + "runs/run-2/15-reopen-saved-0.jpg": { + "bytes": 722, + "sha256": "d89da17fb8517188426907d542e2b5f91098a2e8d121506b6e65506e40de865d" + }, + "runs/run-2/15-reopen-saved-1.jpg": { + "bytes": 138727, + "sha256": "4605c75cd4f7d2ad784af1230b722b0ad67724dd4f244aa207fcd16f1314b95d" + }, + "runs/run-2/15-reopen-saved.json": { + "bytes": 1093, + "sha256": "b1cf5c0439776fa886738521c3f3619abe15c045763c5c554e411a081116d2b7" + }, + "runs/run-2/app.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-2/app.stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-2/baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-2/cwd/%SystemDrive%/ProgramData/Microsoft/Windows/Caches/cversions.2.db": { + "bytes": 16384, + "sha256": "de800ec458c404e412158787a7bc6660fe54a2bc3b6903b31d07a661325056f0" + }, + "runs/run-2/cwd/%SystemDrive%/ProgramData/Microsoft/Windows/Caches/{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000001.db": { + "bytes": 307760, + "sha256": "8c39c0f94044df6360f160a936cdebdd957dacf8da660cca02951181775ed226" + }, + "runs/run-2/cwd/%SystemDrive%/ProgramData/Microsoft/Windows/Caches/{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000001.db": { + "bytes": 660376, + "sha256": "2b67a249b6048fe0d0ccf1d8623de840b17bc8579c75fcb8f2689f6c19115c31" + }, + "runs/run-2/evidence/baseline.arcadia": { + "bytes": 4389, + "sha256": "70c32355b82393c03ef87b24862863e0a06c4dcb00cf2c0a84a7cfd2da687a8a" + }, + "runs/run-2/evidence/capture.js": { + "bytes": 1589, + "sha256": "71c2ee3c0fbcd6f6d756ba65f732d51500257e6052a35890615af4d3aef2c476" + }, + "runs/run-2/evidence/expected-removed.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "runs/run-2/evidence/fixture-manifest.json": { + "bytes": 882, + "sha256": "2c7b8996b0bcfadfce727e013c4520ecf41e6b6d3ba1e874057a16df2a4a43b0" + }, + "runs/run-2/evidence/inputs.json": { + "bytes": 138269, + "sha256": "839b041088be0638c55cdcc4da18d6cf9b69eecee3c00d48734759166ed06a0f" + }, + "runs/run-2/evidence/native-harness.py": { + "bytes": 13148, + "sha256": "7db4a634633e50a94f7f9b20370688955e7f00c137a7036d9c2ab7a8bea59004" + }, + "runs/run-2/evidence/result.json": { + "bytes": 4454, + "sha256": "539b7536236430b955e2657dd1e5b9ff905c029e5d1d10c2ac194d7d7847464a" + }, + "runs/run-2/evidence/source-proof.json": { + "bytes": 598, + "sha256": "b548459a93f6510422eb8dd8542c9eadfc92604c137bf73b3ffaca4c8d9edffe" + }, + "runs/run-2/evidence/verify-captured.py": { + "bytes": 2019, + "sha256": "32078fe720f00f6c123daa3d7d0cbbd4d296211d3610eb33dec4f74c5be2f573" + }, + "runs/run-2/finished.json": { + "bytes": 452, + "sha256": "bc41474ea3b350b73d8db848161d6f16a1efd63376ff75ccf6ce2ff12c08d4df" + }, + "runs/run-2/prepared.json": { + "bytes": 3773, + "sha256": "ac3679f491892ccbfd1b49db63ce0de348d065e5f24797e202404b10bd7b7f84" + }, + "runs/run-2/snapshots/01-reopened.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + }, + "runs/run-2/snapshots/01-reopened.evaluator.stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/run-2/snapshots/01-reopened.evaluator.stdout.json": { + "bytes": 344, + "sha256": "1d9f44e94faf06a78f356285be89e32974029b89cd5855a8fa77104fc5342444" + }, + "runs/run-2/snapshots/01-reopened.json": { + "bytes": 768, + "sha256": "dc4e4ad8e6c74a53ec3210d411a2d35efe52d9520ed2167bc72fd43d5b40fd8d" + }, + "runs/run-2/started.json": { + "bytes": 740, + "sha256": "b1d7ee9540b01e1a60c5d9c6d552dd8c85e670500dbae1d4b57f2390dbd8df3d" + }, + "runs/run-2/working.arcadia": { + "bytes": 3856, + "sha256": "1cb04cbab8428fc672293f29783fffdeecaf6ec6d81d5439501c32e866c8264f" + } + }, + "excluded_binary_bytes": { + "preflight/fixture-preflight-1/bin/arcadia.exe": { + "bytes": 20719104, + "sha256": "2044a6057b565069bcfe457e644ed3d527f3607ca9c0f8313d036d188d73796c" + }, + "preflight/fixture-preflight-1/bin/libunwind.dll": { + "bytes": 190976, + "sha256": "f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4" + }, + "runs/run-1/bin/arcadia-studio.exe": { + "bytes": 120067072, + "sha256": "e118e7f0a2ff53ac9c22a73d07555929d11e1ad917d430a7ae88d469aaa91155" + }, + "runs/run-1/bin/libunwind.dll": { + "bytes": 190976, + "sha256": "f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4" + }, + "runs/run-2/bin/arcadia-studio.exe": { + "bytes": 120067072, + "sha256": "e118e7f0a2ff53ac9c22a73d07555929d11e1ad917d430a7ae88d469aaa91155" + }, + "runs/run-2/bin/libunwind.dll": { + "bytes": 190976, + "sha256": "f45604a12e8bcd839fd86f667c1be1cc7c4f9da2b3c69ff381ac708f0e1ae7d4" + } + }, + "runs": [ + { + "name": "run-1", + "accepted": true, + "source_phases": { + "working.arcadia": "removed" + } + }, + { + "name": "run-2", + "accepted": true, + "reopen_from": { + "run": "run-1", + "file": "snapshots/05-redo.arcadia" + }, + "source_phases": { + "working.arcadia": "removed" + } + } + ], + "preflights": [ + { + "name": "fixture-preflight-1", + "accepted": true + } + ], + "limits": [ + "Executable/DLL bytes omitted; original readback hashes remain. Offline verification cannot rehash omitted binaries.", + "accepted is an explicit reviewer designation, never inferred from screenshots or a passing checker.", + "All local run/preflight attempts must be declared and closed, including failures.", + "No GUI usability, direct history-depth introspection, remote publication or issue completion claim." + ] +} diff --git a/harness/scenario-group-removal-evidence-20260925/native/native-evidence.zip b/harness/scenario-group-removal-evidence-20260925/native/native-evidence.zip new file mode 100644 index 00000000..9bfadc2f Binary files /dev/null and b/harness/scenario-group-removal-evidence-20260925/native/native-evidence.zip differ diff --git a/harness/scenario-group-removal-evidence-20260925/native/verify.py b/harness/scenario-group-removal-evidence-20260925/native/verify.py new file mode 100644 index 00000000..a25b04b4 --- /dev/null +++ b/harness/scenario-group-removal-evidence-20260925/native/verify.py @@ -0,0 +1,282 @@ +"""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 = 'scenario-aggregate-removal-native-evidence' +PHASES = {'baseline': 'baseline.arcadia', 'removed': 'expected-removed.arcadia'} +FINAL_SOURCE = '43340b94a13f192c3b5d3c3112dbe87246790a44' + + +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/'): + assert fixture['fixture_revision'] == 'removal-v1-source-derived' + assert fixture['schema'] == 7 and fixture['phases'] == PHASES + assert fixture['selection'] == fixture['expected_removed'] == ['intake_lane', 'a'] + assert fixture['expected_changed'] == ['review_flow', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'saved_a', 'saved_b'] + assert fixture['preserved_engineering_definitions'] == ['intake', 'review', 'archive'] + 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'].decode('utf-8') + assert baseline.count('steps [@a,@b,@c,@d,@e,@f,@g,@h];') == 1 + assert baseline.count('oa_occurrence ') == 8 and baseline.count('oa_lifeline ') == 3 + assert baseline.count('diagram saved_') == 2 and baseline.count('oa_activity ') == 3 + for alias in fixture['preserved_engineering_definitions']: + assert baseline.count('oa_activity ' + alias + ' ') == 1 + # The known fixture has one complete declaration per line. No parser or + # archived preparation helper is executed; only its explicit intended delta + # is admitted, including the source writer's retained token whitespace. + def trivia(text): + return ''.join(token for token in re.findall(r'"(?:\\.|[^"\\])*"|\s+|[^\s"]+', text) if token.isspace()) + expected = baseline.replace('steps [@a,@b', 'steps [@b') + for marker in ('oa_lifeline intake_lane ', 'oa_occurrence a '): + rows = [line for line in baseline.splitlines() if marker in line] + assert len(rows) == 1 + declaration = rows[0] + assert expected.count(declaration) == 1 + expected = expected.replace(declaration, '\n\n' + trivia(declaration) + '\n\n') + assert expected.count('sender @intake_lane;') == 7 + expected = expected.replace('sender @intake_lane;', 'sender none;') + for offset in (0, 20): + for field, item in ( + ('lanes', f'{{lifeline @intake_lane;x {140 + offset};}}'), + ('messages', f'{{address{{references[];occurrence @a;}};send_y {160 + offset};}}'), + ): + rows = [line for line in expected.splitlines() if f'{field} [{item},' in line] + assert len(rows) == 1 + old = rows[0] + new = old.replace(item + ',', '', 1) + new = new[:-2] + trivia(item) + '];' + expected = expected.replace(old, new, 1) + assert files[prefix + 'expected-removed.arcadia'] == expected.encode('utf-8'), 'Oracle changes more than the specified removal/reference/layout delta' + + +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')) + config = js('review-config.json') + 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' + + 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['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 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', + '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()