fix(ci): unstick the native Solstice lane — protoc too old for proto3 optional #369
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
toasterson/Anima!369
Loading…
Reference in a new issue
No description provided.
Delete branch "claude/fix-native-ci-protoc"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The native CI lane has been red for two weeks and nobody saw it
runs_on=rust— the native Solstice dispatch path, the one the machine exit bar consumes — last went green on 2026-07-11 20:56. Since 2026-07-20 it has run 36 jobs, 0 successes. Each burns ~40 minutes of a CI VM before failing.Root cause
.solstice/job.shinstalledprotobuf-compilerfrom jammy, which is protoc 3.12. protoc rejects proto3optionalfields before 3.15 unless--experimental_allow_proto3_optionalis passed:Commit
5c1dd37(2026-07-11) addedoptional string project_id = 1;tothread.proto. The native lane's last green run was the same day. Exact correlation.The Forgejo Actions lane never broke, because its
ubuntu-22.04image carries a newer protoc. So the outage was invisible on the path everyone watches, and the green Actions badge kept saying CI was fine.The fix
Install a pinned protoc release into
/usr/local(binary plus the well-known.protoinclude tree) when the detected protoc is older than 3.15, and exportPROTOCsoprost-buildcannot fall back to the distro binary at/usr/bin/protoc.Passing
--experimental_allow_proto3_optionalwould also work, but it means threading a flag through everyprost-buildcall site and keeping it there forever; a current protoc is the smaller standing cost.The version probe treats missing or malformed
protoc --versionoutput as "install" rather than "skip", so it degrades toward doing the work. Verified against3.12.4→ install,27.3→ skip, empty → install, malformed → install.How this was found
Not from the CI badge — from
job_logsinsolstice_proddirectly.jobs.failure_summaryfor these runs contains onlyjob script failed: exit_code=101, with no log tail, so the failure carries no diagnostic content anywhere it is surfaced. Andsolstice-mcp list_runs(owner, repo)cannot see these jobs at all because native-dispatch rows leaverepo_owner/repo_nameNULL.Both of those are filed separately against the new
solstice-ciAnima project:source—019f998b-be04-7f70-8138-27774a142d85runningrows vs 5 real VMs) —019f998b-9cea-7bf3-87c4-c6a6ad24f0efVerification status
Not yet proven end to end. This change only takes effect on a native
rustdispatch, which is triggered by an agent branch push, not by opening this PR — the Actions lane that will run on this PR is the one that was already passing. The fix should be confirmed by watching the first native job after merge, not by this PR going green.🤖 Generated with Claude Code
Verification update — mechanism proven, install path still pending
The PR description said this was unproven. Part of it no longer is.
The protoc version theory is now confirmed directly, not inferred from the error message:
A modern protoc compiles
thread.proto— includingoptional string project_id = 1;at line 74 — cleanly, with no--experimental_allow_proto3_optional. That is the exact file and the exact field the CI failure names, so the diagnosis holds: the only difference between red and green here is the protoc version.The download path is also verified:
https://github.com/protocolbuffers/protobuf/releases/download/v27.3/protoc-27.3-linux-x86_64.zip→ HTTP 200bin/protoc, plusinclude/google/protobuf/field_mask.protoandinclude/google/protobuf/timestamp.proto— the two well-known imports named in the build warnings. Unzipping to/usr/localtherefore lands the binary on PATH ahead of/usr/bin/protocand the includes where protoc looks for them.What remains unproven is narrower than before: whether the install actually executes correctly inside the CI VM — sudo/unzip availability, PATH ordering in the runner's non-login shell, and
prost-buildhonouring the exportedPROTOC. Those only exercise on a nativerustdispatch, which this PR does not trigger. Confirm on the first native job after merge.Note that
unzipwas added to the apt line in this change; without it the install step would fail rather than silently skip, which is the intended direction.Impact update: this bug is not just red CI, it is actively destroying work items
Measured on
solstice_prod, last 24 hours:23 of 24 native CI failures for this repo in the last day are this exact protoc error. That is not background noise — it is the near-totality of the lane.
The chain
exit_code=101.anima_server::solsticereads that as a genuine CI-red and re-dispatches the work item with corrective context — telling an implementer to fix a build failure that has nothing to do with their change.cap=3.auto-parked: CI-red failed dispatch cap reached— the work item leaves the dispatch queue.What it has cost
Seven work items auto-parked in the last 24 hours, five of them Anima:
WI-A through WI-D are the entire ACP escalation slice. All four parked today, none for a reason connected to their own code. Every one of them also burned agent sessions first (one ran 2200s before failing), chasing a phantom.
The park is silent by design — it looks like a work item that legitimately gave up, and it is indistinguishable from one.
Follow-up after merge
Merging this stops the bleeding but does not undo it. The parked items need reopening once a native run goes green — they were parked on false evidence and their
failed_dispatch_countshould be reset, not merely decremented. Recommend confirming one green native job first, then unparking as a batch.Worth noting how this compounds with the two lane-visibility gaps already filed: the Actions lane stayed green throughout, so from every dashboard this looked like a healthy repo steadily parking work for its own reasons.
-D warningsfloats with whatever rustc the image ships #385