Protocol

What is an Evidence Package?

One file. Nine sections. No field that source code could go into.

Short answer

An Evidence Package is a single JSON file describing one analysis of one system. It carries the entities the system is made of, how they contain one another, how they relate, the interfaces between them, the data they hold and move, the claims made about them, the evidence behind each claim, the questions that could not be answered, and a record of what was and was not looked at. Keys are local to the file, and everything referenced must be declared in it.

#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.
The envelope Invented example — not a customer
{
  "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

The sections of an Evidence Package
SectionWhat it holds
coverageOne 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".
limitationsPlain sentences about what this analysis could not establish at all.
entitiesThe 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.
structureContainment: which entity sits inside which, in one of five views — application, business, organization, deployment, data.
relationsMeaning: uses, depends on, reads from, writes to, implements, owned by, and the rest.
interfacesHow two things talk, each with a readable purpose and a set of operations.
data_objects, representations, data_flows, mappingsWhat business data is, the shapes it takes, where it moves, and what happens to it on the way.
evidenceWhere a finding came from: a path, a symbol, a line range, a short summary. Never the code itself.
claimsA statement about one thing, with a perspective — observed, declared, inferred — and the evidence keys backing it.
unknownsEvery 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.
An algorithm, as recorded Invented example — not a customer
"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.

See a complete package, field by field.

The metadata preview shows a full worked example with what is sent, what is never sent, and an honest section on where metadata can still be sensitive.

Open the metadata preview Build your project map — free