Skip to content
Memtru
Documentation menu
Reference

Report format

Reports use schema version 1.0. The source of truth is the pydantic model in packages/memtru/src/memtru/reporting/schema.py; the JSON Schema in packages/report-schema/report.schema.json is generated from it, and a test fails if they drift. The web app validates uploads with an equivalent strict Zod schema, tested against real CLI output.

Top level

Field Type Notes
schema_version "1.0" Uploads with any other value are rejected.
run_id UUID Unique per run; used for idempotent uploads.
project string From project.name.
status PASS / FAIL / INCONCLUSIVE / ERROR / SKIPPED Derived from the summary: FAIL > ERROR > INCONCLUSIVE > PASS; SKIPPED if nothing executed.
environment string From execution.environment.
tool {name, version} CLI version.
adapter {name, version, type, capabilities[], details{}} details holds safe metadata only (fault list, host).
config_fingerprint string Hash of the configuration, to flag config changes between runs.
source {branch, commit} Optional.
started_at, completed_at ISO-8601 UTC
duration_ms integer
summary {total, passed, failed, inconclusive, errors, skipped} Must match results.
privacy {raw_content_included, redaction_applied, redactions}
results array One per scenario.
findings array One per FAIL.

Result

scenario_id, scenario_slug, scenario_version, title, category, mode (storage/agent), status, summary, expected, observed, duration_ms, attempts, required_capabilities, evidence[], limitations[], error ({code, message} or null), cleanup ({status, removed, remaining[], message}).

Evidence steps are {step, action, actor, detail, outcome}. Actors are synthetic labels such as tenant-a/user-b/session-1. Content appears as sha256: fingerprints unless raw content was enabled.

Finding

finding_id, fingerprint (stable across runs: scenario:failure-code:hash), scenario_id, scenario_version, category, severity, status (FAIL), title, summary, expected, observed, evidence_refs[], reproduction[], remediation[], hypotheses[], limitations[], detected_at, duration_ms.

Ingestion rules (server)

POST /api/report-upload with Authorization: Bearer mtru_… (scope runs:write):

  1. Authenticate the token (unknown, revoked, expired, or for an archived project or deleted organization: 401).
  2. Check the scope (403).
  3. Take the project and organization from the token, never from the body.
  4. Enforce a 1,000,000-byte limit while reading the body (413).
  5. Parse JSON (422).
  6. Require schema_version: "1.0" (422 unsupported_schema).
  7. Validate strictly; unknown fields are rejected (422).
  8. Reject privacy.raw_content_included: true (422 raw_content_rejected).
  9. Reject any string matching a known secret pattern (422 contains_secret, with the JSON path).
  10. Reject reports whose summary, status or findings contradict their results (422 inconsistent_report).
  11. Store in one transaction. A second upload of the same run_id returns 200 with duplicate: true.
  12. Record an audit event and apply the project's retention window.

Responses carry X-Request-Id. Errors are {"error": {"code", "message", "request_id"}}.