Restore director-completion authority in .ward/ forgejo guardfiles: PR merge (director/engineer roles) + commit-status read + action-run status #446

Closed
opened 2026-07-10 17:58:54 +00:00 by coilyco-ops · 3 comments
Member

Request

Restore the director role's completion authority in the coilyco .ward/ forgejo guardfiles. The director exists to coordinate work to completion, and merging PRs in pull-request workflow mode is that job (per Kai: pull-request = director merges, pull-requests-and-merge = engineers self-merge, branch = merge withheld). Today no tier grants merge at all - guardfile.forgejo.kdl:236 exposes only view/list pr and deliberately walls merge off - so a director surface cannot complete the loop it is meant to own. This gap surfaced live during the infrastructure#538 recovery: from the read-only director surface I could see the merge-ready PR wave but could neither read per-PR CI status nor merge, so I had to hand every step back as UI clicks.

This is a permission-surface change (dialect-1 guardfile), so the implementing PR must get Kai's human review before it merges - a merge-authority grant must not ride the automation it is granting. Scope it to exactly the read/idempotent + director-merge set below, nothing wider.

Do

Add these operations to the coilyco .ward/ guardfiles, pinned by operationId the way the existing leaves are:

  1. PR merge (director completion authority). Add repoMergePullRequest (POST /repos/{owner}/{repo}/pulls/{index}/merge) plus the read helper repoPullRequestIsMerged. Place it in a new guardfile.forgejo.merge.kdl bound in roles.kdl to the director and engineer roles only (not advisor, not qa). Gate it {owner}-scoped to coily* like the other leaves, and align it with the existing ward agent director merge composite (merge only when the issue thread authorizes it). Do not grant it to the shared read/write tiers, since advisor/qa inherit those.

  2. Commit combined-status read. Add repoGetCombinedStatusByRef (GET /repos/{owner}/{repo}/commits/{ref}/status) and repoListStatusesByRef to guardfile.forgejo.read.kdl (pure read, safe for every role). This is what lets a director read CI red/green per PR head and produce a confirmed red-list instead of a candidate set.

  3. Actions run status. Surface ListActionRuns / ActionRun as status-bearing verbs (the current actions runs exec-bridge in guardfile.forgejo.readactions.kdl lists runs but the director needs the per-run conclusion to decide what to re-run). Read-only.

  4. Actions rerun is intentionally out of scope here - the pinned swagger has no rerun operationId, so it rides the guarded custom verb tracked in agentic-os#434. Bind that verb into the director/engineer tier once #434 lands rather than duplicating it.

Acceptance

  • A director surface can run ward ops forgejo commit ... combined-status and ward ops forgejo pr merge ... (owner-scoped, thread-authorized), while advisor and qa still cannot merge.
  • The read additions (commit status, action-run status) resolve for every role.
  • The guardfile PR was reviewed and merged by Kai, not self-merged.
  • pre-commit run --all-files passes (check-skills / catalog suite) and the .ward/ bundle still renders (the specverb lock + swagger checks stay green).

Context

Filed at Kai's request during the infrastructure#538 post-reboot recovery, after a permissions rollback that also stripped this surface's kubectl, tailnet, ~/.aws, and generate-runner-token reach (tracked/right-sized separately). This issue is scoped strictly to the forgejo director-completion verbs - merge + status read - and deliberately keeps push of a clone's own tree, org/label mutation, and issue delete on the far side of the wall. Sibling incident-hardening: infrastructure#539, infrastructure#540. Guardfile refs: .ward/roles.kdl, .ward/guardfile.forgejo.kdl (line 236 pr block, line 413 doc-link), .ward/guardfile.forgejo.read.kdl, .ward/guardfile.forgejo.readactions.kdl.

## Request Restore the **director role's completion authority** in the coilyco `.ward/` forgejo guardfiles. The director exists to coordinate work to completion, and merging PRs in `pull-request` workflow mode is that job (per Kai: `pull-request` = director merges, `pull-requests-and-merge` = engineers self-merge, `branch` = merge withheld). Today no tier grants merge at all - `guardfile.forgejo.kdl:236` exposes only `view/list pr` and deliberately walls merge off - so a director surface cannot complete the loop it is meant to own. This gap surfaced live during the infrastructure#538 recovery: from the read-only director surface I could see the merge-ready PR wave but could neither read per-PR CI status nor merge, so I had to hand every step back as UI clicks. This is a **permission-surface change (dialect-1 guardfile), so the implementing PR must get Kai's human review before it merges** - a merge-authority grant must not ride the automation it is granting. Scope it to exactly the read/idempotent + director-merge set below, nothing wider. ## Do Add these operations to the coilyco `.ward/` guardfiles, pinned by operationId the way the existing leaves are: 1. **PR merge (director completion authority).** Add `repoMergePullRequest` (`POST /repos/{owner}/{repo}/pulls/{index}/merge`) plus the read helper `repoPullRequestIsMerged`. Place it in a new `guardfile.forgejo.merge.kdl` bound in `roles.kdl` to the `director` and `engineer` roles only (not `advisor`, not `qa`). Gate it `{owner}`-scoped to `coily*` like the other leaves, and align it with the existing `ward agent director merge` composite (merge only when the issue thread authorizes it). Do **not** grant it to the shared read/write tiers, since `advisor`/`qa` inherit those. 2. **Commit combined-status read.** Add `repoGetCombinedStatusByRef` (`GET /repos/{owner}/{repo}/commits/{ref}/status`) and `repoListStatusesByRef` to `guardfile.forgejo.read.kdl` (pure read, safe for every role). This is what lets a director read CI red/green per PR head and produce a confirmed red-list instead of a candidate set. 3. **Actions run status.** Surface `ListActionRuns` / `ActionRun` as status-bearing verbs (the current `actions runs` exec-bridge in `guardfile.forgejo.readactions.kdl` lists runs but the director needs the per-run conclusion to decide what to re-run). Read-only. 4. **Actions rerun** is intentionally **out of scope here** - the pinned swagger has no rerun operationId, so it rides the guarded custom verb tracked in agentic-os#434. Bind that verb into the `director`/`engineer` tier once #434 lands rather than duplicating it. ## Acceptance - A `director` surface can run `ward ops forgejo commit ...` combined-status and `ward ops forgejo pr merge ...` (owner-scoped, thread-authorized), while `advisor` and `qa` still cannot merge. - The read additions (commit status, action-run status) resolve for every role. - The guardfile PR was reviewed and merged by Kai, not self-merged. - `pre-commit run --all-files` passes (check-skills / catalog suite) and the `.ward/` bundle still renders (the specverb lock + swagger checks stay green). ## Context Filed at Kai's request during the infrastructure#538 post-reboot recovery, after a permissions rollback that also stripped this surface's `kubectl`, tailnet, `~/.aws`, and `generate-runner-token` reach (tracked/right-sized separately). This issue is scoped strictly to the forgejo **director-completion** verbs - merge + status read - and deliberately keeps `push` of a clone's own tree, org/label mutation, and issue delete on the far side of the wall. Sibling incident-hardening: infrastructure#539, infrastructure#540. Guardfile refs: `.ward/roles.kdl`, `.ward/guardfile.forgejo.kdl` (line 236 pr block, line 413 doc-link), `.ward/guardfile.forgejo.read.kdl`, `.ward/guardfile.forgejo.readactions.kdl`.
Author
Member

WARD-RESERVATION: held 🔒

reservation details

Holder: container engineer-claude-agentic-os-446 on host kais-macbook-pro-2.local.

Reserved by ward agent --harness claude (reserved 2026-07-10T18:04:10Z). 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/agentic-os#446 · branch issue-446 · harness claude · workflow pull-requests-and-merge
  • Run: engineer-claude-agentic-os-446 · ward v0.584.0 · dispatched 2026-07-10T18:04:10Z
  • Comment thread: 0 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.584.0).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> WARD-RESERVATION: held 🔒 <details><summary>reservation details</summary> Holder: container `engineer-claude-agentic-os-446` on host `kais-macbook-pro-2.local`. Reserved by `ward agent --harness claude` (reserved 2026-07-10T18:04:10Z). 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/agentic-os#446` · branch `issue-446` · harness `claude` · workflow `pull-requests-and-merge` - **Run:** `engineer-claude-agentic-os-446` · ward `v0.584.0` · dispatched `2026-07-10T18:04:10Z` - **Comment thread:** 0 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.584.0). </details> </details> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

WARD-OUTCOME: merge-ready

details

workflow: pull-requests-and-merge; review summary: skipped (review gate skipped by ~/.ward/config.yaml default)

The in-container review gate was intentionally skipped by the ~/.ward/config.yaml default, so this run carries no in-container review verdict. PR #449 (#449) awaits Kai's human review and merge, required here because a dialect-1 merge-authority grant must not ride the automation it grants. CI is green on the PR head (ci / gate success on f4d2c27). The engineer does not self-merge this PR.

What landed:

  • guardfile.forgejo.merge.kdl - pr merge (repoMergePullRequest) plus pr is-merged (repoPullRequestIsMerged), coily*-owner-scoped, op-pinned, bound in roles.kdl to director and engineer only, aligned with the ward agent director merge composite (merge only when the issue thread authorizes it). advisor and qa still cannot merge.
  • commit status (repoGetCombinedStatusByRef) and commit list-statuses (repoListStatusesByRef) in guardfile.forgejo.read.kdl and the monolith - pure reads, every role.
  • action-run list (ListActionRuns) and action-run get (ActionRun) beside the exec bridge - pure reads carrying the per-run conclusion.
  • Actions rerun stays deferred to agentic-os#434 as scoped.
  • Follow-through: regenerated docs/ward-ops-forgejo-reference.md, added the new guardfile to the release tar list, the ward-specs-bundle validator, and the bundle tests, and merged main (aos#437) with the docs/ward-specs.md conflict resolved.

Retrospective: the guardfile work felt mechanical against clean sibling leaves. The two real forks: the merge overlay's singletons (the agent chose standalone coilyco values like the readactions overlay, per the issue's coily* instruction, instead of inheriting the example-valued read tier), and main moving mid-run with aos#437's swagger-lock removal, which forced conflict resolution plus packaging follow-through so the new guardfile actually ships. One just-landed upstream test asserted a render literal (page=1) the v0.584.0 renderer no longer emits, so the agent retargeted it at the still-true guardfile anchor plus the new verbs.

Confidence: high on the guardfile surface. ward doctor was all-PASS and the full ward ops forgejo describe render resolved every new leaf at the pre-merge commit d808f0f. Caveat: on the merged lock-less tree, ward v0.584.0 doctor fails ops bundle (read spec lock) identically on main d5079cc, a pre-existing aos#437/ward-version skew this PR neither causes nor can fix from here.

Surprises: host disk repeatedly hit 100% mid-run (config-bundle cache TTL churn plus consumers outside the container), which made bundle-render validation a scavenging exercise.

Follow-ups: bind the rerun custom verb into the director/engineer tier once agentic-os#434 lands, and bump the ward pin once the no-lock spec fetch ships so doctor goes green on lock-less bundles.

— Claude (she/her), via ward agent

WARD-OUTCOME: merge-ready <details><summary>details</summary> workflow: pull-requests-and-merge; review summary: skipped (review gate skipped by ~/.ward/config.yaml default) The in-container review gate was intentionally skipped by the ~/.ward/config.yaml default, so this run carries no in-container review verdict. PR #449 (https://forgejo.coilysiren.me/coilyco-flight-deck/agentic-os/pulls/449) awaits Kai's human review and merge, required here because a dialect-1 merge-authority grant must not ride the automation it grants. CI is green on the PR head (ci / gate success on f4d2c27). The engineer does not self-merge this PR. What landed: * `guardfile.forgejo.merge.kdl` - `pr merge` (repoMergePullRequest) plus `pr is-merged` (repoPullRequestIsMerged), coily*-owner-scoped, op-pinned, bound in roles.kdl to director and engineer only, aligned with the `ward agent director merge` composite (merge only when the issue thread authorizes it). advisor and qa still cannot merge. * `commit status` (repoGetCombinedStatusByRef) and `commit list-statuses` (repoListStatusesByRef) in guardfile.forgejo.read.kdl and the monolith - pure reads, every role. * `action-run list` (ListActionRuns) and `action-run get` (ActionRun) beside the exec bridge - pure reads carrying the per-run conclusion. * Actions rerun stays deferred to agentic-os#434 as scoped. * Follow-through: regenerated docs/ward-ops-forgejo-reference.md, added the new guardfile to the release tar list, the ward-specs-bundle validator, and the bundle tests, and merged main (aos#437) with the docs/ward-specs.md conflict resolved. Retrospective: the guardfile work felt mechanical against clean sibling leaves. The two real forks: the merge overlay's singletons (the agent chose standalone coilyco values like the readactions overlay, per the issue's coily* instruction, instead of inheriting the example-valued read tier), and main moving mid-run with aos#437's swagger-lock removal, which forced conflict resolution plus packaging follow-through so the new guardfile actually ships. One just-landed upstream test asserted a render literal (page=1) the v0.584.0 renderer no longer emits, so the agent retargeted it at the still-true guardfile anchor plus the new verbs. Confidence: high on the guardfile surface. ward doctor was all-PASS and the full `ward ops forgejo describe` render resolved every new leaf at the pre-merge commit d808f0f. Caveat: on the merged lock-less tree, ward v0.584.0 doctor fails ops bundle (read spec lock) identically on main d5079cc, a pre-existing aos#437/ward-version skew this PR neither causes nor can fix from here. Surprises: host disk repeatedly hit 100% mid-run (config-bundle cache TTL churn plus consumers outside the container), which made bundle-render validation a scavenging exercise. Follow-ups: bind the rerun custom verb into the director/engineer tier once agentic-os#434 lands, and bump the ward pin once the no-lock spec fetch ships so doctor goes green on lock-less bundles. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent` </details>
Author
Member

Scope addition (Kai): add PR close/reopen (repoEditPullRequest state transitions) to this specgen also-grant alongside merge + status, scoped to the director/engineer roles. The foundational home is the ward-native issue; this is the specgen convenience mirror.

Scope addition (Kai): add **PR close/reopen** (`repoEditPullRequest` state transitions) to this specgen also-grant alongside merge + status, scoped to the `director`/`engineer` roles. The foundational home is the ward-native issue; this is the specgen convenience mirror.
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/agentic-os#446
No description provided.