| title | Labeling Strategy & Governance | ||||||
|---|---|---|---|---|---|---|---|
| description | Label taxonomy, automation rules, and governance for LightSpeed repositories. | ||||||
| file_type | documentation | ||||||
| version | v1.1.0 | ||||||
| last_updated | 2026-08-06 | ||||||
| author | LightSpeed Team | ||||||
| maintainer | LightSpeed Team | ||||||
| owners |
|
||||||
| tags |
|
This document describes how LightSpeed uses GitHub labels to power automation, search, workflow routing, and community management across all repositories—including issues, pull requests (PRs), and discussions.
- Purpose & Principles
- Label Categories & Families
- Issue Labelling
- Pull Request Labelling
- Discussion Labelling
- Automation & Agent Integration
- Pre-Creation Label Validation (Phase 3)
- Best Practices
- Troubleshooting
- Clarity & Automation: Labels provide high-signal metadata for automation, project boards, and contributors.
- Consistency: All repositories follow a shared, canonical taxonomy (see
.github/labels.yml). - Discoverability: Labels make it easy to filter, search, and report on work across code, docs, and community.
- Community Engagement: Dedicated labels for discussions and non-code topics ensure inclusive collaboration.
- One-hot principle: Only one value per label group (e.g., one
priority:*, onestatus:*).
All label colours derive from the canonical 8-family palette defined in docs/LABEL_COLOR_STRATEGY.md. Each family has a primary (WCAG AA ≥ 4.5:1 against white), a secondary, and a light tertiary for label backgrounds.
| Family | Semantic use | Primary | Secondary | Tertiary |
|---|---|---|---|---|
| Green | Ready / Done | #1A7F37 |
#2A7A3B |
#ABEBC6 |
| Blue | Planning / Review | #0969DA |
#3467D3 |
#C5DEF5 |
| Yellow | Testing / Audit | #D29922 |
#F2D06D |
#FCE2B7 |
| Red | Blocked / Impediment | #CF222E |
#B91C1C |
#FCE2E2 |
| Orange | On-Hold / Deferred | #9A6700 |
#D5A87B |
#FDBF7C |
| Purple | Design / UX | #8957E5 |
#B4A7E8 |
#D89AF6 |
| Gray | Meta / Infrastructure | #57606A |
#B1BAC4 |
#D0D7DE |
| Teal | Integration / Deps | #007580 |
#0D7F6F |
#9FE1E3 |
Tertiary pastels are used as GitHub label backgrounds only (GitHub renders black text on light backgrounds automatically). Primary and secondary colours pass WCAG 2.2 AA (≥ 4.5:1) for use as foreground text on white.
All canonical labels use a family prefix. The organisation recognises the following label families:
Indicate the current progress or state of an issue or PR:
status:needs-triage— New, not yet reviewedstatus:ready— Clear requirements, ready to workstatus:in-progress— Someone is actively workingstatus:needs-review— Waiting for review/approvalstatus:blocked— Blocked by another issue or dependencystatus:done— Completed and closedstatus:wontfix— Intentionally closed as not actionable
Rule: Each issue and PR has exactly one status:* label.
Indicate urgency and scheduling priority:
priority:critical— Production/launch-blocking issue or severe defectpriority:important— Must-do, high-impact workpriority:normal— Standard feature or improvement (default)priority:minor— Nice-to-have, deferred work
Rule: Each issue and PR has exactly one priority:* label.
Classify the nature of the work:
type:bug— Unexpected behaviour or errortype:feature— New functionalitytype:improve— Enhancement to existing functionality or UXtype:enhancement— Enhancement to existing capabilitytype:chore— Maintenance, cleanup, tooling, or refactoringtype:documentation— Documentation improvementstype:test— Test suite additions or fixestype:refactor— Code quality improvements, no behaviour changetype:performance— Performance optimisationtype:security— Security-related changestype:a11y— Accessibility improvementstype:design— Design-related worktype:release— Release-related taskstype:ci— CI/CD pipeline worktype:automation— Workflow automation and toolingtype:dependency— Dependency management and updates
Rule: Each issue and PR has exactly one type:* label. For PRs, it's automatically assigned from the branch prefix; for issues, it's assigned from issue templates or manually. See .github/labels.yml for the full list of canonical type values.
Area labels (area:*): Indicate the high-level system or domain:
area:ci— CI/CD pipelines and automationarea:dependencies— Package and dependency managementarea:documentation— Docs, guides, examplesarea:quality— Quality validation and QA controlsarea:a11y— Accessibility standardsarea:performance— Performance optimisation- Other areas as needed
Component labels (comp:*): For WordPress-specific or product areas:
comp:block-editor— Gutenberg editor integrationcomp:block-json— Block JSON schemacomp:theme-json— Theme JSON featurescomp:templates— Template systemcomp:patterns— Block pattern library- Others as relevant to your projects
Rule: At least one area:* or comp:* label per issue/PR.
Provide additional context:
- Environment:
env:live(production),env:staging,env:prototype(sandbox/dev) - Compatibility:
compat:wordpress,compat:php,compat:woocommerce,compat:gutenberg,compat:rtl,compat:multisite - Language/Format:
lang:php,lang:js,lang:css,lang:html,lang:md,lang:json,lang:yaml - Others as defined per project
For release hygiene and workflow signals:
meta:needs-changelog— Requires a CHANGELOG.md entry (enforced on PRs)meta:no-changelog— Explicitly no changelog needed (internal-only changes)meta:has-pr— Issue has a linked PRmeta:no-issue-activity— No activity for 30+ daysmeta:stale— Marked for cleanup/archivalmeta:dependabot-security— Security update from Dependabotrelease:patch— Patch version bump requiredrelease:minor— Minor version bump requiredrelease:major— Major version bump requiredrelease:hotfix— Hotfix release required
Rule: Never apply both meta:needs-changelog and meta:no-changelog on the same PR.
Contributor labels (contrib:*):
contrib:good-first-issue— Suitable for new contributorscontrib:help-wanted— Needs community input or volunteerscontrib:discussion— Topic for community discussion
Discussion labels (discussion:*):
discussion:community— Social, networking, or open-ended topicsdiscussion:showcase— User projects, demos, "Show & Tell"discussion:announcement— Official news and team updatesdiscussion:feedback— Suggestions, UX feedback, ideasdiscussion:support— Help requests, troubleshooting (non-bug)discussion:sponsorship— Funding, GitHub Sponsorsdiscussion:partnership— Collaboration, business, outreach
Every issue must have:
- One
status:*(e.g.,status:needs-triage, then progressing tostatus:ready,status:in-progress, etc.) - One
priority:*(e.g.,priority:normal) - One
type:*(e.g.,type:bug,type:feature) - At least one
area:*orcomp:*(e.g.,area:ci,comp:block-editor) - Contextual labels as needed (
phase:6,meta:needs-changelog,contrib:good-first-issue)
- Automated: Issue templates auto-assign initial labels (
type:*,priority:*,status:needs-triage) - Manual curation: Triage and maintainers adjust labels as issue status changes or scope evolves
- Labeler rules:
.github/labeler.ymlcan auto-apply labels based on file paths, branch prefixes
- The unified labeling agent enforces one-hot rules (exactly one status, one priority, one type)
- The agent removes non-canonical labels or migrates them to canonical equivalents
- Project board auto-triage uses status labels to organize work
- Changelog and release labels (
meta:needs-changelog,release:*) drive release automation
Every PR must have:
- One
status:*(automatically set tostatus:needs-reviewon open) - One
type:*(automatically matched from branch prefix:feat/→type:feature,fix/→type:bug, etc.) - One
priority:*(derived from branch prefix or set manually; defaults topriority:normal) - At least one
area:*orcomp:* - Release label:
release:patch,release:minor, orrelease:major(required for shipping PRs) - Meta labels:
meta:needs-changelogormeta:no-changelog(enforced; cannot have both)
PR branch names automatically assign type:* labels:
Core prefixes:
feat/→type:featurefix/→type:bughotfix/→type:bug+release:hotfixrefactor/→type:refactorperf/→type:performancedocs/→type:documentationtest/→type:testchore/→type:choreci/→type:ci+area:cideps/→type:dependency+area:dependenciessecurity/→type:securitya11y/→type:a11ybuild/→type:build
Optional prefixes (as needed for your projects):
proto/,ds/,api/,.schemas/— Product/design systemcontent/,seo/,config/,migrate/— Client/project specific
- User-facing changes must have
meta:needs-changelog(a CHANGELOG.md entry is required for merge) - Internal-only changes (refactoring, testing, CI) can use
meta:no-changelogto skip changelog requirement - Never apply both
meta:needs-changelogandmeta:no-changelogon the same PR
- Labeler automatically applies labels based on branch name and file changes
- Changelog validation blocks merges if a user-facing PR lacks a changelog entry or required label
- Status transitions follow one-hot rules (only one status at a time)
- Release labels guide automated changelog compilation and semantic versioning
Discussion labels organize community conversations by topic, making it easy for users to find relevant threads and for moderators to filter and prioritize.
discussion:community— Social, networking, or open-ended topicsdiscussion:showcase— User projects, demos, "Show & Tell"discussion:announcement— Official news and team updatesdiscussion:feedback— Suggestions, UX feedback, general ideasdiscussion:support— "How do I…" setup, troubleshooting, help requests (non-bug)discussion:sponsorship— Funding, GitHub Sponsors, financial topicsdiscussion:partnership— Collaboration, business, outreach
- Encourage users to select a label when starting a new discussion
- Apply or update labels when moderating to keep threads organized
- Use labels to filter discussions when reviewing or responding
- A discussion can have multiple labels if it spans categories
All labelling, status enforcement, type assignment, and standardisation are handled by the unified labelling agent (.github/scripts/agents/labeling.agent.js) and labelling workflow (.github/workflows/labeling.yml).
How it works:
- Triggered on issue/PR creation, edits, and label changes
- Reads canonical configuration from
.github/labels.yml,.github/labeler.yml, and.github/issue-types.yml - Applies automatic labels based on:
- Branch prefixes (PRs only)
- File path changes
- PR body front matter
- Content heuristics
- Enforces one-hot rules (exactly one status, priority, type)
- Removes non-canonical labels and migrates legacy labels
- Generates reports for monitoring and debugging
The agent orchestrates reusable utility modules in scripts/agents/includes/:
| Utility | Responsibility |
|---|---|
label-lookup.js |
Fetch canonical labels, build alias maps, find standard labels |
labeler-utils.js |
Apply labeler rules based on file/branch patterns |
label-sync.js |
Sync repository labels with canonical configuration |
status-enforcer.js |
Enforce one-hot status, priority, type labels |
label-reporting.js |
Build labelling and standardisation reports |
type-lookup.js |
Load issue types and find matches from titles/bodies |
label-heuristics.js |
Suggest labels from issue/PR content |
.github/labels.yml— Canonical label definitions, colours, and aliases.github/labeler.yml— File/branch-based label rules.github/issue-types.yml— Canonical issue type definitions
All automation reads from these files; there is no hardcoded label logic in agents or workflows.
To prevent bare labels and invalid label combinations, all issues and PRs are validated by an automated validation workflow after creation.
- Trigger: Validation runs on issue/PR
opened,edited,labeled,unlabeled, and PRsynchronizeevents (after creation) - Script:
scripts/validation/validate-labels-before-creation.cjsenforces 5 rules - Workflow:
.github/workflows/validate-issue-labels.ymlposts guidance on failure - Outcome: Valid labels pass silently; invalid labels receive a helpful error comment with corrected examples
| Rule | Requirement | Example ✅ | Example ❌ |
|---|---|---|---|
| Rule 1: Existence | Label must exist in canonical set (.github/labels.yml) | type:bug |
type:bugfix |
| Rule 2: Family Prefix | Label must have family prefix (type:, status:, priority:, etc.) | status:needs-triage |
needs-triage |
| Rule 3: One-hot per Family | Only one label per family (except meta:, comp:, lang:) | type:bug, status:ready |
type:bug, type:feature |
| Rule 4: Required Families | All issues/PRs must have a type:* label |
type:documentation |
(no type:) |
| Rule 5: Warnings | Common mistakes flagged with suggestions | type:bug (after correction) |
bug (bare, triggers warning) |
✅ Valid labels (all rules pass):
type:bug
status:needs-triage
priority:critical
area:ci
meta:needs-changelog
❌ Invalid labels (caught by validation):
bug # ❌ Rule 2 (missing type: prefix)
feature # ❌ Rule 2 (missing type: prefix)
type:bug, type:feature # ❌ Rule 3 (multiple type: labels)
status:ready # ❌ Rule 4 (missing type:*)
urgent # ❌ Rule 2 (bare label, not in canonical set)
When validation fails, the workflow posts a comment with:
- Issue description — What's wrong and why
- Valid examples — Copy-paste ready label combinations
- Documentation link — This page and other resources
- Canonical label reference — Link to
.github/labels.yml(158 total labels)
Example error comment:
⚠️ Label Validation FailedLabels on this issue:
bug, feature, ciIssues:
- Label 'bug' missing required family prefix. Use one of: type:, status:, priority:, area:, meta:, release:, lang:, env:, compat:, comp:
- Label 'feature' missing required family prefix. Use one of: type:, status:, priority:, area:, meta:, release:, lang:, env:, compat:, comp:
- Label 'ci' missing required family prefix. Use one of: type:, status:, priority:, area:, meta:, release:, lang:, env:, compat:, comp:
How to fix:
- Use only canonical labels with family prefixes:
type:,status:,priority:,area:,meta:, etc.- Check the canonical labels (158 total)
- Each family allows ONE label (except
meta:andcomp:which allow multiple)- All issues/PRs must have a
type:*labelValid Examples:
type:bug, status:needs-triage, priority:critical, area:ci type:feature, priority:normal, area:documentation type:task, status:ready, area:automation
If you receive a validation error:
- Remove bare labels (bug, feature, urgent, ci, docs, etc.)
- Add family prefix (type:bug, area:ci, priority:urgent → priority:critical, etc.)
- Edit the issue/PR to apply corrected labels
- Validation re-runs automatically when labels change
- Keep exactly one
status:*andpriority:*on every issue/PR. - Use the most specific
area:*orcomp:*for filtering and reporting. - Update labels as work progresses or if scope changes.
- Trust automation: Let the labelling agent handle most label application; only manually adjust when needed.
- Refer to
.github/labels.ymlas the source of truth for canonical labels. - Use discussion labels to keep conversations organised and welcoming.
- Review and clean up labels quarterly, removing unused or redundant entries.
- Always provide
meta:needs-changelogormeta:no-changelogon PRs before merging.
"Label 'X' missing required family prefix"
- The label isn't prefixed (e.g.,
buginstead oftype:bug) - Fix: Edit the issue/PR and apply canonical labels with family prefix (type:, status:, priority:, area:, etc.)
- Reference: See Validation Rules above and
.github/labels.ymlfor all 158 canonical labels
"Label 'X' not found in canonical set"
- The label doesn't exist in
.github/labels.yml(typo or custom label) - Fix: Use a canonical label from the 158-label set; custom labels are not allowed
- Reference: Canonical labels
"Multiple labels from family 'Y' found: [a, b]"
- You applied more than one label from the same family (e.g.,
type:bugANDtype:feature) - Fix: Keep only one label per family (except meta:, comp:, lang: which allow multiples)
- Reference: Validation Rules — one-hot per family
"Missing required 'type:*' label for classification"
- The issue/PR has no
type:*label (e.g., missingtype:bug,type:feature,type:task) - Fix: Add a
type:*label that matches the work type - Reference: Type Labels — choose the correct type for your issue/PR
Validation failed but I don't see a comment
- The issue/PR might not have raised a validation event yet
- Fix: Edit the issue/PR and save (even without label changes) to trigger validation re-run
- Alternative: Remove and re-apply labels to trigger the workflow
- Check
.github/labels.ymlfor missing/typo entries - Verify branch prefix or file pattern matches in
.github/labeler.yml - Run
node scripts/agents/includes/check-template-labels.jsto validate issue/PR templates - Use
scripts/validation/validate-labels-before-creation.cjsto test labels locally
- Review labeler workflow logs in the PR/issue activity
- Check if the labelling workflow is enabled and up-to-date
- Verify the labelling agent has access to read/write labels
- Run the pre-creation validation script to check if labels are canonical
- Update
.github/labels.ymlwith the new canonical definition - Update
.github/labeler.ymlif you need automatic application rules - Update this documentation to describe the new label
- Create a PR and reference issue #636
- Note: New labels must follow the family-prefix naming convention (e.g.,
area:newarea, notnewarea)
- The labelling agent automatically migrates old labels to canonical equivalents
- If a label persists, check
.github/label-governance-policy.ymlfor exceptions - Open an issue if a label should be migrated or removed
- Run
scripts/validation/validate-labels-before-creation.cjsto test label canonicality
- Canonical Labels Config
- Label Colour Strategy
- Labeler Rules
- Issue Types Config
- Labelling Workflow
- Labelling Agent
- Issue Creation Standards
- PR Creation Standards
Built by 🧱 LightSpeedWP with ☕, 🚀, and open-source spirit!