overengineeringstudio / overengineeringstudio/effect-utils
Add `githubLabels` genie runtime helper
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 82
- Forks
- 2
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 121
Description
Proposal
Add a new runtime helper @overeng/genie/src/runtime/github-labels/ (parallel to the existing github-ruleset/) that emits a typed JSON manifest for a repo's labels, plus an applier task that syncs the manifest to GitHub via the gh label CLI.
The existing ruleset pattern is:
.genie.tssource → runtime helper → typed JSON artifact at.github/repo-settings.json- Applied via
dt gh:apply-settingswhich shellsgh api repos/.../rulesets/{id} --method PUT --input .github/repo-settings.json
This issue proposes the same shape for labels.
Motivation
Label taxonomies want to be version-controlled, diff-reviewable, and drift-checked — the same reasons branch rulesets already are. Currently labels drift silently across repos: a prefix-based taxonomy (type:*, state:*, origin:*, area:*) just got deployed across multiple repos via one-off gh label create commands, and there's no mechanism to keep them in sync or catch divergence.
Design
Runtime helper
New module packages/@overeng/genie/src/runtime/github-labels/mod.ts exporting:
export interface LabelSpec {
name: string
color: string // hex, no leading '#'
description?: string
}
export interface GithubLabelsArgs {
labels: readonly LabelSpec[]
}
export const githubLabels: (args: GithubLabelsArgs) => GenieOutput
Emits .github/labels.json as a sorted array (deterministic output — sort by name for stable diffs).
.genie.ts usage
// .github/labels.json.genie.ts
import { githubLabels } from '../repos/effect-utils/genie/external.ts'
import { sharedLabels } from '../repos/effect-utils/genie/labels.ts'
export default githubLabels({
labels: [
...sharedLabels,
{ name: 'area:ci', color: '...', description: 'CI-related' },
],
})
Shared labels (the type:* / state:* / origin:* axes) live in a shared module; per-repo .genie.ts files compose them with their own area:* entries.
Applier
New devenv task gh:apply-labels (or extend gh:apply-settings to cover both):
- Fetch current labels:
gh label list --json name,color,description --limit 500 - Diff against
.github/labels.json:- label in manifest but not in repo → create
- label in both but color/description differ → update
- label in repo but not in manifest → skip (additive default) or delete (with
--prune)
- Use
gh label create --forcefor upsert (simpler than per-field PATCH viagh api)
Delete semantics
Destructive, so opt-in:
- Default: additive. Manifest is a guaranteed subset; extras survive.
- With
--prune: strict. Manifest is authoritative; extras are deleted.
Rename handling is deferred — first version treats rename as destroy+create. A future rename: string field can be added to LabelSpec if needed.
Shared taxonomy module
Ship a repos/effect-utils/genie/labels.ts with the shared axes that downstream repos can import:
export const sharedLabels: LabelSpec[] = [
{ name: 'type:epic', color: '1D76DB', description: 'Large tracking issue with child tasks' },
{ name: 'type:rca', color: '5319E7', description: 'Root cause analysis tracking' },
// ... etc for the 10 already-deployed labels
]
Acceptance criteria
- New
github-labelsruntime helper underpackages/@overeng/genie/src/runtime/github-labels/with tests - Exported from
@overeng/geniepublic surface + fromrepos/effect-utils/genie/external.ts .github/labels.json.genie.tsin theeffect-utilsrepo itself as the first consumerdt gh:apply-labelsdevenv task (or extendedgh:apply-settings) that:- Creates missing labels
- Updates mismatched color/description
- Leaves extras alone by default
- Deletes extras with
--prune - Is idempotent on repeat runs
- Shared taxonomy module exportable to downstream consumers (
schickling/dotfiles+schickling/megarepo-allwill adopt after) - Works with the private-repo + public-repo variants both
Non-goals
- GitHub issue templates (separate helper)
- GitHub environment secrets (separate helper)
- Label renames (deferred)
References
- Existing pattern:
packages/@overeng/genie/src/runtime/github-ruleset/mod.ts - Downstream consumer planned:
schickling/dotfiles(has the 10-label taxonomy already deployed) - Label taxonomy doc in downstream repo:
nixpkgs/ai/rules/workflow.md— "Label taxonomy" subsection
Posted by 🧬 cl1-helix on behalf of @schickling · 6cfe014f-38bd-46cf-90ac-18cbd4dc034f@mbp2025
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading packages/@overeng/genie/src/runtime/github-ruleset/mod.ts and the existing @overeng/genie public exports, then inspect the devenv task behind dt gh:apply-settings. Add the github-labels runtime helper, effect-utils consumer, shared taxonomy export, and applier behavior described in the acceptance criteria; verify creation, updates, additive defaults, --prune deletion, and idempotent repeat runs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, typescript
- Domain
- devops, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100