ci: correct the Analyze (swift) diagnosis, and record what trace=false cannot do - #24
Shepdesign wants to merge 3 commits into
Conversation
The banner asserted that no workaround exists for the swift-plugin-server EBADARCH failure. It is now tested rather than asserted, so the next person does not spend an afternoon on the obvious idea. CodeQL's tracer does take an extra Lua config, and a `trace = false` matcher for swift-plugin-server does fire. It still cannot help: `trace = false` suppresses the extractor for a process, not the library injection into it. The preload variable is set once in the build command's environment and inherited by every descendant, so an arch-incompatible child dies in dyld before any matcher is consulted. Reproduced against CodeQL 2.27.0 — a child matched by `trace = false` saw the preload variable set identically to an unmatched control. That also explains sandbox-exec: it is already excluded upstream, and what fixed it was removing its spawn, not excluding it. Skipping the build is ruled out too: the Swift extractor declares only autobuild and manual build modes, so a traced build is mandatory. Comments only. No step, option or behaviour changes, and the reproduction's one weakness — it was run on Linux, against LD_PRELOAD rather than DYLD_INSERT_LIBRARIES — is recorded alongside it rather than glossed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UuHYhiqbmF4dT7sq8a6AYm
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The remaining feedback is minor documentation-level clarification.
Review effort: Lite
Findings: 1
Open (1)
What changed in this PR
Documents why CodeQL tracing exclusions cannot resolve the Swift plugin architecture failure without changing workflow behavior.
Changes:
- Replaces the unsupported workaround claim with a precise diagnosis.
- Records tracing/build-mode experiments, limitations, and likely upstream fixes.
| File | Description |
|---|---|
.github/workflows/codeql.yml |
Adds diagnostic documentation; workflow behavior is unchanged. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
"there is no no-build path" was grammatical — `no-build path` is a compound noun — but the line break landing between the two made it look like a typo, and two readers in a row stumbled on it. The construction is gone rather than defended: "there is no way around the tracer at all" says the same thing. Comment text only. Same eight steps, suite still 110/110. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UuHYhiqbmF4dT7sq8a6AYm
Reading two job logs properly turned up three things this comment had wrong, one of them a claim it presented as tested. The version claim was false. It said this action SHA pins CodeQL 2.27.0 via the action's own src/defaults.json. The logs show 2.27.1 being installed. That was asserted and never observed, so it is now stated from the logs instead, and the "not a version problem" conclusion is downgraded to what is actually known: nothing yet ties either failure to a CodeQL version. The EBADARCH failure is intermittent, not deterministic. "Bad CPU type" appears fourteen times on 932b589 and zero times on 6682385 — two runs five minutes apart on the same branch, different runners. And there is a second failure underneath it, consistent across both runs: four "'self' is immutable" errors in KeyboardShortcuts/ViewModifiers.swift, visible only under the traced build. They were always there and were buried under the louder one. Cause not established, and recorded as not established. The mechanism is now named rather than hand-waved: an arm64 libtrace.dylib is inserted into an x86_64 compile, because nothing sets ARCHS or ONLY_ACTIVE_ARCH so the Release configs build universal. That also retires the claim that the fix had to be upstream — building one architecture under CodeQL is a flag on the two xcodebuild calls, and it had not been tried when that claim was made. The trace=false negative result stands and is kept, now marked as predating this understanding: it rules out two approaches, not the problem. Comments only. Same eight steps, suite still 110/110. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UuHYhiqbmF4dT7sq8a6AYm
Correction, and this PR's conclusion no longer holds as written
1. The CodeQL version claim was falseBoth logs show the action installing 2.27.1: The banner claimed this action SHA pins 2.27.0 through the action's own 2. The failure is intermittent, and I described it as deterministic
Two runs, five minutes apart, same branch, different runners. I wrote above that it "reproduces deterministically." It does not. 3. A second failure was hiding under the firstThose four And the conclusion was wrongThis PR concluded the fix had to be upstream. That was reached without ever checking what architecture the traced build targets. It targets two: An arm64 tracer inserted into an x86_64 compile. Nothing in What still standsThe The honest shape of this PR is now: a correct negative result plus a diagnosis that was confidently wrong about scope, both recorded. Generated by Claude Code |

What
You asked me to try the CodeQL tracer-config fix for the failure keeping
Analyze (swift)red. Two things came out of it, and only one is what I set out to find:Comments only. One file. YAML parses to the same 8 steps, the non-comment diff is empty, suite still 110/110.
The two failures, from the logs
Runs 36092189970 (
932b589) and 36092546432 (6682385), five minutes apart on this branch:932b5896682385Bad CPU typecould not be loaded'self' is immutableA — an arch mismatch, intermittent. An arm64 tracer inserted into an x86_64 compile:
dyld refuses the insert, so
#Previewnever expands. The build is universal because nothing inproject.ymlor the xcconfigs setsARCHS, so Release takesARCHS_STANDARD. Fourteen occurrences on one run and zero on the next means one clean run proves nothing.B — a second failure underneath, consistent. Four
'self' is immutableerrors inKeyboardShortcuts/ViewModifiers.swift, in both runs, only under tracing. Buried under A's fourteen lines; when A was silent they were the whole failure. Cause not established, and recorded as not established. B is what will still be red when A clears.What I tested on the tracer config, and what it proved
Pulled CodeQL 2.27.0 locally and ran the mechanism end to end.
--extra-tracing-configreal ondatabase init?--definitely-not-an-optionis rejected withUnknown option.CODEQL_TRACER_EXTRA_CONFIG— visible indb/temp/tracingEnvironment/start-tracing.sh, and the name is inlibtrace's strings.error()surfaces in the tracer log.RegisterExtractorPackthe entry point?RegisterExtraConfig(), pertools/tracer/base.lua.trace = falsematcher fire?Lua: Disabling tracing for language swift.Identical.
trace = falsemeans "run no extractor for this process", not "do not inject into it" — which is whatbase.luadocuments. The preload variable is set once in the build command's environment and inherited by every descendant, so the library is loaded before any Lua runs.That reproduction was on 2.27.0, which is not the 2.27.1 CI installs. The Lua contract is documented and unchanged between them, but the run was on the other patch version and the banner now says so.
It also explains
sandbox-exec: already excluded upstream withtrace = false, and still died. What fixed it was removing its spawn, not excluding it.A trap for anyone who revisits this
Extra-config matchers overwrite a language's matchers rather than adding to them. A naive config would have destroyed
SwiftMatcherand produced a database with no Swift in it — which the gate reads as clean. Mine calledGetRegisteredMatchers('swift')and errored if it came back empty. That is the fail-open shape this mechanism has already been bitten by twenty-eight times.Also ruled out
build-mode: nonewould skip the tracer entirely. Swift does not support it —swift/codeql-extractor.ymldeclaresautobuildandmanualonly, wherejavaandcsharpalso declarenone. A traced build is mandatory.What I got wrong, and why
I concluded the fix had to be upstream without checking what architecture the traced build targets. That was the first question to ask, and the answer was one grep away in a log I had already downloaded. The arch mismatch had been sitting in both logs the whole time.
The version claim is the same shape: inherited from this file, repeated as if verified, never checked against a log. I flagged exactly this failure mode in the handoff for #22 and then reproduced it.
What this does not change
The queries have still never been observed firing on real Swift. That needs a traced build that completes. This PR makes the reason precise; #25 tries to fix it.
Demo
CI infrastructure, so the demo is the verification above plus the checks on this branch:
Analyze (swift)will be red here, for the reasons this PR documents.Rule check
Non-negotiable 5 — touches its enforcement only as documentation. No app behaviour, no endpoint,
Sources/untouched,contents: readunchanged. No new network call in CI; the CodeQL bundle was downloaded into a scratch dir for local verification and is neither committed nor referenced.Brand check
None. No UI, no assets, no tokens.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UuHYhiqbmF4dT7sq8a6AYm