Cette page existe aussi en français
feint does more than answer: it reports what it served, what a client actually drove, and what a real cloud would return in its place. These three mechanisms serve one goal, knowing whether a test proves anything: an introspection page served by the binary, a recording proxy that measures instead of guessing, and snapshots to replay a dataset as often as needed.
What you will learn
- Read the page the emulator serves about itself, and its three counters.
- Tell apart a mounted route, a probed route and a driven route.
- Record what an official client sends, without leaking a credential.
- Return to a known test state, as often as you need.
Seeing what the emulator actually served
feint ui opens a page the binary serves about itself, at
http://127.0.0.1:4599/_feint/ui. No second port, no second process, no build
step: three files embedded in the binary. It answers the question neither the
logs nor status fully cover: what was mounted, exercised, and by what.
feint ui 
The top of the page is a counter that does not add up, and that is deliberate. The three numbers stay separate because they are not worth the same: a mounted route exists, a probed route answers the protocol correctly, a route driven by a real client is the only one whose behaviour is demonstrated. The bar shows the probed part hatched rather than filled, for the same reason.
The rest of the page shows the session inventory, read from the internal store rather than from a provider API, with full attributes and a search box; the gap with the upstream surface, product by product, where every declined operation carries its written reason; and a call log reporting two things no other tool surfaces: the fields a client sent that no handler read, and the fields an answer carried that the provider's own API description does not define.
The page is read-only and served on the loopback interface only. Off loopback it is not hidden, it does not exist. There is no authentication, and that is an argued choice rather than an oversight: a password would protect the wrong boundary, since the risk is a hostile page open in the operator's browser, which would inherit any secret that browser holds.
The same event ring is readable from a script, which makes it a mechanism rather than a screen:
curl -s localhost:4599/_feint/trace \ | jq -r '.exchanges[] | "\(.method) \(.path) \(.status) \(.operation // "no route")"'GET /v2/instance-type 200 exoscale/v2.list-instance-typesGET /v2/zone 200 exoscale/v2.list-zonesGET /v2/quota 200 exoscale/v2.list-quotasThree further endpoints complete the set for tooling: /_feint/conformance
carries the per-operation detail, /_feint/resources publishes the
inventory, and /_feint/health answers the state and capabilities of the
current mode.
Returning to a known state
feint snapshot names the state of a running emulator and lets you come back
to it. It is the mechanism that makes a test dataset reachable once and
replayable as often as needed.
feint snapshot save reference-statefeint snapshot listsaved 21 resources to /home/bob/.local/state/feint/snapshots/reference-state.json
NAME RESOURCES BYTES SAVEDreference-state 21 26472 2026-07-30T09:43:40ZAfter deleting every resource, feint snapshot load reference-state answers
loaded reference-state: the emulator now holds 21 resources and the
inventory is rebuilt. Loading replaces the state, it does not merge: a
test fixture must not depend on what the session did before it.
Knowing what a real client expects
feint proxy sits between an official client and a cloud and writes every
exchange to a file; feint transcript reads that file by verbs. The pair
answers a question no provider documentation settles: what the client actually
calls, and the exact shape of the responses it receives.
The intended use is a real account, in read-only. The demonstration below points the proxy at the emulator itself, which shows the mechanics without an invoice; only the upstream address changes in the real case.
feint proxy --upstream http://127.0.0.1:4599 --record recording.jsonl --provider scalewayeval "$(feint env scaleway --endpoint http://127.0.0.1:4600)"scw instance server create name=via-proxy type=DEV1-S image=ubuntu_jammy zone=fr-par-1feint transcript turns it into a work queue ranked by call count, that
is the operations a client asks for and nobody has served yet:
already served, and exercised here (6): 2 1888 200,201 instance/v1/API.CreateServer 1 4734 200 instance/v1/API.ListServersTypes 1 506 200 instance/v1/API.GetImage 1 303 201 instance/v1/API.CreateIPThe --shape flag prints the field tree actually returned, which is not
what the SDK says it may return, and --against compares that tree with the
emulator's to list missing or mistyped fields.
response shape of instance/v1/API.ListServersTypes, as the real cloud returned it:
object servers object servers.DEV1-L string servers.DEV1-L.arch bool servers.DEV1-L.capabilities.block_storageNo credential reaches the file: redaction is a property of the recorded type,
not a step a call site could forget. Headers follow an allowlist, bodies a
denylist, because a body is the measurement while a header is not. The proxy
listens on the loopback interface only, unless --expose-to-network: every
request crossing it carries a live credential.
feint shapes extends the same logic to verification: it records the field
tree of a real cloud, without values or identifiers, which makes the file
publishable where a transcript is not, then feint shapes --check compares
the emulator with that recording offline and without a credential.
Key points
- The page is served by the binary, on loopback, read-only and without authentication by argued choice.
- Served, probed and driven do not add up: only the last category demonstrates behaviour.
feint proxymeasures instead of guessing what a client sends, and redacts credentials by construction.feint transcriptanswers by verbs: what to serve next, what shape a response must have, which fields are missing.- A snapshot replaces the state, it does not merge it: a test fixture does not depend on what preceded it.