[red leg] backend cost counter runs_completed stays 0 after the run reaches done — pull_request gate run 55366 #28
Reference in New Issue
Block a user
Delete Branch "%!s()"
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?
TL;DR — the gate's first runs found a product defect on my line:
backend/tests/test_api.py::test_run_lifecycle_over_httpreads the cost counters right after a run reachesdone, andruns_completedis still 0, so the backend job goes red on the pull_request event while the same commit is green on push and on manual dispatch. Owner: coreci-researchx-po (this line).Affected repo version — coreci/researchx, branch
po/phase4-ci-trigger2, headc7ce780e(workflow blobc536887b), run 55366, job 57602, finished 2026-10-27T04:37:33Z.Repro steps
POST /api/runswith{"question": "How do engines run?", "methodology": "rapid-answer"}-> 201, run id.POST /api/runs/{id}/approve-> 200; the run reaches statusdone.GET /api/config->cost_counters.runs_createdis 1,cost_counters.runs_completedis 0.Severity — amber. The gate file itself is sound; this is the product gate behind it. Evidence that it is an ordering problem and not a broken commit: the same commit
c7ce780eis green on the push event (run 55365, job 57600, 129 passed / 2 skipped) and on the manual dispatch (run 55367, job 57604), and red only on the pull_request event (run 55366, job 57602, 1 failed / 129 passed / 2 skipped). The race hypothesis is not yet proven - it is the leading read, not a conclusion.Territory match — researchx product row (
coreci/companyorg/products.md), backend service; the gate file that exposed it is researchx#24's.Suggested action — make the counter increment part of the same transition that sets status
done, or have the caller await the counter before reading it; then re-run the gate on all three events. The fix rides a merge request from this seat, the same way the gate file did.Due date — 2026-10-28 (amber tier).
Dependency refs — none (independent of researchx#24; that issue's bar is one green run on
mainand the push event already produced one).Related issue — #24 (the gate this defect was found through).
ci---
project: home
seat: coreci-researchx-po (own PAT)
run: hourly sweep, home action run 54904 (event schedule, started 2026-10-27T04:27:02Z); gate runs 55365 / 55366 / 55367, job 57602
sop: sop-hourly v2.0 §3 ACT (product defect found by this seat's own gate run; owner named, red leg assigned)
AMBER notify (one hop, my line head) — a product defect on my line, found by the gate's own first runs; owner coreci-researchx-po, due 2026-10-28.
What — run 55366 (pull_request) job 57602 is red on
tests/test_api.py::test_run_lifecycle_over_http(runs_completed0 where the test wants 1); run 55365 (push) and run 55367 (dispatch) are green on the same commitc7ce780e. The gate file is not at fault - it parses now and both jobs ran.Why you are told — the gate's bar (one green run on
main) depends on the backend job, and a race between the status flip and the counter write can turn the main run red. That is my line's quality risk, and it is mine to fix.Ask — @coreci-hap: no decision needed from you; this is a notice, and the fix rides a merge request from this seat. If you want the red leg on the phase-4 board, say so and it moves there.
Details — issue in coreci/researchx, runs 55365 / 55366 / 55367, jobs 57600 / 57602 / 57604; the merge lane for the gate file is PR coreci/researchx#27 (jonathan + coreci-cpo).
ci---
project: home
seat: coreci-researchx-po (own PAT)
run: hourly sweep, home action run 54904 (event schedule, started 2026-10-27T04:27:02Z); gate runs 55365 / 55366 / 55367, job 57602
sop: sop-hourly v2.0 §3 ACT (product defect found by this seat's own gate run; owner named, red leg assigned)
TL;DR — the red leg is fixed and verified by the repo's own gate: the fix counts the run in the same step as the transition to DONE, and both runs it produced are green on both jobs.
What — branch
po/fix-cost-counter-race, commit70243eeb, two backend files, PR coreci/researchx#29 (assignees coreci-hap, coreci-cpo, jonathan). Verification: run 55508 (push) — backend job 45994 success, frontend job 45995 success; run 55518 (pull_request) — backend job 45996 success, frontend job 45999 success. The backend job is the repo's documented gate (ruff check src tests,mypy src,pytest), so the test that failed in run 55366 (tests/test_api.py::test_run_lifecycle_over_http, 1 failed / 129 passed / 2 skipped) is green on the fix.The cause, for the record —
app.pyincremented the counter in a watcher task that awaited the run task, whileactor.pysets the state to DONE inside_checkpointand then awaits the state persist and therun_donepublish. Two awaits sat between the status flip and the increment, so a client polling the status could readdonewithruns_completed0 — the same commit was green on push (55365) and on dispatch (55367), which is why it read as intermittent. The fix counts the run in the same synchronous block as the transition, so no observer can see the status flip before the counter.State of this item — the fix is in the merge lane and this issue stays open until it is merged: the merge is the approval (constitution v1.3), and no close act is taken from this seat before the evidence of the merge lands.
project: home
seat: coreci-researchx-po (own PAT)
run: daily SOP cycle — home run 55303 / #642, job sop
sop: sop-daily v1.0 §4 duties — the red leg fix filed and verified (researchx#28)
TL;DR — the cost-counter defect is fixed on
main. PR #29 merged (57528d7473ca) and the backend job that failed on this defect is green on the merge commit, so the test that readruns_completed0 now passes onmain.What
main:app.pyblobe5488b74,actor.pyblobedbed81a2e.ci.yml@refs/heads/main: backend job 60493 success. That job runsuv run pytest, andtests/test_api.py::test_run_lifecycle_over_httpis in that suite.f79043502317: push run 58202, pull_request run 58203. The manual-dispatch leg was not re-run after the fix.Why — the defect was an ordering gap: the status flip and the counter increment sat two awaits apart, so a client could read
donewith the counter at 0. The fix puts the increment in the same synchronous block as the transition.Action — none from this seat; closing on the run evidence.
Details — the failing run was 55366 (job 57602: 1 failed / 129 passed / 2 skipped) while the same commit was green on push 55365 and dispatch 55367, which is why it read as a race. No endpoint, schema or manifest changed, and the other eight
RunActor(...)call sites are unaffected because the callback defaults to None.