Complete HTTP reference for the evidence & estate API — the read-only
service that assembles a per-app evidence record from the authoritative
sources and lists the estate. For the workflow see
query an app's evidence; for why evidence is
assembled this way see the evidence chain.
Sources of truth: specs/003-governance-depth/contracts/evidence-api.md
(delta on specs/001-walking-skeleton/contracts/evidence-estate-api.md) and
services/evidence-estate-api/.
The read surface is a read-time projection and never mutates App CRs. The API
additionally carries the OIDC-gated estate action surface: POST
/estate/{app}/actions/{action} for suspend, resume, retire and restore.
Its only write is patching a tendtech.io/<action> annotation carrying the
server-stamped actor; it never writes status, and the operator is still the sole
writer of authoritative state. The App CR remains the single source of truth.
Returns the full per-app evidence record in one call. The App CR core
(scopes, purpose, promotion, attestation refs) is merged with four live
sources — Gitea, Harbor attestations, the data-gateway access log, and Argo
CD — queried concurrently, each with its own 5-second budget. A slow or
unreachable source degrades only the categories it feeds; it never fails
the call. Responses are served from a 60-second TTL cache keyed by app (and
dataAccessLimit). The performance budget is SC-003: full response in
under 10 seconds.
Response
When
200 with the EvidenceRecord
Normal case, including partial degradation.
404{"error":"app not found: …"}
No App CR with that name in the watch namespace.
503{"error":"evidence unavailable: …"}
Only when no category could be assembled at all. Per-source failure never triggers this — it degrades completeness instead.
Query parameter
Meaning
dataAccessLimit
Widens the default-bounded dataAccess page. A page filled to exactly the limit is marked partial (more history may exist); auditors page the data gateway query API directly for full lifetime history.
Data-gateway decision log, newest-first, both outcomes.
tier1Posture
object
The Tier-1 Posture Record: where this app's inference prompts go and under what provider terms. Always present, never gated on the app's own spec; a missing record degrades it rather than dropping it.
completeness
map category → enum
One entry per category (below).
provenance
map category → source id
One entry per category (below).
dataScopes and purpose are CR fields on the record; the
completeness/provenance maps cover the seven assembled categories.
One entry per category — prompts, models, artifacts, tests,
promotions, deployments, dataAccess, tier1Posture — with values complete,
partial, or unavailable. Partial results are never presented as
complete; consumers must treat absent-with-unavailable differently from
empty-with-complete.
Degradation
Effect
Harbor unreachable
prompts/models/artifacts (and tests on its own failure) → partial; CR-sourced values are kept, never wiped.
Gitea unreachable
promotions → partial (CR record stands, uncorroborated).
Argo CD unreachable
deployments → partial.
Data gateway unreachable
dataAccess → unavailable — the gateway is the sole source; no CR fallback exists.
One row per App, sorted by name. All cost/suspension values are read-only
projections of the App CR status (see
App CRD — CostStatus).
Row field
Source
name
App CR name.
owner
spec.owner.
environment
Mirrors status.state.
dataScopes
Declared scope names ([]string).
expiry
spec.expiry (RFC3339; omitted when unset).
aiActTriage
spec.purpose.decisionsAboutPeople.
cost
{accrued, currency, capAmount, state} — accrued/currency/state from status.costStatus; capAmount from spec.costCap (the cap is owner-declared, accrued is operator-observed). Apps without cost status report state: "unknown".
suspended
true if and only if the Suspended condition is True.
Query parameter
Meaning
aiActTriage=true
Only apps flagged as making decisions about people — the compliance-triage view. Surface, don't adjudicate.
costState=<state>
Only apps whose cost.state equals the value (normal, warning-75, warning-90, suspended, unknown).
All configuration is environment variables. Every source client is
optional: an unset base URL leaves that client unwired and its categories
degrade to unavailable — a missing source config is not a crash.
Variable
Default
Meaning
EVIDENCE_LISTEN_ADDR
:8080
HTTP listen address.
EVIDENCE_WATCH_NAMESPACE
tend-system
Namespace searched for App CRs; empty = cluster-wide.
GITEA_URL
—
Gitea base URL (promotions/prompts corroboration).
GITEA_TOKEN
—
Gitea API token.
GITEA_ORG
tend-apps
Gitea organisation app repos live under.
HARBOR_URL
—
Harbor base URL (attestation categories).
HARBOR_PROJECT
apps
Harbor project holding app artifacts.
HARBOR_ROBOT_NAME
—
Scoped robot account name — never the admin credential.
HARBOR_ROBOT_TOKEN
—
Robot account token.
DATA_GATEWAY_URL
—
Data gateway base URL for the platform query API.
ARGOCD_NAMESPACE
argocd
Namespace Argo CD Application objects live in.
OIDC_ISSUER
—
Keycloak realm issuer for the client-credentials grant this service uses to call the data-gateway query API as a platform caller.