Skip to content

test: add model-based process lifecycle nightly coverage - #209

Merged
Greepolis merged 5 commits into
mainfrom
test/proc-intensive-coverage-201
Nov 12, 2026
Merged

Greepolis merged 5 commits into
mainfrom
test/proc-intensive-coverage-201

Conversation

@Greepolis

@Greepolis Greepolis commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

Scope

Adds a seeded, independent lifecycle model for the portable process table in kernel/proc/process.c, building on the now-merged PR #208. The model checks public PID allocation, parent/child relationships, termination tombstones, explicit reaping, child reparenting, owned-thread cleanup, public lifecycle counters, bounded-table exhaustion and slot reuse without PID reuse.

The test maintains its own PID/parent/thread ledger and compares derived process/live/terminated/thread counts with the public API. It also verifies that a live process cannot be reaped, a terminated process remains queryable until reap, each owned thread disappears on termination, children are reparented to init, and a reaped PID is no longer queryable. The mutation gate independently sabotages slot reclamation, child reparenting and owned-thread cleanup.

Adds an ASan/UBSan nightly job, a focused CTest entry and a module-specific mutation gate. PROC is the only module removed from the coverage debt by this PR. ABI remains uncovered, because PR #208 deliberately provides scoped ABI tests rather than complete Linux and NT coverage. The correct baseline is therefore 2: ABI and TXN.

The portable process table remains intentionally unreachable from the live x86-64 syscall path. The remaining C3 caller-check and caller-identity defects keep that reachability gate closed; this PR does not wire the portable subsystem into runtime code or claim that those defects are fixed.

Branch order

@Greepolis
Greepolis force-pushed the test/proc-intensive-coverage-201 branch from 2c55279 to d463e2d Compare November 9, 2026 10:10
@Greepolis
Greepolis changed the base branch from main to test/abi-intensive-coverage-201 November 9, 2026 10:10
@Greepolis
Greepolis force-pushed the test/abi-intensive-coverage-201 branch from 6cd6236 to 3b848ea Compare November 9, 2026 20:29
@Greepolis
Greepolis force-pushed the test/proc-intensive-coverage-201 branch from d463e2d to bb1e3ff Compare November 9, 2026 20:34
@Greepolis
Greepolis force-pushed the test/proc-intensive-coverage-201 branch from bb1e3ff to a5534ee Compare November 11, 2026 19:02
@Greepolis
Greepolis changed the base branch from test/abi-intensive-coverage-201 to main November 11, 2026 19:02
@Greepolis
Greepolis marked this pull request as ready for review November 11, 2026 20:06

@Greepolis Greepolis left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Review: ready to merge

What it does

  • Fixes the defect module_torture.md asked to be fixed, instead of encoding it. vibeos_proc_reap() releases a terminated process's slot. It refuses a live process, and a process that still owns a thread. Termination leaves a queryable tombstone, and public PIDs stay monotonic across slot reuse.
  • Keeps the reachability fence. process.c still says it is not reached by the running kernel. phases.md and docs/core/README.md say the slot defect is closed in the portable model, while the C3 gate stays closed: the caller check and the caller-supplied identity are still open. That is the "retained, modelled as the intended contract" path the debt table required.
  • Tests against an independent ledger. proc_torture.c keeps its own PID, parent, tombstone and thread ledger, and compares it with the public process-table operations. It does not compare the table with itself.

Verification (local, on a5534eec)

Check Result
ctest 17/17 pass
check-nightly-coverage.py ok, baseline 2 (abi, txn)
check-sabotage-anchors.py ok
vibeos_proc_torture, seeds 1/7/19/43 × 20000 rounds all OK
Reap leaves the slot allocated red: public lifecycle counters differ from independent ledger
Children not reparented to init red: child was not reparented to init before parent reap
Terminate keeps an owned thread slot red, at round 112: parent thread creation

CI: 19/19 green.

Minor, not blocking

  • The thread-slot mutation is caught by its symptom: a later thread creation fails because capacity is gone. It is not caught at the moment of termination. A check in the ledger that the terminated process owns no thread right after terminate would catch it directly, on the first round.
  • One line in docs/core/README.md is 127 characters long where the rest of the paragraph wraps at 80.

A thread slot left in use with no owner shows through no id, and the
public thread count still agrees. The mutation that does that was
caught only about a hundred rounds later, when the table ran out. After
each termination the torture now takes threads until the table refuses
and gives them back. It must take exactly the capacity less the threads
the ledger says are live. The mutation is now caught on round 0, with
a message that names it. Also re-wraps a paragraph of docs/core/README.md
that ran to 127 columns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Greepolis
Greepolis merged commit 1f12ccf into main Nov 12, 2026
19 checks passed
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