jonnifyagile agents
jonnify / Agile Agent Workflow / A4 · Spec / A4.5 / A4.5.1 · Invariant vs check

A4.5 · Invariants · dive 1

Invariant, or check

Two statements can both be true of a slice and still be different kinds of claim: a rule that holds for every value, against one named scenario.

An invariant is universally quantified — for all values, always. An acceptance check is one scenario — a single Given/When/Then. Telling them apart is how a spec names the rules a slice must never break, separately from the examples that prove it behaves. Classify each statement on the right.

Classify the statement · invariant or check

INVARIANT for all values, always ∀ value named once, in Invariants CHECK for one scenario ∃ this case a Given/When/Then on a story the selected statement lights the kind it is
Invariant · holds for every value, always. “The web layer calls only the Portal facade …” quantifies over all requests. It states a rule the slice must never break, not one example of it behaving.

Two true statements, two kinds of claim

Read these two statements about the Portal's first web rung. First: the web layer calls only the Portal facade. Second: for an unknown user id, the page renders the empty state. Both are true. But the first is universal — it claims something of every request the slice will ever serve. The second is one example — it claims something of one scenario.

That difference is the whole distinction. An invariant is universally quantified: for all values, at all times. It names a rule the increment must never break, and it is written once, in the spec's Invariants section. An acceptance check is existentially scoped: for this one case. It is written as a Given/When/Then on a story, and it proves one example. A spec carries both because they cover different things — the rule, and the example of the rule.

invariant
A property true for every value, always. Universally quantified (“for all”); named once in the Invariants section; exercised by checks, never restated per scenario.
acceptance check
A property true for one specified scenario. Existentially scoped (“for this case”); written as a Given/When/Then on a story; proves one example.
they compose
A check exercises an invariant but does not replace it. No finite set of passing checks proves a universal rule — the checks sample it.

A rung is done only when every invariant holds and every check passes — two conditions, because the two are different claims (the A4.6 closure makes this operational).

Where each one is written

The two claims also live in two places. An invariant is written in the Invariants section of the spec (f6.1.md) — named once, with an id, exercised by checks. A check is written as a Given/When/Then on a story in f6.1.stories.md — one scenario, with its own acceptance criteria. Select a statement to see which artifact and section is its home.

This is not a filing detail. The home tells you the claim's scope: a statement in the Invariants section is a rule over all values; a Given/When/Then on a story is one named case. Reading the home is a fast way to tell an invariant from a check without parsing the sentence.

Which artifact and section holds the claim · pick one

f6.1.md the spec · what & why & done Invariants a rule over all values, named once with an id f6.1.stories.md the stories · who wants what Given/When/Then one scenario on a story, with acceptance criteria the home tells you the scope of the claim
An invariant lives in the Invariants section of f6.1.md — named once, with an id, exercised by checks. The master invariant is F6.1-INV1: a rule over every request.

Read the home: a claim in the Invariants section is a rule over all values; a Given/When/Then on a story is one named scenario.

On the Portal: F6.1-INV1 against F6.1-US5

On the Portal — the learning platform this course builds — the first web rung carries both kinds of claim. The Invariants section of f6.1.md names the master invariant, F6.1-INV1: a rule the whole web layer obeys for every request. The stories file f6.1.stories.md carries F6.1-US5, whose first Given/When/Then is one scenario: an authenticated learner with no enrollments sees the empty state at the protected /my/courses. Read side by side, the universal rule and the one example are easy to tell apart.

The fragment below is the two claims, verbatim — the invariant line from the spec and the scenario from the story. No code, only spec text: the rule, and one example of the slice behaving.

# f6.1.md — Invariants (a rule over ALL values, named once).
#   F6.1-INV1 (master): the web layer calls only the Portal facade and renders
#   only the closed %Portal.Error{} set. No controller, LiveView, plug, or
#   template names Portal.Engine, a repo, or GenServer.call.   → INVARIANT (∀ request)

# f6.1.stories.md — F6.1-US5 acceptance (ONE scenario).
#   Given an authenticated learner with no enrollments,
#   When  GET /my/courses (the learner's own courses, protected),
#   Then  the page renders the empty state — a clean 200.   → CHECK (∃ this case)

The principle

Name the universal rules apart from the example checks — they are different claims, written in different homes, and a slice is done only when both hold.

On the Portal

F6.1-INV1, the master invariant, is named once in f6.1.md; F6.1-US5's “unknown id → 200” is a Given/When/Then in f6.1.stories.md. The rule, and one example of it.

An invariant is a universal rule; a check is one scenario — same slice, two kinds of claim, two homes.

Recap — the rule and the example

An invariant holds for every value, always — it is universally quantified, named once in the Invariants section, and exercised by checks. An acceptance check holds for one scenario — it is one Given/When/Then on a story. They are different kinds of claim, written in different homes, and a rung is done only when every invariant holds and every check passes. With the two told apart, the next dive reads the one invariant the Portal's web chapter rests on.

Next in A4.5: A4.5.2 · The master invariant — the Portal's canonical invariant, read verbatim, and the static-search check that samples it.

References

Primary sources for the invariant-against-check distinction, and where it connects in the course.

Sources

Related in this course