You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Story (D): full-file on:/permissions drift guard in compliance-audit [#604] #607
Part of the shim-identity epic #604 — Story D-audit (full-file guard in compliance-audit).
The compliance audit is field-allowlist, not full-file, so a trimmed on: block passes. check_dev_lead_stub() validates channel pin + agent_ref + no per-stub concurrency: + statuses: read but never on:; the RING branch of check_centralized_workflow_stubs() validates pin only.
Changes (petry-projects/.github)
Add a tier-normalized full-file identity check: for each enrolled shim, re-derive the expected stub = canonical standards/workflows/<name>.ymlrepinned to the target repo's ring tier (reuse deploy-standard-workflows.sh repin logic / ring_canonical_ref, mirroring how template_stub_drift.sh emits-and-compares), then compare against the repo's deployed file. Any diff beyond the tier channel pin → finding.
At minimum, guard the on: trigger surface, permissions: block, and absence of per-stub concurrency: for dev-lead and all RING shims (fold into the full-file check or add explicit sub-checks).
Tests in the compliance-audit suite: trimmed trigger, added/removed permission, injected concurrency → each flagged; a correctly-tiered stub → clean.
Acceptance
A dev-lead.yml (or any RING shim) with a trimmed on: block is flagged by the weekly audit.
A stub that differs from the canonical template only by its correct tier channel pin is not flagged.
Issue:#607 — Story (D): full-file on:/permissions drift guard in compliance-audit [#604]
Scope
Add a tier-normalized surface-drift guard to compliance-audit.sh that flags a dev-lead / RING caller stub whose on: triggers, permissions: grants, or (per-stub) concurrency: block have drifted from the canonical standards/workflows/<name>.yml, while never flagging a stub that differs only by its correct tier channel pin.
Design notes
The three guarded surfaces (on:, permissions:, concurrency:) carry no channel pin — the tier pin lives only on the jobs.<id>.uses / agent_ref lines (already guarded by check_centralized_workflow_stubs / check_dev_lead_stub). So the surface comparison is tier-invariant by construction: a stub differing only by its correct tier pin has identical surfaces → not flagged (AC2). This is the "explicit sub-checks" branch Story (D): full-file on:/permissions drift guard in compliance-audit [#604] #607 authorizes, chosen over a full-file byte guard because agent-shield / feature-ideation document legitimate per-repo with: liberties (and feature-ideation a per-repo cron) that a byte guard would false-positive on.
feature-ideation's legit per-repo cron retune is tolerated by normalizing - cron: values before comparison; a trimmed trigger still drifts.
To avoid duplicate findings, dev-lead's existing dedicated permissions (statuses: read) and concurrency checks in check_dev_lead_stub stay as-is; the new check owns dev-lead's previously-unguarded on: surface plus all three surfaces for the 8 RING shims (whose permissions:/concurrency: were entirely unguarded).
Implementation Checklist
Add pure helpers to scripts/compliance-audit.sh: stub_extract_blocks, stub_normalize_surface, stub_surface_drift
Add check_stub_surface_drift(repo) (reads canonical from standards/workflows/, deployed via gh API) + STANDARDS_WF_DIR
Wire check_stub_surface_drift "$repo" into the per-repo driver loop
Tests to Write
test/scripts/compliance-audit/stub-surface-drift.bats exercising the real pure helpers:
trimmed trigger (removed on: event / narrowed types) → flagged
✅ Issue #607 — full-file on:/permissions drift guard in compliance-audit
Implemented the tier-normalized surface-drift guard for the centralized caller stubs (dev-lead + all RING shims). Chose the explicit sub-checks branch of the two authorized options: guard the three tier-invariant surfaces (on:, permissions:, concurrency:) rather than a full-file byte guard — a byte guard would false-positive on the documented per-repo with: liberties (agent-shield, feature-ideation) and feature-ideation's documented per-repo cron retune. Because those three surfaces carry no channel pin, the comparison is tier-invariant by construction, which satisfies AC2 automatically.
Changes
scripts/compliance-audit.sh
STANDARDS_WF_DIR — points the guard at the on-disk canonical templates in standards/workflows/.
Three pure, unit-tested helpers (org standard "decision logic lives in a pure, tested script"):
stub_extract_blocks <content> <key> — awk indentation extractor; captures every block for a key at any depth (so dev-lead's top-level permissions: {} + job-level permissions: are both compared), never treats a # concurrency: comment as the key.
stub_normalize_surface — strips comments/blank lines and collapses schedule cron: values (so a legitimate per-repo cron retune is not flagged).
stub_surface_drift <canonical> <deployed> <key> — success-means-drift (returns 0 on drift, 1 on clean).
check_stub_surface_drift <repo> — for each enrolled shim, re-derives the canonical surface and compares against the deployed stub via the contents API. Skips .github (source of truth) and .github-private (runs inline). dev-lead's permissions/concurrency already have dedicated higher-signal checks in check_dev_lead_stub(), so this check owns dev-lead's previously-unguarded on: only, plus all three surfaces for the 8 RING shims. on:/permissions: drift → error; concurrency: → warning. Shim list is in lockstep with RING_REUSABLES in lib/ring-pins.sh.
Wired into the driver loop after check_dev_lead_stub.
Activity
don-petry commentedon Jul 13, 2026
Dev-Lead Implementation Plan
Issue: #607 — Story (D): full-file on:/permissions drift guard in compliance-audit [#604]
Scope
Add a tier-normalized surface-drift guard to
compliance-audit.shthat flags a dev-lead / RING caller stub whoseon:triggers,permissions:grants, or (per-stub)concurrency:block have drifted from the canonicalstandards/workflows/<name>.yml, while never flagging a stub that differs only by its correct tier channel pin.Design notes
on:,permissions:,concurrency:) carry no channel pin — the tier pin lives only on thejobs.<id>.uses/agent_reflines (already guarded bycheck_centralized_workflow_stubs/check_dev_lead_stub). So the surface comparison is tier-invariant by construction: a stub differing only by its correct tier pin has identical surfaces → not flagged (AC2). This is the "explicit sub-checks" branch Story (D): full-file on:/permissions drift guard in compliance-audit [#604] #607 authorizes, chosen over a full-file byte guard becauseagent-shield/feature-ideationdocument legitimate per-repowith:liberties (andfeature-ideationa per-repo cron) that a byte guard would false-positive on.feature-ideation's legit per-repo cron retune is tolerated by normalizing- cron:values before comparison; a trimmed trigger still drifts.permissions(statuses: read) andconcurrencychecks incheck_dev_lead_stubstay as-is; the new check owns dev-lead's previously-unguardedon:surface plus all three surfaces for the 8 RING shims (whosepermissions:/concurrency:were entirely unguarded).Implementation Checklist
scripts/compliance-audit.sh:stub_extract_blocks,stub_normalize_surface,stub_surface_driftcheck_stub_surface_drift(repo)(reads canonical fromstandards/workflows/, deployed via gh API) +STANDARDS_WF_DIRcheck_stub_surface_drift "$repo"into the per-repo driver loopTests to Write
test/scripts/compliance-audit/stub-surface-drift.batsexercising the real pure helpers:on:event / narrowed types) → flaggedconcurrency:→ flaggedfeature-ideationcron retune → clean; canonicalconcurrency:retained → cleanTest Command
node_modules/.bin/bats test/scripts/compliance-audit/(CI:bats test/scripts/compliance-audit/)don-petry commentedon Jul 13, 2026
✅ Issue #607 — full-file
on:/permissionsdrift guard in compliance-auditImplemented the tier-normalized surface-drift guard for the centralized caller stubs (dev-lead + all RING shims). Chose the explicit sub-checks branch of the two authorized options: guard the three tier-invariant surfaces (
on:,permissions:,concurrency:) rather than a full-file byte guard — a byte guard would false-positive on the documented per-repowith:liberties (agent-shield, feature-ideation) and feature-ideation's documented per-repo cron retune. Because those three surfaces carry no channel pin, the comparison is tier-invariant by construction, which satisfies AC2 automatically.Changes
scripts/compliance-audit.shSTANDARDS_WF_DIR— points the guard at the on-disk canonical templates instandards/workflows/.stub_extract_blocks <content> <key>— awk indentation extractor; captures every block for a key at any depth (so dev-lead's top-levelpermissions: {}+ job-levelpermissions:are both compared), never treats a# concurrency:comment as the key.stub_normalize_surface— strips comments/blank lines and collapses schedulecron:values (so a legitimate per-repo cron retune is not flagged).stub_surface_drift <canonical> <deployed> <key>— success-means-drift (returns 0 on drift, 1 on clean).check_stub_surface_drift <repo>— for each enrolled shim, re-derives the canonical surface and compares against the deployed stub via the contents API. Skips.github(source of truth) and.github-private(runs inline). dev-lead'spermissions/concurrencyalready have dedicated higher-signal checks incheck_dev_lead_stub(), so this check owns dev-lead's previously-unguardedon:only, plus all three surfaces for the 8 RING shims.on:/permissions:drift →error;concurrency:→warning. Shim list is in lockstep withRING_REUSABLESinlib/ring-pins.sh.check_dev_lead_stub.test/scripts/compliance-audit/stub-surface-drift.bats(new, 16 tests) — AC1 (trimmed trigger / narrowed types / dropped discussion → flagged), AC2 (ring1-repinned stub clean on every surface), permissions add/remove flagged, dev-leadstatuses: readremoval flagged, concurrency injection flagged, feature-ideation canonical concurrency retained clean / changed flagged, cron retune NOT flagged, plusstub_extract_blocksmulti-block / absent-key / comment-not-key coverage.Acceptance
dev-lead.yml(or any RING shim) with a trimmedon:block is flagged ✔ (tests 118–120)Verification
bats test/scripts/compliance-audit/→ 130 / 130 pass (16 new)shellcheck --severity=warning -x scripts/compliance-audit.sh→ cleanbash .dev-lead/scripts/dev-lead-lint.sh→ all checks passedNo commit/push/PR performed — leaving git operations to CI.
feat: implement issue #607 — Story (D): full-file on:/permissions dri…
feat: implement issue #607 — Story (D): full-file on:/permissions dri…