[PR #5249] [MERGED] fix(process): settle native exit and repair ownership verification #6837

Closed
opened 2026-11-01 21:43:24 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5249
Author: @gensokyo-dev
Created: 10/19/2026
Status: ✅ Merged
Merged: 10/19/2026
Merged by: @gensokyo-dev

Base: main ← Head: audit/ci-tests-20261019-round2


📝 Commits (10+)

  • 5f94077 fix(process): classify baseline cleanup with current ownership facts
  • b32ce58 fix(ci): distinguish process inventory from historical PID lookups
  • b82ae19 test(ci): verify decoded historical PID controls before tracing
  • d34c851 fix(ci): trace historical PID handles and signal probes
  • 5d2895d fix(ci): resolve traced directory paths across pathname syscalls
  • 804caa2 chore: merge latest main for CI verification
  • 5c65671 test(ci): declare unresolved legacy pathname coverage
  • 1e84699 fix(ci): reject priority access to historical PIDs
  • 8dd8ca0 chore: integrate current CI pathname verification
  • 26b870b fix(ci): preserve C-quoted components in traced path checks

📊 Changes

23 files changed (+1355 additions, -313 deletions)

View changed files

📝 docs/recorded-crashes.md (+22 -1)
📝 scripts/lib/recorded-core-fixtures.py (+12 -11)
📝 scripts/verify-recorded-crash.mjs (+16 -0)
📝 scripts/verify/recorded-crash/trace-client.mjs (+9 -1)
📝 scripts/verify/recorded-crash/trace-ownership.d.mts (+15 -4)
📝 scripts/verify/recorded-crash/trace-ownership.mjs (+53 -53)
➕ scripts/verify/recorded-crash/trace-policy.d.mts (+16 -0)
➕ scripts/verify/recorded-crash/trace-policy.mjs (+202 -0)
📝 scripts/verify/recorded-crash/trace.mjs (+90 -58)
📝 src/domain/stringPatterns.test.ts (+18 -0)
📝 src/process/LinuxProcessStat.test.ts (+37 -0)
📝 src/process/LinuxProcessStat.ts (+22 -2)
➕ src/process/ProcessLifecycle.ts (+27 -0)
➕ src/process/ProcessOwnership.exiting.test.ts (+179 -0)
📝 src/process/ProcessOwnership.finalSweep.test.ts (+39 -0)
📝 src/process/ProcessOwnership.identity.test.ts (+46 -0)
📝 src/process/ProcessOwnership.ts (+49 -47)
📝 src/process/ProcessOwnershipEvidence.ts (+3 -6)
📝 src/process/ProcessOwnershipObservation.ts (+74 -33)
📝 tests/boundary/filesystem/recordedCrashTraceClassifier.test.ts (+123 -96)

...and 3 more files

📄 Description

Summary

Cleanup could reject an already exiting Linux child because its environment became unreadable or ps changed its command display before state Z. Separately, a provisional baseline identity failure could override fresh ownership facts, and the recorded-crash oracle did not consistently distinguish native ownership inventory from historical-PID access.

  • Parse native lifecycle once, including Linux PF_EXITING, terminal Z/X/x and unknown flags. Share lifecycle interpretation across ownership observation, signaling validation and retained Evidence. Exit-in-progress alone never proves cleanup: refresh only those PIDs within the existing one-second verification window, stop on unavailable/reused identity, preserve caller cancellation, and retain unresolved ownership. Initial identity/token/relation evidence stays attributable; no global table rescan per poll.
  • Let current identity/token facts settle baseline candidates. Keep unknown/current ownership fail-closed. Make the Jadx workspace fault fixture target its own workspace and enforce the cleanup stages with strict assertions.
  • Give recorded-crash trace facts one owner: exact Node/ps execution and CLONE_THREAD attribution, PID syscall selection/interpretation and explicit coverage. Require both CLI/MCP controls to decode the chosen PID, including an unassignable-PID control. Preserve main's portable schema, selective UID, native clock, setup and selected-path fixes; remove superseded schema/classifier implementations.

Executed validation

Runtime source at 3de261cc5 is identical to the validated 2026d0099 (tree equality checked), including main b44cb5bd3 and existing audit commits. Final head 33450d02ea only restores two explicit unverified coverage entries and their documentation; execution/guard behavior is unchanged:

  • 299 tests / 22 files passed, covering native identity/ownership, retained facts, cancellation, 87 trace-policy controls, nine topology controls, native baseline absence and actual SDK-converted schema validation.
  • 62 Jadx/Java subprocess controls / two files passed in an ordinary-UID PID namespace with Tini. These exercise owned test producers, not a real Jadx-engine qualification. The previously failing strict cleanup/idle-retirement scenarios pass.
  • A separate 30-child native Linux experiment observed same-generation R-state/PF_EXITING processes whose environment could not be opened, with zero start-identity mismatches; all children were reaped. A pinned-main parser comparison reproduces three lifecycle classification defects and verifies the correction. This establishes a possible native exit race, not the effective UID or exact cause of every earlier CI failure.
  • 44 real GDB 13.1/pwndbg CLI/MCP cases passed, both historical-PID controls decoded, four traces checked and cleanup verified with no descendants. Runtime build passed. npm run check:fast, npm run docs:check and the full-repository formatting check passed.

Heavy checks run serially on two CPUs, with a 3 GiB V8 heap and an 8 GiB sampled process-family guard. Build: 51.50 s wall / 80.73 s CPU / 3,060 MiB peak family RSS. Jadx controls: 49.79 s / 40.96 s / 852 MiB. Shared controls: 23.83 s / 27.57 s / 1,058 MiB. Real GDB task: 117.70 s / 129.39 s / 2,802 MiB. Final static gate: 123.42 s / 239.36 s / 4,452 MiB; docs: 25.91 s / 31.10 s / 781 MiB. Family RSS is sampled every 20 ms, can double-count shared pages and miss brief/reparented children; OS caches are uncontrolled. No speedup, model-token saving or unmeasured platform/provider qualification is claimed.

Follow-up on the final coverage declaration: 118 lifecycle/parser/policy/topology tests across four files and docs checks pass. Two CPUs; 2.85 s wall / 2.69 s CPU / 390 MiB sampled family RSS for the controls; docs 9.08 s / 10.66 s / 704 MiB.

Limits

The trace report explicitly leaves legacy cwd-relative paths, symlink aliases, unlisted PID interfaces and same-Node-thread stat/status purpose unverified; it is not universal kernel containment. No local macOS, Windows or live Ghidra qualification is claimed. Required CI lanes and token retry counts remain unchanged; permission errors and unresolved identities still fail cleanup.

Author readiness

Human owner: @gensokyo-dev

The owner explicitly delegated these declarations and authorized opening ready, following CI/review and merging in this session. Codex reviewed the final diff and stated evidence; independent human review was not observed.

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/5249 **Author:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Created:** 10/19/2026 **Status:** ✅ Merged **Merged:** 10/19/2026 **Merged by:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Base:** `main` ← **Head:** `audit/ci-tests-20261019-round2` --- ### 📝 Commits (10+) - [`5f94077`](https://github.com/morluto/rea/commit/5f94077b3c0a8052488fa8482ae1c167e155cf7f) fix(process): classify baseline cleanup with current ownership facts - [`b32ce58`](https://github.com/morluto/rea/commit/b32ce58c3a050ef99b2e8a883de6a1b68c5735d5) fix(ci): distinguish process inventory from historical PID lookups - [`b82ae19`](https://github.com/morluto/rea/commit/b82ae1962f8e105237bfec6ed8efa960be68f94b) test(ci): verify decoded historical PID controls before tracing - [`d34c851`](https://github.com/morluto/rea/commit/d34c8514a17e417ebdcbc5fafe21f8d3deca31a2) fix(ci): trace historical PID handles and signal probes - [`5d2895d`](https://github.com/morluto/rea/commit/5d2895d2b21035411b621d23d3e1e952a8a59df6) fix(ci): resolve traced directory paths across pathname syscalls - [`804caa2`](https://github.com/morluto/rea/commit/804caa2cb296dd5083251ad5bb0682821297d114) chore: merge latest main for CI verification - [`5c65671`](https://github.com/morluto/rea/commit/5c656717eff11c056191ac0f0a1d48c950910cd4) test(ci): declare unresolved legacy pathname coverage - [`1e84699`](https://github.com/morluto/rea/commit/1e846990180a09b52b0f9741f75a3ff3c111781c) fix(ci): reject priority access to historical PIDs - [`8dd8ca0`](https://github.com/morluto/rea/commit/8dd8ca080411bd0de2710b037e314e9ff4e5ba74) chore: integrate current CI pathname verification - [`26b870b`](https://github.com/morluto/rea/commit/26b870b1b2e304399d3d4d61be15023d7e2ba6ff) fix(ci): preserve C-quoted components in traced path checks ### 📊 Changes **23 files changed** (+1355 additions, -313 deletions) <details> <summary>View changed files</summary> 📝 `docs/recorded-crashes.md` (+22 -1) 📝 `scripts/lib/recorded-core-fixtures.py` (+12 -11) 📝 `scripts/verify-recorded-crash.mjs` (+16 -0) 📝 `scripts/verify/recorded-crash/trace-client.mjs` (+9 -1) 📝 `scripts/verify/recorded-crash/trace-ownership.d.mts` (+15 -4) 📝 `scripts/verify/recorded-crash/trace-ownership.mjs` (+53 -53) ➕ `scripts/verify/recorded-crash/trace-policy.d.mts` (+16 -0) ➕ `scripts/verify/recorded-crash/trace-policy.mjs` (+202 -0) 📝 `scripts/verify/recorded-crash/trace.mjs` (+90 -58) 📝 `src/domain/stringPatterns.test.ts` (+18 -0) 📝 `src/process/LinuxProcessStat.test.ts` (+37 -0) 📝 `src/process/LinuxProcessStat.ts` (+22 -2) ➕ `src/process/ProcessLifecycle.ts` (+27 -0) ➕ `src/process/ProcessOwnership.exiting.test.ts` (+179 -0) 📝 `src/process/ProcessOwnership.finalSweep.test.ts` (+39 -0) 📝 `src/process/ProcessOwnership.identity.test.ts` (+46 -0) 📝 `src/process/ProcessOwnership.ts` (+49 -47) 📝 `src/process/ProcessOwnershipEvidence.ts` (+3 -6) 📝 `src/process/ProcessOwnershipObservation.ts` (+74 -33) 📝 `tests/boundary/filesystem/recordedCrashTraceClassifier.test.ts` (+123 -96) _...and 3 more files_ </details> ### 📄 Description ## Summary Cleanup could reject an already exiting Linux child because its environment became unreadable or `ps` changed its command display before state Z. Separately, a provisional baseline identity failure could override fresh ownership facts, and the recorded-crash oracle did not consistently distinguish native ownership inventory from historical-PID access. - Parse native lifecycle once, including Linux PF_EXITING, terminal Z/X/x and unknown flags. Share lifecycle interpretation across ownership observation, signaling validation and retained Evidence. Exit-in-progress alone never proves cleanup: refresh only those PIDs within the existing one-second verification window, stop on unavailable/reused identity, preserve caller cancellation, and retain unresolved ownership. Initial identity/token/relation evidence stays attributable; no global table rescan per poll. - Let current identity/token facts settle baseline candidates. Keep unknown/current ownership fail-closed. Make the Jadx workspace fault fixture target its own workspace and enforce the cleanup stages with strict assertions. - Give recorded-crash trace facts one owner: exact Node/ps execution and CLONE_THREAD attribution, PID syscall selection/interpretation and explicit coverage. Require both CLI/MCP controls to decode the chosen PID, including an unassignable-PID control. Preserve main's portable schema, selective UID, native clock, setup and selected-path fixes; remove superseded schema/classifier implementations. ## Executed validation Runtime source at `3de261cc5` is identical to the validated `2026d0099` (tree equality checked), including main `b44cb5bd3` and existing audit commits. Final head `33450d02ea` only restores two explicit unverified coverage entries and their documentation; execution/guard behavior is unchanged: - **299 tests / 22 files passed**, covering native identity/ownership, retained facts, cancellation, 87 trace-policy controls, nine topology controls, native baseline absence and actual SDK-converted schema validation. - **62 Jadx/Java subprocess controls / two files passed** in an ordinary-UID PID namespace with Tini. These exercise owned test producers, not a real Jadx-engine qualification. The previously failing strict cleanup/idle-retirement scenarios pass. - A separate 30-child native Linux experiment observed same-generation R-state/PF_EXITING processes whose environment could not be opened, with zero start-identity mismatches; all children were reaped. A pinned-main parser comparison reproduces three lifecycle classification defects and verifies the correction. This establishes a possible native exit race, not the effective UID or exact cause of every earlier CI failure. - **44 real GDB 13.1/pwndbg CLI/MCP cases passed**, both historical-PID controls decoded, four traces checked and cleanup verified with no descendants. Runtime build passed. `npm run check:fast`, `npm run docs:check` and the full-repository formatting check passed. Heavy checks run serially on two CPUs, with a 3 GiB V8 heap and an 8 GiB sampled process-family guard. Build: **51.50 s wall / 80.73 s CPU / 3,060 MiB peak family RSS**. Jadx controls: **49.79 s / 40.96 s / 852 MiB**. Shared controls: **23.83 s / 27.57 s / 1,058 MiB**. Real GDB task: **117.70 s / 129.39 s / 2,802 MiB**. Final static gate: **123.42 s / 239.36 s / 4,452 MiB**; docs: **25.91 s / 31.10 s / 781 MiB**. Family RSS is sampled every 20 ms, can double-count shared pages and miss brief/reparented children; OS caches are uncontrolled. No speedup, model-token saving or unmeasured platform/provider qualification is claimed. Follow-up on the final coverage declaration: **118 lifecycle/parser/policy/topology tests across four files** and docs checks pass. Two CPUs; **2.85 s wall / 2.69 s CPU / 390 MiB sampled family RSS** for the controls; docs **9.08 s / 10.66 s / 704 MiB**. ## Limits The trace report explicitly leaves legacy cwd-relative paths, symlink aliases, unlisted PID interfaces and same-Node-thread stat/status purpose unverified; it is not universal kernel containment. No local macOS, Windows or live Ghidra qualification is claimed. Required CI lanes and token retry counts remain unchanged; permission errors and unresolved identities still fail cleanup. ## Author readiness Human owner: @gensokyo-dev The owner explicitly delegated these declarations and authorized opening ready, following CI/review and merging in this session. Codex reviewed the final diff and stated evidence; independent human review was not observed. - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:43:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6837
No description provided.