The code can be valid and the change can still be wrong.
These are not lint problems. They are the kinds of cross-tool, cross-repo, rollout, and compatibility constraints senior engineers catch because they remember the history.
NOT NULL before the backfill
The task says “make email required.” The agent changes the schema immediately. The migration playbook requires adding the column/constraint safely, backfilling existing rows, validating, and only then enforcing it.
team rule: backfill → validate → enforce
Backend passes. Clients break.
An API field is renamed in the service and OpenAPI file. Service tests pass, but an older mobile release and generated SDK still expect the previous field for the deprecation window.
consumer: still reads workspace.slug
Schema changed, SDK did not
The agent edits the API implementation and contract but misses the repository that generates the TypeScript and Python clients from that contract.
sdk-typescript: stale
sdk-python: stale
A retry creates duplicate side effects
A queue worker uses at-least-once delivery. The agent adds an email, webhook, or external write directly in the handler without the job's required idempotency key.
PR: sendWebhook() every attempt
A read path quietly gains write scope
The agent reuses an existing internal client because it is convenient. That client carries broader OAuth scopes than the read-only flow is supposed to have.
new client: records:read + records:write
Shared type changes. One consumer is missed.
A shared package changes an event or type. The web app is updated in the same PR, but a background worker imports the same package through a different workspace path and is not touched.
web: updated
worker: still destructures v3 field
The flag is removed before old clients age out
The agent sees a flag that has been “100% on” for weeks and deletes the fallback. The mobile support policy says the old app version still needs that branch until the minimum supported version moves.
mobile policy: keep fallback through v8.14
An event field is renamed like a local refactor
The producer and its tests move from account_id to workspace_id. The event contract says consumers must receive both during a compatibility window.
contract: dual-publish for 2 releases
A new storage resource violates residency
The agent provisions a bucket in the default region because the Terraform module permits it. The customer/environment policy requires EU workloads to keep customer data in-region.
environment rule: eu-west-1 only
An event moves before the commit
The agent publishes an integration event immediately after a write call. The service's outbox pattern requires publishing only from committed rows so consumers never observe data that later rolls back.
service rule: commit → outbox → publish
A service-role key bypasses row-level security
The agent fixes a failing query by swapping in a privileged server client. It works, but bypasses the tenant isolation rule the normal user-scoped client enforces.
PR: service-role client for convenience
Cleanup happens in the same deploy as the cutover
The task says “finish migration.” The agent removes old reads, old writes, and the fallback immediately. The rollout plan requires one release of observation before destructive cleanup.
plan: cutover → observe → cleanup
Not “is this code good?” — “what did this task need to preserve?”
For each task, HoldUp finds the relevant constraints before implementation, makes contradictions explicit, and carries that same approved packet into PR review.