Skip to content

0.9.0 — the word this kernel could not set without a trampoline of its own - #18

Merged
Sunrisepeak merged 3 commits into
mainfrom
a-unit-a-caller-cannot-name
Aug 31, 2026
Merged

0.9.0 — the word this kernel could not set without a trampoline of its own#18
Sunrisepeak merged 3 commits into
mainfrom
a-unit-a-caller-cannot-name

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

kal_process_stop_requested answered null here while two other implementations
answered a word. The reason was never the specification: the raw sigaction of
this kernel takes a structure whose SECOND field is sa_tramp, the kernel
enters THAT address rather than the handler, and the C library that ordinarily
supplies it (_sigtramp) is not beneath this implementation.

⚠️ A wrong trampoline is not a wrong answer — it is a program that dies inside
the handler at an address belonging to nobody. So the order was: the check
that raises the signal first, the trampoline second.
The check installs the
disposition, has a shell raise SIGTERM at this program, waits on the word
through kal_task_wait, and then asserts the program is STILL RUNNING — which
reaching the line proves and a compiled disposition cannot show.

⭐ arm64 only, and that is the whole of it rather than half: the CI matrix is
macos-14 alone because the build tool has no x86_64 release for this system,
so a trampoline there could be compiled and never entered. Clause 6.2 makes the
absence a fact a caller reads, and kal_process_props claims the position only
where it has been run.

⚠️ The test is this ecosystem's first consumer of openkal.macros, and writing
it is how the module's own gap was found — see openkal.

…s own

`kal_process_stop_requested` answered null here while two other implementations
answered a word. The reason was never the specification: the raw `sigaction` of
this kernel takes a structure whose SECOND field is `sa_tramp`, the kernel
enters THAT address rather than the handler, and the C library that ordinarily
supplies it (`_sigtramp`) is not beneath this implementation.

⚠️ A wrong trampoline is not a wrong answer — it is a program that dies inside
the handler at an address belonging to nobody. So the order was: **the check
that raises the signal first, the trampoline second.** The check installs the
disposition, has a shell raise SIGTERM at this program, waits on the word
through `kal_task_wait`, and then asserts the program is STILL RUNNING — which
reaching the line proves and a compiled disposition cannot show.

⭐ arm64 only, and that is the whole of it rather than half: the CI matrix is
`macos-14` alone because the build tool has no x86_64 release for this system,
so a trampoline there could be compiled and never entered. Clause 6.2 makes the
absence a fact a caller reads, and `kal_process_props` claims the position only
where it has been run.

⚠️ The test is this ecosystem's first consumer of `openkal.macros`, and writing
it is how the module's own gap was found — see openkal.
Every check in this file is silent when it holds, and that convention cannot
serve this one. Each observation is SKIPPED rather than failed when its
precondition is absent --- no root directory, no word, no shell --- so a green
run was consistent both with a trampoline that was entered and returned and
with a block that never ran at all. Those are exactly the two outcomes the
check exists to tell apart.

Noticed from the run that first exercised it: the job reported `ok (0.52s)',
which is consistent with the 0.3s sleep the check spawns and proves nothing on
its own.
Found in self-review, and it is the shape this ecosystem exists to exclude: the
installation's result was discarded, so a failed one would have left a word that
can never change while the caller was handed it anyway. The program would ask
whether its end had been requested, be told no, and go on being told no after
it had been.

`kal_process_props' now agrees, because the header defines null there as the
absence that position reports and the two cannot disagree. It reads the state
and never arms --- asking what an implementation can do must not install a
disposition.
@Sunrisepeak
Sunrisepeak merged commit 6546f16 into main Aug 31, 2026
2 of 3 checks passed
@Sunrisepeak
Sunrisepeak deleted the a-unit-a-caller-cannot-name branch August 31, 2026 00:46
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