fix(agent): read the scoped autonomy labels, restoring the live-collab guard #1667

Merged
coilyco-ops merged 1 commit from aos/claude/bk79-autonomy-label-scope into main 2026-08-16 04:59:13 +00:00
Owner

Refs coilyco-flight-deck/umbra#292, which is filed on umbra but the gate is here.

The risk is the opposite of what the report says

The report predicts everything fails closed and nothing dispatches. Reading the tree, that is not what happens:

  • issueModeCeiling has no production callers. Only a test calls it. The fail-closed ceiling is dead code, so no queue goes quiet.
  • The one live check fails open. agent.go:1102 and :1164 refuse an engineer dispatch when the issue carries interactive. After the rename that never matches, so an issue marked as needing a human present dispatched to an autonomous engineer with no refusal.

A guard that quietly stopped guarding, rather than a queue that quietly emptied. umbra#292 itself carries autonomy/live-collab, so it was in exactly that state.

The fix

autonomyName reduces a label to its ceiling name:

autonomy/async-consult -> consult
autonomy/live-collab   -> interactive
autonomy/headless      -> headless

A prefix strip alone is not enough - live-collab and async-consult are new words, not rescoped old ones - so an alias map carries them. Bare old names still resolve, so nothing that worked stops.

Tests

Three, and they fail without the fix with the defect stated in the message:

agent_ceiling_test.go:122: "autonomy/live-collab" no longer refuses an engineer dispatch

The third pins that priority/*, role/* and autonomy/epic are not autonomy ceilings, so the scope prefix cannot swallow a neighbouring axis.

Deliberately not decided

  • Whether live-collab should gate differently from the interactive it replaced. The report is right that they are not synonyms. This restores the pre-rename behaviour exactly rather than folding a semantic change into a string fix.
  • What autonomy/epic should mean at the gate. It resolves to no ceiling, which is the status quo, not an answer.

Both are decisions on umbra#292.

Verification

go build ./... and go vet ./cmd/... clean; the ceiling and dispatch tests pass.

go test ./cmd/ward/ does not finish - it hangs and is killed at a 400s timeout. That is pre-existing: I ran the identical command on a clean tree and it fails the same way, same duration, with a goroutine dump through lumberjack and os/exec. Not caused by this change, and worth its own issue - a package suite that cannot complete locally means the commit gate is effectively unrunnable here.

Refs `coilyco-flight-deck/umbra#292`, which is filed on umbra but the gate is here. ## The risk is the opposite of what the report says The report predicts everything fails closed and nothing dispatches. Reading the tree, that is not what happens: * **`issueModeCeiling` has no production callers.** Only a test calls it. The fail-closed ceiling is dead code, so no queue goes quiet. * **The one live check fails open.** `agent.go:1102` and `:1164` refuse an engineer dispatch when the issue carries `interactive`. After the rename that never matches, so **an issue marked as needing a human present dispatched to an autonomous engineer with no refusal.** A guard that quietly stopped guarding, rather than a queue that quietly emptied. umbra#292 itself carries `autonomy/live-collab`, so it was in exactly that state. ## The fix `autonomyName` reduces a label to its ceiling name: ``` autonomy/async-consult -> consult autonomy/live-collab -> interactive autonomy/headless -> headless ``` A prefix strip alone is not enough - `live-collab` and `async-consult` are new words, not rescoped old ones - so an alias map carries them. Bare old names still resolve, so nothing that worked stops. ## Tests Three, and they fail without the fix with the defect stated in the message: ``` agent_ceiling_test.go:122: "autonomy/live-collab" no longer refuses an engineer dispatch ``` The third pins that `priority/*`, `role/*` and `autonomy/epic` are **not** autonomy ceilings, so the scope prefix cannot swallow a neighbouring axis. ## Deliberately not decided * Whether `live-collab` should gate **differently** from the `interactive` it replaced. The report is right that they are not synonyms. This restores the pre-rename behaviour exactly rather than folding a semantic change into a string fix. * What `autonomy/epic` should mean at the gate. It resolves to no ceiling, which is the status quo, not an answer. Both are decisions on umbra#292. ## Verification `go build ./...` and `go vet ./cmd/...` clean; the ceiling and dispatch tests pass. **`go test ./cmd/ward/` does not finish** - it hangs and is killed at a 400s timeout. That is **pre-existing**: I ran the identical command on a clean tree and it fails the same way, same duration, with a goroutine dump through `lumberjack` and `os/exec`. Not caused by this change, and worth its own issue - a package suite that cannot complete locally means the commit gate is effectively unrunnable here.
fix(agent): read the scoped autonomy labels, restoring the live-collab guard
All checks were successful
test / test (pull_request) Successful in 48s
d4472d8265
The autonomy labels moved to a scoped, renamed taxonomy on 2026-08-15 and
this gate still compared the literal old names, so autonomy/live-collab
matched nothing.

The consequence is the opposite of a queue going quiet. issueModeCeiling,
the fail-closed ceiling, has no production callers and is dead code. The
one autonomy label the dispatch path actually consults is the interactive
check at agent.go:1102 and :1164, and it refuses on a match, so after the
rename it stopped refusing: an issue marked as needing a human present
dispatched to an autonomous engineer unguarded.

autonomyName reduces a label to its ceiling name, tolerating the scope
prefix and the renamed members. live-collab and async-consult are new
words rather than rescoped ones, so a prefix strip alone is not enough
and an alias map carries them. Bare old names still resolve.

Deliberately unchanged: whether live-collab should gate differently from
the interactive it replaced, and what autonomy/epic should mean. Both are
decisions on umbra#292 rather than mine, so this restores the pre-rename
behaviour exactly and decides neither.

priority/* and role/* stay outside the autonomy axis, pinned by a test,
so the scope prefix cannot swallow another group.

Refs coilyco-flight-deck/umbra#292

Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Commenting is not possible because the repository is archived.
No reviewers
No milestone
No project
No assignees
1 participant
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!1667
No description provided.