feat(ops): route issue-label add/set/remove through the broker (consumes cli-guard#193) #618

Closed
opened 2026-07-06 16:48:36 +00:00 by coilysiren · 2 comments
Owner

Papercut

From a ward director read-only surface, ward ops forgejo issue-label add is refused - "the broker serves the write tier only (create / edit / comment / close / reopen issue); issue-label add is out of tier" - because the broker write-tier classifier carries no label op. The ward-kdl write guardfile already grants can add/set/remove issue-label; the only gap is the broker route. A director then cannot relabel a freshly-filed issue headless and has to fall back to --force on dispatch.

Blocked on

  • cli-guard#193 broker op - the credential broker must first learn a label_issue op (pkg/broker) and ship a Forgejo release tag. Start this run by bumping go.mod's forgejo.coilysiren.me/coilyco-flight-deck/cli-guard pin to that tag, then ward exec tidy.

Scope (cmd/ward/broker_client.go)

  1. mapForgejoWriteOp - map the issue-label resource verbs to the new broker op: add / set / remove -> OpLabelIssue (with the mode discriminator the broker defines). Today the function early-returns ok=false for any resource != "issue", so it needs an issue-label arm alongside the issue one.
  2. runForgejoWriteViaBroker - extract the --labels values from the leaf argv and populate the broker Request.Labels (and mode). The label leaves take <owner> <repo> <index> like edit/comment, so the existing needNumber path applies.
  3. Confirm verbTail classifies ward.ops.forgejo.issue-label.add to (issue-label, add) correctly (two-segment tail), and that forgejoReadVerbs still routes issue-label list direct as a read.

Acceptance

  • From a director surface, ward ops forgejo issue-label add <owner> <repo> <index> --labels headless succeeds through the broker (no --force), and the label lands.
  • The director capture-and-dispatch path can then relabel a filed issue headless before warded engineer instead of forcing.
  • ward exec test + ward exec vet green, pre-commit run --all-files clean.
  • docs/broker.md updated for the new brokered op; docs/FEATURES.md if the surface note warrants it.
## Papercut From a ward director read-only surface, `ward ops forgejo issue-label add` is refused - "the broker serves the write tier only (create / edit / comment / close / reopen issue); issue-label add is out of tier" - because the broker write-tier classifier carries no label op. The ward-kdl write guardfile **already grants** `can add/set/remove issue-label`; the only gap is the broker route. A director then cannot relabel a freshly-filed issue `headless` and has to fall back to `--force` on dispatch. ## Blocked on - **cli-guard#193 broker op** - the credential broker must first learn a `label_issue` op (`pkg/broker`) and ship a Forgejo release tag. Start this run by bumping `go.mod`'s `forgejo.coilysiren.me/coilyco-flight-deck/cli-guard` pin to that tag, then `ward exec tidy`. ## Scope (`cmd/ward/broker_client.go`) 1. **`mapForgejoWriteOp`** - map the `issue-label` resource verbs to the new broker op: `add` / `set` / `remove` -> `OpLabelIssue` (with the mode discriminator the broker defines). Today the function early-returns `ok=false` for any `resource != "issue"`, so it needs an `issue-label` arm alongside the `issue` one. 2. **`runForgejoWriteViaBroker`** - extract the `--labels` values from the leaf argv and populate the broker `Request.Labels` (and mode). The label leaves take `<owner> <repo> <index>` like edit/comment, so the existing `needNumber` path applies. 3. Confirm `verbTail` classifies `ward.ops.forgejo.issue-label.add` to (`issue-label`, `add`) correctly (two-segment tail), and that `forgejoReadVerbs` still routes `issue-label list` direct as a read. ## Acceptance - From a director surface, `ward ops forgejo issue-label add <owner> <repo> <index> --labels headless` succeeds through the broker (no `--force`), and the label lands. - The director capture-and-dispatch path can then relabel a filed issue `headless` before `warded engineer` instead of forcing. - `ward exec test` + `ward exec vet` green, `pre-commit run --all-files` clean. - `docs/broker.md` updated for the new brokered op; `docs/FEATURES.md` if the surface note warrants it.
Author
Owner

Issue comment needing to route through the broker is mega overkill

Issue comment needing to route through the broker is mega overkill
Author
Owner

Reframe + forward link: filed #625 to complete this. Since this was closed, cli-guard v0.74.0 (cli-guard#193, commit b8e3e63) shipped the broker op end to end - OpLabelIssue, add/set/remove modes, fail-closed labelInvariants authz, client.LabelIssue, the Executor interface method, and the server dispatch arm. ward still pins cli-guard v0.73.0, one release behind, so the broker op is built and sitting unused. #625 is the ward-only catch-up (pin bump + executor.LabelIssue + client mapForgejoWriteOp arm), which is why it is no longer the broker overkill this issue was closed for - the broker half already exists.

Reframe + forward link: filed #625 to complete this. Since this was closed, cli-guard **v0.74.0** (cli-guard#193, commit b8e3e63) shipped the broker op end to end - OpLabelIssue, add/set/remove modes, fail-closed labelInvariants authz, client.LabelIssue, the Executor interface method, and the server dispatch arm. ward still pins cli-guard v0.73.0, one release behind, so the broker op is built and sitting unused. #625 is the ward-only catch-up (pin bump + executor.LabelIssue + client mapForgejoWriteOp arm), which is why it is no longer the broker overkill this issue was closed for - the broker half already exists.
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#618
No description provided.