Skip to content

The quit's walk stays in the kernel, and the manual says what a quit request does - #1218

Merged
Japabu merged 1 commit into
mainfrom
quit-walk-stays-in-kernel
Nov 11, 2026
Merged

Japabu merged 1 commit into
mainfrom
quit-walk-stays-in-kernel

Conversation

@Japabu

@Japabu Japabu commented Nov 11, 2026 •

Copy link
Copy Markdown
Collaborator

Closes the design question issues/the-kernel-decides-who-is-asked-to-quit-and-who-is-killed.md by the orchestrator's decision: the quit's walk stays in the kernel. Records and the manual only; no code changes.

Decision and reason

The record asked whether a parent should ask its children to quit over its own protocol (the kernel keeping only the kill) or whether the kernel's walk is the mechanism the interrupt, hang-up and terminate events need. The second holds:

  • whether a process listens and whether it is claimed for its end are one act under one lock (kernel/proclife/src/quit.rs, checked by the process-lifecycle model), so no read comes between the check and the claim;
  • a hung or deaf process in the middle of a tree cannot shield what is below it;
  • the userland alternative needs a listener in every process and a relay in three runtimes (the orchestrator's analysis; I did not re-derive the count).

What changes

  • docs/src/architecture/authority.md, the process tree: a holder of a child's handle may ask its subtree to quit with a reason; the kernel carries the request to every process below; a listener receives it as an event; one that never listened, or has not taken the last request, is ended; the kernel never asks on its own. This replaces "quitting gracefully is the parent's job".
  • docs/src/architecture/sessions.md, ending a session: the page read as if a sign-out offered every app the chance to finish and as if a second request ended a process that ignored the first. What the code does (system/session/src/lib.rs, kernel/proclife/src/quit.rs): the first ask ends at once every app that never listened; a second request ends a process that has not yet taken the first and asks again one that has; a process that took a request and carries on is ended only by a force. A second request is sent only by a person's action or the machine's stop (Owner::stopping asks every app again with a terminate after a control's hang-up). The page now says that.
  • The question record is deleted (issues/README.md's closing procedure) and its one citation, in issues/the-kernel-is-small-interrupts-post-and-threads-wait.md's list of unresolved design changes, removed. git grep for the slug and the title finds nothing else. The durable rule already stands in kernel/proclife/src/quit.rs's header, so nothing is folded.

Checks

Markdown only: no build or test run. No build gate reads docs/ or issues/ (searched build/ and .github/workflows). Verified by reading: quit::decide/quit::ask for the listen/unread rule, Owner::sign_out/stopping for what a sign-out sends, and that SYS_PROCESS_QUIT (kernel/src/syscall/proc.rs) is quit_process's only caller.

Left as it was, unverified

The sessions page still names "the system controls' stop" as an explicit force. The session owner's stop is a terminate request that waits (Owner::stopping); whether the supervisor then forces is the supervisor track's design and I did not change the sentence's claim.

Rebased onto main 67713cb for review round 1 (suggestions 1 and 2 taken, commit-message typo fixed). #1241 removes the adjacent inventory bullet and rebases after this lands.

🤖 Generated with Claude Code

@Japabu

Japabu commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator Author

Review of #1218 at 24ab5a4

Architecture. This PR changes only Markdown. The decision is that the quit's walk of a subtree stays in the kernel, and it fits what the kernel is for. The check of whether a process listens and the claim for its end are one act, done under the table lock and the notice's lock. The walk also reaches each process directly, so a deaf or hung process in the middle of a tree cannot shield what is below it. A relay in userland could provide neither guarantee. The kernel adds no policy, because it never asks on its own.

The manual against the code. I verified the following:

  • authority.md:68–74 against quit::decide and quit::ask (kernel/proclife/src/quit.rs):
    • A listener is a process that has read its notice or armed a watch on it. If it holds no unread reason, it is notified, and its children are owed to the walk.
    • A process that never listened, or still holds an unread reason, is claimed for Killed, and its subtree ends with it.
    • The reasons are exactly interrupt, hang-up and terminate.
    • quit_process has one caller, SYS_PROCESS_QUIT, which is gated by MANAGE. No other kernel path asks, so "the kernel never asks on its own" holds.
  • sessions.md:47–58 against Owner (system/session/src/lib.rs):
    • sign_out(false) asks every app once with a hang-up, and a repeated sign-out asks nobody again.
    • ended reports what remains until no app is left, then answers Exit.
    • sign_out(true) kills every app.
    • Nothing reads a clock.
  • The new text in both pages names no code.

The deleted record. Its exit was "the design says which reading holds; this file is deleted", and authority.md now says which reading holds. The record's other facts were line counts, file names and the track stage that built the walk. The code and git history already hold those, and the durable rule is in quit.rs's header. I ran git grep for the record's slug and its title at the head and at main 67713cb. The only citation is the inventory bullet this PR deletes. #1241's head still carries that bullet because it was branched earlier; its rebase resolves it.

Overlap. git merge-tree shows this PR merges cleanly onto main 67713cb. It should land first, and #1241 second (see that PR's review).

BLOCKERS

None.

SUGGESTIONS

  1. docs/src/architecture/authority.md:68–74: the decision is that the kernel carries the request through the subtree. The page says this only by implication, through "no process in between can shield" and "the kernel never asks on its own". One clause such as "the kernel carries it to every process below" would state the decision directly.
  2. docs/src/architecture/sessions.md:56–58: "is sent only by a person's action" leaves out the machine's stop. After a control's hang-up, Owner::stopping asks every app again with a terminate, and that ends any app that has not taken the hang-up. Stops come from holders of power: the power button through acpiserver, the compositor's stop view, and shutdown or reboot. "By a person's action or the machine's stop" would be exact.
  3. The commit message has a typo: "the orchestrator.s analysis".

LAND

…request does

The record asked which of two readings of the design holds: a parent asks
its children to quit over its own protocol and the kernel keeps only the
kill, or the kernel's walk of the subtree is the mechanism the interrupt,
hang-up and terminate events need. The orchestrator decided the second.

Why the walk stays: whether a process listens and whether it is claimed
for its end are checked and acted on as one act under one lock, which the
process-lifecycle model checks, so no read comes between them; a hung or
deaf process in the middle of a tree cannot shield what is below it, since
the walk reaches each process itself; and the userland alternative needs a
listener in every process and a relay in three runtimes to carry a request
down (the orchestrator's analysis; not re-derived here).

The authority page now states it: a holder of a child's handle may ask its
subtree to quit with a reason, a listener receives it as an event, one that
never listened or has not taken the last request is ended, and the kernel
never asks on its own. "Quitting gracefully is the parent's job" is
replaced by that last clause, which is the part of it that was true.

The sessions page read as if a sign-out offered every app the chance to
finish, and as if a second request ended a process that ignored the first.
What happens: the first ask ends at once every app that never listened; a
second request ends a process that has not yet taken the first and asks
again one that has taken it; a process that took a request and carries on
is ended only by a force.

issues/the-kernel-decides-who-is-asked-to-quit-and-who-is-killed.md is
deleted and its one citation, in the kernel inventory's list of unresolved
design changes, with it. The durable rule already stands at the site that
owns it, kernel/proclife/src/quit.rs's header.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@Japabu
Japabu force-pushed the quit-walk-stays-in-kernel branch from 24ab5a4 to dd0ceb7 Compare November 11, 2026 16:39
@Japabu

Japabu commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator Author

Orchestrator: verified dd0ceb7 against review LAND at 24ab5a4. The range-diff shows only suggestions 1 and 2 taken (authority.md: "The kernel carries the request to every process below."; sessions.md: "…by a person's action or the machine's stop."), the commit-message typo fixed, and a rebase onto 67713cb. Markdown only, no code. Queueing.

@Japabu
Japabu marked this pull request as ready for review November 11, 2026 16:48
@Japabu
Japabu added this pull request to the merge queue Nov 11, 2026
Merged via the queue into main with commit b053390 Nov 11, 2026
10 checks passed
@Japabu
Japabu deleted the quit-walk-stays-in-kernel branch November 11, 2026 16:53
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