@bompus/house-rules 0.13.0 → 0.14.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.
package/README.md CHANGED
@@ -1,14 +1,22 @@
1
1
  <h1 align="center">
2
2
  <picture>
3
3
  <source media="(prefers-color-scheme: dark)" srcset="docs/assets/banner-dark.png">
4
- <img src="docs/assets/banner-light.png" alt="house-rules" width="100%">
4
+ <img src="docs/assets/banner-light.png" alt="house-rules: Working rules and skills for AI coding agents" width="100%">
5
5
  </picture>
6
6
  </h1>
7
7
 
8
8
  <p align="center">
9
9
  <a href="https://github.com/bompus/house-rules/actions/workflows/check.yml"><img src="https://github.com/bompus/house-rules/actions/workflows/check.yml/badge.svg" alt="CI status"></a>
10
- <a href="https://github.com/bompus/house-rules/releases/latest"><img src="https://img.shields.io/github/v/release/bompus/house-rules" alt="Latest release"></a>
11
- <a href="LICENSE"><img src="https://img.shields.io/github/license/bompus/house-rules" alt="MIT license"></a>
10
+ <a href="https://github.com/bompus/house-rules/releases/latest"><img src="https://badgen.net/github/release/bompus/house-rules" alt="Latest GitHub release"></a>
11
+ <a href="https://www.npmjs.com/package/@bompus/house-rules"><img src="https://badgen.net/npm/v/@bompus/house-rules" alt="Latest npm version"></a>
12
+ <a href="LICENSE"><img src="https://badgen.net/badge/license/MIT/blue" alt="MIT license"></a>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="rules/core.md">Core rules</a>&nbsp;·
17
+ <a href="#modifiers">Opt-in modifiers</a>&nbsp;·
18
+ <a href="#writing-your-own-sections">Your own layer</a>&nbsp;·
19
+ <a href="examples/project/AGENTS.md">Each repo's AGENTS.md</a>
12
20
  </p>
13
21
 
14
22
  A practical starting point for ordinary development with AI coding agents.
@@ -291,7 +299,7 @@ changing the configuration.
291
299
  | `hr-ordering-tests` | Enumerate event orderings through the real code to find race bugs. |
292
300
  | `hr-plain-prose` | Make text people read plain and specific. |
293
301
  | `hr-progress-report` | Report current task activity, milestone completion and remaining wall-clock time. |
294
- | `hr-pr-followup` | Address conflicts, feedback and failing checks for a PR; honor landing authority; CodeRabbit review gate. |
302
+ | `hr-pr-followup` | Address conflicts, feedback and failing checks for a PR; landing authority; CodeRabbit and cubic gate. |
295
303
  | `hr-read-reddit` | Read Reddit feed output while supported; RSS support ends November 13, 2026. Partial web-search fallback. |
296
304
  | `hr-read-x-links` | Read the full content of X posts. |
297
305
  | `hr-research-shared-links` | Research a shared link or repository in depth, compare it with your setup and rate each idea. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bompus/house-rules",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Composable working rules and skills for AI coding agents",
5
5
  "homepage": "https://github.com/bompus/house-rules#readme",
6
6
  "license": "MIT",
@@ -15,6 +15,16 @@ or readiness condition in the task plan. Backlog items do not authorize
15
15
  implementation or landing. Do not hold a ready batch for unrelated, unapproved
16
16
  or indefinite work.
17
17
 
18
+ Before any decision to publish, check every package for commits past its latest
19
+ release tag, and recommend a new release first when there are any. This covers
20
+ public and private packages alike, and a republish of an existing tag, which
21
+ ships the tagged content without the later commits. State how many commits are
22
+ unreleased and what they change, and name the version the repository's scheme
23
+ gives the combined changes. A package that has never been tagged has no
24
+ baseline, so say that and treat the publish as its first release. The
25
+ recommendation is not permission to tag, publish or announce, and it does not
26
+ hold a ready batch for unrelated work.
27
+
18
28
  Before any release or public announcement, audit every public-facing
19
29
  material against the intended revision or artifact and current verified state:
20
30
  the README and package READMEs, comparisons, performance metrics, graphics and
@@ -55,8 +55,8 @@ Name the exact revision, failed or unfinished gates and unresolved decisions.
55
55
  Clean CI alone is not evidence that every review finding was handled.
56
56
 
57
57
  When the repository or user selects these GitHub helper policies, use
58
- [the CodeRabbit review gate and one-thread resolver](references/review-helpers.md).
59
- Its review-status checks cover CodeRabbit only; its thread check covers any
58
+ [the CodeRabbit and cubic review gate and one-thread resolver](references/review-helpers.md).
59
+ Its review-status checks cover CodeRabbit and cubic only; its thread check covers any
60
60
  reviewer and its review-body check any bot. It does not replace other required
61
61
  checks or the caller's judgment. The same reference describes the landing helper scripts (`merge-pr.sh`,
62
62
  `verify-landed.sh`, `check-landing.py`).
@@ -14,12 +14,24 @@ bun scripts/check-pr-review.ts 123 --repo OWNER/REPO
14
14
 
15
15
  The gate exits 0 when its selected feedback checks pass, 1 for open feedback,
16
16
  and 2 when coverage cannot be verified. It checks unresolved threads, pending
17
- CodeRabbit review, skipped review statuses and a missing check when the head
18
- contains `.coderabbit.yaml`. It also checks bot review bodies with outside-diff,
19
- nitpick or duplicate findings. A completed CodeRabbit CheckRun must conclude SUCCESS;
20
- failed, cancelled, skipped or missing conclusions block the gate. A CodeRabbit status also requires SUCCESS
21
- and a description starting with "Review completed". It does not
22
- check every CI result or authorize landing.
17
+ CodeRabbit or cubic review, skipped review statuses and a missing check when
18
+ the head contains `.coderabbit.yaml`. It also checks bot review bodies with
19
+ outside-diff, nitpick or duplicate findings. A completed CodeRabbit CheckRun
20
+ must conclude SUCCESS; failed, cancelled, skipped or missing conclusions block
21
+ the gate. A CodeRabbit status also requires SUCCESS and a description starting
22
+ with "Review completed". It does not check every CI result or authorize landing.
23
+
24
+ The check named exactly "cubic · AI code reviewer" on the head commit is held to the
25
+ same rule: while it runs, the gate refuses, and a completed one must conclude
26
+ SUCCESS. A NEUTRAL or skipped conclusion means cubic did not review the head
27
+ ("Incremental review could not start", "Automatic AI review not started after
28
+ branch rewrite", "AI review line limit reached"), so the gate refuses it too.
29
+ That pull request stays blocked until someone comments `@cubic review` or the
30
+ limit clears, and the refusal says so. A head commit with no cubic check is not blocked,
31
+ because cubic's `cubic.yaml` is optional and its absence does not show that cubic is
32
+ expected. `--wait` does not wait for a cubic check that has not posted yet.
33
+ In a repository that uses cubic, confirm right after a push that its check has appeared
34
+ before landing.
23
35
 
24
36
  If a review is missing or incomplete, inspect the integration and the repository's
25
37
  review policy. The helper does not determine automatic-review enablement or
@@ -42,7 +54,7 @@ judges whether the explanation answers the findings.
42
54
  Connections are paginated. Partial responses, malformed fields, repeated
43
55
  cursors and head changes fail closed. A final head read does not make review
44
56
  feedback an atomic snapshot. `--wait --timeout 30` polls only while CodeRabbit
45
- runs, or briefly while its expected check has not appeared.
57
+ or cubic runs, or briefly while CodeRabbit's expected check has not appeared.
46
58
 
47
59
  ## Resolve one review thread
48
60
 
@@ -1,16 +1,22 @@
1
1
  #!/usr/bin/env bun
2
2
  // Refuses to land a pull request while review feedback is open: an unresolved review thread, a
3
- // review bot (CodeRabbit) whose check is still running, or a bot review whose body carries findings
3
+ // review bot (CodeRabbit or cubic) whose check is still running, or a bot review whose body carries findings
4
4
  // GitHub cannot show as threads ("Outside diff range comments", "Nitpick comments", "Duplicate comments") with no human
5
5
  // explicit acknowledgement for that review and the current head. Run only when the repository
6
6
  // selects this gate. It also refuses when CodeRabbit's status on the
7
7
  // head commit says anything but "Review completed": CodeRabbit marks a skipped review (for example
8
8
  // on a non-default base) as success with "Review skipped: …". When the head commit has
9
- // `.coderabbit.yaml` but no CodeRabbit check, it refuses too. Missing or incomplete reviews
9
+ // `.coderabbit.yaml` but no CodeRabbit check, it refuses too. A cubic check ("cubic · AI code
10
+ // reviewer") on the head commit must also complete with SUCCESS: a running one refuses, and so does
11
+ // any other conclusion, NEUTRAL and skipped included, because NEUTRAL means cubic did not review the
12
+ // head ("Incremental review could not start", "AI review line limit reached"). That PR stays blocked
13
+ // until someone comments `@cubic review` or the limit clears. A head commit with no cubic check is
14
+ // not blocked, since cubic's `cubic.yaml` is optional and its absence does not show that cubic
15
+ // is expected, and --wait does not wait for one to appear. Missing or incomplete reviews
10
16
  // require inspection of the review integration and the repository's selected review policy.
11
17
  // bun scripts/check-pr-review.ts <pr> [--repo <owner>/<name>] [--wait [--timeout <minutes>]]
12
18
  // Exit 1 while feedback is open, 2 when gh fails. Without --repo, gh resolves the repository from
13
- // the current checkout. --wait polls every 30 s while CodeRabbit's review is still running, and for
19
+ // the current checkout. --wait polls every 30 s while CodeRabbit's or cubic's review is still running, and for
14
20
  // up to 3 minutes while the head commit has no CodeRabbit check yet (CodeRabbit posts it a little
15
21
  // after a push), then reports as usual; after --timeout minutes (default 30) it reports what is
16
22
  // still open.
@@ -30,13 +36,17 @@
30
36
  import { spawnSync } from "node:child_process";
31
37
  import { parseArgs } from "node:util";
32
38
 
33
- const REVIEW_BOTS = /coderabbit/i;
39
+ const CODERABBIT = /coderabbit/i;
40
+ const CUBIC = /^cubic · AI code reviewer$/i;
41
+ const isReviewBot = (name: string) => CODERABBIT.test(name) || CUBIC.test(name);
34
42
  const REVIEW_BOT_CONFIG = ".coderabbit.yaml";
35
43
  const BODY_FINDINGS = /Outside diff range comments|Nitpick comments|Duplicate comments/;
36
44
  const REVIEWED = /^Review completed/;
37
45
  const FOLLOW_UP = "check the review integration and repository review policy";
38
46
  const RUNNING = "review still running: ";
39
47
  const NO_CHECK = "no CodeRabbit check on the head commit";
48
+ // A neutral cubic result means it did not review the head; a person has to ask again.
49
+ const CUBIC_RETRY = "comment `@cubic review` or wait for its limit to clear";
40
50
  const POLL_MS = 30_000;
41
51
  const NO_CHECK_GRACE_MS = 180_000;
42
52
 
@@ -364,25 +374,26 @@ export function openFeedback(pr: ReviewState): string[] {
364
374
  const head = pr.commits.nodes[0]?.commit;
365
375
  const contexts = head?.statusCheckRollup?.contexts.nodes ?? [];
366
376
  const hasConfig = head?.tree.entries.some((e) => e.name === REVIEW_BOT_CONFIG) ?? false;
367
- if (hasConfig && !contexts.some((ctx) => REVIEW_BOTS.test(ctx.context ?? ctx.name ?? ""))) {
377
+ if (hasConfig && !contexts.some((ctx) => CODERABBIT.test(ctx.context ?? ctx.name ?? ""))) {
368
378
  open.push(`${NO_CHECK}: ${FOLLOW_UP}`);
369
379
  }
370
380
  for (const ctx of contexts) {
371
381
  const name = ctx.context ?? ctx.name ?? "";
372
382
  const running =
373
383
  ctx.state === "PENDING" || (ctx.status !== undefined && ctx.status !== "COMPLETED");
374
- if (!REVIEW_BOTS.test(name)) {
384
+ if (!isReviewBot(name)) {
375
385
  continue;
376
386
  }
377
387
  if (running) {
378
388
  open.push(`${RUNNING}${name}`);
379
389
  } else if (ctx.name !== undefined && ctx.conclusion !== "SUCCESS") {
390
+ const retry = CUBIC.test(name) ? `; ${CUBIC_RETRY}` : "";
380
391
  open.push(
381
- `${name} review concluded ${ctx.conclusion ?? "(missing conclusion)"}: ${FOLLOW_UP}`,
392
+ `${name} review concluded ${ctx.conclusion ?? "(missing conclusion)"}: ${FOLLOW_UP}${retry}`,
382
393
  );
383
394
  } else if (
384
395
  ctx.context !== undefined &&
385
- (ctx.state !== "SUCCESS" || !REVIEWED.test(ctx.description ?? ""))
396
+ (ctx.state !== "SUCCESS" || (CODERABBIT.test(name) && !REVIEWED.test(ctx.description ?? "")))
386
397
  ) {
387
398
  open.push(
388
399
  `${name} did not review the head commit ("${ctx.description ?? ""}"): ${FOLLOW_UP}`,