Adopt deny-by-default .claude gitignore; record git-hygiene audit

The cross-repo git-hygiene audit (ROADMAP item 6) found the documented canonical .claude/ block was allow-by-default and would have un-ignored a password-bearing .claude/launch.json. Switch portability.md to a deny-by-default .claude/* + allow-list block and align the two retrofit summaries. Mark item 6 done with residuals; refresh Current state.
This commit is contained in:
Keysat
2026-06-14 12:19:48 -05:00
parent 36e1f78014
commit 828fc99dd4
5 changed files with 69 additions and 34 deletions
+19 -9
View File
@@ -93,12 +93,22 @@ should carry this so any vendor's agent surfaces pending items at session start:
- `/roundup` is built: a cross-project status report that reads every repo's
AGENTS.md/ROADMAP.md plus the inbox and groups all to-dos by priority — reads and reports
only; deciding focus stays with the user.
- The inbox-check line and canonical `.gitignore` are now threaded into the retrofit flow
(playbook + `/retrofit` guide), so new repos inherit them — but they're **not yet in other
*existing* repos**; a shallow scan shows the `.claude`/git setup is inconsistent across
repos.
- Specced in `ROADMAP.md`, not built: the cross-repo git-hygiene audit (item 6, HIGH), the
`new-project` bootstrap, the cross-repo quality-gate standard, and the SessionStart hook.
- Next session: (1) run the cross-repo git-hygiene audit (ROADMAP item 6, HIGH); (2) build
the `new-project` bootstrap (item 5); (3) add `/capture`, `/triage`, `/roundup` to README's
"The rhythm" section.
- The cross-repo git-hygiene audit (ROADMAP item 6) is **DONE**: all 9 git repos under
`~/Projects` audited (one read-only `portability-checker` each). No safety issues anywhere —
zero tracked `.env`/`.DS_Store`/`*.local.json`, all in-repo symlinks relative. 6 repos
remediated (inbox-check line + canonical `.gitignore`) and pushed; `recap-relay` is
committed locally only (no git remote).
- The audit drove a **standards change**: `portability.md`'s canonical `.claude/` block is now
**deny-by-default** (`.claude/*` + an allow-list of the shared wiring). The old
allow-by-default block would have un-ignored `premier-gunner`'s password-bearing
`.claude/launch.json` — deny-by-default keeps stray scratch/secrets out by default. The two
retrofit summaries were updated to match.
- The inbox-check line + canonical `.gitignore` are threaded into the retrofit flow *and* now
live in the 6 remediated repos. Still missing from `ten31-transcripts` (needs a mini-retrofit)
and from the many **non-git folders** under `~/Projects` (unprotected work).
- Specced in `ROADMAP.md`, not built: the `new-project` bootstrap (item 5), the cross-repo
quality-gate standard (item 1), and the SessionStart hook (item 3). Item 6 residuals:
`ten31-transcripts` mini-retrofit, a Gitea remote for `recap-relay`, the non-git-folder sweep.
- Next session: (1) work the item-6 residuals — `ten31-transcripts` mini-retrofit and a remote
for `recap-relay`; (2) build the `new-project` bootstrap (item 5); (3) add `/capture`,
`/triage`, `/roundup` to README's "The rhythm" section.
+27 -17
View File
@@ -104,23 +104,33 @@ the CLAUDE.md symlink, ROADMAP.md, the canonical `.gitignore`, and the inbox-che
is generic vs. stack-specific (does it call a `/harden` step from item 1 to install the
stack's linter+hook?); whether the workshop output also seeds the first `## Current state`.
## 6. Cross-repo git-hygiene audit + remediation — HIGH PRIORITY
## 6. Cross-repo git-hygiene audit + remediation ✅ DONE (2026-06-14)
**Why:** a shallow scan of `~/Projects` (2026-06-14) shows the `.claude`/git setup is *not*
consistent across repos. Git repos with the full AGENTS.md + `.claude` + `.gitignore` setup:
`CRM`, `premier-gunner`, `recap-relay`, `recap`, `spark-control`, `standards`, `Workout-log`.
Outliers: `ten31-transcripts` has a `CLAUDE.md` but **no `.claude/` dir** (possible real file
instead of an AGENTS.md symlink — the stale-retrofit failure); `start-os` has neither (likely
an external/upstream repo). Plus many non-git folders (unprotected work). We don't yet know,
per repo, what inside `.claude/` is committed vs gitignored, or whether in-repo symlinks are
relative.
Fanned out one read-only `portability-checker` per git repo under `~/Projects`. **No safety
issues anywhere:** zero tracked `.env` / `.DS_Store` / `*.local.json`, and every in-repo
symlink is relative. The gaps were consistency: the inbox-check line was missing in all 7
non-standards repos, and only `standards` had a complete canonical `.gitignore`.
**Do:** fan out one read-only `portability-checker` (or `Explore`) per git repo under
`~/Projects`, each reporting: is `CLAUDE.md` a relative symlink to `AGENTS.md` or a real
file; what's in `.claude/` and which of it is tracked vs gitignored (esp. `settings.local.json`
committed by mistake, or shared `settings.json`/rules symlinks missing); whether `.gitignore`
carries the canonical block; any absolute in-repo symlinks. Synthesize one compliance matrix +
a prioritized remediation list, then a follow-up pass fixes each repo (its own commit).
**Fixed — 6 repos, one commit each, pushed** (`CRM`, `premier-gunner`, `recap`,
`spark-control`, `Workout-log`; `recap-relay` committed locally — see residuals): added the
repo-tagged inbox-check line and normalized `.gitignore`.
**Open questions:** treat non-git folders (flag for retrofit) vs. external upstreams
(`start-os`?) differently; report-only first vs. auto-fix.
**Standard improved by the audit:** the documented canonical `.claude/` block was
allow-by-default and would have *un-ignored* `premier-gunner`'s password-bearing
`.claude/launch.json`. Switched `portability.md` (and the two retrofit summaries) to a
**deny-by-default `.claude/*` + allow-list** of the shared wiring.
**Residual follow-ups:**
- **`ten31-transcripts` (MAJOR) — needs its own mini-retrofit.** Despite the name it's an
active Xcode/Swift app with no `.claude/` at all. Scaffold `.claude/settings.json`; decide
whether to reorganize its flat `docs/NN_*.md` into `docs/guides/` + `.claude/rules/` symlinks.
Too big for the mechanical pass.
- **`recap-relay` has no git remote** — committed locally only; create a Gitea repo + push.
- **`premier-gunner/s9pk/.gitignore`** lacks the secrets/Claude lines (low priority; the root
`.gitignore` covers `.env` tree-wide already).
- **Many non-git folders under `~/Projects` are unprotected work** (discount-watcher,
expense-organizer, giga, heart-rate, licensing, one-river, satoshi-sleep, START9 PACKAGING,
ten31-agents/-command-center/-signal-engine, timestamp-converter, timestamp-newspaper,
website-landing, Grand-Cayman-paddleboard). Each needs `git init` + retrofit, or an explicit
"scratch, don't track" decision.
- **`start-os`** is an external upstream (Start9Labs/start-os) — out of scope, no action.
+2 -2
View File
@@ -23,8 +23,8 @@ guess on anything that changes what lands on disk.
## Phase 1 — Git audit (playbook Step 0)
- If this is not a git repo: propose `git init`, a `.gitignore` (the canonical block from
`portability.md`'s "What git tracks" — `.env`, `.claude/settings.local.json` and
`*.local.*`, OS cruft), and an initial commit. Get approval before running.
`portability.md`'s "What git tracks" — `.env`/`.env.*`, a deny-by-default `.claude/*` with
the shared wiring allow-listed, OS cruft), and an initial commit. Get approval before running.
- If it is: report whether there are uncommitted changes and when the last commit was,
then propose committing anything outstanding (a repo existing isn't the same as work
being saved — uncommitted changes are as unprotected as no repo at all).
+20 -5
View File
@@ -72,8 +72,17 @@ symlinks; `ROADMAP.md`; `.claude/settings.json` (shared project settings and hoo
deterministic behavior is part of the repo); `.claude/agents/*.md`, `.claude/commands/*.md`,
`.claude/skills/` (project-scoped wrappers).
Gitignored (per-user, per-machine, or secret): `.claude/settings.local.json` and any
`*.local.*` (personal permissions/overrides); `.env` and secrets (corollary 5); OS cruft.
Gitignored (per-user, per-machine, secret, or session scratch): `.claude/settings.local.json`
and any `*.local.*` (personal permissions/overrides); `.claude/worktrees/` and other Claude
session/editor scratch that lands in `.claude/`; `.env` and secrets (corollary 5); OS cruft.
Because `.claude/` accumulates unpredictable scratch — worktrees, editor debug configs
(sometimes carrying credentials), `.DS_Store` — **ignore it deny-by-default and allow-list
only the shared wiring.** A blanket `.claude/*` plus `!` exceptions is safer than naming
individual local files: a new kind of local scratch is ignored automatically, and a stray
secret never slips in by default. (Already-tracked files stay tracked even under `.claude/*`,
so a deliberate, secret-free editor config a repo wants to commit can simply be allow-listed
with its own `!` line.)
Put these in the repo's **own committed `.gitignore`** — don't rely on a global
excludesfile, which a fresh clone or another machine won't have. Canonical block:
@@ -84,9 +93,15 @@ excludesfile, which a fresh clone or another machine won't have. Canonical block
.env.*
!.env.example
# Claude Code — commit shared config, ignore personal/local
.claude/settings.local.json
.claude/*.local.json
# Claude Code — deny by default, allow-list shared wiring.
# .claude/ also accumulates worktrees, editor configs, and OS cruft; commit
# only the shared parts so new local scratch (or a stray secret) stays out.
.claude/*
!.claude/rules/
!.claude/agents/
!.claude/commands/
!.claude/skills/
!.claude/settings.json
# OS cruft
.DS_Store
+1 -1
View File
@@ -62,7 +62,7 @@ claude
Paste:
> Is this a git repo? If not: git init, write a .gitignore covering .env, .claude/settings.local.json (and any *.local.*), and OS cruft — the canonical block in portability.md's "What git tracks" — and make an initial commit. If it is: tell me whether there are uncommitted changes and when the last commit was, then commit anything outstanding.
> Is this a git repo? If not: git init, write a .gitignore covering .env/.env.*, a deny-by-default .claude/* with the shared wiring allow-listed (rules/agents/commands/skills/settings.json), and OS cruft — the canonical block in portability.md's "What git tracks" — and make an initial commit. If it is: tell me whether there are uncommitted changes and when the last commit was, then commit anything outstanding.
Approve the git commands it proposes. Then `/exit`. (A repo existing isn't the same as work being saved in it — uncommitted changes are exactly as unprotected as no repo at all.)