This example composes the existing Google-origin proof surfaces into one local proof chain:
- AP2 / Verifiable Intent receipt and evidence verification
- A2A signed Agent Card plus verifier-gated handoff evidence
- Google ADK Python decision-ledger signing before dispatch, followed by ADK Python tool-callback signing and a handler-error terminal outcome proof
Run:
pnpm --filter @atrib/integration google-stack-chain-proofOpen the visual workbench:
pnpm --filter @atrib/integration google-stack-chain-visualVite prints the local URL, usually http://127.0.0.1:5173/. The workbench also
supports direct file opening through
visual/index.html; the served path is better for normal
review, while the file path is useful for quick local inspection.
The workbench opens on the live runtime path first. The main proof chain stays
empty until the runtime returns records. The pinned seven-record snapshot remains
available from the Reference view. When runtime-config.js or ?runtime= is
set, the page asks the Google evidence runtime for live AP2 verifier state,
shows the AP2 -> A2A -> ADK decision -> ADK tool run and handler-error outcome
as records arrive,
marks matching BigQuery Agent Analytics-shaped rows, and keeps proof
boundaries visible.
The script prints a JSON summary with the AP2 transaction record hash, A2A
remote and receiver follow-up hashes, ADK Python allow-decision hash, and ADK Python
tool-callback record hash, plus the ADK Python handler-error decision and
terminal-outcome hashes. It also prints a deterministic snapshot block. The
snapshot excludes the runtime /tmp artifact path and pins the stable A2A
evidence identifiers used for the signed record body.
Current snapshot record hashes:
- AP2 transaction:
sha256:e5f103d959cbb1e316e6d658b35fabc547b6b9b3bd530d0165cfbe48155cc6db - A2A remote evidence:
sha256:23e25fd31fc81cf8f6d668cf68454d05c6018451f3a7467fc15f2649277e42f9 - A2A receiver follow-up:
sha256:1225fb6849cab06d9bec936abdf28f5ff1a4e2872ea8f5a87c1b469c54c18fb2 - ADK Python allow decision:
sha256:f52b375c72747cb07a26fd9ed0038b12803a2beee2b8104bc2a34a43b65aa34f - ADK Python tool callback:
sha256:b68851adcf913713f2eba14e2dce27abd3212ebee7f52c87ad44ca77aed1f3af - ADK Python handler-error decision:
sha256:49e8f7c207bcea047601dab8a5bdce53777bc559b20c99ab1ec357fb9b425d24 - ADK Python terminal error outcome:
sha256:192d8c403e65a34ae37d184c4f9dacc4c1b6a84c1eb4b0270426737f5570e9c0
The script also writes a local AP2 artifact bundle under /tmp.
The ADK Python decision-ledger layer includes Google-style operational IDs as local
sidecar facts. The trace and span IDs are deterministic local projections for
this proof. The ADK invocation ID and function-call ID come from the local
google-adk Python run, so live runtime values can vary across runs.
The output also includes an analytics_fixture block shaped around the common
ADK BigQuery Agent Analytics columns (timestamp, event_type, agent,
session_id, invocation_id, user_id, trace_id, span_id,
parent_span_id, status, error_message, is_truncated). It adds
atrib-specific columns for record hash, parent record hashes, and protocol. This
static chain output is a local fixture for review. The runtime can write its
rows to BigQuery as an operator action with BIGQUERY_WRITE_ENABLED=1.
The visual snapshot lives at visual/proof-snapshot.json.
visual/proof-snapshot.js is generated from the JSON
so the workbench can also run from file://. When the proof script's pinned
hashes change, update both files and rerun
pnpm --filter @atrib/integration test -- google-stack-chain-visual before using
the workbench as public proof material.
For a hosted preview, the visual can remain a static site while live verifier
state comes from a separately deployed runtime. Vercel or Cloudflare Pages is
enough for the visual. The Cloud Run runtime in runtime/ can be
configured locally with visual/runtime-config.js
or with the ?runtime= query parameter. Do not commit deployment-specific
preview URLs to this public example.
The Cloud Run runtime lives in runtime/ and serves:
GET /v1/runtime-state: live AP2 replay verifier state for the visual.GET /api/runs: recent active runtime runs, held in memory.POST /api/runs: verifier-gated AP2 -> A2A -> ADK Python run creation.GET /api/runs/:runId: one active run with timeline and analytics rows.POST /v1/verify-ap2: inline AP2 packet verification for a merchant or payment participant.POST /v1/analytics/write: operator-only BigQuery row write whenBIGQUERY_WRITE_ENABLED=1.GET /v1/merchant-adapter: the packet contract for "bring your AP2 merchant" integration.
Public deployments leave BIGQUERY_WRITE_ENABLED unset, so the workbench can
show live verifier state without exposing a public write endpoint.
To run the same gate from official Google AP2 sample output, capture the sample packet and point the runtime at the generated files:
pnpm --filter @atrib/integration ap2-google-live-capture \
--out-dir /tmp/google-ap2-live \
--temp-db-dir /path/to/google-agentic-commerce/AP2/code/samples/python/scenarios/a2a/human-not-present/cards/.temp-db \
--context-id google-ap2-live-demo
ATRIB_AP2_INTEROP_RESULT_JSON=/tmp/google-ap2-live/atrib-packet/ap2-result.json \
ATRIB_AP2_INTEROP_EVIDENCE_JSON=/tmp/google-ap2-live/atrib-packet/ap2-vi-evidence.json \
ATRIB_AP2_INTEROP_TRANSACTION_RECORD_JSON=/tmp/google-ap2-live/atrib-packet/atrib-transaction-record.json \
pnpm --filter @atrib/integration google-evidence-runtimeBring-your-AP2-merchant shape:
{
"result": "AP2 result JSON",
"evidence": "AP2 / Verifiable Intent evidence bundle",
"transactionRecord": "atrib transaction record with counterparty signer",
"nowSeconds": 1779840000
}The runtime returns allow_next_action only after AP2 detection, AP2 / VI
evidence verification, atrib record verification, and counterparty attestation
all pass.
The active /api/runs path uses that gate as the first decision, then runs the
local A2A handoff proof with the accepted AP2 record as parent evidence. It then
runs the Python ADK decision-ledger proof through google-adk Python, signs an
allow decision with the A2A follow-up as parent evidence, and signs the tool
callback with that decision as parent evidence. It also runs a separate ADK
handler-error path that signs an allow decision, lets the FunctionTool raise,
and signs the terminal error outcome from the decision record. The visual
workbench calls this endpoint to show the current run state instead of only
replaying the pinned snapshot.
- AP2 authorization and receipt evidence can produce a signed atrib transaction record with counterparty attestation over atrib transaction bytes.
- That AP2 transaction record can inform the remote A2A evidence record.
- A2A handoff evidence can be accepted before a receiving agent signs a
verifier-resolved
informed_byfollow-up. - Google ADK Python can sign a hash-only allow decision before tool dispatch, then
sign the tool outcome with the decision record in
informed_bywhile local sidecars keep the raw ADK payload inspectable. - Google ADK Python can sign a terminal error outcome from
on_tool_error_callbackwhen aFunctionToolraises after an allow decision. - The Cloud Run runtime can make the next-action decision from verified AP2 evidence, run the A2A and ADK Python follow-up, and produce BigQuery-shaped rows tied to atrib record hashes.
- These surfaces can be presented as one verifier story for support, audit, or external review.
This is a local explicit informed_by bridge, not a shared context_id across
AP2, A2A, and ADK. The AP2, A2A, and ADK records still use their existing local
proof contexts.
It is also not an Agent Platform Runtime proof, an A2A TCK result, a live AP2 payment run, a Gemini Enterprise registration, or a Cloud Marketplace listing. The AP2 runtime is deployed on Cloud Run and uses official-sample replay or provided packet JSON; it is not a real external AP2 merchant or payment service. The ADK handler-error branch proves a real exception path, but timeout, cancellation, and process-crash completeness still need ADK-owned terminal emission semantics.