code-yeongyu / code-yeongyu/senpi
CI runs biome with --write, so a formatting regression can never fail the Static checks job
- Dominant language
- TypeScript
- Stars
- 429
- Forks
- 98
- Avg merge
- 5h 3m
- Merged PRs (30d)
- 526
Description
## Summary
The root `check` script — which the CI **Static checks** job runs as `npm run check` — invokes Biome with `--write`:
```json
"check": "biome check --write --error-on-warnings . && ..."
```
In CI, `--write` **reformats the offending files inside the runner and exits 0**. The rewrite is never committed, so the drift stays in the repository while the job reports success. A formatting regression therefore cannot fail CI.
## Measured
Against `origin/main`'s copy of `packages/ai/test/gpt-6-astra-context-window.test.ts`:
| invocation | result |
|---|---|
| `biome check --error-on-warnings .` (no `--write`) | **rc=1** — reports the violation |
| `biome check --write --error-on-warnings .` (the CI form) | **rc=0**, and rewrites the file (4 insertions / 1 deletion) |
So that file is genuinely unformatted on `main` today, and CI has been green on it throughout.
## Why this matters
This is a gate that cannot fail. Its purpose is to reject unformatted code; instead it silently repairs a copy that is thrown away when the runner exits. Two consequences:
1. **Formatting drift accumulates in the repo unnoticed** — nothing ever reports it.
2. **Local and CI disagree.** A contributor running the documented `npm run check` locally gets their working tree rewritten (convenient), while a contributor running `biome check` without `--write` sees a failure CI never shows. That mismatch cost a session real time today: a lane observed the local failure, reasonably inferred it was the cause of a red CI aggregate, and reported it as such — it was not, because the CI form cannot fail that way.
## Suggested direction
Separate the two intentions rather than overloading one script:
- CI should run a **verify** form with no `--write` (e.g. `biome check --error-on-warnings .`), so drift fails the job.
- Keep a **fix** form (`--write`) as a separate script for local use, e.g. `check:fix`.
Whatever the split, the CI path must be able to fail on unformatted input — otherwise the check is decorative.
## Note
The immediate drift in `gpt-6-astra-context-window.test.ts` is being reformatted separately as hygiene. That does not address this issue: the next unformatted file will be equally invisible.
Contributor guide
Research direction
Inspect the root check script and the Static checks job, then run the Biome commands against packages/ai/test/gpt-6-astra-context-window.test.ts to confirm their differing exit codes. Done means the CI path verifies without --write and fails on unformatted input, while any rewriting remains in a separate local-use script.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- ci-cd
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100