feat(docs): the promise on line 41 is derived from a matrix that asks the doorstep, and the quick start is four commands a reader can run (#592, #593) - #595
Merged
Conversation
… the doorstep, and the quick start is four commands a reader can run (#592, #593) Measured on `main@3b00d23`, and verified in the files before touching them: `README.md:41` promised "Run your Terraform against Scaleway, Outscale or Exoscale" while `docs/confidence.md:48` answered "A Terraform run against Exoscale — no, and refused rather than half-served", and the Exoscale pack's VetoEngine had been refusing `iac.engine: terraform` since #525 landed on 2026-08-26. Every doc gate was green throughout, and none was wrong: they compare values an artefact also holds, and a claim about capability is not one. capabilityMatrix is provider × client × mode × support × proof × reason. The proof column is resolved, never printed: a `supported` row against clientsProvenInCI — the same workflow scan the status table reads — and a `refused` row against the pack's own VetoEngine, which is the code `up` and `down` consult. Both directions, so a veto nobody wrote down and a row nothing proves are equally refused. The promise is generated from it per locale, and unownedCapabilityClaims reads every generated block of the front pages back: a sentence naming a refused pair passes only if it carries the upstream issue that would change it. Put the old sentence back and `docs --check` exits 2, naming the pair and the fix. The Quick Start taught the 0.10 sequence and was not copyable — no directory, no main.tf, no provider block, under an `Apply complete! Resources: 5 added` unreachable from it. examples/quickstart/{scaleway,outscale} are the first example now: 34 and 43 lines, `runtime: mode: off`. examples/stacks is unchanged and keeps being the qualification stack. The apply line is counted from the configuration, and tools/conformance/quickstart.sh lifts it out of the README and requires the run to print it. The quickstart directory joins the population `feint docs --check` already judges, rather than living one directory away from it. Run: prepush green, docs:check green and red on the restored sentence, conformance:quickstart, conformance:environment, conformance:leg -- probe and -- fields on 127.0.0.1:4699, lint-shell, and the falsification specs testplan named for this diff. tools/falsify/specs/capability-matrix.json is 13 mutations and every one bites; three more, planted outside the tree, redden the quickstart gate. limits:check is red on #570 and was before this branch. Assisted-by: Claude Code (claude-opus-5)
This was referenced Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #592. Closes #593.
The contradiction, read in the files before anything moved
Hand-written prose, outside every marker — which is exactly why no gate could
see it.
feint docs --checkverifies numbers and names, each comparable to anartefact. "Run your Terraform against …" is a claim about capability, owned
by nobody, and it had been false since #525 landed on 2026-08-26.
The sentence, and why it stays a promise rather than a warning
The headline is unqualified and leads; the Exoscale line opens with what
works and the engine is a future addition, not a missing feature; the
exception is one clause of one bullet. And it says "the day a published release
carries the fix" — #573 is closed and PR #576 is merged into
master, but notag carries it (last is
v0.70.0, 17 July).The list shape is not decoration. The claim reader treats a unit naming two
packs and two clients as asserting every pair, so a single sentence reading
"
scwfor Scaleway,octlfor Outscale,exofor Exoscale" would be claimingscwagainst Exoscale. One pack per item is what makes each line carriable.The matrix, and what
proofdemandsinternal/cli/capability.go— provider × client × mode × support × proof ×reason, published as a generated table in
docs/clients.md.proofis resolved, never printed:conformance workflowresolves throughthe same scan the status table already shares;
up.go VetoEngineresolvesthrough the pack itself, via
newServer+packEngineVeto— the codeupanddownconsult.Checked in both directions: a row nothing establishes fails, and a pair an
instrument establishes with no row fails too. A
supportedrow for an engine apack really vetoes is refused by name. A refused row must carry a reason and a
marker, and the reason must contain the marker — a rule found when the claim
reader fired on the matrix's own published table.
docs:checkred on the restored sentence, then green again:An ordering defect in
feint docsitself, found on the wayIt wrote its target last, from a copy spliced before the helpers that re-read
the same file — so a run changing two README sections kept one and printed
success.
TestARunThatChangesTwoSectionsOfTheREADMEKeepsBoth; reverting theordering makes it fail.
The quickstart, and its gate
examples/quickstart/{scaleway,outscale}— 34 and 43 HCL lines,runtime: mode: off. Outscale is three over budget: the provider block plus thecreate-then-link public IP its API requires. The Net+Subnet form was measured
first (52 lines) and dropped after proving a Vm applies and re-plans empty
without one.
examples/stacks/is unchanged — it stays the qualificationstack that found #249 and #250.
tools/conformance/quickstart.sh+conformance:quickstart, wired into theaggregate and onto the terraform/opentofu legs. It runs
feint up, checks everydeclared ready condition was confirmed, checks the emulator answers, checks the
second plan is empty, then
feint downand that nothing answers.Real execution:
A defect the first real run found: the script guessed its engine (
tofuifinstalled) while
feint upruns the declared one. On a station holding both,it planned with OpenTofu a directory Terraform had initialised — Inconsistent
dependency lock file, reported as "the second plan errored". It reads
iac.enginefrom the declaration now, the wayupdoes.And #593's own complaint is dead: the
Apply complete!line is derived fromthe configuration (
resourceCount, refusingcount/for_eachrather thanmiscounting), and the gate lifts that line out of
README.mdand requires therun to print it.
No
proof.json, and the header says why: a quickstart that boots nothing canhonour none of #503's families.
The French block
The generated blocks carrying prose are now rendered per locale.
TestTheFrenchQuickStartIsInFrenchnames the five English sentences that werelanding there and asserts the French ones are present and the commands
untranslated. The
> [!NOTE]onREADME.fr.mdwas itself false and iscorrected.
Falsification
capability-matrix.json— 13 mutations, all bite. Two survived the firstreplay, and both times the comment was wrong: one asserted merely that
"something was reported" where a second correct rule fired about the same table
(it now asserts what the refusal says); the other named the wrong branch. Both
rewritten rather than defended.
stack-proof.json— 3 mutations killed by the refactor, retargeted, all 5 bite.Outside the tree, on a copied layout: the quickstart gate reddens on an
unreachable ready condition, on a non-empty second plan, on an example declaring
no ready condition, and on a README claiming a resource count the run does not
produce. Control green each time.
Gates
prepush·docs:check(and red on the restored sentence) ·lint-shell·go test ./...·conformance:quickstart·conformance:environment·conformance:leg -- probe·conformance:leg -- fields(352/375, 216 s) · the 7specs
testplannamed ·falsify:lint(944 mutations, 148 specs) — all green.internal/providers/untouched; every run on127.0.0.1:4699;FEINT_VMneverleft
off.What was not obtained
docs/confidence.mdis not generated from the matrix. Its row is correctand guarded by
TestEveryConfidenceRowCarriesItsProof, but single ownershipstops at the READMEs and
docs/clients.md.modecolumn has one legal value.control planeis checked againstthe workflow, but nothing produces a second, so it is a guarded placeholder
rather than a live dimension.
feint downon the Scaleway quickstart left 1 resource in the store afterDestroy complete! Resources: 2 destroyed. Observed, not investigated; thegate is unaffected (empty second plan, clean destroy). It is in the pack, which
this lot was told not to enter.
limits:checkis red and was before this branch — one section'sacknowledgement predates Scaleway renamed the VPC object-storage field on 2026-08-25 and the response body still answers the old name: the query parameter was fixed, the answer was not #570 closing today. Scaleway renamed the VPC object-storage field on 2026-08-25 and the response body still answers the old name: the query parameter was fixed, the answer was not #570 is Scaleway VPC territory,
out of this lot's lane.
Where
testplanwas wrong, and it is fixed hereIt sent
examples/quickstart/**toconformance:environmentthrough thecatch-all
examples/rule, and namedconformance:quickstartnowhere —while
testplan:checkpassed, because a wrong rule is still a rule. Two rulesadded, each with a cited claim and an
Unprovenline saying the suite judges whata reader copies and never a machine that boots.