PRD: Add scope labels to distinguish repo-ops from product work
Issue: #102
Requestor: Dina Berry
Lead: Flight
Status: Draft
1. Problem Statement
bradygaster/squad has accumulated 60+ labels across type:, go:, priority:, release:, status:, and squad: categories. None of these categories answers the question: "Is this work about the Squad product itself, or about how this repository is operated?"
This gap caused real confusion during the session that produced issues #97 and #98:
Both carried type:feature and enhancement labels. A reviewer scanning the backlog could not distinguish them without reading the full body. This is a triage failure that a scope label would have prevented in seconds.
The consequence is broader than one session:
- Triage is slower. Triagers must read issue bodies to classify work, even for routine routing decisions.
- Filtering is incomplete.
gh issue list --label type:bug returns product bugs mixed with repo-ops bugs. There is no clean way to view only product work or only repo-ops work.
- Reporting is imprecise. Sprint reviews cannot split "what we shipped to users" from "what we fixed about our own process."
- Automation is underused. sync-squad-labels.yml already creates squad: labels from team.md. It could create scope: labels with minimal changes but currently does not.
The fix is a small, well-defined label set: four scope: labels that compose with the existing taxonomy.
2. Goals
| Goal |
Measure |
| Every issue has a scope label |
Within 24h of creation, verified by heartbeat workflow |
| Filtering by scope works |
gh issue list --label scope:product, UI filter, and API all work |
| Triage enforces scope |
squad-triage.yml flags issues missing a scope label, same as type: and go: |
| Scope labels are auto-created |
sync-squad-labels.yml creates all 4 scope: labels on run |
| Backfill complete |
All open issues on bradygaster/squad have a scope label within 1 sprint |
Non-goals:
- Replacing the existing type: taxonomy (scope and type compose, they do not replace each other)
- Adding scope: labels to closed issues (open issues only for backfill)
- Enforcing a single scope per PR (PRs often span scopes; requirement applies to issues only)
3. Proposed Labels
scope:product
- Color: #0075ca (GitHub feature blue -- readable in both light and dark themes)
- Description: Squad product -- SDK, CLI, agent behavior, casting, ceremonies
- When to use:
- When NOT to use:
- Changes to this repo's GitHub Actions, branch rules, or contributor workflow
- npm publish pipeline changes
- docs site infrastructure (use scope:docs)
- Build tooling (use scope:infra)
scope:repo-ops
- Color: #e4860a (amber orange -- distinct from product blue, visible in dark mode)
- Description: This repo's operations -- CI, workflows, branch protection, contributor process
- When to use:
- When NOT to use:
- Squad product features (even if delivered via GitHub Actions)
- npm publish pipeline (use scope:infra -- publish is product infrastructure, not repo governance)
- docs site changes (use scope:docs)
scope:docs
- Color: #0e8a16 (GitHub green -- conventional for docs across open source)
- Description: Documentation site -- Astro, Starlight, content pages, nav, search
- When to use:
- Astro/Starlight site changes
- New or updated docs pages
- Broken link fixes in docs
- Docs navigation, search, or rendering issues
- Examples: Search/TF-IDF feature work, any issue affecting docs.squad.dev
- When NOT to use:
- README changes scoped to repo governance (use scope:repo-ops)
- CONTRIBUTING.md changes about the contributor process (use scope:repo-ops)
- In-code documentation (JSDoc, inline comments) -- those ride with the feature issue
Note: scope:docs is distinct from type:docs. type:docs says "this issue is a documentation task." scope:docs says "this issue lives in the docs product surface." An issue can be scope:product + type:docs (e.g., writing SDK reference pages). scope:docs is for the docs site itself.
scope:infra
- Color: #6f42c1 (GitHub purple -- reserved for infrastructure concerns in most repos)
- Description: Build, release, publish, and promotion infrastructure
- When to use:
- npm publish pipeline
- Insider release workflow
- Semver and release promotion automation
- Pre-publish validation jobs
- Sample CI coverage (see Section 7)
- Examples: npm publish fix, insider release gate, pre-flight dependency scan
- When NOT to use:
- GitHub Actions that govern the repo (use scope:repo-ops)
- docs site build (use scope:docs unless the build pipeline is the subject)
- Squad product features (use scope:product)
4. Interaction with Existing Labels
scope: + type:
These compose freely. Every issue should have one of each:
| scope: |
type: |
Meaning |
| scope:product |
type:bug |
Bug in Squad SDK or CLI |
| scope:product |
type:feature |
New Squad capability |
| scope:product |
type:docs |
SDK/feature reference documentation |
| scope:repo-ops |
type:chore |
Routine repo maintenance |
| scope:repo-ops |
type:feature |
New repo governance capability |
| scope:infra |
type:bug |
Release pipeline failure |
| scope:docs |
type:feature |
New docs page or section |
scope: + squad:
Also composes freely. scope: says what the work is about; squad: says who owns it:
| scope: |
squad: |
Example |
| scope:repo-ops |
squad:fido |
FIDO audits CI workflow |
| scope:product |
squad:eecom |
EECOM implements casting feature |
| scope:infra |
squad:surgeon |
Surgeon owns publish pipeline |
| scope:docs |
squad:pao |
PAO writes docs page |
Multiple scope: labels
Recommendation: no. Pick the primary scope. If a PR spans scopes (e.g., a feature that also touches the release pipeline), apply the scope that the issue is primarily about. Boundary cases:
- If the work changes both a Squad feature AND its docs, use scope:product (the docs ride with the feature)
- If the work changes both the repo CI AND the publish pipeline, pick whichever is the primary subject
scope:docs vs type:docs
- type:docs = the deliverable is documentation (a task type)
- scope:docs = the subject is the docs site (a product surface)
- These are orthogonal: scope:product + type:docs is valid and common
5. Automation
sync-squad-labels.yml
Current behavior: reads team.md, creates squad:* labels for each agent.
Required change: add a step that ensures all 4 scope: labels exist with the correct color and description. This is a single gh label create --force block alongside the existing squad: label creation.
# pseudocode for the new step
for label in scope:product scope:repo-ops scope:docs scope:infra:
gh label create "$label" --color "$color" --description "$desc" --force --repo bradygaster/squad
The --force flag updates color/description if the label already exists, making the step idempotent.
squad-triage.yml
Current behavior: flags issues missing type: or go: labels.
Required change: add scope: to the required label prefix list. Issues that complete triage without a scope: label should receive the same warning comment that missing type: labels trigger.
Implementation pattern: the workflow already checks for label prefixes. Adding scope: to the required prefixes list is a one-line change to the prefix array.
squad-heartbeat.yml
Current behavior: periodic health check on team and issue state.
Required change: add a check that counts open issues without any scope: label. Report the count in the heartbeat output. If the count exceeds a threshold (suggested: 5), flag it.
Template manifest (config.json)
If the label list is maintained in a config.json or similar manifest file, add all 4 scope: labels there. If the labels are hardcoded in the workflow YAML, move them to a shared config to keep a single source of truth. Recommendation: define labels in a .github/labels.json file (GitHub's standard format) and have sync-squad-labels.yml consume it.
6. Migration Plan
Phase 0: Assess current open issues
Run gh issue list --repo bradygaster/squad --state open --limit 200 --json number,title,labels to get the full open issue list and identify which have no scope: label.
Backfill mapping (current open issues, diberry/squad fork)
Based on the issue table in the original #102 body:
| Issue |
Title (abbreviated) |
Recommended scope |
| #97 |
Branch protection rules |
scope:repo-ops |
| #98 |
Workflow minutes PRD |
scope:product |
| #99 |
Main-guard bug |
scope:product |
| #100 |
Review completeness |
scope:product |
| #101 |
Linked chat summaries |
scope:product |
| #102 |
Add scope labels (this issue) |
scope:repo-ops |
For bradygaster/squad, apply the same mapping to corresponding issues. Issues related to release pipeline failures (bradygaster#556-bradygaster#564) should get scope:infra. Issues related to SDK or CLI features get scope:product. Issues related to CI, label management, or branch governance get scope:repo-ops.
Backfill execution
gh issue edit <number> --repo bradygaster/squad --add-label scope:product
Run in batches, grouped by scope, to reduce error risk. Assign FIDO to audit the backfill results.
diberry/squad fork
Yes, the fork also needs the labels. The sync-squad-labels.yml workflow should run on the fork as well. If it is not set up to run there, trigger it manually once or apply the labels via gh CLI directly.
7. Samples CI Gap (from bradygaster#640 discussion)
During review of PR bradygaster#640 (storage samples), a finding emerged that the samples/ directory has zero CI coverage. Samples ship untested.
This is a scope:infra concern, not a scope:product concern -- the samples themselves may be correct, but the infrastructure to validate them does not exist.
Finding: samples/ has no automated test execution in CI. Every PR that adds or modifies a sample can ship broken code without any workflow catching it.
Proposed label use: Tag all issues related to sample CI coverage with scope:infra. This creates a filterable backlog of sample infrastructure work, separate from the product feature work that generates the samples.
Proposed action: File a child issue under bradygaster#640 (or a new standalone issue) for "Add CI coverage for samples/ directory," labeled scope:infra + type:chore + priority:p1.
Why p1: Untested samples are a trust and adoption risk. When developers copy sample code that fails silently, they lose confidence in the framework. Given Squad's adoption goals, this is not a p2 maintenance item.
8. Implementation Phases
Phase 1: Create labels on bradygaster/squad
Manual or via gh CLI. Do not wait for automation.
gh label create "scope:product" --color "0075ca" --description "Squad product -- SDK, CLI, agent behavior, casting, ceremonies" --repo bradygaster/squad
gh label create "scope:repo-ops" --color "e4860a" --description "This repo's operations -- CI, workflows, branch protection, contributor process" --repo bradygaster/squad
gh label create "scope:docs" --color "0e8a16" --description "Documentation site -- Astro, Starlight, content pages, nav, search" --repo bradygaster/squad
gh label create "scope:infra" --color "6f42c1" --description "Build, release, publish, and promotion infrastructure" --repo bradygaster/squad
Owner: Flight or repo admin. Duration: 10 minutes.
Phase 2: Update sync-squad-labels.yml
Add scope: label creation to the label sync workflow so labels are recreated automatically whenever team.md changes or the workflow is triggered manually.
Owner: FIDO (CI/test domain). Duration: 1 sprint.
Prerequisite: Phase 1 complete (labels must exist to test the workflow).
Phase 3: Update triage workflow
Add scope: to the required label prefix list in squad-triage.yml.
Add scope: count to squad-heartbeat.yml output.
Owner: FIDO. Duration: 1 sprint (can run in parallel with Phase 2).
Phase 4: Backfill existing issues
Apply scope: labels to all open issues on bradygaster/squad.
Apply scope: labels to all open issues on diberry/squad fork.
Owner: Flight (mapping decisions) + Scribe (execution).
Duration: 1 sprint (timebox to 2 hours of CLI work).
9. Acceptance Criteria
Related
PRD: Add scope labels to distinguish repo-ops from product work
Issue: #102
Requestor: Dina Berry
Lead: Flight
Status: Draft
1. Problem Statement
bradygaster/squad has accumulated 60+ labels across type:, go:, priority:, release:, status:, and squad: categories. None of these categories answers the question: "Is this work about the Squad product itself, or about how this repository is operated?"
This gap caused real confusion during the session that produced issues #97 and #98:
Both carried
type:featureandenhancementlabels. A reviewer scanning the backlog could not distinguish them without reading the full body. This is a triage failure that a scope label would have prevented in seconds.The consequence is broader than one session:
gh issue list --label type:bugreturns product bugs mixed with repo-ops bugs. There is no clean way to view only product work or only repo-ops work.The fix is a small, well-defined label set: four scope: labels that compose with the existing taxonomy.
2. Goals
Non-goals:
3. Proposed Labels
scope:product
scope:repo-ops
scope:docs
Note: scope:docs is distinct from type:docs. type:docs says "this issue is a documentation task." scope:docs says "this issue lives in the docs product surface." An issue can be scope:product + type:docs (e.g., writing SDK reference pages). scope:docs is for the docs site itself.
scope:infra
4. Interaction with Existing Labels
scope: + type:
These compose freely. Every issue should have one of each:
scope: + squad:
Also composes freely. scope: says what the work is about; squad: says who owns it:
Multiple scope: labels
Recommendation: no. Pick the primary scope. If a PR spans scopes (e.g., a feature that also touches the release pipeline), apply the scope that the issue is primarily about. Boundary cases:
scope:docs vs type:docs
5. Automation
sync-squad-labels.yml
Current behavior: reads team.md, creates squad:* labels for each agent.
Required change: add a step that ensures all 4 scope: labels exist with the correct color and description. This is a single
gh label create --forceblock alongside the existing squad: label creation.The
--forceflag updates color/description if the label already exists, making the step idempotent.squad-triage.yml
Current behavior: flags issues missing type: or go: labels.
Required change: add scope: to the required label prefix list. Issues that complete triage without a scope: label should receive the same warning comment that missing type: labels trigger.
Implementation pattern: the workflow already checks for label prefixes. Adding
scope:to the required prefixes list is a one-line change to the prefix array.squad-heartbeat.yml
Current behavior: periodic health check on team and issue state.
Required change: add a check that counts open issues without any scope: label. Report the count in the heartbeat output. If the count exceeds a threshold (suggested: 5), flag it.
Template manifest (config.json)
If the label list is maintained in a config.json or similar manifest file, add all 4 scope: labels there. If the labels are hardcoded in the workflow YAML, move them to a shared config to keep a single source of truth. Recommendation: define labels in a
.github/labels.jsonfile (GitHub's standard format) and have sync-squad-labels.yml consume it.6. Migration Plan
Phase 0: Assess current open issues
Run
gh issue list --repo bradygaster/squad --state open --limit 200 --json number,title,labelsto get the full open issue list and identify which have no scope: label.Backfill mapping (current open issues, diberry/squad fork)
Based on the issue table in the original #102 body:
For bradygaster/squad, apply the same mapping to corresponding issues. Issues related to release pipeline failures (bradygaster#556-bradygaster#564) should get scope:infra. Issues related to SDK or CLI features get scope:product. Issues related to CI, label management, or branch governance get scope:repo-ops.
Backfill execution
Run in batches, grouped by scope, to reduce error risk. Assign FIDO to audit the backfill results.
diberry/squad fork
Yes, the fork also needs the labels. The sync-squad-labels.yml workflow should run on the fork as well. If it is not set up to run there, trigger it manually once or apply the labels via gh CLI directly.
7. Samples CI Gap (from bradygaster#640 discussion)
During review of PR bradygaster#640 (storage samples), a finding emerged that the samples/ directory has zero CI coverage. Samples ship untested.
This is a scope:infra concern, not a scope:product concern -- the samples themselves may be correct, but the infrastructure to validate them does not exist.
Finding: samples/ has no automated test execution in CI. Every PR that adds or modifies a sample can ship broken code without any workflow catching it.
Proposed label use: Tag all issues related to sample CI coverage with scope:infra. This creates a filterable backlog of sample infrastructure work, separate from the product feature work that generates the samples.
Proposed action: File a child issue under bradygaster#640 (or a new standalone issue) for "Add CI coverage for samples/ directory," labeled scope:infra + type:chore + priority:p1.
Why p1: Untested samples are a trust and adoption risk. When developers copy sample code that fails silently, they lose confidence in the framework. Given Squad's adoption goals, this is not a p2 maintenance item.
8. Implementation Phases
Phase 1: Create labels on bradygaster/squad
Manual or via gh CLI. Do not wait for automation.
Owner: Flight or repo admin. Duration: 10 minutes.
Phase 2: Update sync-squad-labels.yml
Add scope: label creation to the label sync workflow so labels are recreated automatically whenever team.md changes or the workflow is triggered manually.
Owner: FIDO (CI/test domain). Duration: 1 sprint.
Prerequisite: Phase 1 complete (labels must exist to test the workflow).
Phase 3: Update triage workflow
Add scope: to the required label prefix list in squad-triage.yml.
Add scope: count to squad-heartbeat.yml output.
Owner: FIDO. Duration: 1 sprint (can run in parallel with Phase 2).
Phase 4: Backfill existing issues
Apply scope: labels to all open issues on bradygaster/squad.
Apply scope: labels to all open issues on diberry/squad fork.
Owner: Flight (mapping decisions) + Scribe (execution).
Duration: 1 sprint (timebox to 2 hours of CLI work).
9. Acceptance Criteria
Related