Skip to content

ci: typecheck ratchet + changed-file lint on every PR#46

Merged
hblanken merged 1 commit into
collabfrom
chore/ci-typecheck-lint-ratchet
Jun 14, 2026
Merged

ci: typecheck ratchet + changed-file lint on every PR#46
hblanken merged 1 commit into
collabfrom
chore/ci-typecheck-lint-ratchet

Conversation

@hblanken

Copy link
Copy Markdown

Why

parse-smoke only catches Bun parse failures, not type errors — which is exactly how the TS2741 in #45 (required url missing on two PreviewStateSnapshot literals) reached a green PR. This adds the missing type + lint gates, designed around the fork's reality.

The constraint

A plain tsgo --noEmit gate is impossible here: the fork carries ~20 pre-existing TS errors (Drizzle drift, date/number mixups — documented in parse-smoke.yml) that the runtime tolerates but tsgo rejects. A naive gate would be red on day one and block every PR.

Two jobs

typecheck-ratchet — runs typecheck on both the PR head and the PR base, fails only on error signatures the PR introduces.

lint-changedoxlint on the PR's changed .ts/.tsx files only, so a new lint error fails without being blocked by lint debt in untouched files.

Files

  • .github/workflows/typecheck.yml
  • .github/scripts/collect-type-errors.sh (the signature collector)

Both reuse the existing ./.github/actions/setup-bun and run on ubuntu-latest.

To make it actually block merges

Mark typecheck-ratchet and lint-changed as required status checks in the collab branch-protection rule. Until then they run + report but don't block.

Note on the currently-open PRs

This gates PRs opened/updated after it merges. The open #37#45 were branched before it exists, so they won't get the new checks unless re-pushed — fine, they were already reviewed (#45's type errors are fixed).

Validated

YAML parses; bash -n clean on the script and all 5 run-blocks.

🤖 Generated with Claude Code

parse-smoke only catches Bun *parse* failures, not type errors — which is
how the TS2741 in PR #45 (required `url` missing on two PreviewStateSnapshot
literals) reached a green PR.  Add two PR gates:

typecheck-ratchet — runs `tsgo --noEmit` (via `bun turbo typecheck`) on BOTH
  the PR head and the PR base, and fails only on type-error signatures the PR
  INTRODUCES.  A plain typecheck gate is impossible on this fork: it carries
  ~20 pre-existing TS errors (Drizzle drift, date/number mixups — documented
  in parse-smoke.yml) that the runtime tolerates but tsgo rejects, so it would
  be red on day one.  The base-vs-head ratchet lets that debt through while
  catching anything new.  No committed baseline to maintain — the base branch
  IS the baseline.  Signatures strip (line,col) so unrelated edits don't churn
  them; base typecheck reuses head's installed node_modules via symlink to
  avoid a second install.

lint-changed — oxlint on the PR's changed .ts/.tsx files only, so a new lint
  error fails without being blocked by (or needing a baseline for) lint debt
  in untouched files.

Both run on GitHub-hosted ubuntu-latest and reuse the existing setup-bun
action.  To actually BLOCK merges, mark `typecheck-ratchet` + `lint-changed`
as required status checks in the collab branch protection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hblanken hblanken merged commit 7bab8d8 into collab Jun 14, 2026
2 of 3 checks passed
hblanken added a commit that referenced this pull request Jun 14, 2026
#47)

The S7 sweep shipped in #42 used synchronous rmSync(recursive) to delete
orphan workspace dirs on boot.  Each orphan is a ~1.5 GB tree on EFS (a
network FS); deleting several synchronously blocked the event loop for
minutes, so /healthz couldn't respond, the ALB health check timed out
("Request timed out"), ECS killed the task mid-sweep, and it crash-looped
(observed 2026-06-14: server reached "listening on :4096" three times,
each killed ~4 min later by failed ELB health checks; exit code null, not
OOM).

Fixes:
- Use fs/promises rm + stat with `await` per deletion — libuv does the
  slow EFS work off-thread, so the loop stays free to answer /healthz
  between deletions.
- Cap removals at 10 per boot (ORPHAN_WORKSPACE_MAX_PER_SWEEP); a larger
  backlog drains over subsequent boots instead of one marathon.
- Defer the sweep ~90 s after boot (unref'd timer) in serve.ts, so it
  can't run during the ALB startup health-check window at all —
  belt-and-suspenders on top of the non-blocking rewrite.

cleanupSessionWorkspace (explicit DELETE path) keeps sync rmSync — it's a
single dir on a user action, not the boot path.

This is a hotfix for the crash-loop that took the site down after the
#37-#46 batch deploy; merge + Deploy collab to recover (or roll the
service back to the pre-#42 task-def revision in the meantime).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant