runner beyond bare metal: honour [target.<triple>].runner on hosted targets, typed launch failures, not-run reporting, [xlings] values per host (#544) - #545
Open
Sunrisepeak wants to merge 7 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #544.
The defect
[target.<triple>].runnerwas parsed, validated and documented for every exact triple, and consulted only whenos == "none". On a hosted cross target (aarch64-linux-muslbuilt on x86_64)mcpp runexecuted the artifact bare, the kernel refused it withENOEXEC, andrun_execturned the refusal into a bare 127 with nothing printed;mcpp testreportedFAIL (exit 127), which states that the test ran. The bounded launcher's own invariant ("could not spawn" and "ran and failed" must not share an exit code) was defeated one layer down, and both deadline wrappers spawned a second time and discarded the first errno.Design record:
.agents/docs/2026-09-02-runner-beyond-baremetal-design.md(sections 0 and 4 are normative). Plan:.agents/docs/2026-09-02-issue544-runner-implementation-plan.md.What changes
Launcher layer.
DeadlineRunandBoundedOutcomecarry the spawn error;run_exec,capture_execand both deadline wrappers take a trailingint* spawn_error. A refused spawn is reported exactly once: typed to the caller when it asked, printed by the launcher otherwise. There is no second spawn.choose_runnerreads both producers for every target. The freestanding predicate decides one thing only: whether an absent runner is fatal before any spawn. The runner's first element is located by mcpp — thebin/of each payload declared under[xlings] deps, thenPATH— because a bare name onPATHreaches an xvm shim that answers for the current SubOS rather than for the package (e2e 130 recorded this in CI). Not found anywhere is decided before any spawn and is an error, not a fallback to bare execution.mcpp run. A declared runner is used; a runner that cannot be found or started is an error naming the program, the directories searched and the errno; an artifact the kernel refuses with no runner declared is reported with the key to write. All three exit 2, distinct from 1 ("ran and failed"). The run fast path declines an entry whose target has a runner declared (runner=line in.build_cache), so the secondmcpp runbehaves as the first.mcpp test.TestResult::St::NotRunwith a reason. The runner is resolved once per invocation; the first refused spawn sets an invocation-wide flag, later tests are reported not-run without a spawn, and the reason is printed once. The summary line carries the count at the same weight as failures;--message-format jsoncarriesnot_runandreasonper record andnot_run/not_run_reasonon the summary;--workspaceaddstests_not_runandunrunnable_members. Exit code 2 whenever the count is non-zero — the code the freestanding no-runner path already returns for the same situation.--no-runneronrunandtest: execute directly, ignoring a declared runner. The manifest has no host axis; this is the operator on a host where the triple is native stating that fact.[xlings]values per host platform. Adepsentry and a[xlings.workspace]value may be{ linux = "...", macos = "...", windows = "...", default = "..." }, the form xlings' own.xlings.jsonaccepts forworkspace;macosxis accepted as xlings' spelling. Resolved against the host at manifest load, so every downstream reader keeps its flat list. An unknown key is an error. Previously[xlings.workspace]dropped a table value in silence, and[xlings] depshad no conditional form at all, which madedeps = ["qemu-user-aarch64"](an x86_64-only package) a hard build error on every other host.The
[target.<triple>]unknown-key sweep now covers arrays (runnerX = [...]is reported) and listsrunneramong the supported keys.Decisions taken on review (design §0)
ENOENTas "absent" when it also means "found, interpreter missing".# requires:e2e never ran in CI.--no-runnerreplaces the withdrawn principle "a declaration this machine cannot satisfy must not disable a capability it has".runner = ""deferred (no producer emitsmcpp:runner=for a hosted triple); spelling settled as[]when needed.[xlings]values, in xlings' own form.Behaviour changes for existing manifests
runneralready declared under a hosted triple stops being inert. Where its program is missing on a host,mcpp run/mcpp teston that host now fail with a message instead of silently running the artifact bare;--no-runneris the escape.mcpp testrun that reportedFAIL (exit 127)for unrunnable artifacts now reportsNOT RUNand exits 2 (still non-zero).[xlings] depsand[xlings.workspace]accept a table value; a table with an unknown platform key is now an error where it was previously dropped.Verification
test_process_run_exec(+9),test_manifest(+6), newtest_runner_lookup(9). Full unit suite: 97 test binaries pass.330_runner_hosted_targets.sh— no# requires:beyondunix-shell; the runner is a recording shell script and the unrunnable artifact is a host binary withe_machinepatched to0xffff, so it runs identically on a host with and without binfmt_misc. Sections: declared runner used on bothrundoors;--no-runner; runner not found (runandtest); unrunnable artifact onrun;mcpp testwith one and two tests (streaming and capturing paths), human and JSON; array typo in the sweep. Fails at its first section on 2026.9.1.1 and passes on this branch.check_docs_style.sh,check_modules_wiring.sh,check_version_pins.shpass.Docs: 05 (§2.7.1, new §2.7.3 and §2.7.3.1, §2.13), 11 (the
mcpp teststream), 13, 15, 17, each with itsdocs/zh/twin.Version: 2026.9.2.1 (
mcpp.toml,modules/versioning/src/version.cppm); the bootstrap pin stays at 2026.9.1.1 until the release is indexed.