forked from bchanot/claude
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8962824c0 | ||
|
|
817a866b7c | ||
|
|
2940134c86 | ||
|
|
78a25aeb5e | ||
|
|
9b89da29be | ||
|
|
95ddd28992 | ||
|
|
1ef6e6e694 | ||
|
|
6c489ebcfb | ||
|
|
33f9529b9e | ||
|
|
648bc6e90d | ||
|
|
f82ea1e4f8 | ||
|
|
75c81f3f9c | ||
|
|
533fcc841e | ||
|
|
db6f476685 | ||
|
|
90850096ef | ||
|
|
0a8ecf6c34 |
@@ -208,3 +208,10 @@ rules:
|
||||
- **Real cause**: two viable-looking paths, both dead. (API KEY) is per-user not per-site (docs), but IS the account identity → one key per client account, exactly what the user feared; non-scoped, no expiry, passed in query string. (OAuth) is the right delegation model (like GSC) but a swamp: Redirect URI rejects ALL local forms (http/https/127.0.0.1 — user-tested); refresh tokens are ROTATED + single-use, self-described non-compliant with OAuth 2.0 → store rewrite every call, AND our parallel seo‖geo dispatch would race the rotation → `invalid_grant` + dead token; undocumented "Could not extract expected anti-forgery token" on refresh, unanswered on MS Q&A; docs contradict themselves on grant_type + token endpoint; no library. MS's own advisor recommends falling back to the API key.
|
||||
- **Verified live**: the Webmaster API itself is ALIVE (`GetUserSites?apikey=INVALID` → HTTP 400 `{"ErrorCode":3,"Message":"InvalidApiKey"}`, 0.4s) — distinct from Bing SEARCH API (retired 2025-08-11). So the block is auth/model, not availability.
|
||||
- **Status**: open/deferred. REVIVAL: a client already on Bing adds the user as Read-Only → test in ~10 min whether one API key sees DELEGATED sites (undocumented, nobody knows). If yes → W2 is cheap+clean (one key, client-owned verification, revocable, read-only, zero OAuth). Value RAISED by [[BDR-071]]: GetUrlLinks is now the only free viable backlink source (first-party only).
|
||||
|
||||
## BLK-018 — release-executor finish span blocked by permission classifier (human signal invisible to subagent) — 2026-07-20
|
||||
- **Friction**: v1.3.1 release — `SPAN: finish` dispatch denied at tool-permission layer: classifier flagged "Merge Without Review" (`gitflow.sh finish` in subagent transcript carries no explicit human merge signal). Executor correctly refused workaround, reported BLOCKED. v1.2.0/v1.3.0 same span passed → classifier behavior change, not skill regression.
|
||||
- **Real cause**: gitflow doctrine "finish only on explicit human signal" lives in DISPATCHER transcript (user ask + STEP 4 AskUserQuestion go); subagent transcript starts fresh → classifier sees consequential merge with zero authorization evidence. Structural: any human-gated action dispatched to a subagent loses its gate evidence.
|
||||
- **Solution** (workaround): dispatcher ran `gitflow.sh finish` + tag inline after its own human gate — where the signal is real. Release completed clean (main `648bc6e`, tag v1.3.1).
|
||||
- **Status**: open. Candidate fixes: (a) quote gate evidence verbatim in span prompt — untested vs classifier; (b) move finish+tag span permanently inline in /release-candidate — keeps prep span dispatched, costs the sonnet pin on ~5 mechanical commands, cheap; (c) permission rule allowing subagent `gitflow.sh finish` — weakens the guard, refused. Decide at next release.
|
||||
- **Reference**: skill `release-candidate` STEP 5. Pattern adjacent [[LRN-089]] (ambient-state/context assumptions across boundaries). Journal 2026-07-20.
|
||||
|
||||
@@ -91,6 +91,7 @@ rules:
|
||||
| BDR-071 | 2026-07-17 | No viable free backlink source → Off-page axis stays brand-mentions-only (FINAL, not placeholder) | accepted |
|
||||
| BDR-072 | 2026-07-17 | SPA: honest refuse (On-page N/A, not zero), no headless browser (R2 over R1) | accepted |
|
||||
| BDR-073 | 2026-07-17 | Scoring: LLM judges findings+severity, engine does the arithmetic (deterministic /20) | accepted |
|
||||
| BDR-080 | 2026-07-21 | Bug routing inverted: /bugfix primary, /investigate explicit-only | accepted |
|
||||
|
||||
---
|
||||
|
||||
@@ -980,6 +981,7 @@ rules:
|
||||
- **Why**: user call 2026-07-14 — registries already capture decisions; a stale plan describes a superseded intermediate state and misleads future readers; accumulation pollutes the repo. Precedent: gsc-crux cleanup (8a1fac0, 2026-07-10) did the same — this makes it law, not habit.
|
||||
- **Alternatives rejected**: never-commit (gitignore docs/superpowers) — breaks mid-run: briefs, reviewers, other-machine checkouts need the files; superpowers brainstorming commits the spec by convention. Keep-forever — the drift + pollution complained about.
|
||||
- **Reference**: project CLAUDE.md; cleanup commit this chore; precedent 8a1fac0. Linked [[BDR-064]], [[LRN-124]].
|
||||
- **Amendment (2026-07-22)**: DELETE side now AUTOMATED — `lib/gitflow.sh` `_gitflow_purge_transient` at `gitflow finish` (feature/bugfix, pre-merge, on HEAD) git-rm's `docs/superpowers/{specs,plans}` + scoped commit → develop TIP clean, feature commits stay reachable (`git show <sha>:…` archive intact). Best-effort: NEVER aborts finish (nothing-tracked no-op / dirty-path skip / commit-fail index+tree restore). Opt-out `GITFLOW_PURGE_TRANSIENT=0`. Retires the manual chore that slipped (655e364). Universal via `~/.claude/lib`→repo symlink (ship-feature STEP 9 + init-project STEP 11 both finish through it). gitignore STILL rejected — unchanged: breaks superpowers' `git add` of the spec (silently skipped, no travel to SDD worktree). `.claude/tasks/{contracts,plans}` kept versioned (user call — durable, referenced by decisions.md). Tests: gitflow-test.sh T17 a-d. [[LRN-138]].
|
||||
|
||||
---
|
||||
|
||||
@@ -1068,3 +1070,6 @@ Amendment (same session): skills/find-docs = machine-owned dist (gitignored, ctx
|
||||
|
||||
### BDR-079 — profile `set` symmetric on managed externals + MCPs [accepted] (2026-07-20)
|
||||
Audit (user ask "profile toggles externals both ways?"): ASYMMETRIC. Enable side OK — gstack on-demand from submodule when pack off (shared `skills-disabled/gstack__*` convention with toggle-external.sh, interoperable), externals restored from parked, magic delegated to toggle-external. Disable side MISSING: `cmd_set` trimmed only gstack + MANAGED_PLUGINS → `set backend` left emil/frontend-design/design-motion/impeccable active + magic registered; SKILL.md claimed both-ways toggle (true only at enable). Shipped: (1) `MANAGED_EXTERNALS` (emil-design-eng, frontend-design, design-motion-principles, impeccable = exact union of profile `external` usage; darwin-skill excluded — not task-type-driven) + `MANAGED_MCPS` (magic) allowlists, same doctrine as MANAGED_PLUGINS; (2) cmd_set refactored to 4 trim helpers (`disable_{gstack,plugins,externals,mcps}_not_in`) — symmetric, nothing outside allowlists ever auto-touched; (3) enable_skill external += from-source fallback (`ln -sf skills-external/<name>`, mirrors toggle-external) — closes the "missing symlink" warn; (4) stale usage() NOTE ("NOT toggled automatically") + SKILL.md fixed. Hermetic test profile-set-managed.test.sh 16 checks: fixture repo (both *_REPO_OVERRIDE), fake `claude` shim on PATH logging calls + flat-file MCP registry — gstack on-demand, external from-source, park/restore round-trip, magic add/remove calls, non-managed untouched. shellcheck + make test green. Branch feature/profile-managed-externals, unmerged (human gate).
|
||||
|
||||
### BDR-080 — bug routing inverted: /bugfix primary, /investigate explicit-only [accepted] (2026-07-21)
|
||||
Old routing "Bug → investigate (bugfix if gstack off)" + gstack ON by default → every bug took path bypassing own quality pipeline (gitflow aiguillage, contract, fresh verifier + security gates, doc-sync, `.claude/memory` registries) — /bugfix relegated to near-never fallback. Skill comparison: same core doctrine (root-cause iron law, hypothesis loop, regression test, 3-strike stop, >5-files alert) but incompatible wrappers — investigate monolithic (same context investigates+fixes+verifies, ~1075-line SKILL.md w/ gstack preamble/telemetry/onboarding, capitalizes to `~/.gstack` learnings.jsonl framework never reads at session start); bugfix orchestrator (reflection inline, sonnet bugfixer executor, fresh gates — BDR-066, LRN-083). Composition rejected: skills superpose in context, don't compose — invoking investigate inside bugfix = two full workflows, two completion protocols, two memory systems loaded at once. Decision: CLAUDE.global.md routing line inverted — bugfix primary; investigate ONLY on explicit ask for gstack ecosystem (cross-project learnings, /freeze scope lock, long no-commit investigation). Alternatives rejected: keep investigate primary (bypasses framework), embed investigate inside bugfix (context conflict, dual memory). Known drift noted at write time: Index table rows BDR-074..079 missing (pre-existing, /prune-memory scope).
|
||||
|
||||
@@ -418,3 +418,12 @@ rules:
|
||||
- ctx7 coverage audit (user ask "ctx7 appelé à chaque techno ?") → verdict PARTIAL. 4 gaps: find-docs question-only, /feat //bugfix executors blind, ad-hoc coding uncovered, fast-libs hardcoded 3×. All 4 closed → BDR-078 (fast-libs.sh single source + ctx7-reminder hook + description trigger + executor-brief rule). fast-libs test 11/0, make test + review-guards green. feature/ctx7-coverage, UNMERGED.
|
||||
- v1.2.0 cut + pushed (release-candidate flow: prep/finish via release-executor, tag on main 51b6572). CHANGELOG backfilled at prep: 10 entries added to Unreleased (plan-challenge, seo-data verbs, model-tiering v2, integrity pass, safe_fetch/url-guard) — was ctx7-only. /doc full post-release: README model-routing table v1→v2 reframe + ctx7 two-surface wording, chore/doc-sync-v1.2.0 merged. All pushed on explicit go.
|
||||
- profile↔toggle-external audit (user) → enable side already symmetric (gstack on-demand LIVE), disable side missing → BDR-079: MANAGED_EXTERNALS+MANAGED_MCPS trim at set, external from-source fallback, 16-check hermetic test (claude shim). feature/profile-managed-externals, UNMERGED.
|
||||
- README rebuilt: short pitch (what/how/why) top, old content → reference manual below separator. Dedup title/overview/install block, hardcoded version dropped from footer (staleness risk). chore/readme-v2 merged → develop, pushed.
|
||||
- v1.3.1 cut + pushed (docs-only: README rebuild). prep span via release-executor OK; finish span BLOCKED by permission classifier on subagent (no human signal in its transcript) → ran inline after both gates. [[BLK-018]].
|
||||
|
||||
## 2026-07-21
|
||||
- Skill audit (user ask "pourquoi pas investigate dans bugfix ?") → same core doctrine, incompatible wrappers: investigate = monolithic gstack (own memory ~/.gstack, no gitflow/gates, ~1075-line preamble), bugfix = orchestrator (contract, fresh verifier+security gates, registries). Routing inverted in CLAUDE.global.md: bugfix primary, investigate explicit-only → BDR-080. chore/skill-routing-bugfix, UNMERGED.
|
||||
|
||||
## 2026-07-22
|
||||
- User: auto-gitignore+delete transient pipeline artifacts in all projects. Investigation reframed the ask — gitignore = WRONG tool (files read from disk during run; would break superpowers SDD `git add` of spec). BDR-065 already rejected gitignore + its DELETE side was doctrine-only (no code, manual chore slipped once — 655e364). User picks (2 recommended): keep committed-during-run + AUTOMATE delete; keep `.claude/tasks/{contracts,plans}` versioned.
|
||||
- Built `lib/gitflow.sh` `_gitflow_purge_transient` at finish (feature/bugfix, pre-merge, best-effort never-abort, opt-out `GITFLOW_PURGE_TRANSIENT=0`) + `purge-transient` CLI verb. Universal via `~/.claude/lib`→repo symlink. gitflow-test T17 a-d (10 checks, `--full-history` recovery), shellcheck clean, make test exit 0. BDR-065 amendment + [[LRN-138]]. feature/gitflow-auto-purge-transient.
|
||||
|
||||
@@ -1349,3 +1349,9 @@ rules:
|
||||
- **fail-safe pin rule**: keep the HIGHEST tier as the frontmatter pin and override DOWN at call sites — a forgotten override then over-tiers (costs money) instead of silently downgrading judgment (costs correctness).
|
||||
- **future application**: before splitting any agent across model tiers, try MODE + `model=` first; create a new agent file only for a genuinely new role. Run-scoped `.audit/<name>-<RUNID>` files + completeness sentinel + fail-closed consumer for any cross-dispatch artifact.
|
||||
- **cousin**: [[LRN-125]] [[LRN-126]] [[BDR-077]].
|
||||
|
||||
## LRN-138 — gitignore ≠ delete for run-time artifacts read from disk (2026-07-22)
|
||||
- **pattern**: gitignore is the WRONG tool for an artifact a pipeline READS FROM DISK during a run — it blocks the commit but leaves the file (cleans nothing) AND breaks git-travel flows (superpowers commits the spec via `git add` so it reaches the SDD worktree; a gitignored path is silently skipped w/o `-f`). Right tool = commit-during-run + AUTO-DELETE at the integration boundary (`gitflow finish`, pre-merge, on the working branch → history keeps the archive, develop tip clean).
|
||||
- **context**: user asked to gitignore transient planning artifacts (`docs/superpowers/{specs,plans}`, `.claude/tasks/{contracts,plans}`) to stop them merging. BDR-065 had already REJECTED gitignore for docs/superpowers on the git-travel ground; the real gap was the DELETE side never being coded (doctrine-only manual chore, slipped once — 655e364). Built `_gitflow_purge_transient`.
|
||||
- **future application**: "don't merge transient X" → ask: does the run read X from disk? does X travel via git (worktree, foreign checkout)? Yes → auto-purge at finish, not gitignore. Scoped commit `-- <paths>` avoids sweeping a dirty index; `git diff --quiet HEAD -- paths` precheck makes `git rm` all-or-nothing safe; keep the purge best-effort so cleanup NEVER blocks a merge. Prove archive-reachability with `git log --full-history` / `git show <sha>:path` — plain `git log -- path` prunes the purged add-commit via history simplification (bit me writing T17).
|
||||
- **link**: [[BDR-065]].
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# TODO
|
||||
|
||||
## 2026-07-22 — auto-purge transient superpowers artifacts at finish (feature/gitflow-auto-purge-transient)
|
||||
User: transient planning artifacts (`docs/superpowers/{specs,plans}`) leak into
|
||||
develop; BDR-065 "post-merge cleanup" is DOCTRINE ONLY (no code) — manual chore,
|
||||
already missed once (655e364). Decision (user 2026-07-22, 2 recommended picks):
|
||||
keep committed-during-run (SDD worktree + reviewers read them), AUTOMATE the
|
||||
delete at `gitflow finish`. NO gitignore (would break superpowers' `git add` of
|
||||
the spec → no travel to SDD worktree). `.claude/tasks/{contracts,plans}` stay
|
||||
versioned (durable, referenced by decisions.md e.g. BDR-076). Universal via the
|
||||
`~/.claude/lib` → repo `lib` symlink: every project's finish gets it.
|
||||
- [x] lib/gitflow.sh: `_gitflow_purge_transient` (clean-precheck → git rm →
|
||||
scoped commit `-- paths`; best-effort, NEVER aborts finish; opt-out
|
||||
`GITFLOW_PURGE_TRANSIENT=0`) wired into finish `feature|bugfix` pre-merge;
|
||||
`purge-transient` CLI verb.
|
||||
- [x] lib/gitflow-test.sh T17 a/b/c/d (purge+recover-from-history via
|
||||
--full-history+`git show`, no-op when absent, opt-out keeps, chore scope).
|
||||
Also fixed 2 pre-existing SC2034 warnings (T16 gl_out/noleaks_out).
|
||||
- [x] Gate: shellcheck lib/*.sh CLEAN + `make test` exit 0 (gitflow 106/0, full
|
||||
suite green). Universal via ~/.claude/lib → repo lib symlink (verified).
|
||||
- [x] CLAUDE.md §Transient planning artifacts: → "AUTO-PURGED by gitflow finish".
|
||||
- [ ] Capitalize: BDR-065 amendment (delete side now automated) + LRN — pending user OK.
|
||||
|
||||
## 2026-07-20 — pending merge gates (reconcile)
|
||||
- [x] merge feature/profile-managed-externals → develop (BDR-079 profile
|
||||
symmetry + /doc clean pass: README/USAGE/ARCHITECTURE.md) — 37c79f0
|
||||
|
||||
@@ -6,6 +6,46 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.4.0] — 2026-07-22
|
||||
|
||||
### Added
|
||||
- **Transient planning artifacts auto-purged at feature-finish (BDR-065)** —
|
||||
`gitflow finish` on a `feature`/`bugfix` branch now removes the run-time
|
||||
superpowers artifacts (`docs/superpowers/{specs,plans}`) on the working
|
||||
branch just before the directed merge, so `develop`'s tip lands clean while
|
||||
the feature commits stay reachable as the archive (`git show <sha>:…`). This
|
||||
automates the manual post-merge cleanup that BDR-065 had left as doctrine —
|
||||
the step that slipped in 1.3.0 and needed a hand purge. Best-effort by
|
||||
contract: a purge that finds nothing, meets uncommitted changes under those
|
||||
paths, or fails to commit never aborts the finish (index/tree restored); opt
|
||||
out with `GITFLOW_PURGE_TRANSIENT=0`. New `gitflow.sh purge-transient` verb.
|
||||
`.claude/tasks/{contracts,plans}` are deliberately out of scope (durable,
|
||||
versioned, referenced by the decision registry). Live in every project via
|
||||
the `~/.claude/lib` symlink; covered by `lib/gitflow-test.sh` T17 (a–d).
|
||||
|
||||
### Changed
|
||||
- **Bug routing inverted: `/bugfix` primary, `/investigate` explicit-only
|
||||
(BDR-080)** — a bug / error / 500 now routes to `/bugfix` by default (the
|
||||
full framework: gitflow, contract, fresh verifier + security gates,
|
||||
registries). The gstack `/investigate` monolith — its own `~/.gstack`
|
||||
memory, no gitflow or gates — is reserved for explicit requests
|
||||
(cross-project learnings, `/freeze` scope lock, long investigation with no
|
||||
immediate commit intent). Same core debugging doctrine, incompatible
|
||||
wrappers; the default now favours the gated, integrated path.
|
||||
|
||||
## [1.3.1] — 2026-07-20
|
||||
|
||||
### Changed
|
||||
- **README rebuilt around a short pitch** — new top half: what it is / how
|
||||
it works / why it's good in ~60 lines (skills = entry points, agents =
|
||||
model-tiered execution units, hooks = deterministic guardrails,
|
||||
templates/memory = compounding per-project registries); all previous
|
||||
content demoted to an explicit reference-manual half below a separator.
|
||||
Deduplicated in the process: old title/tagline, Overview prose and the
|
||||
duplicated fresh-install block removed (unique install notes kept under
|
||||
a new "Install notes" section); hardcoded version number dropped from
|
||||
the footer (staleness risk). Docs-only release — no code change.
|
||||
|
||||
## [1.3.0] — 2026-07-20
|
||||
|
||||
### Added
|
||||
|
||||
+4
-1
@@ -252,7 +252,10 @@ description fits (full list is in context). Rules below cover only the
|
||||
non-obvious cases: gstack fallbacks, disambiguation, cryptic names.
|
||||
|
||||
- Product idea, "worth building?" → office-hours
|
||||
- Bug / error / 500 → investigate (bugfix if gstack off)
|
||||
- Bug / error / 500 → bugfix (full framework: gitflow, contract, fresh
|
||||
verifier/security gates, registries). investigate ONLY on explicit ask
|
||||
for the gstack ecosystem (cross-project learnings, /freeze scope lock,
|
||||
long investigation with no immediate commit intent)
|
||||
- feat / hotfix / bugfix distinguished by file count → see descriptions
|
||||
- Ship / deploy / PR → ship (ship-feature if gstack off)
|
||||
- Cut a release / tag a version (develop ahead of main) → release-candidate
|
||||
|
||||
@@ -32,8 +32,13 @@ or re-run `make plugin`.
|
||||
|
||||
`docs/superpowers/specs/**` and `docs/superpowers/plans/**` are run-time
|
||||
artifacts of a feature pipeline (subagent briefs, reviewer references).
|
||||
They are committed DURING the run and DELETED in the post-merge cleanup
|
||||
(BDR-065) — git history at the feature commits is their archive. Durable
|
||||
knowledge goes to `.claude/memory/` registries, never to these files.
|
||||
Derived scan/audit outputs (`.audit/**`) are gitignored and never
|
||||
committed, even redacted (LRN-124).
|
||||
They are committed DURING the run (the SDD worktree + reviewers read them
|
||||
from disk — NOT gitignored), then AUTO-PURGED by `gitflow finish` on a
|
||||
`feature`/`bugfix` branch, before the merge, so develop's tip stays clean
|
||||
(BDR-065, `lib/gitflow.sh` `_gitflow_purge_transient`). The feature commits
|
||||
stay reachable from develop, so `git show <sha>:docs/…` is still the archive.
|
||||
Opt out with `GITFLOW_PURGE_TRANSIENT=0`. NOT in scope: `.claude/tasks/{contracts,plans}`
|
||||
(durable, versioned, referenced by decisions.md). Durable knowledge goes to
|
||||
`.claude/memory/` registries, never to these files. Derived scan/audit
|
||||
outputs (`.audit/**`) are gitignored and never committed, even redacted
|
||||
(LRN-124).
|
||||
|
||||
@@ -1,21 +1,67 @@
|
||||
# claude-config
|
||||
|
||||
Global Claude Code configuration — agents, skills, plugins, and project templates.
|
||||
One repo that turns Claude Code into a reproducible engineering system —
|
||||
skills, agents, hooks, plugins, and per-project memory, versioned and
|
||||
symlinked into `~/.claude/`. Clone it on any machine, run one command,
|
||||
and every project gets the same assistant with the same rules.
|
||||
|
||||
> **Guide d'utilisation complet :** voir [`USAGE.md`](./USAGE.md) — workflows typiques, exemples par type de projet, arbre de décision "quel skill utiliser ?".
|
||||
> **Historique des versions :** voir [`CHANGELOG.md`](./CHANGELOG.md).
|
||||
## What it is
|
||||
|
||||
Not a collection of prompts — an operating layer on top of Claude Code:
|
||||
|
||||
- **Skills** (`/feat`, `/bugfix`, `/ship-feature`, `/seo`, `/tour`…) are the
|
||||
entry points: each one encodes a complete workflow, from quick fix to
|
||||
full feature pipeline with validation gates.
|
||||
- **Agents** are the execution units skills dispatch to — each pinned to
|
||||
the cheapest model that can do the job (haiku collects, sonnet executes,
|
||||
opus judges, the session model only reflects).
|
||||
- **Hooks and permissions** are deterministic guardrails: gitflow enforced
|
||||
by a pre-commit hook, deny-first permission rules, secrets kept in
|
||||
`~/.claude/.env` and never in config files.
|
||||
- **Templates and memory** seed every project with persistent registries
|
||||
(decisions, learnings, blockers) — what a session learns, the next
|
||||
session knows.
|
||||
|
||||
## How it works
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/bchanot/claude
|
||||
cd claude
|
||||
make install # CLI + auth + symlinks + plugins (pinned in plugins.lock.json)
|
||||
make doctor # verify everything
|
||||
```
|
||||
|
||||
`link.sh` symlinks the repo into `~/.claude/`, so editing here updates the
|
||||
live config — and `git log` is the audit trail of your entire setup.
|
||||
Day to day:
|
||||
|
||||
```bash
|
||||
/onboard # bring an existing repo into the framework
|
||||
/ship-feature "…" # brainstorm → plan → adversarial challenge → TDD → review → merge
|
||||
/feat "…" # same idea, 1-5 files, no ceremony
|
||||
/close # flush decisions and learnings to memory before quitting
|
||||
make update # keep CLI, plugins, and submodules current
|
||||
```
|
||||
|
||||
## Why it's good
|
||||
|
||||
- **Reproducible.** One clone rebuilds the whole environment; versions are
|
||||
locked, `make doctor` proves it works.
|
||||
- **Cost-shaped.** Model tiering routes reflection to the big model and
|
||||
execution to cheap ones — the expensive context does only what it must.
|
||||
- **Safe by default.** Protected branches, ask-before-run on risky tools,
|
||||
parameterized secrets: the guardrails are code, not good intentions.
|
||||
- **It compounds.** Memory registries, audit skills, and doc-sync keep every
|
||||
project's knowledge growing across sessions instead of evaporating.
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
Everything below is the reference manual — model routing, components,
|
||||
commands, settings, secrets, maintenance.
|
||||
|
||||
This repo is your personal Claude Code setup, versioned and reproducible across machines.
|
||||
---
|
||||
|
||||
See [`ARCHITECTURE.md`](./ARCHITECTURE.md) for the full project layout and
|
||||
structural principles (skills = entry points, agents = execution units,
|
||||
templates = per-project scaffolding, graphify = codebase knowledge graph).
|
||||
|
||||
### Agent model routing (model-tiering v2)
|
||||
## Agent model routing (model-tiering v2)
|
||||
|
||||
Doctrine: the session model (Fable) does main-loop reflection ONLY —
|
||||
brainstorm, plan, contract, audit judgment, gates, loop decisions — enforced
|
||||
@@ -47,21 +93,7 @@ children are dispatched `model:"fable"` (they carry reflection).
|
||||
|
||||
---
|
||||
|
||||
## Fresh install (new machine)
|
||||
|
||||
```bash
|
||||
# 1. Clone with submodules
|
||||
git clone --recurse-submodules https://github.com/bchanot/claude
|
||||
cd claude
|
||||
|
||||
# 2. Bootstrap (CLI + auth + symlinks + plugins)
|
||||
make install
|
||||
|
||||
# 3. Verify setup
|
||||
make doctor
|
||||
|
||||
# 4. Restart Claude Code — plugins load automatically
|
||||
```
|
||||
## Install notes
|
||||
|
||||
All scripts use their own location to find the repo — run them from anywhere.
|
||||
The plugins step logs to `install-YYYYMMDD-HHMMSS.log`.
|
||||
@@ -306,3 +338,11 @@ make new-skill name=myskill # scaffold agent + skill files
|
||||
```
|
||||
|
||||
`doctor.sh` checks: symlinks, GStack submodule, prerequisites (git, Node, Cargo, Python, Claude Code), plugins, permissions, token budget, config consistency.
|
||||
|
||||
---
|
||||
|
||||
## Going further
|
||||
|
||||
[`USAGE.md`](./USAGE.md) — workflows and skill decision tree ·
|
||||
[`ARCHITECTURE.md`](./ARCHITECTURE.md) — layout and principles ·
|
||||
[`CHANGELOG.md`](./CHANGELOG.md) — version history.
|
||||
|
||||
@@ -239,6 +239,7 @@ gitflow_start feature glwork >/dev/null 2>&1
|
||||
# proving this backstop is NOT gated by the branch-protection check above it)
|
||||
printf 'aws_access_key_id = AKIA%s\n' "GDR5XRBXYARW2I5N" > secret.txt
|
||||
git add secret.txt
|
||||
# shellcheck disable=SC2034 # gl_out is used in the deferred chk eval strings
|
||||
gl_out="$(git commit -q -m "add secret" 2>&1)"; gl_rc=$?
|
||||
chk "T16a fake secret on feature branch → blocked" "[ $gl_rc -ne 0 ]"
|
||||
chk "T16a message mentions gitleaks" 'printf "%s" "$gl_out" | grep -qi gitleaks'
|
||||
@@ -252,10 +253,57 @@ chk "T16b clean commit still succeeds" 'git commit -q -m "clean work" 2>/dev/nul
|
||||
# T16c — gitleaks missing from PATH → warn, never block (defense in depth
|
||||
# must not become a new single point of failure)
|
||||
echo clean2 > clean2.txt; git add clean2.txt
|
||||
# shellcheck disable=SC2034 # noleaks_out is used in the deferred chk eval strings
|
||||
noleaks_out="$(PATH=/usr/bin:/bin git commit -q -m "clean work 2" 2>&1)"; noleaks_rc=$?
|
||||
chk "T16c missing-gitleaks → still commits (rc0)" "[ $noleaks_rc -eq 0 ]"
|
||||
chk "T16c missing-gitleaks → warns" 'printf "%s" "$noleaks_out" | grep -qi "not installed"'
|
||||
|
||||
echo "T17 — finish auto-purges transient superpowers artifacts (BDR-065)"
|
||||
# T17a — feature carrying docs/superpowers spec+plan: purged before merge,
|
||||
# develop TIP clean, artifacts still recoverable from history (archive property)
|
||||
newrepo purgefeat; echo a>a; hookon; gitflow_init >/dev/null 2>&1
|
||||
gitflow_start feature pf >/dev/null 2>&1
|
||||
mkdir -p docs/superpowers/specs docs/superpowers/plans
|
||||
echo spec > docs/superpowers/specs/s.md
|
||||
echo plan > docs/superpowers/plans/p.md
|
||||
echo code > feat.txt
|
||||
git add -A; git commit -q -m "feat + transient spec/plan"
|
||||
gitflow_finish >/dev/null 2>&1
|
||||
# the add-commit stays reachable from develop via the --no-ff merge's 2nd parent;
|
||||
# --full-history defeats the path simplification that hides it, and `git show
|
||||
# <sha>:path` proves BDR-065's "git history = the archive" recovery.
|
||||
# shellcheck disable=SC2034 # pf_add_sha is used in the deferred chk eval string
|
||||
pf_add_sha="$(git log develop --full-history --format=%H -- docs/superpowers/specs/s.md | tail -1)"
|
||||
chk "T17a merged into develop" 'git log develop --oneline | grep -q "Merge feature/pf into develop"'
|
||||
chk "T17a develop TIP has no transient" '[ -z "$(git ls-tree -r develop --name-only -- docs/superpowers)" ]'
|
||||
chk "T17a purge commit on record" 'git log develop --oneline | grep -q "purge transient planning artifacts"'
|
||||
chk "T17a artifact recoverable from history" '[ "$(git show "$pf_add_sha":docs/superpowers/specs/s.md 2>/dev/null)" = spec ]'
|
||||
chk "T17a non-transient code survives" 'git ls-tree -r develop --name-only | grep -qx feat.txt'
|
||||
chk "T17a feature branch deleted" '! git rev-parse --verify -q refs/heads/feature/pf >/dev/null'
|
||||
|
||||
# T17b — no artifacts → purge is a silent no-op, no spurious commit
|
||||
newrepo purgenone; echo a>a; hookon; gitflow_init >/dev/null 2>&1
|
||||
gitflow_start feature pn >/dev/null 2>&1; echo w>w.txt; git add w.txt; git commit -q -m w
|
||||
gitflow_finish >/dev/null 2>&1
|
||||
chk "T17b merged into develop" 'git log develop --oneline | grep -q "Merge feature/pn into develop"'
|
||||
chk "T17b no purge commit created" '! git log develop --oneline | grep -q "purge transient"'
|
||||
|
||||
# T17c — opt-out (GITFLOW_PURGE_TRANSIENT=0) keeps the artifacts on develop
|
||||
newrepo purgeoff; echo a>a; hookon; gitflow_init >/dev/null 2>&1
|
||||
gitflow_start feature po >/dev/null 2>&1
|
||||
mkdir -p docs/superpowers/specs; echo spec > docs/superpowers/specs/s.md
|
||||
git add -A; git commit -q -m "feat + spec"
|
||||
GITFLOW_PURGE_TRANSIENT=0 gitflow_finish >/dev/null 2>&1
|
||||
chk "T17c opt-out keeps transient on develop TIP" '[ -n "$(git ls-tree -r develop --name-only -- docs/superpowers)" ]'
|
||||
|
||||
# T17d — chore is OUT of purge scope (only feature/bugfix originate artifacts)
|
||||
newrepo purgechore; echo a>a; hookon; gitflow_init >/dev/null 2>&1
|
||||
gitflow_start chore pc >/dev/null 2>&1
|
||||
mkdir -p docs/superpowers/specs; echo spec > docs/superpowers/specs/s.md
|
||||
git add -A; git commit -q -m "chore + spec"
|
||||
gitflow_finish >/dev/null 2>&1
|
||||
chk "T17d chore leaves transient (not in scope)" '[ -n "$(git ls-tree -r develop --name-only -- docs/superpowers)" ]'
|
||||
|
||||
echo
|
||||
echo "==== RESULT: $PASS passed, $FAIL failed ===="
|
||||
[ "$FAIL" -eq 0 ]
|
||||
|
||||
+48
-2
@@ -18,6 +18,12 @@ GITFLOW_MAIN="main"
|
||||
GITFLOW_DEVELOP="develop"
|
||||
# template resolved relative to the lib; overridable for tests.
|
||||
GITFLOW_GITIGNORE_TEMPLATE="${GITFLOW_GITIGNORE_TEMPLATE:-$_GITFLOW_LIB_DIR/../templates/gitignore/standard.gitignore}"
|
||||
# Transient planning artifacts (superpowers spec/plan). A feature/bugfix run
|
||||
# COMMITS them (SDD worktree + reviewers read them from disk); finish PURGES
|
||||
# them before the merge reaches develop's tip (BDR-065). Fixed path list;
|
||||
# read GITFLOW_PURGE_TRANSIENT=0 at finish time to opt out (read in the helper,
|
||||
# never cached here, so an inline `VAR=0 gitflow_finish` override works).
|
||||
GITFLOW_TRANSIENT_PATHS=("docs/superpowers/specs" "docs/superpowers/plans")
|
||||
|
||||
# ── predicates / pure helpers ────────────────────────────────────────────────
|
||||
|
||||
@@ -97,6 +103,42 @@ _gitflow_delete() { # <branch>
|
||||
git branch -q -d "$br" || { echo "gitflow: '$br' not fully merged — branch kept" >&2; return 5; }
|
||||
}
|
||||
|
||||
# _gitflow_purge_transient → remove the committed transient planning artifacts
|
||||
# (BDR-065) from the CURRENT branch just before the directed merge. Result: the
|
||||
# removal rides the feature/bugfix branch, whose earlier commits stay reachable
|
||||
# from develop through the --no-ff merge (`git show <sha>:…` = the archive),
|
||||
# while develop's TIP lands clean. Automates the manual post-merge chore that
|
||||
# BDR-065 left as doctrine (and that slipped once — commit 655e364).
|
||||
#
|
||||
# BEST-EFFORT BY CONTRACT: this NEVER aborts a finish. Nothing tracked → no-op;
|
||||
# uncommitted changes under those paths, or a failed commit → warn + degrade to
|
||||
# the old manual-cleanup behaviour, index/tree restored, merge still proceeds.
|
||||
# The scoped commit (`-- <paths>`) records only the deletions, so a dirty index
|
||||
# is never swept in. Opt out with GITFLOW_PURGE_TRANSIENT=0.
|
||||
_gitflow_purge_transient() {
|
||||
[ "${GITFLOW_PURGE_TRANSIENT:-1}" = 1 ] || return 0
|
||||
local p; local -a tracked=()
|
||||
for p in "${GITFLOW_TRANSIENT_PATHS[@]}"; do
|
||||
[ -n "$(git ls-files -- "$p")" ] && tracked+=("$p")
|
||||
done
|
||||
[ "${#tracked[@]}" -gt 0 ] || return 0 # nothing tracked → no-op
|
||||
# only purge paths with no pending changes → git rm is all-or-nothing safe and
|
||||
# never discards uncommitted work under docs/superpowers.
|
||||
if ! git diff --quiet HEAD -- "${tracked[@]}" 2>/dev/null; then
|
||||
echo "gitflow: transient artifacts have uncommitted changes — purge skipped, finishing without it (clean up by hand)" >&2
|
||||
return 0
|
||||
fi
|
||||
if git rm -r -q -- "${tracked[@]}" >/dev/null 2>&1 \
|
||||
&& git commit -q -m "chore: purge transient planning artifacts (BDR-065)" -- "${tracked[@]}"; then
|
||||
echo "gitflow: purged transient planning artifacts before merge (${tracked[*]})" >&2
|
||||
else
|
||||
echo "gitflow: transient-artifact purge failed — finishing without it (clean up by hand)" >&2
|
||||
git reset -q HEAD -- "${tracked[@]}" 2>/dev/null || true # unstage any partial rm
|
||||
git checkout -q -- "${tracked[@]}" 2>/dev/null || true # restore working tree
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# gitflow_finish [<type> <name>] → directed merge of the CURRENT branch per its
|
||||
# type, then delete. WHEN to call this is the human gate (SKILL.md).
|
||||
#
|
||||
@@ -117,7 +159,10 @@ gitflow_finish() {
|
||||
fi
|
||||
type="$(gitflow_branch_type "$br")"
|
||||
case "$type" in
|
||||
feature|bugfix|chore)
|
||||
feature|bugfix)
|
||||
_gitflow_purge_transient # BDR-065 auto-cleanup, on HEAD, pre-merge; never blocks
|
||||
_gitflow_merge_into "$GITFLOW_DEVELOP" "$br" && _gitflow_delete "$br" ;;
|
||||
chore)
|
||||
_gitflow_merge_into "$GITFLOW_DEVELOP" "$br" && _gitflow_delete "$br" ;;
|
||||
release)
|
||||
_gitflow_merge_into "$GITFLOW_MAIN" "$br" \
|
||||
@@ -283,8 +328,9 @@ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
||||
finish) gitflow_finish "$@" ;;
|
||||
init) gitflow_init "$@" ;;
|
||||
reconcile) gitflow_reconcile_gitignore "$@" ;;
|
||||
purge-transient) _gitflow_purge_transient ;;
|
||||
install-hook) gitflow_install_hook "$@" ;;
|
||||
emit-hook) _gitflow_emit_pre_commit ;;
|
||||
*) echo "usage: gitflow.sh {type|protected-base|base-for|release-open|start|finish|init|reconcile|install-hook|emit-hook}" >&2; exit 2 ;;
|
||||
*) echo "usage: gitflow.sh {type|protected-base|base-for|release-open|start|finish|init|reconcile|purge-transient|install-hook|emit-hook}" >&2; exit 2 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.3.0
|
||||
1.4.0
|
||||
|
||||
Reference in New Issue
Block a user