Summary
The work-items plugin's canonical-role machinery carries an internal contradiction plus two implementation gaps, discovered when a consuming repo's "role_labels is null" report was independently verified against plugin source (0.25.2; identical in cached 0.25.3).
1. Doc contradiction: warn-on-absent vs omit-defaults
reference/label-taxonomy.md ("Canonical roles"): an absent config.role_labels entry falls back to its default "with a loud warning" — and reference/tracker-seam.md ("Role-label resolution is an action-entry invariant") repeats the loud-warning mandate.
skills/setup/SKILL.md (~line 273): "Omit entries that keep their default rather than snapshotting defaults into the file."
A repo that follows setup's instruction exactly is therefore condemned to warn on every lane pass forever. Conforming configuration should not produce a standing warning; the two surfaces cannot both be right.
2. The warning is prose-only — no code emits it
tools/work-item-tracker/lib/binding.sh falls back silently (jq -r '.config.role_labels["human-gated"] // empty' then a plain default). The loud warning exists only as a skill-prose obligation, dependent entirely on model compliance. Either implement it (once the contradiction above is resolved in favor of warning) or delete the mandate from both reference docs.
3. Seam resolves only one of three roles
binding.sh resolves human-gated only — it is what work-item-tracker.sh (~line 199) feeds to wit_filter_frontier for list-frontier --autonomous. autonomous-eligible and recurring-maintenance have no runtime resolution path at the seam; they are skill-prose obligations. If remapping those roles is meant to be supported (label-taxonomy says it is), the seam should resolve them too; if not, the docs overpromise.
Suggested resolution (maintainer's call)
Reconcile in favor of "absent = sanctioned, silent, zero-migration": delete the loud-warning mandate from both reference docs, keep setup's omit-defaults instruction, and extend binding.sh to resolve all three roles so remaps actually bind at the seam. (The alternative — implement the warning and have setup snapshot values — contradicts the zero-migration promise and adds noise to every conforming repo.)
For reference, the correct schema consuming repos should use when they DO remap (hyphenated keys; verified against label-taxonomy.md, setup/SKILL.md, binding.sh):
"role_labels": {
"autonomous-eligible": "agent-ready",
"human-gated": "needs-human",
"recurring-maintenance": "recurring"
}
Provenance
Surfaced by melodic-software/ci-workflows#247 (now closed, re-homed here). Findings independently verified by a fresh-context agent against plugin source and the live consuming repo, 2026-07-26. Note for the fix: ci-workflows#247's original body proposed underscored key names — wrong; treat this issue's schema block as the reference.
Filed by an AI agent at the operator's direction (attended queue session, 2026-07-26).
Summary
The work-items plugin's canonical-role machinery carries an internal contradiction plus two implementation gaps, discovered when a consuming repo's "role_labels is null" report was independently verified against plugin source (0.25.2; identical in cached 0.25.3).
1. Doc contradiction: warn-on-absent vs omit-defaults
reference/label-taxonomy.md("Canonical roles"): an absentconfig.role_labelsentry falls back to its default "with a loud warning" — andreference/tracker-seam.md("Role-label resolution is an action-entry invariant") repeats the loud-warning mandate.skills/setup/SKILL.md(~line 273): "Omit entries that keep their default rather than snapshotting defaults into the file."A repo that follows setup's instruction exactly is therefore condemned to warn on every lane pass forever. Conforming configuration should not produce a standing warning; the two surfaces cannot both be right.
2. The warning is prose-only — no code emits it
tools/work-item-tracker/lib/binding.shfalls back silently (jq -r '.config.role_labels["human-gated"] // empty'then a plain default). The loud warning exists only as a skill-prose obligation, dependent entirely on model compliance. Either implement it (once the contradiction above is resolved in favor of warning) or delete the mandate from both reference docs.3. Seam resolves only one of three roles
binding.shresolveshuman-gatedonly — it is whatwork-item-tracker.sh(~line 199) feeds towit_filter_frontierforlist-frontier --autonomous.autonomous-eligibleandrecurring-maintenancehave no runtime resolution path at the seam; they are skill-prose obligations. If remapping those roles is meant to be supported (label-taxonomy says it is), the seam should resolve them too; if not, the docs overpromise.Suggested resolution (maintainer's call)
Reconcile in favor of "absent = sanctioned, silent, zero-migration": delete the loud-warning mandate from both reference docs, keep setup's omit-defaults instruction, and extend
binding.shto resolve all three roles so remaps actually bind at the seam. (The alternative — implement the warning and have setup snapshot values — contradicts the zero-migration promise and adds noise to every conforming repo.)For reference, the correct schema consuming repos should use when they DO remap (hyphenated keys; verified against
label-taxonomy.md,setup/SKILL.md,binding.sh):Provenance
Surfaced by melodic-software/ci-workflows#247 (now closed, re-homed here). Findings independently verified by a fresh-context agent against plugin source and the live consuming repo, 2026-07-26. Note for the fix: ci-workflows#247's original body proposed underscored key names — wrong; treat this issue's schema block as the reference.
Filed by an AI agent at the operator's direction (attended queue session, 2026-07-26).