feat(forgejo): declare the label taxonomy instead of copying an org #932

Merged
coilysiren merged 1 commit from aos/claude/label-taxonomy-declarative into main 2026-08-25 18:30:24 +00:00
Member

Step 1 of coilyco-flight-deck/agent-compose#342. Changes nothing in Forgejo.

What was wrong

The authority for the fleet triage labels was live Forgejo org state. forgejo-label-taxonomy-sync.py named coilyco-gaming as the source of truth and copied it onto the other two orgs, so a label change was an API call with no diff, no review, and no commit.

Two things followed from that:

  • The role/* values went on naming the eight-seat roster that Core Roster v2 replaced, and nothing reported it.
  • The script had been unrunnable. It called json.loads on aosguard output without --output json, and aosguard emits YAML, so it raised on its first read. There was no test and no justfile verb, so neither problem was caught.

What this does

config/forgejo-label-taxonomy.yaml declares the taxonomy. The script drives it onto every org named there. The committed file is a faithful snapshot of current state.

Three rules the converge holds:

  • Every declared field is driven to its value. A label edited by hand in the web UI is corrected rather than accepted. Stricter than the old behavior, which reported colour and exclusivity drift in a closing summary and never fixed it.
  • Nothing is ever deleted. A delete strips the label from every issue holding it, which is the only irreversible move here. An undeclared label is reported and left alone.
  • A rename is an edit in place. Every issue keeps the label it already carries, so renaming role/engineer to role/platform carries all 414 of its issues at no per-issue cost. That is what makes step 2 cheap.

Four new justfile verbs, where there were none: forgejo-label-taxonomy, -dry-run, -check, -test.

Verification

just forgejo-label-taxonomy-check against live state:

taxonomy: 18 shared labels across 3 orgs
=== coilyco-gaming
  converged
=== coilyco-bridge
  converged
=== coilyco-flight-deck
  converged
exit=0

Negative control, because "converged" is worthless if the tool cannot see divergence. A probe taxonomy carrying a rename, a colour change, and a new label:

=== coilyco-gaming
  would rename role/ai -> role/eval
  would edit   role/ops
  would create role/gamedev

exit 1, on all three orgs.

17 planner tests, no live calls. Full pre-commit run --all-files green.

Notes for review

  • The spent 2026-08-15 flat-to-prefixed rename map is removed. All three orgs carry only prefixed names, so it was dead weight.
  • No docs page and no docs/FEATURES.md entry, matching the precedent set by forgejo-branch-protection and forgejo-repo-settings, which are converge scripts documented by their docstring and justfile verb. An earlier draft added one and it pushed docs/ over the 40-doc cap.
  • What the axes mean stays documented in agentic-os beside the triage skill that reads them, and is deliberately not restated here.
  • An apply still needs an org owner token. coilyco-ops is a member rather than an owner and gets 403. --check and --dry-run only read.

Refs coilyco-flight-deck/agent-compose#342

Step 1 of coilyco-flight-deck/agent-compose#342. **Changes nothing in Forgejo.** ## What was wrong The authority for the fleet triage labels was live Forgejo org state. `forgejo-label-taxonomy-sync.py` named `coilyco-gaming` as the source of truth and copied it onto the other two orgs, so a label change was an API call with no diff, no review, and no commit. Two things followed from that: * The `role/*` values went on naming the eight-seat roster that Core Roster v2 replaced, and nothing reported it. * **The script had been unrunnable.** It called `json.loads` on `aosguard` output without `--output json`, and aosguard emits YAML, so it raised on its first read. There was no test and no justfile verb, so neither problem was caught. ## What this does `config/forgejo-label-taxonomy.yaml` declares the taxonomy. The script drives it onto every org named there. The committed file is a faithful snapshot of current state. Three rules the converge holds: * **Every declared field is driven to its value.** A label edited by hand in the web UI is corrected rather than accepted. Stricter than the old behavior, which reported colour and exclusivity drift in a closing summary and never fixed it. * **Nothing is ever deleted.** A delete strips the label from every issue holding it, which is the only irreversible move here. An undeclared label is reported and left alone. * **A rename is an edit in place.** Every issue keeps the label it already carries, so renaming `role/engineer` to `role/platform` carries all 414 of its issues at no per-issue cost. That is what makes step 2 cheap. Four new justfile verbs, where there were none: `forgejo-label-taxonomy`, `-dry-run`, `-check`, `-test`. ## Verification `just forgejo-label-taxonomy-check` against live state: ``` taxonomy: 18 shared labels across 3 orgs === coilyco-gaming converged === coilyco-bridge converged === coilyco-flight-deck converged exit=0 ``` **Negative control**, because "converged" is worthless if the tool cannot see divergence. A probe taxonomy carrying a rename, a colour change, and a new label: ``` === coilyco-gaming would rename role/ai -> role/eval would edit role/ops would create role/gamedev ``` exit 1, on all three orgs. 17 planner tests, no live calls. Full `pre-commit run --all-files` green. ## Notes for review * The spent 2026-08-15 flat-to-prefixed rename map is removed. All three orgs carry only prefixed names, so it was dead weight. * No docs page and no `docs/FEATURES.md` entry, matching the precedent set by `forgejo-branch-protection` and `forgejo-repo-settings`, which are converge scripts documented by their docstring and justfile verb. An earlier draft added one and it pushed `docs/` over the 40-doc cap. * What the axes *mean* stays documented in agentic-os beside the triage skill that reads them, and is deliberately not restated here. * An apply still needs an **org owner token**. `coilyco-ops` is a member rather than an owner and gets 403. `--check` and `--dry-run` only read. Refs coilyco-flight-deck/agent-compose#342
feat(forgejo): declare the label taxonomy instead of copying an org
All checks were successful
CI / lint (pull_request) Successful in 44s
TruffleHog / Scan for secrets (pull_request) Successful in 5s
47d962dff1
The authority for the fleet triage labels was live Forgejo org state. The sync
script named coilyco-gaming as the source of truth and copied it onto the other
two orgs, so a label change was an API call with no diff, no review, and no
commit.

Two things followed. The role/* values went on naming the eight-seat roster that
Core Roster v2 replaced, and nothing reported it. And the script had been
unrunnable: it called json.loads on aosguard output without --output json, and
aosguard emits YAML, so it raised on its first read. There was no test and no
justfile verb, so neither was caught.

config/forgejo-label-taxonomy.yaml now declares the taxonomy and the script
drives it onto every org named there. The committed file is a faithful snapshot
of current state, so this lands as a verified no-op: `just
forgejo-label-taxonomy-check` reports all three orgs converged and exits 0. A
probe run with a rename, a colour change, and a new label plans all three
correctly and exits 1, so the check is not reporting converged vacuously.

Three rules the converge holds. Every declared field is driven to its value, so
a label edited by hand in the web UI is corrected rather than accepted, which is
stricter than the old behaviour of reporting drift and never fixing it. Nothing
is ever deleted, because a delete strips the label from every issue holding it.
A rename is an edit in place, so every issue keeps the label it already carries
and a roster rename costs no per-issue work.

The spent 2026-08-15 flat-to-prefixed rename map is removed; all three orgs
carry only prefixed names.

This is step 1 of coilyco-flight-deck/agent-compose#342 and changes nothing in
Forgejo. The role/* rename onto Core Roster v2 is step 2 and lands as a diff to
the new file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Agent-Role: tpm
coilysiren deleted branch aos/claude/label-taxonomy-declarative 2026-08-25 18:30:26 +00:00
Sign in to join this conversation.
No reviewers
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/infrastructure!932
No description provided.