Finding — recording only, not claimed. Surfaced while landing the half-state patrol family (PR #11294, the parameterisation half graded on #11217). Filed unassigned and out of that PR's declared file surface, which was exactly scripts/pm/check-half-states.mjs, .github/workflows/half-state-patrol.yml and scripts/pm/ensure-pm-labels.sh.
Dedup-searched over open domain:skills cards and the sweeper's own history (ci-failure, PM_SWEEP_REPO, OWNER_REPO, the sibling-repo adoption thread): #11217 covers the sweeper, #11218 the cross-repo Blocked-by: target, #10971dispatch-gates.mjs. None covers this file.
The defect
scripts/pm/ci-failure.mjs:300, verbatim:
constOWNER_REPO=process.env.PM_SWEEP_REPO??'objectstack-ai/objectstack';
That is the same hardcoded-default trap the sweeper just had removed, in a second PM script, and it is the one shape that reads as correct in every review: on a runner the variable is normally unset, so a copy of this file in objectui — or a run of it from any container without the override — reads objectstack's Actions API and reports about this repo's CI while its caller believes it is reading its own. A wrong-repo answer is not distinguishable from a right one by its shape; only the run ids give it away, and nobody checks run ids against a repo they did not doubt.
The shape of the fix
The remedy landed for the sweeper in PR #11294 and is three lines, exported and self-tested there — resolveSweepRepo, which resolves PM_SWEEP_REPO -> GITHUB_REPOSITORY (what Actions sets to the repo the workflow is installed in) -> the literal default, and refuses a malformed value rather than substituting a different board. Importing that resolver here is probably the whole change; ci-failure.mjs already imports four other things from check-half-states.mjs, so the seam exists.
⛔ Not costed here, and worth a triage read first: whether ci-failure.mjs has a sibling-repo consumer at all today. If it does not, this is latent rather than live — but it is latent in the direction that produces a confident wrong answer, not an error.
Re-check
grep -n "OWNER_REPO = process.env" scripts/pm/*.mjs
Generated by Claude Code
Finding — recording only, not claimed. Surfaced while landing the half-state patrol family (PR #11294, the parameterisation half graded on #11217). Filed unassigned and out of that PR's declared file surface, which was exactly
scripts/pm/check-half-states.mjs,.github/workflows/half-state-patrol.ymlandscripts/pm/ensure-pm-labels.sh.Dedup-searched over open
domain:skillscards and the sweeper's own history (ci-failure,PM_SWEEP_REPO,OWNER_REPO, the sibling-repo adoption thread): #11217 covers the sweeper, #11218 the cross-repoBlocked-by:target, #10971dispatch-gates.mjs. None covers this file.The defect
scripts/pm/ci-failure.mjs:300, verbatim:That is the same hardcoded-default trap the sweeper just had removed, in a second PM script, and it is the one shape that reads as correct in every review: on a runner the variable is normally unset, so a copy of this file in objectui — or a run of it from any container without the override — reads objectstack's Actions API and reports about this repo's CI while its caller believes it is reading its own. A wrong-repo answer is not distinguishable from a right one by its shape; only the run ids give it away, and nobody checks run ids against a repo they did not doubt.
The shape of the fix
The remedy landed for the sweeper in PR #11294 and is three lines, exported and self-tested there —
resolveSweepRepo, which resolvesPM_SWEEP_REPO->GITHUB_REPOSITORY(what Actions sets to the repo the workflow is installed in) -> the literal default, and refuses a malformed value rather than substituting a different board. Importing that resolver here is probably the whole change;ci-failure.mjsalready imports four other things fromcheck-half-states.mjs, so the seam exists.⛔ Not costed here, and worth a triage read first: whether
ci-failure.mjshas a sibling-repo consumer at all today. If it does not, this is latent rather than live — but it is latent in the direction that produces a confident wrong answer, not an error.Re-check
Generated by Claude Code