mix surfex.status prints a verdict (ok or FAILING), counts per type and state, then
each group needing attention. It exits non-zero when failing.
Options: --format json (the work list), --verify (check the log's integrity),
--evidence (check evidence confirmations against the last test run), --merge PATH
(once per CI job's evidence file: checked together, so no claim goes unchecked), --validated (also
fail on unvalidated relations), --no-planned (fail on planned), --no-marks (fail on
marks), --no-baseline (fail on relations resting on an adoption baseline),
--no-deviations (fail on declared deviations).
What fails, and the usual fix:
| Group | Fix |
|---|---|
| Dangling | see what changed; re-confirm by the process (mix surfex.info process) |
| Proposed | validate it: evidence (confirm --evidence) or a review (validate) |
| Orphaned | mix surfex.move OLD NEW, or retire |
| Conflicted | mix surfex.resolve FROM TO --type T --pick TIP |
| Unmet | relate it (suggest, the process), or excuse code with a class |
| Broken / broken citation | fix the tag, or the name the spec cites |
| Failed | its test failed in the run, whatever validated the relation: fix the code or the test |
| Unproven | run the tests; a confirmation the evidence doesn't bear out |
| Undeclared | the test dropped its tag: restore it, or retire the relation |
| Unrecorded | a tag with no verifies relation: record it (suggest, then validate), or remove the tag; one whose relation was retired: remove the tag, or reinstate the relation |
| Moved | a block or hint now sits in another unit: mix surfex.suggest --accept relates the new one and retires the old |
| Stale deviations | a test tagged deviation: passed: the code meets the unit now, so drop the tag and validate |
| Triangle | the unit's verifying test must call the implementing code (triangle: :fail) |
Unvalidated (--validated) | review it (mix surfex.validate) |
Known deviations. When the spec is right and the code isn't yet, write the test from
the spec, watch it fail, and tag it @tag deviation: "#119", skip: "known deviation (#119)". Its units are listed under Deviating with the reference; their proposed
relations (marked deviates) don't fail, and a failed run of it isn't Failed. Check it
with the skip included (mix surfex.test --deviations runs exactly those): once it
passes, status fails it as a stale deviation. While the tag is on, mix surfex.confirm --evidence holds back (lists, doesn't validate) any implements to the unit or a unit
holding it, and such a relation is unearned as deviates.
Not failing: new, planned, impacted, deviating (unless --no-deviations), open marks (unless --no-marks), claims not
checked here because this run excluded or skipped their test, and tests unselectable by
--only. A test tagged verifies: ["a", "b"] is recorded against both ids, but
mix test --only verifies:a selects it by neither (ExUnit compares the list as one
string). The text counts them; the JSON's unselectable lists each test and its ids.
mix surfex.test ID runs them by what they declare, so a list tag costs nothing there.
Uncredited (with --evidence, not failing): a test that went red then green against
the same code versions, so its red→green can't be credited. What made it pass is outside
what it reaches: look for a call the scanner doesn't see (a dispatch by name, an
unscanned module), a change outside the scanned code, or a flaky test.
Contained and On a container (not failing): a claim verified only through a claim
inside it, its own prose unclaimed, and a verifies aimed at a unit with no text of its
own, which verifies nothing. The header line counts claims by verdict
(claims: N · verified · contained · unverified · containers); mix surfex.info claims
says what each means and how a contained claim is settled. Under a require: spec rule a
contained claim's unmet line ends contained: a unit inside it is verified, its own text isn't.
Excused and deferred units (spec classes and deferrals) are counted in one header
line, excused by class: N (M with claims inside) · deferred: N, and listed in the JSON.
Two lists fail: Contradicted, a relation to a section its
class says asserts nothing (retire the relation, or remove the class), and Stale
deferrals, a deferral whose unit has a test of its own, whose issue is closed, or that
the tracker couldn't answer. mix surfex.status --issues asks the tracker through the
issues: command; without it only a built unit is judged.
Unearned (counted in the header): an implements no
verified claim's test or check exercises, with why (unverified, not_exercised,
nothing_inside; mix surfex.info claims). It meets no require: code: rule, and the
list fails where require: [code: [:implements]] is set. not_exercised usually means
the code belongs to another claim: mix surfex.migrate --report shows which. The same
report lists each contained section with the verified claims inside it, the migration's
one work list (spec §14.2).
Inert (not failing): a verifies tag that applies to no test or property block, so it
verifies nothing: a @tag no test follows, a @moduletag or @describetag over no test,
or any tag in test/support/. Move it onto the test that checks the claim, or delete it.
JSON, per relation: type, state, impacted, tips, and ends, each with kind, id,
recorded and now (hashes), changed, planned and location. Work it one relation
at a time.