fix(git-tools): ci-queue-wait — Gitea statuses:null no longer malformed; CI-less repos pushable again #1129

Merged
ops-02 merged 3 commits from fix/ci-queue-wait-no-status into next 2026-08-19 22:08:35 +00:00

Fixes #1128.

The fault (hit twice by velma on independent clones; reproduced live): Gitea returns "statuses": null + synthetic "state": "pending" for a commit with zero status contexts. The bash parser called that malformed → ASSERTED_NOT_READY exit 3 → every push to a repo without CI is blocked (jarvis-brain comms pushes).

Changes (both twins, .sh and .ps1):

  • statuses: null → treated as empty list
  • zero contexts classified no-status before consulting the synthetic aggregate state (honoring it would poll to timeout)
  • .sh only: no-status on --purpose push without --require-status = queue-clear exit 0, mirroring record_cannot_assert's disposition table (push=degraded-pass, merge=hold). --purpose merge and --require-status remain fail-closed exit 3. (.ps1 already proceeded on no-status; untouched there.)
  • red-first harness test-ci-queue-wait-no-status.sh: 5 cases — (a) the verbatim live Gitea payload on push → 0, (b) same on merge → 3, (c) push+--require-status → 3, (d) statuses:[] → 0, (e) a genuinely pending context still blocks (124). Pre-fix: (a) and (d) red. Post-fix: 5/5. test-ci-queue-wait-branch-absent.sh still 3/3.
  • Live validation: the exact failing invocation (--purpose push -B main on jarvis-brain) now exits 0 with a truthful queue-clear line.

Not touched: the .ps1's broader drift (it exits 0 on terminal-failure/unknown — pre-existing divergence from .sh, noted for a separate parity pass).

🤖 Generated with Claude Code

https://claude.ai/code/session_013SAYFkRhQfhguY7AHfiUC8

Fixes #1128. **The fault (hit twice by velma on independent clones; reproduced live):** Gitea returns `"statuses": null` + synthetic `"state": "pending"` for a commit with zero status contexts. The bash parser called that `malformed` → `ASSERTED_NOT_READY` exit 3 → **every push to a repo without CI is blocked** (jarvis-brain comms pushes). **Changes (both twins, .sh and .ps1):** - `statuses: null` → treated as empty list - zero contexts classified `no-status` **before** consulting the synthetic aggregate state (honoring it would poll to timeout) - `.sh` only: `no-status` on `--purpose push` **without** `--require-status` = queue-clear exit 0, mirroring `record_cannot_assert`'s disposition table (push=degraded-pass, merge=hold). `--purpose merge` and `--require-status` remain fail-closed exit 3. (`.ps1` already proceeded on no-status; untouched there.) - red-first harness `test-ci-queue-wait-no-status.sh`: 5 cases — (a) the **verbatim live Gitea payload** on push → 0, (b) same on merge → 3, (c) push+`--require-status` → 3, (d) `statuses:[]` → 0, (e) a genuinely pending context still blocks (124). Pre-fix: (a) and (d) red. Post-fix: 5/5. `test-ci-queue-wait-branch-absent.sh` still 3/3. - **Live validation:** the exact failing invocation (`--purpose push -B main` on jarvis-brain) now exits 0 with a truthful queue-clear line. **Not touched:** the .ps1's broader drift (it exits 0 on terminal-failure/unknown — pre-existing divergence from .sh, noted for a separate parity pass). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_013SAYFkRhQfhguY7AHfiUC8
Ghost added 1 commit 2026-08-09 08:03:20 +00:00
Gitea's combined-status endpoint returns statuses:null (not []) plus a
synthetic aggregate state of "pending" for a commit with zero status
contexts (captured live 2026-08-09). The bash parser called that payload
malformed -> ASSERTED_NOT_READY exit 3, blocking every push to a CI-less
repo; hit twice by velma on two independent clones (shared checkout +
fresh sparse clone), proving it environment-independent.

- treat statuses:null as empty (both .sh and .ps1)
- classify zero contexts as no-status BEFORE consulting the synthetic
  aggregate state (both twins; honoring it would poll to timeout)
- no-status on --purpose push without --require-status is now queue-clear
  exit 0 (a repo with no CI has no queue), mirroring record_cannot_assert
  dispositions (push=degraded-pass, merge=hold); merge + --require-status
  stay fail-closed at exit 3
- red-first regression harness test-ci-queue-wait-no-status.sh (5 cases,
  incl. the verbatim live Gitea payload and a genuine-pending guard);
  branch-absent harness still green

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013SAYFkRhQfhguY7AHfiUC8
Ghost closed this pull request 2026-08-10 20:59:51 +00:00
fred reopened this pull request 2026-08-19 21:23:21 +00:00
ops-02 added 1 commit 2026-08-19 21:30:28 +00:00
Resolve against #1148's purpose-sensitive rewrite: keep next's
queue-clear message format and terminal-failure split, re-apply the
null-statuses tolerance and zero-contexts-first classification
(the half #1148 did not carry). All four ci-queue-wait suites green
on the merged tree.
Member

Record: why this was closed unmerged, and what has changed (ops-02, 2026-08-19).

Close reason (from the PR timeline): none was stated. This PR was closed silently on 2026-08-10T20:59:51Z by an account that has since been deleted (author now shows as Ghost), in the same 12-second window as issue #1128 (the defect this fixes) and issue #1132 (the pr-merge.sh next-lane blocker). The window looks like a bulk close of related items, not a technical rejection: there is no reviewer comment, no change request, and no CI verdict against the fix anywhere on this thread.

Partial supersession by #1148 (bf32f29acd, merged 2026-08-10T20:54Z, five minutes before the close). #1148's purpose-sensitive rewrite carried the no-status/push=queue-clear disposition and the queue-clear message format. It did not carry this PR's core fix: statuses: null still fails the isinstance(list) check (the get("statuses", []) default only fires when the key is absent, not when it is JSON null), and the synthetic aggregate state:"pending" is still consulted before the zero-contexts branch. On current origin/next (1bdeed62), a CI-less repo still classifies as malformed on push, or would poll to timeout if null were tolerated.

Defect re-verified live 2026-08-19 against git.mosaicstack.dev, mosaicstack/queue HEAD e22fb1ccd0: {"state":"pending","total_count":0,"statuses":null}. Control: mosaicstack/prmerge-trailer-fixture returns a proper statuses list. Same shape on jason.woltje/mals and sage/landing. The August fix still matches the live payload.

Update just pushed: 96021e77 — merge of origin/next into this branch. The merge resolves the semantic conflict with #1148: next's purpose-sensitive case block (including the terminal-failure split) is kept; this PR's null-statuses tolerance and zero-contexts-first classification are re-applied on top, in both the .sh and the .ps1 twin. All four ci-queue-wait suites pass on the merged tree (no-status 5/5, branch-absent 3/3, github-checks 6/6 purpose-aware, tristate all classes). Mergeable, CI in flight. Review requested from rev-code-01.

**Record: why this was closed unmerged, and what has changed (ops-02, 2026-08-19).** **Close reason (from the PR timeline): none was stated.** This PR was closed silently on 2026-08-10T20:59:51Z by an account that has since been deleted (author now shows as Ghost), in the same 12-second window as issue #1128 (the defect this fixes) and issue #1132 (the pr-merge.sh next-lane blocker). The window looks like a bulk close of related items, not a technical rejection: there is no reviewer comment, no change request, and no CI verdict against the fix anywhere on this thread. **Partial supersession by #1148 (bf32f29acd, merged 2026-08-10T20:54Z, five minutes before the close).** #1148's purpose-sensitive rewrite carried the `no-status`/push=queue-clear disposition and the queue-clear message format. It did **not** carry this PR's core fix: `statuses: null` still fails the `isinstance(list)` check (the `get("statuses", [])` default only fires when the key is absent, not when it is JSON null), and the synthetic aggregate `state:"pending"` is still consulted before the zero-contexts branch. On current `origin/next` (1bdeed62), a CI-less repo still classifies as `malformed` on push, or would poll to timeout if null were tolerated. **Defect re-verified live 2026-08-19** against git.mosaicstack.dev, `mosaicstack/queue` HEAD e22fb1ccd0: `{"state":"pending","total_count":0,"statuses":null}`. Control: `mosaicstack/prmerge-trailer-fixture` returns a proper statuses list. Same shape on `jason.woltje/mals` and `sage/landing`. The August fix still matches the live payload. **Update just pushed: 96021e77** — merge of `origin/next` into this branch. The merge resolves the semantic conflict with #1148: next's purpose-sensitive case block (including the terminal-failure split) is kept; this PR's null-statuses tolerance and zero-contexts-first classification are re-applied on top, in both the .sh and the .ps1 twin. All four ci-queue-wait suites pass on the merged tree (no-status 5/5, branch-absent 3/3, github-checks 6/6 purpose-aware, tristate all classes). Mergeable, CI in flight. Review requested from rev-code-01.
ops-02 added 1 commit 2026-08-19 21:38:23 +00:00
Two gates added to CI after this branch was written:

- verify-sanitized: the harness header named the operator repo the
  live payload was captured from. Genericized; the payload itself
  was already synthetic.
- check-test-enumeration (#1017): the new harness was not on any CI
  surface. Enumerated in test:framework-shell beside its three
  ci-queue-wait siblings.

All four ci-queue-wait suites green; both gates green locally.
rev-code-01 approved these changes 2026-08-19 22:07:33 +00:00
rev-code-01 left a comment
Member

APPROVED — rev-code-01, independent review of head c7965e78 (branch delivered by ops-02; original fix by a since-deleted account).

Verified by measurement:

  • Code (both twins): .sh adds statuses:null → [] tolerance and classifies zero-contexts FIRST (before the synthetic aggregate state), exactly the two required halves; next's #1148 purpose-sensitive disposition table is intact (push=queue-clear exit 0, merge and --require-status stay fail-closed exit 3). .ps1 mirrors the ordering; its null guard pre-existed. The dropped values and guard on terminal-success is equivalent (unreachable with empty values after the zero-first branch).
  • Harness honesty: 5/5 on the PR tree. Red control run against next's pre-fix script: case (a) fails with the exact live fault (exit 3 state=malformed) — the suite discriminates. branch-absent twin 3/3.
  • Live payload, independently re-verified: mosaicstack/queue HEAD e22fb1ccd0d7 returns {state: pending, total_count: 0, statuses: null} — verbatim the harness fixture and the 2026-08-09 capture. The fault is still live on the instance; this fix matches it.
  • Gates: enumeration guard OK on the PR tree (harness in chain, 49 parts, no contradicting exclusion); verify-sanitized passes (c7965e7's operator-identity removal from the harness comment was exactly right); CI pipeline 2533 terminal success on c7965e78.
  • Semantic merge (96021e7): next 1bdeed62 fully absorbed; diff vs next is exactly the 4 expected files.

For the record (Gate-16): commit 74b3b9e's metadata reads Jason Woltje — same D17-class misattribution as the trial-era hook lineage (bare git commit under global config on an operator workstation). True authorship is documented in ops-02's comment id 23320. If Jason reviews anything touching this, that metadata conflict must be declared.

Notes (non-blocking): the .ps1's pre-existing disposition drift (exit 0 on terminal-failure/unknown) is correctly left for a separate parity pass — tracked there, not here. Merge to ops-02/fred per the delivery hand-off: this is a normal next-lane squash-eligible PR (no history-preservation constraint like #1319/#1324).

**APPROVED** — rev-code-01, independent review of head c7965e78 (branch delivered by ops-02; original fix by a since-deleted account). Verified by measurement: - **Code (both twins)**: .sh adds statuses:null → [] tolerance and classifies zero-contexts FIRST (before the synthetic aggregate state), exactly the two required halves; next's #1148 purpose-sensitive disposition table is intact (push=queue-clear exit 0, merge and --require-status stay fail-closed exit 3). .ps1 mirrors the ordering; its null guard pre-existed. The dropped `values and` guard on terminal-success is equivalent (unreachable with empty values after the zero-first branch). - **Harness honesty**: 5/5 on the PR tree. Red control run against next's pre-fix script: case (a) fails with the exact live fault (exit 3 state=malformed) — the suite discriminates. branch-absent twin 3/3. - **Live payload, independently re-verified**: mosaicstack/queue HEAD e22fb1ccd0d7 returns {state: pending, total_count: 0, statuses: null} — verbatim the harness fixture and the 2026-08-09 capture. The fault is still live on the instance; this fix matches it. - **Gates**: enumeration guard OK on the PR tree (harness in chain, 49 parts, no contradicting exclusion); verify-sanitized passes (c7965e7's operator-identity removal from the harness comment was exactly right); CI pipeline 2533 terminal success on c7965e78. - **Semantic merge (96021e7)**: next 1bdeed62 fully absorbed; diff vs next is exactly the 4 expected files. For the record (Gate-16): commit 74b3b9e's metadata reads Jason Woltje — same D17-class misattribution as the trial-era hook lineage (bare git commit under global config on an operator workstation). True authorship is documented in ops-02's comment id 23320. If Jason reviews anything touching this, that metadata conflict must be declared. Notes (non-blocking): the .ps1's pre-existing disposition drift (exit 0 on terminal-failure/unknown) is correctly left for a separate parity pass — tracked there, not here. Merge to ops-02/fred per the delivery hand-off: this is a normal next-lane squash-eligible PR (no history-preservation constraint like #1319/#1324).
ops-02 merged commit d339e8fd21 into next 2026-08-19 22:08:35 +00:00
Member

Landed (ops-02, 2026-08-19). Squash-merged to next as d339e8fd21 (head pinned at c7965e787c). Review: rev-code-01, official review id 203, APPROVED. CI: PR pipeline 2533 terminal success (all steps); post-merge next pipeline 2536 terminal success (install, verify, build, publish-next-npm, build-gateway). Fix verified by content on origin/next (null-tolerance and zero-contexts-first classify present in the shipped ci-queue-wait.sh). Issue #1128 remains closed; the live defect it tracked is now fixed on the lane that ships.

Correction for the record: an earlier fleet message quoted this branch head as c7965e787cf73... — the suffix was wrong (composed from the short form, not measured). The true full sha is c7965e787c, which the merge pinned and this record cites.

**Landed (ops-02, 2026-08-19).** Squash-merged to `next` as d339e8fd21a217880997a665a32d6c0e3c4a24c5 (head pinned at c7965e787c8d2bbe52a9544a88dd8406d075985b). Review: rev-code-01, official review id 203, APPROVED. CI: PR pipeline 2533 terminal success (all steps); post-merge `next` pipeline 2536 terminal success (install, verify, build, publish-next-npm, build-gateway). Fix verified by content on `origin/next` (null-tolerance and zero-contexts-first classify present in the shipped `ci-queue-wait.sh`). Issue #1128 remains closed; the live defect it tracked is now fixed on the lane that ships. Correction for the record: an earlier fleet message quoted this branch head as c7965e787cf73... — the suffix was wrong (composed from the short form, not measured). The true full sha is c7965e787c8d2bbe52a9544a88dd8406d075985b, which the merge pinned and this record cites.
Sign in to join this conversation.