# Tighten a nullable column to non-null behind a backfill

A column that is nullable only because nobody backfilled it, tightened after the nulls are resolved.

Category: Data layer and migrations
Source: https://letsship.ai/use-cases/tighten-a-nullable-column
Published: 2026-08-25

## Goal

Backfill the nulls in one column and tighten it to non-null.

## Acceptance criteria

- Existing nulls are counted and resolved with an agreed rule
- The default for new rows is stated
- The constraint is added without an unacceptable lock
- Application code no longer handles the null case

## What lands as proof

A null count before the backfill and a constraint that refuses one after, with the plan reviewed first.

## Prompt

Copy this to an agent to open the ticket:

```text
Create a Linear issue in my team and assign it to the SHIP agent.

Title: Make {column} non-null

Description: Backfill the nulls in one column and tighten it to non-null.

Acceptance criteria:
- Existing nulls are counted and resolved with an agreed rule
- The default for new rows is stated
- The constraint is added without an unacceptable lock
- Application code no longer handles the null case

Before you create the issue, find a column in this repository that is nullable but never legitimately null, and replace {column}.
```

## Questions

### What does the agent actually change?

The ticket is scoped to one outcome: backfill the nulls in one column and tighten it to non-null. Work that serves that outcome is in scope, and anything outside it is left for a separate ticket, so the pull request stays reviewable.

### How do I know the work is done?

The pull request carries the evidence, not only the diff. Here that means the plan is read and approved before a migration is written, so a reviewer can confirm the result without reproducing the work locally.

### How much oversight does this need?

The run stops for the plan, and the review bar is raised afterwards so that smaller suggestions block the merge too, not only serious findings.
