Deterministic report ingestion
Phase 1 supplies a native, versioned normalized-report adapter. Tools that produce coverage, complexity or other measurements can convert their output to this contract. Native LCOV, SARIF and CI-service integrations are not implied.
{
"schemaVersion": "1.0",
"id": "example-report",
"source": {
"id": "example-adapter",
"tool": "example-fixture",
"adapterVersion": "1.0.0",
"repositoryId": "my-repository",
"revision": "COPY_THE_SCANNED_REVISION",
"collectedAt": "2026-09-01T00:00:00Z"
},
"configuration": {"include": ["src/main.ts"]},
"metrics": [
{"path": "src/main.ts", "key": "example.count", "value": 2, "unit": "count"}
],
"findings": [
{
"id": "example-finding",
"path": "src/main.ts",
"severity": "info",
"message": "Illustrative fixture, not a real coverage measurement"
}
]
}
Replace the repository ID, revision and path with the values in the generated
graph/graph.json. The sample is deliberately labelled as fixture evidence;
do not relabel it as measured test coverage.
topo ingest /path/to/repository /path/to/report.json
One or more report files are accepted. Every report is validated before inputs are persisted or the dashboard is replaced. Successful ingestion writes:
- Content-addressed canonical JSON under
.topo/reports/inputs/. .topo/reports/outputs/dashboard.json, with node IDs, source provenance and SHA-256 fingerprints of normalized inputs.- A new atomic website data snapshot.
Repeated identical ingestion is idempotent. Reports are ordered by ID; metrics
by path/key; findings by ID; object keys by code-unit ordering. An unchanged
revision, normalized inputs and configuration produce byte-identical dashboard
output. collectedAt is supplied evidence, not a new timestamp created on each
run. Array order in adapter-specific configuration is preserved.
Stored input filenames are revalidated against their canonical content hashes.
Do not edit a hashed input in place: move the old evidence out of the input set
and ingest the changed report so its filename and fingerprint remain consistent.
Explicit rejection rules
Unknown schema versions/keys, malformed inputs, foreign repositories, stale revisions, missing source provenance, unscanned paths and duplicate IDs are errors. Conflicting values or units for the same path/metric across sources are also errors: select or reconcile the sources explicitly, rather than silently averaging incompatible measurements.
Supported units are nonnegative integer count, percent in [0,100], ratio
in [0,1], and nonnegative milliseconds. Values must be finite. Findings use
info, warning or error. Paths must be repository-relative.
Reports are revision-bound. A scan at a newer revision refuses stale persisted
inputs; move obsolete inputs out of reports/inputs/ or replace them with new
evidence before regenerating. Human-authored metadata is unaffected. Content
fingerprints on graph nodes describe the working files, but a report's revision
alone does not prove that it measured uncommitted changes. The CLI therefore
requires clean source files and matching HEAD for ingestion, excluding .topo/
artifacts from the dirty check. Library callers must supply an equally verified
revision context.
The pipeline records what each source reports. High coverage is not proof of test quality, and complexity is not an automatic quality verdict. No unsupported aggregate denominator or inferred risk score is introduced by normalization.
Read or edit this page on GitHub