aboutsummaryrefslogtreecommitdiff
path: root/.ai/session-context.org
diff options
context:
space:
mode:
Diffstat (limited to '.ai/session-context.org')
-rw-r--r--.ai/session-context.org151
1 files changed, 0 insertions, 151 deletions
diff --git a/.ai/session-context.org b/.ai/session-context.org
deleted file mode 100644
index 8c3afba..0000000
--- a/.ai/session-context.org
+++ /dev/null
@@ -1,151 +0,0 @@
-#+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.