aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--claude-rules/commits.md2
-rw-r--r--inbox/2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org118
-rw-r--r--inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org75
-rw-r--r--inbox/lint-followups.org30
4 files changed, 2 insertions, 223 deletions
diff --git a/claude-rules/commits.md b/claude-rules/commits.md
index 9e1a8e0..41d17e7 100644
--- a/claude-rules/commits.md
+++ b/claude-rules/commits.md
@@ -272,6 +272,8 @@ Run the `review-code` skill against the change:
- Before a PR: `/review-code` (branch diff against `main` merge-base)
- Before commenting on someone else's PR: `/review-code <PR#>`
+**Discovery check.** If `/review-code` doesn't appear in the session's available-skills list, check `~/.claude/commands/review-code.md` and `./.claude/commands/review-code.md` on disk before declaring it unavailable. The available-skills enumeration covers plugin-installed skills but can miss user commands under `~/.claude/commands/`, which are still routable as slash-commands. If either file exists, surface the discrepancy to the user before falling through to the trivial-one-liner exception in Step 2 — don't auto-skip.
+
Surface **all** findings to the user: Critical, Important, and Minor.
**Default block:** any Critical or Important finding stops the flow. Fix the
diff --git a/inbox/2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org b/inbox/2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org
deleted file mode 100644
index ae832b0..0000000
--- a/inbox/2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org
+++ /dev/null
@@ -1,118 +0,0 @@
-#+TITLE: Handoff: =/review-code= skill missing from session menu
-#+FROM: dotemacs (~/.emacs.d)
-#+DATE: 2026-05-16
-
-* Context
-
-During a =/start-work= invocation in =~/.emacs.d= on 2026-05-15, Phase 7
-(Review-and-Publish handoff) called for =/review-code --staged= before
-the commit. I declared the skill unavailable based on the session's
-available-skills system-reminder list and proceeded under the
-trivial-one-liner exception in =commits.md=.
-
-After the commit landed and the chore-close followed, Craig asked: "what
-did you do that you couldn't see it?"
-
-* What I missed
-
-Checking the filesystem after the fact:
-
-- =/home/cjennings/.claude/commands/review-code.md= exists.
-- =/home/cjennings/code/rulesets/.claude/commands/review-code.md= is the
- canonical source.
-- =/home/cjennings/.claude/commands/start-work.md= also exists — and
- =/start-work= is the workflow I just executed.
-
-So =/review-code= is on disk and routable as a slash-command. The
-session's available-skills system-reminder list contained only the
-plugin-installed skills (=pairwise-tests=, =root-cause-trace=, =voice=,
-=debug=, =init=, =review=, =security-review=, etc.) — not Craig's custom
-commands at =~/.claude/commands/=.
-
-I treated the available-skills list as authoritative. I never ran =ls
-~/.claude/commands/= to verify.
-
-* The rule that produced the dead end
-
-Claude Code's session instructions say:
-
-#+begin_quote
-Only invoke a skill that appears in that list, or one the user explicitly
-typed as /<name> in their message. Never guess or invent a skill name
-from training data.
-#+end_quote
-
-That rule is correct for preventing hallucinated skill calls. But it
-produces a false negative for custom commands at =~/.claude/commands/=
-that are routable via slash-command but absent from the session-time
-available-skills enumeration. The instruction has no opt-in for "verify
-against filesystem before declaring unavailable."
-
-The "user explicitly typed =/<name>=" branch is also a near-miss: Craig
-typed =/start-work=, which routed correctly because it was loaded
-inline. =/start-work='s workflow body referenced =/review-code= as part
-of Phase 7. The "user typed it" rule reads strictly — Craig didn't type
-=/review-code= himself — so I treated the workflow-internal reference as
-not user-explicit and skipped invocation.
-
-The trivial-one-liner exception in =commits.md= happened to give me an
-honest off-ramp ("dictated subject, skip draft-file + voice"), so I took
-it without surfacing the discrepancy as the actual blocker.
-
-* Narrow failure
-
-I noted the discrepancy in chat ("=/review-code= isn't in the available
-skills here") and moved on without verifying against the filesystem. One
-=ls ~/.claude/commands/= would have surfaced the file. I had Bash; I
-just didn't think to use it.
-
-* Proposed adjustments
-
-Two angles, each tractable on the rulesets side:
-
-1. *Tighten the "skip =/review-code=" off-ramp in =commits.md=.* Step 1
- today says: "Run =/review-code --staged= before each commit, or
- =/review-code= on the whole branch before the PR. Block on Critical
- or Important findings." Add a sub-step: "If =/review-code= isn't in
- the session's available-skills list, check
- =~/.claude/commands/review-code.md= and
- =./.claude/commands/review-code.md= on disk; if the file exists,
- surface the discrepancy to the user before deciding to skip — don't
- auto-skip via the trivial-one-liner exception."
-
-2. *Reconsider how =~/.claude/commands/= surfaces in available-skills.*
- Out of scope for the rulesets repo itself, but worth flagging.
- Claude Code's session-init lists plugin skills as "available" but
- not user commands. The plugin/rules layer can't change Claude Code's
- behavior. The workaround in #1 only helps once the agent thinks to
- check. Trip-wire phrasing: "if the skill isn't in the list, ls before
- declaring missing."
-
-* What I'd do differently
-
-A one-line check before declaring any =/<skill>= unavailable:
-
-#+begin_src bash
-ls ~/.claude/commands/<skill>.md
-ls ./.claude/commands/<skill>.md
-#+end_src
-
-If either exists: read it and run inline, or surface the discrepancy.
-
-* Outcome of the dotemacs session
-
-Original task shipped clean:
-
-- =3b4c8d8 fix(ai-config): Ensure gptel-magit is installed via use-package=
-- =26572be chore(todo): close transient-setup gptel-magit fix=
-
-The =/review-code= skip didn't hurt anything (trivial 2-line org-keyword
-change). The /reasoning/ I used to skip was wrong — I assumed the skill
-didn't exist, when it did.
-
-* Filing
-
-Rule/workflow-improvement signal, not a code bug. Belongs in rulesets's
-=todo.org= as a tracked task if it warrants one, or in =notes.org= /
-relevant rule file as a reminder. The narrow ask: add a "check disk
-before declaring skill unavailable" line to =commits.md= Step 1.
diff --git a/inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org b/inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org
deleted file mode 100644
index 5f1e0ea..0000000
--- a/inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org
+++ /dev/null
@@ -1,75 +0,0 @@
-#+TITLE: Handoff: rulesets has no top-level =inbox/= directory
-#+FROM: dotemacs (~/.emacs.d)
-#+DATE: 2026-05-16
-
-* Context
-
-While trying to deliver a cross-project handoff from the dotemacs session
-(~/.emacs.d) to the rulesets project, I discovered that
-=~/code/rulesets/= has no top-level =inbox/= directory.
-
-The =inbox-send.py= script (the canonical mechanism documented in
-=claude-rules/cross-project.md=) requires the target project to have
-*both* =.ai/= AND =inbox/=:
-
-#+begin_src python
-def is_project(path: Path) -> bool:
- """A project has a `.ai/` marker AND a top-level `inbox/` directory."""
- return (path / ".ai").is_dir() and (path / "inbox").is_dir()
-#+end_src
-
-(=.ai/scripts/inbox-send.py:61-62=)
-
-So =inbox-send.py --list= did not list =rulesets= as an available target,
-even though it has =.ai/=. I worked around this by:
-
-1. =mkdir -p ~/code/rulesets/inbox/=
-2. =Write= the handoff file directly to that new directory.
-
-This handoff file landed at:
-=~/code/rulesets/inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org=
-
-(There's a sibling handoff =2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org=
-also in this inbox from the same session.)
-
-* What's missing
-
-- =~/code/rulesets/inbox/= didn't exist before this session.
-- The directory is not gitignored (per the project's =.gitignore=).
-- No prior commits reference =inbox/= except for the =inbox-send.py=
- script itself.
-
-* Why this matters
-
-The rulesets project is an active Claude-managed project — it has
-=.ai/protocols.org=, =.ai/sessions/=, a startup workflow, and its own
-=todo.org=. Without an =inbox/= dir:
-
-- Cross-project handoffs from other projects can't land via the canonical
- =inbox-send= mechanism.
-- The rulesets startup workflow has no inbox-processing step that would
- pick up cross-project messages on session start.
-- I had to bypass =inbox-send.py= and =Write= directly, which skips
- filename auto-derivation and source-project provenance handling.
-
-The =claude-templates/= subdir inside rulesets also has =.ai/= but no
-=inbox/=, with the same effect.
-
-* What to fix
-
-Two changes, low effort:
-
-1. *Create =~/code/rulesets/inbox/= and commit it.* Add a =.gitkeep= or
- a README so the directory exists in the tree from the start. Once it
- exists, =inbox-send.py --list= will discover the project and future
- cross-project handoffs will route normally.
-
-2. *(Optional) Same for =~/code/rulesets/claude-templates/inbox/=.* If
- claude-templates is considered its own routable project rather than a
- subdir-only artifact, mirror the change there.
-
-* Filing
-
-This is project-hygiene signal — track in =todo.org= as a single quick
-fix (S effort, single =mkdir= + =.gitkeep= + commit), and the
-=inbox-send.py= discovery starts working automatically.
diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org
deleted file mode 100644
index 6fb4c0d..0000000
--- a/inbox/lint-followups.org
+++ /dev/null
@@ -1,30 +0,0 @@
-
-* 2026-05-16 lint-org follow-ups — todo.org
-** TODO line 2153 — misplaced-heading — Possibly misplaced heading line
-
-* 2026-05-16 Sat — Date coverage: [#A] / [#B] tasks without DEADLINE or SCHEDULED
-Review each: add a date, drop the priority, or confirm 'no-date by intent' inline.
-- 10: ** TODO [#A] Implement task-review daily-habit per spec
-- 28: ** DOING [#A] Check that memories are sync'd across machines via git.m
-- 58: ** TODO [#A] Build =create-documentation= skill for high-quality project/product docs
-- 692: ** TODO [#A] Review pass: tighten skills and rulesets after 2026-05-04 audit
-- 1221: ** TODO [#B] Build =ov-1= skill for DoDAF OV-1 (High-Level Operational Concept Graphic)
-- 1295: ** TODO [#A] Build =/update-skills= skill for keeping forks in sync with upstream
-- 1621: ** TODO [#B] Add =make remove= for interactive ruleset removal via fzf
-- 1686: ** TODO [#B] Document the =mcp/= install pipeline in =mcp/README.org=
-- 1773: ** TODO [#B] Phase A startup blind to =claude-templates/inbox/= post-fold :bug:fold:
-
-* 2026-05-17 lint-org follow-ups — todo.org
-** TODO line 2153 — misplaced-heading — Possibly misplaced heading line
-
-* 2026-05-17 Sun — Date coverage: [#A] / [#B] tasks without DEADLINE or SCHEDULED
-Review each: add a date, drop the priority, or confirm 'no-date by intent' inline.
-- 10: ** TODO [#A] Implement task-review daily-habit per spec
-- 28: ** DOING [#A] Check that memories are sync'd across machines via git.m
-- 58: ** TODO [#A] Build =create-documentation= skill for high-quality project/product docs
-- 692: ** TODO [#A] Review pass: tighten skills and rulesets after 2026-05-04 audit
-- 1221: ** TODO [#B] Build =ov-1= skill for DoDAF OV-1 (High-Level Operational Concept Graphic)
-- 1295: ** TODO [#A] Build =/update-skills= skill for keeping forks in sync with upstream
-- 1621: ** TODO [#B] Add =make remove= for interactive ruleset removal via fzf
-- 1686: ** TODO [#B] Document the =mcp/= install pipeline in =mcp/README.org=
-- 1773: ** TODO [#B] Phase A startup blind to =claude-templates/inbox/= post-fold :bug:fold: