Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/rules/glossary-maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ The same decision tree applies when finding contradictions (e.g., two entries de

- **Canonical source**: [`docs/glossary.md`](../../docs/glossary.md) (Maintenance section also summarizes triggers; this rule is the operational expansion)
- **Acceptance check**: `acceptance-check.js` Q9 — Orchestrator's mechanical verification step during PR review
- **Sibling rule**: [`pre-pr-completeness.md`](pre-pr-completeness.md) — covers process completeness for new mechanisms; this rule is adjacent (terminology) and orthogonal (Gap-Scan does not include glossary checks)
- **Sibling rule**: [`pre-pr-completeness.md`](pre-pr-completeness.md) — covers process completeness for new mechanisms; this rule is adjacent (terminology) and orthogonal (Gap-Scan does not perform glossary judgment). **The orthogonality forbids duplicating the substance, not pointing at it.** Gap-Scan Q1.7 is a one-line recall point that sends the reader here; the trigger list and the drift-handling tree stay in this file as their single writer. A future reader should not "restore" the orthogonality by deleting that pointer — it was added (2026-08-20) precisely because recall, not judgment, was the layer that was missing: two PRs in two days reached the acceptance check with the entry absent, and the author had no step in their flow that would have surfaced this rule.
- **Future automation**: Issue [#671](https://github.com/ms2sato/agent-console/issues/671) — referenced-but-not-defined linter (separate concern, this rule remains the manual gate until the linter lands)

## How this rule is expected to evolve
Expand Down
2 changes: 2 additions & 0 deletions .claude/rules/pre-pr-completeness.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Before opening a PR that introduces a **new skill, script, rule, file type, or c
- If a similar mechanism exists: is this new thing a genuine extension, a replacement, or a duplicate? Duplicate → stop and reuse. Extension → cross-link. Replacement → document migration.
- **1.5 (cross-doc citation sub-check):** When this PR cites another document's technical claim (schema, API, command behaviour), verify the claim against the actual code, not just the other document. Documents describe intent; code describes reality. When the two drift, cite the code's current state. (Lesson: Sprint 2026-04-20 PR #677 claimed `multi-user-shared-setup.md` "declared REFERENCES users(id)"; CodeRabbit caught that migration v14 shipped without the REFERENCES DDL. The design doc described the spec; the code did something different.)
- **1.6 (adjacent-fallback sub-check):** When designing a new "X-fallback" / "X-recovery" / "X-retry" mechanism, do not stop at "grep the function I'm modifying". Also grep adjacent code paths for the same pattern: `catch` blocks within the same function family, sibling functions that handle the same failure mode, helper functions in the same file with `force` / `fallback` / `recovery` / `retry` keywords. The risk is **duplicating existing recovery logic** because the new mechanism's intent is described in different words than the existing one. Read the full function body of any nearby `catch (error)` block before committing to the design. (Lesson: Sprint 2026-06-26 PR #897 — agent designed a new `pruneWorktrees` helper + a dedicated orphan-recovery branch in `WorktreeService.removeWorktree`, without auditing `lib/git.ts:removeWorktree`'s existing force-fallback catch block which already did `fs.rm` + `git worktree prune` for the same orphan case. Owner caught the duplicate during review. The agent had grepped `removeWorktree` for callsites but did not read the function body or the adjacent catch block.)
- **1.7 (glossary recall sub-check):** When this PR introduces a new domain concept — an exported type or interface, a DB table or column, an API endpoint or MCP tool parameter — check it against `glossary-maintenance.md`'s trigger list and add the `docs/glossary.md` entry in the same PR if it matches. **The judgment lives there, not here.** This item is a recall point, not a second copy of the decision tree: do not restate the triggers or the drift-handling steps in this file. (Lesson: Sprint 2026-08-20 PRs [#1373](https://github.com/ms2sato/agent-console/pull/1373) and [#1384](https://github.com/ms2sato/agent-console/pull/1384) both reached the Orchestrator's acceptance check with the glossary entry missing. The #1384 delegate's retrospective identified the mechanism precisely: they had the glossary rule loaded and did not actively exclude it — their pre-implementation checklist was built from the AC plus the Orchestrator's emphasis, and a glossary step was simply never in the flow. Of the three layers that could catch this — AC drafting, this checklist, and acceptance-check Q9 — only Q9 was doing so, because this one had no entry at all.)

2. **Is the invocation or trigger of this new thing documented in a canonical procedure?**
- If it is a script or a skill that needs to run at a specific point, find where that point is described (e.g., `core-responsibilities.md §N`, `sprint-lifecycle.md`, or equivalent)
- Add the invocation instruction there in the same PR
Expand Down
16 changes: 16 additions & 0 deletions .claude/rules/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,22 @@ Claims of the form "**still waiting on** X" are the highest-risk shape, because

(Lessons, both Sprint 2026-08-05: the Architect held "PR #1270 is awaiting owner gate" across two days of intermittent turns, restating it in each status summary without re-reading, then raised an urgent warning that a commit-message keyword would close an Issue on merge — the PR had merged two days earlier and the Issue had closed with it. Separately, the Orchestrator left a self-check timer whose action text still described a PR merged hours before; it fired repeatedly while a delegate's completed PR sat unreviewed for six hours, and the stall was surfaced by the owner asking what the hold-up was, not by the timer.)

## Cheap refutation: universal claims

A sister criterion to Inference vs Verification, and a different axis. That rule asks *which signal you are treating as ground truth*. This one asks *what shape the claim has*, regardless of who made it.

**When a claim is universal — "nowhere else in the codebase", "always", "never", "none of them", "every" — estimate what it would cost to find one counterexample before accepting it.** Usually that is a single `ls` or `grep`. Run it.

The asymmetry is what makes this worth a rule. Refuting a universal costs one command; accepting a false one costs everything built on top of it, because a universal claim is what people stop searching after. "There is no precedent anywhere" ends the search. "There is no test for this elsewhere either" ends the objection.

It fires on the claim's form, not its source — a subagent's report, a review comment, a design doc, or your own reasoning from ten minutes ago.

**The boundary: this is not "distrust universal claims". It is "price the refutation".** Some universals are expensive to refute — "this distributed system never deadlocks" is not settled by a grep, and needs its own kind of verification. The criterion fires only when a counterexample search is cheap. There, one command before accepting wins on expected value; everywhere else, use the verification the claim actually calls for.

This names a point several existing disciplines already circle: the vacuous truth of `[].every()` in boundary-value testing, and the way an "accepted risk" paragraph can quietly remove something from the verification surface. All three are the same shape — a universal, an empty set, or a negation, cheap to state and expensive to have wrong.

(Lessons, both Sprint 2026-08-20: a specialist reported "no dedicated sibling test anywhere else in the codebase either", which the delegate refuted with one `ls` — the precedent existed and the gap was real, requiring a re-delegation. Separately, the Orchestrator inferred that a `queryFn` signature trap was silently affecting 18 sibling call sites, framed it to the owner as a probable latent-debt finding, and had a delegate measure it: `typecheck` catches it at every site. Both claims were plausible, both were refutable in under a minute, and only one of them was actually checked before it travelled.)

## Commands

```bash
Expand Down
Loading