aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
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.