Make the label taxonomy declarative, then rename role/* onto the current roster #342
Labels
No labels
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/devrel
role/eval
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/sysadmin
role/tpm
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/agent-compose#342
Loading…
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?
Outcome
The
role/*label axis names the roster Core Roster v2 replaced. Fix it, and fix the arrangement that let it drift silently.Body rewritten after the decisions landed. The investigation and the original framing are in the comments, which are worth reading for the evidence rather than just the plan.
Root cause
infrastructure/scripts/forgejo-label-taxonomy-sync.pynames the authority in its docstring: "coilyco-gaming is the source of truth. Run after changing labels there." The authoritative taxonomy is live Forgejo org state, with no committed file declaring it. A label change is an API call with no diff, no review, and no commit.agentic-os/.agents/composed/tooling-issue-prioritization/references/label-taxonomy.mddescribes the taxonomy without defining it, which is how it sits listing ninerole/*values while the roster moved to seven different ones and nothing noticed.This is the same failure #329 is fixing in agent-compose: configuration living inside a running system rather than in reviewable data. The drift is what the arrangement produces, not an oversight.
What makes this cheap
role/*strings. Across every checkout on this host, outside the prioritization skill docs, zero matches. No dispatch gate, no test, no script. Thelabel-taxonomy.mdwarning that renaming is a breaking change is accurate forautonomy/*andpriority/*and does not apply here.The mapping
Counts via
issues/search, approximate given known indexer lag.role/engineer414 torole/platform. Clean rename.role/ops194 torole/sysadmin. Clean rename.role/ai76 torole/eval. Clean rename.role/director53 torole/tpm. Clean rename.role/creator22 torole/devrel. Clean rename.role/design11 torole/frontend. Clean rename.role/exec4. Collides withdirectorontpm. Migrate its 4 issues ontorole/tpm, then delete.role/qa16. Retired. Redistribute its issues, then delete.role/gamedev. New seat, no predecessor. Pure create.role/human4. Unchanged. Never a seat, and stays the value meaning a person and specifically not an agent seat.Decisions
role/qais retired, its 16 issues redistributed, and the label deleted. See the open question below.role/directorbecomesrole/tpm, carrying its 53 issues.role/exec's 4 move ontorole/tpmby hand, thenrole/execis deleted.coilyco-gaming,coilyco-bridge,coilyco-flight-deck.coilysirenrepo-level labels andcoilysiren/inboxare out of scope and tracked separately.Sequence
role/gamedev.role/exec's 4 issues ontorole/tpm, then deleterole/exec.role/qa's 16 issues, then deleterole/qa.label-taxonomy.mdand thetooling-issue-prioritizationskill so the described taxonomy matches the defined one.Steps 2 through 4 are irreversible in the delete cases and need an org owner token. Per the sync script's docstring the
coilyco-opsbot is a member rather than an owner and answers 403, so Kai runs these.Open, needs a rule before step 4
Where do
role/qa's 16 issues go? Core Roster v2 has no QA seat, so each needs a destination. Proposal: read them and assign by content, with agent-behavior measurement going torole/evaland everything else defaulting torole/platform. Confirm before deleting, since the delete cannot be undone.Acceptance criteria
role/*label across all three orgs.role/execandrole/qaissues are rehomed before their labels are deleted.label-taxonomy.mdand the prioritization skill describe the current set.Boundaries
autonomy/*orpriority/*in this work. Those are matched by string in a test, two AGENTS files, a worklog, and two migration scripts, and the silent-failure warning applies to them.coilysiren/inboxuses an unprefixed taxonomy and is not converted here.Investigation: where the canon lives, what breaks, and what it costs
Read on 2026-08-25. Three findings change the plan in the body, one of them substantially.
1. The canon has no tracked home, and that is the root cause
coilyco-flight-deck/infrastructure/scripts/forgejo-label-taxonomy-sync.pyis the rollout, and its docstring names the authority: "coilyco-gaming is the source of truth. Run after changing labels there, so the three orgs keep one vocabulary."The authoritative taxonomy is live Forgejo org state. There is no committed file declaring it. A label change is an API call or a UI click with no diff, no review, and no commit.
references/label-taxonomy.mdin agentic-os describes the taxonomy but does not define it, which is why it can sit there listing ninerole/*values while the roster it mirrors moved to seven different ones and nothing noticed.This is the same disease #329 is curing in agent-compose: configuration living inside a running system instead of in reviewable data, with the tool that reads it treated as the authority. The label drift is not an oversight, it is what this arrangement produces.
2. Renaming
role/*is not the breaking change the docs warn aboutlabel-taxonomy.mdsays "Renaming these labels is a breaking change" and warns of silent failure. That warning is accurate forautonomy/*andpriority/*, and substantially overstated forrole/*.Grepped across every checkout on this host. Outside the
tooling-issue-prioritizationskill docs,role/*values are matched in zero places. No dispatch gate, no test, no script.For contrast,
autonomy/*is matched inagentic-os/tests/test_blocked_on_dependency_contract.py:45, insirens-echo/AGENTS.md, in its worklog, in the sync script'sRENAMEmap, and inagentic-os-kai/scripts/backfill-personal-labels.sh.So the axis that needs renaming is the one axis that is safe to rename.
3. In-place edit means a rename carries its issues automatically
From the sync script: "Existing labels are EDITED in place rather than deleted and recreated, so every issue keeps the label it already carries through the rename. Only genuinely new labels are created, and nothing is deleted - a delete would strip the label from every issue holding it, which is the one irreversible move here."
This supersedes step 3 in the body, which called for relabeling issues across the org. For any 1:1 rename, no issue is touched at all.
Counts, and where the mapping is not 1:1
Per-label totals via
issues/search, so approximate rather than exact given known indexer lag.role/engineer414, toplatform. Clean rename.role/ops194, tosysadmin. Clean rename.role/ai76, toeval. Clean rename.role/director53, totpm. Clean rename, but collides withexec.role/creator22, todevrel. Clean rename.role/qa16, no successor seat. Decision needed.role/design11, tofrontend. Clean rename.role/exec4, also totpm. Collision withdirector.role/human4, unchanged. Not a seat by design.gamedev, new seat with no predecessor. Pure create.Roughly 794 labeled issues total. Five clean renames carry 717 of them with zero per-issue work. The hand-migration is about twenty issues: move
exec's 4 ontotpm, and decideqa's 16.role/qamay not be an orphanThe body called
qaa value with no successor. #273 is open and titled "role-qa: evaluate bounded reconfiguration authority for the QA seat", which suggests QA is a seat under active consideration rather than a retired one. Settle #273's direction before retiringrole/qa, because deleting a label is the one irreversible move in this whole operation.Operational constraint
The sync script requires an org owner token. Per its docstring the
coilyco-opsbot is a member rather than an owner on all three orgs and answers 403, so this needs Kai's credentials. That makes the rollout HITL by mechanism, not merely by policy.Namespaces the sync script does not cover
coilysiren/coilysirencarries repo-level labels with the same taxonomy, ids 339 through 414. The sync script's targets are onlycoilyco-bridgeandcoilyco-flight-deck.agentic-os-kai/scripts/backfill-personal-labels.shappears to be the separate path for these.coilysiren/inboxuses an entirely different scheme. Perdeploy/services/forgejo-mcp/docs/tool-surface.md:29, it "uses an unprefixed taxonomy that a prefixed rule would lock out entirely."coilysiren/inboxandcoilysiren/loreare private and could not be enumerated unauthenticated, so their label state is unverified here.The org role labels encode the retired roster, so new work cannot be role-labeledto Make the label taxonomy declarative, then rename role/* onto the current rosterStep 1 authored, in review
coilyco-flight-deck/infrastructure#932. Changes nothing in Forgejo.
config/forgejo-label-taxonomy.yamldeclares the taxonomy, the sync script drives it, and four justfile verbs exist where there were none. The committed file is a faithful snapshot of current state.Verified, both directions
just forgejo-label-taxonomy-checkreports all three orgs converged and exits 0. A probe taxonomy carrying a rename, a colour change, and a new label plans all three correctly on every org and exits 1, so "converged" is a real reading rather than a vacuous one. 17 planner tests with no live calls. Full pre-commit suite green.A finding that explains the drift
The rollout script had been unrunnable. It called
json.loadsonaosguardoutput without--output json, and aosguard emits YAML, so it raised on its first read. There was no test and no justfile verb, so nothing caught it.That reframes the root cause in the body. The taxonomy did not drift only because the authority was live org state. It drifted because the one tool that could have corrected it was broken, and nothing anywhere would have said so.
Acceptance criteria this covers, pending merge
What step 2 now looks like
A diff to the new file. Add the pairs to
renames:, change the entries underlabels:, dry-run, apply. From the probe:Because a rename is an edit in place,
role/engineer's 414 issues move with the label and cost nothing.Where it stops
The merge is director-gated per infrastructure's own AGENTS.md, so I stopped at the pull request rather than merging. Steps 2 through 4 need an org owner token regardless, since
coilyco-opsis a member rather than an owner and gets 403 on org label writes.Step 4 prepared: where
role/qa's 16 issues goRule approved by Kai: agent-behavior measurement to
role/eval, everything else defaulting torole/platform, confirmed per issue before the delete. All 16 read.Refinement that halves the work
Eight of the sixteen already carry a second
role/*label.role/*is deliberately non-exclusive, so those are already routed. Deletingrole/qastrips it from every issue holding it, which is exactly the desired outcome for these eight and needs no per-issue action at all.Applying the default to them would be wrong rather than merely redundant.
sirens-echo#265carriesrole/ai, which becomesrole/eval, so addingrole/platformwould misroute it.So the work is 8 label adds, then the delete.
Needs a label before the delete
To
role/eval, because each measures how an agent or the inference path actually behaves:coilyco-gaming/sirens-echo#1134- watch the coalescing lane answer a real member, six observations no test reaches. Observing live agent behavior.coilyco-gaming/sirens-echo#1082- measure the coalescing lane once #1080 rolls, and check how a merged reply reads.coilyco-flight-deck/agent-proxy#107- concurrency burst test. Body is a measurement design: Little's law arrival-rate arithmetic, three competing explanations span data cannot separate, and one burst to decide between them. Textbook eval.To
role/platform, because each is a defect or gap in software rather than a measurement:coilyco-flight-deck/agentic-os#1117-docs/test-harness.mddocuments a goose harness deleted in June 2026.coilyco-flight-deck/lunch-money-k8s#42,coilyco-flight-deck/bluesky-mcp#12,coilyco-flight-deck/node-stats-mcp#22- the caveat-last ordering audit. The finding surfaced from an agent's wrong answer, but the fix is response construction in each MCP server, so the work is platform's.coilyco-gaming/eco-app#270- QA sweep collector across the 25-tool Eco MCP surface. A defect collector on a service.Needs nothing, the delete handles them
coilyco-gaming/eco-mods#19,coilyco-gaming/eco-app#269,coilyco-gaming/eco-app#184,coilyco-gaming/galaxy-gen#78,coilyco-gaming/sirens-echo#577(closed) - all carryrole/engineer, which becomesrole/platform.coilyco-gaming/sirens-echo#265-role/ai, which becomesrole/eval.coilyco-gaming/sirens-echo#179-role/exec, which becomesrole/tpm.coilyco-flight-deck/agentic-os#781-role/ops, which becomesrole/sysadmin.A consequence of the rename worth a separate look
role/engineerbecomesrole/platformmechanically, and that is correct as a rename. But it will route every Eco mod issue torole/platformwhenrole/gamedevexists and starts empty.eco-mods#19is tailoring and husbandry perks not applying at mod benches, which is gamedev work wearing an engineer label because gamedev was not a seat when it was filed.The rename cannot fix this, because it cannot know which of
role/engineer's 414 issues belong to the new seat. A sweep of thecoilyco-gamingrepositories after step 2 would, and it is cheap because it is additive rather than destructive. Not filed yet.Blocked until step 2
role/evalandrole/platformdo not exist until the rename lands, so none of the 8 adds can be applied yet. This is a prepared plan rather than pending work.Status: steps 1, 2, and 5 authored
a0caf7e. The taxonomy is declarative and the check reports all three orgs converged.Ordering, and why step 5 is being held
agentic-os runs a merge-your-own-PR lane, and #1237 is being held against it deliberately.
label-taxonomy.mdcarries the rule that labels, matchers, and docs change in one batch. There are no matchers forrole/*, so the batch is two parts. If the doc merges before the apply runs, it namesrole/platformwhile the orgs still carryrole/engineer, and an agent following it would apply a label that does not exist. A wrong label name silently applies nothing rather than erroring, so the failure would be invisible.The window hurts equally in the other direction, which is the point of the batch rule. Order:
just forgejo-label-taxonomywith an org owner token.Expected intermediate state
Between the apply and the two deletes,
just forgejo-label-taxonomy-checkexits 1 and reportsrole/execandrole/qaas undeclared. That is the design working, not a regression. The check goes green once steps 3 and 4 finish.What unblocks after the apply
role/exec's 4 issues ontorole/tpm, then deleterole/exec.role/qa. The other 8 need nothing, because the delete strips the label and each already carries a second role.role/gamedevsweep of the gaming repositories. Additive and repo-scoped, so it needs no owner token.Steps 3 and 4 both end in a delete, which is the only irreversible move in this operation, so both need Kai.
Step 2 applied. The role labels now name the Core Roster v2 seats.
Ran clean against all three orgs. Six renames and one create each, with
role/execandrole/qareported and left alone.just forgejo-label-taxonomy-checkfrom merged main now reports all three converged, and exits 1 solely because of the two pending retirements. That is the designed intermediate state.It took two more fixes to get there
Both were mine, and both are the same shape.
aosguard ops forgejo org-label, where create and edit are flagless stubs that only redirect. The real surface isforgejo-admin. The original script had this defect too, which with thejson.loadsbug from #932 means it carried two independent failures and had never run.guard()kept hardcodingforgejowhile its caller passed a surface in, so the surface landed as an argument to the wrong verb group.The lesson is about test shape, twice over. #932 covered
plan()and not the argv. #934 covered the argv builder and the constants but not the command line they combine into. Each time, the only piece that was wrong was the only piece nothing asserted. #935 now asserts the full argv end to end and was checked with a negative control: reintroducing the bug fails two tests, removing it turns all 30 green.No issue lost its label
Verified structurally rather than by counting. Every renamed label kept its id:
role/engineer360 torole/platform360 in gaming, 382 to 382 in flight-deck, and so on for all six across both orgs sampled. Issue-label association is by id, so a rename cannot drop one.The apparent shortfall against my pre-rename baseline reconciles exactly against
coilysirenuser-owned repositories, which carry their own repo-level labels, were out of scope, and still hold the retired names. Per-label:role/design4,role/creator4,role/engineer8,role/ops1,role/ai1. That is #343, now with a number.Where this leaves the sequence
role/exec's 4 issues ontorole/tpm, then deleterole/exec.role/qaadds settled earlier, then deleterole/qa. The other 8 need nothing.role/gamedevsweep. It is now unblocked, androle/gamedevcurrently holds 0 issues.Steps 3 and 4 end in deletes, the only irreversible move here.