diff --git a/CLAUDE.md b/CLAUDE.md index f26ff42..8e5f957 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,6 +108,10 @@ caveats: README "Release + repin order"; wave mechanics and fleet counts: `docs/ reusables float the same way; majors are the only action bumps that get a PR anywhere. - `dependabot-validate` stub `name:` stays byte-identical (`Dependabot validate`) — `-report`'s `workflow_run` name-matches it. The job always runs and branches internally; never `if:`-skip it. +- `templates/github/claude-standards.md` is style only — never permissions, tool rules or hooks. On a PR + run claude-code-action restores `CLAUDE.md` and `.claude/` from the base branch but not `.github/`, so + the `@` import resolves to the PR head's copy and a collaborator's branch can change what the protected + file loads (Avara #226, 2026-10-01; accepted by decision). Load-bearing rules go in `CLAUDE.md` or `.claude/`. - Never `pull_request_target`. Never set `anthropic_api_key` (overrides OAuth, bills at API rates). - The `claude.yml` reusable's `actions/checkout` keeps `persist-credentials` at default — claude-code-action's early fetch 403s on a private repo without it. The Dependabot reusables' checkouts diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index b8fa5ef..5a7d8f4 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -36,18 +36,6 @@ To-dos are the open `todo` issues on this repo since 2026-10-01 (#61–#64 carry ## Open decisions -- **Where the standards file lives, given PR runs.** claude-code-action restores a fixed list from the - PR base before Claude starts (`.claude/`, `.mcp.json`, `.claude.json`, `.gitmodules`, `.ripgreprc`, - `CLAUDE.md`, `CLAUDE.local.md`, `.husky/` — `SENSITIVE_PATHS` in its `restore-config.ts`, documented in - its `docs/security.md`). `.github/claude-standards.md` is not on it, so on a PR run the base's - `CLAUDE.md` imports the PR head's copy: a collaborator's branch can change what the protected file - loads (forks and outsiders are already refused by the Trusted-authors step). Found by Avara #226, - 2026-10-01. Options: accept it and keep the file style-only — nothing load-bearing (permissions, - tool rules, hooks) ever goes in it, those live in `CLAUDE.md` or `.claude/`, which the action - restores — or move it under `.claude/` so it rides the restore list (changes `dest()` in the wave, - the audit probe, the docs and every repo's import line; some repos gitignore `.claude/`). A restore - step in the reusable cannot work on the comment path, where the action checks out the PR branch - itself after our steps. Recommended: accept with the style-only rule, recorded as an invariant. - **`dependabot-report`'s future.** It runs Claude automatically on every Dependabot PR (verdict over the inert artifact, never the diff). Macroscope reviews Dependabot PRs too since 2026-09-10, so it is the one place two bots still review automatically. Keep, or retire like the review rails. @@ -69,7 +57,8 @@ To-dos are the open `todo` issues on this repo since 2026-10-01 (#61–#64 carry both `CLAUDE.md` and `.github/claude-standards.md` as attachments; Avara #226, 2026-10-01). The comment path is still unverified: the `@claude` must come from a collaborator or the dispatcher (bot comments are `author_association` NONE), and the transcript never prints loaded instructions, so - have the implementer quote the attachment header. See the open decision on where the file lives. + have the implementer quote the attachment header. The PR-run gap (the import resolves to the PR + head's copy) is accepted: the file is style-only, now a `CLAUDE.md` invariant (Maria, 2026-10-01). - A human `@claude` (tag mode) still gets the action's own co-author text; the nine-item quality standard is global to `--append-system-prompt` — both unchanged. @@ -87,10 +76,13 @@ To-dos are the open `todo` issues on this repo since 2026-10-01 (#61–#64 carry not run tickets through the app before it). On Avara, the first store run's log must read `Provisioned store 'avara'` and the "Mint the store token as a log mask" step must pass — never print the token cache to prove the mask. -3. **`fleet-wave.sh` gains `.macroscope/check-run-agents/`** (#61) — after the first real Avara design +3. **Ride-along for the next reusable change** (#70, part 2): reword `claude.yml`'s + `--append-system-prompt` item (7) to the revised comments standard — a tight summary, no apostrophes, + no newline — then release, repin and wave as usual. Not urgent (Maria, 2026-10-01). +4. **`fleet-wave.sh` gains `.macroscope/check-run-agents/`** (#61) — after the first real Avara design ticket tunes the rubric (driver-agents #32 holds the prompt; Avara's copy merged 2026-09-29). The `dest()` helper is where a second root goes. -4. **Fleet `dependabot.yml` standard** (#62): the kit block, cooldown included, is the candidate; +5. **Fleet `dependabot.yml` standard** (#62): the kit block, cooldown included, is the candidate; the gaps are in [`fleet-operations.md`](fleet-operations.md#dependabot-and-the-wave). ## Pointers diff --git a/templates/github/claude-standards.md b/templates/github/claude-standards.md index 8a22444..1b3e5f8 100644 --- a/templates/github/claude-standards.md +++ b/templates/github/claude-standards.md @@ -3,16 +3,37 @@ Shared across every Driver repo. The fleet wave installs this file at `.github/claude-standards.md` beside the implementer and keeps it current (a repo without the implementer copies it by hand); the repo's `CLAUDE.md` imports it with `@.github/claude-standards.md`. Edit it in `DriverDigital/workflows` -(`templates/github/claude-standards.md`), never in place. +(`templates/github/claude-standards.md`), never in place. It carries style only — never permissions, +tool rules or hooks: on a pull request the implementer loads `CLAUDE.md` from the base branch but this +file from the PR head, so anything load-bearing belongs in `CLAUDE.md` or `.claude/`. - **Commit messages** — Natural language, not strict conventional-commit formatting. Succinct: what changed, plus any rationale a senior developer would need later. No history, narratives, or who-decided-what. -- **Code comments** — Code should be self-describing whenever possible. Comments are written as one - senior engineer to another, only to clarify complex or non-obvious code, in 2–3 lines at most. Never - make junior-level comments (e.g. saying what a for loop does), and never put requirements, decisions, - or history in a comment. In a theme repo, each Liquid file opens with a short `{% comment %}` saying - what it is, where it's used, and any setup it needs. +- **Code comments** — Code should be self-describing; comments are written as one senior engineer to + another. A comment is either a *guidebook* (what this is, where it is used, how it works, what it is + bound to) or *provenance* (which Figma frame, which ticket, which date, who decided). Guidebooks + stay; provenance never goes in code. + - *Wayfinding stays.* A one-line label naming a region (`{% comment %} Products {% endcomment %}`, + ``, `/* Mobile */`), a bare ownership tag on a block we wrote inside a + third-party file, Start/End markers around an app's script, and banners between a file's parts. + They may restate the code; that is their job. Drop one only when it repeats the header for the + same region. + - *Headers are guidebooks.* Every section and non-trivial file opens with one: what it renders and + where it is used, how it works when that is not obvious, the metaobjects and metafields that feed + it, the file on the other side of a binding, one line per param. Length follows complexity. Keep + an existing header whole and strip only its provenance lines; give a file without one a header. + - *Explanation earns its lines.* Only where the code does not show it: a coupling, an ordering or + timing constraint, a cascade trick, a unit gloss like `/* 11px */`. Two or three full sentences. + When compressing, keep the subject (the app or component), both ends of a coupling, and every + step of a trade-off; never swap in a slogan or absorb a neighbouring label. Do not reword a + comment that already fits. + - *Third-party code keeps its comments* as the app or vendor wrote them, junior ones included, so + it stays diffable against the source. + - *Disabled code is a code call.* Commented-out markup and debug blocks, with their reason line, + stay until a code change removes them. + - *Say it once.* History and cross-cutting context live in `CLAUDE.md`; a mechanism is explained at + the code that implements it, never replaced by a pointer; a rationale repeated within a file goes. - **To-dos** — One-off to-dos are GitHub issues labelled `todo` on the repo they belong to. The driver-skills plugin lists a repo's open ones at session start, and its todo-capture skill files new ones, including cross-repo handoffs with a `from:` line. Close the issue when done. `CLAUDE.local.md`