ci: detect drift between source SOPS YAMLs and embedded @gen/env payloads#18
ci: detect drift between source SOPS YAMLs and embedded @gen/env payloads#18cooper (czxtm) wants to merge 1 commit intomainfrom
Conversation
…oads PR #15/#17/#18 chased an Unauthorized: Authentication error in CI for roughly half a day. The proximate fix was a fresh Cloudflare token, but the real bug was that rotating that token in shared.sops.yaml never propagated into packages/gen/env/src/runtime/generated-payloads/_envs/deploy.ts, which is what loaders.deploy() actually decrypts at runtime. Codegen only runs on devshell entry; CI deploys never run codegen, so they happily shipped the old cfat_KJ57… value into every Worker request. This workflow closes the drift class with a hard CI gate: - On PR/push touching any source-of-truth path - enter the devshell and re-run stackpanel codegen build - git diff --quiet against the embedded runtime payloads under packages/gen/env/data/_envs/ and packages/gen/env/src/runtime/generated-payloads/_envs/ - on drift, print the affected files + a remediation command Verified locally that a simulated sops set edit triggers the failure and that a clean tree passes. Closes stackpanel-04d.
PR SummaryLow Risk Overview Updates Reviewed by Cursor Bugbot for commit 9020ad6. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Drift check misses per-app encrypted runtime payloads
- Updated the workflow drift-check target paths to diff the full
packages/gen/env/dataandpackages/gen/env/src/runtime/generated-payloadstrees so per-app encrypted payload drift is detected.
- Updated the workflow drift-check target paths to diff the full
Or push these changes by commenting:
@cursor push 102850f4d5
Preview (102850f4d5)
diff --git a/.github/workflows/secrets-codegen-check.yml b/.github/workflows/secrets-codegen-check.yml
--- a/.github/workflows/secrets-codegen-check.yml
+++ b/.github/workflows/secrets-codegen-check.yml
@@ -115,8 +115,8 @@
# stackpanel-04d for the rationale: the ONLY drift class that broke
# production was the embedded encrypted payload + its TS wrapper.
target_paths=(
- packages/gen/env/data/_envs
- packages/gen/env/src/runtime/generated-payloads/_envs
+ packages/gen/env/data
+ packages/gen/env/src/runtime/generated-payloads
)
if git diff --quiet -- "${target_paths[@]}"; thenYou can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit 9020ad6. Configure here.
| target_paths=( | ||
| packages/gen/env/data/_envs | ||
| packages/gen/env/src/runtime/generated-payloads/_envs | ||
| ) |
There was a problem hiding this comment.
Drift check misses per-app encrypted runtime payloads
High Severity
The target_paths array only covers the _envs/ subdirectories, but the repository has per-app encrypted payloads under packages/gen/env/src/runtime/generated-payloads/api/, web/, docs/, stackpanel-go/ and companion data files under packages/gen/env/data/dev/, prod/, staging/. These are real encrypted runtime payloads loaded via loadGeneratedPayload() in registry.ts — not the "typed env wrappers under src/<app>/" that get cosmetic churn (those live at src/exports/). A SOPS source rotation affecting per-app secrets like POSTGRES_URL would leave per-app payloads stale while this check passes silently — the same bug class the workflow was built to prevent.
Reviewed by Cursor Bugbot for commit 9020ad6. Configure here.



Summary
Closes
stackpanel-04d. Adds a GitHub Actions check that fails the build if anyone edits a SOPS source file (.stack/secrets/vars/*.sops.yaml, etc.) without re-running codegen and committing the regenerated embedded payloads underpackages/gen/env/.This is the bug class that ate ~half a day on PRs #15/#17/#18:
loaders.deploy()at runtime reads frompackages/gen/env/src/runtime/generated-payloads/_envs/deploy.ts, not from.stack/secrets/vars/shared.sops.yamldirectly.stackpanel codegen build env, which only runs on devshell entry.chore: rekey,sops set,himitsu set, etc. all silently drift the embedded payload from the source.mainHEAD continued decrypting to the oldcfat_KJ57…token and every CI deploy 401'd until the regen was committed (cf01361 on main, 7b62e2c on PR demo: drive Studio against MSW via endpoint swap (no /demo route) #15).What this changes
A single new workflow (
.github/workflows/secrets-codegen-check.yml):Triggers on PR/push touching any source-of-truth path — SOPS YAMLs, Nix env declarations, codegen implementation, or the generated outputs themselves.
Enters the Nix devshell (which writes
.stack/gen/codegen/env-manifest.jsonand runs codegen as part of the shell-hook).Re-runs
stackpanel codegen buildexplicitly with the sameSOPS_AGE_KEYthe deploy workflows use — belt-and-braces guarantee the build was run with the right decrypt key.git diff --quietagainst:packages/gen/env/data/_envs/packages/gen/env/src/runtime/generated-payloads/_envs/The diff is deliberately scoped to just the embedded runtime payloads. The typed env wrappers under
src/<app>/get cosmetic churn on every devshell entry and aren't on the deploy hot path.On drift: surfaces the file list inline and tells the contributor exactly what to run (
nix develop --impure --command stackpanel codegen build) and what to commit.Test plan
Verified locally inside the devshell on this branch:
sops setedit oncloudflare_api_token→ check fails with the expected file list (packages/gen/env/data/_envs/deploy.sops.json,packages/gen/env/src/runtime/generated-payloads/_envs/deploy.ts).CI verification will happen automatically on this PR.
Notes