Skip to content

Compare Unity exits with loader snaps - #1020

Merged
Eli Pinkerton (wallstop) merged 4 commits into
mainfrom
codex/native-loader-snaps-comparison
Oct 17, 2026
Merged

Eli Pinkerton (wallstop) merged 4 commits into
mainfrom
codex/native-loader-snaps-comparison

Conversation

@wallstop

@wallstop Eli Pinkerton (wallstop) commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

DISCLOSURE: LLM-GENERATED TEXT

Why: Unexpected runner loader snaps need a controlled comparison during native fault investigation.

What:

  • Record flags and compare enabled, disabled, and restored Unity exits.
  • Restore exact values from checksummed receipts after interrupted captures.
  • Run capture controls in Windows startup and contract suites.

Refs #343, #637, #794


Note

High Risk
Opt-in mode writes the local-machine Unity.exe IFEO GlobalFlag on licensed Windows runners; incorrect lease or recovery logic could leave runner state wrong despite safeguards.

Overview
Adds an opt-in Unity Tests path (native-loader-snaps-comparison) that runs native fault capture with loader snaps enabled, disabled, and restored instead of the usual direct/debugger pair. The workflow validates the combo (native-diagnostics, EditMode, acceptance: none), passes -CompareLoaderSnaps into capture-native-fault.ps1, shortens per-phase timeout when comparing, and runs an always() restore step via restore-native-loader-snaps.ps1.

Introduces checksummed registry lease helpers (native-loader-flag-lease.ps1) that temporarily clear only the loader-snaps bit on Unity.exe Image File Execution Options GlobalFlag, persist .prepared / active receipts, restore in finally, and support interrupted-run recovery. Comparison mode enforces stable editor and packages-lock.json hashes and requires the same single passing NUnit case in each phase.

CI and docs: Windows runner diagnostics run test-native-fault-capture.ps1 -RequireWindowsRegistry; contract tests and npm run test:native-fault-capture cover lease, ACL, and workflow wiring. The Unity runners runbook documents the opt-in and manual restore.

Reviewed by Cursor Bugbot for commit 7508f55. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6d1c99a. Configure here.

Comment thread .github/workflows/unity-tests.yml

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Session closeout — 2026-10-16 22:14 UTC

The user requested session end. PR #1018 remains open with successful CI and all three review threads resolved. PR #1019 remains open with all 28 checks terminal (22 successful, six expected skips) and no review findings. Neither PR was merged.

PR #1020 is now draft, at unchanged head 6d1c99af3d83bc74333f5a384f2d82fae6d58bd9. Its normal Unity CI still has five Editor jobs queued or running; no failed check is currently reported. Local validation remains 140 Windows controls and 67 Linux controls.

Remaining review defect: Cursor's “Restore fails without lease receipt” remains unresolved. The always() restore step at .github/workflows/unity-tests.yml:548 applies a receipt created only at the beginning of direct-disabled (capture-native-fault.ps1:264). A failure or cancellation before that phase leaves no receipt, and restore-native-loader-snaps.ps1:9 throws despite no flag change. Before making the PR ready, add recovery that positively verifies unchanged original state for a pre-write failure. Missing, corrupt or unverifiable evidence after a possible write must still fail. Acceptance needs real Windows controls for failure/cancellation before receipt creation, interruption after the write, exact restoration, and refusal on conflicting external edits; then rerun affected checks and review.

The real comparison was never dispatched or run. Shared-host configuration approval was requested but not received; “not intentionally enabled” describes configuration history only. No shared runner Unity.exe or system GlobalFlag was changed. Loader snaps remain an observed lead, with causation unproven. The native faults and the full acceptance scope of #343, #637 and #794 remain open. No further code change or experiment will be made in this session.

@wallstop
Eli Pinkerton (wallstop) changed the base branch from main to codex/native-loader-flag-evidence October 16, 2026 22:16
@wallstop
Eli Pinkerton (wallstop) added this pull request to stack #1021 October 16, 2026 22:16
Base automatically changed from codex/native-loader-flag-evidence to main October 16, 2026 22:17
Both CI runners have an unexpected Unity.exe loader-snaps flag. Add a disabled-by-default direct comparison before, during and after clearing only that bit. These diagnostic records cannot satisfy acceptance.

Persist a bounded, checksummed original lease immediately before the attempted write. Automatic cleanup restores only its active write and preserves external edits before or after that ownership window. Independent workflow recovery and an explicit Apply command restore matching temporary values from the exact original data, kind, machine, key and registry view. Refuse conflicting state and require matching inputs, a selected passing case and natural exits.

A real Windows regression reproduces cleanup overwriting an external edit before this lease writes. The corrected ownership phase passes that control and post-restoration edits for every supported value representation. Receipt-write failure prevents mutation. Interrupted-process recovery, exact string/type restoration, signed bits, permission refusal, damaged receipts and input drift are covered.

Validation: 140 native Windows controls and 67 Linux controls pass. Windows-only cases are explicitly unavailable on Linux and required on Windows. Both preflight modes, full spelling, docs links, Markdown lint, strict MkDocs, YAML/actionlint, contract runner self-tests, PowerShell invocation and workflow enrollment/license controls pass. Two-pass review found and resolved the ownership defect; no findings remain. No version or changelog change is needed for this diagnostic tooling.

Capture controls are now enrolled in the contract suite and Windows runner startup. Tests write only a new temporary HKCU key and remove it. No shared runner Unity.exe or system flags have been changed. The real configuration comparison has not run.

Refs #343, #637, #794. Evidence: #343 (comment)
@wallstop
Eli Pinkerton (wallstop) force-pushed the codex/native-loader-snaps-comparison branch from 6d1c99a to 41e5eec Compare October 16, 2026 22:17

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Linked #1019 → #1020 with GitHub's native stack API (stack #1021), as requested. The bottom PR #1019 merged as 003973868656b31910c7274d79c384e19430896a; GitHub automatically rebased this remaining draft onto main at 41e5eec4dc3d38be10983043faaa352971eee25a. The missing-lease recovery finding remains open. This PR is excluded from merging until that defect is addressed and checks/review pass. No comparison was run and no shared runner flags were changed.

Save the exact original flag before debugger setup. Recovery can verify a pre-write stop without changing the registry. Active write evidence takes precedence; missing post-write evidence, damaged receipts, and external edits still fail.

Validate 160 Windows controls and 75 Linux controls. Windows covers natural failure and process cancellation before the write, interrupted writes, exact restoration, and conflicting edits. A copy with the old read behavior fails on the missing pre-write lease. Shared runner settings were not changed.

Pass changed-file preflight in both modes, focused workflow and PowerShell checks, actionlint, full spelling, documentation links, Markdown, strict MkDocs, and pre-push safety. No package API or runtime behavior changes.
@wallstop
Eli Pinkerton (wallstop) marked this pull request as ready for review October 17, 2026 02:45
@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

The pre-write recovery fix is published at 91f2aca7; this PR is ready for review. All 160 Windows and 75 Linux controls pass, the recovery review thread is resolved, and hosted checks and Cursor review pass. The current Unity matrix is still running; completed 2022.3, regular 6000.6 and package-export jobs pass with confirmed healthy license/lock cleanup and no native crash headers in their full logs.

The user has now explicitly approved the one-time shared Windows loader-snaps comparison after CI and review pass. It has not been dispatched. No shared runner Unity.exe or system GlobalFlag has changed. I will wait for this exact head's full CI before dispatching once, then verify the before/disabled/restored outcomes, exact saved value/type restoration and licensed-job cleanup. The native-fault cause and the broader #343/#637 acceptance remain open.

@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Current head 91f2aca7 passes all 29 checks: 23 successful and six expected skips. The full Unity run passes all four versions, SINGLE_THREADED and package export. All six acquired jobs confirm healthy license/lock cleanup; their full logs contain no native crash headers. Cursor review passes and the recovery thread is resolved. All feedback surfaces and the full repository coverage report were checked; no new finding remains.

Windows CI runs 159 passing capture controls on each tested host. The local Windows total is 160 because an absent Unity.exe flag adds an extra read-state assertion; the registry transaction/recovery coverage is the same. Linux retains 75 passing controls.

With the user's explicit conditional approval satisfied, I dispatched the one-time loader-snaps comparison run 39002999733 once. Its SHA is exactly 91f2aca77d35d778b64673d9bcc81d70c2b2f4e4. Inputs select EditMode, no extra acceptance, native diagnostics and the loader-snaps comparison. The workflow's static matrix still runs its normal version legs. The run is queued; no comparison outcome or shared-host change is claimed yet. I will inspect the three phase receipts, exact restoration and every acquired job's cleanup before reporting a result.

@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

The one-time diagnostic reached job 117309748046 on ELI-MACHINE. Capture failed at the initial writable OpenSubKey with Requested registry access is not allowed, before lease creation or any flag write. Its receipt has LoaderFlagLease: null, Cases: [], and no restoration failure. The independent restore then failed because neither lease file existed. No before/disabled/restored process ran, so no comparison result exists. Normal EditMode passed; license cleanup and healthy lock release are confirmed.

Artifact 12091003251 is bound to run 39002999733 and head 91f2aca7; its downloaded ZIP matches SHA-256 9fe3d77a669553fc9aa1c7890c3df0d5f314fa00bc95b24dcc865e032be83de5. The read-only snapshot records Unity.exe String 00000002 and System DWORD 00000000.

This exposes a remaining pre-write recovery gap: preparing evidence currently requires a writable handle. I am addressing this PR CI finding by saving the prepared lease through read-only access first and allowing unchanged-state recovery through read-only access. Missing or conflicting evidence must still fail. No permissions will be granted and the shared-host comparison will not be repeated.

Prepare the checksummed original lease through a read-only handle before requesting write access. Verify an unchanged original value through read-only recovery; require write permission only for an active restoration.

The one-time run 39002999733 on 91f2aca failed its initial writable OpenSubKey before any lease or flag write. Its independent restore lacked evidence. Artifact 12091003251 matches SHA-256 9fe3d77a669553fc9aa1c7890c3df0d5f314fa00bc95b24dcc865e032be83de5. No comparison phase ran; license and lock cleanup were confirmed. No permission changes or repeat experiment are authorized by this fix.

Validation: 168 real Windows controls and 76 Linux controls pass. Windows uses a temporary HKCU key with a real deny-write ACL, proves unchanged recovery in prepared/active/restored phases, rejects conflicts, refuses a denied actual restoration, and restores exactly after permission returns. Both changed-file preflights, spelling (2975 files), PowerShell invocation lint, Markdown, and documentation links pass.

Refs #343, #637
@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Fixed the denied-access CI finding in 7508f55a. Capture now saves prepared evidence through a read-only handle before requesting write access. Recovery verifies unchanged original state through read-only access and requests write access only for an active restoration. Missing/corrupt evidence and conflicting values still fail. No runner permissions changed and the diagnostic will not be repeated.

All 168 Windows controls and 76 Linux controls pass. Windows controls use a temporary HKCU key with a real deny-write ACL: unchanged prepared/active/restored states recover, conflicts remain untouched, a denied actual restoration fails, and restoration succeeds after the temporary ACL is removed. Both changed-file preflights, full spelling, PowerShell invocation lint, Markdown, and documentation links pass. The Windows test process exited naturally and was disposed. Fresh CI and review are required on this head before merge.

@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Current-head Unity 6000.6 Standalone has one failure: an unexpected native allocator lifetime warning during SceneHelperTests.GetObjectOfTypeInScene teardown. The warning and guard failure match the previously investigated #393, now reopened with exact-head XML/log evidence. Runtime/Editor/test C# and analyzer inputs are unchanged from main. The recovery controls pass all 167 assertions on this host. Cleanup is confirmed healthy.

A request to retry only this failed normal job was rejected with HTTP 403 because its containing workflow is still running; no retry started. I will wait for the other jobs and then request that single-leg retry. A passing retry will not resolve #393. No warning filtering, test skips, new implementation, or repeat shared-flag diagnostic is being added. This PR will not merge while its current-head required checks remain red.

@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

The original current-head matrix is terminal: five Windows jobs passed, one failed on the native allocator warning recorded in reopened #393. All six full logs were inspected and confirm healthy license cleanup and lock release. The passing Unity 2021 and 2022 logs retain UNKNOWN native reports; these remain tracked in #343 and are not acceptance evidence.

With the workflow now completed and head still 7508f55a, GitHub accepted the single-job retry for regular Unity 6000.6. The earlier HTTP 403 request had started no retry. No code changed, no warning was suppressed, and the one-time shared-flag diagnostic is not being repeated. #393 remains open regardless of the retry result.

@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Current head 7508f55a now passes all 29 checks: 23 successful and six expected skips. The single regular Unity 6000.6 retry passes all selected modes and confirms healthy license cleanup/lock release, with no native crash headers. Its fresh Standalone artifact 12093684375 is bound to this run/head and matches SHA-256 5a616190a71ecae2cc8549deac7cf42df98d476d9b13721b325a83e117c59229; XML explicitly passes the previously failed SceneHelperTests.GetObjectOfTypeInScene case. The original failing artifact remains retained. This adds current-head CI evidence and does not fix or close #393.

The five successful first-attempt jobs were carried forward with their original timestamps, not rerun. Their full cleanup evidence remains verified. Native UNKNOWN reports in the passing 2021/2022 jobs remain tracked in #343. The one-time flag diagnostic was not repeated and made no flag write. #1022's remaining cancelled jobs are being retried after the classified watchdog race (#1023). Native stack #1021 will merge only after both current heads pass checks and final feedback review.

@wallstop
Eli Pinkerton (wallstop) merged commit 480a360 into main Oct 17, 2026
38 of 41 checks passed
@wallstop
Eli Pinkerton (wallstop) deleted the codex/native-loader-snaps-comparison branch October 17, 2026 09:08
@wallstop

Copy link
Copy Markdown
Collaborator Author

DISCLOSURE: LLM-GENERATED TEXT

Merged through GitHub native stack #1021 as 480a360374c4b54be247b38f91aa39f195098bcc, atomically with #1022, after all 29 checks passed on 7508f55a and final review/feedback was clear. No rule was bypassed. Fetched main's tree exactly matches the tested upper head. Every acquired PR job's licensed cleanup is verified.

The approved one-time diagnostic stopped before any flag write because registry access was denied. The resulting recovery CI finding is fixed here; no permissions were granted or comparison repeated. Native reports and broader acceptance remain open in #343/#637. The independent allocator-warning and watchdog defects remain open in #393/#1023.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant