Add repeatable browser acceptance for real consumer connections
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a13590-a16f-7f60-be60-fd71627bc99d
This commit is contained in:
parent
3a30ef159a
commit
5b8e798419
7 changed files with 591 additions and 3 deletions
347
docs/evidence/2026-10-13-consumer-verifier.json
Normal file
347
docs/evidence/2026-10-13-consumer-verifier.json
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
{
|
||||
"local_pass": {
|
||||
"started_at": "2026-10-13T20:10:02.963127+00:00",
|
||||
"service_url": "http://127.0.0.1:18083",
|
||||
"argv": [
|
||||
"tools/verify_consumer.py",
|
||||
"--url",
|
||||
"http://127.0.0.1:18083",
|
||||
"--expected-release",
|
||||
"sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"--expected-location",
|
||||
"workstation-release-check",
|
||||
"--out",
|
||||
".local/acceptance-tool-02"
|
||||
],
|
||||
"expected_release": "sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"expected_location": "workstation-release-check",
|
||||
"checks": [
|
||||
"preflight_identity",
|
||||
"responsive_keyboard_trial_and_downloads",
|
||||
"foreign_run_and_artifact_denied",
|
||||
"ui_failure_preserves_evidence",
|
||||
"private_target_denied",
|
||||
"running_job_cancellation"
|
||||
],
|
||||
"status": "passed",
|
||||
"identity_authentication_verified": false,
|
||||
"scope": "browser API only; pair with native consumer identity and permission receipts",
|
||||
"finished_at": "2026-10-13T20:10:20.767858+00:00"
|
||||
},
|
||||
"wrong_release": {
|
||||
"started_at": "2026-10-13T20:10:04.425524+00:00",
|
||||
"service_url": "http://127.0.0.1:18083",
|
||||
"argv": [
|
||||
"tools/verify_consumer.py",
|
||||
"--url",
|
||||
"http://127.0.0.1:18083",
|
||||
"--expected-release",
|
||||
"deliberately-wrong",
|
||||
"--expected-location",
|
||||
"workstation-release-check",
|
||||
"--out",
|
||||
".local/acceptance-tool-wrong-release"
|
||||
],
|
||||
"expected_release": "deliberately-wrong",
|
||||
"expected_location": "workstation-release-check",
|
||||
"checks": [],
|
||||
"status": "failed",
|
||||
"identity_authentication_verified": false,
|
||||
"scope": "browser API only; pair with native consumer identity and permission receipts",
|
||||
"error": "release_mismatch",
|
||||
"finished_at": "2026-10-13T20:10:04.527311+00:00"
|
||||
},
|
||||
"wrong_location": {
|
||||
"started_at": "2026-10-13T20:10:15.402989+00:00",
|
||||
"service_url": "http://127.0.0.1:18083",
|
||||
"argv": [
|
||||
"tools/verify_consumer.py",
|
||||
"--url",
|
||||
"http://127.0.0.1:18083",
|
||||
"--expected-release",
|
||||
"sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"--expected-location",
|
||||
"railiance01/playwright",
|
||||
"--out",
|
||||
".local/acceptance-tool-wrong-location"
|
||||
],
|
||||
"expected_release": "sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"expected_location": "railiance01/playwright",
|
||||
"checks": [],
|
||||
"status": "failed",
|
||||
"identity_authentication_verified": false,
|
||||
"scope": "browser API only; pair with native consumer identity and permission receipts",
|
||||
"error": "execution_location_mismatch",
|
||||
"finished_at": "2026-10-13T20:10:15.452794+00:00"
|
||||
},
|
||||
"trial_receipt": {
|
||||
"id": "be7f8e4a-c0d3-4728-b290-06c08dc224f4",
|
||||
"api_version": "1",
|
||||
"status": "passed",
|
||||
"error": null,
|
||||
"label": "independent-browser-trial",
|
||||
"target": "fixture",
|
||||
"viewports": [
|
||||
{
|
||||
"name": "desktop",
|
||||
"width": 1280,
|
||||
"height": 800
|
||||
},
|
||||
{
|
||||
"name": "narrow",
|
||||
"width": 390,
|
||||
"height": 844
|
||||
}
|
||||
],
|
||||
"timeout_ms": 60000,
|
||||
"created_at": "2026-10-13T20:10:03.005Z",
|
||||
"expires_at": "2026-10-13T21:10:03.005Z",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"release": "sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"execution_location": "workstation-release-check",
|
||||
"browser_version": "156.0.8078.4",
|
||||
"completed_steps": 14,
|
||||
"steps": [
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 0,
|
||||
"action": "visible",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:06.924Z",
|
||||
"selector": "h1"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:07.220Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 2,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:07.332Z",
|
||||
"key": "Tab"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 3,
|
||||
"action": "focused",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:07.410Z",
|
||||
"selector": "#increment"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 4,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:07.420Z",
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 5,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:07.429Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 6,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:07.510Z"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 0,
|
||||
"action": "visible",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.121Z",
|
||||
"selector": "h1"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.324Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 2,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.431Z",
|
||||
"key": "Tab"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 3,
|
||||
"action": "focused",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.438Z",
|
||||
"selector": "#increment"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 4,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.514Z",
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 5,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.521Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 6,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:09.529Z"
|
||||
}
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "desktop-6-keyboard-result.png",
|
||||
"bytes": 26622
|
||||
},
|
||||
{
|
||||
"name": "desktop-final.png",
|
||||
"bytes": 26622
|
||||
},
|
||||
{
|
||||
"name": "narrow-6-keyboard-result.png",
|
||||
"bytes": 24280
|
||||
},
|
||||
{
|
||||
"name": "narrow-final.png",
|
||||
"bytes": 24280
|
||||
}
|
||||
],
|
||||
"started_at": "2026-10-13T20:10:03.007Z",
|
||||
"blocked_requests": 13,
|
||||
"finished_at": "2026-10-13T20:10:10.349Z",
|
||||
"downloads": [
|
||||
{
|
||||
"name": "desktop-6-keyboard-result.png",
|
||||
"bytes": 26622,
|
||||
"sha256": "b15998824256b86c74f2bbb75f061061be65db0b4f3bb5444529ac69a723cdad"
|
||||
},
|
||||
{
|
||||
"name": "desktop-final.png",
|
||||
"bytes": 26622,
|
||||
"sha256": "b15998824256b86c74f2bbb75f061061be65db0b4f3bb5444529ac69a723cdad"
|
||||
},
|
||||
{
|
||||
"name": "narrow-6-keyboard-result.png",
|
||||
"bytes": 24280,
|
||||
"sha256": "49d27cb169b8e180ce93969c6d2b8619a7684cf035bb9dcae9cd91d8bd9952e8"
|
||||
},
|
||||
{
|
||||
"name": "narrow-final.png",
|
||||
"bytes": 24280,
|
||||
"sha256": "49d27cb169b8e180ce93969c6d2b8619a7684cf035bb9dcae9cd91d8bd9952e8"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ui_failure_receipt": {
|
||||
"id": "fc5aa6c0-6335-4b39-a321-5c24c4dea3c4",
|
||||
"api_version": "1",
|
||||
"status": "failed",
|
||||
"error": "ui_assertion_failed",
|
||||
"label": "independent-browser-trial",
|
||||
"target": "fixture",
|
||||
"viewports": [
|
||||
{
|
||||
"name": "desktop",
|
||||
"width": 1280,
|
||||
"height": 800
|
||||
}
|
||||
],
|
||||
"timeout_ms": 60000,
|
||||
"created_at": "2026-10-13T20:10:10.377Z",
|
||||
"expires_at": "2026-10-13T21:10:10.377Z",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"release": "sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"execution_location": "workstation-release-check",
|
||||
"browser_version": "156.0.8078.4",
|
||||
"completed_steps": 1,
|
||||
"steps": [
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 0,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T20:10:14.611Z"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "failed",
|
||||
"at": "2026-10-13T20:10:15.009Z",
|
||||
"selector": "#count"
|
||||
}
|
||||
],
|
||||
"artifacts": [
|
||||
{
|
||||
"name": "desktop-0-before-failure.png",
|
||||
"bytes": 25740
|
||||
}
|
||||
],
|
||||
"started_at": "2026-10-13T20:10:10.380Z",
|
||||
"blocked_requests": 9,
|
||||
"finished_at": "2026-10-13T20:10:20.537Z",
|
||||
"downloads": [
|
||||
{
|
||||
"name": "desktop-0-before-failure.png",
|
||||
"bytes": 25740,
|
||||
"sha256": "141dcadca4774da5fefec835bb789c5221685d3f453070a593e69aa6ad4782ce"
|
||||
}
|
||||
]
|
||||
},
|
||||
"cancellation_receipt": {
|
||||
"id": "6af97df4-d8eb-4c3f-897f-47ec8568634a",
|
||||
"api_version": "1",
|
||||
"status": "cancelled",
|
||||
"error": "cancelled",
|
||||
"label": "independent-browser-trial",
|
||||
"target": "fixture",
|
||||
"viewports": [
|
||||
{
|
||||
"name": "desktop",
|
||||
"width": 1280,
|
||||
"height": 800
|
||||
}
|
||||
],
|
||||
"timeout_ms": 60000,
|
||||
"created_at": "2026-10-13T20:10:20.636Z",
|
||||
"expires_at": "2026-10-13T21:10:20.636Z",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"release": "sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"execution_location": "workstation-release-check",
|
||||
"browser_version": null,
|
||||
"completed_steps": 0,
|
||||
"steps": [],
|
||||
"artifacts": [],
|
||||
"started_at": "2026-10-13T20:10:20.638Z",
|
||||
"finished_at": "2026-10-13T20:10:20.658Z",
|
||||
"downloads": []
|
||||
}
|
||||
}
|
||||
|
|
@ -82,3 +82,32 @@ imagetools inspect --raw <image-reference>` and hash the exact returned bytes.
|
|||
Require the expected digest, then pull that immutable reference with
|
||||
`sudo k3s crictl pull <image-reference>` on railiance01 and verify its recorded
|
||||
repo digest. A successful upload alone does not establish node pull access.
|
||||
|
||||
|
||||
## Repeatable consumer API acceptance
|
||||
|
||||
After Platform establishes and verifies the caller's own identity, permission
|
||||
boundary and port-forward, run this from the provider checkout with Python 3.10+:
|
||||
|
||||
```sh
|
||||
python3 tools/verify_consumer.py --url http://127.0.0.1:18081 \
|
||||
--expected-release forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441 \
|
||||
--expected-location railiance01/playwright --out .local/consumer-acceptance-01
|
||||
```
|
||||
|
||||
Use a fresh output directory for each caller/run. Exit 0 means browser API checks
|
||||
passed; exit 3 means verification failed. `verification.json` lists checks and
|
||||
errors. The command verifies exact release/location, desktop/narrow PNG dimensions
|
||||
and hashed downloads, keyboard assertions, foreign-token receipt/artifact denial,
|
||||
failed-assertion evidence, private-target refusal and running-job cancellation.
|
||||
It submits only fixture jobs and one denied private-target request, cancels its
|
||||
own runs on exit and does not restart the service or alter access grants.
|
||||
|
||||
Keep all `run.json` files private. Pair the result with Platform's native consumer
|
||||
identity/permission receipt for each real human and registered coding agent.
|
||||
The result deliberately says `identity_authentication_verified: false`: neither
|
||||
operator impersonation nor this browser check alone proves self-service access.
|
||||
Target-unreachable diagnostics, abrupt interruption/recovery, revocation/stream
|
||||
termination and cross-version rollback require their separate evidence. The
|
||||
command's local validation is retained in
|
||||
[evidence](evidence/2026-10-13-consumer-verifier.json).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue