/projects was deleted with the hosted pipeline in b3dbf0b. Five redirects to it were not:
| file | line | path |
|---|---|---|
resources/views/login.stx | 20 | already signed in |
resources/views/login.stx | 124 | just signed in |
resources/views/register.stx | 20 | already signed in |
resources/views/register.stx | 133 | just signed in |
resources/views/forgot.stx | 19 | already signed in |
Every person who signed in would have landed on a 404. They now go to /reports — resources/views/reports/index.stx is what an account has instead of projects.
Why nothing caught it
Each guard failed for a different reason, and each was individually reasonable:
marketing-linksreadshrefattributes. These arewindow.location.replace(...)in a script, so the exact class of bug the test exists to prevent was invisible to it. It also only looked at the marketing pages —login.stxwas never in its list.- The post-deploy check probes
/, the marketing pages and the two robots files. It never signs in, and/projectsis not among them. - The live site answered 200 on every one of those paths throughout, because the running release predates the deletion. It still serves
/projectstoday and 404s/reports.
So the first correct deploy would have broken signing in, with all three checks green while it happened.
The fixes
tests/feature/marketing-links.test.ts now reads location.replace(...) and location.href = ... alongside href, and covers login, register, forgot, reset, account and AuthGuard.
Verified by reintroducing the bug rather than by assuming: the suite fails and names /projects. Restored, 28 pass.
.github/workflows/ci.yml — the post-deploy probe gains /login, /register and /reports. 200 is a weak assertion for the last one (it renders for an anonymous caller and lets AuthGuard bounce the browser, so curl sees the shell either way), but it still catches a route that stopped being registered and a page that 500s.
Verification
Clean slate, every gitignored artifact deleted first:
| step | result |
|---|---|
bun buddy lint | 1207 files, 0 errors |
bun buddy test:types | pass |
bun run test | 81 pass, 0 fail (was 75) |
bun test ./packages | 49 pass, 0 fail |
php packages/laravel/tests/run.php | 40 pass, 0 fail |
bun scripts/verify-tokens.ts | pass |
test-postgres unverified locally — no Postgres on this machine.
Worth knowing before merging
A green push to main fires the production deploy, so merging this releases everything from b3dbf0b forward in one go. Two open questions that a release makes non-theoretical:
resources/views/account.stxstill callsprojectsFor(user), which queries aprojectstable whose model was deleted. Not traced. That page is in the probe list now, so a 500 would fail the deploy rather than ship quietly.buddy migrateregenerates 13 drop-table migrations every run — the model snapshot still describesprojects,events,reports,report_blocks,report_shares,usage_countersand seven more. Harmless in CI against a fresh database; a real data decision against production.
🤖 Generated with Claude Code