Query an app's evidence¶
Answer "what has this app done, and who approved it?" with one query. The evidence index returns every category — prompts, models, artifacts, tests, promotions, deployments, data access — in a single response, in under ten seconds.
Preconditions¶
- A running platform and
kubectlaccess totend-system. - An app with some history (created, iterated, ideally promoted).
Steps¶
1. Reach the evidence & estate API¶
2. Run the one query¶
Expect every category in one response, and wall-clock under 10 s (SC-003):
app, owner, purpose, aiActTriage, dataScopes, prompts,
models, artifacts, tests, promotions, deployments, dataAccess,
tier1Posture, completeness, provenance (plus pipelines, policy and
vulnerabilities once the app has data for them).
3. Pull out what you need¶
EV=http://localhost:18082/apps/expense-helper/evidence
# Prompts and models (assembled from the Harbor attestations)
curl -s "$EV" | jq '{prompts, models}'
# Approvals: who approved which promotion, and when
curl -s "$EV" | jq '.promotions[] | {prUrl, decision, approver, decidedAt}'
# Deployments per environment (from Argo CD history)
curl -s "$EV" | jq '.deployments'
# Data access decisions — allow AND deny — from the gateway log
curl -s "$EV" | jq '.dataAccess[] | {source, decision, reason, at}'
dataAccess is bounded to the most recent page by default;
?dataAccessLimit=<n> widens it.
4. Read the completeness and provenance maps — always¶
completenesshas one entry per category:complete,partial, orunavailable. Partial results are never presented as complete — treat an empty category markedunavailableas "source unreachable", not as "nothing happened".provenancenames the authoritative source that served each category (for exampleharbor-attestations,app-cr+gitea,argocd,data-gateway). Hand-entered data is not a legal value.
5. Query the estate¶
curl -s http://localhost:18082/estate \
| jq '.apps[] | {name, aiActTriage, cost, suspended}'
curl -s "http://localhost:18082/estate?aiActTriage=true" | jq '.apps[].name'
curl -s "http://localhost:18082/estate?costState=suspended" | jq '.apps[].name'
Verify it worked¶
The query returned in under 10 s, every category key is present, and
completeness explains any gap explicitly. If no category could be
assembled the API returns 503 instead of a silently empty record.
When the evidence page is not enough¶
For full lifetime data-access history, page the gateway's query API
directly (platform OIDC token required; records newest-first, follow
nextCursor):
kubectl -n tend-system port-forward svc/data-gateway 18081:8080 &
curl -s -H "Authorization: Bearer $PLATFORM_TOKEN" \
"http://localhost:18081/v1/logs?app=tend-system/expense-helper&limit=1000" \
| jq '{count: (.records|length), nextCursor}'
Response shapes and all query parameters are in the evidence & estate API reference and the data gateway API reference; why the index assembles rather than stores is in The evidence chain.