Repository navigation
Epic: Enforce identical reusable-workflow shims across the fleet (full-file drift, not just pin) #604
Description
Problem
Fleet Monitor issue combsmith/broodminder-data#7 proposed trimming dev-lead.yml's
on: block, justified by: "the stub header explicitly permits adjusting dev-lead triggers
for repo-specific needs, and drift detection guards only the initiative-planner stub, so this
is not flagged drift." That statement is currently true — and that is the bug. We want
dev-lead, pr-review-*, and every other reusable-workflow shim to be full-file identical
across repos (modulo the per-repo ring/channel pin), so a trigger/permission/concurrency
edit to a shim is flagged drift, never sanctioned.
Why it slips through today (enforcement inventory)
| Shim | Check | What it validates | on: / full-file? |
|---|---|---|---|
dev-lead.yml |
check_dev_lead_stub() |
channel pin (stable/next/ring<N>), agent_ref, no per-stub concurrency:, statuses: read |
❌ on: never checked |
auto-rebase, dependency-audit, dependabot-automerge, dependabot-rebase, agent-shield, pr-review-mention |
check_centralized_workflow_stubs() (RING) |
pin only | ❌ |
feature-ideation |
same, fixed v1 |
pin only; template is a frozen @SHA (off channel model) |
❌ |
pr-auto-review |
none | not in centralized[]; template pins @v2 (off channel) |
❌ |
initiative-planner, initiative-driver |
fleet_stub_drift.sh (byte-identity) |
full-file blob-SHA vs canonical | ✅ (only these two) |
Both compliance functions are field-allowlist checks, not full-file identity. The only
byte-identity mechanism (fleet_stub_drift.sh via fleet_monitor.sh STUB_REGISTRY) is
enrolled for just the two initiative stubs. Net: a trimmed trigger surface on any shim passes.
Fleet is already fragmented (survey, 2026-07-04)
Deployed reusable pins across 7 consumer repos are a mix of @vN, @SHA, @main, and channel
tags on nearly every shim. Only broodminder-export is fully converged onto the
@<name>/stable channel model. This drift is invisible because ring-pins.sh's legacy
@v1/@v2/@SHA grace is still active (declared "migration complete" in-comment, but the fleet
is not converged).
Sanctioning language to remove (A)
standards/workflows/dev-lead.ymlheader line ~19: "…may be freely modified on PR branches
to adjust triggers for repo-specific needs." (contradicts line 7 "Copy this file verbatim")..github-private/AGENTS.md: "Repo-specific trigger adjustments may be made todev-lead.yml…".github-private/docs/dev-lead/implementation-plan.md(~line 543): same header text.
Target state
Every centralized shim is byte-identical across repos after normalizing the ring/channel pin
to the repo's tier (ring_canonical_ref, deploy-standard-workflows.sh repin). Allowed pins:
@<name>/{stable,next,ring0,ring1,…} — never @SHA, @main, or @vN. Any other diff = drift.
Approach: B + A → D (D proves E)
Do B (standards) and A (strip sanctions) first; then D (build tier-normalized
byte-identity fleet drift and enroll every shim). Running D surfaces the existing fragmentation,
and that report drives and proves E (consumer re-syncs) — monitor goes green as repos converge.
Stories
B — Standards (petry-projects/.github)
-
standards/ci-standards.md: state centralized shims are full-file identical modulo the
tier channel pin; triggers/permissions/concurrency are not repo-adjustable. Cross-link
the channel model (#reusable-workflow-versioning--the-stable-channel). - Decide & document the two off-channel exceptions: bring
feature-ideationand
pr-auto-reviewonto the channel model, or record them as explicit fixed-pin exceptions
(and addpr-auto-reviewtocentralized[]either way — it is currently unenforced).
A — Remove sanctioning language
-
standards/workflows/dev-lead.ymlheader (petry-projects/.github). -
.github-private/AGENTS.md+docs/dev-lead/implementation-plan.md(petry-projects/.github-private). - Comment on docs: document branch protection rules, rulesets, and auto-merge policy #7 correcting the premise so the next dev-lead run does not reuse it.
D — Tier-normalized full-file drift + enrollment
- Extend the byte-identity model so "expected" content is the canonical template repinned to
the target repo's ring tier (reusedeploy-standard-workflows.shrepin /ring_canonical_ref,
mirroringtemplate_stub_drift.sh's emit-and-compare). This is what makes full-file identity
compatible with per-tier channel pins. - Add a full-file
on:/permissions/concurrency guard tocheck_dev_lead_stub()and the
RING branch ofcheck_centralized_workflow_stubs()(or fold both into the drift check), so a
trimmed trigger surface is flagged in the weekly compliance audit too. - Register
dev-lead.yml,pr-review-mention.yml, and the RING shims in
fleet_monitor.shSTUB_REGISTRY(.github-private) so drift is alerted, not just audited. - Tests:
fleet_stub_drift.bats/ compliance-audit test suite for the tier-normalized cases.
E — Converge the fleet (driven & proven by D)
- Re-sync each drifted consumer to its tier channel (per the D drift report):
TalkTerm,
broodly,ContentTwin,markets,google-app-scripts,bmad-bgreat-suite— one PR per
repo, admin-merge where rulesets block direct push. - Once converged, remove the
@v1/@v2/@SHAlegacy grace fromring-pins.shso off-channel
pins are hard-failed (the grace's own comment already claims the migration is complete). - Acceptance: fleet drift monitor reports 0 drifted across all enrolled shims.
Out of scope / follow-ups
- CodeQL /
ci.yml/sonarcloud.yml(per-repo by design — not centralized shims). - SonarCloud S7637/S7635 markers already handled by existing standards.
Survey performed against fresh branches: .github@docs/enrollment-gate-labels,
.github-private@fix/code-quality-add-secret-scan-coverage-966.
Decision log
- 2026-07-04 — off-channel shims → channel-ify (all shims use channels, no fixed-pin exceptions).
feature-ideation(@sha) andpr-auto-review(@v2) move onto@<name>/stablechannels and join the RING model + compliance. See story Story (B): channel-ify feature-ideation + pr-auto-review [#604] #606.
Story tracking
- Story (B+A): standards + strip dev-lead trigger-edit sanction [#604] #605 — B+A standards + strip dev-lead trigger-edit sanction (petry-projects/.github)
- Story (B): channel-ify feature-ideation + pr-auto-review [#604] #606 — B channel-ify
feature-ideation+pr-auto-review(petry-projects/.github) - Story (D): full-file on:/permissions drift guard in compliance-audit [#604] #607 — D full-file
on:/permissions drift guard in compliance-audit (petry-projects/.github) - Story (A+D): strip AGENTS/impl-plan sanction + enroll all shims in fleet byte-identity drift [petry-projects/.github#604] .github-private#1079 — A+D strip AGENTS/impl-plan sanction + enroll all shims in fleet byte-identity drift (.github-private)
- E — consumer re-syncs (
TalkTerm,broodly,ContentTwin,markets,google-app-scripts,bmad-bgreat-suite) + remove@v1/@v2/@SHAlegacy grace. Filed after D lands and its drift report exists; the report is the worklist and the proof (acceptance: 0 drifted).
Execution model
Work is triggered by applying the dev-lead label to the story issues above; progress is monitored via the fleet monitor and steered as needed. Order: #605 / #606 / #1079 (independent) → #607 and #1079-D (drift) → E.
Activity
don-petry commentedon Jul 10, 2026
Plan review — 2026-07-10
The world moved under this epic since it was filed (2026-07-04). The motivation section is largely overtaken by events; the enforcement thesis is still valid and unaddressed. Summary and revised scope below.
Overtaken by events
@v1/@v2/@SHAlegacy grace.ring-pins.shnow hard-flags off-channel pins for RING shims — this was Story E's headline task.auto-rebase,dependency-audit,dependabot-automerge,dependabot-rebase,agent-shield,pr-review-mention,dev-lead) is now on<name>/<tier>channels across all 7 consumers, with correct tiers (TalkTerm/bmad → ring1, rest → stable). The "only broodminder-export converged" survey is stale..githuband enabled (Epic: relocate the canary-rollout engine + bootstrap into .github (org tooling consolidation) #613 / feat(#613): relocate canary-rollout engine + bootstrap into .github (workflow disabled) #624 / feat(#613): enable canary-rollout schedule in .github (cutover) #628 / canary-rollout: autocut silently broken after #613 relocation — execs cut-release.sh (left in .github-private) #633 / fix(canary-rollout): autocut cuts inline via gh-api — no sibling cut-release.sh (#633) #634). The automated ring-promotion engine is now live — it's what re-synced the fleet.Still valid and unaddressed (the actual core of this epic)
check_dev_lead_stub()still never validateson:;check_centralized_workflow_stubs()RING branch validates pin only; andfleet_stub_drift.shSTUB_REGISTRYstill contains onlyinitiative-planner. A trimmed trigger surface on any shim still passes silently — the exact broodminder-export#7 hole.standards/workflows/dev-lead.yml:19,.github-private/AGENTS.md:26,.github-private/docs/dev-lead/implementation-plan.md:543.feature-ideation(@v1/@v2/@sha) andpr-auto-review(@v2/@sha) are still off-channel — now the only consumer-facing off-channel pins left in the fleet (RING_REUSABLESstill excludes both).Revised scope
on:/permissions guard): unchanged, now the highest-value remaining work — it's the only thing that closes the original bug.feature-ideation+pr-auto-reviewto their new channels after Story (B): channel-ify feature-ideation + pr-auto-review [#604] #606, then confirm 0 drift. The "fleet fragmented" acceptance survey is obsolete and should be rewritten.Body edits recommended
feature-ideation/pr-auto-reviewremain off-channel pending Story (B): channel-ify feature-ideation + pr-auto-review [#604] #606.ring-pins.sh's legacy@v1/@v2/@SHAgrace is still active" — grace removed in [#850] standards-deploy driver deploys BROKEN dev-lead pins (@dev-lead/v14-* has no tag — uses release major, not channel major) #870.@v1/@v2/@SHAlegacy grace" done ([#850] standards-deploy driver deploys BROKEN dev-lead pins (@dev-lead/v14-* has no tag — uses release major, not channel major) #870); scope remaining re-sync to the two Story (B): channel-ify feature-ideation + pr-auto-review [#604] #606 shims only.New: major-version gap (Story F, filed separately)
The version+ring model has no major-version boundary — channels (
next/ring0/ring1/stable) encode blast-radius tier, not semver major, and@vNis now drift. A breaking change promoted tostablereaches everystableconsumer with no opt-in gate. Filed as Story F to decide: major-scoped channels vs. a promotion gate at the major bump vs. accept-and-document.Reviewed 2026-07-10 against live
ring-pins.sh,compliance-audit.sh,fleet_stub_drift.sh, and the deployed pins across all 7 consumer repos.Generated by Claude Code
feat: implement issue #605 — Story (B+A): standards + strip dev-lead …
feat: implement issue #606 — Story (B): channel-ify feature-ideation …
feat: implement issue #607 — Story (D): full-file on:/permissions dri…
feat: implement issue #606 — Story (B): channel-ify feature-ideation …
feat: implement issue #607 — Story (D): full-file on:/permissions dri…