@clipboard-health/ai-rules 2.29.0 → 2.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/ai-rules",
3
- "version": "2.29.0",
3
+ "version": "2.29.2",
4
4
  "description": "Pre-built AI agent rules for consistent coding standards.",
5
5
  "keywords": [
6
6
  "ai",
@@ -43,6 +43,7 @@ Optional metadata:
43
43
  - `parent`: parent Linear identifier, for example `ENG-123`
44
44
  - blocked-by relations: tickets this new ticket depends on
45
45
  - blocking relations: tickets this new ticket blocks
46
+ - relevant labels: team labels (e.g. `product-area`) that fit the task, in addition to the required `agent-*` label
46
47
 
47
48
  ## Description Template
48
49
 
@@ -77,6 +78,7 @@ Use the current agent's structured Linear issue tool. Tool names and exact field
77
78
  - Assign it to the current Linear user.
78
79
  - Set its state to Todo.
79
80
  - Apply the chosen `agent-*` label.
81
+ - Apply relevant team labels (e.g. `product-area`) drawn from the team's label set (Linear MCP `list_issue_labels`) when clearly inferable from the task; ask the user if unsure. These are in addition to — never a replacement for — the required `agent-*` label, and never an extra `agent-*` label (the eligibility contract allows exactly one).
80
82
  - Put the generated Markdown body in the issue description.
81
83
  - Set the parent issue when the user provided one.
82
84
  - Add dependency relations for blockers and blocked tickets.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: write-bug-ticket
3
- description: Use when creating a Linear bug report ticket from conversation context, investigation findings, or user-provided evidence. Focuses on structuring and writing not investigating.
3
+ description: Use when creating a Linear bug report ticket from conversation context, investigation findings, or user-provided evidence when evidence already exists and needs structuring, not investigating.
4
4
  ---
5
5
 
6
6
  # Write Bug Ticket
@@ -18,7 +18,8 @@ Structure and write Linear bug reports from evidence that already exists in the
18
18
  3. **Draft** — title + description, structure scaled to complexity (see format below)
19
19
  4. **Self-review** — check every Red Flag below before presenting
20
20
  5. **Present for review** — show ONLY the draft and metadata suggestions. Ask for team/assignee.
21
- 6. **Create in Linear** — only after explicit approval
21
+ 6. **Resolve labels** — always include the `bug` type label, plus any relevant team labels (see Labels below).
22
+ 7. **Create in Linear** — only after explicit approval. Apply the resolved labels.
22
23
 
23
24
  ## Hard Rules
24
25
 
@@ -27,6 +28,8 @@ Structure and write Linear bug reports from evidence that already exists in the
27
28
  - **STR preferred, not required.** If not reproduced: "Not yet reproduced manually. Observed via monitoring." NEVER invent STR.
28
29
  - **Clean titles.** No bracket prefixes. Describe the symptom. Under 70 characters.
29
30
  - **Always document the repository.** Flag multi-repo bugs to the user for splitting.
31
+ - **Approval required.** Always present the draft for user review first. Only create the ticket in Linear after the user explicitly approves.
32
+ - **Always label by type.** Every bug ticket carries the `bug` type label (or the team's closest equivalent — never invent or create a label without the user's say-so). Also suggest relevant team labels for approval. See Labels.
30
33
  - **Redirect non-bugs.** Features → `write-feature-ticket`, tech debt → `write-tech-debt-ticket`.
31
34
 
32
35
  ## Ticket Format
@@ -35,14 +38,25 @@ Structure and write Linear bug reports from evidence that already exists in the
35
38
 
36
39
  **Repository:** Always include the repository name in the ticket body. Run `git remote get-url origin | sed 's/\.git$//' | sed 's/.*[:/]\([^/]*\/[^/]*\)$/\1/'` to get the `org/repo` name. For simple bugs, include as a bold inline label. For complex bugs, include in `## Technical Context`.
37
40
 
41
+ **Discovery context (optional):** If the bug was found while working on a ticket or PR, add a one-liner so reviewers understand how it surfaced (e.g., "Discovered while working on [TICKET-123](link)."). Place it after the opening paragraph for simple bugs, or in `## Technical Context` for complex bugs.
42
+
38
43
  **Simple bug** (<4 details): A paragraph with bold inline labels (**Expected:**, **Actual:**, **Repository:**, etc.). No `##` headers needed.
39
44
 
40
45
  **Complex bug** (multi-service, intermittent, wide impact): Use `## Expected Behavior`, `## Actual Behavior`, `## Steps to Reproduce`, `## Evidence`, `## Technical Context` (include repository — observables only, NOT diagnosis), `## Impact`.
41
46
 
42
- **Metadata:** Priority, labels (`bug`), presented BELOW the body. Always ask for team/assignee.
47
+ **Metadata:** Priority, labels (`bug` type label + approved relevant labels, see Labels), presented BELOW the body. Always ask for team/assignee.
43
48
 
44
49
  See reference.md for full examples.
45
50
 
51
+ ## Labels
52
+
53
+ Every ticket gets its type label plus any relevant team labels. Labels are presented in the metadata block and applied when the user approves the ticket.
54
+
55
+ **Resolving labels requires the target team.** `list_issue_labels` is team-scoped, so confirm the team (the "Present for review" step) before resolving — suggest the type label by name up front, then resolve it against the team's actual label set once the team is known.
56
+
57
+ 1. **Type label (mandatory).** Fetch the target team's labels (Linear MCP `list_issue_labels` for that team) and apply the one denoting a bug: `bug` if it exists, otherwise the closest existing equivalent (e.g. `bug-report`). Match case-insensitively and accept grouped variants. If no reasonable match exists, ask the user which label to use — NEVER invent a label or create a new one without the user's say-so.
58
+ 2. **Relevant labels (suggested).** Review the team's other labels (e.g. `product-area`, area, severity) and suggest those that fit this ticket. Apply them only on approval.
59
+
46
60
  ## Red Flags — Self-Review Before Presenting
47
61
 
48
62
  | Anti-Pattern | Fix |
@@ -60,3 +74,4 @@ See reference.md for full examples.
60
74
  | Guessed team assignment | Ask the user — never guess |
61
75
  | Bracket title prefixes | Describe the symptom without brackets |
62
76
  | Missing repository | Include repo name in ticket body — derive from git remote |
77
+ | No `bug` type label | Always apply it (or the team's closest equivalent) |
@@ -2,11 +2,13 @@
2
2
 
3
3
  ## Examples
4
4
 
5
+ Headings inside these examples are deepened to nest within this document — real tickets use the `##` sections specified in SKILL.md.
6
+
5
7
  ### What NOT to Write
6
8
 
7
9
  > **Title:** [BUG] 500 errors spiking on timesheet approval endpoint
8
10
  >
9
- > ### Investigation Notes
11
+ > #### Investigation Notes
10
12
  >
11
13
  > - [ ] Pull error logs and stack traces from Datadog
12
14
  > - [ ] Check for recent deployments prior to 14:00 UTC
@@ -34,38 +36,38 @@ Nurses on the mobile app are unable to complete shift bookings. After submitting
34
36
  - [RUM: session for user 12345 showing hang](https://app.datadoghq.com/rum/...)
35
37
  - [Logs: timeout errors on booking confirmation endpoint (last 7d)](https://app.datadoghq.com/logs?query=...)
36
38
 
37
- Suggested metadata: Priority: High
39
+ Suggested metadata: Priority: High | Labels: bug (type), Shift Bookability (relevant)
38
40
 
39
41
  ### Monitoring-Surfaced Bug
40
42
 
41
43
  **Title:** Elevated 500 errors on timesheet approval endpoint since 14:00 UTC
42
44
 
43
- ## Expected Behavior
45
+ #### Expected Behavior
44
46
 
45
47
  Timesheet approval requests complete successfully.
46
48
 
47
- ## Actual Behavior
49
+ #### Actual Behavior
48
50
 
49
51
  ~8% of requests returning 500 errors since 14:00 UTC on 2026-03-12. Error rate is 5x baseline.
50
52
 
51
- ## Steps to Reproduce
53
+ #### Steps to Reproduce
52
54
 
53
55
  Not yet reproduced manually. Observed via monitoring.
54
56
 
55
- ## Evidence
57
+ #### Evidence
56
58
 
57
59
  - [Logs: 500 errors on /api/timesheets/approve (last 4h)](https://app.datadoghq.com/logs?query=...)
58
60
  - [APM: error trace sample](https://app.datadoghq.com/apm/traces/...)
59
61
  - [Monitor: timesheet-approval-error-rate (alerting)](https://app.datadoghq.com/monitors/...)
60
62
 
61
- ## Technical Context
63
+ #### Technical Context
62
64
 
63
65
  **Repository:** ClipboardHealth/core-utils
64
66
 
65
67
  Errors began at 2026-03-12 14:00 UTC. Error logs reference `MongoServerError: connection pool exhausted`. Correlates with deploy at 13:45 UTC.
66
68
 
67
- ## Impact
69
+ #### Impact
68
70
 
69
71
  Users unable to approve timesheets. ~300 failed requests in 4 hours.
70
72
 
71
- Suggested metadata: Priority: Urgent
73
+ Suggested metadata: Priority: Urgent | Labels: bug (type), Workplace timesheets (relevant)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: write-feature-ticket
3
- description: Use when creating a Linear feature request ticket from conversation context, a brief description, or code/PR analysis. Interviews the user for clarity when context is insufficient.
3
+ description: Use when creating a Linear feature request ticket from conversation context, a brief description, or code/PR analysis including when context is too thin to draft from.
4
4
  ---
5
5
 
6
6
  # Write Feature Ticket
@@ -18,14 +18,14 @@ Draft Linear feature request tickets that describe what users need and why — n
18
18
  3. **Final validation** — run the checklist below before drafting. This is the ticket skill's own quality check — it doesn't blindly trust upstream context.
19
19
  4. **Assess scope** — does the problem contain multiple independent user-facing outcomes? If so, decompose into parent + sub-issues, each describing one outcome. Decomposition is about what the user gets, not how the engineer builds it.
20
20
  5. **Draft** — title + description, structure scaled to complexity (see Ticket Format below)
21
- 6. **Self-review** — check every item in [red-flags.md](red-flags.md) before presenting
22
- 7. **Suggest metadata (conditional)** — priority (Urgent/High/Medium/Low/No Priority), labels, project when context supports it. Present metadata suggestions BELOW the ticket body, separate from the description.
23
- 8. **Present for review** — show the draft to the user. Wait for explicit approval before proceeding.
24
- 9. **Create in Linear** — once the user approves (or approves with changes), create the ticket in Linear using the Linear MCP tools. For sub-issues, create parent first, then children linked to it. Apply any confirmed metadata. NEVER create without user approval.
21
+ 6. **Self-review** — check every Red Flag below before presenting
22
+ 7. **Present for review** — show the draft to the user, plus metadata suggestions BELOW the ticket body, separate from the description: the `feature` type label, priority (Urgent/High/Medium/Low/No Priority), relevant team labels, and project when context supports it. Ask for team/assignee.
23
+ 8. **Resolve labels** — once the team is known, resolve labels against that team's label set (see Labels below): the `feature` type label on the parent and every sub-issue, plus any approved relevant labels. Wait for explicit approval before proceeding.
24
+ 9. **Create in Linear** — once the user approves (or approves with changes), create the ticket in Linear using the Linear MCP tools. For sub-issues, create parent first, then children linked to it. Apply the resolved labels and any confirmed metadata. NEVER create without user approval.
25
25
 
26
26
  ## Final Validation Checklist
27
27
 
28
- Before drafting, verify ALL of these. If any fail, bounce back to `interview-feature` or ask the user directly:
28
+ This gate checks the INPUTS before drafting (the Red Flags table below checks the DRAFT after writing). Verify ALL of these. If any fail, bounce back to `interview-feature` or ask the user directly:
29
29
 
30
30
  | Check | Fail condition |
31
31
  | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -46,11 +46,13 @@ Before drafting, verify ALL of these. If any fail, bounce back to `interview-fea
46
46
  - **Never invent.** If a detail isn't established from the user, research, or conversation, it doesn't go in the ticket. Period.
47
47
  - **Approval required.** Always present the draft for user review first. Only create the ticket in Linear after the user explicitly approves.
48
48
  - **Always document the repository.** Every ticket must specify which repo the work belongs in. If the feature spans multiple repos, flag this — it likely needs separate tickets.
49
+ - **Always label by type.** Every feature ticket (and each sub-issue) carries the `feature` type label (or the team's closest equivalent — never invent or create a label without the user's say-so). Also suggest relevant team labels for approval. See Labels.
50
+ - **Always ask for team/assignee.** Never guess — ask the user.
49
51
  - **Feature requests only.** Redirect bug reports to `write-bug-ticket`, tech debt to `write-tech-debt-ticket`.
50
52
 
51
53
  ## Ticket Format
52
54
 
53
- **Title:** Short, imperative, describes the CAPABILITY — not the implementation. Under 70 characters.
55
+ **Title:** Short, imperative, describes the CAPABILITY — not the implementation. Under 70 characters. No bracket prefixes.
54
56
 
55
57
  **Repository:** Always include the repository name in the ticket body. Run `git remote get-url origin | sed 's/\.git$//' | sed 's/.*[:/]\([^/]*\/[^/]*\)$/\1/'` to get the `org/repo` name. For simple features, include as a bold inline label at the end. For complex features, include in `## Context`.
56
58
 
@@ -68,5 +70,36 @@ Sections as needed:
68
70
  **Sub-issues** (when decomposed):
69
71
  Each sub-issue follows the same format. Note blocking relationships (e.g., "_Blocked by: [sub-issue title]_").
70
72
 
71
- **For self-review anti-patterns**, see [red-flags.md](red-flags.md).
72
- **For ticket examples** (good and bad), see [examples.md](examples.md).
73
+ See reference.md for full examples (good and bad).
74
+
75
+ ## Labels
76
+
77
+ Every ticket gets its type label plus any relevant team labels. Labels are presented in the metadata block and applied when the user approves the ticket.
78
+
79
+ **Resolving labels requires the target team.** `list_issue_labels` is team-scoped, so confirm the team (the "Present for review" step) before resolving — suggest the type label by name up front, then resolve it against the team's actual label set once the team is known.
80
+
81
+ 1. **Type label (mandatory).** Fetch the target team's labels (Linear MCP `list_issue_labels` for that team) and apply the one denoting a feature: `feature` if it exists, otherwise the closest existing equivalent (e.g. `feature-request`). Match case-insensitively and accept grouped variants. If no reasonable match exists, ask the user which label to use — NEVER invent a label or create a new one without the user's say-so.
82
+ 2. **Relevant labels (suggested).** Review the team's other labels (e.g. `product-area`, area) and suggest those that fit this ticket. Apply them only on approval.
83
+ 3. **Sub-issues.** Each sub-issue carries the same `feature` type label as the parent, plus its own relevant labels.
84
+
85
+ ## Red Flags — Self-Review Before Presenting
86
+
87
+ This table checks the DRAFT after writing (the Final Validation Checklist above gates the inputs before drafting). If any row applies, fix before presenting.
88
+
89
+ | Anti-Pattern | Fix |
90
+ | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
91
+ | "Proposed Solution" section ("Add a toggle to settings") | DELETE the section entirely — describe only the problem and desired outcome |
92
+ | Technical suggestions in body ("Use Redis for caching") | Remove — describe the need, not the solution |
93
+ | Implementation steps as AC ("Add a column to the table") | Rewrite as what the user can do or observe |
94
+ | Internal system behavior as AC ("The cron job skips...") | Rewrite from user perspective — every AC must pass: "Could a non-engineer verify this?" |
95
+ | Implementation constraints as AC ("Persisted at workplace level") | Remove — this is an implementation detail |
96
+ | Vague problem statement ("Improve search") | Add who is affected, what they can't do, why it matters |
97
+ | Solution-shaped title ("Add GraphQL endpoint for shifts") | Rewrite as the capability: "Allow filtering shifts by..." |
98
+ | Code references in body ("Modify `DailyNotificationCronJob`") | Remove all code references — describe the behavior change from the user's perspective |
99
+ | Parroting technical input (user says "field X", ticket says it) | Translate to user-facing language — the ticket reader shouldn't need to know the codebase |
100
+ | Invented details | Remove — if the detail is needed, bounce back to the interview skill |
101
+ | No decomposition for multi-outcome work | Split into parent + sub-issues, each describing one deliverable outcome |
102
+ | Bracket title prefixes | Describe the capability without brackets |
103
+ | Guessed team assignment | Ask the user — never guess |
104
+ | Missing repository | Include repo name in ticket body — derive from git remote |
105
+ | No `feature` type label | Always apply it (or the team's closest equivalent), on the parent and every sub-issue |
@@ -1,8 +1,10 @@
1
- # Ticket Examples
1
+ # Feature Ticket Reference
2
2
 
3
- Based on real ticket TG-3228 to show the contrast.
3
+ ## Examples
4
4
 
5
- ## What NOT to write (anti-pattern)
5
+ Based on real ticket TG-3228 to show the contrast. Headings inside these examples are deepened to nest within this document — real tickets use the `##` sections specified in SKILL.md.
6
+
7
+ ### What NOT to Write
6
8
 
7
9
  > **Title:** Disable Interview List (Daily Digest) Per Workplace
8
10
  >
@@ -10,7 +12,7 @@ Based on real ticket TG-3228 to show the contrast.
10
12
 
11
13
  This prescribes implementation (field names, specific cron job, migration strategy) and mixes what with how.
12
14
 
13
- ## Simple Ticket
15
+ ### Simple Ticket
14
16
 
15
17
  **Title:** Allow workplaces to disable the daily interview digest
16
18
 
@@ -24,15 +26,15 @@ Workplaces using phone interviews receive a daily interview digest email that is
24
26
 
25
27
  **Repository:** ClipboardHealth/core-utils
26
28
 
27
- ## Complex Ticket (with sub-issues)
29
+ ### Complex Ticket (with sub-issues)
28
30
 
29
31
  **Parent — Title:** Allow workplaces to disable the daily interview digest
30
32
 
31
- ### Problem
33
+ #### Problem
32
34
 
33
35
  Workplaces using phone interviews receive a daily interview digest email that isn't relevant to their workflow. There is no way to turn it off — the digest is sent to all workplaces regardless of their interview type. Employee admins need a way to control this per workplace.
34
36
 
35
- ### Acceptance Criteria
37
+ #### Acceptance Criteria
36
38
 
37
39
  - [ ] An employee admin can enable or disable the daily interview digest for a workplace
38
40
  - [ ] The digest is not sent to workplaces that have it disabled
@@ -40,16 +42,16 @@ Workplaces using phone interviews receive a daily interview digest email that is
40
42
  - [ ] When a workplace switches to phone interviews, the digest is automatically disabled
41
43
  - [ ] Only employee admins can change this setting (not workplace admins)
42
44
 
43
- ### Context
45
+ #### Context
44
46
 
45
47
  **Repository:** ClipboardHealth/core-utils
46
48
 
47
- ### Scope
49
+ #### Scope
48
50
 
49
51
  - **In:** Per-workplace toggle, auto-disable for phone interview workplaces
50
52
  - **Out:** Per-user digest preferences, other notification types
51
53
 
52
- ### Sub-issues
54
+ #### Sub-issues
53
55
 
54
56
  **Sub-issue 1 — Title:** Support per-workplace interview digest control
55
57
 
@@ -75,4 +77,4 @@ Employee admins need a way to manually enable or disable the daily interview dig
75
77
  - [ ] The toggle is not visible to non-employee-admin roles
76
78
  - [ ] The toggle reflects the current state of the setting
77
79
 
78
- **Suggested metadata:** Priority: Medium | Team: Team Gaia
80
+ Suggested metadata: Priority: Medium | Labels: feature (type), Knock / Notifications (relevant) — applied to the parent and each sub-issue
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: write-tech-debt-ticket
3
- description: Use when creating a Linear tech debt ticket while working in the codebase — from code review, PR comments, codebase audits, or post-incident findings. Expects deep technical context; classifies debt, assesses interest/risk with evidence, and justifies impact.
3
+ description: Use when creating a Linear tech debt ticket while working in the codebase — from code review, PR comments, codebase audits, or post-incident findings.
4
4
  ---
5
5
 
6
6
  # Write Tech Debt Ticket
@@ -15,16 +15,18 @@ Draft Linear tech debt tickets that justify _why_ the debt matters — cost to c
15
15
 
16
16
  1. **Gather context** — from code, PR comment, conversation, or audit. Note how the debt was discovered (see Discovery Context below).
17
17
  2. **Analyze the code** — read the actual code. Understand what it does and why it qualifies as debt.
18
- 3. **Classify** — pick a primary debt type (and optional secondary) from classification table in reference.md
18
+ 3. **Classify** — pick a primary debt type (and optional secondary) from the debt types table in reference.md
19
19
  4. **Gather evidence** (driven by classification):
20
20
  - Performance/Scalability/Reliability → search Datadog (NOT optional for these types)
21
21
  - Maintainability/DX → `git log` for change frequency and bug-fix commits, grep for workarounds
22
22
  - Security → check dependency versions, scan for vulnerability patterns
23
23
  5. **Assess interest & risk** — produce structured ratings with evidence (see reference.md for rating framework)
24
- 6. **Draft** — title + description, structure scaled to complexity (see format below)
25
- 7. **Self-review** — check every Red Flag below before presenting
26
- 8. **Present for review** — show ONLY the draft and metadata suggestions. Ask for team/assignee.
27
- 9. **Create in Linear** — only after explicit approval. Apply `technical-debt` label.
24
+ 6. **Clarify (conditional)** — if blast radius, business impact, or ownership can't be determined from code or data, ask the user before drafting. NEVER invent answers.
25
+ 7. **Draft** — title + description, structure scaled to complexity (see format below)
26
+ 8. **Self-review** — check every Red Flag below before presenting
27
+ 9. **Present for review** — show ONLY the draft and metadata suggestions. Ask for team/assignee.
28
+ 10. **Resolve labels** — always include the `technical-debt` type label, plus any relevant team labels (see Labels below).
29
+ 11. **Create in Linear** — only after explicit approval. Apply the resolved labels.
28
30
 
29
31
  ## Hard Rules
30
32
 
@@ -38,6 +40,8 @@ Draft Linear tech debt tickets that justify _why_ the debt matters — cost to c
38
40
  - **Never invent.** Every claim must be backed by code you read, data you found, or context from the conversation. If you can't find evidence for an assertion, don't include it — even if it seems plausible.
39
41
  - **One ticket, one concern.** If the debt spans multiple independent problems (e.g., a performance issue AND a maintainability issue in the same service), split into separate tickets — each with its own classification, evidence, and impact. Related debt can reference each other.
40
42
  - **Always document the repository.** Flag multi-repo debt to the user for splitting.
43
+ - **Approval required.** Always present the draft for user review first. Only create the ticket in Linear after the user explicitly approves.
44
+ - **Always label by type.** Every tech debt ticket carries the `technical-debt` type label (or the team's closest equivalent — never invent or create a label without the user's say-so). Also suggest relevant team labels for approval. See Labels.
41
45
  - **Redirect non-debt.** Bugs → `write-bug-ticket`, features → `write-feature-ticket`.
42
46
 
43
47
  ## Ticket Format
@@ -52,9 +56,18 @@ Draft Linear tech debt tickets that justify _why_ the debt matters — cost to c
52
56
 
53
57
  **Complex debt** (multi-file, systemic, high-stakes): Use `## What Is The Debt` (include repository), `## Discovery Context` (if applicable — originating ticket/PR and how the work revealed the debt), `## Debt Classification` (type + rated interest/risk with justifications), `## Code References`, `## Evidence`, `## Ideal State` (destination, not route), `## Impact If Left Unaddressed`.
54
58
 
55
- **Metadata:** Priority, labels (`technical-debt`), presented BELOW the body. Always ask for team/assignee.
59
+ **Metadata:** Priority, labels (`technical-debt` type label + approved relevant labels, see Labels), presented BELOW the body. Always ask for team/assignee.
56
60
 
57
- See reference.md for classification tables, rating framework, and full examples.
61
+ See reference.md for the debt types table, rating framework, and full examples.
62
+
63
+ ## Labels
64
+
65
+ Every ticket gets its type label plus any relevant team labels. Labels are presented in the metadata block and applied when the user approves the ticket.
66
+
67
+ **Resolving labels requires the target team.** `list_issue_labels` is team-scoped, so confirm the team (the "Present for review" step) before resolving — suggest the type label by name up front, then resolve it against the team's actual label set once the team is known.
68
+
69
+ 1. **Type label (mandatory).** Fetch the target team's labels (Linear MCP `list_issue_labels` for that team) and apply the one denoting tech debt: `technical-debt` if it exists, otherwise the closest existing equivalent. Match case-insensitively and accept grouped variants. If no reasonable match exists, ask the user which label to use — NEVER invent a label or create a new one without the user's say-so.
70
+ 2. **Relevant labels (suggested).** Review the team's other labels (e.g. `product-area`, area, severity) and suggest those that fit this ticket. Apply them only on approval.
58
71
 
59
72
  ## Red Flags — Self-Review Before Presenting
60
73
 
@@ -70,6 +83,7 @@ See reference.md for classification tables, rating framework, and full examples.
70
83
  | No "Impact If Left Unaddressed" | Always include — this gets the ticket prioritized |
71
84
  | No Datadog for perf/reliability | You MUST search Datadog for these types |
72
85
  | Forced Datadog on maintainability | Only for performance/reliability/scalability |
73
- | Guessed team assignment | Ask the user |
86
+ | Guessed team assignment | Ask the user — never guess |
74
87
  | Missing repository | Include repo name in ticket body — derive from git remote |
75
88
  | Missing discovery context | If debt was found during ticket/PR work, link it |
89
+ | No `technical-debt` type label | Always apply it (or the team's closest equivalent) |
@@ -1,6 +1,6 @@
1
1
  # Tech Debt Ticket Reference
2
2
 
3
- ## Debt Classification
3
+ ## Debt Types
4
4
 
5
5
  | Type | Description | Evidence to Gather |
6
6
  | ------------------------ | ---------------------------------------------------- | ------------------------------------------------ |
@@ -33,6 +33,8 @@ Each: High/Medium/Low with a one-line justification backed by evidence.
33
33
 
34
34
  ## Examples
35
35
 
36
+ Headings inside these examples are deepened to nest within this document — real tickets use the `##` sections specified in SKILL.md.
37
+
36
38
  ### Simple Tech Debt Ticket
37
39
 
38
40
  **Title:** Shift matching query scans full collection on every request
@@ -65,7 +67,7 @@ Four cron jobs (`DailyDigestCron`, `ShiftReminderCron`, `CredentialExpiryCron`,
65
67
 
66
68
  Discovered while implementing push notification support for [ENG-3891](https://linear.app/clipboard-health/issue/ENG-3891). Adding the new channel required duplicating dispatch logic into a fifth cron job, revealing the extent of the divergence.
67
69
 
68
- #### Classification
70
+ #### Debt Classification
69
71
 
70
72
  - **Type:** Maintainability (primary), Reliability (secondary)
71
73
  - **Interest:** High — 11 commits across these 4 files in the last 90 days, 6 were bug fixes. Each fix required checking whether the same bug existed in the other three. Two workaround functions exist in `src/services/notifications/helpers.ts` solely to normalize behavior.
@@ -93,4 +95,4 @@ A single notification dispatch service handles recipient resolution, template se
93
95
 
94
96
  Every new notification type or channel requires duplicating logic in 4 places. Bug fixes remain whack-a-mole — every fix is 4x the work and still risks inconsistency. At current rate (~2 notification bugs/month), engineering cost compounds and reliability divergence widens.
95
97
 
96
- Suggested metadata: Priority: Medium | Labels: tech-debt, notifications
98
+ Suggested metadata: Priority: Medium | Labels: technical-debt, notifications
@@ -1,18 +0,0 @@
1
- # Red Flags — Self-Review Before Presenting
2
-
3
- Check every row before showing the draft to the user. If any apply, fix before presenting.
4
-
5
- | Anti-Pattern | Example | Fix |
6
- | --------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
7
- | "Proposed Solution" section | "Add a toggle to the settings panel" | DELETE the section entirely. Describe only the problem and desired outcome. |
8
- | Technical suggestions in body | "Use Redis for caching" | Remove — describe the need, not the solution |
9
- | Implementation steps as AC | "Add a column to the table" | Rewrite as what the user can do or observe |
10
- | Internal system behavior as AC | "The cron job skips workplaces where...", "The API exposes a setting that..." | Rewrite from user perspective: "Workplaces with X disabled do not receive..." Every AC must pass the test: "Could a non-engineer verify this?" |
11
- | Implementation constraints as AC | "Setting is persisted at workplace level" | Remove — this is an implementation detail |
12
- | Vague problem statement | "Improve search" | Add who is affected, what they can't do, why it matters |
13
- | Solution-shaped title | "Add GraphQL endpoint for shifts" | Rewrite as the capability: "Allow filtering shifts by..." |
14
- | Code references in body | "Modify `DailyNotificationCronJob`" | Remove all code references. Describe the behavior change from the user's perspective. |
15
- | Parroting technical input | User says "field X", ticket says "field X" | Translate to user-facing language. The ticket reader shouldn't need to know the codebase. |
16
- | Invented details | Plausible-sounding claims not from conversation or research | Remove. If the detail is needed, bounce back to the interview skill. |
17
- | No decomposition for multi-outcome work | Two independent user-facing outcomes in one ticket | Split into parent + sub-issues, each describing one deliverable outcome |
18
- | Missing repository | No repo specified in ticket body | Include repo name — derive from git remote |