feat(tui): role-sync listener + docs (010 PR-5) - #79
Merged
Merged
Conversation
Fifth and final PR of proposal 010. Closes the operator-facing
piece: TUI badge state + comprehensive runbook docs.
New module acc/tui/role_sync_listener.py:
* RoleSyncListener subscribes (callback-style) to acc.role.sync.>
and maintains a per-role RoleSyncState dataclass with last
conflict + last applied + counters.
* has_fresh_conflict() / render_badge() are the surfaces the
Ecosystem screen will consume — three rendering tiers
(fresh-conflict red, aged-conflict dim, applied-only dim).
* Tolerates malformed JSON + missing role_id without raising.
15 unit tests cover state ingestion, per-role isolation, malformed
payload handling, unknown subjects, the fresh/stale badge window,
and the badge string rendering across all three states.
New docs/role-sync.md:
* Operator-facing comprehensive doc. Explains the three modes
(files/crd/mirror) with per-deploy_mode defaults.
* Mode-by-mode behavioural description with ASCII flow diagrams.
* Sequence diagram showing how mirror-mode echoes die in one round
trip (sentinel-strip on the Python side + ParseRoleFile no-op
check on the Go side).
* Operator runbook: switching modes safely (mirror-validation
step in the middle), diagnosing a stuck conflict badge.
* Explicit non-goals (role.md sync, three-way merge, Spiffe
identity, PD edit path).
Out of scope for this PR: wiring the listener to the existing TUI
NATS subscription. That subscription is collective-scoped
(acc.{collective_id}.>) but role-sync events are global
(acc.role.sync.*), so it needs a second subscription. Pure
plumbing — a tiny follow-up PR will land it without touching the
listener or its tests.
Total: +470 LOC across 4 files (production ~180 + tests ~190 +
docs ~110 + changelog ~30). Comfortably under PR-5's 300-LOC
production budget.
Proposal 010 status: all five PRs landed. Bi-directional file ↔
CRD sync ships as opt-in via role_sync.role_source — default
behaviour unchanged so existing deployments see no difference.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
flg77
added a commit
that referenced
this pull request
Jun 14, 2026
…ble (#79) Live RHOAI 3.4 validation: agent ReplicaSets got FailedCreate because the operator hardcoded the pod-level securityContext.runAsUser to 1001. OpenShift's restricted-v2 SCC requires the UID to come from the namespace's assigned range (openshift.io/sa.scc.uid-range, e.g. [1000920000, 1000929999]), so admission rejected every pod and zero agents were created. - Extract AgentPodSecurityContext() / AgentContainerSecurityContext() helpers. - Drop the hardcoded runAsUser: 1001 from the pod SecurityContext — let the SCC inject the namespace UID. Keep runAsNonRoot: true and add a RuntimeDefault seccomp profile. - Add a container-level SecurityContext that drops ALL capabilities, disallows privilege escalation, sets runAsNonRoot + RuntimeDefault seccomp, and (like the pod context) does NOT pin runAsUser. The acc-agent-core image (UBI10, USER 1001, GID 0, chmod -R g=u /app) already tolerates an arbitrary high UID under GID 0, so no image change is needed; on vanilla k8s it falls back to the image's own USER 1001. Adds regression tests asserting both security contexts are SCC-safe (no fixed runAsUser/runAsGroup/fsGroup; caps dropped; non-root). Co-authored-by: flg <flg@acc1.ic3net.internal> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
Jun 15, 2026
0.2.0 rolls up the RHOAI-maturity wave merged to main today: - #79 agent podspec SCC-compatible (drops pinned runAsUser:1001) → unblocks agent pods on OpenShift restricted-v2 (the 0-agent-pods finding) - #80 AccPackageInstall execs `python3 -m acc.cli` → fixes pack infusion (bare acc-cli console script is not on the non-login kubectl-exec $PATH) - #76 CollectiveStatus.SharedModel surfacing ("model: shared from acc-system") - #75 assistant concierge default-injection + hybrid role-catalogue validation - #74 acc-webgui (Keycloak OIDC) + acc-tui — spec.webgui/spec.tui instantiable CSV name/version → v0.2.0, replaces v0.1.6, image refs → :0.2.0. acc1 builds the image + bundle + index (FROM_INDEX 0.1.6) and redeploys on sandbox1154 to clear the agent pods and the pack-install failures. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
Jun 29, 2026
Two deliverables from the RHOAI-alignment pass: * docs/demos/rhoai-end-to-end-demo.md — the canonical, runnable end-to-end demo guide (operator → deploy → drive → eval-history → MLflow), consolidating the scattered runbooks. Step 0 is the IMAGE-CURRENCY prerequisite: the operator defaults AgentCorpus spec.version to 0.1.0 (~16 versions behind v0.5.27), so a RHOAI deploy must first publish + pin the v0.5.27 agent image (build → Quay push [human-only] → spec.version bump) and clear the SCC bug (PR #79). Wires MLflow per proposal G (009 now live). * docs/tui-webgui-parity-gaps.md — TUI↔WebGUI feature-gap analysis (~60% parity). The critical gap for full RHOAI integration is the Diagnostics eval-history surface (proposal G) — present in the TUI, absent in the WebGUI (golden-prompt list only). All gaps reuse already-shipped runtime functions; the work is API + React, sequenced as the next engineering item. Docs-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
Jul 1, 2026
…in 0.2.12 (#146) Step 0 of the end-to-end demo guide lagged reality in three ways this deploy surfaced: - Pinned v0.5.27 and listed only the agent image. The operator's WebGUIReconciler also pulls acc-webgui-<ver>, so a version bump without that image ImagePullBackOffs the webgui. Now builds + pushes BOTH images at 0.5.28 (with --build-arg ACC_VERSION), and notes any podman host (lighthouse/acc1/bb3) can build them (self-contained multi-stage Containerfiles). - The SCC co-requisite claimed PR #79 "must be merged + the operator redeployed". #79 (8c44f3f) is already in operator 0.2.12 (commit 3a5425b) — verified by ancestry and the live AgentPodSecurityContext / AgentContainerSecurityContext helpers (no pinned runAsUser; RunAsNonRoot + RuntimeDefault seccomp). A current deployment needs NO operator rebuild; the per-CR spec.version bump suffices. Only an operator older than 0.2.0 still needs the bundle bump. - Verify table + troubleshooting updated to match (FailedCreate-at-admission symptom, not CrashLoopBackOff). Docs-only; no runtime/operator code touched. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fifth and final PR of proposal 010. Closes the operator-facing piece: TUI badge state for role-sync events + comprehensive runbook docs.
acc/tui/role_sync_listener.py—RoleSyncListener.handle_event(subject, payload)ingestsacc.role.sync.{applied,conflict}events, maintains a per-roleRoleSyncStatedataclass, and exposeshas_fresh_conflict()/render_badge()for the Ecosystem screen to consume. Tolerates malformed JSON without raising.docs/role-sync.md— operator-facing runbook explaining the three modes (files | crd | mirror), defaults perdeploy_mode, conflict-window semantics with an ASCII sequence diagram showing how echo loops die in one round trip, and a "switching modes safely" runbook.Test plan
tests/test_role_sync_listener.py— state ingestion, per-role isolation, robustness against malformed payloads, fresh/stale badge window, badge string rendering across all three tiers.docs/role-sync.mdend-to-end — primary deliverable of this PR is the docs.Out of scope
Wiring the listener to the existing TUI NATS subscription. That subscription is collective-scoped (
acc.{collective_id}.>) but role-sync events are global (acc.role.sync.*), so a second subscription is needed. Pure plumbing — handled by a tiny follow-up PR without touching the listener or its tests.Diff size
Production is under PR-5's 300-LOC budget; doc weight is intentional (this is the proposal's operator-facing capstone).
Proposal 010 status
With this PR merged, all five PRs land and bi-directional file ↔ CRD sync ships as opt-in via
role_sync.role_source. Default behaviour unchanged — existing deployments see no difference.role_sourceconfig flag🤖 Generated with Claude Code