From 60101b093212eaf938c928e4150484a4ddd4f053 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 13 Oct 2026 20:55:31 +0200 Subject: [PATCH] Activate Playwright pilot with scoped consumer group and native evidence Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a13690-09e0-7cd1-964b-ec83cdbcd348 --- .gitignore | 1 + WORK-RECORDS.md | 14 +- .../adr/ADR-0006-playwright-consumer-group.md | 54 +++++ .../after-restart-receipt.json | 184 +++++++++++++++++ .../desktop-6-keyboard-result.png | Bin 0 -> 26622 bytes .../desktop-final.png | Bin 0 -> 26622 bytes .../narrow-6-keyboard-result.png | Bin 0 -> 24280 bytes .../narrow-final.png | Bin 0 -> 24280 bytes .../negative-checks.json | 8 + .../preflight.json | 24 +++ .../receipt.json | 184 +++++++++++++++++ .../runtime.json | 40 ++++ docs/evidence/2026-10-13-playwright-rbac.json | 194 ++++++++++++++++++ .../2026-10-13-playwright-source-review.json | 16 ++ docs/playwright-consumer-access.md | 47 +++++ helm/playwright-consumer-access.yaml | 18 ++ ...k-execution-and-wrapped-delivery-review.md | 38 ++++ scripts/verify_playwright_access.py | 94 +++++++++ workplans/README.md | 40 ++-- ...-0038-forgejo-scaleway-primary-coverage.md | 5 +- ...F-WP-0056-playwright-consumer-admission.md | 122 +++++++++++ 21 files changed, 1055 insertions(+), 28 deletions(-) create mode 100644 docs/adr/ADR-0006-playwright-consumer-group.md create mode 100644 docs/evidence/2026-10-13-playwright-managed/after-restart-receipt.json create mode 100644 docs/evidence/2026-10-13-playwright-managed/desktop-6-keyboard-result.png create mode 100644 docs/evidence/2026-10-13-playwright-managed/desktop-final.png create mode 100644 docs/evidence/2026-10-13-playwright-managed/narrow-6-keyboard-result.png create mode 100644 docs/evidence/2026-10-13-playwright-managed/narrow-final.png create mode 100644 docs/evidence/2026-10-13-playwright-managed/negative-checks.json create mode 100644 docs/evidence/2026-10-13-playwright-managed/preflight.json create mode 100644 docs/evidence/2026-10-13-playwright-managed/receipt.json create mode 100644 docs/evidence/2026-10-13-playwright-managed/runtime.json create mode 100644 docs/evidence/2026-10-13-playwright-rbac.json create mode 100644 docs/evidence/2026-10-13-playwright-source-review.json create mode 100644 docs/playwright-consumer-access.md create mode 100644 helm/playwright-consumer-access.yaml create mode 100644 intakes/RPF-IN-0012-task-execution-and-wrapped-delivery-review.md create mode 100644 scripts/verify_playwright_access.py create mode 100644 workplans/RPF-WP-0056-playwright-consumer-admission.md diff --git a/.gitignore b/.gitignore index 9fd4227..997fd50 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index c6a8686..dc7f3aa 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -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 | diff --git a/docs/adr/ADR-0006-playwright-consumer-group.md b/docs/adr/ADR-0006-playwright-consumer-group.md new file mode 100644 index 0000000..d7316f1 --- /dev/null +++ b/docs/adr/ADR-0006-playwright-consumer-group.md @@ -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. diff --git a/docs/evidence/2026-10-13-playwright-managed/after-restart-receipt.json b/docs/evidence/2026-10-13-playwright-managed/after-restart-receipt.json new file mode 100644 index 0000000..0b82d98 --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-managed/after-restart-receipt.json @@ -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" + } + ] +} diff --git a/docs/evidence/2026-10-13-playwright-managed/desktop-6-keyboard-result.png b/docs/evidence/2026-10-13-playwright-managed/desktop-6-keyboard-result.png new file mode 100644 index 0000000000000000000000000000000000000000..91a204048b0770305733f1a80622eaeace4f4d74 GIT binary patch literal 26622 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/2026-10-13-playwright-managed/narrow-final.png b/docs/evidence/2026-10-13-playwright-managed/narrow-final.png new file mode 100644 index 0000000000000000000000000000000000000000..c2ad4e93933c020b666626c85a4c500c453cbcd6 GIT binary patch literal 24280 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/2026-10-13-playwright-managed/negative-checks.json b/docs/evidence/2026-10-13-playwright-managed/negative-checks.json new file mode 100644 index 0000000..5aad21a --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-managed/negative-checks.json @@ -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 +} diff --git a/docs/evidence/2026-10-13-playwright-managed/preflight.json b/docs/evidence/2026-10-13-playwright-managed/preflight.json new file mode 100644 index 0000000..7d3b61e --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-managed/preflight.json @@ -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 + } +} diff --git a/docs/evidence/2026-10-13-playwright-managed/receipt.json b/docs/evidence/2026-10-13-playwright-managed/receipt.json new file mode 100644 index 0000000..af78292 --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-managed/receipt.json @@ -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" + } + ] +} diff --git a/docs/evidence/2026-10-13-playwright-managed/runtime.json b/docs/evidence/2026-10-13-playwright-managed/runtime.json new file mode 100644 index 0000000..481d6c1 --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-managed/runtime.json @@ -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" +} diff --git a/docs/evidence/2026-10-13-playwright-rbac.json b/docs/evidence/2026-10-13-playwright-rbac.json new file mode 100644 index 0000000..cd070e8 --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-rbac.json @@ -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 +} diff --git a/docs/evidence/2026-10-13-playwright-source-review.json b/docs/evidence/2026-10-13-playwright-source-review.json new file mode 100644 index 0000000..b8e3557 --- /dev/null +++ b/docs/evidence/2026-10-13-playwright-source-review.json @@ -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": [] +} diff --git a/docs/playwright-consumer-access.md b/docs/playwright-consumer-access.md new file mode 100644 index 0000000..3e8f0a9 --- /dev/null +++ b/docs/playwright-consumer-access.md @@ -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. diff --git a/helm/playwright-consumer-access.yaml b/helm/playwright-consumer-access.yaml new file mode 100644 index 0000000..fbadbf5 --- /dev/null +++ b/helm/playwright-consumer-access.yaml @@ -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 diff --git a/intakes/RPF-IN-0012-task-execution-and-wrapped-delivery-review.md b/intakes/RPF-IN-0012-task-execution-and-wrapped-delivery-review.md new file mode 100644 index 0000000..04f2772 --- /dev/null +++ b/intakes/RPF-IN-0012-task-execution-and-wrapped-delivery-review.md @@ -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. diff --git a/scripts/verify_playwright_access.py b/scripts/verify_playwright_access.py new file mode 100644 index 0000000..eb5360a --- /dev/null +++ b/scripts/verify_playwright_access.py @@ -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) diff --git a/workplans/README.md b/workplans/README.md index d582987..407962f 100644 --- a/workplans/README.md +++ b/workplans/README.md @@ -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. diff --git a/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md b/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md index e352ac5..d8a1baa 100644 --- a/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md +++ b/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md @@ -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" ``` diff --git a/workplans/RPF-WP-0056-playwright-consumer-admission.md b/workplans/RPF-WP-0056-playwright-consumer-admission.md new file mode 100644 index 0000000..437a8fd --- /dev/null +++ b/workplans/RPF-WP-0056-playwright-consumer-admission.md @@ -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.