Skip to content

Commit e84c14d

Browse files
committed
fix(review): the iOS gate could not fail, and two smaller findings of the same pass
THE macOS JOB THAT MEASURED THE iOS ROWS WAS A PROBE, AND IT STAYED ONE AFTER ITS MEASUREMENTS MOVED `aarch64-ios-sim` TO `verified`. Every step continued on error, so a regression in the Apple cross path would have printed `RUN-THROUGH-RUNNER-FAILED` inside a job reported green. Every reading of that job had been green, which is why only reading the workflow could find it. The job is split along that distinction: ios-host-surface the premise measurements; continues on error; runs on workflow_dispatch only, because a check that cannot fail, shown beside a gate, reads as a second gate ios-engine fails when an artefact's architecture, LC_BUILD_VERSION platform (2 device, 7 simulator) or minos differs from the row's -- compared as whole values, so an empty reading fails -- and when `mcpp run --target aarch64-ios-sim` does not exit 0 with `1-2-3` as a line of its output The fixture no longer declares `toolchain = "llvm@22.1.8"` for the three rows. That override was needed while they were `planned`, and it meant the job measured an override and never the rows' own pin. THE LOCATED SDK PATH REACHES THREE COMMAND LINES AND WAS QUOTED ON TWO. The std module's own command spliced it into a shell string unquoted, while every other path in that string goes through `shq`; an Xcode installed as `Xcode 16.app` would have broken only the module precompile. THE PAYLOAD ROOT JOINED `bin/` IN THE RUNNER SEARCH WITH A MEASUREMENT AND NO TEST. The rule is now `runner_lookup::payload_search_dirs`, and `AFlatPayloadIsFoundAtItsRoot` fails when it is reverted to `bin/` alone -- checked by reverting it. Two comments that still said "bin/ first, then PATH" now state the pair. Also: an emoji removed from a comment in tests/matrix/scan.sh; the design record's Status line said "for review before implementation" and now names where each item was implemented; its front matter is `landed` and the index is regenerated. Local: unit 111 passed, 0 failed; e2e 641 and 334 pass against the rebuilt binary.
1 parent 26c5ac9 commit e84c14d

8 files changed

Lines changed: 233 additions & 263 deletions

File tree

.agents/docs/2026-09-11-sdk-toolchains-and-ios-local-verification.md

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
---
22
subject: targets
3-
status: active
3+
status: landed
44
---
55

66
# SDK toolchains, the payload/engine seam, and openkal across iOS, Android and Web
77

8-
**Status:** design. Items A and E1 are measured and merged; the rest is for
9-
review before implementation.
8+
**Status:** implemented, in mcpp #612 (2026.9.11.4), xim-pkgindex #813 and
9+
#820, openkal #29 and #30, mcpp-index #393, and the new repository
10+
`mcpplibs/openkal-emscripten`. The design sections are kept as they were
11+
reviewed; where the implementation departed from them, the sections from "What
12+
the implementation found" onward record why.
1013

1114
**Scope.** Five items, in dependency order. The first is measured and only needs
1215
writing down; the second removes something rather than adding; the third is the
@@ -491,8 +494,8 @@ write it down.
491494
| C: the engine stops knowing | delete `ndk_host_tag()`'s call site and the build still resolves, because the descriptor answered; and a malformed descriptor is refused naming the file | yes -- a descriptor naming `oddly/named/clang++` resolved there, a path no engine derivation produces; a non-string `platform_floor` was refused naming the file and the key |
492495
| C: no flag day | a payload with no descriptor resolves exactly as today -- asserted against the released android-ndk | yes, against the installed r30 payload: with the file removed the resolution line and the effective triple are byte-identical |
493496
| C: the floor and the defines travel | not in the original list, and each needs its own reading or it is carried by the frontend's | yes -- `platform_floor = "26"` gave `…-android26` while `meta/platforms.json` says 21; an added define appeared in the std module's command AND in its cache identity |
494-
| D: iOS builds | macOS runner, `xim:llvm` plus the located SDK, artefact is Mach-O arm64 with the iOS platform in `LC_BUILD_VERSION` | yes -- `platform 2` (IOS) for the device and `platform 7` (IOSSIMULATOR) for both simulator rows, `minos 18.0`, `sdk 18.5` |
495-
| D: the simulator runs | macOS runner, `mcpp run --target aarch64-ios-sim` prints `1-2-3` | yes, through the `runner` and `xim:apple-simulator-tools`; and separately under a bare `simctl spawn`, which is what proved a bundle is not needed |
497+
| D: iOS builds | macOS runner, `xim:llvm` plus the located SDK, artefact is Mach-O arm64 with the iOS platform in `LC_BUILD_VERSION` | yes -- `platform 2` (IOS) for the device and `platform 7` (IOSSIMULATOR) for both simulator rows, `minos 18.0`, `sdk 18.5`. Asserted by `ios-engine`, which fails when any of the three readings differs, an empty reading included |
498+
| D: the simulator runs | macOS runner, `mcpp run --target aarch64-ios-sim` prints `1-2-3` | yes, through the `runner` and `xim:apple-simulator-tools`; and separately under a bare `simctl spawn`, which is what proved a bundle is not needed. Asserted by `ios-engine`, which fails when the exit status is not 0 or the line is absent |
496499
| D: the host surface is bounded | on a macOS runner with `xcode-select` pointing nowhere, both iOS rows fail with a message naming the SDK -- and no other row changes | THE CRITERION WAS WRONG AND WAS REPLACED. `DEVELOPER_DIR=/nonexistent` did not make the SDK unlocatable -- `xcrun` ignores an invalid developer directory and falls back -- so the iOS build SUCCEEDED and the step asserted nothing. The claim now lives where the SDK is genuinely absent: e2e 641 on every non-Apple host, with the refusal required to name the SDK, the `xcrun` command, the Command-Line-Tools note and the compiler, and to arrive before any payload is resolved |
497500
| E1: Android shares the implementation | merged and green against the RELEASED engine: both ABIs build, objects name no C library symbol, and a program over openkal alone ran on an emulator | yes (openkal-linux 0.12.0) |
498501
| E2: iOS reuses it | `openkal-macos` compiles for the three iOS rows on a macOS runner, and its objects name no C library symbol -- the same check the Android leg applies, against a third libc | the `cfg` line is in `examples/portable`; the compile leg belongs to openkal-macos's own CI and is not in this batch |
@@ -729,6 +732,43 @@ file was written on, travelling as if it were a property of the scheme. The
729732
fourth is a field the caller sets and the implementation must honour, and the
730733
suite passes a deliberately short structure to find out.
731734

735+
### A verified tier whose only check could not fail
736+
737+
The macOS job that measured the iOS rows was written as a probe. Every step
738+
continued on error, because its first version stopped at the first unmet
739+
premise and skipped the four measurements after it, and for a probe that was
740+
correct. It stayed that way after those measurements moved `aarch64-ios-sim` to
741+
`verified`, and a probe is not a gate: a regression in the Apple cross path
742+
would have printed `RUN-THROUGH-RUNNER-FAILED` inside a job reported green, and
743+
the tier would have gone on claiming a run that no longer happened.
744+
745+
The final review found it by reading the workflow rather than its result, which
746+
is the only way it could have been found. Every reading of that job was green.
747+
748+
The job is now split along that distinction. `ios-host-surface` keeps the
749+
premise measurements, continues on error, and runs only on request, because a
750+
check that cannot fail, shown beside a gate, reads as a second gate.
751+
`ios-engine` fails on four claims. Each of the three artefacts must be a Mach-O
752+
of the row's architecture whose `LC_BUILD_VERSION` names the row's platform
753+
(`2` for the device, `7` for both simulator rows) and the project's `minos`,
754+
compared as whole values so that an empty reading fails. And
755+
`mcpp run --target aarch64-ios-sim` must exit 0 with `1-2-3` as a whole line of
756+
its output.
757+
758+
The same review removed the fixture's three `toolchain = "llvm@22.1.8"`
759+
overrides. They were needed while the rows were `planned`, and they meant the
760+
job measured an override and never the rows' own pin, which is the path a
761+
project that declares nothing takes.
762+
763+
Two smaller findings from the same pass have the shapes already recorded
764+
above. The located SDK path reaches three command lines and was quoted on two:
765+
the std module's own command spliced it into a shell string unquoted, while
766+
every other path in that string goes through `shq`, so an Xcode installed as
767+
`Xcode 16.app` would have broken only the module precompile. And the payload
768+
root joined `bin/` in the runner's search with a measurement behind it and no
769+
test. The rule is now `runner_lookup::payload_search_dirs`, and a unit test
770+
fails when it is reverted to `bin/` alone, which was checked by reverting it.
771+
732772
## Gaps this batch recorded and did not close
733773

734774
Each is an engine or package change with a measurement behind it, and each was

.agents/docs/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Records that declare one. Everything else is listed by date below.
4646

4747
### targets
4848

49-
- [SDK toolchains, the payload/engine seam, and openkal across iOS, Android and Web](2026-09-11-sdk-toolchains-and-ios-local-verification.md)active
49+
- [SDK toolchains, the payload/engine seam, and openkal across iOS, Android and Web](2026-09-11-sdk-toolchains-and-ios-local-verification.md)landed
5050
- [Where a platform's knowledge belongs: iOS, Android and Web across the engine, the index and the plugins](2026-09-11-platform-targets-design-review.md) — active
5151

5252
### triage
@@ -58,7 +58,7 @@ Records that declare one. Everything else is listed by date below.
5858
### 2026-09
5959

6060
- [Six open issues: what each one actually is, and what would answer it](2026-09-11-six-open-issues-analysis.md) — active
61-
- [SDK toolchains, the payload/engine seam, and openkal across iOS, Android and Web](2026-09-11-sdk-toolchains-and-ios-local-verification.md)active
61+
- [SDK toolchains, the payload/engine seam, and openkal across iOS, Android and Web](2026-09-11-sdk-toolchains-and-ios-local-verification.md)landed
6262
- [Where a platform's knowledge belongs: iOS, Android and Web across the engine, the index and the plugins](2026-09-11-platform-targets-design-review.md) — active
6363
- [The category the plugin taxonomy does not name, and what a platform actually decomposes into](2026-09-11-distribution-plugins-and-platform-decomposition.md) — active
6464
- [Two answers and two silences: the scanner's second grammar, and the manifest keys nothing reads](2026-09-09-two-answers-and-two-silences.md) — active

0 commit comments

Comments
 (0)