Smaller findings from a Windows install: exec bit, CRLF re-install, lint, scaffold count, overhead #5

Open
opened 2026-09-13 14:45:35 +02:00 by solvreven · 0 comments

Field report from installing f498b6f on 2026-09-12 into a real, busy repository (Python app, ~1,500 tests, background jobs that write tracked data files, a 120 KB CLAUDE.md).

Environment: Windows 11, Git for Windows (bash 5.3.9, core.autocrlf=true from
the system gitconfig), Python 3.14 (python3 is the WindowsApps alias and works),
Claude Code 2.1.269 → 2.1.270.

How it was checked: the kit's own suite; the hooks driven exactly as
settings.json holds them; and four live headless claude -p sessions reading
the hook_response events. Nothing here was run on Linux or macOS.

These are design notes with untested proposals.

B2. The exec bit is not recorded when installing from Windows

install.sh runs chmod +x, but git on Windows does not record it
(core.filemode=false). Installed and committed from Windows, both hooks and
the lint script land as 100644. settings.json runs them by path, so on
Linux or macOS they fail with Permission denied. Hooks fail open, so that
failure is silent. Git Bash runs them by shebang anyway, so nothing looks
wrong on the machine that installed them.

This is inferred, not executed, since no Linux was available. We fixed our repo
with git update-index --chmod=+x.

Proposal: print git add --chmod=+x .claude/hooks/*.sh .claude/scripts/*.sh
in the installer's "Next steps", or run it when the target is a git repo.
Prefixing the commands with bash also works, but the merge's exact-match
dedupe would then add a second entry to existing installs.

B3. Re-installing on a CRLF checkout creates phantom modifications

The installer's sed rewrites the .claude/ machinery as LF. On an
autocrlf=true checkout that leaves four files showing M in git status,
while git diff --quiet reports no content change. That alone trips the Stop
guard.

Re-install also silently reverts local edits to SKILL.md and the hooks. That
is documented ("machinery is refreshed"), but it is easy to miss. It would help
to say where local policy should live instead.

B4. Lint cannot see a stale number

  • STALE compares dates, so commits later on the same day as updated are
    invisible.
  • Sources that are untracked, gitignored or URLs are never dated, and a
    page citing only those is reported LINT-CLEAN.

Most measured numbers come from exactly such sources: caches, APIs, generated
files.

Proposal: report UNDATED-SOURCE instead of clean, and compare commit
timestamps, for example by recording a SHA in frontmatter.

B5. Smaller things

  • Empty scaffold: SessionStart reports (3 pages, last update <install date>)
    when all three files are scaffolding. Count category pages only, or print
    empty.
  • Guard overhead: marker files accumulate in $TMPDIR and are never pruned.
    The guard costs ~460 ms per stop on Windows because Python starts before the
    cheap git checks.
  • Skill description: at 380 characters it gets dropped when many skills are
    installed. Claude Code truncates the skill listing on 200k-window models:
    27 skills, 8704 chars > 8000 budget showed - wiki with no description
    (observed on haiku; 1M-window models are unaffected). Under ~150 characters
    would survive.
  • "Error" label: Claude Code labels a designed Stop block
    stop-hook-error ("Stop hook error occurred") in stream-json. That is not the
    kit's doing, but a README line saves someone debugging the nudge as a failure.
    The interactive TUI was not checked.

What works well

  • The installer is careful: the merge is additive and idempotent, and wiki
    content is never overwritten.
  • The CLAUDE.md fragment is a self-contained section.
  • On Windows the Python probe correctly skips a broken python3.
  • Live, the SessionStart pointer reached the model verbatim, the wiki skill
    was registered and loaded with its body, and the once-per-session marker held
    across --resume.
  • Log-per-entry is a good fix for merge conflicts.

Companion issues from the same install: #3 (the Stop guard keys on the tree, not the session; B1 in the original numbering) and #4 (Windows defects with a tested patch; part A).

Field report from installing **f498b6f** on 2026-09-12 into a real, busy repository (Python app, ~1,500 tests, background jobs that write tracked data files, a 120 KB CLAUDE.md). **Environment:** Windows 11, Git for Windows (bash 5.3.9, `core.autocrlf=true` from the system gitconfig), Python 3.14 (`python3` is the WindowsApps alias and works), Claude Code 2.1.269 → 2.1.270. **How it was checked:** the kit's own suite; the hooks driven exactly as `settings.json` holds them; and four live headless `claude -p` sessions reading the `hook_response` events. **Nothing here was run on Linux or macOS.** These are design notes with untested proposals. ### B2. The exec bit is not recorded when installing from Windows `install.sh` runs `chmod +x`, but git on Windows does not record it (`core.filemode=false`). Installed and committed from Windows, both hooks and the lint script land as `100644`. `settings.json` runs them by path, so on Linux or macOS they fail with `Permission denied`. Hooks fail open, so that failure is **silent**. Git Bash runs them by shebang anyway, so nothing looks wrong on the machine that installed them. This is inferred, not executed, since no Linux was available. We fixed our repo with `git update-index --chmod=+x`. **Proposal:** print `git add --chmod=+x .claude/hooks/*.sh .claude/scripts/*.sh` in the installer's "Next steps", or run it when the target is a git repo. Prefixing the commands with `bash` also works, but the merge's exact-match dedupe would then add a second entry to existing installs. ### B3. Re-installing on a CRLF checkout creates phantom modifications The installer's `sed` rewrites the `.claude/` machinery as LF. On an `autocrlf=true` checkout that leaves four files showing `M` in `git status`, while `git diff --quiet` reports no content change. That alone trips the Stop guard. Re-install also silently reverts local edits to `SKILL.md` and the hooks. That is documented ("machinery is refreshed"), but it is easy to miss. It would help to say where local policy should live instead. ### B4. Lint cannot see a stale number - `STALE` compares **dates**, so commits later on the same day as `updated` are invisible. - Sources that are untracked, gitignored or URLs are **never dated**, and a page citing only those is reported `LINT-CLEAN`. Most measured numbers come from exactly such sources: caches, APIs, generated files. **Proposal:** report `UNDATED-SOURCE` instead of clean, and compare commit timestamps, for example by recording a SHA in frontmatter. ### B5. Smaller things - **Empty scaffold:** SessionStart reports `(3 pages, last update <install date>)` when all three files are scaffolding. Count category pages only, or print `empty`. - **Guard overhead:** marker files accumulate in `$TMPDIR` and are never pruned. The guard costs ~460 ms per stop on Windows because Python starts before the cheap git checks. - **Skill description:** at 380 characters it gets dropped when many skills are installed. Claude Code truncates the skill listing on 200k-window models: `27 skills, 8704 chars > 8000 budget` showed `- wiki` with no description (observed on haiku; 1M-window models are unaffected). Under ~150 characters would survive. - **"Error" label:** Claude Code labels a designed Stop block `stop-hook-error` ("Stop hook error occurred") in stream-json. That is not the kit's doing, but a README line saves someone debugging the nudge as a failure. The interactive TUI was not checked. ## What works well - The installer is careful: the merge is additive and idempotent, and wiki content is never overwritten. - The CLAUDE.md fragment is a self-contained section. - On Windows the Python probe correctly skips a broken `python3`. - Live, the SessionStart pointer reached the model verbatim, the `wiki` skill was registered and loaded with its body, and the once-per-session marker held across `--resume`. - Log-per-entry is a good fix for merge conflicts. Companion issues from the same install: #3 (the Stop guard keys on the tree, not the session; B1 in the original numbering) and #4 (Windows defects with a tested patch; part A).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kristofferopsahl/auto-llm-wiki#5
No description provided.