🤖 Generated by the Agentic Engineer
Evidence
validate-go-project.yaml hard-codes GOMEMLIMIT: 8GiB on both memory-hungry Go analysis jobs (govulncheck and deadcode). That value is chosen for ubuntu-latest on a public repository, which GitHub documents as 16 GB — it leaves half the host for everything GOMEMLIMIT does not govern.
On a private repository the standard ubuntu-latest runner has 8 GB. 8GiB is about 8.59 GB, so the cap would exceed the machine's entire memory and provide no headroom at all — reinstating exactly the OOM class that PR #1218 was opened to fix (an opaque exit 143 that no retry clears).
The workflow's own comment already tells such a consumer what to do: use a larger runner or a caller-side cap below it. The second half of that sentence names a remedy that does not exist — GOMEMLIMIT is a literal in the job's env:, and workflow_call.inputs exposes no way to lower it. A private consumer's only options today are forking the workflow or paying for a larger runner.
Audience and problem
Any future private-repository consumer of this reusable workflow. There is no such consumer today — ksail is currently the only external caller, it is public, and the organisation's only private repository has no Go workflow — which is why this is filed rather than fixed inside #1218.
Hypothesis
Exposing the cap as a workflow_call input with the current value as its default lets a private consumer size the limit to its own runner without forking, and makes the documented remedy true. Being additive with an unchanged default, it cannot affect the existing public consumer.
Success signal
A private-repository caller can run this workflow to completion on a standard runner by passing a lower cap, with no fork and no larger-runner spend. Baseline: impossible today. Guardrail: ksail's scan time and OOM rate must not change, since its effective value is unchanged.
Acceptance criteria
Size
Small-to-medium. The workflow change is a handful of lines; the guard change is the real work, because it must keep every property proven in #1218 — decimal parsing, the per-unit digit bound, and failing closed on anything it cannot compare.
Found while resolving a Codex review finding on #1218.
Evidence
validate-go-project.yamlhard-codesGOMEMLIMIT: 8GiBon both memory-hungry Go analysis jobs (govulncheckanddeadcode). That value is chosen forubuntu-lateston a public repository, which GitHub documents as 16 GB — it leaves half the host for everythingGOMEMLIMITdoes not govern.On a private repository the standard
ubuntu-latestrunner has 8 GB.8GiBis about 8.59 GB, so the cap would exceed the machine's entire memory and provide no headroom at all — reinstating exactly the OOM class that PR #1218 was opened to fix (an opaque exit 143 that no retry clears).The workflow's own comment already tells such a consumer what to do: use a larger runner or a caller-side cap below it. The second half of that sentence names a remedy that does not exist —
GOMEMLIMITis a literal in the job'senv:, andworkflow_call.inputsexposes no way to lower it. A private consumer's only options today are forking the workflow or paying for a larger runner.Audience and problem
Any future private-repository consumer of this reusable workflow. There is no such consumer today —
ksailis currently the only external caller, it is public, and the organisation's only private repository has no Go workflow — which is why this is filed rather than fixed inside #1218.Hypothesis
Exposing the cap as a
workflow_callinput with the current value as its default lets a private consumer size the limit to its own runner without forking, and makes the documented remedy true. Being additive with an unchanged default, it cannot affect the existing public consumer.Success signal
A private-repository caller can run this workflow to completion on a standard runner by passing a lower cap, with no fork and no larger-runner spend. Baseline: impossible today. Guardrail:
ksail's scan time and OOM rate must not change, since its effective value is unchanged.Acceptance criteria
workflow_call.inputsgains an input for the Go memory cap, defaulting to the current8GiB.GOMEMLIMITconsume it.test-govulncheck-timeout.shstill enforces the ceiling. This is the load-bearing part: the guard reads.jobs.*.env.GOMEMLIMITfrom the YAML, so once that value becomes a${{ inputs.… }}expression the guard sees an expression string rather than a number and rejects it. It must resolve the input'sdefaultinstead, and must still fail closed when it can resolve neither.Size
Small-to-medium. The workflow change is a handful of lines; the guard change is the real work, because it must keep every property proven in #1218 — decimal parsing, the per-unit digit bound, and failing closed on anything it cannot compare.
Found while resolving a Codex review finding on #1218.