Operating principles
Five rules that explain why these APIs refuse the things they refuse.
The VERIFI SDKs are unusually opinionated. They refuse things that look harmless, and they omit conveniences other tool SDKs provide. Every one of those refusals traces to a specific failure that shipped. Read this page once and the rest of the API stops looking arbitrary.
An assertion is not evidence — P4
A component is not working because it says it is, or because someone wrote it down.
The reference case: a Burp Suite MCP was registered for the entire life of the previous
engine and served zero calls. The readiness check counted any 4xx response as ready,
and nothing ever performed an MCP initialize or tools/list. Preflight passed, scans
proceeded, every Burp call timed out. Web penetration tests ran for months without their
primary scanner, and no part of the system could tell the difference.
What this produces in the API:
- The registry lifecycle enum has no state meaning "registered, assumed working". It
is
unregistered | probing | available | degraded | unavailable | retired. Registry.register()inserts asprobingwhatever the caller supplies.setStatus()throws if you passavailable. The only route toavailableisprobe()passing.zMcpServerrefuses to parse whenstatus: 'available'andprobe.passed !== true.zModelrefusesavailablewithoutprobeInvoked: true— a real invocation that returned tokens, because model catalogues list models they cannot serve.zKnowledgeBaserefusesavailablewith zero chunks — it answers HTTP but retrieves nothing.- The probe runs again as a run preflight, because a probe that passed last week says nothing about right now.
The registration schemas are P4 in the type system
A field a caller can set is a field a caller can lie about. So zModelRegistration,
zMcpRegistration, zKbRegistration and zHarnessRegistration are all .strict() and
simply do not carry the fields that are outcomes:
status · probe · probeInvoked · tools · lastProbedAt · authRefSending one is a parse error, not a silently ignored key. Verified against contract 1.5.1
— every one of those six is refused on a model registration. zMcpRegistration goes
further and excludes shared from the concurrency enum it accepts, because declaring
shared is asserting a passed statelessness probe.
That is also why the console's register form has no status control: there is no request body that can register something as already working. See Registering a component.
Listing is not availability — P12
A provider will cheerfully list models it cannot invoke. NIM does; so does Bedrock, where most modern models are reachable only through a cross-region inference profile and a call to the bare model id returns a validation error.
So a Model does not get a three-gate HTTP probe — it has no endpoint to probe. It gets a real invocation, and the pass condition is that the invocation returned non-zero token counts:
parseModelResponsereturns{ text: '', inputTokens: 0, outputTokens: 0 }for a shape it does not recognise, rather than guessing. A parser that invented plausible numbers would let a model that cannot be called reachavailable.- A 200 response with zero tokens is a failed probe. A well-formed empty response is exactly what a provider returns for a model it advertises and cannot run.
zModelrefusesstatus: 'available'withoutprobeInvoked: true.
The same shape applies to a Harness, which serves nothing at all: it is probed by checking that its image digest exists, has been scanned, and the scan is neither stale nor carrying a blocking severity. An unscanned image fails exactly like a vulnerable one — "no findings" and "no scan" are different statements.
A dead scanner reporting zero findings reads as a clean bill of health
This is the failure mode the whole design is bent around. A scan that completes with no
findings is indistinguishable, from the outside, from a scan whose tools were never
installed. The previous engine's infrastructure line wired end to end perfectly and
produced approximately zero findings, because every CLI reported SKIP: not installed.
What this produces in the API:
- Gate 2 of the three-gate probe (
GET /test) must exercise the real backend, not report process liveness. The real MCPs execute each binary with a version flag — presence on$PATHis not enough, because a truncated or wrong-architecture download resolves on$PATHand then fails on every call. - Gate 3 requires at least one tool. A server that answers the protocol and exposes nothing is not available; it is decorative.
- A slot's dead primary raises
mcp.no_healthy_toolaterrorseverity, once, rather than emitting onetool_errorper call and leaving "the scanner is gone" to be inferred from a thin result set. run.completed_zero_findingsis a first-class alert routed to both analyst and ops.- A green dry run proves wiring, never findings — the SDK's own comments say so, and so does this site.
A passed check is not a finding
Coverage and findings are separate outputs. A harness declares coverage intent through
declarePlan(), and the run reports what it actually achieved against that declaration.
A gap is a coverage_gap event and a run.coverage_gap alert — a first-class run
output, not an absence.
This is also why declarePlan() is explicitly not the execution plan. At runtime the
agent takes a data-dependent number of steps and may use any tool its belt offers,
because recon shapes which tests are worth running.
Time is the only hard bound
Cost, tokens, tool calls and evidence bytes are metered, thresholded and alerted — never enforced.
The reasoning is in budget.ts verbatim: capping any of those severs a scan mid-test.
The target is left half-examined, the findings are partial, and the delivered report is
wrong in a way that is hard to detect from outside. An overspend is a bill; a truncated
assessment is a defective product shipped to a client.
What this produces in the API:
zBudgetis.strict()so a resurrectedmaxCostUsdorpolicyfield is a loud parse error rather than a silently ignored field somebody believes is enforced.BudgetLedgerhas no method that can refuse a spend.record()always succeeds.zRunStatushas nobudget_exceeded.timed_outis the terminal condition that remains, and since spend accrues at a finite rate, a time bound is also a cost bound.- The gRPC
Stopmessage carries'deadline' | 'operator' | 'failure'. There is deliberately no cost reason. ctx.signalfires on stop, deadline or operator cancel. Never on cost.
Two more that follow from the above
Findings persist the moment they are produced. Never at finalize. The previous engine
made _finalize() the only caller of persist_findings, so a failure in a later phase
gave the tenant zero findings from a scan whose results were verified on disk. Run
outcome and finding persistence are independent: a run that fails late keeps everything
it already found.
Credentials are indirections, never values. zCredRef is a regex that only accepts
secret:<id>, env:<VAR>, or bedrock-sts. A raw connection string or API key is not
representable anywhere a credRef is expected. No sample on this site contains a
credential, real or fake.
The single exception is apiKey on a registration, and it is an exception in flight only:
the engine splits the key off the record before anything is stored, writes it to Secrets
Manager, and persists authRef: secret:<id>. The response carries the reference, never the
key, and there is no route that reads it back.
"Read failed" is not "value absent"
The narrowest rule here and the one that has cost the most. Two statements that look alike from a call site and are not:
| I looked, and there is nothing there. | a fact about the world |
| I could not look. | a fact about us |
Collapsing them is how a live credential once got overwritten with a stale seed. It appears throughout these APIs as a deliberate refusal to default:
isCompatible('1.0')returns false. Unparseable is never "compatible".- A probe that throws is a failed probe, never an absent one — for the three gates, for the model probe, and for the harness image scan.
- A harness image that has never been scanned fails the probe exactly like one with a critical CVE, and so does one whose scanner could not be reached.
parseModelResponsereturns zero tokens for an unrecognised payload rather than a guess.buildModelRequestrefuses a Bedrock family it has no body shape for, rather than sending an Anthropic body that will 400 in a way that reads like a broken model.modelEndpointrefusesopenai_compatwith nobaseUrlrather than defaulting to OpenAI, which would send a self-hosted deployment's traffic and its key to a third party.
When you write a harness or an MCP, the same rule applies to you: a tool that could not run must not return the same thing as a tool that ran and found nothing.