Make director merge read successful PR status contexts from Forgejo status history #994

Closed
opened 2026-07-10 09:39:56 +00:00 by coilyco-ops · 10 comments
Member

Problem

warded director merge --repo coilyco-flight-deck/ward --dry-run --limit 100 is skipping ward PRs even when Forgejo reports the required PR status context as successful.

Live evidence from 2026-07-10:

  • ward#983 head 79ea8f3e6f077c7646d8de3212307619a5a179e1 has status test / test (pull_request) = success, description Successful in 26s.
  • ward#984 head 50a13c9e3d78e6e07e99085137cc145547695194 has status test / test (pull_request) = success, description Successful in 28s.
  • ward#987 head b221f004904e0d3aa71082a71e0b20cce80de261 has status test / test (pull_request) = success, description Successful in 25s.

But the director dry-run prints:

skipping coilyco-flight-deck/ward#983: linked PR head SHA 79ea8f3e6f077c7646d8de3212307619a5a179e1 has required status context test / test (pull_request)=
skipping coilyco-flight-deck/ward#984: linked PR head SHA 50a13c9e3d78e6e07e99085137cc145547695194 has required status context test / test (pull_request)=
skipping coilyco-flight-deck/ward#987: linked PR head SHA b221f004904e0d3aa71082a71e0b20cce80de261 has required status context test / test (pull_request)=

The Forgejo status list includes multiple rows for the same context (pending, then success). The director appears to be treating the context as unset instead of selecting the latest successful state.

Acceptance criteria

  • The director status check selects the authoritative/latest status per context for a PR head SHA.
  • A status history containing older pending rows and a newer success row passes the required-context gate.
  • Tests cover repeated statuses for the same context in Forgejo response order.
  • The skip message prints the actual status value when the context exists but is not passing.
  • warded director merge --repo coilyco-flight-deck/ward --dry-run --limit 100 no longer skips successful PRs with context= blank.
## Problem `warded director merge --repo coilyco-flight-deck/ward --dry-run --limit 100` is skipping ward PRs even when Forgejo reports the required PR status context as successful. Live evidence from 2026-07-10: * `ward#983` head `79ea8f3e6f077c7646d8de3212307619a5a179e1` has status `test / test (pull_request)` = `success`, description `Successful in 26s`. * `ward#984` head `50a13c9e3d78e6e07e99085137cc145547695194` has status `test / test (pull_request)` = `success`, description `Successful in 28s`. * `ward#987` head `b221f004904e0d3aa71082a71e0b20cce80de261` has status `test / test (pull_request)` = `success`, description `Successful in 25s`. But the director dry-run prints: ```text skipping coilyco-flight-deck/ward#983: linked PR head SHA 79ea8f3e6f077c7646d8de3212307619a5a179e1 has required status context test / test (pull_request)= skipping coilyco-flight-deck/ward#984: linked PR head SHA 50a13c9e3d78e6e07e99085137cc145547695194 has required status context test / test (pull_request)= skipping coilyco-flight-deck/ward#987: linked PR head SHA b221f004904e0d3aa71082a71e0b20cce80de261 has required status context test / test (pull_request)= ``` The Forgejo status list includes multiple rows for the same context (`pending`, then `success`). The director appears to be treating the context as unset instead of selecting the latest successful state. ## Acceptance criteria * The director status check selects the authoritative/latest status per context for a PR head SHA. * A status history containing older `pending` rows and a newer `success` row passes the required-context gate. * Tests cover repeated statuses for the same context in Forgejo response order. * The skip message prints the actual status value when the context exists but is not passing. * `warded director merge --repo coilyco-flight-deck/ward --dry-run --limit 100` no longer skips successful PRs with `context=` blank.
Author
Member

WARD-DISPATCH: deferred ⏸

deferred details

This forwarded dispatch was deferred after the issue was already reserved.

Attempted harness: codex
Attempted run: ward agent engineer coilyco-flight-deck/ward#994 --harness codex --details Fix ward#994. Director merge is skipping PRs whose Forgejo status history has pending rows followed by success for the same required context. Select the authoritative/latest status per context, print actual failing values, add regression coverage, and close ward#994 when landed.
Container: engineer-codex-ward-994
Container created: no running engineer was observed.
Host log: /Users/kai/.ward/agent-logs/dispatch/20260710T094006Z-director-codex-zv99-coilyco-flight-deck-ward-994.log
Capacity: ward agent engineer --harness codex: global engineer limit is reached: 12 running (limit 12); wait for a run to finish or run ward agent reap for stale engineers

Retry: the issue stays queued and the director will try again when a slot opens.

— Codex, via ward agent

<!-- ward-agent-reservation-released --> <!-- ward-needs-redispatch --> WARD-DISPATCH: deferred ⏸ <details><summary>deferred details</summary> This forwarded dispatch was deferred after the issue was already reserved. Attempted harness: `codex` Attempted run: `ward agent engineer coilyco-flight-deck/ward#994 --harness codex --details Fix ward#994. Director merge is skipping PRs whose Forgejo status history has pending rows followed by success for the same required context. Select the authoritative/latest status per context, print actual failing values, add regression coverage, and close ward#994 when landed.` Container: `engineer-codex-ward-994` Container created: no running engineer was observed. Host log: `/Users/kai/.ward/agent-logs/dispatch/20260710T094006Z-director-codex-zv99-coilyco-flight-deck-ward-994.log` Capacity: `ward agent engineer --harness codex: global engineer limit is reached: 12 running (limit 12); wait for a run to finish or run `ward agent reap` for stale engineers` Retry: the issue stays queued and the director will try again when a slot opens. </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

Additional evidence from agentic-os#423:

  • Head 29d53be09e30298aac1a87ceb9f7d2d1b0653885 has Forgejo status ci / gate (pull_request) = failure, description Failing after 6s.
  • Director dry-run prints has required status context ci / gate (pull_request)= with a blank value instead of failure.

So the fix should cover both sides of the status-reader bug: selecting the authoritative latest success when repeated rows exist, and printing the actual non-passing value when the context exists but fails.

Additional evidence from `agentic-os#423`: * Head `29d53be09e30298aac1a87ceb9f7d2d1b0653885` has Forgejo status `ci / gate (pull_request)` = `failure`, description `Failing after 6s`. * Director dry-run prints `has required status context ci / gate (pull_request)=` with a blank value instead of `failure`. So the fix should cover both sides of the status-reader bug: selecting the authoritative latest success when repeated rows exist, and printing the actual non-passing value when the context exists but fails.
Author
Member

WARD-DISPATCH: deferred ⏸

deferred details

This forwarded dispatch was deferred after the issue was already reserved.

Attempted harness: codex
Attempted run: ward agent engineer coilyco-flight-deck/ward#994 --harness codex --ward-version v0.573.0 --details Fix ward#994. Director merge dry-runs still print required status contexts as blank even when Forgejo status history has status=success/failure and state=null. Teach the status reader to use the populated Forgejo status field, preserve latest status selection, add coverage, and close ward#994 when ward PRs with green test / test and aos ci / gate no longer read blank.
Container: engineer-codex-ward-994
Container created: no running engineer was observed.
Host log: /Users/kai/.ward/agent-logs/dispatch/20260710T100937Z-director-codex-zv99-coilyco-flight-deck-ward-994.log
Capacity: ward agent engineer --harness codex: global engineer limit is reached: 13 running (limit 12); wait for a run to finish or run ward agent reap for stale engineers

Retry: the issue stays queued and the director will try again when a slot opens.

— Codex, via ward agent

<!-- ward-agent-reservation-released --> <!-- ward-needs-redispatch --> WARD-DISPATCH: deferred ⏸ <details><summary>deferred details</summary> This forwarded dispatch was deferred after the issue was already reserved. Attempted harness: `codex` Attempted run: `ward agent engineer coilyco-flight-deck/ward#994 --harness codex --ward-version v0.573.0 --details Fix ward#994. Director merge dry-runs still print required status contexts as blank even when Forgejo status history has status=success/failure and state=null. Teach the status reader to use the populated Forgejo status field, preserve latest status selection, add coverage, and close ward#994 when ward PRs with green test / test and aos ci / gate no longer read blank.` Container: `engineer-codex-ward-994` Container created: no running engineer was observed. Host log: `/Users/kai/.ward/agent-logs/dispatch/20260710T100937Z-director-codex-zv99-coilyco-flight-deck-ward-994.log` Capacity: `ward agent engineer --harness codex: global engineer limit is reached: 13 running (limit 12); wait for a run to finish or run `ward agent reap` for stale engineers` Retry: the issue stays queued and the director will try again when a slot opens. </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-RESERVATION: held 🔒

reservation details

Holder: container engineer-codex-ward-994 on host kais-macbook-pro-2.local.

Reserved by ward agent --harness codex (reserved 2026-07-10T10:28:18Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL). --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/ward#994 · branch issue-994 · harness codex · workflow pull-requests-and-merge
  • Run: engineer-codex-ward-994 · ward v0.573.0 · dispatched 2026-07-10T10:28:18Z
  • Comment thread: 3 included in the pre-flight read, 0 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.573.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> WARD-RESERVATION: held 🔒 <details><summary>reservation details</summary> Holder: container `engineer-codex-ward-994` on host `kais-macbook-pro-2.local`. Reserved by `ward agent --harness codex` (reserved 2026-07-10T10:28:18Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL). `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh**. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/ward#994` · branch `issue-994` · harness `codex` · workflow `pull-requests-and-merge` - **Run:** `engineer-codex-ward-994` · ward `v0.573.0` · dispatched `2026-07-10T10:28:18Z` - **Comment thread:** 3 included in the pre-flight read, 0 stripped (ward's own automated comments). - included: @coilyco-ops (2026-07-10T09:40:08Z), @coilyco-ops (2026-07-10T09:44:50Z), @coilyco-ops (2026-07-10T10:09:39Z) Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.573.0). </details> </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-RESERVATION: held 🔒

reservation details

Holder: container engineer-codex-ward-994 on host kais-macbook-pro-2.local.

Reserved by ward agent --harness codex (reserved 2026-07-10T16:54:57Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL). --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/ward#994 · branch issue-994 · harness codex · workflow pull-requests-and-merge
  • Run: engineer-codex-ward-994 · ward v0.584.0 · dispatched 2026-07-10T16:54:57Z
  • Comment thread: 3 included in the pre-flight read, 1 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.584.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> WARD-RESERVATION: held 🔒 <details><summary>reservation details</summary> Holder: container `engineer-codex-ward-994` on host `kais-macbook-pro-2.local`. Reserved by `ward agent --harness codex` (reserved 2026-07-10T16:54:57Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL). `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh**. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/ward#994` · branch `issue-994` · harness `codex` · workflow `pull-requests-and-merge` - **Run:** `engineer-codex-ward-994` · ward `v0.584.0` · dispatched `2026-07-10T16:54:57Z` - **Comment thread:** 3 included in the pre-flight read, 1 stripped (ward's own automated comments). - included: @coilyco-ops (2026-07-10T09:40:08Z), @coilyco-ops (2026-07-10T09:44:50Z), @coilyco-ops (2026-07-10T10:09:39Z) - stripped: @coilyco-ops (2026-07-10T10:28:19Z) Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.584.0). </details> </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-OUTCOME: merge-ready

details

workflow: pull-requests-and-merge; review summary: skipped by ~/.ward/config.yaml default
retrospective: the fix was mostly a status-history normalization pass, plus a bundle-fixture correction so the live-ref test used a real git checkout
confidence: high
surprise: Forgejo can return status with state null on the same row
follow-ups: none

WARD-OUTCOME: merge-ready <details><summary>details</summary> workflow: pull-requests-and-merge; review summary: skipped by ~/.ward/config.yaml default retrospective: the fix was mostly a status-history normalization pass, plus a bundle-fixture correction so the live-ref test used a real git checkout confidence: high surprise: Forgejo can return `status` with `state` null on the same row follow-ups: none </details>
Author
Member

Additional merge-pass evidence from 2026-07-10 17:53 UTC:

  • ward agent director merge --repo coilyco-flight-deck/ward still merges 0 PRs.
  • Mergeable ward PRs are blocked by blank required status contexts:
    • ward#1063 head fed6795ef3bc9166a15f8cc4fc0d4910651fec3e: test / test (pull_request)=
    • ward#1052 head 35333eba28642131bddb02c2f9c85791755bb32b: test / test (pull_request)=
    • ward#1024 head f201cef4740d27936226b2246589ea3f3329ecbf: test / test (pull_request)=
  • agentic-os and cli-guard director merge passes still show the same blank required-context symptom for otherwise mergeable PRs.

This keeps ward#994 as the current merge-drain bottleneck even though PR #1040 itself is now blocked on base-branch conflicts.

Additional merge-pass evidence from 2026-07-10 17:53 UTC: * `ward agent director merge --repo coilyco-flight-deck/ward` still merges 0 PRs. * Mergeable ward PRs are blocked by blank required status contexts: * `ward#1063` head `fed6795ef3bc9166a15f8cc4fc0d4910651fec3e`: `test / test (pull_request)=` * `ward#1052` head `35333eba28642131bddb02c2f9c85791755bb32b`: `test / test (pull_request)=` * `ward#1024` head `f201cef4740d27936226b2246589ea3f3329ecbf`: `test / test (pull_request)=` * `agentic-os` and `cli-guard` director merge passes still show the same blank required-context symptom for otherwise mergeable PRs. This keeps `ward#994` as the current merge-drain bottleneck even though PR `#1040` itself is now blocked on base-branch conflicts.
Author
Member

Additional merge-pass evidence from 2026-07-10 17:56 UTC:

ward agent director merge --repo coilyco-flight-deck/ward still merges 0 PRs. The status-reader symptom now includes a push-context variant:

ward#1052 head 4e2cd1c7a9530629834ba35debb960a6e50e8f51 has required status context release / release (push)=

That is notable because the PR is branch-mergeable, but the director merge helper is still reading an empty required-context value. This may be the same Forgejo status vs state normalization bug, or it may show that the director is considering a push-only release context when gating a PR. Either way, it is currently blocking merge drain alongside the existing blank test / test (pull_request) and ci / gate (pull_request) cases.

Additional merge-pass evidence from 2026-07-10 17:56 UTC: `ward agent director merge --repo coilyco-flight-deck/ward` still merges 0 PRs. The status-reader symptom now includes a push-context variant: ```text ward#1052 head 4e2cd1c7a9530629834ba35debb960a6e50e8f51 has required status context release / release (push)= ``` That is notable because the PR is branch-mergeable, but the director merge helper is still reading an empty required-context value. This may be the same Forgejo `status` vs `state` normalization bug, or it may show that the director is considering a push-only release context when gating a PR. Either way, it is currently blocking merge drain alongside the existing blank `test / test (pull_request)` and `ci / gate (pull_request)` cases.
Author
Member

WARD-RESERVATION: held 🔒

reservation details

Holder: container engineer-codex-ward-994 on host kais-macbook-pro-2.local.

Reserved by ward agent --harness codex (reserved 2026-07-10T18:02:31Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL). --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/ward#994 · branch issue-994 · harness codex · workflow pull-requests-and-merge
  • Run: engineer-codex-ward-994 · ward v0.584.0 · dispatched 2026-07-10T18:02:31Z
  • Comment thread: 6 included in the pre-flight read, 2 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.584.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> WARD-RESERVATION: held 🔒 <details><summary>reservation details</summary> Holder: container `engineer-codex-ward-994` on host `kais-macbook-pro-2.local`. Reserved by `ward agent --harness codex` (reserved 2026-07-10T18:02:31Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL). `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh**. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/ward#994` · branch `issue-994` · harness `codex` · workflow `pull-requests-and-merge` - **Run:** `engineer-codex-ward-994` · ward `v0.584.0` · dispatched `2026-07-10T18:02:31Z` - **Comment thread:** 6 included in the pre-flight read, 2 stripped (ward's own automated comments). - included: @coilyco-ops (2026-07-10T09:40:08Z), @coilyco-ops (2026-07-10T09:44:50Z), @coilyco-ops (2026-07-10T10:09:39Z), @coilyco-ops (2026-07-10T17:25:40Z), @coilyco-ops (2026-07-10T17:54:08Z), @coilyco-ops (2026-07-10T17:55:47Z) - stripped: @coilyco-ops (2026-07-10T10:28:19Z), @coilyco-ops (2026-07-10T16:54:57Z) Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.584.0). </details> </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-OUTCOME: blocked 🛑

details

workflow: pull-requests-and-merge; review summary: skipped by ~/.ward/config.yaml default
retrospective: the merge update landed cleanly, but Forgejo's go test job on run 1694 failed after 10m2s instead of turning green
confidence: medium
surprise: go vet passed and the failure is isolated to the go test step
follow-ups: inspect the slow/full-suite test path or lift the CI timeout, then rerun PR #1040

WARD-OUTCOME: blocked 🛑 <details><summary>details</summary> workflow: pull-requests-and-merge; review summary: skipped by ~/.ward/config.yaml default retrospective: the merge update landed cleanly, but Forgejo's `go test` job on run 1694 failed after 10m2s instead of turning green confidence: medium surprise: `go vet` passed and the failure is isolated to the `go test` step follow-ups: inspect the slow/full-suite test path or lift the CI timeout, then rerun PR #1040 </details>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#994
No description provided.