Restore director-completion authority in .ward/ forgejo guardfiles: PR merge (director/engineer roles) + commit-status read + action-run status #446
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#446
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?
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 inpull-requestworkflow 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:236exposes onlyview/list prand 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:PR merge (director completion authority). Add
repoMergePullRequest(POST /repos/{owner}/{repo}/pulls/{index}/merge) plus the read helperrepoPullRequestIsMerged. Place it in a newguardfile.forgejo.merge.kdlbound inroles.kdlto thedirectorandengineerroles only (notadvisor, notqa). Gate it{owner}-scoped tocoily*like the other leaves, and align it with the existingward agent director mergecomposite (merge only when the issue thread authorizes it). Do not grant it to the shared read/write tiers, sinceadvisor/qainherit those.Commit combined-status read. Add
repoGetCombinedStatusByRef(GET /repos/{owner}/{repo}/commits/{ref}/status) andrepoListStatusesByReftoguardfile.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.Actions run status. Surface
ListActionRuns/ActionRunas status-bearing verbs (the currentactions runsexec-bridge inguardfile.forgejo.readactions.kdllists runs but the director needs the per-run conclusion to decide what to re-run). Read-only.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/engineertier once #434 lands rather than duplicating it.Acceptance
directorsurface can runward ops forgejo commit ...combined-status andward ops forgejo pr merge ...(owner-scoped, thread-authorized), whileadvisorandqastill cannot merge.pre-commit run --all-filespasses (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, andgenerate-runner-tokenreach (tracked/right-sized separately). This issue is scoped strictly to the forgejo director-completion verbs - merge + status read - and deliberately keepspushof 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.WARD-RESERVATION: held 🔒
reservation details
Holder: container
engineer-claude-agentic-os-446on hostkais-macbook-pro-2.local.Reserved by
ward agent --harness claude(reserved 2026-07-10T18:04:10Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (1h TTL).--forceoverrides.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#446· branchissue-446· harnessclaude· workflowpull-requests-and-mergeengineer-claude-agentic-os-446· wardv0.584.0· dispatched2026-07-10T18:04:10ZStatic container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.584.0).
— Claude (she/her), via
ward agentWARD-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) pluspr is-merged(repoPullRequestIsMerged), coily*-owner-scoped, op-pinned, bound in roles.kdl to director and engineer only, aligned with theward agent director mergecomposite (merge only when the issue thread authorizes it). advisor and qa still cannot merge.commit status(repoGetCombinedStatusByRef) andcommit list-statuses(repoListStatusesByRef) in guardfile.forgejo.read.kdl and the monolith - pure reads, every role.action-run list(ListActionRuns) andaction-run get(ActionRun) beside the exec bridge - pure reads carrying the per-run conclusion.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 describerender resolved every new leaf at the pre-merge commitd808f0f. Caveat: on the merged lock-less tree, ward v0.584.0 doctor fails ops bundle (read spec lock) identically on maind5079cc, 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 agentScope addition (Kai): add PR close/reopen (
repoEditPullRequeststate transitions) to this specgen also-grant alongside merge + status, scoped to thedirector/engineerroles. The foundational home is the ward-native issue; this is the specgen convenience mirror.