Skip to content

feat: generate an opt-in PR drift-check workflow#236

Merged
joshua-temple merged 1 commit into
mainfrom
feat/generate-drift-check-workflow
Jun 21, 2026
Merged

feat: generate an opt-in PR drift-check workflow#236
joshua-temple merged 1 commit into
mainfrom
feat/generate-drift-check-workflow

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

cascade ships cascade verify (drift + orphan detection) and uses it as a required PR gate on its own repo, but users only get that protection if they wire the workflow by hand. Closes #229.

Fix

Adds an opt-in, additive manifest toggle drift_check (enabled + comment) under config:. When drift_check.enabled is set, cascade generate-workflow emits a pull_request drift-check workflow (.github/workflows/cascade-drift-check.yaml) that runs cascade verify and fails the check on drift. When drift_check.comment is also set, it emits the fork-safe workflow_run comment companion (.github/workflows/cascade-drift-comment.yaml) that posts the verify result as a sticky PR comment.

This mirrors cascade's own two-file dogfood pattern:

  • The pull_request job is strictly read-only (contents: read, no secrets, posts no comment). A fork PR gets a read-only token and uploads the verify result as the cascade-drift-result artifact instead.
  • The workflow_run companion runs in the base-repo context with a scoped pull-requests: write token, downloads the artifact (data only), and posts the sticky comment. It never checks out or executes PR head code.

Both generated files carry the cascade-owned GeneratedFileMarker, so cascade verify itself tracks them. Third-party actions route through the existing pin seam (pin_mode honored); the cascade self-action uses the cli_version ref pattern.

Security note

The generated comment companion derives the target PR number ONLY from trusted workflow_run run metadata (run.pull_requests[0].number, or listPullRequestsAssociatedWithCommit matching run.head_sha for fork PRs), NEVER from the fork-uploaded artifact. This preserves the fix from #228: a fork cannot redirect the comment at another PR. The pull_request job has no write permissions and no secrets and posts no comment itself.

Verification

  • schema_version is NOT bumped (the field is additive and omitempty); all three manifest.schema.json copies regenerated and byte-identical.
  • Unit tests assert the security invariant (PR number from trusted metadata, read-only pull_request job, no checkout/secrets/comment in the check lane), determinism, SHA pinning, and an actionlint pass over both files.
  • e2e scenario 28-drift-check.yaml: a manifest with the toggle ON generates both workflows, they are cascade-owned, and a fresh verify is clean. Ran under Docker: PASS.
  • go build ./... && go test ./... (1531 pass) and golangci-lint run ./... (clean); e2e module builds and vets clean.

Closes #229

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple joshua-temple enabled auto-merge (squash) June 21, 2026 07:24
@joshua-temple joshua-temple merged commit be1cd00 into main Jun 21, 2026
15 checks passed
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.

Generate a PR drift-check workflow for users' repos

1 participant