Skip to content
Registry StackDocsDevelopment (unreleased)

Prove an Evidence Gateway project

For the assertion provider and operator

View as Markdown

Start with an editable project: the directory evidencectl init created, holding questions/, derivations/, fixtures/, and its source objects. It has no runtime.yaml and no bundle/; those belong to the candidate evidencectl package produces later. If you need to create a project, connect an institution source from OpenAPI or get your first assertion before adding fixtures. Fixtures are executable claims about your own Evidence Gateway project. They are not sample data for a first run and they must not be generated from an unrelated domain.

Use them when your source, requirement, and derivation are ready for review. Local assurance lets a project load without them, but the run below is not a formality you can pass with an empty suite: a run that evaluated no case refuses with no case was evaluated, so this run proves nothing: every fixture the project references must declare at least one case. Production and evidence-grade assurance require complete fixture coverage before the bundle loads.

Add the governance each question hands off

Section titled “Add the governance each question hands off”

The fixture runner compiles the editable project the way a production build compiles it, so the governance a candidate needs is required before the first fixture run, not at build time. Give every question a governance block and every answer a stable concept identifier:

answers:
- concept: is_adult
id: urn:example:concept:adult-status:v1
type: boolean
governance:
requirement: urn:example:requirement:adult-status:v1
kind: criterion
referenceFrameworks: [urn:example:framework:adult-status:v1]
evidenceType: urn:example:evidence-type:adult-status:v1
validitySeconds: 300
observationTimezone: UTC
fixtures: fixtures/adult-status.yaml
disclosureFamilies: [urn:example:disclosure-family:adult-status]

Three rules decide whether the run starts at all:

  • A question with no governance block stops the run with evidencectl: compiling editable project for fixture evaluation: every production question requires governance.
  • An answer with no id stops it with every production answer requires one stable concept id.
  • governance.fixtures must be exactly fixtures/<name>.yaml, a path inside the project. No requirement, framework, Evidence Type, disclosure family, or concept identifier may be one of the disposable urn:registrystack:evidence:local: URIs that a local generation issues.

The project a local tutorial leaves behind satisfies none of this, so adding governance is the first change to make here. The Evidence authoring form reference states these three beside the other refusals a project meets on the way to a candidate, under Rules that block a build.

Place the fixture file under fixtures/ in the editable project and name it from the question’s governance.fixtures. Keep every value synthetic and sanitized.

Cover behavior your reviewers need to approve:

  • one ordinary positive result;
  • one legitimate negative value, or an unresolved case when false would be misleading;
  • each important boundary in the derivation;
  • missing required facts, which the extractor generated from OpenAPI fails as source.unavailable rather than as a no_match or ambiguous outcome; get a real no_match or ambiguous by hand-editing the extractor, as Finish extraction and facts covers;
  • mistyped required facts;
  • malformed and unavailable source responses;
  • output outside the governed codelist or schema;
  • privacy expectations proving source fields and selector values stay out of evidence and diagnostics;
  • anti-reconstruction cases for concepts that must not be released together.

The fixture format is closed. Start from the fixture contract, then keep only cases that express your project.

From any directory, run:

Terminal window
evidencectl check "<evidence-project>" --deny-findings
evidencectl test "<evidence-project>"

The first command validates authored completeness without contacting a source, identity provider, or database. It reports each gap with its file path and a corrective action. The second command asks the evidence binary for its version first and refuses one that is not its own, then compiles the editable project into a private staging bundle, runs evidence bundle-check against it, discovers the fixture files the compiled bundle captured, and drives each one through evidence bundle-evaluate; pass --evidence-bin when the matching binary is not the first evidence on PATH. The run does not start HTTP, resolve a source credential, call the source, or write the production audit log. The served HTTP path remains a separate integration check.

A passing run reports the check and one line per fixture:

PASS: check
PASS: fixtures/adult-status.yaml (8 cases)
2 passed, 0 failed (8 cases evaluated)

Use JSON output in CI:

Terminal window
evidencectl test "<evidence-project>" --format json > fixture-report.json

Treat any failed case, missing reference, unknown field, or unsupported expectation as a failed build input. Do not convert a real failure into an ignored case.

A failure names the contract that broke, which says a case failed but not where it stopped. Ask the run to explain itself:

Terminal window
evidencectl test "<evidence-project>" --explain

Each fixture prints one JSON trace after its result line. The trace holds one entry per case, with the case id, its expectedResult and observedResult, the reasonCode the run settled on, and one stages entry for every stage that case reached: prepare, acquire, extract, derive, validate, and sign. Every stage carries its own status and a short note, such as the keys a response was projected to or the concepts the output gate accepted. A failed case adds failure and findingCodes, and its stages list stops at the stage that ended the case, so read that last entry first.

To explain one fixture on its own, or one case inside it, name them. The paths are the ones the compiled bundle captured, which are the project’s own fixtures/ paths:

Terminal window
evidencectl test "<evidence-project>" \
--fixture "fixtures/<cases>.yaml" --case "<case-id>" --explain

The trace reports shapes: member names, counts, and identifiers. It never prints a response, fact, derived, or selector value, and a run whose trace holds a value the fixture declared under privacy_expectation.diagnostics_exclude is refused before the trace is printed. The flag changes no outcome, exit code, or message, and it is offline only: a served request is diagnosed from its public problem and the audit chain instead.

An editable project has no runtime document to check. Once evidencectl package has produced a candidate, that candidate is what carries runtime.yaml beside bundle/, and evidence check runs against it:

Terminal window
evidence check --runtime "<candidate>/runtime.yaml"

This validates the complete captured bundle, scripts, schemas, codelists, key references, and runtime bindings, and it initializes the configured signer, so a production or evidence-grade candidate needs its Transit proxy already running. Source credentials are checked by readiness when the service starts, not by the offline fixture runner.

During local authoring, keep the project writable so changes are convenient. Freeze inputs only for the deployable revision: make the runtime and bundle non-writable to the service identity, or mount them read-only, then rerun the check against those exact bytes.

Evidencectl has no generic promote command. Your deployment system owns approval, artifact transport, rollback, and environment binding. Use evidencectl package to create a new candidate from the editable project and one explicit production target.

Build and hand off only when these facts are recorded together:

  1. The fixture suite passed against the editable inputs and the generated candidate.
  2. evidence check accepted the exact candidate runtime and bundle.
  3. A reviewer approved the source projection, cardinality mapping, requirement, derivation, codelists, purposes, audiences, and privacy expectations.
  4. The environment supplies a governed public signing key and matching Transit binding, plus independent owner-only subject-binding and audit secrets.
  5. The deployed bundle revision matches the reviewed candidate.
  6. Readiness passes, followed by one authorized HTTP-path check using synthetic data.

Build a complete governed bundle for each environment. Each target owns its identities, endpoints, audiences, public keys, authority bindings, runtime paths, secret references, audit storage, listener settings, and trust files. Promote the reviewed editable source revision, then build staging and production candidates separately. Build and deploy an Evidence Gateway project covers the target-host ceremony.