Files
reverse-engineering-anything/docs/verification/electron-cancellation-2026-10-16.md
T
180ba03bfd fix(electron): preserve cancellation across waits, state reads and cleanup
Fixes #4388. Refs #4027.

Observe cancellation during first-window waits and state reads; preserve cancellation and caller reasons before cleanup and retain partial observations when cleanup fails. Keep late cancellation and cleanup failure precedence.

Validation: 49 focused cases, static/docs checks, six controlled verifier-oracle cases and 39 current-head CI checks passed. Codex and Greptile found no remaining blocking issues. Real Joplin cancellation phases verified; complete Linux cleanup/first-signal CLI exit and packaged-runtime startup remain explicitly unverified/failed. Both verifiers now fail incomplete cleanup, including after main-process exit.

Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com>
Co-authored-by: Adolanium <94890352+Adolanium@users.noreply.github.com>
2026-10-16 21:12:26 +08:00

9.1 KiB

Electron cancellation verification, 2026-10-16

#4388, existing #4387, umbrella #4027.

The cancellation boundaries and retained cancellation cause are verified below. The complete real Linux Joplin workflow remains partial or failed because process ownership/cleanup cannot be verified. Publishing a typed reply, exiting the CLI, and cleaning up its application are separate observations.

Source and deterministic regressions

Latest-main control is fe2a398dd9ab290ba6cb3411403d319cec8d07a2. The existing reviewed PR head af732dd8 was integrated with that main in 3b094802a. Its initial 47 focused cases passed. An unrelated compact-catalog test hit its unchanged 10-second CI deadline; an unchanged-source job retry passed. The original failed execution remains in CI history.

Real CLI verification exposed an introduced regression: the PR replaced an already observed cancellation with success after the final snapshot. A later cleanup failure then lost the cancellation category and caller reason. Two deterministic cases reproduced this for process and transport cleanup: 20 old cases passed and both new cases failed. Main's public reply retained category cancelled; the reviewed PR returned execution_failure for the same kind of cancelled wait plus incomplete cleanup.

Fix 73d4a712b records cancellation before finalization and uses one constructor for the early and late partial-capture errors. Cleanup failure keeps precedence, its diagnostics and the earlier cancellation cause. Cancellation first observed during cleanup retains the existing precedence. The fix changes the producing outcome; no CLI/MCP projection repair or ownership-policy exception was added.

All 49 focused cases in three files passed after the fix. Full static checks passed: six tasks plus architecture guards. Documentation checks also passed (six tasks, including two cached, plus five README consistency cases). One intermediate build rejected an over-narrowed aborted === true comparison; the original truthiness pattern resolved that TypeScript error before the passing build. Recorded catalog metadata is byte-identical to main. No new tool, schema, cache or normal-case result field was added.

Real application observations

The unchanged official Joplin 3.7.21 ASAR is 233,575,014 bytes, SHA-256 767df409b18effe60421fbefcca873de237c7e813eac744ecdeebbc5e825a33a. Acquisition is linked in the original Joplin verification. Its complete unpacked native files/assets accompany it. These trials use the actual application with generic Electron 44.7.0, fresh profiles and Xvfb. They exercise startup/cancellation, not a completed Joplin business workflow.

Frozen verifier revision 279aa29a7 records source/runtime hashes before the final probes. The controlled cases hold a REA-side Playwright reply while the real application runs. They do not establish a naturally occurring Joplin stall.

Controlled condition Observed result
Main: first-window reply stays pending Still pending 20.001 s after cancellation; verifier watchdog fails
Fixed: same pending first-window reply Cancellation returned in 5.658 s; cancelled action retained
Fixed: initial snapshot reply stays pending Cancellation returned in 5.335 s; no invented partial snapshot
Fixed: final snapshot reply stays pending Cancellation returned in 10.262 s; five-second cancellation grace expiry and initial snapshot retained

Every fixed case preserves the cancelled category. Every real case still has unverified provider cleanup and a nonzero verifier exit; these are cancellation phase proofs, not complete runtime passes. The known Linux ownership gap is tracked in #4282. Ownership was not inferred from process names, PIDs or executable paths to make these tests pass.

The public CLI trials send SIGTERM after actual Joplin startup logging. Main and the fixed version both publish cleanup_incomplete with category cancelled and a cancelled action. The fixed reply was observed about 5.268 s after SIGTERM (50 ms polling resolution). Both fail the verifier's 20-second first-signal exit deadline and require a second, explicitly recorded recovery signal. The resulting 143 exit is not proof that the first signal completed cleanup.

The official packaged Joplin executable also passed static fuse admission, but its initial Inspector evaluation failed with a destroyed execution context before the cancellation condition was reached. Those attempts remain failed diagnostics; they establish no bundled-runtime compatibility or cancellation result.

Costs, limits and reproducibility

Costly operations run serially on one CPU 10 with an 8 GiB hard limit, 6 GiB early stop, no swap and 192 tasks. The passing static gate used 153.534 s wall, 152.274161 family CPU seconds and 6,442,016,768 peak cgroup bytes. It reported no OOM and verified payload cleanup. Cgroup memory includes file cache, not RSS. Other trials' exact counters and failures are preserved in the compact record.

Payload-exit counters are collected while the observer remains alive and are not final whole-scope counters. Some failed probes retain live app/Xvfb processes at that point. Every recorded scope was independently confirmed inactive/dead after the external owner stopped it. That recovery does not establish successful provider cleanup.

OS/build caches are uncontrolled. A timed-out baseline and a partial fixed workflow do not establish a completed-task speedup. Live event sets also differ, so reply-size differences do not establish token savings. Model billing, peak agent context and complete host/tool-schema token costs are unmeasured. Historical diagnostic helper hashes were not captured at execution; the record marks that gap instead of assigning the later frozen hash to earlier runs.

Build each pinned checkout, then run under the existing resource observer and a private Xvfb instance. The shared verifier supports all four named cases:

node experiments/analysis-efficiency/electron-cancellation.mjs \
  --runtime-root /absolute/pinned-checkout \
  --executable /absolute/electron-44.7.0/electron \
  --application /absolute/Joplin/resources/app.asar \
  --profile-root /absolute/temporary-profile-parent --case window-wait

Use initial-state, final-state or normal-wait for the other boundaries. The public CLI probe has no injected stalled reply:

python3 experiments/analysis-efficiency/joplin-cli-cancellation.py \
  --node /absolute/node-24.18.0/bin/node --runtime-root /absolute/pinned-checkout \
  --executable /absolute/electron-44.7.0/electron \
  --application /absolute/Joplin/resources/app.asar \
  --profile-root /absolute/temporary-profile-parent

The scripts return failure rather than claiming complete cleanup when the real owned app remains unresolved. App binaries, extracted runtimes/profiles and raw large output are regenerable and are not committed. No macOS, Windows, full Joplin GUI or live-model success is claimed.

Review follow-up: verifier exit semantics

Review of beb4a47db found a verifier false pass: the shared probe could exit successfully once its main process had exited even though provider cleanup was still unverified. The CLI probe also accepted cleanup_incomplete. Those are verifier bugs; they do not invalidate the recorded failed Joplin trials above.

Revision 227217ac3 requires verified provider cleanup in both probes and the public cancelled category in the CLI. Six controlled oracle cases cover an exited main process with incomplete cleanup, complete cleanup, transport failure after process cleanup, and a wrong public category. Both old scripts fail these regressions; the fixed scripts pass all six. These cases substitute provider/CLI replies and do not establish real-provider compatibility or performance.

The fixed, frozen scripts were then rerun on the same real Joplin artifact. The shared window-wait probe retained cancellation in 5.577 s and explicitly failed because cleanup remained unverified. The public CLI retained category cancelled and a cancelled action, published its reply about 6.335 s after SIGTERM, and again failed the first-signal exit deadline. Both verifiers exited nonzero; their externally owned scopes were stopped separately. Production source and the earlier historical records are unchanged. The compact record appends these observations under review_followup.

Run the controlled oracle regressions separately from the real-app commands:

python3 experiments/analysis-efficiency/electron-cancellation-oracles.py \
  --node /absolute/node-24.18.0/bin/node