MF-7: Label + milestone bootstrap across forges #298

Closed
opened 2026-04-23 23:33:16 +00:00 by code-lead · 0 comments
Collaborator

As an operator, I want the first-run label + milestone reconcile to work against Forgejo, GitHub, and GitLab, producing the same canonical area:* / type:* set on every forge so that routing and milestone queries work uniformly.

Acceptance criteria

Labels reconcile

  • labels.ts reconcile loop iterates config.repos, calls forgePort.listRepoLabels and the adapter's label-create surface per forge.
  • Domain code speaks a single colour format: "d97706" (no #). The adapter layer handles translation (Forgejo wants #-prefixed; GitHub/GitLab want bare hex).
  • Reconcile is idempotent on all three forges.

Milestones

  • Extend ForgePort with listMilestones + createMilestone.
  • Per-adapter implementation.
  • just labels-bootstrap creates any missing milestone on the active repo set.

Known-quirk documentation

  • Document label-render differences between forges (e.g., Forgejo shows darker text on light hex, GitHub auto-picks text colour, GitLab forces a specific text-colour algorithm). Don't try to correct — document and move on.

Tests

  • labels.test.ts: reconcile on each forge stub produces the identical canonical set (verified via listRepoLabels).
  • Colour-format round-trip: domain "d97706" → adapter → round-trip listing → domain "d97706".
  • Milestone createMilestone idempotent across re-runs.

Out of scope

  • Colour palette drift correction between forges.
  • Label description sync where a forge truncates the field (GitLab caps description length).
  • Converting existing issues' labels mid-reconcile — this is pure label surface bootstrap.

References

  • Spec: specs/multi-forge.md § MF-7.
  • apps/server/src/infrastructure/forge/labels.ts — current reconcile entry.
  • CLAUDE.md § Multi-repo / label bootstrap recipe.

Dependencies

  • Blocks on MF-4 (adapter factory) — reconcile picks the adapter per repo.
  • Touches the ForgePort surface (adds listMilestones / createMilestone); Forgejo adapter implements them first, others inherit the contract and close it in their adapter stories.
  • Depends on #295 (MF-4)
As an operator, I want the first-run label + milestone reconcile to work against Forgejo, GitHub, and GitLab, producing the same canonical `area:*` / `type:*` set on every forge so that routing and milestone queries work uniformly. ## Acceptance criteria ### Labels reconcile - [ ] `labels.ts` reconcile loop iterates `config.repos`, calls `forgePort.listRepoLabels` and the adapter's label-create surface per forge. - [ ] Domain code speaks a single colour format: `"d97706"` (no `#`). The adapter layer handles translation (Forgejo wants `#`-prefixed; GitHub/GitLab want bare hex). - [ ] Reconcile is idempotent on all three forges. ### Milestones - [ ] Extend `ForgePort` with `listMilestones` + `createMilestone`. - [ ] Per-adapter implementation. - [ ] `just labels-bootstrap` creates any missing milestone on the active repo set. ### Known-quirk documentation - [ ] Document label-render differences between forges (e.g., Forgejo shows darker text on light hex, GitHub auto-picks text colour, GitLab forces a specific text-colour algorithm). Don't try to correct — document and move on. ### Tests - [ ] `labels.test.ts`: reconcile on each forge stub produces the identical canonical set (verified via `listRepoLabels`). - [ ] Colour-format round-trip: domain `"d97706"` → adapter → round-trip listing → domain `"d97706"`. - [ ] Milestone `createMilestone` idempotent across re-runs. ## Out of scope - Colour palette drift correction between forges. - Label description sync where a forge truncates the field (GitLab caps description length). - Converting existing issues' labels mid-reconcile — this is pure label surface bootstrap. ## References - Spec: [`specs/multi-forge.md`](../src/branch/main/specs/multi-forge.md) § MF-7. - `apps/server/src/infrastructure/forge/labels.ts` — current reconcile entry. - CLAUDE.md § Multi-repo / label bootstrap recipe. ## Dependencies - **Blocks on MF-4** (adapter factory) — reconcile picks the adapter per repo. - Touches the `ForgePort` surface (adds `listMilestones` / `createMilestone`); Forgejo adapter implements them first, others inherit the contract and close it in their adapter stories. <!-- machine-parseable deps for the deps.ts body fallback; native POST /dependencies is currently returning HTTP 404 on this Forgejo. --> - Depends on #295 (MF-4)
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
charles/claude-hooks#298
No description provided.