Skip to content

feat(safety): add dependency-safety workflow with native-cooldown verification#61

Merged
j7an merged 11 commits into
mainfrom
feat/dependency-safety-workflow
May 23, 2026
Merged

feat(safety): add dependency-safety workflow with native-cooldown verification#61
j7an merged 11 commits into
mainfrom
feat/dependency-safety-workflow

Conversation

@j7an
Copy link
Copy Markdown
Owner

@j7an j7an commented May 23, 2026

Summary

Adds dependency-safety.yml, a reusable workflow that verifies the
Dependabot-cooldown invariant on each scan instead of enforcing its own
waiting period. Native Dependabot cooldown.default-days: 5 owns the
wait; the workflow scans, comments, labels, and optionally auto-merges,
failing deterministically when a young target version slips through.

  • New: dependency-safety.yml, safety-verdict.sh, safety-verdict.bats, ci-safety.yml
  • Removed: ci-cooldown.yml (replaced by ci-safety.yml)
  • Modified: .github/dependabot.yml (cooldown 7→5), check-inline-sync.sh (5→10 pairs), README.md (rewrite), .claude/CLAUDE.md (docs)
  • Untouched: dependency-cooldown.yml, cooldown-rescan.yml (Phase 2 migration window)

Test plan

  • bats tests/safety-verdict.bats — 13 scenarios pass
  • bats tests/ — full suite passes (106/106)
  • ./scripts/check-inline-sync.sh — all 10 pairs sync
  • ./scripts/lint-workflow-call.sh — passes
  • After merge: next Dependabot PR to this repo runs through ci-safety.yml and produces a clean verdict (or expected age-violation if a bumped action is young)

Fixes #59.

j7an added 11 commits May 22, 2026 22:36
Pure verdict translator for the upcoming dependency-safety workflow.
Consumes scan facts as env vars, emits a 6-field TSV verdict line,
fail-closes on missing/invalid input.
Copies dependency-cooldown.yml as starting point with new identifiers
(workflow name, status context, comment marker, comment title). Extends
INLINE_PAIRS so the four shared scripts remain sync-checked under the
new file. Behavior is otherwise identical to dependency-cooldown.yml;
the verdict semantic change lands in the next commit.
…ndency-safety.yml

Inserts verdict computation immediately after scan-results counting,
deletes the legacy gate state machine, moves the auto-merge attempt to
just before the final status call so subsequent comment composition
(Task 5) can attach setup-failure notes. Swaps inputs:
cooldown_days -> minimum_release_age_days,
fail_on_cooldown -> fail_on_age_violation. Preserves COOLDOWN_DAYS env
name at the YAML/script boundary because check-release-age.sh (shared
with the legacy workflow) requires that name.

Uses the if-then-else command-substitution pattern for verdict capture
instead of $? — under bash -e a failing command substitution can
abort the step before $? is read.
Replaces cooldown-pending reconciliation with two new labels owned by
the new workflow: dependency-age-violation and dependency-safety-error.
security-review-needed is shared with the legacy workflow. cooldown-pending
is NOT touched here — it remains the legacy workflow's exclusive label
during Phase 2 migration.
Replaces hardcoded clean/dirty result footers with verdict-row-specific
operator guidance per spec §6.3. Renames Release Age section header
('cooldown:' -> 'minimum:'), reworks the unblock footer to not imply
auto-healing (no scheduled rescan), and attaches auto-merge SETUP-failure
notes to the comment instead of mutating the immutable status_desc.
Replaces ci-cooldown.yml with ci-safety.yml so this repo becomes the
canary for the new model. The legacy reusable workflows themselves
(dependency-cooldown.yml, cooldown-rescan.yml) remain available for
sibling repos during Phase 2 migration.
Aligns this repo's own dependabot config with the new model's expected
floor. dependency-safety.yml's default minimum_release_age_days is also
5, so this repo's own Dependabot PRs should pass age verification on
the first scan.
Adds dependency-safety.yml to the workflows-and-roles list, marks the
two cooldown workflows as legacy during the Phase 2 migration window,
and extends the inline-sync pair list with the five new pairs.
Promotes dependency-safety.yml to the headline workflow and demotes
dependency-cooldown.yml / cooldown-rescan.yml to a 'Legacy Workflows'
section. Adds a Migration From Legacy Cooldown recipe and a Gate states
and labels reference table.
Replace the boolean coercion (HAS_ERROR → SCAN_ERROR_COUNT=0|1) with a
true counter incremented at each GHSA/OSV failure point. The verdict
script's contract defines SCAN_ERROR_COUNT as the number of scan
failures excluding Scorecard; the previous boolean underreported when
multiple packages errored in a single scan.

Fail-closed semantics unchanged: any count > 0 still escalates the
verdict to error.

Refs PR review finding #5.
…hape in README

Three doc fixes surfaced in PR review:

- Add a prominent note that native Dependabot cooldown applies only to
  version updates, not security updates. Repos with security updates
  enabled need to opt into advisory mode (fail_on_age_violation: false)
  knowingly, or wait for follow-up detection.
- Add a Step 6 to the legacy-cooldown migration section telling consumers
  to switch required-status-check rules from `dependency-cooldown / gate`
  to `dependency-safety / gate`. Old context would otherwise wait forever.
- Add a caveat near the Quick Start `@v2` reference that the floating tag
  only contains this workflow after a manual release dispatch. Correct
  the Versioning section's incorrect claim that merging a PR
  auto-creates tags — this repo uses manual `release-self.yml`.

Refs PR review findings #2, #3, #4.
@j7an
Copy link
Copy Markdown
Owner Author

j7an commented May 23, 2026

Pushed fixes for review findings #2, #3, #4, #5:

  • feat(safety): count GHSA/OSV errors into SCAN_ERROR_COUNT — replaces the boolean coercion at each failure point so the verdict script's count contract is honored. Fail-closed semantics unchanged.
  • feat(safety): clarify security-update scope, migration, and release shape in README — adds the security-update note (Prerequisites), branch-protection migration step (Step 6), @v2 pin caveat (Quick Start), and corrects the Versioning section.

Finding #1 (partial-extraction false-green) is deferred to #62 — it's inherited from dependency-cooldown.yml and the fix needs to touch both workflows together.

bats tests/ 106 pass · check-inline-sync.sh 10 pairs pass · lint-workflow-call.sh pass locally.

@j7an j7an merged commit 928d3db into main May 23, 2026
7 checks passed
@j7an j7an deleted the feat/dependency-safety-workflow branch May 23, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add dependency-safety workflow using native 5-day Dependabot cooldown

1 participant