@clipboard-health/ai-rules 2.29.8 β†’ 2.29.10

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.8",
3
+ "version": "2.29.10",
4
4
  "description": "Pre-built AI agent rules for consistent coding standards.",
5
5
  "keywords": [
6
6
  "ai",
@@ -27,9 +27,9 @@ This skill always runs exactly one pass. It never waits or repeats internally. F
27
27
 
28
28
  The skill uses two sentinels. Each is a visible footer line wrapped in `<sub>` (a πŸ€– mark plus the token in `<code>`).
29
29
 
30
- **Addressed sentinel**: `<sub>πŸ€– <code>babysit-pr:addressed v1 core@3.9.0</code></sub>`. Appended on its own line at the end of every reply the skill posts (both thread replies and the review-body summary); this is how re-runs know which threads and review-body comments are already handled. Dedupe matches the version-agnostic substring `babysit-pr:addressed v1` followed by a space (also matches legacy `<!-- babysit-pr:addressed v1 ... -->` sentinels). Grep `babysit-pr:addressed v1` for any version; add `core@3.9.0` for a specific one.
30
+ **Addressed sentinel**: `<sub>πŸ€– <code>babysit-pr:addressed v1 core@3.10.1</code></sub>`. Appended on its own line at the end of every reply the skill posts (both thread replies and the review-body summary); this is how re-runs know which threads and review-body comments are already handled. Dedupe matches the version-agnostic substring `babysit-pr:addressed v1` followed by a space (also matches legacy `<!-- babysit-pr:addressed v1 ... -->` sentinels). Grep `babysit-pr:addressed v1` for any version; add `core@3.10.1` for a specific one.
31
31
 
32
- **Follow-up sentinel**: `<sub>πŸ€– <code>babysit-pr:followup v1 core@3.9.0</code></sub>`. Attached to replies that defer an out-of-scope comment as a tracked follow-up (see the Scope subsection and the Defer verdict in step 6). Grep `babysit-pr:followup` across PR conversation JSON to enumerate deferred items. This sentinel is additive β€” the post-reply scripts still append the `addressed` sentinel at the end, so a deferred thread is correctly machine-classified as addressed (the skill _has_ handled it β€” by deferring). Human reviewers and future sweeps distinguish deferred from resolved by looking for the follow-up sentinel.
32
+ **Follow-up sentinel**: `<sub>πŸ€– <code>babysit-pr:followup v1 core@3.10.1</code></sub>`. Attached to replies that defer an out-of-scope comment as a tracked follow-up (see the Scope subsection and the Defer verdict in step 6). Grep `babysit-pr:followup` across PR conversation JSON to enumerate deferred items. This sentinel is additive β€” the post-reply scripts still append the `addressed` sentinel at the end, so a deferred thread is correctly machine-classified as addressed (the skill _has_ handled it β€” by deferring). Human reviewers and future sweeps distinguish deferred from resolved by looking for the follow-up sentinel.
33
33
 
34
34
  **Sentinel recency rules.** The script emits a per-thread `activityState` with three values:
35
35
 
@@ -280,7 +280,7 @@ Body templates (the script appends the `addressed` sentinel if missing):
280
280
  - **Agree**: `Addressed in <commit-url>. <one-line what-changed>.`
281
281
  - **Disagree**: `Leaving current behavior. <reasoning>.`
282
282
  - **Already fixed**: `Already handled by <commit-url-or-file:line>. <brief pointer>.`
283
- - **Defer**: `Out of scope for this PR; this looks like follow-up work rather than something introduced or required by this change. <one-line rationale or pointer if useful>.\n\n<sub>πŸ€– <code>babysit-pr:followup v1 core@3.9.0</code></sub>`
283
+ - **Defer**: `Out of scope for this PR; this looks like follow-up work rather than something introduced or required by this change. <one-line rationale or pointer if useful>.\n\n<sub>πŸ€– <code>babysit-pr:followup v1 core@3.10.1</code></sub>`
284
284
 
285
285
  For Defer replies, include the follow-up sentinel on its own line as shown. The script will append the `addressed` sentinel after it on its own line, so the final body ends with the follow-up sentinel followed by a blank line followed by the `addressed` sentinel β€” `grep babysit-pr:followup` finds the deferral and `grep babysit-pr:addressed` still marks the thread handled for dedupe.
286
286
 
@@ -296,7 +296,7 @@ The PR-level summary should:
296
296
 
297
297
  - Group by source. Use `## Review-body findings` for step-7 work and `## Conversation-tab comments` for step-6b work. Omit a section if its list is empty.
298
298
  - Inside each section, group verdicts under **Agree / Disagree / Already fixed / Deferred (out of scope)** subheadings. Omit a subheading if its list is empty.
299
- - Under **Deferred (out of scope)**, list each deferred item as a bullet, followed on its own line by `<sub>πŸ€– <code>babysit-pr:followup v1 core@3.9.0</code></sub>` so grep catches them individually.
299
+ - Under **Deferred (out of scope)**, list each deferred item as a bullet, followed on its own line by `<sub>πŸ€– <code>babysit-pr:followup v1 core@3.10.1</code></sub>` so grep catches them individually.
300
300
  - Include the commit URL for fixes.
301
301
  - End with a fenced fingerprint block listing every current fingerprint β€” addressed and deferred β€” one per line. Include both `reviewBodyComments[].fingerprint` (whole-body, one per automated review) and `activeIssueComments[].fingerprint` (per Conversation-tab comment). Future runs dedupe by matching these against `priorBabysitSentinels`.
302
302
 
@@ -9,7 +9,7 @@
9
9
  # substituted at build time by embedPluginVersion.mts.
10
10
 
11
11
  SENTINEL_PREFIX='babysit-pr:addressed v1 '
12
- SENTINEL='<sub>πŸ€– <code>babysit-pr:addressed v1 core@3.9.0</code></sub>'
12
+ SENTINEL='<sub>πŸ€– <code>babysit-pr:addressed v1 core@3.10.1</code></sub>'
13
13
 
14
14
  # Bot author allowlist (JSON array literal). Used by unresolvedPrComments.sh
15
15
  # as a fallback when GraphQL's `author.__typename == "Bot"` misses a GitHub
@@ -47,7 +47,7 @@ Script paths in this procedure are written as `scripts/...`, relative to this SK
47
47
  6. Check for an existing PR with `gh pr view`.
48
48
 
49
49
  PR title format: conventional-commit type + description, with no scope, plus the Linear ticket in parentheses at the end when one applies (e.g., `feat: add resume command (STAFF-123)`). This differs from the commit subject, which keeps its scope. Derive the ticket from the branch name, commit body, or session context; omit the parenthetical when no ticket applies.
50
- - No PR: create with `gh pr create` using the PR title format above. Description = the PR body shape above, followed by the session footer line if known and the agent footer `<sub>πŸ€– <code>commit-push-pr:created v1 core@3.9.0</code></sub>` on its own line.
51
- - PR exists: if the title doesn't match the format above, correct it with `gh pr edit --title`. Refresh the body via `gh pr edit --body` so (a) the new commit's changes are reflected in the prose while existing `## Summary`, `## Validation`, and `## Notes` sections are preserved unless clearly stale, (b) any known session footer line is appended if missing, never removing or rewriting existing `Agent session: ...` or `Agent session ID: ...` lines, and (c) any existing footer carrying the substring `commit-push-pr:created v1` is preserved verbatim, appending `<sub>πŸ€– <code>commit-push-pr:created v1 core@3.9.0</code></sub>` only if absent. Then report the URL.
50
+ - No PR: create with `gh pr create` using the PR title format above. Description = the PR body shape above, followed by the session footer line if known and the agent footer `<sub>πŸ€– <code>commit-push-pr:created v1 core@3.10.1</code></sub>` on its own line.
51
+ - PR exists: if the title doesn't match the format above, correct it with `gh pr edit --title`. Refresh the body via `gh pr edit --body` so (a) the new commit's changes are reflected in the prose while existing `## Summary`, `## Validation`, and `## Notes` sections are preserved unless clearly stale, (b) any known session footer line is appended if missing, never removing or rewriting existing `Agent session: ...` or `Agent session ID: ...` lines, and (c) any existing footer carrying the substring `commit-push-pr:created v1` is preserved verbatim, appending `<sub>πŸ€– <code>commit-push-pr:created v1 core@3.10.1</code></sub>` only if absent. Then report the URL.
52
52
 
53
53
  7. End with one short text response: branch name and the full PR URL (e.g., `https://github.com/clipboardhealth/core-utils/pull/123`). Never use shorthand like `repo#123` β€” always output the complete URL.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: humanize-prose
3
+ description: Strip AI writing tells from prose you draft or clean: PR descriptions, Slack messages, docs, emails, commit messages. Cuts hedging, throat-clearing, marketing adjectives, bullet bloat, connective filler, and em-dashes. Use whenever the user asks to "humanize" text, "remove the AI slop" from writing, "make this not sound AI-generated", "deslop this PR description", or runs /humanize-prose. Also applies implicitly: any prose you draft for the user must already satisfy these rules.
4
+ ---
5
+
6
+ # Humanize prose
7
+
8
+ Strip AI writing tells out of prose, whether cleaning existing text or generating it. Edit in place, change as little as possible, preserve meaning. When a change would alter meaning, or you cannot tell which of two conflicting statements is correct, leave it and flag it.
9
+
10
+ Applies to PR descriptions, Slack messages, docs, and emails.
11
+
12
+ Cut:
13
+
14
+ - Throat-clearing openers: "In this PR, I've...", "This change introduces...", "I wanted to...".
15
+ - Hedging filler: "it's worth noting", "it's important to", "generally speaking", "as you may know".
16
+ - Marketing adjectives and trendy intensifiers: robust, seamless, comprehensive, powerful, leverage, streamline, delve, load-bearing.
17
+ - Rule-of-three padding and restating the obvious.
18
+ - Connective tissue that links sentences without adding content: "That said", "With that in mind", "To that end", "As such", "Moreover", "Furthermore", "Additionally", "It follows that". Drop the phrase or replace it with a full stop.
19
+ - Duplicated information: a point already made earlier in different words, a closing line that repeats the opening, a sentence that restates its own heading. Keep it once.
20
+ - Contradictory information: two statements in the same text that conflict (a number, a claim, or a recommendation stated one way then another). Keep the version that is correct and flag the contradiction; do not silently pick one if you cannot tell which is right.
21
+ - Bullet bloat where two sentences of prose are tighter; bold-everything formatting.
22
+ - Summary-of-the-summary closers: "In conclusion...", "Overall, this...".
23
+ - Em-dashes and double hyphens (use a comma, colon, or full stop instead).
24
+
25
+ Keep it concrete: what changed, why, what to check. Match the channel (a PR body is not a Slack one-liner).
26
+
27
+ ```text
28
+ slop: In this PR, I've made some changes to refactor the billing service. It's
29
+ worth noting this is a fairly comprehensive update that should make the
30
+ code more robust and maintainable.
31
+ clean: Refactors the billing service: extracts charge calculation into
32
+ ChargeCalculator and removes the duplicated rounding logic.
33
+ ```
34
+
35
+ Commit messages still follow Conventional Commits 1.0.
36
+
37
+ ## Output
38
+
39
+ Make edits silently, without narrating each change. End with a 1-3 sentence summary of what categories you cut and anything you left in place and flagged (a contradiction you could not resolve). Nothing else.
@@ -131,7 +131,7 @@ Every finding **must** include a `failure_mode`: one sentence on the concrete us
131
131
 
132
132
  ### Do-not-raise list (binding)
133
133
 
134
- - Speculative defensiveness at trusted internal boundaries.
134
+ - Speculative defensiveness at trusted internal boundaries (only where the boundary's guarantee is actually _enforced_ β€” a declared or cast type is not enforcement; see AntiSlop).
135
135
  - Restating the obvious ("consider a comment explaining what this does").
136
136
  - Hypothetical future-caller scenarios with no current caller.
137
137
  - Style/formatting a linter or formatter covers.
@@ -150,6 +150,8 @@ For every candidate finding, run the litmus test before keeping it: _"What is th
150
150
 
151
151
  For each change name a realistic input or condition that would expose a bug. If you cannot, do not raise it.
152
152
 
153
+ - **Declared β‰  enforced β€” check what actually guarantees a precondition.** When new code performs an operation that faults on a missing or malformed input (destructuring, property/array access, non-null assertion, iteration, parsing, arithmetic), do not accept a declared type, function signature, cast, or `as` as proof the input is safe β€” those _label_ a value, they don't _check_ it. Ask what enforces the precondition on this path: a runtime validator, a preceding explicit check, or a constructor/factory invariant. If nothing does, trace the value to its origin β€” it can fault on real data even though it compiles. Look at the operation that would actually throw, not only the named field beside it.
154
+ - **Asymmetric handling across sibling call sites is a likely bug, not a style nit.** When the diff guards, validates, converts, or error-wraps a value in one place but consumes the same value or shape bare elsewhere, exactly one side is usually right. Compare the call sites against each other instead of reviewing each in isolation, and resolve the inconsistency: guard missing where it's absent β†’ bug; guard unnecessary everywhere β†’ slop to remove.
153
155
  - Edge cases, error paths, observability of real failure modes.
154
156
  - Tests cover real risk, not lines.
155
157
  - Concurrency, performance at real scale, data integrity.
@@ -212,7 +214,7 @@ Tag every convention finding with `[CONVENTION]` in the title. Cap severity at M
212
214
 
213
215
  This PR may have been written or assisted by an LLM. For each addition, ask: _"Is this line earning its keep, or is it pattern-matching what code is supposed to look like?"_ Push back on what other lenses are too polite to flag. Apply to additions **inside the diff itself**.
214
216
 
215
- - **Defensive code at trusted internal boundaries.** Null guards on private helpers whose callers' types guarantee non-null; `try`/`catch` wrapping a single non-throwing call, or that re-throws unchanged, or that "logs and swallows" without naming what to do next; optional-chaining through types that don't include optionality.
217
+ - **Defensive code at trusted internal boundaries.** Null guards on private helpers whose callers' types guarantee non-null; `try`/`catch` wrapping a single non-throwing call, or that re-throws unchanged, or that "logs and swallows" without naming what to do next; optional-chaining through types that don't include optionality. **But "trusted" means the guarantee is _enforced_** β€” by a validator on this path, a constructor/factory invariant, or a preceding check you can point to. A type, signature, cast, or `as`/non-null-assertion only _asserts_ the guarantee; a guard backing a merely-asserted guarantee is load-bearing, not slop. Confirm what enforces the type at the call site before flagging the guard.
216
218
  - **Defensiveness against unrealistic product scenarios.** Litmus: _"In the real product flow this code participates in, what user action / system event / upstream call could land us in this branch?"_ If the answer is "none" or "I had to invent one to justify the guard", it's slop. Concrete shapes:
217
219
  - Null/undefined guard on an ID immediately after that ID was used to load (and find) the entity.
218
220
  - A `null`/`undefined`/`""`/`0` branch on a field whose TypeScript or Zod/class-validator already rejects those.
@@ -282,7 +284,7 @@ Does this follow our FE conventions, and will it behave correctly under realisti
282
284
  After walking the checklist, apply these filters to your candidate findings:
283
285
 
284
286
  1. **Drop findings with empty or hypothetical `failure_mode`.** "A future caller might…", "in case someone…" β†’ drop.
285
- 2. **Self-audit for slop.** For every finding you wrote, ask: does it match a slop pattern (asks-for-defensive-guard on already-narrowed value; hypothetical future caller; restating-obvious comment request; abstract refactor with no concrete cost-of-keeping; observability without named failure mode; test for trivially-verifiable code; defends against a state the product cannot produce)? If yes and you can't write a concrete, product-specific cost in one sentence β€” drop it. Being your own AntiSlop reviewer is the main lever for keeping this skill honest.
287
+ 2. **Self-audit for slop.** For every finding you wrote, ask: does it match a slop pattern (asks-for-defensive-guard on an already-narrowed value β€” but only if an _enforced_ check narrows it, not merely a declared type or cast (see Engineering's declared β‰  enforced); hypothetical future caller; restating-obvious comment request; abstract refactor with no concrete cost-of-keeping; observability without named failure mode; test for trivially-verifiable code; defends against a state the product cannot produce)? If yes and you can't write a concrete, product-specific cost in one sentence β€” drop it. Being your own AntiSlop reviewer is the main lever for keeping this skill honest.
286
288
  3. **Cross-repo audit.** For every finding, ask: does the failure_mode reference a downstream actor (FE, mobile, consumer service, rolling deploy, external library user) or a contract/schema/public-artifact boundary? If yes, did you actually read the relevant external file(s) to confirm the claim, or are you reasoning from priors about "how FEs usually work"? If you didn't read it, the finding is cross-repo β€” route to the Cross-repo evidence policy (verify, ask for access, or downgrade to a clearly-labeled "speculative" MINOR). Do not ship a "consumer will break" finding sourced from imagination.
287
289
  4. **Drop do-not-raise items** that slipped through.
288
290
  5. **Apply the NIT gate.** NITs that don't meet (a)/(b)/(c) β†’ drop. Kept internally but hidden by default in synthesis.
@@ -34,6 +34,9 @@ Review the same changes for hacky patterns:
34
34
  6. **Unnecessary JSX nesting**: wrapper Boxes/elements that add no layout value β€” check if inner component props (flexShrink, alignItems, etc.) already provide the needed behavior
35
35
  7. **Nested conditionals**: ternary chains (`a ? x : b ? y : ...`), nested if/else, or nested switch 3+ levels deep β€” flatten with early returns, guard clauses, a lookup table, or an if/else-if cascade
36
36
  8. **Unnecessary comments**: comments explaining WHAT the code does (well-named identifiers already do that), narrating the change, or referencing the task/caller β€” delete; keep only non-obvious WHY (hidden constraints, subtle invariants, workarounds)
37
+ 9. **Defensive code on trusted inputs**: null/empty/type guards on inputs already guaranteed upstream (a validated DTO, the type system, a controller that already checked), optional chaining where the types guarantee presence, fallbacks that mask bugs (`?? ''`, `|| []`, `?? 0` on values that should never be absent), and try/catch that only logs and rethrows or guards an impossible state. Leave guards at genuine trust boundaries (raw request bodies, webhook payloads, third-party responses) and any error handling around real I/O, network, parsing, or payments β€” removing those changes behavior
38
+ 10. **Type escapes**: `as any`, `: any`, `as unknown as X`, gratuitous non-null `!`, `@ts-ignore`/`@ts-expect-error` added to dodge a type error β€” replace with the real type when it is determinable from the call site, the imported type, or the shape in use; if it is not, leave it and flag it rather than deleting it (breaks the build) or swapping in a TODO (more clutter)
39
+ 11. **Leftover debug statements**: stray `console.log` or debug logging added during development
37
40
 
38
41
  ### Agent 3: Efficiency Review
39
42