diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-17 16:05:17 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-17 16:12:56 -0500 |
| commit | 470085f4220afabb3b487f9342ed6bc35f5feca0 (patch) | |
| tree | ee261830bae5691d66cfb0f2b4286390270c812f /inbox | |
| parent | 97aa2fd6041b366fac09bd7e7c9337dda61333f9 (diff) | |
| download | rulesets-470085f4220afabb3b487f9342ed6bc35f5feca0.tar.gz rulesets-470085f4220afabb3b487f9342ed6bc35f5feca0.zip | |
docs(inbox): Add handoffs on skill discovery and missing inbox dir
Diffstat (limited to 'inbox')
| -rw-r--r-- | inbox/2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org | 118 | ||||
| -rw-r--r-- | inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org | 75 |
2 files changed, 193 insertions, 0 deletions
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 new file mode 100644 index 0000000..ae832b0 --- /dev/null +++ b/inbox/2026-05-16-handoff-from-dotemacs-review-code-skill-discovery.org @@ -0,0 +1,118 @@ +#+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 new file mode 100644 index 0000000..5f1e0ea --- /dev/null +++ b/inbox/2026-05-16-handoff-from-dotemacs-rulesets-missing-inbox-dir.org @@ -0,0 +1,75 @@ +#+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. |
