Repository navigation
feat: implement issue #861 — [#850 Phase 1b] Make compliance audit + deploy compliance v<M>-stable-aware (flag bare tags) #863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1563,31 +1563,36 @@ check_centralized_workflow_stubs() { | |
| decoded=$(echo "$content" | base64 -d 2>/dev/null || echo "") | ||
| [ -z "$decoded" ] && continue | ||
|
|
||
| # Compliant if a non-comment `uses:` line pins the reusable at the canonical | ||
| # channel or — transitionally, during the #482 migration — an accepted legacy | ||
| # @vN ref. stub_pin_acceptable anchors to start-of-line so a `# uses: …` | ||
| # comment never satisfies the check. For RING reusables, also accept the | ||
| # major-scoped `<name>/v<M>-<tier>` form (major-scoped-channels epic #657 F3) | ||
| # for any major M whose tier matches the repo — backward-compatible with the | ||
| # bare-tier pins the fleet still carries; the wrong tier stays drift. | ||
| if stub_pin_acceptable "$decoded" "$reusable" "$canonical" "$legacy" \ | ||
| || { [ "$is_ring" = 1 ] && ring_major_form_acceptable "$decoded" "$reusable" "$chan" "$repo"; }; then | ||
| # Compliance rule (major-scoped-channels epic #657 F5, #861): | ||
| # RING reusables MUST pin the major-scoped `<name>/v<M>-<tier>` form — any | ||
| # major M whose tier matches the repo (ring_major_form_acceptable). A bare | ||
| # `<name>/<tier>` pin is now drift: the fleet has migrated onto the v-form, | ||
| # so the bare grace (stub_pin_acceptable) no longer applies to the rings. | ||
| # Non-RING reusables (fixed-pin entries) keep the exact/legacy match via | ||
| # stub_pin_acceptable. | ||
| # Both helpers anchor to start-of-line so a `# uses: …` comment never counts; | ||
| # a v-form pinned to the WRONG tier stays drift. | ||
| if { [ "$is_ring" = 1 ] && ring_major_form_acceptable "$decoded" "$reusable" "$chan" "$repo"; } \ | ||
| || { [ "$is_ring" != 1 ] && stub_pin_acceptable "$decoded" "$reusable" "$canonical" "$legacy"; }; then | ||
| continue | ||
| fi | ||
|
Comment on lines
+1575
to
1578
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The new ring-only acceptance path unconditionally rejects bare Severity Level: Major
|
||
|
|
||
| # Determine why it's non-compliant for a more actionable message. | ||
| local esc_reusable why | ||
| # Determine why it's non-compliant for a more actionable message. For RING | ||
| # reusables the expected pin is the major-scoped v-form `<name>/v<M>-<tier>` | ||
| # (major-agnostic on tier, #657 F5); non-ring keeps the fixed canonical ref. | ||
| local esc_reusable why expected_pin="$canonical" | ||
| esc_reusable=$(escape_ere "$reusable") | ||
| [ "$is_ring" = 1 ] && expected_pin="${chan}/v<M>-$(ring_tier_for_repo "$repo")" | ||
| if echo "$decoded" | grep -qE "^[[:space:]]*uses:[[:space:]]*petry-projects/\\.github/\\.github/workflows/${esc_reusable}\\.yml@"; then | ||
| why="references the reusable but is not pinned to \`@${canonical}\` (org standard)" | ||
| why="references the reusable but is not pinned to the major-scoped channel \`@${expected_pin}\` (org standard — a bare \`@${canonical}\` tier pin is drift)" | ||
| elif echo "$decoded" | grep -qF "petry-projects/.github/.github/workflows/${reusable}"; then | ||
| why="references the reusable but the \`uses:\` line does not match the canonical stub" | ||
| else | ||
| why="is an inline copy instead of a thin caller stub — re-sync from \`standards/workflows/${wf}\`" | ||
| fi | ||
|
|
||
| add_finding "$repo" "ci-workflows" "non-stub-$wf" "error" \ | ||
| "Centralized workflow \`$wf\` $why. Replace with the canonical stub from \`standards/workflows/${wf}\` which delegates to \`petry-projects/.github/.github/workflows/${reusable}.yml@${canonical}\`." \ | ||
| "Centralized workflow \`$wf\` $why. Replace with the canonical stub from \`standards/workflows/${wf}\` which delegates to \`petry-projects/.github/.github/workflows/${reusable}.yml@${expected_pin}\`." \ | ||
| "standards/ci-standards.md#centralization-tiers" | ||
| done | ||
| } | ||
|
|
@@ -1627,26 +1632,31 @@ check_dev_lead_stub() { | |
| # channel `next` and per-ring channels `ring0`, `ring1`, … A frozen `@vX.Y.Z` | ||
| # or `@<sha>` is NOT a channel and is intentionally rejected — callers pin the | ||
| # moving channel so rollout/rollback is a single central tag move. | ||
| if ! printf '%s\n' "$decoded" | grep -qE "^[[:space:]]*uses:[[:space:]]*petry-projects/\\.github-private/\\.github/workflows/dev-lead-reusable\\.yml@dev-lead/(stable|next|ring[0-9]+)([[:space:]]|$)"; then | ||
| # Major-scoped channels (#657 F5, #861): the channel MUST carry the `v<M>-` | ||
| # major prefix — a bare `dev-lead/stable` is now drift; only `dev-lead/v<M>-<tier>` | ||
| # (any major) is accepted, mirroring the RING reusables above. | ||
| if ! printf '%s\n' "$decoded" | grep -qE "^[[:space:]]*uses:[[:space:]]*petry-projects/\\.github-private/\\.github/workflows/dev-lead-reusable\\.yml@dev-lead/v[0-9]+-(stable|next|ring[0-9]+)([[:space:]]|$)"; then | ||
| add_finding "$repo" "ci-workflows" "dev-lead-stub-pin" "error" \ | ||
| "The \`dev-lead.yml\` caller stub must pin a \`dev-lead\` channel tag — \`petry-projects/.github-private/.github/workflows/dev-lead-reusable.yml@dev-lead/<channel>\` where <channel> is \`stable\` (default), \`next\`, or \`ring<N>\`. Re-sync from \`standards/workflows/dev-lead.yml\`." \ | ||
| "The \`dev-lead.yml\` caller stub must pin a major-scoped \`dev-lead\` channel tag — \`petry-projects/.github-private/.github/workflows/dev-lead-reusable.yml@dev-lead/v<M>-<channel>\` where <channel> is \`stable\` (default), \`next\`, or \`ring<N>\` (a bare \`dev-lead/<channel>\` tier pin is drift). Re-sync from \`standards/workflows/dev-lead.yml\`." \ | ||
| "standards/ci-standards.md#dev-lead-agent" | ||
|
Comment on lines
+1638
to
1641
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: This check now requires Severity Level: Major
|
||
| fi | ||
|
|
||
| # 2) agent_ref must be threaded through to pin the same channel inside the | ||
| # reusable's own script/prompt checkout (prevents split-brain on promotion). | ||
| # Same channel set as the uses: pin above; should match the uses: channel. | ||
| uses_channel=$(printf '%s\n' "$decoded" | sed -nE 's#^[[:space:]]*uses:[[:space:]]*petry-projects/\.github-private/\.github/workflows/dev-lead-reusable\.yml@dev-lead/(stable|next|ring[0-9]+)([[:space:]]|$).*#\1#p') | ||
| # Same major-scoped channel form as the uses: pin above; must match the uses: | ||
| # channel exactly — including its major, so a `v3-stable` uses pin with a | ||
| # `v2-stable` agent_ref is caught. | ||
| uses_channel=$(printf '%s\n' "$decoded" | sed -nE 's#^[[:space:]]*uses:[[:space:]]*petry-projects/\.github-private/\.github/workflows/dev-lead-reusable\.yml@dev-lead/(v[0-9]+-(stable|next|ring[0-9]+))([[:space:]]|$).*#\1#p') | ||
| if [ -n "$uses_channel" ]; then | ||
| if ! printf '%s\n' "$decoded" | grep -qE "^[[:space:]]*agent_ref:[[:space:]]*dev-lead/$uses_channel([[:space:]]|$)"; then | ||
| add_finding "$repo" "ci-workflows" "dev-lead-stub-agent-ref" "error" \ | ||
| "The \`dev-lead.yml\` caller stub must pass \`with: agent_ref: dev-lead/$uses_channel\` to match the pinned channel \`$uses_channel\`. Re-sync from \`standards/workflows/dev-lead.yml\`." \ | ||
| "standards/ci-standards.md#dev-lead-agent" | ||
| fi | ||
| else | ||
| if ! printf '%s\n' "$decoded" | grep -qE "^[[:space:]]*agent_ref:[[:space:]]*dev-lead/(stable|next|ring[0-9]+)([[:space:]]|$)"; then | ||
| if ! printf '%s\n' "$decoded" | grep -qE "^[[:space:]]*agent_ref:[[:space:]]*dev-lead/v[0-9]+-(stable|next|ring[0-9]+)([[:space:]]|$)"; then | ||
| add_finding "$repo" "ci-workflows" "dev-lead-stub-agent-ref" "error" \ | ||
| "The \`dev-lead.yml\` caller stub must pass \`with: agent_ref: dev-lead/<channel>\` (\`stable\`, \`next\`, or \`ring<N>\`) so the reusable checks out its own scripts/prompts from the same channel. Re-sync from \`standards/workflows/dev-lead.yml\`." \ | ||
| "The \`dev-lead.yml\` caller stub must pass \`with: agent_ref: dev-lead/v<M>-<channel>\` (\`stable\`, \`next\`, or \`ring<N>\`) so the reusable checks out its own scripts/prompts from the same major-scoped channel. Re-sync from \`standards/workflows/dev-lead.yml\`." \ | ||
| "standards/ci-standards.md#dev-lead-agent" | ||
| fi | ||
| fi | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -302,16 +302,27 @@ is_already_compliant() { | |
| if [[ "$prefix" =~ /([a-z0-9-]+)-reusable\.yml$ ]]; then | ||
| base="${BASH_REMATCH[1]}" | ||
| # Only treat it as ring-managed if the reusable is on the ring model AND the | ||
| # template pins a channel tag (not a frozen @vX / SHA). | ||
| if ring_is_ring_reusable "$base" && [[ "$ref_after" =~ ^${base}/(stable|next|ring[0-9]+)$ ]]; then | ||
| local ref | ||
| while IFS= read -r ref; do | ||
| [[ -n "$ref" ]] && grep -qF "${prefix}@${ref}" <<< "$existing_content" && return 0 | ||
| done < <(ring_accepted_refs "$base" "$repo") | ||
| # Transition to major-scoped channels (#657 F5): a stub already pinned to the | ||
| # repo's tier-correct `v<M>-<tier>` form (any major) is compliant too, so the | ||
| # sweep accepts both the bare and the v-form during migration. A WRONG-tier | ||
| # v-form is not accepted here and stays drift. | ||
| # template pins a channel tag (not a frozen @vX / SHA). The template ref may be | ||
| # the bare `<base>/<tier>` OR the major-scoped `<base>/v<M>-<tier>` form (#657 | ||
| # F5) — post-migration the templates pin the v-form, so both must enter here. | ||
| if ring_is_ring_reusable "$base" && [[ "$ref_after" =~ ^${base}/(v[0-9]+-)?(stable|next|ring[0-9]+)$ ]]; then | ||
| # Major-scoped channels (#657 F5, #861): the bare-tier grace is now | ||
| # major-AWARE. A bare `<base>/<tier>` stub stays compliant only while the | ||
| # agent has NO release (no current major line) — the pre-release fleet has | ||
| # nothing to major-scope to yet. Once the agent has a release, a bare stub is | ||
| # drift and must migrate to the tier's `v<M>-<tier>` form. | ||
| local host major | ||
| host="$(cut -d/ -f1-2 <<< "$prefix")" | ||
| major="$(ring_host_current_major "$host" "$base")" | ||
| if [[ -z "$major" ]]; then | ||
| local ref | ||
| while IFS= read -r ref; do | ||
| [[ -n "$ref" ]] && grep -qF "${prefix}@${ref}" <<< "$existing_content" && return 0 | ||
| done < <(ring_accepted_refs "$base" "$repo") | ||
|
Comment on lines
+315
to
+321
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The bare-tier grace is keyed only on Severity Level: Major
|
||
| fi | ||
| # A stub already pinned to the repo's tier-correct `v<M>-<tier>` form (any | ||
| # major) is compliant regardless of release state. A WRONG-tier v-form — or a | ||
| # bare stub once the agent has a release — is not accepted here and stays drift. | ||
| local existing_ref | ||
| existing_ref=$(grep -oE "@${base}/[^[:space:]\"']+" <<< "$existing_content" | head -1) | ||
| existing_ref="${existing_ref#@}" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Audit/deploy pin mismatch
🐞 Bug≡ CorrectnessAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools