Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The public home of Driver's Bonsai→GitHub pipeline workflows. Two products liv
four caller stubs pinning a reusable by immutable SHA (`claude.yml` and the Dependabot three), plus
three whole-file workflows (`shopify-tool-smoke.yml` store repos only, `lint.yml`,
`pr-bonsai-link.yml` beside `claude.yml`) and `pull_request_template.md` and `claude-standards.md`
(both live at `.github/`; the wave carries them) and `dependabot.yml` (hand-installed — merged into a repo's existing file, never copied over it).
(both live at `.github/`; the wave carries them and installs `claude-standards.md` beside `claude.yml`; the `@` import in each repo's `CLAUDE.md` is by hand) and `dependabot.yml` (hand-installed — merged into a repo's existing file, never copied over it).
Kit install conventions: `templates/github/README.md`.

PR review is Macroscope's, org-wide (Maria, 2026-09-12): Claude reviews a PR only when a person `@claude`s it
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ all PRs — [`docs/macroscope-integration-scope.md`](docs/macroscope-integration
carries a caller stub for each reusable above, plus `shopify-tool-smoke.yml` (store repos only),
`lint.yml` (actionlint over the installing repo's own workflows), `pr-bonsai-link.yml` (fails a PR
that names no Bonsai task; installed beside `claude.yml`), `pull_request_template.md` (waved since v1.15.0), `claude-standards.md` (the house commit and comment
standard, imported by each repo's `CLAUDE.md`, waved at `.github/`) and `dependabot.yml` (the `github-actions` updater that bumps
standard, installed beside `claude.yml` and waved at `.github/`; each repo's `CLAUDE.md` imports it) and `dependabot.yml` (the `github-actions` updater that bumps
the stub pins between waves — installed by hand, merged into an existing file).

**Not every repo takes the whole kit.** A repo that is not on the Bonsai → PR pipeline can install
Expand Down
2 changes: 2 additions & 0 deletions docs/HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ To-dos are the open `todo` issues on this repo since 2026-10-01 (#61–#64 carry

1. **Make `bonsai-link` a required check per repo** — the wave has installed it everywhere `claude.yml`
is; the context is the job id `bonsai-link` (kit README). First, because step 2 waits.
The wave also installs `claude-standards.md` beside `claude.yml` since 2026-10-01; the
`@.github/claude-standards.md` import is a `todo` issue in each repo that lacks it.
2. **One real ticket end to end** on the new rail, transcript read (private repos log it) — after
driver-engineering-app's security hardening pass (Maria, 2026-10-01: a couple of weeks; she will
not run tickets through the app before it). On Avara, the first store run's log must read
Expand Down
4 changes: 3 additions & 1 deletion docs/fleet-operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ commit per file. Per target:
the wave aborts a target whose deployed file still carries a handle the variable does not hold.
The PR template and `claude-standards.md` are written under `.github/`, the rest under
`.github/workflows/`.
2. `pr-bonsai-link.yml` ← written wherever `claude.yml` is, present or not.
2. `pr-bonsai-link.yml` and `claude-standards.md` ← written wherever `claude.yml` is, present or not.
The `@.github/claude-standards.md` import in `CLAUDE.md` stays a per-repo edit: the wave never
writes outside `.github/`.
3. Delete by presence anything the kit no longer ships (`bonsai-status-sync.yml` since v1.13.0).
4. `actionlint` every file about to be written, then one atomic commit (CI-skip token in the
message) and patch the ref.
Expand Down
6 changes: 3 additions & 3 deletions templates/github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ workflow here touches it.
|---|---|---|
| `pr-bonsai-link.yml` | `.github/workflows/pr-bonsai-link.yml` — wherever `claude.yml` is | Fails a PR whose body names no Bonsai task: an `app.hellobonsai.com/tasks/<uuid>` URL, or a `Bonsai task: none` line. Dependabot PRs are exempt. Check-run context is the job id, **`bonsai-link`**; make it required per repo only once the wave has installed it. |
| `pull_request_template.md` | `.github/pull_request_template.md` | Gives human PRs the `Bonsai task: <url> \| none` line `bonsai-link` checks for, and prompts them to **link the Bonsai issue** (`Closes #N`) so the dispatcher can resolve the task. AI PRs write both themselves. |
| `claude-standards.md` | `.github/claude-standards.md` | The house commit-message and code-comment standard. The repo's `CLAUDE.md` imports it with `@.github/claude-standards.md` (replacing any pasted copy), so local sessions load it (CI loading is unconfirmed — `../../docs/HANDOFF.md`). Lint-only repos are wave targets through it. |
| `claude-standards.md` | `.github/claude-standards.md` — wherever `claude.yml` is | The house commit-message and code-comment standard. The repo's `CLAUDE.md` imports it with `@.github/claude-standards.md` (replacing any pasted copy), so local sessions load it (CI loading is unconfirmed — `../../docs/HANDOFF.md`). Lint-only repos are wave targets through it. |
| `shopify-tool-smoke.yml` | `.github/workflows/` — **STORE REPOS ONLY** | Manual (`workflow_dispatch`) diagnostic for the Shopify admin tool: secrets → `driver-agents` clone at the pin → token mint → Admin API, read-only. Fails **loudly** where `claude.yml` degrades — that's the point. Skip it in repos with no store. |
| `lint.yml` | `.github/workflows/lint.yml` | actionlint + shellcheck over the installing repo's own `.github/workflows/`. Guards the one CI failure with no signal: a YAML or shell error surfaces as a `startup_failure` — no check run, no notification — which on the PR page is indistinguishable from checks that have not started. Check-run context is the job id, **`actionlint`**. Not the same file as this repo's own `.github/workflows/lint.yml`, which runs a superset and never ships. |

Expand Down Expand Up @@ -122,8 +122,8 @@ Requested, approved → Ready for QA) were retired with the review leg at v1.12.
Then add `@.github/claude-standards.md` to the repo's `CLAUDE.md` (a new repo: start `CLAUDE.md`
as that line and let `/init` write the rest around it).
Every file above is kept current by the wave afterwards (`tools/fleet-wave.sh`, presence-based:
it replaces what a branch already carries, and installs only `pr-bonsai-link.yml`, beside
`claude.yml`).
it replaces what a branch already carries, and installs `pr-bonsai-link.yml` and
`claude-standards.md` beside `claude.yml`; the `CLAUDE.md` import line is the one step it cannot do).
**Then `dependabot.yml`, by hand** — it is the updater for the stub pins (without it nothing
bumps the `uses: DriverDigital/workflows/...@<sha>` lines between waves), and most repos already
have one, so never blind-copy it. No `.github/dependabot.yml` → copy the kit's. One without a
Expand Down
7 changes: 4 additions & 3 deletions templates/github/claude-standards.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# House standards

Shared across every Driver repo. A repo copies this file to `.github/claude-standards.md` once and
imports it from its `CLAUDE.md` with `@.github/claude-standards.md`; the fleet wave keeps the copy
current. Edit it in `DriverDigital/workflows` (`templates/github/claude-standards.md`), never in place.
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.

- **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
Expand Down
15 changes: 11 additions & 4 deletions tools/fleet-pin-audit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,23 @@ scan_ref() { # repo ref
[ -f "$KIT/$f" ] || continue
content_row "$repo" "$ref" "$f"
done
# The wave installs pr-bonsai-link.yml wherever claude.yml is, so its absence there is drift.
# The wave installs pr-bonsai-link.yml and claude-standards.md wherever claude.yml is, so their
# absence there is drift (the standards file is probed at .github/ below).
if grep -qx claude.yml <<<"$files" && ! grep -qx pr-bonsai-link.yml <<<"$files"; then
echo "CONTENT $repo@$ref pr-bonsai-link.yml DRIFT missing"
fi
# The kit files outside .github/workflows/: the PR template (waved since v1.15.0) and the house
# standards.
# standards. Presence comes from the directory listing, as above, so a failed API call skips the
# file rather than reading as "missing".
local dotgithub
dotgithub="$(gh api "repos/$ORG/$repo/contents/.github?ref=$ref" --jq '.[].name' 2>/dev/null)" || dotgithub=""
for f in pull_request_template.md claude-standards.md; do
if gh api "repos/$ORG/$repo/contents/.github/$f?ref=$ref" \
-H 'Accept: application/vnd.github.raw' > "$TMP/raw" 2>/dev/null; then
if grep -qx "$f" <<<"$dotgithub"; then
gh api "repos/$ORG/$repo/contents/.github/$f?ref=$ref" \
-H 'Accept: application/vnd.github.raw' > "$TMP/raw" 2>/dev/null || continue
content_row "$repo" "$ref" "$f"
elif [ -n "$dotgithub" ] && [ "$f" = claude-standards.md ] && grep -qx claude.yml <<<"$files"; then
echo "CONTENT $repo@$ref $f DRIFT missing"
fi
done
}
Expand Down
7 changes: 5 additions & 2 deletions tools/fleet-wave.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# every kit file the branch already carries <- kit version; the PR template and the house
# standards live at .github/, the rest at
# .github/workflows/
# pr-bonsai-link.yml <- also written wherever claude.yml is
# pr-bonsai-link.yml, claude-standards.md <- also written wherever claude.yml is
# bonsai-status-sync.yml <- deleted if present (kit no longer ships it)
#
# Guards, in order:
Expand Down Expand Up @@ -213,9 +213,12 @@ plan_and_push() {
grep -qxFf <(printf '%s\n' "$kit_paths") <<<"$existing" \
|| { echo " $repo@$branch: no kit file in the .github listings" >&2; exit 3; }

# Two files are installed beside claude.yml, not only refreshed where present: the Bonsai-link
# check and the house standards (whose CLAUDE.md import stays a per-repo edit — nothing outside
# .github/ is ever written).
for f in "${FULL_FILES[@]}"; do
grep -qxF "$(dest "$f")" <<<"$existing" \
|| { [ "$f" = pr-bonsai-link.yml ] && grep -qxF .github/workflows/claude.yml <<<"$existing"; } \
|| { case "$f" in pr-bonsai-link.yml|claude-standards.md) grep -qxF .github/workflows/claude.yml <<<"$existing" ;; *) false ;; esac; } \
|| continue
# errexit would abort on the cp's missing source anyway; this fails with a clear message and
# exit 3 before the network fetch. If the kit dropped it on purpose it belongs in DELETE_FILES.
Expand Down
Loading