LBL-1: Schema + builtin-sync for label_catalog #754

Closed
opened 2026-05-02 17:27:12 +00:00 by claude-desktop · 1 comment
Collaborator

Bundle directive

This story ships in one PR with #743 (AT-1) and #750 (SVC-1) — the foundation layer. Assign #743, not this issue. The PR closes all three (Closes #743 #750 #754).


As a platform engineer, I want a label_catalog table and a builtin-sync pass that mirrors config/labels.json into scope='builtin', so that the canonical label set per repo can move off the file system onto a DB-backed source of truth shared with the rest of the agent-config surface.

Acceptance criteria

Schema

  • migrations/<n>-label-catalog.ts creates label_catalog with the columns + scope check (builtin/global/repo) + UNIQUE(scope, repo, name) index per specs/config-to-db.md § Architecture.

Builtin sync

  • syncLabelCatalogBuiltin(labelsJsonPath) writes one builtin row per label. Idempotent.
  • getLabelCatalogForRepo(repo) resolves scope='repo' over scope='global' over scope='builtin'.

Tests

  • Unit: idempotent sync, scope ladder merge.
  • Integration: a scope='repo' row for area:dashboard shadows the builtin colour for that one repo only.

Out of scope

  • Swapping consumers — covered by LBL-2.
  • Dashboard CRUD UI — covered by LBL-3.

References

  • Spec: specs/config-to-db.md § Story LBL-1, § Architecture.
  • Bundled with: #743 (AT-1), #750 (SVC-1) — assign #743, this closes via the same PR.
## Bundle directive This story ships in **one PR with #743 (AT-1) and #750 (SVC-1)** — the foundation layer. **Assign #743**, not this issue. The PR closes all three (`Closes #743 #750 #754`). --- As a platform engineer, I want a `label_catalog` table and a builtin-sync pass that mirrors `config/labels.json` into `scope='builtin'`, so that the canonical label set per repo can move off the file system onto a DB-backed source of truth shared with the rest of the agent-config surface. ## Acceptance criteria ### Schema - [ ] `migrations/<n>-label-catalog.ts` creates `label_catalog` with the columns + scope check (`builtin`/`global`/`repo`) + UNIQUE(scope, repo, name) index per `specs/config-to-db.md` § Architecture. ### Builtin sync - [ ] `syncLabelCatalogBuiltin(labelsJsonPath)` writes one builtin row per label. Idempotent. - [ ] `getLabelCatalogForRepo(repo)` resolves `scope='repo'` over `scope='global'` over `scope='builtin'`. ### Tests - [ ] Unit: idempotent sync, scope ladder merge. - [ ] Integration: a `scope='repo'` row for `area:dashboard` shadows the builtin colour for that one repo only. ## Out of scope - Swapping consumers — covered by LBL-2. - Dashboard CRUD UI — covered by LBL-3. ## References - Spec: `specs/config-to-db.md` § Story LBL-1, § Architecture. - Bundled with: #743 (AT-1), #750 (SVC-1) — assign #743, this closes via the same PR.
Author
Collaborator

Shipped via PR #761 (commit 28027b9) as part of the foundation bundle alongside #743 (AT-1) and #750 (SVC-1). Closing.

Coverage:

  • migrations/<n>-label-catalog.ts created with the (scope, repo, name) unique index
  • syncLabelCatalogBuiltin(labelsJsonPath) writes one builtin row per label, idempotent
  • getLabelCatalogForRepo(repo) resolves repo → global → builtin
Shipped via PR #761 (commit `28027b9`) as part of the foundation bundle alongside #743 (AT-1) and #750 (SVC-1). Closing. Coverage: - `migrations/<n>-label-catalog.ts` created with the `(scope, repo, name)` unique index - `syncLabelCatalogBuiltin(labelsJsonPath)` writes one builtin row per label, idempotent - `getLabelCatalogForRepo(repo)` resolves `repo → global → builtin`
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#754
No description provided.