Short answer
#The shape of the file
- Evidence Package
- A single JSON document produced by one analysis, identified by a schema version and a protocol version, bound to one scan job, and carrying nine sections that together describe a system and the confidence with which each part of that description is held.
- In plain terms The file your coding agent writes: a structured description of your system, with a citation behind each claim.
{
"schema": "1adk.evidence-package/1",
"protocol_version": "1",
"scan_job_id": "…",
"generated_by": { "agent": "claude-code", "version": "…" },
"source": { "kind": "AGENT_SCAN", "title": "Static scan", "revision": "9f3c1a2" },
"coverage": [ … ],
"limitations": [ … ],
"entities": [ … ],
"structure": [ … ],
"relations": [ … ],
"interfaces": [ … ],
"data_objects": [ … ],
"representations":[ … ],
"data_flows": [ … ],
"mappings": [ … ],
"evidence": [ … ],
"claims": [ … ],
"unknowns": [ … ]
}
source.revision is the commit the analysis was read at. Without
it a package describes a system at no particular moment, and two packages
cannot be meaningfully ordered.
#What each section is for
| Section | What it holds |
|---|---|
coverage | One row per scope examined, with a status — complete, partial, not covered, unknown — and what was deliberately excluded. This is what makes it possible to distinguish "removed" from "not looked at". |
limitations | Plain sentences about what this analysis could not establish at all. |
entities | The things the system is made of. Each has a package-local key, a canonical type, a name, and a description written for a non-programmer. |
structure | Containment: which entity sits inside which, in one of five views — application, business, organization, deployment, data. |
relations | Meaning: uses, depends on, reads from, writes to, implements, owned by, and the rest. |
interfaces | How two things talk, each with a readable purpose and a set of operations. |
data_objects, representations, data_flows, mappings | What business data is, the shapes it takes, where it moves, and what happens to it on the way. |
evidence | Where a finding came from: a path, a symbol, a line range, a short summary. Never the code itself. |
claims | A statement about one thing, with a perspective — observed, declared, inferred — and the evidence keys backing it. |
unknowns | Every question a person would have to answer, with why it matters and a priority of low, medium or high. |
There is deliberately no priority above high. Something more urgent than that is a risk for one person to raise with another, not a line in a generated file.
#Identity, and why it is asked for explicitly
The single most consequential requirement in the format.
Every entity is asked to carry something stable to be recognised by across analyses:
repository_path— where a file or directory lives, relative to the root;fully_qualified_name— the unambiguous name in the language's own terms;external_id— a chosen, kept label for things with neither: a database, a queue, a deployment target, a cloud resource.
A name is not identity. Rename a class and it is the same class; call two things "Main database" and they are two different things. An entity with none of the three is a new thing to every analysis, and its history restarts each time.
Snapshots and change goes into what is built on top of this, and why it is the part that decides whether a tool can track architecture over time at all.
#Behaviour and algorithms
An operation on an interface may carry two extra things, and both exist because of the same problem: knowing that an endpoint exists tells you almost nothing about whether it is safe to depend on.
- Behaviour — authentication, authorization, timeout, retry, idempotency. The five properties an owner actually needs when asking "what happens if this fails".
- Algorithm — nested steps describing what an operation does: validate, condition, write, fail, call. Not pseudocode and not a transcription; a readable account of the decisions taken.
"algorithm": {
"name": "Create payment",
"steps": [
{ "type": "VALIDATE", "description": "The amount and the currency are checked." },
{ "type": "CONDITION", "condition": "the amount is above the limit",
"children": [ { "type": "FAIL", "description": "The request is refused." } ] },
{ "type": "WRITE", "description": "A payment row is created." }
]
}
Three steps, in a form a non-programmer can read, that answer a question an architecture diagram cannot: what happens when the amount is too large.
#What the format has no field for
The negative space is the design.
- File contents. There is no field a function body could go in.
- Configuration values. The name of a setting may appear; its value has nowhere to live.
- Data. No rows, no dumps, no SQL, no fixtures.
- Absolute paths. Rejected by the instruction and pointless in the schema, which is rooted at the repository.
- Credentials. No field, and free text carrying credential shapes is refused on arrival.
The instruction reinforces this from the other side: descriptions must be plain sentences rather than formatted output, and a field that reads like source is refused along with the whole package. Between a schema with nowhere to put code and a validator that rejects text shaped like code, pasting a file body is impractical without deliberately working around both.
#What happens to a package that breaks a rule
It is refused whole. There is no partial acceptance, no "we kept the good parts" and no quarantine-and-repair: a package that fails validation writes nothing, and the project store is untouched.
The reasons a package is refused:
- it does not match the schema, or declares a version the server does not serve;
- it exceeds the size limit stated in its own job;
- it claims a scan job it was not issued for, or one that has expired;
- it references a key it does not declare;
- its free text carries the shape of a credential.
#Limits of the format
What this does not do
- It records structure and behaviour, not intent. There is no field for why a decision was taken, because an analysis cannot recover it.
- It has no quality judgement. No complexity metric, no rating, no opinion about whether a component should exist.
- It describes one analysis at one commit. Everything about change lives in the comparison between two packages, not inside one.
- It is only as complete as the analysis that produced it — which is exactly why coverage is required rather than assumed.
- The machine-readable schema is not published. Whether to publish it is a separate product decision that has not been taken.