Skip to content

Core concepts

Six ideas carry the whole platform: sessions and forks, executions, findings and severity, workspaces and projects, audits and reports, and attestations. Everything else is a detail of one of them.

Sessions and forks

A fork is a private copy of a real chain, pinned to a block. It reads through to an upstream node for state it does not have, and it never writes anything back. A session is your handle on one fork: it holds the fork, the contracts in scope, the accounts, and the history of what you have run.

Opening a session is a real boot — the fork is created for you and the target contract is loaded and analysed. You get back a session_id, and the session stays with you until you close it.

Two accounts matter by convention. The auditor is the account you send from; the other side of the scenario is whatever the target needs — a pool, a router, a token holder.

Balance reads and the transaction sender accept a small set of aliases in place of raw hex: auditor (you), me (equivalent), and target (the contract under analysis). Everything else must be a hex address. "Counterparty" is how these docs talk about the other side of a scenario — it is not an alias the API accepts, and sending it is rejected at the front door with 400 validation_failed.

Isolated and stateful sends

The single most important behaviour to understand is how a send treats state.

Mode What happens Use it for
Isolated (default) Each transaction runs from the same base state, is measured, then rolled back Comparing variants — twenty attempts, all from identical conditions
Stateful (persist: true) Each transaction commits, and the next one starts from the result Multi-step reproductions where step 3 depends on step 2

A stateful sequence is how a real finding gets demonstrated: fund an account, call the setup function, then call the one that breaks. The mined block climbs as you go.

Snapshots

A snapshot is a named point you can return to. Take one before a risky sequence and restore it afterwards, and you can re-run the same reproduction from the same starting conditions as many times as you need — without rebuilding the fork. Restoring is a mutating call, so it needs an Idempotency-Key.

See Sessions and forks for the endpoints.

Executions

Every transaction you send against a fork produces an execution, identified as exec_…. It is a durable resource, not a log line: it is written as accepted before the transaction fires, and moved to confirmed or failed after. A send that dies mid-flight is therefore visible as accepted, never silently absent.

Each execution carries what it did — gas, value deltas, the storage slots it touched with before and after values, the return data, the revert reason if it reverted — and it is attributed to a user, a workspace and a project. That is what makes a reproduction citable weeks later rather than a screenshot.

Executions and their traces are listed under Execution.

Findings and severity

A finding is a claim about a contract that you can support. It has a title, a description, a location, and a severity:

Severity Meaning
critical Direct loss of funds or complete loss of control
high Serious impact, or loss under conditions an outsider can create
medium Real impact under narrower conditions
low Limited impact, or requires an unlikely precondition
info No direct impact; hygiene, clarity or defence in depth

Findings arrive from three directions and land in the same ledger: the detector sweep over a contract's bytecode, the analysis endpoints that probe a specific class of problem, and you — filing what you found by hand. Findings attach to an audit inside a workspace, and they can be exported as SARIF for a code-scanning pipeline.

The important discipline: a finding is reproducible when there is an execution on a fork that demonstrates it. That link is what an attestation later seals.

Workspaces, projects and contracts

Tenancy is a chain of containers, widest first:

organization
└── team
    └── workspace          tenancy + membership boundary
        ├── project        one engagement, one codebase, one scope
        │   └── contracts  the inventory under review
        ├── audits         the work, with its findings
        ├── reports        what you publish
        └── activity       an append-only trail of what happened

A workspace is what you are billed to, invited into, and audited within. A project is a single engagement inside it. The contract inventory is the set of addresses in scope, so "what did we actually review" is a stored fact rather than an argument.

Both IDEs file into the same structure. An execution from the Auditing IDE and a merge request from the Contract IDE land in one workspace's activity trail, which is what makes the record reconstructable.

Endpoints: Workspaces, Projects, Contract index, Activity.

Two things named 'reports'

A workspace's reports are documents you author and share. A project also has a reports view, which is the same documents filtered to that engagement. They are one concept seen at two scopes, not two features.

Audits and reports

An audit is the unit of work: it collects findings, comments, acknowledgements and a status, and it can be resolved, archived or shared. A report is what leaves the building — a document produced from an audit, publishable behind a share link with a controlled lifetime.

Sharing is deliberate and revocable. A share link is its own resource; deleting it withdraws access without touching the report.

Endpoints: Audit index, Workspaces.

Attestations (Audit Passport)

An attestation is a signed, tamper-evident record that a specific audit reached a specific conclusion at a specific time. Attestations within a workspace are hash-chained — each one commits to the previous — so a record cannot be quietly removed or reordered after the fact.

They are signed with RS256, and the public keys are published as a JWKS. That means a third party — a client, an exchange, an insurer — can verify a passport you hand them without an account:

curl -X GET https://api.trilocore.ai/api/v1/public/attestations/jwks.json

and then submit the passport itself. The request is the certificate exactly as it was issued — the server re-derives the hashes over what you send and checks the signature against the published key. It reads no tenant data and returns nothing but a verdict:

curl -X POST https://api.trilocore.ai/api/v1/public/attestations/verify \
  -H "Content-Type: application/json" \
  -d @passport.json

The verdict separates its reasons — whether the content is consistent, whether the hash chain is consistent, and whether the signature is valid — so a failure tells you which of the three broke.

What verification does and does not prove

A successful verification proves the attestation was issued by Trilocore and has not been edited since. It does not re-derive the audit, and it does not check the contract's current on-chain state — a contract can be upgraded the day after a valid passport is issued. Read a passport as "this audit happened, and this is exactly what it said", not as a live safety guarantee.

Endpoints: Public (unauthenticated) and the attestation routes under Workspaces. Issuing an attestation is a mutating call and requires an Idempotency-Key.

How the API expresses all this

Every concept above is a resource with an identifier in the path, and the API is uniform about it: creation returns 201 with a Location, a resource you cannot see returns 404 rather than admitting it exists, and errors carry a stable machine-readable code.