← Statpro dev log

2026-08-27

A jq filter that passed wrong evidence

datainfraautomation

A one-character bug in a jq evidence filter

The migration pipeline kept passing its evidence checks, and I could not trust it. Every run reported success. But the jq filter that validated ECS task evidence had a subtle bug: it iterated with all(.; cond) when it needed all(.[]; cond). The difference is between checking a single array wrapper and checking each element inside it.

Here is the fix, verbatim from the diff:

# before: checks the wrapper, not the items
(.overrides.containerOverrides // []) | all(.;
  (.name // "job") == "job" and (.command // []) == [] and (.environment // []) == []
)

# after: checks each override element
(.overrides.containerOverrides // []) | all(.[];
  (.name // "job") == "job" and (.command // []) == [] and (.environment // []) == []
)

That [] is the whole story. Without it, jq receives a single array and evaluates the condition once on the array itself, which is truthy, so every task passes attestation regardless of what its overrides actually contain. With [], all iterates the array elements and checks each one.

The five-commit push for a reproducible pipeline

This was the last fix in a five-commit push to make the Statpro NFL stat pipeline reproducible across its promotion phases. The other pieces, by user outcome:

  • Deterministic request negotiation: resource requests now send explicit, frozen Accept headers instead of undefined, so the same representation comes back every time.
  • Semantic projection comparison: projections are now normalized before comparison, so two phases produce equivalent plans even when their metadata timestamps differ.
  • Versioned stat contract: two new SQL migrations install a contract function and then assertion-only checks that prove it exists, is owned by the right role, and is executable by the right principals.
  • CloudFormation template guard: the migration stack kept creeping past CloudFormation template size limit. The fix was --path-metadata false on cdk synth plus a hard byte-count guard in the workflow.

The takeaway: when a pipeline evidence checks are wrong, green builds are worse than red ones. You stop looking. The contract assertions and the jq fix now make the evidence mean what it says.

this is the build log of statpro · statpro.io · all entries · essays