Activate Playwright pilot with scoped consumer group and native evidence
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a13690-09e0-7cd1-964b-ec83cdbcd348
This commit is contained in:
parent
b98d17c09f
commit
60101b0932
21 changed files with 1055 additions and 28 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -13,6 +13,7 @@ helm/*.yaml
|
|||
!helm/*-probe.yaml
|
||||
!helm/vergabe-demo-company-role.yaml
|
||||
!helm/vergabe-demo-company-database.yaml
|
||||
!helm/playwright-consumer-access.yaml
|
||||
|
||||
# ArgoCD repository credentials — encrypt locally, never commit
|
||||
argocd/repositories/*.repository.sops.yaml
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
| task | RPF-WP-0035-T13 | done | — | workplans/RPF-WP-0035-credential-lane-implementation.md |
|
||||
| task | RPF-WP-0036-T01 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T02 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T03 | todo | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T03 | wait | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T04 | wait | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T05 | done | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
| task | RPF-WP-0036-T06 | wait | — | workplans/RPF-WP-0036-platform-service-assurance.md |
|
||||
|
|
@ -94,12 +94,12 @@
|
|||
| task | RPF-WP-0043-T05 | done | — | workplans/RPF-WP-0043-policy-nexus-argocd-onboarding.md |
|
||||
| task | RPF-WP-0044-T01 | done | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T02 | done | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T03 | todo | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T04 | todo | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T05 | todo | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T06 | todo | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T03 | done | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T04 | wait | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T05 | done | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T06 | wait | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T07 | wait | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T08 | wait | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0044-T08 | done | — | workplans/RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md |
|
||||
| task | RPF-WP-0045-T01 | done | — | workplans/RPF-WP-0045-eso-kubernetes-auth-activity-core-email-connect.md |
|
||||
| task | RPF-WP-0045-T02 | done | — | workplans/RPF-WP-0045-eso-kubernetes-auth-activity-core-email-connect.md |
|
||||
| task | RPF-WP-0045-T03 | done | — | workplans/RPF-WP-0045-eso-kubernetes-auth-activity-core-email-connect.md |
|
||||
|
|
@ -116,7 +116,7 @@
|
|||
| task | RPF-WP-0047-T02 | done | — | workplans/RPF-WP-0047-bao-coulomb-social-notice-page.md |
|
||||
| task | RPF-WP-0047-T03 | done | — | workplans/RPF-WP-0047-bao-coulomb-social-notice-page.md |
|
||||
| task | RPF-WP-0048-T01 | done | — | workplans/RPF-WP-0048-activity-core-gitops-adoption.md |
|
||||
| task | RPF-WP-0048-T02 | todo | — | workplans/RPF-WP-0048-activity-core-gitops-adoption.md |
|
||||
| task | RPF-WP-0048-T02 | wait | — | workplans/RPF-WP-0048-activity-core-gitops-adoption.md |
|
||||
| task | RPF-WP-0048-T03 | done | — | workplans/RPF-WP-0048-activity-core-gitops-adoption.md |
|
||||
| task | RPF-WP-0049-T01 | done | — | workplans/RPF-WP-0049-platform-root-custody-record-delivery.md |
|
||||
| task | RPF-WP-0049-T02 | done | — | workplans/RPF-WP-0049-platform-root-custody-record-delivery.md |
|
||||
|
|
|
|||
54
docs/adr/ADR-0006-playwright-consumer-group.md
Normal file
54
docs/adr/ADR-0006-playwright-consumer-group.md
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
id: RPLAT-ADR-0006
|
||||
title: "ADR-0006 — Give Playwright consumers a dedicated namespace-scoped group"
|
||||
status: accepted
|
||||
revision: "1.0"
|
||||
owner: railiance-platform
|
||||
date: "2026-10-13"
|
||||
last_reviewed: "2026-10-13"
|
||||
review_interval: 6m
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
rapp-playwright's published private pilot has a namespace Role but deliberately
|
||||
no consumer binding. The user requested establishing a group during the Platform
|
||||
open-work review. Existing cluster documentation provides administrative access;
|
||||
the live binding inventory contains no non-system consumer group.
|
||||
|
||||
## Decision
|
||||
|
||||
Establish Kubernetes RBAC group subject `playwright-consumers`, bound only to
|
||||
the package-owned `playwright-consumer` Role in namespace `playwright`. Platform
|
||||
owns the RoleBinding; rapp-playwright retains the Role and workload source.
|
||||
The initial membership policy includes all identified platform humans and coding
|
||||
agents, as explicitly directed by the user. No per-use-case membership restriction
|
||||
is introduced now. The identity/cluster owners must implement an authenticated
|
||||
group claim for those entities before general consumer availability is accepted.
|
||||
|
||||
## Consequences
|
||||
|
||||
The Role permits pod get/list, pod port-forward creation and get of Deployment
|
||||
`playwright`. It grants no Secrets, pod exec, workload writes, identity
|
||||
impersonation or other namespaces. The namespace must remain dedicated to this
|
||||
service because pod discovery and forwarding cover all its pods. Membership
|
||||
confers browser-job submission for the reviewed trusted targets; it does not
|
||||
authorize private targets, hostile pages or mutually untrusted tenant workloads.
|
||||
|
||||
Kubernetes has no separate Group object to create. This establishes an RBAC
|
||||
subject and permissions, not a KeyCape group, login integration or membership.
|
||||
Administrator impersonation can verify the permission boundary but cannot prove
|
||||
consumer authentication. RPF-WP-0056 retains those outstanding acceptance steps.
|
||||
|
||||
Rollback removes only the Platform RoleBinding after reviewing its exact live
|
||||
identity; it does not delete the Namespace, workload or artifact PVC. Existing
|
||||
port-forwards require separate termination when revoking a consumer's active
|
||||
access. Do not treat removal of a binding as proof that a running tunnel closed.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
Binding all authenticated users would broaden browser access beyond the human/coding-agent
|
||||
identity population. Sharing the administrator kubeconfig would convey unrelated cluster
|
||||
authority. Both are rejected. Selecting OIDC configuration or issuing client
|
||||
certificates without an owner-supported membership route remains outside this
|
||||
bounded group-binding change.
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
{
|
||||
"id": "b11fd28b-58fe-4b20-a15e-32b18ea76f2b",
|
||||
"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-13T18:52:59.076Z",
|
||||
"expires_at": "2026-10-13T19:52:59.076Z",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"release": "forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"execution_location": "railiance01/playwright",
|
||||
"browser_version": "156.0.8078.4",
|
||||
"completed_steps": 14,
|
||||
"steps": [
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 0,
|
||||
"action": "visible",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.091Z",
|
||||
"selector": "h1"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.214Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 2,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.323Z",
|
||||
"key": "Tab"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 3,
|
||||
"action": "focused",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.360Z",
|
||||
"selector": "#increment"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 4,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.393Z",
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 5,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.407Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 6,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:01.454Z"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 0,
|
||||
"action": "visible",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.526Z",
|
||||
"selector": "h1"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.786Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 2,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.877Z",
|
||||
"key": "Tab"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 3,
|
||||
"action": "focused",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.891Z",
|
||||
"selector": "#increment"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 4,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.896Z",
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 5,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.905Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 6,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:53:02.915Z"
|
||||
}
|
||||
],
|
||||
"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-13T18:52:59.078Z",
|
||||
"blocked_requests": 12,
|
||||
"finished_at": "2026-10-13T18:53:03.351Z",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
docs/evidence/2026-10-13-playwright-managed/desktop-final.png
Normal file
BIN
docs/evidence/2026-10-13-playwright-managed/desktop-final.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/evidence/2026-10-13-playwright-managed/narrow-final.png
Normal file
BIN
docs/evidence/2026-10-13-playwright-managed/narrow-final.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"wrong_token": true,
|
||||
"wrong_artifact_token": true,
|
||||
"ui_failure_distinguished": true,
|
||||
"bounded_cancellation": true,
|
||||
"private_target_refused": true,
|
||||
"preflight_healthy": true
|
||||
}
|
||||
24
docs/evidence/2026-10-13-playwright-managed/preflight.json
Normal file
24
docs/evidence/2026-10-13-playwright-managed/preflight.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"available": true,
|
||||
"error": null,
|
||||
"checked_at": "2026-10-13T18:49:56.214Z",
|
||||
"browser_version": "156.0.8078.4",
|
||||
"api_version": "1",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"execution_location": "railiance01/playwright",
|
||||
"release": "forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"allowed_origins": [
|
||||
"https://onco.cc"
|
||||
],
|
||||
"fixture": true,
|
||||
"active": 0,
|
||||
"queued": 0,
|
||||
"limits": {
|
||||
"concurrency": 1,
|
||||
"max_queue": 4,
|
||||
"max_timeout_ms": 120000,
|
||||
"retention_ms": 3600000,
|
||||
"max_runs": 64
|
||||
}
|
||||
}
|
||||
184
docs/evidence/2026-10-13-playwright-managed/receipt.json
Normal file
184
docs/evidence/2026-10-13-playwright-managed/receipt.json
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
{
|
||||
"id": "6a51e164-cec5-46ed-89b1-92b93dd16d23",
|
||||
"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-13T18:50:40.554Z",
|
||||
"expires_at": "2026-10-13T19:50:40.554Z",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"release": "forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"execution_location": "railiance01/playwright",
|
||||
"browser_version": "156.0.8078.4",
|
||||
"completed_steps": 14,
|
||||
"steps": [
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 0,
|
||||
"action": "visible",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.655Z",
|
||||
"selector": "h1"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.815Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 2,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.851Z",
|
||||
"key": "Tab"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 3,
|
||||
"action": "focused",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.911Z",
|
||||
"selector": "#increment"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 4,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.924Z",
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 5,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.937Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "desktop",
|
||||
"index": 6,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:42.949Z"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 0,
|
||||
"action": "visible",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:43.919Z",
|
||||
"selector": "h1"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 1,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:44.063Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 2,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:44.180Z",
|
||||
"key": "Tab"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 3,
|
||||
"action": "focused",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:44.228Z",
|
||||
"selector": "#increment"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 4,
|
||||
"action": "press",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:44.260Z",
|
||||
"key": "Enter"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 5,
|
||||
"action": "text",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:44.275Z",
|
||||
"selector": "#count"
|
||||
},
|
||||
{
|
||||
"viewport": "narrow",
|
||||
"index": 6,
|
||||
"action": "screenshot",
|
||||
"status": "passed",
|
||||
"at": "2026-10-13T18:50:44.314Z"
|
||||
}
|
||||
],
|
||||
"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-13T18:50:40.557Z",
|
||||
"blocked_requests": 12,
|
||||
"finished_at": "2026-10-13T18:50:44.840Z",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
40
docs/evidence/2026-10-13-playwright-managed/runtime.json
Normal file
40
docs/evidence/2026-10-13-playwright-managed/runtime.json
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"observed_at": "2026-10-13T18:52:58.325239+00:00",
|
||||
"image": "forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"replica_ready": true,
|
||||
"pvc_phase": "Bound",
|
||||
"pvc_uid": "da36929a-1d69-457a-ad99-7580ef86ab18",
|
||||
"pvc_size": "2Gi",
|
||||
"initial_pod_uid": "3475ad46-d9d8-4b97-99b7-54b4d984d2f2",
|
||||
"restarted_pod_uid": "a22030a4-c12d-4e97-be8d-98a8d80808c2",
|
||||
"same_image_restart_completed_artifacts_verified": true,
|
||||
"preflight_after_restart": {
|
||||
"available": true,
|
||||
"error": null,
|
||||
"checked_at": "2026-10-13T18:51:59.595Z",
|
||||
"browser_version": "156.0.8078.4",
|
||||
"api_version": "1",
|
||||
"service_version": "0.1.0",
|
||||
"playwright_version": "1.64.0",
|
||||
"execution_location": "railiance01/playwright",
|
||||
"release": "forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"allowed_origins": [
|
||||
"https://onco.cc"
|
||||
],
|
||||
"fixture": true,
|
||||
"active": 0,
|
||||
"queued": 0,
|
||||
"limits": {
|
||||
"concurrency": 1,
|
||||
"max_queue": 4,
|
||||
"max_timeout_ms": 120000,
|
||||
"retention_ms": 3600000,
|
||||
"max_runs": 64
|
||||
}
|
||||
},
|
||||
"access_path": "Existing authenticated operator SSH; administrator impersonation of playwright-consumers; loopback-only port-forward",
|
||||
"actual_consumer_authentication_proven": false,
|
||||
"cross_version_rollback_proven": false,
|
||||
"abrupt_interruption_recovery_proven": false,
|
||||
"source_workload_sha256": "d5d3f3d816dd4320059b4fcdc8409fb84d6075aeb1f409f4d112263d7e14191d"
|
||||
}
|
||||
194
docs/evidence/2026-10-13-playwright-rbac.json
Normal file
194
docs/evidence/2026-10-13-playwright-rbac.json
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
{
|
||||
"schema": "platform-playwright-rbac/v1",
|
||||
"observed_at": "2026-10-13T18:49:52.369304+00:00",
|
||||
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
|
||||
"role_uid": "d24e8b51-7456-4000-8816-b4a49a06ca37",
|
||||
"binding_uid": "190eb32f-8649-4b36-a525-8936cf3ceb51",
|
||||
"group": "playwright-consumers",
|
||||
"checks": [
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "get",
|
||||
"resource": "pods",
|
||||
"subresource": "",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": true,
|
||||
"allowed": true,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "list",
|
||||
"resource": "pods",
|
||||
"subresource": "",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": true,
|
||||
"allowed": true,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "create",
|
||||
"resource": "pods",
|
||||
"subresource": "portforward",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": true,
|
||||
"allowed": true,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "get",
|
||||
"resource": "deployments",
|
||||
"subresource": "",
|
||||
"group": "apps",
|
||||
"namespace": "playwright",
|
||||
"name": "playwright"
|
||||
},
|
||||
"expected": true,
|
||||
"allowed": true,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "get",
|
||||
"resource": "deployments",
|
||||
"subresource": "",
|
||||
"group": "apps",
|
||||
"namespace": "playwright",
|
||||
"name": "other"
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "get",
|
||||
"resource": "secrets",
|
||||
"subresource": "",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "create",
|
||||
"resource": "pods",
|
||||
"subresource": "exec",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "create",
|
||||
"resource": "pods",
|
||||
"subresource": "",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "patch",
|
||||
"resource": "deployments",
|
||||
"subresource": "",
|
||||
"group": "apps",
|
||||
"namespace": "playwright",
|
||||
"name": "playwright"
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "create",
|
||||
"resource": "pods",
|
||||
"subresource": "portforward",
|
||||
"group": "",
|
||||
"namespace": "default",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": true,
|
||||
"attributes": {
|
||||
"verb": "create",
|
||||
"resource": "rolebindings",
|
||||
"subresource": "",
|
||||
"group": "rbac.authorization.k8s.io",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": false,
|
||||
"attributes": {
|
||||
"verb": "list",
|
||||
"resource": "pods",
|
||||
"subresource": "",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"member": false,
|
||||
"attributes": {
|
||||
"verb": "create",
|
||||
"resource": "pods",
|
||||
"subresource": "portforward",
|
||||
"group": "",
|
||||
"namespace": "playwright",
|
||||
"name": ""
|
||||
},
|
||||
"expected": false,
|
||||
"allowed": false,
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true,
|
||||
"actual_consumer_authentication_proven": false
|
||||
}
|
||||
16
docs/evidence/2026-10-13-playwright-source-review.json
Normal file
16
docs/evidence/2026-10-13-playwright-source-review.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"schema": "platform-playwright-source-review/v1",
|
||||
"source_commit": "70268154c06cf78c5d9e1f4eb900213ffd436d1b",
|
||||
"source_sha256": {
|
||||
"declarations/rapp.yaml": "5b030686f1e3ca737805e681fc8b714e1452f879a3fa30bbac8ca30798bb3343",
|
||||
"manifests/workload.yaml": "7d76ad38e25597b629660d31782867d84d7241020a2e450e346a3792ce43290c",
|
||||
"releases/0.1.0.json": "364dcbc16fd50155b7d8eddb0ecb87b1709f0efdc8a41c9f15afd81e5a18506e",
|
||||
"docs/platform-admission.md": "c37dc9f77d5be5bc55c873af98e8ecb0bc945ddd37ea42010d169f5d472b53c0",
|
||||
"docs/operations.md": "fea5f9e25752c0199839559da5bba0ebca77be7c4906dbce4b7b6278ce5b4dab"
|
||||
},
|
||||
"image": "forgejo.coulomb.social/coulomb/rapp-playwright@sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441",
|
||||
"provider_unit_tests_passed": 3,
|
||||
"managed_runtime_accepted": false,
|
||||
"group": "playwright-consumers",
|
||||
"member_identities": []
|
||||
}
|
||||
47
docs/playwright-consumer-access.md
Normal file
47
docs/playwright-consumer-access.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Playwright consumer access
|
||||
|
||||
The release 0.1.0 pilot is running in namespace `playwright` on railiance01.
|
||||
Platform owns its lifecycle and the `playwright-consumers` group binding;
|
||||
rapp-playwright owns the browser implementation, package Role and client.
|
||||
|
||||
The initial membership policy includes all identified platform humans and coding
|
||||
agents. The group binding is installed and tested. Mapping authenticated platform
|
||||
identities into that Kubernetes group is still open in RPF-WP-0056-T03; a KeyCape
|
||||
group alone would not establish Kubernetes access. No administrator kubeconfig
|
||||
is distributed and no broad `system:authenticated` binding is installed.
|
||||
|
||||
Once the caller has the supported group identity and API route:
|
||||
|
||||
```sh
|
||||
kubectl -n playwright port-forward deployment/playwright 18081:8080 --address 127.0.0.1
|
||||
```
|
||||
|
||||
In another terminal, from the existing rapp-playwright checkout:
|
||||
|
||||
```sh
|
||||
python3 client/rapp_playwright.py preflight
|
||||
python3 client/rapp_playwright.py trial --out .local/first-managed-trial
|
||||
```
|
||||
|
||||
Use a new output directory each time. Keep `run.json` private: it contains the
|
||||
run capability. Download retained receipts/screenshots before the one-hour
|
||||
artifact expiry. Current targets are the bundled fixture and public OnCo home
|
||||
page; additional target admission remains separate from group membership.
|
||||
|
||||
Platform can recheck the native permission boundary without changing grants:
|
||||
|
||||
```sh
|
||||
python3 scripts/verify_playwright_access.py --output /tmp/playwright-rbac.json
|
||||
```
|
||||
|
||||
The verifier uses administrator impersonation solely for authorization checks.
|
||||
Its success is not consumer-login proof. It checks the cluster UID, exact Role
|
||||
and group binding, allowed discovery/forwarding and denied exec, Secrets,
|
||||
workload writes, foreign scope and nonmembers.
|
||||
|
||||
October 13 evidence: [RBAC](evidence/2026-10-13-playwright-rbac.json),
|
||||
[runtime and restart](evidence/2026-10-13-playwright-managed/runtime.json),
|
||||
[responsive keyboard trial](evidence/2026-10-13-playwright-managed/receipt.json).
|
||||
Native operator-driven trials passed before and after a same-image restart;
|
||||
completed screenshots survived with identical hashes. Actual consumer login,
|
||||
abrupt-interruption recovery and cross-version rollback remain unproven.
|
||||
18
helm/playwright-consumer-access.yaml
Normal file
18
helm/playwright-consumer-access.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Group membership and authentication are managed by the identity/cluster owners.
|
||||
# This binding does not issue credentials or make anyone a member.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: playwright-consumers
|
||||
namespace: playwright
|
||||
labels:
|
||||
app.kubernetes.io/part-of: rapp-playwright
|
||||
app.kubernetes.io/managed-by: railiance-platform
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: playwright-consumer
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: Group
|
||||
name: playwright-consumers
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
id: RPF-IN-0012
|
||||
kind: intake
|
||||
type: intake
|
||||
title: "Return independent task-execution contract and wrapped-delivery owner review"
|
||||
repo: railiance-platform
|
||||
status: open
|
||||
owner: railiance-platform
|
||||
requested_by: secrets-engine
|
||||
origin: handoff
|
||||
origin_ref: SECRETS-WP-0013-T01
|
||||
priority: high
|
||||
created: "2026-10-11"
|
||||
updated: "2026-10-11"
|
||||
---
|
||||
|
||||
Review the proposed SECRETS-EXEC-20261011-v1 metadata-only mediated execution
|
||||
contract and return the exact Platform owner workplan/task binding and reviewed
|
||||
revision. Identity/approval/PDP owners still owe independent returns. This intake
|
||||
records no foreign owner assent and requests no credential value or native action.
|
||||
|
||||
D3 P3=b separately selects response-wrapped issuer delivery. The existing issuer
|
||||
primitive is hardened in Secrets Engine: native KV-v2/AppRole creation path and
|
||||
TTL/accessor are verified, a fresh private recipient file is exclusively reserved
|
||||
and fsynced before mint, and uncertain attempts cannot silently overwrite/remint.
|
||||
Disposable local OpenBao proves a first unwrap and specific consumed-token denial;
|
||||
it does not prove estate custody or delivery. Review the exact actor/path/audience,
|
||||
deadline, authorization/consume, destination, audit, replay/crash reconciliation and
|
||||
rollback requirements for a separate delivery operation. Metadata execute-ccr
|
||||
explicitly excludes wrap/KV-value delivery and cannot lend its grant to this lane.
|
||||
|
||||
Source: secrets-engine/docs/task-scoped-openbao-execution-contract.md and
|
||||
src/secrets_engine/{openbao,wrap}.py; tests/test_wrapped_issuer_native.py is an
|
||||
isolated test, not a production proof. The already D2-approved repository issuer
|
||||
has its own prepared bounded command and attended Platform login requirement;
|
||||
no second repository scope approval is requested and its waiting task is not
|
||||
reopened by this source review. Owner-prepared execution must precede any new
|
||||
attended item. Genuinely expanded scope belongs in the single daily red batch.
|
||||
94
scripts/verify_playwright_access.py
Normal file
94
scripts/verify_playwright_access.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Read-only native RBAC checks; impersonation is not consumer login proof."""
|
||||
import argparse
|
||||
from datetime import datetime, timezone
|
||||
import json
|
||||
from pathlib import Path
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
|
||||
CLUSTER_UID = 'a553c742-0115-43d4-99a4-a5ca56fe0786'
|
||||
GROUP = 'playwright-consumers'
|
||||
ROLE = 'playwright-consumer'
|
||||
|
||||
|
||||
def verify(target):
|
||||
def kubectl(args, body=None):
|
||||
result = subprocess.run(
|
||||
['ssh', '-o', 'BatchMode=yes', '-o', 'ConnectTimeout=10', target,
|
||||
shlex.join(['kubectl', '--request-timeout=10s', *args])],
|
||||
input=json.dumps(body) if body is not None else None,
|
||||
capture_output=True, text=True, timeout=20, check=True)
|
||||
return json.loads(result.stdout)
|
||||
|
||||
uid = kubectl(['get', 'ns', 'kube-system', '-o', 'json'])['metadata']['uid']
|
||||
if uid != CLUSTER_UID:
|
||||
raise RuntimeError('wrong cluster')
|
||||
binding = kubectl(['get', 'rolebinding', GROUP, '-n', 'playwright', '-o', 'json'])
|
||||
role = kubectl(['get', 'role', ROLE, '-n', 'playwright', '-o', 'json'])
|
||||
if binding['subjects'] != [{'apiGroup': 'rbac.authorization.k8s.io',
|
||||
'kind': 'Group', 'name': GROUP}]:
|
||||
raise RuntimeError('consumer binding subjects differ')
|
||||
if binding['roleRef'] != {'apiGroup': 'rbac.authorization.k8s.io',
|
||||
'kind': 'Role', 'name': ROLE}:
|
||||
raise RuntimeError('consumer binding role differs')
|
||||
expected = [
|
||||
{'apiGroups': [''], 'resources': ['pods'], 'verbs': ['get', 'list']},
|
||||
{'apiGroups': [''], 'resources': ['pods/portforward'], 'verbs': ['create']},
|
||||
{'apiGroups': ['apps'], 'resources': ['deployments'],
|
||||
'resourceNames': ['playwright'], 'verbs': ['get']},
|
||||
]
|
||||
if role['rules'] != expected:
|
||||
raise RuntimeError('consumer role rules differ')
|
||||
cases = [
|
||||
(True, 'get', 'pods', '', '', 'playwright', '', True),
|
||||
(True, 'list', 'pods', '', '', 'playwright', '', True),
|
||||
(True, 'create', 'pods', 'portforward', '', 'playwright', '', True),
|
||||
(True, 'get', 'deployments', '', 'apps', 'playwright', 'playwright', True),
|
||||
(True, 'get', 'deployments', '', 'apps', 'playwright', 'other', False),
|
||||
(True, 'get', 'secrets', '', '', 'playwright', '', False),
|
||||
(True, 'create', 'pods', 'exec', '', 'playwright', '', False),
|
||||
(True, 'create', 'pods', '', '', 'playwright', '', False),
|
||||
(True, 'patch', 'deployments', '', 'apps', 'playwright', 'playwright', False),
|
||||
(True, 'create', 'pods', 'portforward', '', 'default', '', False),
|
||||
(True, 'create', 'rolebindings', '', 'rbac.authorization.k8s.io', 'playwright', '', False),
|
||||
(False, 'list', 'pods', '', '', 'playwright', '', False),
|
||||
(False, 'create', 'pods', 'portforward', '', 'playwright', '', False),
|
||||
]
|
||||
checks = []
|
||||
for member, verb, resource, subresource, group, namespace, name, expected_allowed in cases:
|
||||
attributes = dict(verb=verb, resource=resource, subresource=subresource,
|
||||
group=group, namespace=namespace, name=name)
|
||||
args = ['--as=rpf-playwright-rbac-probe', '--as-group=system:authenticated']
|
||||
if member:
|
||||
args.append('--as-group=' + GROUP)
|
||||
# Raw review endpoint avoids kubectl's unrelated CRD-discovery permission.
|
||||
review = kubectl([*args, 'create', '--raw',
|
||||
'/apis/authorization.k8s.io/v1/selfsubjectaccessreviews',
|
||||
'-f', '-'], {
|
||||
'apiVersion': 'authorization.k8s.io/v1', 'kind': 'SelfSubjectAccessReview',
|
||||
'spec': {'resourceAttributes': attributes}})
|
||||
status = review['status']
|
||||
if status.get('evaluationError') or type(status.get('allowed')) is not bool:
|
||||
raise RuntimeError('authorization review incomplete')
|
||||
checks.append(dict(member=member, attributes=attributes,
|
||||
expected=expected_allowed, allowed=status['allowed'],
|
||||
passed=status['allowed'] == expected_allowed))
|
||||
return dict(schema='platform-playwright-rbac/v1',
|
||||
observed_at=datetime.now(timezone.utc).isoformat(), cluster_uid=uid,
|
||||
role_uid=role['metadata']['uid'], binding_uid=binding['metadata']['uid'],
|
||||
group=GROUP, checks=checks, passed=all(c['passed'] for c in checks),
|
||||
actual_consumer_authentication_proven=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--target', default='railiance01', choices=['railiance01'])
|
||||
parser.add_argument('--output', required=True, type=Path)
|
||||
args = parser.parse_args()
|
||||
result = verify(args.target)
|
||||
args.output.write_text(json.dumps(result, indent=2) + '\n')
|
||||
print(json.dumps({'passed': result['passed'], 'checks': len(result['checks']),
|
||||
'evidence': str(args.output)}))
|
||||
raise SystemExit(0 if result['passed'] else 1)
|
||||
|
|
@ -1,25 +1,27 @@
|
|||
# Current platform work
|
||||
|
||||
Reviewed September 27, 2026. Eight workplans remain blocked with 23 waiting
|
||||
tasks. No active, ready or proposed source workplan remains. Completed work
|
||||
retains its IDs and managed UUIDs, including plans under `archived/`.
|
||||
Reviewed October 13, 2026 against source workplans and the live inbox. Source
|
||||
files remain authoritative; the generated brief contains historical aliases.
|
||||
Completed plans retain their IDs and managed UUIDs, including archived plans.
|
||||
|
||||
| Workplan | Remaining tasks | Next dependency |
|
||||
| Workplan | Open tasks | Next work or dependency |
|
||||
| --- | --- | --- |
|
||||
| [RPF-WP-0015](RPF-WP-0015-audit-core-custody-and-recovery-coordination.md) | T02/T03 | Fresh recovery windows, synthetic sender/abort owner and snapshot/quorum/access evidence |
|
||||
| [RPF-WP-0027](RPF-WP-0027-keycape-live-secret-exposure-recovery.md) | T03/T06 | Complete historical resolver custody/routing contract; T05 closed from September 23 operator disposition and owner receipt |
|
||||
| [RPF-WP-0035](RPF-WP-0035-credential-lane-implementation.md) | T02/T03/T06/T07/T08 | Exact service registration/custody, human memo acceptance, reader/disablement returns, governed npm migration and formerly-valid audit-bearer revocation proof |
|
||||
| [RPF-WP-0036](RPF-WP-0036-platform-service-assurance.md) | T03/T04/T06 | Current recovery/cadence/custody evidence, Q2 production delivery and owner/projection acceptance; local archive adapter implemented |
|
||||
| [RPF-WP-0038](RPF-WP-0038-forgejo-scaleway-primary-coverage.md) | T04 | Durable scheduled caller, canonical verified inventory and quota/retention gates; September 15 cutover/expiration hold persists |
|
||||
| [RPF-WP-0043](RPF-WP-0043-policy-nexus-argocd-onboarding.md) | T02/T03/T04 | Cross-owner chart/values agreement, committed values and source access, zero-diff proof and adoption |
|
||||
| [RPF-WP-0044](RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md) | T03–T08 | Per-app promotion gates, issue-core credentials/ownership, target-revenue hook acceptance, ESO adoption/observation and readable old-controller inventory |
|
||||
| [RPF-WP-0048](RPF-WP-0048-activity-core-gitops-adoption.md) | T02 | Healthy observation through September 28 at 16:06:22 Berlin plus bounded authenticated release broker/admission and rollback proof |
|
||||
| [RPF-WP-0015](RPF-WP-0015-audit-core-custody-and-recovery-coordination.md) (active) | T02, T03 | Recovery windows, sender/abort owner and snapshot/quorum/access evidence |
|
||||
| [RPF-WP-0027](RPF-WP-0027-keycape-live-secret-exposure-recovery.md) (blocked) | T03, T06 | Resolver and custody owner contracts |
|
||||
| [RPF-WP-0035](RPF-WP-0035-credential-lane-implementation.md) (blocked) | T02, T03, T07, T08, T10, T12 | Execution integration and owner acceptance; verified-source compiler correction tested October 13 |
|
||||
| [RPF-WP-0036](RPF-WP-0036-platform-service-assurance.md) (blocked) | T03, T04, T06 | Bounded scheduler, telemetry receiving contract and ownership returns |
|
||||
| [RPF-WP-0038](RPF-WP-0038-forgejo-scaleway-primary-coverage.md) (blocked) | T04 | Durable caller, verified inventory and quota/retention; expiration/cutover hold persists |
|
||||
| [RPF-WP-0043](RPF-WP-0043-policy-nexus-argocd-onboarding.md) (blocked) | T03, T04 | Owner values/render diff, then root automation before adoption |
|
||||
| [RPF-WP-0044](RPF-WP-0044-argocd-phase-b-adopt-existing-applications.md) (blocked) | T04, T06, T07 | Attended issue-core issuer login, ordered ESO adoption and root automation |
|
||||
| [RPF-WP-0048](RPF-WP-0048-activity-core-gitops-adoption.md) (blocked) | T02 | Activity-core promotion evidence |
|
||||
| [RPF-WP-0053](RPF-WP-0053-coulomb-paired-backup-admission.md) (proposed) | T01, T02, T03, T04, T05 | Paired archive execution/custody, retrieval/recovery and monitoring admission |
|
||||
| [RPF-WP-0055](RPF-WP-0055-keycape-client-secret-rotation-residual.md) (backlog) | T01 | Unpromoted rotation residual; do not implement without demand/risk promotion |
|
||||
| [RPF-WP-0056](RPF-WP-0056-playwright-consumer-admission.md) (blocked) | T03 | Dedicated Playwright consumer group, managed pilot and authenticated identity route |
|
||||
|
||||
Latest [review and evidence](../history/2026-09-27-loose-end-review.md).
|
||||
No new task or workplan was created. Existing completed credential reviews,
|
||||
delivery, retention projection and rotations are not reopened by these waits.
|
||||
October 13 review corrected WP-0038-T04's stale `todo` state to the documented
|
||||
`wait`. RPF-IN-0012 remains an open independent execution/wrapped-delivery review;
|
||||
the compiler fix does not close it. Playwright publication is resolved; its new
|
||||
Platform workplan records the user-requested group and actual activation evidence.
|
||||
|
||||
Source files are authoritative. The generated brief still contains retired
|
||||
aliases and stale statuses; do not recreate work from it. Routine synchronization
|
||||
uses the exact-commit Repo Manager receipt described in AGENTS.md. Legacy alias
|
||||
repair remains the scoped owner dependency in WP-0036-T06.
|
||||
Routine synchronization uses the exact-commit Repo Manager receipt described in
|
||||
AGENTS.md. Legacy alias repair remains the scoped WP-0036-T06 dependency.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ status: blocked
|
|||
flavor: implementation
|
||||
owner: codex
|
||||
created: "2026-09-06"
|
||||
updated: "2026-10-03"
|
||||
updated: "2026-10-13"
|
||||
state_hub_workstream_id: "7beec1a7-aa82-5a36-9a66-6b60008a2455"
|
||||
---
|
||||
|
||||
|
|
@ -72,7 +72,8 @@ removed. Evidence: `docs/evidence/forgejo-scaleway-restore-2026-09-06.json`.
|
|||
|
||||
```task
|
||||
id: RPF-WP-0038-T04
|
||||
status: todo
|
||||
status: wait
|
||||
blocking_reason: "Durable scheduled caller, verified inventory and quota/retention gates remain open; September 15 prohibits expiration and scheduled secondary cutover."
|
||||
priority: high
|
||||
state_hub_task_id: "a4807df0-ec96-58f1-9cbd-42b1dcde0d6f"
|
||||
```
|
||||
|
|
|
|||
122
workplans/RPF-WP-0056-playwright-consumer-admission.md
Normal file
122
workplans/RPF-WP-0056-playwright-consumer-admission.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
---
|
||||
id: RPF-WP-0056
|
||||
type: workplan
|
||||
title: "Admit the Playwright pilot and establish scoped consumer group access"
|
||||
domain: financials
|
||||
repo: railiance-platform
|
||||
status: blocked
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-10-13"
|
||||
updated: "2026-10-13"
|
||||
---
|
||||
|
||||
Incoming owner request: State Hub c82d75f3-3191-410d-a8c8-fd647bf7f3ef,
|
||||
superseding publication return a282c300-eaef-4cd6-99b0-f4fb255203b3;
|
||||
consumer RAPP-PLAYWRIGHT-WP-0004-T01. The user selected establishing a group
|
||||
in this session. Platform owns lifecycle admission; implementation remains in
|
||||
rapp-playwright. Publication is complete, and must not remain a blocker.
|
||||
|
||||
## Review the immutable package and pilot boundary
|
||||
|
||||
```task
|
||||
id: RPF-WP-0056-T01
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Reviewed rapp-playwright revision 70268154c06cf78c5d9e1f4eb900213ffd436d1b:
|
||||
declaration, release, workload, admission and operations contract. The published
|
||||
image is sha256:8d6fd5a8172cf906bb503642ed620761945c5138b86f6396c36f65cbe6def441.
|
||||
Three provider contract/network/proxy tests pass independently in this session.
|
||||
One Recreate replica requests 100m CPU/256Mi memory, limits 1 CPU/1Gi, and uses
|
||||
a 2Gi transient artifact PVC with one-hour retention. Non-root, read-only root,
|
||||
no service-account token, dropped capabilities, loopback listener, denied ingress
|
||||
and public HTTPS/DNS egress match the proposed trusted-target pilot.
|
||||
Chromium's OS sandbox is disabled; this is no hostile-page or cross-tenant
|
||||
isolation acceptance. Initial targets remain the bundled fixture and public
|
||||
https://onco.cc; no private preview, source import or data-license grant follows.
|
||||
|
||||
## Establish and verify the consumer group RBAC boundary
|
||||
|
||||
```task
|
||||
id: RPF-WP-0056-T02
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
User requested a group; use exact Kubernetes group `playwright-consumers`.
|
||||
Platform binding: helm/playwright-consumer-access.yaml, referring to the package's
|
||||
existing namespace Role `playwright-consumer`. Bootstrap only its reviewed
|
||||
Namespace and Role, then bind the group. No cluster-wide role, Secret access,
|
||||
pod execution, workload mutation, credential issuance or group membership grant.
|
||||
Verify live allowed discovery/port-forward and denied execution/Secrets/foreign
|
||||
namespace/workload changes, plus nonmember denial. Impersonated authorization
|
||||
checks prove RBAC only, not actual consumer authentication or connectivity.
|
||||
|
||||
## Connect platform identities and prove managed consumer operation
|
||||
|
||||
```task
|
||||
id: RPF-WP-0056-T03
|
||||
status: wait
|
||||
priority: high
|
||||
blocked_on: message-from:railiance-cluster
|
||||
blocking_reason: "User admitted all identified platform humans and coding agents; their supported Kubernetes authentication/group-mapping route remains unimplemented."
|
||||
```
|
||||
|
||||
The session's initial readback found only built-in/system user/group bindings;
|
||||
the cluster documentation describes an administrator kubeconfig. A group subject
|
||||
in RBAC does not create an identity-provider group or convey membership. The user admitted all identified platform humans and coding agents; establish
|
||||
their existing-owner authentication and group-mapping route,
|
||||
including expiration/revocation. Do not distribute the admin kubeconfig or infer
|
||||
that a KeyCape group is already understood by the Kubernetes API.
|
||||
|
||||
The immutable pilot is now deployed after fresh capacity, server dry-run and
|
||||
diff: 1/1 Ready, 2Gi PVC Bound and matching imageID. A real group-identity trial
|
||||
is still required; administrator impersonation is recorded separately.
|
||||
Retain screenshots/keyboard receipts, wrong-token/assertion/target negatives,
|
||||
cancellation and restart/interrupted/completed-artifact recovery. One available
|
||||
release supports same-image recovery only; cross-version rollback stays unproven.
|
||||
Keep RAPP-PLAYWRIGHT-WP-0004-T01 open until its owner accepts those receipts.
|
||||
|
||||
|
||||
## October 13 native implementation
|
||||
|
||||
ADR-0006 records the group decision. Namespace, package Role and Platform binding
|
||||
are applied on the pinned railiance01 cluster. Thirteen native authorization
|
||||
checks pass: intended discovery/forwarding is allowed; Secrets, exec, writes,
|
||||
foreign namespaces, foreign deployment and nonmember access are denied. The
|
||||
initial verifier's kubectl schema discovery needed unrelated CRD access; using
|
||||
the native SelfSubjectAccessReview endpoint corrected the verifier without any
|
||||
permission expansion. Re-run scripts/verify_playwright_access.py with --output.
|
||||
|
||||
Fresh capacity before deployment: 3460m/4000m CPU requested, 9472Mi memory
|
||||
requested and 126Gi free storage. Adding 100m/256Mi plus a 2Gi PVC fits that
|
||||
scheduling headroom; aggregate CPU/memory limits were already overcommitted.
|
||||
The declared single-browser limits remain in force. Full package server dry-run
|
||||
and diff passed and the published immutable image reached Ready.
|
||||
|
||||
Initial fixture trial through administrator-impersonated group port-forward
|
||||
passed desktop/narrow keyboard and screenshot checks. This demonstrates native
|
||||
RBAC and browser operation; it does not turn the administrative SSH identity
|
||||
into a generally available consumer authentication route. T03 retains that gap.
|
||||
|
||||
## Activate the bounded pilot and verify operator-driven recovery
|
||||
|
||||
```task
|
||||
id: RPF-WP-0056-T04
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
The published package is running. Thirteen RBAC checks and six native negative/
|
||||
health checks pass, including wrong receipt/artifact token, deliberate assertion
|
||||
failure, bounded cancellation and private-target refusal. Actual Deployment
|
||||
restart reached Ready with a new pod UID, the same immutable image and the same
|
||||
PVC; all four completed artifacts were retrieved and their hashes matched.
|
||||
Evidence: docs/evidence/2026-10-13-playwright-managed/ and
|
||||
docs/evidence/2026-10-13-playwright-rbac.json. This is same-image recovery, not
|
||||
cross-version rollback or abrupt-interruption proof. T03 remains open for actual
|
||||
consumer identity/group mapping and the remaining package-owner acceptance.
|
||||
|
||||
Group decision mirrored to State Hub d2426028-0b04-4ea2-b199-d7f9e19e38e6.
|
||||
Loading…
Add table
Add a link
Reference in a new issue