Quarantine
When an asset declares a schema, the engine compares the columns it observed in the write with that schema. The check is schema_contract. Its default severity is block. A blocking failure still stores the materialization, and leaves latest on the previous result.
The check fails when a declared column is missing, a type does not match, or a null appears in a column the schema does not mark nullable. An extra observed column passes. An observed integer satisfies a declared float. A declared integer does not accept an observed float.
Set the severity
Section titled “Set the severity”block is the default even when you omit checks. Set warn when a mismatch should still become latest:
checks: { schema_contract: { severity: "warn" },},The rows are written first. ctx.emit() does not reject a bad row. The check runs after the write.
What a run does
Section titled “What a run does”A blocking failure stores the materialization and leaves latest on the previous one. The attempt status is failed_by_check. Assets later in that run are blocked and do not build on the failed result. puppi run exits 1.
A warning becomes latest. The failure is recorded on the materialization.
puppi assetspuppi assets core/customerpuppi assets shows a quarantined latest as quarantined next to its staleness state. puppi assets <key> shows which check failed.
A custom check can block the same way. The default severity is block. The function runs in the attempt, after the write, and sees the rows:
checks: { custom: { has_rows: { run: (ctx) => ctx.rows.length > 0 ? { result: "pass" } : { result: "fail", detail: "no rows" }, }, },},A check that throws fails the attempt the way a throw in run does. It is recorded as an attempt failure, not as a failed check.
What a deploy does
Section titled “What a deploy does”Activating a deployment re-checks every declared schema against the columns already stored on the current latest materialization. No asset runs.
If the stored columns no longer match, that materialization is marked quarantined while it is still latest. Activating the previous deployment runs the same check against the restored schema and clears the quarantine when the stored columns match again.
puppi run --local prints the same contract verdict. It writes no materialization, so it quarantines nothing.