aboutsummaryrefslogtreecommitdiff
path: root/.ai/session-context.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-06 21:59:52 -0500
committerCraig Jennings <c@cjennings.net>2026-05-06 21:59:52 -0500
commitd81b23ad6b6e437dfe3c338a00a4be39bc555146 (patch)
tree2d4b0d7890fd1fc70d81282b81fed2808c28a106 /.ai/session-context.org
parent201377f57430ef28d02e703a2191434bbee55c75 (diff)
downloadrulesets-d81b23ad6b6e437dfe3c338a00a4be39bc555146.tar.gz
rulesets-d81b23ad6b6e437dfe3c338a00a4be39bc555146.zip
chore(ai): initialize project notes and Claude tooling surfaces
Replace the seed notes.org with project-specific context (layout, install modes, task tracker location, recent inflection point). Bring in the synced template surfaces (protocols, workflows, scripts, references, retrospectives, someday-maybe) as tracked content for this content/documentation project.
Diffstat (limited to '.ai/session-context.org')
-rw-r--r--.ai/session-context.org151
1 files changed, 151 insertions, 0 deletions
diff --git a/.ai/session-context.org b/.ai/session-context.org
new file mode 100644
index 0000000..8c3afba
--- /dev/null
+++ b/.ai/session-context.org
@@ -0,0 +1,151 @@
+#+TITLE: Session Context — first-session setup + Makefile picker + work/deepsat reorg + skill-budget test
+#+AUTHOR: Craig Jennings & Claude
+#+DATE: 2026-05-06
+
+* Summary
+
+** Active Goal
+
+*Picking up after a session restart.* The first thing to do is verify the in-flight test: did adding =disable-model-invocation: true= to =~/code/rulesets/.claude/commands/arch-document.md= remove its description from the model's preloaded skill listing? See the *Next Steps* section for the decision tree.
+
+** Decisions
+
+- Project type: content/documentation. =.ai/= is committed.
+- =install-lang= should fzf-pick =LANG== when not set, mirroring how =PROJECT== was already picked.
+- Move =~/code/deepsat/= → =~/projects/work/deepsat/code/= and rename =~/projects/career/= → =~/projects/work/=. No backwards-compat symlinks.
+- Test the skill-budget hypothesis on *one* command (=arch-document=) before mass-editing the other 17.
+- Forward-rewrite forward-looking org files in =work/= to point at the new path. Leave session archives untouched.
+
+** Data Collected / Findings
+
+- Per Anthropic's official docs (=code.claude.com/docs/en/skills.md=), "Custom commands have been merged into skills." Moving a file from =~/.claude/skills/= to =~/.claude/commands/= does *not* by itself reduce what gets preloaded into the model's context. The frontmatter field =disable-model-invocation: true= is the documented lever for excluding a command from model-side invocation while keeping =/<name>= routing for the user. Whether it also removes the entry from =SLASH_COMMAND_TOOL_CHAR_BUDGET= accounting is *not stated explicitly* in the docs — that's why we're testing one command first.
+- The 18 converted commands in =~/code/rulesets/.claude/commands/= had =description:= and some =argument-hint:=, but none had =disable-model-invocation: true=. That's the gap.
+- =~/.claude/settings.json= is a symlink resolving to =/home/cjennings/code/rulesets/.claude/settings.json=. Edits to "user-scope" Claude Code settings actually land in the rulesets repo as tracked changes.
+- =~/.gitconfig= resolves through =~/code/archsetup/dotfiles/common/.gitconfig=. Same pattern — edits to the gitconfig land in the archsetup dotfiles repo.
+- Python bundle ships a single file (=python-testing.md=); elisp ships more (CLAUDE.md, settings.json, hooks, githooks, gitignore-add). The new typescript bundle matches python's minimalism: just =typescript-testing.md=.
+- Inside =~/projects/work/.gitignore=, the existing =code= rule already covers =deepsat/code/= (no slashes in the rule means it matches any path component named =code=). No new gitignore line needed.
+- Bug found and fixed in the Makefile change: =$(LANG)= silently inherits =en_US.UTF-8= from the env, bypassing the new picker. Fixed by checking =$(origin LANG)= and blanking when origin is =environment=. The old code had the same latent bug.
+
+** Files Modified
+
+*** Rulesets repo (=~/code/rulesets/=)
+- =Makefile= — added =pick_lang_shell= macro mirroring =pick_project_shell=, wired into =install-lang= and =diff= recipes, blanked =$(LANG)= when origin is environment.
+- =languages/typescript/claude/rules/typescript-testing.md= — new file. Vitest-canonical TypeScript testing rules with notes for Mocha+Chai, Jest, and Angular Karma legacy idioms. Covers RTL, MSW, =it.each=, async patterns, and TS-specific discipline (no =any=, prefer =satisfies= over =as=, etc.).
+- =languages/typescript/= directory tree created.
+- =.claude/commands/arch-document.md= — added =disable-model-invocation: true= to frontmatter as the budget-test target.
+- =.ai/notes.org= — replaced template starter with project-specific context. Notes that both =elisp= and =python= bundles ship (later corrected to add =typescript=).
+- =.ai/session-context.org= — this file.
+
+*** Other repos / configs
+- =~/projects/work/= — renamed from =~/projects/career/= (=mv=). Then 14G atomic move of =~/code/deepsat/= → =~/projects/work/deepsat/code/=. =git status= shows 21 modified files (1 pre-existing =M .ai/workflows/wrap-it-up.org= + 20 from forward-rewrites I did).
+- =~/projects/claude-templates/.ai/workflows/daily-prep.org= — path leak fixed (=~/code/deepsat/...= → =~/projects/work/deepsat/code/...=).
+- =~/code/archsetup/dotfiles/common/.gitconfig= (resolved from =~/.gitconfig=) — =includeIf gitdir= path updated to =~/projects/work/deepsat/code/=. Verified it fires: =git config --get user.email= inside the moved tree returns =craig.jennings@deepsat.com=.
+- =~/.emacs.d/modules/dirvish-config.el= line 262 — bookmark renamed from =pcr= to =pwk=, path updated to =~/projects/work/=.
+- =~/.emacs.d/.ai/notes.org= — two late-April reminders rewritten with new path.
+- =~/sync/org/drill/deepsat.org= — symlink retargeted to =/home/cjennings/projects/work/deepsat.org=.
+- =~/projects/career/= no longer exists. =~/code/deepsat/= no longer exists.
+
+** Next Steps
+
+*** First thing on restart: verify the skill-budget test
+
+The system-reminder Claude Code injects at session start lists every skill / command the model can invoke, with full description text. Before this session ended, =arch-document= was in that list with its full description.
+
+I added =disable-model-invocation: true= to its frontmatter. Three possible outcomes on next session:
+
+1. *=arch-document= is absent entirely* from the system-reminder skill list, and the truncation warning's "21 dropped" count drops to 20 (or the warning disappears if it was borderline). → The flag works. Apply the same one-line frontmatter edit to the other 17 converted commands. The list to edit:
+ - =arch-decide.md=, =arch-design.md=, =arch-evaluate.md=, =brainstorm.md=, =c4-analyze.md=, =c4-diagram.md=, =codify.md=, =create-v2mom.md=, =finish-branch.md=, =prompt-engineering.md=, =refactor.md=, =respond-to-cj-comments.md=, =respond-to-review.md=, =review-code.md=, =security-check.md=, =start-work.md=, =update-config.md=
+ - (=arch-document.md= already done.)
+ - Plus =keybindings-help.md= and =simplify.md= and =fewer-permission-prompts.md= and =loop.md= and =schedule.md= and =claude-api.md= if those should also be user-only.
+2. *=arch-document= still appears with full description* → flag does *not* exclude from budget. Move on to plan B: either (a) raise =skillListingBudgetFraction= / =SLASH_COMMAND_TOOL_CHAR_BUDGET= to ~5% in =~/code/rulesets/.claude/settings.json= (cost: ~8k tokens/session, but a tracked change in rulesets), or (b) /skills UI to disable specific entries. Re-research the field's exact effect via =claude-code-guide= agent if the docs were unclear.
+3. *=arch-document= appears but truncated / different in some way* → partial effect. Investigate before applying broadly.
+
+*** Other in-flight work (uncommitted, do at Craig's pace)
+
+- =~/projects/claude-templates/= has 1 modified file (=.ai/workflows/daily-prep.org=). Commit + push so other machines pick up the path correction on their next startup sync.
+- =~/projects/work/= has 21 modified files. The 1 pre-existing =M .ai/workflows/wrap-it-up.org= is Craig's own prior in-flight change — I did not touch it. The other 20 are my forward-rewrites of =~/code/deepsat/...= → =~/projects/work/deepsat/code/...= and =~/projects/career...= → =~/projects/work=. Worth eyeballing the assets/ entries (3 of them: =deepsat/assets/2026-03-02-daily-prep.org=, =2026-03-25-deepsat-vision-analysis.org=, =2026-03-31-se41-analysis-quality-report.org=). They're dated analysis files; if Craig considers those historical archives like sessions, =git checkout deepsat/assets/2026-03-*.org= reverts just those three.
+- =~/code/rulesets/= has staged/unstaged changes: =.claude/settings.json= (pre-existing M from session start), the Makefile, the new typescript bundle, the =.ai/= files, the arch-document frontmatter. Multiple logical commits possible — Makefile fzf picker, typescript bundle, =.ai/= initialization, skill-budget test.
+- =~/code/archsetup/= has 1 modified file (=dotfiles/common/.gitconfig=). Track + commit alongside any other dotfile cleanup Craig has in flight there.
+- =~/.emacs.d/= — dirvish-config.el and =.ai/notes.org= were edited. If =.emacs.d= is a tracked repo, that's two changes to commit there too.
+
+*** Things still on the table (mentioned but not actioned)
+
+- The skills/commands not yet given =disable-model-invocation: true= treatment that probably *should* stay model-invocable (e.g. =add-tests=, =debug=, =five-whys=, =frontend-design=, =humanizer=, =pairwise-tests=, =playwright-js=, =playwright-py=, =root-cause-trace=). These are the ones Claude needs to know about so it can recommend them. The plan is to leave those alone — only convert the user-triggered =/commands=.
+- =languages/typescript/= bundle is minimal (just =typescript-testing.md=). If Craig wants more for it later — a =typescript.md= for general code style, hooks, etc. — that's a clean next step.
+- The =/respond-to-review= and =/respond-to-cj-comments= command files have very long descriptions (the reason they triggered the "exceeds per-entry cap" warning earlier). Either trim those descriptions, or rely on =disable-model-invocation: true= to drop them from the listing entirely once the test confirms the lever works.
+
+* Session Log
+
+** First-session workflow
+
+Craig kicked off "let's run the first session workflow" after the startup workflow flagged the seed notes.org with the first-session pointer.
+
+Step 1 — git/.ai policy. Repo is at =git@cjennings.net:rulesets.git=, single =origin= remote, no GitHub. Craig confirmed it's a content/documentation project, so =.ai/= gets committed normally (not gitignored).
+
+Step 2 — project orientation. Craig described the project as a personal Claude Code rules + skills repo. Quick directory walk confirmed the layout from =README.org=: top-level skill dirs, =claude-rules/= for global rules, =languages/= bundles, =.claude/= local config, =Makefile= entry points, =todo.org= at root (~73 KB).
+
+Step 3 — current state. Craig flagged the recent skills→commands refactor (commit =aa69245=) as the inflection point worth capturing in notes.org.
+
+Step 4 — wrote =.ai/notes.org= with Project-Specific Context, Pending Decisions, and Active Reminders subsections. Removed the "If this is the first session" pointer in the same write.
+
+Step 5 — Craig wants to work on something specific that isn't on =todo.org= yet. Waiting for him to describe it before continuing.
+
+** install-lang fzf picker for LANG
+
+Craig flagged that =make install-lang= already fzf-picks the *project* directory (via =pick_project_shell=) when =PROJECT== isn't set, but errors out immediately when =LANG== isn't set. Symmetric work was incomplete.
+
+Added =pick_lang_shell= as a sibling macro in the Makefile, structured the same way as =pick_project_shell=: bail with a clear error if fzf is missing, otherwise pipe =$(LANGUAGES)= to =fzf --prompt="Language> "= and exit cleanly on Esc / no selection. Wired the picker into =install-lang= and =diff=, dropped their =test -n "$(LANG)"= guards, and adjusted the help strings so =[LANG=<lang>]= reads as optional.
+
+Caught a real bug during the dry-run: =$(LANG)= silently expanded to =en_US.UTF-8= because =LANG= is also the standard POSIX locale env var and Make inherits env vars into its variable namespace. The old code had this bug too — it just failed less visibly inside =install-lang.sh=. Fixed by checking =$(origin LANG)= and blanking the variable when it came from the environment, so command-line =LANG=elisp= and in-file assignments still work.
+
+Verified with =make -n= dry-runs across four invocation patterns (no args, =LANG== only, both set, =install-elisp= sub-make pass-through). Then ran a real install into a temporary git sandbox — copied the four generic rules, the Elisp ruleset, hooks, =CLAUDE.md=, and =.gitignore= entries. All clean.
+
+Also updated notes.org to reflect that both =elisp= and =python= bundles ship (earlier first-pass note had said only =elisp= shipped).
+
+** Python install + TypeScript bundle scaffolding
+
+Craig asked to install python + typescript bundles into =~/projects/career=. Initial scan found:
+- No =typescript= bundle existed (only elisp + python).
+- Career's CLAUDE.md was =D=-deleted in the working tree.
+- I incorrectly flagged that running install would re-create CLAUDE.md, then corrected myself: python bundle has no CLAUDE.md template, so the install wouldn't touch it.
+- Craig restored CLAUDE.md from HEAD via =git restore=.
+
+Ran =make install-lang LANG=python PROJECT=/home/cjennings/projects/career=. Cleanly added 5 rule files to =.claude/rules/=. =CLAUDE.md= untouched.
+
+For typescript: Craig redirected to =~/code/deepsat= (not career) for the install target. Inventoried deepsat's test stacks (Mocha+Chai for backend, Vitest+RTL+Playwright+MSW for the modern frontend, Angular Karma elsewhere). Drafted =languages/typescript/claude/rules/typescript-testing.md= mirroring the python bundle's shape — Vitest-canonical with notes for the legacy idioms, RTL query priorities, MSW for network mocking, =it.each= for parametrize, TS-specific discipline (no =any=, prefer =satisfies=).
+
+Lint passed. Installed into =~/code/deepsat= cleanly. Flagged that =~/code/deepsat= itself isn't a git repo (it's a container of inner repos), so the bundle landed at the container level.
+
+** Removed-claude-assets pivot → directory reorg
+
+Craig asked to remove all .claude/CLAUDE.md/.ai/AGENTS.md from deepsat subdirs (keeping the container-level one). Scan found 16 untracked items across 4 inner git repos. Before running =rm=, Craig stepped back — asked whether =~/code/deepsat= should live somewhere under =~/projects= instead. Quick layout analysis showed =~/projects/career/deepsat/= was already partly built out (notes, an empty =code/= placeholder, a =doc-staging= symlink). No path-hardcoding in shell, gitconfig, or emacs init beyond the =.gitconfig= includeIf and one =dirvish-config.el= bookmark.
+
+Recommendation accepted: move =~/code/deepsat= into =~/projects/career/deepsat/code= AND rename =career= → =work=. No backwards-compat symlinks. Rename the dirvish bookmark. Forward-rewrite emacs auto-memory and forward-looking org files in work/.
+
+Pre-flight scan caught: =~/.gitconfig= has =[includeIf "gitdir:~/code/deepsat/"]= pointing at =~/.gitconfig-deepsat=. Inbound symlink =~/sync/org/drill/deepsat.org= pointing at the old career path. Dirvish line 262 with the =pcr= bookmark.
+
+Executed in phases:
+1. =mv ~/projects/career ~/projects/work=. Symlink retargeted.
+2. =rmdir= the empty =work/deepsat/code= placeholder. =mv ~/code/deepsat ~/projects/work/deepsat/code= (14G, atomic on same filesystem).
+3. Updated =~/.gitconfig= (via the archsetup symlink target). Verified the includeIf fires inside the moved tree — work identity =craig.jennings@deepsat.com= returns correctly.
+4. Renamed dirvish bookmark =pcr= → =pwk=, path → =~/projects/work/=.
+5. Forward-rewrites — initial pass on the 10 files I'd pre-flight scanned, then a sweep that caught 14 more I'd missed (the pre-flight regex was too narrow).
+6. Found a path leak in =~/projects/claude-templates/.ai/workflows/daily-prep.org= (template source, not just local copy). Updated the template so future startup syncs propagate the fix.
+
+Final verification: directories in correct state, bundle survived at new path, includeIf live, dirvish bookmark renamed, inbound symlink resolves, =.gitignore= already covers =deepsat/code= via the existing =code= rule. All clean.
+
+** Skill-budget investigation
+
+Craig saw "Skill listing will be truncated" in a session opened in the work directory. Asked whether it should be specific to work. Answer: no — it's a global (per-machine) condition driven by the count and length of skills + commands installed at =~/.claude/= (and via plugins). The work directory has no project-scope skills/commands, so what he sees there is the same thing he'd see anywhere.
+
+He then said: "I thought moving the skills to commands would give me the budget back. Can you check on site whether this is correct or not?" I dispatched the =claude-code-guide= agent against the official docs. Findings:
+
+- Custom commands have been merged into skills (per =code.claude.com/docs/en/skills.md=). Moving the file from =skills/= to =commands/= doesn't separate them in the loading model.
+- The frontmatter lever =disable-model-invocation: true= is the documented mechanism for "control who invokes a skill" — model vs user. The docs don't explicitly say this also removes the entry from the =SLASH_COMMAND_TOOL_CHAR_BUDGET= accounting, but it should follow logically.
+- The 18 converted commands in =~/code/rulesets/.claude/commands/= didn't have that field in their frontmatter — the conversion moved files but didn't add the gating.
+
+Craig also gave a feedback rule mid-investigation: "never guess. always check unless you've recently checked (the same session)." Saved as =feedback_never_guess.md= in auto-memory.
+
+Plan: add =disable-model-invocation: true= to *one* command (=arch-document=, since it's user-triggered and a clean test target), then restart the session and observe the system-reminder skill list. If =arch-document= is absent and the dropped count went from 21 to 20, the lever works and we'll apply the same edit to the other 17. If it still appears, we'll re-research.
+
+Craig asked to write this session-context.org so the post-restart session can pick up cleanly. *That's where we are now.* The =arch-document= edit is in. Awaiting restart.