Add the full PR lifecycle (close, reopen, update, edit) to the forgejo KDL spec #488
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/agentic-os#488
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
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?
Problem
A stranded-PR sweep across all 66 repos (3 coilyco orgs plus the
coilysirenpersonal namespace) found 6 open PRs, and none of them can be resolved through ward. The PR surface exposes onlyviewandlist(specgen) plusstatus/merge/runs/rerun(nativeward agent pr). There is no way to close a PR, so a stranded or empty PR can only be cleaned up by hand in the web UI.Five of the six are empty leftovers on
coilyco-bridge/agentic-os-kai(#721, #722, #723, #725, #728). Their head branches are already ancestors ofmain(verified withgit merge-base --is-ancestor), so the work landed and the issues are correctly closed, but the PRs stayed open showing a 0-file diff. The sixth,coilyco-flight-deck/ward#987, was superseded bymainand also needs closing. Every one of these wants exactly one verb that does not exist.Ask
Add the missing PR lifecycle actions to the KDL spec so the PR surface is complete, keeping the existing merge-gate policy intact.
Surface at least:
closepr -repoEditPullRequest(PATCH/repos/{owner}/{repo}/pulls/{index},state=closed). The verb this sweep actually needed.reopenpr - same op,state=open. The inverse, so a wrong close is reversible.editpr - same op, for title and body.updatepr -repoUpdatePullRequest(POST/repos/{owner}/{repo}/pulls/{index}/update), to pullmaininto a stale PR branch.ward#987stranded partly because nothing could refresh a branch 180 commits behind.createpr -repoCreatePullRequest, if it fits the tier.repoGetPullRequestFilesandrepoGetPullRequestCommits. The sweep had to clone each repo to learn a PR was empty, becauseadditions/changed_filesalone did not distinguish "no work" from "already merged".Please survey the pulls section of the Forgejo swagger and add the coherent lifecycle set, not only
close.Where
Authored in this repo, per the aos#332 carved exception.
.ward/guardfile.forgejo.merge.kdlis the natural home for the mutating verbs: it already lives outside the read/write/admin tier chain and binds to the director and engineer roles only, which is the right blast radius for closing a PR. Rename or re-describe that overlay if "merge" no longer fits what it grants.Two traps that will bite
The pinned swagger lock is pruned.
.ward/forgejo.swagger.lock.jsoncarries 35 paths and contains onlyrepoListPullRequestsandrepoGetPullRequest. It does not containrepoMergePullRequest,repoPullRequestIsMerged, or any pulls write op, even thoughguardfile.forgejo.merge.kdlgrants the first two. Adding a leaf almost certainly means refreshing the lock so the new operationIds resolve. Work out how that lock is regenerated rather than hand-editing it.The read tier and the monolith disagree about pr today.
guardfile.forgejo.read.kdlhas explicitnever view pr/never list prdenials ("pull requests are not exposed through ward; read them in the web UI") and comments that the denials inherit up so no tier exposes a pr verb. Butguardfile.forgejo.kdl(the monolith) grantscan view pr/can list pr, and on a live director surfaceward ops forgejo pr listandpr viewboth work. So the deny is either dead or being bypassed. Reconcile the two, and make sure the new mutating leaves are not silently dropped by an inheritednever.Done condition
A director surface can run
ward ops forgejo pr close coilyco-bridge agentic-os-kai 721and have it work, the merge gate is unchanged,ward exec surface-checkstill passes, anddocs/ward-ops-forgejo-reference.mdis regenerated so the new verb names are greppable off-disk.Follow-up cleanup of the 6 stranded PRs is blocked on this and will be dispatched once the verb lands.
WARD-RESERVATION: held 🔒
reservation details
Holder: container
engineer-claude-agentic-os-488on hostKAI-DESKTOP-TOWER.Reserved by
ward agent --harness claude(reserved 2026-07-13T03:26:13Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (3h TTL).--override-reservationoverrides.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)
coilyco-flight-deck/agentic-os#488· branchissue-488· harnessclaude· workflowpull-request-and-mergeengineer-claude-agentic-os-488· wardv0.633.0· dispatched2026-07-13T03:26:13ZStatic container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.633.0).
— Claude (she/her), via
ward agentWARD-OUTCOME: submitted
details
workflow: pull-request-and-merge; review summary: skipped - the in-container review gate was intentionally skipped per the temporary ward default pending brokered QA
closes #488andward.workflow: pull-request-and-merge,ci / gategreen on headdda8f08, branch merge-ready for the director gate.ward.bundle.kdlactually mounts forward ops forgejo, so the done-condition command exists), granted the pr read side in the read tier in place of the deadneverpair (trap 2), and re-described the merge overlay as the PR-lifecycle overlay carrying the mutating verbs (the issue's Where). Merge itself is untouched everywhere.kdl-specs lock --guardfiledriver at v0.94.0 (the committed lock's own provenance), not hand-edited. Diff is a strict superset: 5 new operationIds plus 3 transitive definitions,specverb.lockbyte-identical. One wrinkle: the driver only discovers*.guardfile.kdlnames, so the regen ran in a scratch dir with the monolith copied under a glob-matching name - the lock filename derives from thespecnode, so the output is identical.ward doctor(ops bundle mounts fail-closed) passes against the edited bundle,ward ops forgejo pr close coilyco-bridge agentic-os-kai 721 --dry-runresolves to PATCH.../pulls/721with{"state": "closed"},ward exec surface-checkpasses, 459 tests green, pre-commit clean.ward ops forgejomounts only the monolith (roles.kdl overlay mounting is ward#1072), which is why the mutating verbs had to land in the monolith and not only in the merge overlay the issue suggested.actions rerunexec-bridge sections the v0.584.0 render had (same-path exec overlays skip fail-closed). Verified pre-existing binary behavior, not this change - noted on the PR, tracked by ward#950 / agentic-os#434.