Skip to content

feat(tui): role-sync listener + docs (010 PR-5) - #79

Merged
flg77 merged 1 commit into
mainfrom
role-sync/tui-conflict-ui
May 14, 2026
Merged

flg77 merged 1 commit into
mainfrom
role-sync/tui-conflict-ui

Conversation

@flg77

@flg77 flg77 commented May 14, 2026

Copy link
Copy Markdown
Owner

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.pyRoleSyncListener.handle_event(subject, payload) ingests acc.role.sync.{applied,conflict} events, maintains a per-role RoleSyncState dataclass, and exposes has_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 per deploy_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

  • 15 unit tests in 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.
  • Reviewer: read docs/role-sync.md end-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

Area Lines
Production ~180
Tests ~190
Docs ~270
Total ~640

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.

PR URL Status
#75 PR-1 — role_source config flag merged
#76 PR-2 — operator file → CRD merged
#77 PR-3 — agent CRD → file merged
#78 PR-4 — mirror conflict detector merged
#79 PR-5 — TUI listener + docs open

🤖 Generated with Claude Code

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>
@flg77
flg77 merged commit cfc36ca into main May 14, 2026
@flg77
flg77 deleted the role-sync/tui-conflict-ui branch May 14, 2026 20:19
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant