@bompus/house-rules 0.0.0-stage → 0.11.0

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.
Files changed (191) hide show
  1. package/CONTRIBUTING.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +347 -2
  4. package/THIRD_PARTY_NOTICES.md +188 -0
  5. package/compose.mjs +119 -0
  6. package/composition.mjs +353 -0
  7. package/config-view.mjs +194 -0
  8. package/config.mjs +320 -0
  9. package/docs/assets/banner-dark.png +0 -0
  10. package/docs/assets/banner-light.png +0 -0
  11. package/docs/assets/overview.png +0 -0
  12. package/docs/configuration.md +193 -0
  13. package/docs/npm-release.md +45 -0
  14. package/docs/skill-names.md +50 -0
  15. package/examples/person/house-rules.json +15 -0
  16. package/examples/person/rules/10-tooling.md +8 -0
  17. package/examples/person/rules/20-reporting.md +9 -0
  18. package/examples/project/AGENTS.md +18 -0
  19. package/package.json +40 -4
  20. package/rule-references.mjs +91 -0
  21. package/rules/core.md +431 -0
  22. package/rules/modifiers/coded-offers.md +40 -0
  23. package/rules/modifiers/effort-estimates.md +41 -0
  24. package/rules/modifiers/land-when-done.md +12 -0
  25. package/rules/modifiers/low-quota-handoff.md +19 -0
  26. package/rules/modifiers/multi-agent.md +34 -0
  27. package/rules/modifiers/no-attribution.md +10 -0
  28. package/rules/modifiers/plan-files.md +50 -0
  29. package/rules/modifiers/question-cards.md +48 -0
  30. package/rules/modifiers/release-batching.md +13 -0
  31. package/rules/modifiers/scratch-on-disk.md +15 -0
  32. package/rules/modifiers/shared-host-load.md +48 -0
  33. package/rules/modifiers/solo-operator.md +13 -0
  34. package/rules/modifiers/squash-landing.md +22 -0
  35. package/rules/modifiers/swarmail.md +12 -0
  36. package/rules/references/github-actions.md +45 -0
  37. package/rules/references/landing.md +39 -0
  38. package/rules/references/multi-agent.md +47 -0
  39. package/rules/references/release-batching.md +43 -0
  40. package/rules/references/squash-landing.md +44 -0
  41. package/setup.mjs +375 -0
  42. package/skills/hr-agent-guidance-audit/LICENSE +21 -0
  43. package/skills/hr-agent-guidance-audit/SKILL.md +86 -0
  44. package/skills/hr-agent-guidance-audit/agents/openai.yaml +2 -0
  45. package/skills/hr-agent-guidance-audit/references/records-and-lessons.md +60 -0
  46. package/skills/hr-agent-guidance-refresh/LICENSE +21 -0
  47. package/skills/hr-agent-guidance-refresh/SKILL.md +68 -0
  48. package/skills/hr-agent-guidance-refresh/agents/openai.yaml +2 -0
  49. package/skills/hr-agent-guidance-refresh/references/verification.md +47 -0
  50. package/skills/hr-api-exposure-check/SKILL.md +159 -0
  51. package/skills/hr-api-exposure-check/agents/openai.yaml +3 -0
  52. package/skills/hr-audit-choices/SKILL.md +67 -0
  53. package/skills/hr-audit-choices/agents/openai.yaml +2 -0
  54. package/skills/hr-benchmarking/NOTICE.md +36 -0
  55. package/skills/hr-benchmarking/SKILL.md +316 -0
  56. package/skills/hr-benchmarking/agents/openai.yaml +2 -0
  57. package/skills/hr-benchmarking/references/javascript.md +17 -0
  58. package/skills/hr-benchmarking/references/priority-findings-20261006.md +115 -0
  59. package/skills/hr-benchmarking/references/tools.md +160 -0
  60. package/skills/hr-benchmarking/scripts/process-attribution.ps1 +20 -0
  61. package/skills/hr-benchmarking/scripts/process-attribution.py +107 -0
  62. package/skills/hr-better-accessibility/LICENSE +22 -0
  63. package/skills/hr-better-accessibility/NOTICE.md +46 -0
  64. package/skills/hr-better-accessibility/SKILL.md +119 -0
  65. package/skills/hr-better-accessibility/agents/openai.yaml +3 -0
  66. package/skills/hr-better-accessibility/focus-and-keyboard.md +130 -0
  67. package/skills/hr-better-accessibility/forms.md +82 -0
  68. package/skills/hr-better-accessibility/hit-areas.md +98 -0
  69. package/skills/hr-better-accessibility/motion-and-zoom.md +81 -0
  70. package/skills/hr-better-accessibility/screen-readers.md +101 -0
  71. package/skills/hr-better-accessibility/semantics-and-aria.md +84 -0
  72. package/skills/hr-better-colors/LICENSE +21 -0
  73. package/skills/hr-better-colors/NOTICE.md +37 -0
  74. package/skills/hr-better-colors/SKILL.md +114 -0
  75. package/skills/hr-better-colors/agents/openai.yaml +3 -0
  76. package/skills/hr-better-colors/color-formats.md +90 -0
  77. package/skills/hr-better-colors/color-usage.md +140 -0
  78. package/skills/hr-better-colors/contrast.md +80 -0
  79. package/skills/hr-better-colors/palette-generation.md +104 -0
  80. package/skills/hr-better-colors/palette-structure.md +76 -0
  81. package/skills/hr-better-colors/token-naming.md +97 -0
  82. package/skills/hr-better-layout/LICENSE +22 -0
  83. package/skills/hr-better-layout/NOTICE.md +48 -0
  84. package/skills/hr-better-layout/SKILL.md +92 -0
  85. package/skills/hr-better-layout/agents/openai.yaml +3 -0
  86. package/skills/hr-better-layout/grouping-and-alignment.md +144 -0
  87. package/skills/hr-better-layout/spacing-and-adaptivity.md +215 -0
  88. package/skills/hr-better-typography/LICENSE +22 -0
  89. package/skills/hr-better-typography/NOTICE.md +46 -0
  90. package/skills/hr-better-typography/SKILL.md +172 -0
  91. package/skills/hr-better-typography/agents/openai.yaml +3 -0
  92. package/skills/hr-better-typography/choosing-fonts.md +69 -0
  93. package/skills/hr-better-typography/css-cheat-sheet.md +65 -0
  94. package/skills/hr-better-typography/details-and-accessibility.md +119 -0
  95. package/skills/hr-better-typography/spacing-and-sizing.md +131 -0
  96. package/skills/hr-better-typography/variable-fonts-and-opentype.md +105 -0
  97. package/skills/hr-better-typography/wrapping-and-punctuation.md +57 -0
  98. package/skills/hr-better-writing/LICENSE +22 -0
  99. package/skills/hr-better-writing/NOTICE.md +46 -0
  100. package/skills/hr-better-writing/SKILL.md +122 -0
  101. package/skills/hr-better-writing/agents/openai.yaml +3 -0
  102. package/skills/hr-change-impact/SKILL.md +113 -0
  103. package/skills/hr-change-impact/agents/openai.yaml +5 -0
  104. package/skills/hr-code-review/LICENSE +21 -0
  105. package/skills/hr-code-review/NOTICE.md +26 -0
  106. package/skills/hr-code-review/SKILL.md +147 -0
  107. package/skills/hr-code-review/agents/openai.yaml +3 -0
  108. package/skills/hr-code-review/references/evidence.md +57 -0
  109. package/skills/hr-design-exploration/SKILL.md +82 -0
  110. package/skills/hr-design-exploration/agents/openai.yaml +4 -0
  111. package/skills/hr-diagnosing-bugs/NOTICE.md +45 -0
  112. package/skills/hr-diagnosing-bugs/SKILL.md +108 -0
  113. package/skills/hr-diagnosing-bugs/agents/openai.yaml +3 -0
  114. package/skills/hr-diagnosing-bugs/references/reporting.md +72 -0
  115. package/skills/hr-explain-code/NOTICE.md +37 -0
  116. package/skills/hr-explain-code/SKILL.md +110 -0
  117. package/skills/hr-explain-code/agents/openai.yaml +5 -0
  118. package/skills/hr-explain-code/references/helper-brief.md +39 -0
  119. package/skills/hr-extract-shared-steps/SKILL.md +134 -0
  120. package/skills/hr-extract-shared-steps/agents/openai.yaml +3 -0
  121. package/skills/hr-handoff/SKILL.md +91 -0
  122. package/skills/hr-handoff/agents/openai.yaml +5 -0
  123. package/skills/hr-handoff/assets/ledger.example.json +10 -0
  124. package/skills/hr-handoff/assets/receipt.example.json +76 -0
  125. package/skills/hr-handoff/assets/source.example.json +20 -0
  126. package/skills/hr-handoff/references/reconciliation.md +105 -0
  127. package/skills/hr-handoff/scripts/check-reconciliation.mjs +282 -0
  128. package/skills/hr-house-rules-setup/SKILL.md +100 -0
  129. package/skills/hr-house-rules-setup/agents/openai.yaml +5 -0
  130. package/skills/hr-issue-tracker-setup/SKILL.md +49 -0
  131. package/skills/hr-issue-tracker-setup/agents/openai.yaml +5 -0
  132. package/skills/hr-lean-plan/SKILL.md +142 -0
  133. package/skills/hr-lean-plan/agents/openai.yaml +5 -0
  134. package/skills/hr-maintainability-review/SKILL.md +176 -0
  135. package/skills/hr-maintainability-review/agents/openai.yaml +5 -0
  136. package/skills/hr-manual-qa/NOTICE.md +36 -0
  137. package/skills/hr-manual-qa/SKILL.md +37 -0
  138. package/skills/hr-manual-qa/agents/openai.yaml +3 -0
  139. package/skills/hr-navigation-retro/LICENSE +21 -0
  140. package/skills/hr-navigation-retro/NOTICE.md +5 -0
  141. package/skills/hr-navigation-retro/SKILL.md +86 -0
  142. package/skills/hr-navigation-retro/agents/openai.yaml +4 -0
  143. package/skills/hr-navigation-retro/references/inputs.md +67 -0
  144. package/skills/hr-navigation-retro/scripts/retro.py +552 -0
  145. package/skills/hr-navigation-retro/scripts/transcripts.py +205 -0
  146. package/skills/hr-ordering-tests/SKILL.md +51 -0
  147. package/skills/hr-ordering-tests/agents/openai.yaml +2 -0
  148. package/skills/hr-plain-prose/SKILL.md +261 -0
  149. package/skills/hr-plain-prose/agents/openai.yaml +3 -0
  150. package/skills/hr-plain-prose/scripts/check.mjs +331 -0
  151. package/skills/hr-pr-followup/LICENSE +21 -0
  152. package/skills/hr-pr-followup/NOTICE.md +9 -0
  153. package/skills/hr-pr-followup/SKILL.md +71 -0
  154. package/skills/hr-pr-followup/agents/openai.yaml +2 -0
  155. package/skills/hr-pr-followup/references/review-helpers.md +90 -0
  156. package/skills/hr-pr-followup/scripts/check-pr-review.ts +510 -0
  157. package/skills/hr-pr-followup/scripts/resolve-pr-thread.ts +219 -0
  158. package/skills/hr-progress-report/SKILL.md +49 -0
  159. package/skills/hr-progress-report/agents/openai.yaml +5 -0
  160. package/skills/hr-read-reddit/SKILL.md +44 -0
  161. package/skills/hr-read-reddit/agents/openai.yaml +2 -0
  162. package/skills/hr-read-reddit/scripts/reddit.ts +252 -0
  163. package/skills/hr-read-x-links/SKILL.md +42 -0
  164. package/skills/hr-read-x-links/agents/openai.yaml +2 -0
  165. package/skills/hr-read-x-links/scripts/x-post.ts +264 -0
  166. package/skills/hr-split-to-prs/LICENSE +21 -0
  167. package/skills/hr-split-to-prs/NOTICE.md +9 -0
  168. package/skills/hr-split-to-prs/SKILL.md +61 -0
  169. package/skills/hr-split-to-prs/agents/openai.yaml +2 -0
  170. package/skills/hr-stock-ui-audit/SKILL.md +132 -0
  171. package/skills/hr-stock-ui-audit/agents/openai.yaml +3 -0
  172. package/skills/hr-stock-ui-audit/scripts/scan.mjs +619 -0
  173. package/skills/hr-tdd/LICENSE +21 -0
  174. package/skills/hr-tdd/NOTICE.md +10 -0
  175. package/skills/hr-tdd/SKILL.md +40 -0
  176. package/skills/hr-tdd/agents/openai.yaml +3 -0
  177. package/skills/hr-tdd/mocking.md +39 -0
  178. package/skills/hr-tdd/tests.md +77 -0
  179. package/skills/hr-test-audit/SKILL.md +146 -0
  180. package/skills/hr-test-audit/agents/openai.yaml +3 -0
  181. package/skills/hr-test-audit/scripts/floor-guard.ts +137 -0
  182. package/skills/hr-what-next/SKILL.md +61 -0
  183. package/skills/hr-what-next/agents/openai.yaml +4 -0
  184. package/skills/hr-what-next/references/reporting.md +68 -0
  185. package/skills/hr-writing-for-agents/NOTICE.md +46 -0
  186. package/skills/hr-writing-for-agents/SKILL-MECHANICS.md +83 -0
  187. package/skills/hr-writing-for-agents/SKILL.md +108 -0
  188. package/skills/hr-writing-for-agents/agents/openai.yaml +3 -0
  189. package/skills/hr-writing-pr/NOTICE.md +48 -0
  190. package/skills/hr-writing-pr/SKILL.md +104 -0
  191. package/skills/hr-writing-pr/agents/openai.yaml +2 -0
@@ -0,0 +1,39 @@
1
+ # When to mock
2
+
3
+ Mock at **system boundaries** only:
4
+
5
+ - External APIs (payment, email, etc.)
6
+ - Databases (sometimes; prefer a test DB)
7
+ - Time/randomness
8
+ - File system (sometimes)
9
+
10
+ Don't mock:
11
+
12
+ - Your own classes/modules
13
+ - Internal collaborators
14
+ - Anything you control
15
+
16
+ ## Designing for mockability
17
+
18
+ At system boundaries, design interfaces that are easy to mock:
19
+
20
+ **1. Use dependency injection**
21
+
22
+ Pass external dependencies in rather than creating them internally:
23
+
24
+ ```typescript
25
+ // Easy to mock
26
+ function processPayment(order, paymentClient) {
27
+ return paymentClient.charge(order.total);
28
+ }
29
+
30
+ // Hard to mock
31
+ function processPayment(order) {
32
+ const client = new StripeClient(process.env.STRIPE_KEY);
33
+ return client.charge(order.total);
34
+ }
35
+ ```
36
+
37
+ **2. Reuse production interfaces**
38
+
39
+ Prefer existing operation-specific APIs when they serve production callers. Otherwise mock the transport boundary; request routing in a fake is acceptable. Do not add wrappers solely to simplify mocks. Assert observable results rather than calls to repo-owned helpers.
@@ -0,0 +1,77 @@
1
+ # Good and bad tests
2
+
3
+ ## Good tests
4
+
5
+ **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
+
7
+ ```typescript
8
+ // GOOD: Tests observable behavior
9
+ test("user can checkout with valid cart", async () => {
10
+ const cart = createCart();
11
+ cart.add(product);
12
+ const result = await checkout(cart, paymentMethod);
13
+ expect(result.status).toBe("confirmed");
14
+ });
15
+ ```
16
+
17
+ Characteristics:
18
+
19
+ - Tests behavior users/callers care about
20
+ - Uses public API only
21
+ - Survives internal refactors
22
+ - Describes WHAT, not HOW
23
+ - Assertions establish one observable behavior; use several when the contract needs them
24
+
25
+ ## Bad tests
26
+
27
+ **Implementation-detail tests**: Coupled to internal structure.
28
+
29
+ ```typescript
30
+ // BAD: Tests implementation details
31
+ test("checkout calls paymentService.process", async () => {
32
+ const mockPayment = { process: jest.fn() };
33
+ await checkout(cart, mockPayment);
34
+ expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35
+ });
36
+ ```
37
+
38
+ Red flags:
39
+
40
+ - Mocking internal collaborators
41
+ - Testing private methods
42
+ - Asserting internal collaborator calls/counts/order instead of observable behavior. External-boundary count or order contracts are valid assertions.
43
+ - Test breaks when refactoring without behavior change
44
+ - Test name describes HOW not WHAT
45
+ - Bypassing the tested public interface to inspect private implementation state. Observable storage, wire, and DOM outcomes remain valid; prefer fake state over call logs when state expresses the contract.
46
+
47
+ ```typescript
48
+ // BAD: Checks private storage when storage is not the public contract
49
+ test("createUser saves to database", async () => {
50
+ await createUser({ name: "Alice" });
51
+ const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52
+ expect(row).toBeDefined();
53
+ });
54
+
55
+ // GOOD: Verifies through interface
56
+ test("createUser makes user retrievable", async () => {
57
+ const user = await createUser({ name: "Alice" });
58
+ const retrieved = await getUser(user.id);
59
+ expect(retrieved.name).toBe("Alice");
60
+ });
61
+ ```
62
+
63
+ **Tautological tests**: Expected value restates the implementation, so the test passes by construction.
64
+
65
+ ```typescript
66
+ // BAD: Expected value is recomputed the way the code computes it
67
+ test("calculateTotal sums line items", () => {
68
+ const items = [{ price: 10 }, { price: 5 }];
69
+ const expected = items.reduce((sum, i) => sum + i.price, 0);
70
+ expect(calculateTotal(items)).toBe(expected);
71
+ });
72
+
73
+ // GOOD: Expected value is an independent, known literal
74
+ test("calculateTotal sums line items", () => {
75
+ expect(calculateTotal([{ price: 10 }, { price: 5 }])).toBe(15);
76
+ });
77
+ ```
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: hr-test-audit
3
+ description: Gate new or changed tests on the value they add, and sweep an existing suite for low-value, implementation-coupled or duplicate tests to delete. Use when adding or reviewing tests, or when asked to prune, audit or clean up a test suite.
4
+ ---
5
+
6
+ # Test audit
7
+
8
+ Two modes share one value bar: a test earns its upkeep by protecting observable
9
+ behavior, a credible regression, or an independent contract. **Authoring mode**
10
+ gates each new or changed test before it lands. **Audit mode** finds existing
11
+ tests that fail the bar and removes them in small, evidenced batches. For the
12
+ red-green loop itself, use a TDD skill where one is installed; this skill decides which tests are worth
13
+ keeping.
14
+
15
+ ## Authoring gate
16
+
17
+ Before adding a test, answer all four. A missing answer means don't add it yet.
18
+
19
+ 1. What observable behavior, invariant or contract does it protect?
20
+ 2. What credible regression makes it fail? Name the production change that
21
+ turns it red: a wrong constant or argument, a wrong branch, a missing side
22
+ effect, an empty or default return, or a missing check for empty, nil,
23
+ unauthorized or malformed input. If none would, it is a change detector or
24
+ cannot fail.
25
+ 3. Why doesn't existing coverage already catch that? Each contract has one
26
+ owning test at its strongest boundary. Another layer needs its own risk the
27
+ owner cannot reach. Prefer a new case in an existing table or fixture over a
28
+ near-duplicate test.
29
+ 4. Does it need a production seam (export, flag, wrapper, injection hook) that
30
+ no production caller uses? Then test at the real boundary instead.
31
+
32
+ When a unit must be tested in isolation, write down the ways it can fail before
33
+ writing the code, and test those failures. A test written after the code tends
34
+ to restate the code.
35
+
36
+ A bug regression test must fail on the pre-fix code for the intended reason,
37
+ then pass after the fix. One that never demonstrably failed proves the mock, not
38
+ the fix. One regression at the owning boundary covers the bug; don't replay it
39
+ at every layer it crosses. For a sequence `hr-ordering-tests` found, that
40
+ regression is the named test beside its enumeration.
41
+
42
+ Changing an existing test so it checks less counts as removing it: deleting or
43
+ skipping it, loosening an assertion, or rewriting an expected value to match new
44
+ output. It needs the audit-mode evidence from step 2, not only these answers.
45
+ To catch these moves in a diff, run
46
+ `bun <this skill's directory>/scripts/floor-guard.ts [--base <ref>]` from
47
+ the repository. It reports new suppression comments, added skips or
48
+ `.only`, deleted test files and assertions removed from surviving tests, and
49
+ exits 0 clean, 1 with findings, 2 when it could not run. Each finding still
50
+ needs a reason; a 2 is never a pass.
51
+
52
+ For retry and concurrency failures, exercise the implementation at the boundary
53
+ where order matters. Cover the credible lost-response, interrupted-write or
54
+ restart sequence with controlled barriers and assert durable state or externally
55
+ visible behavior. Do not replace that coverage with a separate model of the code.
56
+ Code that merges events from more than one actor also needs an enumeration test
57
+ from `hr-ordering-tests`, and a change that adds a kind of event adds it to that
58
+ test's event list.
59
+
60
+ When behavior depends on three or more independent settings, cover every pair
61
+ of their values rather than every combination: list each setting's value
62
+ classes and edge values, drop combinations the code rejects, and build the
63
+ smallest table where each pair appears at least once (Microsoft PICT generates
64
+ one). Most interaction bugs need only two settings to line up. Add an explicit
65
+ case for each combination of three or more settings already known to interact,
66
+ such as one behind a past bug or a documented constraint.
67
+
68
+ Then check the test against the junk patterns below. A match fails the gate
69
+ unless the retention bar names the contract it independently guards.
70
+
71
+ ## Junk patterns
72
+
73
+ Authoring rejects new tests that match; audits hunt for existing ones that do.
74
+
75
+ - no assertion, or an assertion that cannot fail
76
+ - expected values produced by the code under test, or copied from it
77
+ (fixtures, inventories, export lists, snapshots taken from current output)
78
+ - exact source, import or string greps standing in for behavior
79
+ - private helpers or call shapes tested again where a real boundary already
80
+ covers them
81
+ - the same contract asserted several times, or one shared helper re-tested in
82
+ every caller
83
+ - tests that exist only to keep test-only exports, globals or wrappers alive,
84
+ and production code whose only callers are tests
85
+ - mocks that implement the asserted behavior, or one mock standing in for
86
+ different APIs
87
+ - negative tests that pass for an unrelated reason (a different guard rejects
88
+ the input, or the production path never reaches the check)
89
+ - names or fixtures that promise more than the test exercises
90
+ - tests that break under a behavior-preserving refactor
91
+
92
+ ## Retention bar
93
+
94
+ Keep a test that independently enforces a public API, protocol, config,
95
+ migration, storage, security, platform, default or release contract. Also keep
96
+ call-order tests when order is observable, regressions with a credible failure
97
+ mode, and a source check when it is the cheapest guard that fails on a
98
+ user-facing change and survives a rename. Slow or static is not a reason to
99
+ delete. A kept test that fails on the unchanged baseline may be a real bug:
100
+ reproduce and fix it rather than deleting the test.
101
+
102
+ ## Audit mode
103
+
104
+ 1. **Discover, read-only.** Read the repository's testing guidance first. For a
105
+ large suite, split discovery by area and run the slices in parallel if the
106
+ host allows. Prefer a few high-confidence candidates over a long speculative
107
+ list. Before judging one, read the whole test, the production code it covers,
108
+ that code's callers, and any overlapping tests.
109
+ 2. **Record evidence per candidate** before editing: test name and location;
110
+ the failure it can actually detect; non-test callers of what it covers; the
111
+ stronger test that remains, or why none is needed; why it exists (history);
112
+ what production or test-support code its removal frees; the focused
113
+ validation command. A missing field means the candidate is not ready.
114
+ 3. **Edit one coherent batch.** Remove the tests along with the test-only
115
+ exports, wrappers and dead paths they kept alive; don't leave aliases. Move a
116
+ retained regression to its owning boundary. Don't add replacement tests that
117
+ restate the implementation, and don't count uncertain deletions as progress.
118
+ 4. **Validate.** Run the owning and sibling tests, then the repository's
119
+ required checks. Where a removed test grepped source or a plan, run the
120
+ script or dry run that owns the real contract instead.
121
+ 5. **Report**: categories removed, kept false positives and why, checks run,
122
+ and production versus test lines changed (`git diff --numstat`). Land one
123
+ batch at a time through the repository's normal flow, then rerun discovery on
124
+ the updated base for the next batch.
125
+
126
+ ## Sources
127
+
128
+ Original synthesis, adapting:
129
+
130
+ - OpenClaw's
131
+ [`test-audit`](https://github.com/openclaw/openclaw/blob/65f1e4d2279eecd6e40d55d82027d5c97b4b272b/.agents/skills/test-audit/SKILL.md):
132
+ the authoring gate, junk patterns, retention bar and evidence fields.
133
+ - [Ansh Nanda via Ray Fernando](https://x.com/RayFernando1337/status/2102927565778522610):
134
+ the failure-list-first rule. Their "E2E tests only" rule is not adopted.
135
+ - no_human's [tamper guard](https://github.com/no-human-ai/no_human): weakening
136
+ a test counts as removing it.
137
+ - addyosmani/agent-skills'
138
+ [floor guard](https://github.com/addyosmani/agent-skills/blob/main/skills/constraint-driven-development/references/floor-guard.md)
139
+ (MIT): the diff checker.
140
+ - obra/superpowers `writing-good-tests.md`: the mutation check behind
141
+ authoring-gate question 2.
142
+ - omkamal's [pypict skill](https://github.com/omkamal/pypict-claude-skill):
143
+ pairwise coverage.
144
+
145
+ For recorded proof that a UI change works, see michaelshimeles'
146
+ [`evidence-driven-testing`](https://github.com/michaelshimeles/skills/tree/main/evidence-driven-testing).
@@ -0,0 +1,3 @@
1
+ interface:
2
+ display_name: "HR: Test audit"
3
+ short_description: "Gate new tests and prune low-value ones"
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env bun
2
+ // Flag changes that make tests or checkers easier to pass: new suppression
3
+ // comments, added skips or `.only`, deleted test files, and assertions removed
4
+ // from test files that still exist. Diff-scoped: merge base to working tree,
5
+ // untracked files included. Tightening is silent; only loosening is reported.
6
+ // bun floor-guard.ts [--base <ref>] (default: origin/HEAD, then origin/main)
7
+ // Exit 0 clean, 1 findings, 2 the guard could not run. Never read 2 as clean.
8
+ // Adapted from addyosmani/agent-skills constraint-driven-development
9
+ // references/floor-guard.md (MIT).
10
+ import { spawnSync } from "node:child_process";
11
+ import { parseArgs } from "node:util";
12
+
13
+ export type Finding = { rule: string; file: string; text: string };
14
+
15
+ const SUPPRESSIONS =
16
+ /@ts-ignore|@ts-nocheck|@ts-expect-error|eslint-disable|oxlint-disable|biome-ignore|#\s*noqa|#\s*type:\s*ignore|istanbul ignore|c8 ignore|nosemgrep|gitleaks:allow|Stryker disable/;
17
+ const SKIPS =
18
+ /\.(skip|todo|only)\s*\(|\b(xit|xdescribe|xtest)\s*\(|@pytest\.mark\.(skip|xfail)|\bt\.Skip\(/;
19
+ const ASSERTION = /\b(expect|assert\w*|should)\b/;
20
+
21
+ export function isTestFile(path: string): boolean {
22
+ return /\.(test|spec)\.[^/]+$|_test\.[^/]+$|(^|\/)test_[^/]+$|(^|\/)(tests?|__tests__)\//.test(
23
+ path,
24
+ );
25
+ }
26
+
27
+ // Reads a unified diff (`--unified=0` is enough) and returns the loosening moves.
28
+ export function scanDiff(diff: string): Finding[] {
29
+ const added: { file: string; text: string }[] = [];
30
+ const removed: { file: string; text: string }[] = [];
31
+ const deleted = new Set<string>();
32
+ const strip = (p: string) => p.replace(/^[ab]\//, "");
33
+ let file = "";
34
+ let oldFile = "";
35
+ // File headers appear only between `diff --git` and the first `@@`; inside a hunk,
36
+ // an added line such as `++ x` is content, not a header.
37
+ let inHunk = false;
38
+ for (const line of diff.split("\n")) {
39
+ if (line.startsWith("diff ")) {
40
+ inHunk = false;
41
+ } else if (line.startsWith("@@")) {
42
+ inHunk = true;
43
+ } else if (!inHunk && line.startsWith("--- ")) {
44
+ oldFile = strip(line.slice(4));
45
+ } else if (!inHunk && line.startsWith("+++ ")) {
46
+ const newFile = strip(line.slice(4));
47
+ file = newFile === "/dev/null" ? oldFile : newFile;
48
+ if (newFile === "/dev/null") {
49
+ deleted.add(oldFile);
50
+ }
51
+ } else if (line.startsWith("+")) {
52
+ added.push({ file, text: line.slice(1) });
53
+ } else if (line.startsWith("-")) {
54
+ removed.push({ file, text: line.slice(1) });
55
+ }
56
+ }
57
+
58
+ const findings: Finding[] = [];
59
+ const flag = (rule: string, f: string, text: string) =>
60
+ findings.push({ rule, file: f, text: text.trim().slice(0, 120) });
61
+ for (const { file: f, text } of added) {
62
+ if (SUPPRESSIONS.test(text)) {
63
+ flag("silenced-checker", f, text);
64
+ }
65
+ if (isTestFile(f) && SKIPS.test(text)) {
66
+ flag("test-skipped", f, text);
67
+ }
68
+ }
69
+ for (const f of deleted) {
70
+ if (isTestFile(f)) {
71
+ flag("test-deleted", f, "file deleted");
72
+ }
73
+ }
74
+ // An assertion line that reappears in the same file was moved, not removed.
75
+ const kept = new Set(added.map((a) => `${a.file}\0${a.text.trim()}`));
76
+ for (const { file: f, text } of removed) {
77
+ if (!isTestFile(f) || deleted.has(f) || !ASSERTION.test(text)) {
78
+ continue;
79
+ }
80
+ if (!kept.has(`${f}\0${text.trim()}`)) {
81
+ flag("assertion-removed", f, text);
82
+ }
83
+ }
84
+ return findings;
85
+ }
86
+
87
+ function git(args: string[], okStatuses = [0]): string | null {
88
+ const r = spawnSync("git", args, { encoding: "utf8" });
89
+ return r.status !== null && okStatuses.includes(r.status) ? r.stdout : null;
90
+ }
91
+
92
+ function main(): number {
93
+ const bail = (msg: string) => (console.error(`floor-guard: ${msg}`), 2);
94
+ let base: string | undefined;
95
+ try {
96
+ base = parseArgs({ options: { base: { type: "string" } } }).values.base;
97
+ } catch (error) {
98
+ return bail(error instanceof Error ? error.message : String(error));
99
+ }
100
+ const bases = base ? [base] : ["origin/HEAD", "origin/main"];
101
+ let mergeBase: string | undefined;
102
+ for (const b of bases) {
103
+ mergeBase = git(["merge-base", b, "HEAD"])?.trim();
104
+ if (mergeBase) {
105
+ break;
106
+ }
107
+ }
108
+ if (!mergeBase) {
109
+ return bail(`no merge base against ${bases.join(" or ")}`);
110
+ }
111
+ const tracked = git(["diff", "--unified=0", mergeBase, "--"]);
112
+ const untracked = git(["ls-files", "--others", "--exclude-standard"]);
113
+ if (tracked === null || untracked === null) {
114
+ return bail("could not read the diff");
115
+ }
116
+ let diff = tracked;
117
+ for (const f of untracked.split("\n").filter(Boolean)) {
118
+ // --no-index exits 1 when the sides differ, which is the normal case here.
119
+ const d = git(["diff", "--no-index", "--unified=0", "/dev/null", f], [0, 1]);
120
+ if (d === null) {
121
+ return bail(`could not diff untracked file ${f}`);
122
+ }
123
+ diff += `\n${d}`;
124
+ }
125
+ const findings = scanDiff(diff);
126
+ for (const f of findings) {
127
+ console.log(`${f.rule}\t${f.file}\t${f.text}`);
128
+ }
129
+ if (findings.length === 0) {
130
+ console.log("floor-guard: clean");
131
+ }
132
+ return findings.length ? 1 : 0;
133
+ }
134
+
135
+ if (import.meta.main) {
136
+ process.exit(main());
137
+ }
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: hr-what-next
3
+ description: "Reconcile remaining work and recommend priorities. Use for next, next?, what's next, what remains, backlog reviews, full-session audits of tasks and unanswered or past questions, and equivalent requests. Do not use for go or continue, which retain their acceptance/continuation meaning, or progress/ETA-only requests."
4
+ ---
5
+
6
+ # What next
7
+
8
+ Turn the requested scope into an evidence-based inventory and next decision.
9
+ Before reporting, read the bundled [reporting procedure](references/reporting.md).
10
+ Use it with the governing continuation and offer rules; this request does
11
+ not cancel selected work or authorize a new task.
12
+
13
+ Before a session-completion claim, apply the governing § Finishing work's
14
+ full-session gate even when the request was only a short "next?". Save the
15
+ completed state before the completion message; a report alone does not do so.
16
+
17
+ 1. Choose the review scope from the request and its context. For a short
18
+ "next?", check the current task, its ledger and latest results, plus this
19
+ floor whatever the scope: every question from an earlier offer in this
20
+ conversation that the user has not answered, every owned uncommitted file,
21
+ unpushed commit or held checkout, and the number of other live ledger items
22
+ (deferred, unselected, blocked or follow-up) with a link to the ledger.
23
+ Report each floor item, or state that the floor is empty. While any floor
24
+ item remains, do not say that nothing is left or that nothing needs the
25
+ user; re-present the unanswered questions as an offer instead. When asked
26
+ for all current and past items, review the available session transcript,
27
+ relevant plans, task lists, handoffs and linked follow-ups. Name source
28
+ ranges and missing, inaccessible or truncated records. Sweep other
29
+ sessions' records only within the requested project and scope.
30
+ 2. Trace requests, unanswered questions, commitments, offered alternatives
31
+ and findings to their latest disposition. Reconcile duplicate, superseded
32
+ and stale rows with completion or replacement evidence. Keep owners,
33
+ deferred triggers and other sessions' context visible. An old task
34
+ description alone does not establish current activity or ownership.
35
+ 3. Preserve the latest selected scope and valid unanswered offer in the
36
+ durable ledger. Distinguish done, authorized unfinished, unselected,
37
+ blocked, deferred and other-owner items. A completed implementation does
38
+ not complete required checks or landing; deferral does not mean done.
39
+ 4. Rank remaining items toward the current goal and explicit priorities.
40
+ Explain the objective and weigh expected impact, next-decision value,
41
+ urgency, dependencies, effort and evidence confidence. Keep priority,
42
+ readiness and authority separate. Label unknown gains rather than
43
+ inventing scores or measurements.
44
+ 5. Lead with what is complete, what remains and the next unfinished selected
45
+ step. Show one row per remaining item with rank, state, expected impact
46
+ and its reason, next action or decision, and owner/source where needed.
47
+ For a full audit, put the full individual table in a durable report
48
+ and link it beside the immediate decisions. Answer whether items are
49
+ accounted for separately from whether selected work is complete.
50
+ 6. Continue work that can advance under existing authorization. Ask only for
51
+ unresolved choices using the governing offer format. Preserve schedules
52
+ and ownership; this audit grants no authority to start, transfer, publish
53
+ or clean up work merely because it appears in the inventory.
54
+
55
+ For a full audit, save a mapping from reviewed source records to items or
56
+ reviewed context-only dispositions. If `hr-handoff` and its reconciliation
57
+ resources are available, reuse its `references/reconciliation.md` procedure
58
+ and `scripts/check-reconciliation.mjs` checker. Otherwise retain the mapping
59
+ and coverage gaps without claiming a mechanical check. A passing checker
60
+ accounts for supplied records; it does not prove every promise was understood
61
+ or that unavailable history contains no other work.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "HR: What next"
3
+ short_description: "Reconcile remaining work and recommend priorities"
4
+ default_prompt: "Use $hr-what-next to reconcile remaining work and recommend the next decision."
@@ -0,0 +1,68 @@
1
+ ## Reporting
2
+
3
+ Lead with the answer or the concrete result. Show what is complete and what
4
+ remains, and separate measured facts from unverified claims. Use numbered steps
5
+ for actions the user must perform.
6
+
7
+ During long work, give frequent useful progress updates with completed evidence,
8
+ the current action and what remains. Show clock-time forecasts in the user's
9
+ local timezone. Use the timezone provided by the user or session environment;
10
+ ask if neither establishes it.
11
+
12
+ Use a visual when it makes a change, behavior or decision clearer; keep a short
13
+ text explanation beside it. For visible interface changes, prefer actual
14
+ before/after captures with comparable content, viewport and state when available.
15
+ Label mockups and simulated behavior as illustrations, not verification. Use
16
+ interaction when exploring states or alternatives helps the reader, and provide
17
+ an accessible text or static equivalent. Use the host's available tools within
18
+ existing browser and task authorization.
19
+
20
+ Use a Markdown table when comparing items on common criteria or reporting
21
+ repeated records with useful shared fields. When asked about benefits,
22
+ tradeoffs or how a proposal differs from current behavior, use a compact
23
+ table for multiple items. Explain one item per row. For changes, show current
24
+ and proposed behavior and why the difference matters. Include relevant
25
+ tradeoffs and evidence or uncertainty; label unknowns rather than inventing
26
+ gains. Keep columns consistent and cells short. Label missing or unverified values and put units in headings. Put
27
+ explanations and caveats beside the table. Split wide tables or use lists when
28
+ long cells obscure the comparison. Preserve § Offers and any enabled offer format.
29
+
30
+ When asked for a backlog, research list or remaining work, check the current
31
+ session and relevant task records within the requested scope. Reconcile
32
+ completed, superseded and duplicate items before reporting what remains.
33
+ State which records were checked and label incomplete coverage.
34
+
35
+ Show one row per remaining item in priority order. Use compact columns for
36
+ rank, item, state, expected impact with its priority reason, and next action
37
+ or decision. Include owners and source links when needed to distinguish work.
38
+ Keep blocked, deferred, unstarted and research items visible with their
39
+ conditions; priority does not authorize starting them.
40
+
41
+ State the ranking objective from the current task's goal and explicit user
42
+ priorities. Recent work informs that objective; explain any inferred goal.
43
+ Weigh expected contribution to the goal and how much the next action helps
44
+ make the next decision, accounting for urgency, dependencies, effort and
45
+ confidence in the evidence. For performance work, use relevant latency,
46
+ throughput or resource measures. For fixes, weigh severity and affected users.
47
+ For enhancements, weigh user value and progress toward acceptance criteria.
48
+ For research, name the uncertainty or decision the work could resolve.
49
+ Label expected gains and unknowns; do not invent measurements or scores.
50
+ Keep priority separate from readiness, and preserve § Finishing work's
51
+ requirements for continuing authorized work and making offers.
52
+
53
+ Put the answer, and anything the user must read or act on, in the reply's text
54
+ after its last tool call. Text written between tool calls can be collapsed or
55
+ lost. When the reply ends with a question card, that text goes after every
56
+ other tool call, right before the card.
57
+
58
+ Verify work with completed checks and their output. Confirm each check's exit status or final
59
+ result before claiming a pass, and do not hide failures by filtering output. Report changes,
60
+ verification, failed or unrun checks and remaining uncertainty. At task or session closeout,
61
+ save reusable lessons with their condition, action and evidence in the project's record or notes.
62
+ Link existing rules or checks. When none emerged, no lesson entry is needed.
63
+
64
+ Name each choice made in passing that costs the user something if missed.
65
+ That covers a tradeoff, a default picked for them, a step you did not
66
+ highlight and a result that may be off, but not routine plumbing. Describe
67
+ it in words the user would still recognize a week later, not in names coined
68
+ during the work.
@@ -0,0 +1,46 @@
1
+ # Source notices
2
+
3
+ This notice accompanies the hr-writing-for-agents bundle when copied on its own.
4
+
5
+ ## mattpocock/skills
6
+
7
+ Source: https://github.com/mattpocock/skills (compared at revision `d81f3a1`)
8
+
9
+ - `skills/hr-writing-for-agents/`: adapted from `skills/productivity/writing-for-agents/`.
10
+
11
+ Copyright (c) 2026 Matt Pocock
12
+
13
+ ## obra/superpowers
14
+
15
+ Source: https://github.com/obra/superpowers (compared at revision `8ca22db`)
16
+
17
+ - `skills/hr-writing-for-agents/SKILL.md`: the instruction-form table is adapted
18
+ from `writing-skills`.
19
+
20
+ Copyright (c) 2025 Jesse Vincent
21
+
22
+ The source's wording tests found that a recipe beat a prohibition for shape failures; the instruction-form table preserves that approach.
23
+
24
+ ## house-rules and MIT permission notice
25
+
26
+ MIT License
27
+
28
+ Copyright (c) 2026 Aaron Queen
29
+
30
+ Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ of this software and associated documentation files (the "Software"), to deal
32
+ in the Software without restriction, including without limitation the rights
33
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ copies of the Software, and to permit persons to whom the Software is
35
+ furnished to do so, subject to the following conditions:
36
+
37
+ The above copyright notice and this permission notice shall be included in all
38
+ copies or substantial portions of the Software.
39
+
40
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
46
+ SOFTWARE.