Skip to content
Merged
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
7 changes: 7 additions & 0 deletions exact_dot_claude/rules/git-hazards.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ claude-plugins #1979→#1987):
recomputes `mergeable` asynchronously; `gh pr merge` right after a push
fails with "not mergeable" on a perfectly clean PR. Poll
`gh pr view <n> --json mergeable` until it leaves `UNKNOWN`.
- **Waiting for CI races check *registration*, not just completion.** A loop on
"zero pending checks" can exit **immediately** after a push/`update-branch`:
zero pending is trivially true before the jobs are registered. Observed
2026-07: `state=CLEAN` on a **single** check while three CI jobs had not yet
appeared — merging there merges untested. Gate on **both** nothing-pending
**and** `--jq 'length'` ≥ the expected check count. Same root cause as the
mergeability race above: an async field read once, too early.

- **Check** before every force-push: `git log --oneline origin/main..<sha>` —
expect *exactly* the child's commits, nothing more, never empty.
Expand Down
18 changes: 18 additions & 0 deletions exact_dot_claude/rules/tool-use-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,24 @@ the doctored line contradicted an earlier direct `Read` of the same file.
- **Prefer the Grep tool** over `rg` in Bash: it has no `--replace` surface, so
this class of error cannot occur.

## A rejected flag looks exactly like "no results"

Any `cmd … | jq/grep` whose **non-zero exit** yields empty stdout masquerades as
a legitimate empty result. Worst case is a **dedup step**: you conclude nobody
reported the bug and file a duplicate.

Live instance: `gh search issues --state all` is invalid (that flag takes only
`{open|closed}`; `all` belongs to `gh issue list`). It prints usage to stderr,
so a `--jq` pipeline emits nothing — six consecutive false "no duplicate"
verdicts. Use `gh api --paginate "repos/O/R/issues?state=all"` + `grep` instead
(it returns PRs too; discriminate on `.pull_request`).

**Control-test every negative that gates an action.** Re-run the same command
shape against a term you know is present; if the control also returns nothing,
the tool is broken, not the result empty. One control run caught all six above.
This is `never-fabricate-test-identifiers.md`'s known-good control, applied to
search.

## WebFetch — do not retry the same failing URL

| Failure | Try |
Expand Down
12 changes: 11 additions & 1 deletion tests/test-claude-context-budget.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,17 @@ GLOBAL_CLAUDE_MD="exact_dot_claude/CLAUDE.md"
# pointers). Headroom is deliberate but small: hitting the budget should
# trigger a cleanup pass, not a bump. Ratchet DOWN when cleanups land;
# raising it needs a justification in the commit message.
TOTAL_BUDGET_BYTES=110000
#
# 2026-07-28 → 114,000. Justification: the surface had reached 109,998 of
# 110,000 (2 bytes free), so the budget had stopped being a cleanup trigger
# and become a hard stop on *any* new rule content. The additions that hit it
# were compressed ~50% first and both host files brought back under
# PER_FILE_CAP_BYTES. The cleanup pass is deferred, not skipped — the standing
# candidate is exact_dot_claude/rules/multi-model-delegation.md (~6.6 kB),
# which largely duplicates the agent-patterns-plugin:multi-model-delegation
# skill and is a CONSOLIDATE per meta-context-diet; it was being edited by a
# concurrent session at the time. Ratchet back toward 110,000 once it lands.
TOTAL_BUDGET_BYTES=114000
# Largest unconditional rule at introduction: 8,758 bytes.
PER_FILE_CAP_BYTES=10000

Expand Down
Loading