Skip to content
TEA docs in plain text: llms-full.txt

Live Verification Results

Record the results of live system checks in live-verification-results.json. trace reads it at the live coverage level and can count a passing record alongside static tests.

Two limits apply, and both are enforced:

  • The record’s source_sha must match the commit under trace. A mismatch is stale and contributes no coverage.
  • A requirement covered only by a live record caps the gate at CONCERNS.

Produce the file before running trace.

An agent, script, CI job, or person can record the results. Each uses the same schema. See Verification Architecture.

live_results_input: '{test_artifacts}/live-verification-results.json'

The file sits at the root of {test_artifacts}, outside the trace/ folder where trace writes its own outputs, because other tools and people produce it. Set a different path in the trace skill’s workflow.yaml if you produce the file elsewhere. When the file is absent, trace uses static test discovery only.

{
"schema_version": "0.1.0",
"source_sha": "9f2c41d8b7e35a06c1d4f8e29b7a3c5d6e081f42",
"observed_at": "2026-08-11T14:32:00Z",
"producer": "manual verification by release engineer",
"results": [
{
"id": "1.3-LIVE-001",
"requirement_id": "AC-1",
"title": "User can sign in with a valid password",
"status": "pass",
"evidence": "Signed in as qa@example.com, landed on /dashboard with the account menu populated."
}
]
}

A longer example covering a passing record, a blocked one, and one recorded against an older commit ships with the skill at skills/bmad-tea-trace/resources/live-verification-results.example.json.

Enforced fields determine whether a record or the whole file counts. Recorded fields add context to the report.

FieldTrace does
schema_versionEnforced. "0.1.0". A different major version makes the whole file unreadable and raises a blocker.
source_shaEnforced. The git commit the observations were made against. Per-result source_sha overrides it.
resultsEnforced. Must be an array. May be empty. Anything else makes the file unreadable.
observed_atRecorded. ISO 8601 timestamp. Per-result observed_at overrides it.
producerRecorded. Free text naming whatever recorded the run. Reported back in the run’s trace summary.
FieldTrace does
idEnforced. Test-case ID, format below. Must be unique in the file; a repeat is invalid.
requirement_idEnforced. The oracle item this verifies. Must match an id trace resolved, such as AC-1 or J-02.
statusEnforced. One of pass, fail, blocked, skipped.
source_shaEnforced when the file has no top-level source_sha. Overrides the file-level commit for this record.
titleRecorded. What was verified, in one line. Falls back to the id when absent.
evidenceRecorded. What was observed, or a URL to a recording, log, or screenshot.
observed_atRecorded. Overrides the file-level timestamp for this record.
{target}-LIVE-{NNN}

{target} is the story, epic, or release identifier already used for the run. {NNN} is a zero-padded sequence. This matches the existing 1.3-E2E-001 convention, with LIVE as the level segment, so live results sort and read alongside static test IDs in the matrix.

Examples: 1.3-LIVE-001, 2.7-LIVE-014, v1.4.0-LIVE-003.

A record counts as coverage only when all four hold:

  1. Its status is pass.
  2. Its source_sha matches the commit under trace.
  3. It carries a unique id and a requirement_id.
  4. That requirement_id names an item in the coverage oracle trace resolved, and no other record reports a fail for the same item.

Everything else is recorded as a blocker in the traceability matrix and contributes no coverage:

OutcomeWhat happenedBlocker severity
staleRecorded against a different commit than the one under tracehigh
unverifiableThe current commit sha could not be resolved, so freshness is unknowablehigh
failThe verification failedhigh
contradictedPassed, but another record reports a fail for the same requirement_idhigh
blockedThe verification never reached a verdictmedium
skippedThe verification was skippedmedium
unmatchedrequirement_id names an item not in the resolved coverage oraclemedium
invalidMissing or duplicate id, missing requirement_id, no source_sha, bad statusmedium

An unreadable file (bad JSON, no results array, or an unsupported schema_version) produces one file-level blocker with the id live-results-unreadable at high severity.

A non-pass status is reported as itself regardless of freshness. A fail cannot count at any commit, so calling it stale would send you to re-record a run that already told you the requirement is broken.

When re-verifying a failed requirement, replace its old record. A file with both fail and pass for the same requirement_id marks the pass contradicted and credits no coverage.

If a P0 requirement’s only evidence is stale, it is uncovered and the gate fails. Re-record against the current commit or add a re-runnable test.

Freshness compares SHAs case-insensitively and accepts prefix matches of at least seven characters.

A live record describes one observation at one commit. It cannot re-execute in CI or on the next commit, so a live-only requirement caps a passing gate at CONCERNS.

The cap lowers PASS to CONCERNS. A FAIL remains FAIL; requirements with static test coverage avoid the live-only cap.

To reach PASS, add a re-runnable test at any level for the requirements the matrix reports as live-only. trace names them in its recommendations.

Remove live from coverage_levels in the trace skill’s workflow.yaml:

coverage_levels: 'e2e,api,component,unit'

trace then ignores the results file entirely, including a stale one.

The one exception is collection_mode: runtime_manifest. That mode names the results file as the run’s only evidence source, so it implies the live level and reads the file whether or not coverage_levels lists it. Removing live does not turn live evidence off under that mode. To turn it off, change the collection mode as well.

Set collection_mode: runtime_manifest when recorded live verification is the run’s only evidence source. trace skips static test discovery and reads the results file alone.

A missing or unreadable file sets collection_status to INACCESSIBLE and suppresses the gate.

With no static discovery, auth_negative_path_status and error_path_status are unknown.

The run’s summary, trace/e2e-trace-summary-{run_key}.json under {test_artifacts} (schema 0.2.0 and later), carries a live_evidence block:

{
"live_evidence": {
"present": true,
"results_file": "_bmad-output/test-artifacts/live-verification-results.json",
"freshness": "fresh",
"recorded_source_sha": "9f2c41d8b7e35a06c1d4f8e29b7a3c5d6e081f42",
"current_source_sha": "9f2c41d8b7e35a06c1d4f8e29b7a3c5d6e081f42",
"producer": "manual verification by release engineer",
"counted": 3,
"stale": 0,
"unverifiable": 0,
"failed": 0,
"contradicted": 0,
"blocked": 0,
"skipped": 0,
"unmatched": 0,
"invalid": 0,
"requirements_live_only": 2
}
}

freshness is one of:

ValueMeaning
freshEvery record was checkable and recorded against the commit under trace
mixedSome records counted, others are stale or unverifiable
staleRecords exist but none counted, because none matched the commit under trace
unverifiableThe current commit sha could not be resolved, so nothing could be checked
unreadableThe file exists but could not be parsed or failed its schema check
not_presentNo results file

freshness describes whether records match the commit under trace. A fresh file can contain failed or blocked results. To require current and successful evidence, check freshness === 'fresh' and that every non-counted counter is zero. mixed reports a combination of counted and stale or unverifiable records.

Counted results also appear under coverage.by_level.live, so a dashboard can show how much of a release rests on evidence with no re-runnable artifact behind it.