From b9da3a7bb9a422fc190e5e5fb0ef5d31d647a3ec Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 20 Sep 2026 21:32:39 +0800 Subject: [PATCH] 0.12.0 --- which interfaces this implementation provides, derived not written mcpp 2026.9.20.1 compares a consumer's `[kernel-abi] requires-interfaces` against the resolved implementation's `provides-interfaces` at dependency resolution and refuses before anything is compiled. openkal-linux and openkal-windows carry that array; this package did not, so a consumer that declared a requirement got no answer on macOS --- neither a refusal nor a confirmation, which is the shape of a check that silently does not run. THE ARRAY IS NOT WRITTEN BY HAND, and the step that keeps it honest is the one the two sibling implementations already run. "The exported surface is complete and contains nothing else" now regenerates it from the objects this package builds and fails the run if the two disagree. That is clause 9's surface comparison stopped one step earlier: the walk deciding whether each group is exported whole already answers which interfaces this implementation provides, so regenerating is the same derivation rather than a second one. The step also prints what it derived, so a disagreement names the right answer instead of only reporting that there is one. The array committed here is this implementation's claim to provide every interface --- the same claim `--complete` on the line above already makes. If the artefact disagrees, this run says so and prints what it found. BACKWARD COMPATIBLE, AND THIS REPOSITORY'S OWN CI IS THE TEST. `[kernel-abi]` is an unknown top-level table to an engine that predates the key, and an unknown top-level table is ignored. The pin here is mcpp 2026.8.27.1, three weeks older than the release that introduced the key, so a green run on this branch is that statement measured rather than asserted. --- .github/workflows/ci.yml | 18 ++++++++++++++++++ README.md | 2 +- mcpp.toml | 41 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9aad5a1..86c9bfc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -282,6 +282,24 @@ jobs: test -n "$objs" || { echo "no objects were found" >&2; exit 1; } bash .spec/tools/check-surface.sh --complete .spec/SURFACE.txt $objs + # The array in mcpp.toml is a declaration, and a declaration is + # checked rather than trusted. The check is the comparison above + # stopped one step earlier: the walk that decides whether each group + # is exported whole already answers which interfaces this + # implementation provides, so regenerating and diffing is the same + # derivation rather than a second one. The same step openkal-linux + # and openkal-windows carry, so that the three implementations answer + # the question the same way. + bash .spec/tools/check-surface.sh --toml .spec/SURFACE.txt $objs > /tmp/derived.toml + echo " derived from the artefact:" + sed 's/^/ /' /tmp/derived.toml + awk '/^provides-interfaces = \[/{p=1} p{print} /^\]/{if(p)exit}' mcpp.toml > /tmp/declared.toml + if ! diff -u /tmp/declared.toml /tmp/derived.toml; then + echo "::error::mcpp.toml's provides-interfaces disagrees with the artefact" + exit 1 + fi + echo " ok the declaration is the artefact's own answer" + # The property version 0.3 exists for. The assertion is made against the # objects rather than against the source, because a source can reach a C # library through a macro. diff --git a/README.md b/README.md index 2c83fda..2c88c11 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ written on the kernel's own calls. openkal = "0.14.0" [target.'cfg(os = "macos")'.dependencies] -openkal-macos = "0.11.0" +openkal-macos = "0.12.0" ``` Its purpose is as much to test the specification as to be used. A specification diff --git a/mcpp.toml b/mcpp.toml index fa95e2e..3e2b55a 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-macos" -version = "0.11.0" +version = "0.12.0" description = "An implementation of openkal for macOS, written on the kernel's own calls. Its purpose is as much to test the specification as to be used." license = "Apache-2.0" @@ -17,6 +17,45 @@ provides = ["mcpp:kernel-abi=openkal"] authors = ["mcpplibs"] repo = "https://github.com/mcpplibs/openkal-macos" +# WHICH INTERFACES OF THAT LAYER THIS PACKAGE PROVIDES (mcpp 2026.9.20.1). +# The engine compares this set against a consumer's `requires-interfaces` at +# dependency resolution and refuses before anything is compiled; it learns no +# interface name from it --- both lists are opaque strings and the only +# operation is a set difference, so the specification may add an interface +# without a release of the engine. +# +# NOT WRITTEN BY HAND. The step "The exported surface is complete and contains +# nothing else" regenerates this array from the objects this package builds and +# fails the run if the two disagree. It is clause 9's surface comparison +# stopped one step earlier: the walk that decides whether each group is +# exported whole already answers which interfaces this implementation provides, +# so regenerating is the same derivation rather than a second one. A +# declaration derived from the thing it describes cannot disagree with it, and +# an implementation that gains an interface cannot forget to say so. +# +# BACKWARD COMPATIBLE. An engine that predates the key reads `[kernel-abi]` as +# an unknown top-level table and ignores it, so this manifest loads unchanged +# everywhere it loaded before; the absence of the check is the behaviour that +# release already had. Measured against the published 2026.9.18.3 archive. +[kernel-abi] +provides-interfaces = [ + "openkal.abort", + "openkal.stream", + "openkal.memory", + "openkal.env", + "openkal.time", + "openkal.random", + "openkal.fs", + "openkal.process", + "openkal.task", + "openkal.exec", + "openkal.terminal", + "openkal.net", + "openkal.datagram", + "openkal.space", + "openkal.timeout", +] + [dependencies] openkal = "0.14.0"