3.4 KiB
Snapshot schema
One JSON object per audit run, one line per object, appended to
Data/<target>/snapshots.jsonl. Written by bin/audit-snapshot write;
plan §6 is the source, with the two additions noted at the bottom.
{
"run_id": "2026-07-29T14:02:11Z", // UTC, and the primary key
"rubric_version": "1.0.0", // from bin/boundary-classify
"tool_versions": {"inference-arbitrage": "0.3.0", "cc-tokens": "<path>"},
"target": {
"name": "anxious", "version": "0.31.0", "source": "oleks-local",
"repo": "oleks/claude-plugin-anxious",
"skills": ["anxious:steward-agent", "..."] // ADDITION, see below
},
"window": {"since": "...", "until": "...", "days": 7},
"coverage": {"ratio": 0.735, "attributed_turns": 812},
"totals": {"weighted_tokens": 41200000, "invocations": 60,
"share_mechanical": 0.61},
"candidates": [{
"candidate_id": "anxious/steward/label-derivation",
"signature": ["list_issues(<str>)", "issue_read(<n>)"],
"signature_source": "explicit | scan-ngram | slug",
"signature_hash": "b41f...", // sha256 of the signature, 16 hex
"skill": "anxious:steward-agent",
"position": "llm-over-script-digest",
"boundary_confidence": "high",
"determinism_tests": {"T1": true, "...": true},
"falsifiability": {"signature": true, "examples": true,
"overrule_case": true},
"measurement": {"invocations": 22, "offload_waste": 6900000,
"offload_value": 8400000, "share_of_plugin": 0.22,
"cost_per_invocation": 381818},
"measurement_strength": "measured | thin | unmeasured",
"digest_schema": "...", "escalation_path": "...",
"issue": "oleks/claude-plugin-anxious#41",
"verdict": "file"
}],
"boundary_questions": [ /* same shape, verdict boundary-question */ ],
"measurements_by_signature": {"b41f...": { /* measurement */ }}, // ADDITION
"notes": ["<candidate>: no-offload — ..."]
}
status is not stored on a candidate. Status is a property of a pair of
snapshots, not of one, so it is computed by diff and only ever rendered.
Storing it would let a stale status outlive the comparison that produced it.
Two additions to plan §6
target.skills. FR-5.3's stale means "the target's version changed such
that the skill no longer exists". That is uncomputable from a candidate list
alone — a skill absent from the list because it got cheap looks identical to
one absent because it was deleted. The skill inventory of each run is what
tells them apart.
measurements_by_signature. FR-5.5 requires a later window's measured
cost for a signature whose candidate is gone. Once a candidate drops off the
list nothing else in the snapshot carries its cost, so the resolution test
would be unfalsifiable. This records every recurring signature the scan saw,
candidate or not, keyed by the same hash used for identity.
Identity and drift
identity() resolves in FR-5.2 order — issue, then signature hash, then slug —
and diff matches on all three in that order, recording which one hit in
matched_by. Matching on issue or slug while the hashes differ is
signature-drifted: the same tracked concern, a different tool sequence. The
cost series either side of a drift is not continuous.
A candidate whose signature_source is slug cannot drift by construction —
its hash is derived from its identity. Treat drift-silence on those as absence
of evidence.