Skip to content

feat(tui/ecosystem): role.md detail surface + searchable role table (proposal 003 PR-2) - #55

Merged
flg77 merged 1 commit into
mainfrom
tui/ecosystem-role-detail
May 13, 2026
Merged

feat(tui/ecosystem): role.md detail surface + searchable role table (proposal 003 PR-2)#55
flg77 merged 1 commit into
mainfrom
tui/ecosystem-role-detail

Conversation

@flg77

@flg77 flg77 commented May 13, 2026

Copy link
Copy Markdown
Owner

Summary

PR-2 of proposal 003 (ACC TUI usability hardening). Addresses operator review items 1, 2, 3 from ACC TUI Review.md:

# Operator complaint Resolution
1 Role detail box doesn't show role.md content — only role.yaml New Markdown widget renders role.md content alongside the existing yaml view
2 Role overview too long / fixed-size — needs to be browsable Detail panel split into two Collapsible widgets inside the existing ScrollableContainer
3 Add a search bar for roles New Input(#role-filter) above the role DataTable; case-insensitive substring match against name / domain / persona

Wire shape

ROLE LIBRARY
  [Filter…………………………………………………]   <- new
  [DataTable: Role / Domain / Persona / Tasks]

ROLE DETAIL
  ▼ role.md (narrative)              <- new, open by default
    [Markdown render of role.md]
  ▶ role.yaml (raw)                  <- collapsed by default
    [Static yaml content — unchanged]

Changes

acc/tui/screens/ecosystem.py

  • Compose: Input(#role-filter) added above the role DataTable; the single Static(#role-detail-panel) replaced with a placeholder + two Collapsible widgets (#role-md-collapsible + #role-yaml-collapsible).
  • _load_roles() caches loaded rows in self._all_role_rows; delegates to _apply_filter("") for the initial render.
  • _apply_filter(query) rebuilds the DataTable from the cache keeping only matching rows.
  • on_input_changed(event) reacts to keystrokes in #role-filter.
  • _show_role_detail(role_name) reads role.md alongside role.yaml; renders via the Markdown widget.
  • New _read_role_md(md_path, role_name) helper with friendly-fallback placeholder when role.md is absent (points operators at slot 006's forthcoming authoring guideline).

Tests

  • tests/test_ecosystem_screen_pilot.py_capture_panel_updates() now taps both new surfaces so the prior substring assertions keep passing. 5 new tests cover the md surface (present + absent) and the filter (narrow / persona-match / no-match).
  • tests/test_coding_agent_tui_pilot.py — one-line update to read from #role-yaml-content instead of the removed #role-detail-panel.

25/25 tests green across the ecosystem + coding-agent TUI test files.

CHANGELOG note

PR-2's [Unreleased] CHANGELOG entries will be added during rebase once PR #54 (which introduces CHANGELOG.md) lands. Skipping the file here avoids a guaranteed merge conflict on a file that doesn't yet exist on main.

Manual verification

acc-tui    # navigate to Ecosystem (key 6)
# Type substring in filter → only matching rows render; clear → full list restored
# Click any role → role.md renders in the open collapsible at top
# Click the role.yaml collapsible → raw yaml renders identically to before
# Roles without role.md show the authoring-guidance placeholder

Reference

Proposal 003 — …\ACC Implementation\003 - ACC TUI usability hardening.md (operator vault).

🤖 Generated with Claude Code

Implements PR-2 of proposal 003 (ACC TUI usability hardening).
Addresses operator review items 1, 2, 3 from `ACC TUI Review.md`:

1. Role detail box now shows the role's narrative `role.md`
   content (was: only `role.yaml`).
2. Role overview is browsable — detail panel split into two
   `Collapsible` widgets (role.md open by default; role.yaml
   collapsed) inside the existing `ScrollableContainer`, so the
   operator can scroll a long role.md without losing the yaml
   surface.
3. Role table gains a filter `Input` above it.  Typing narrows
   to rows whose name / domain / persona contains the substring
   (case-insensitive).  Clearing restores the full list.

## Changes

### `acc/tui/screens/ecosystem.py`

* Compose:
  - Added `Input(#role-filter)` above the role DataTable.
  - Replaced the single `Static(#role-detail-panel)` with a
    `Static(#role-detail-placeholder)` + two Collapsibles:
    `#role-md-collapsible` (Markdown widget `#role-md-content`)
    and `#role-yaml-collapsible` (Static `#role-yaml-content`).
* `_load_roles()` now caches the loaded row tuples in
  `self._all_role_rows` and delegates the initial render to a
  new `_apply_filter("")` so the filter handler can repopulate
  without re-reading disk.
* `_apply_filter(query)` clears + repopulates the DataTable
  keeping only rows whose name / domain / persona contain
  the (case-insensitive) substring.
* `on_input_changed(event)` reacts to keystrokes in
  `#role-filter`; other Inputs get a no-op.
* `_show_role_detail(role_name)` rewritten:
  - Hides the "select a role" placeholder once a role is
    chosen.
  - Reads `roles/<name>/role.md` via the new module-level
    `_read_role_md()` helper; renders it in the Markdown
    widget.  Missing file → friendly placeholder pointing
    operators at the authoring convention (slot 006).
  - role.yaml render unchanged in content, but lands on the
    `#role-yaml-content` Static under its collapsible.
* New helper `_read_role_md(md_path, role_name)` — read-only
  with safe fallbacks for missing / unreadable files.

### Tests

* `tests/test_ecosystem_screen_pilot.py`:
  - `_capture_panel_updates()` updated to tap BOTH the Markdown
    and the yaml Static so prior substring assertions
    ("test_role", "pilot fixture") keep passing.
  - 5 new cases:
    - `test_role_detail_renders_role_md_when_present`
    - `test_role_detail_md_placeholder_when_absent`
    - `test_role_filter_input_narrows_table`
    - `test_role_filter_matches_persona_substring`
    - `test_role_filter_no_match_empties_table`
* `tests/test_coding_agent_tui_pilot.py`:
  - One-line update so the test reads from `#role-yaml-content`
    instead of the now-removed `#role-detail-panel`.

25/25 green across `tests/test_ecosystem_screen_pilot.py` +
`tests/test_coding_agent_tui_pilot.py`.

## Note on CHANGELOG entry

This PR's `[Unreleased]` CHANGELOG entries will be added during
rebase once PR #54 (which introduces CHANGELOG.md) lands.
Skipping it here avoids a guaranteed merge conflict on a file
that doesn't yet exist on main.

## Manual verification

* Open Ecosystem screen → type substring in the filter →
  only matching rows render.  Clear → full list restored.
* Click any role row → role.md renders in the open
  collapsible at the top.  Roles without role.md show the
  authoring-guidance placeholder.
* Click the `role.yaml (raw)` collapsible → raw yaml renders
  identically to the pre-PR-2 single-pane view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@flg77
flg77 force-pushed the tui/ecosystem-role-detail branch from cd31086 to bd1404d Compare May 13, 2026 21:03
@flg77
flg77 merged commit eed316d into main May 13, 2026
@flg77
flg77 deleted the tui/ecosystem-role-detail branch May 13, 2026 21:03
flg77 added a commit that referenced this pull request May 13, 2026
All six PRs of proposal 003 (ACC TUI usability hardening) are on
main:

* #54 (PR-1) — Prompt cancel-on-timeout + CHANGELOG/version bump
* #55 (PR-2) — Ecosystem role.md detail + searchable filter
* #56 (PR-3) — Ecosystem roles/ watcher + selection lock
* #57 (PR-4) — Configuration pane (pane 8)
* #58 (PR-5) — Performance + Soma cluster/governance context
* #59 (PR-6) — CLI/TUI infuse parity + subrole sibling listing

pyproject.toml: 0.2.0-dev → 0.2.0
CHANGELOG.md:   [Unreleased] section closed off as [0.2.0]
                (dated 2026-05-14) with a fresh [Unreleased]
                header ready for the next cycle.

Tag v0.2.0 follows this merge.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77 added a commit that referenced this pull request Jun 10, 2026
… fixes CrashLoopBackOff (WS-A) (#55)

* fix(operator): ship AccCatalog/AccPackageInstall CRDs in the bundle (fixes CrashLoopBackOff)

The operator binary registers controllers for all four kinds (agentcorpus,
agentcollective, acccatalog, accpackageinstall), but the bundle shipped only two
CRDs. On a fresh install the AccCatalog/AccPackageInstall Kind sources never sync
("no matches for kind \"AccCatalog\" in version acc.redhat.io/v1alpha1"), the
manager's cache-sync times out, and it exits → CrashLoopBackOff.

Fix (validated live: operator 1/1 Running, 0 restarts, all 4 controllers
"Starting workers", on the SNO sandbox via the private catalog):
* config/crd/bases: add the controller-gen'd acccatalogs + accpackageinstalls
  CRDs; wire both into config/crd/kustomization.yaml.
* bundle/manifests: ship both CRDs so OLM applies them with the CSV.
* CSV: add both to customresourcedefinitions.owned + the clusterPermissions the
  new controllers need (acccatalogs/accpackageinstalls +/status +/finalizers,
  plus pods + pods/exec for the AccPackageInstall pkg-install exec path).
* config/rbac/role.yaml: same rules for source parity (the operator's RBAC is
  hand-curated in the CSV/role.yaml, not from kubebuilder markers).

Completes WS-A (proposal 020): all four ACC CRDs now install via OperatorHub/
the private catalog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(operator): install-UX items 2/4/6/7 — prereq guidance + OTel/Grafana defaults

Operator install-experience improvements (render in the OperatorHub create form):
* deployMode: PREREQUISITES note (rhoai needs RHOAI/DataScienceCluster + Milvus;
  NATS/Redis always provisioned; large fleets → prefer Kafka). [item 2]
* governance.gatekeeperIntegration: manual-prereq hint — install OPA Gatekeeper
  first; the operator only syncs rules, it does not install Gatekeeper. [item 4]
* kafka: "recommended for large agent fleets" + AMQ Streams/Strimzi prereq. [item 7]
* observability defaults: backend otel (was log) + grafanaDashboard true (was
  false); webhook now auto-sets otelCollector.endpoint to the in-cluster
  <name>-otel-collector:4317 so backend=otel works out of the box and passes the
  endpoint-required validator. [item 6]

CRD bases regenerated (controller-gen). Items 3 (RHOAI deployMode auto-detect)
and 5 (surface discovered RHOAI InferenceServices in status) follow in the next
increment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(operator): items 3+5 (RHOAI auto-detect deployMode + model discovery) + fix PrometheusRules panic + daemonsets RBAC

Items 3 & 5 (proposal 020), validated live on the RHOAI sandbox:
* Item 3 — webhook migrated to a client-backed CustomDefaulter that detects a
  DataScienceCluster and defaults deployMode=rhoai (else standalone). deployMode
  loses its static schema default so the webhook can decide. VERIFIED: a CR with
  no deployMode defaulted to "rhoai" (default-dsc present).
* Item 5 — controller scans READY KServe InferenceServices and surfaces them in
  status.availableRHOAIModels (name/namespace/url). New RHOAIModelRef type.

Bugs found while running the first AgentCorpus on RHOAI (both pre-existing, both
blocked any deploy on a cluster with Prometheus):
* PrometheusRulesReconciler passed a nil *runtime.Scheme to util.Upsert →
  SetControllerReference nil-pointer PANIC on every reconcile. Added the Scheme
  field + wired it from the controller.
* CSV clusterPermissions omitted apps/daemonsets (runtime-evidence reconciler
  watches DaemonSets) → reflector forbidden, blocking cache sync. Added it
  (role.yaml already had it).

Also: RBAC for datasciencecluster.opendatahub.io/datascienceclusters (webhook
detection); imagePullPolicy: Always on the manager (clean iterative redeploys);
agentcorpora CRD regenerated (optional deployMode + availableRHOAIModels status).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(operator): RHOAI end-to-end agentset runbook + sample (GPU free → model → agentset)

Full follow-along runbook (operator/docs/rhoai-e2e-agentset-runbook.md) for ACC
on RHOAI, validated live on the SNO sandbox:
* install the operator from the private catalog
* free a GPU held by a model in another project (KServe stop annotation)
* deploy/serve the model (KServe InferenceService)
* apply a complete agentset (AgentCorpus + AgentCollective wired to the existing
  RHOAI model via vllm.deploy=false) → operator reconciles NATS, Redis, OPA
  bundle, OTel collector + the agent Deployments

Every GUI step lists the equivalent CLI (parallel) + 📸 screenshot placeholders;
all YAML inline for manual reproduction. Captures the 7 gotchas found+fixed
(missing CRDs, PrometheusRules nil-Scheme panic, daemonsets RBAC, OperatorGroup
mode, runAsUser SCC, leases RBAC, GPU contention) + the embedding-vs-chat
model-type caveat. Adds operator/config/samples/acc_rhoai_e2e_agentset.yaml.

Live result: deployMode auto-defaulted to rhoai; operator created acc-e2e-nats,
acc-e2e-redis, acc-e2e-opa-bundle (1/1), acc-e2e-otel-collector, and 3 agent
Deployments (ingester/arbiter/observer) from the single agentset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(gitignore): ignore operator/config/samples/local-models (local on-demand KServe test models)

Local scratch CRs (ServingRuntime + InferenceService) for ad-hoc GPU model
deploys during testing (Llama-3.1-8B-Instruct, Qwen2.5-14B-Instruct-AWQ on the
L4). Synced by hand to acc1; never committed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(operator): richer AccCatalog/AccPackageInstall field descriptions for the console form

The console "Create" form for AccCatalog/AccPackageInstall is auto-generated
from the CRD openAPIV3Schema field descriptions (no specDescriptors), so terse
one-line descriptions left the form's help area empty and the enum fields
(tier, mode) unexplained — the "form is very complex, needs more descriptions"
feedback from the test cluster.

Enrich every spec field with what/why/example + enum-value meanings + the
mode-dependency of url/path, at the source of truth (Go doc comments) and
mirrored into the deployed CRD schemas (config/crd/bases + bundle) so the
improvement ships on the next operator redeploy without depending on a
controller-gen run. Also upgrade the two CSV `owned` descriptions from
one-liners to the AgentCorpus/AgentCollective multi-line style.

Comment/description-only — no validation markers, enums, or behavior changed.
Thread 06 (operator corrections).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
flg77 added a commit that referenced this pull request Jun 10, 2026
…bedding, prometheusRules toggle, stop pod churn (#58)

Five fixes found bringing up an acc-e2e collective on RHOAI (vllm backend,
deploy=false). (The missing stage-1.6 CRDs and the PrometheusRules nil-scheme
panic from the same bring-up were already addressed on main by #55.)

1. acc-config.yaml template (templates/acc_config.go) used right-trim
   `{{ if X -}}`, which consumes the *next* line's leading indentation — so
   vllm_inference_url / model / embedding_model rendered at column 0 → invalid
   YAML → agents crash on startup (yaml ScannerError). Switch every
   conditional block to canonical left-trim `{{- if X }}` / `{{- end }}`.

2. The vLLM backend reads config.llm.model, but the template emitted
   `vllm_model` (no such field) → fell back to the ollama default
   `llama3.2:3b` → vLLM returns 404. Emit `model:` (the universal field).

3. acc/config.py build_llm_backend vllm branch dropped embedding_model_path,
   so episode-persist embedding tried to fetch from huggingface.co and failed
   offline. Pass it through like the other backends.

4. AgentCorpusSpec.PrometheusRules had `json:",omitempty"` + default=true, so
   an explicit `false` was dropped by the defaulting webhook's re-marshal and
   the default re-applied — impossible to disable. Drop omitempty.

5. buildManifestDelivery built the acc-roles/skills/mcps ConfigMap volume
   items[] by iterating cm.Data directly — Go randomizes map order, so the
   rendered pod template differed every reconcile. Since the agent Deployment
   reconcile replaces Spec.Template wholesale, this produced a fresh
   ReplicaSet/rollout every ~15s → perpetual pod churn. Sort the keys.

Verified end-to-end on RHOAI: operator generates valid config with the
correct model, agents reach a stable one-per-role steady state (no churn),
offline embedding (no HF calls), and a golden prompt round-trips
(TASK_COMPLETE output "pong").

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
flg77 added a commit that referenced this pull request Jun 11, 2026
…rrides (#57)

Root-caused live on c26sx RHOAI sandbox: rhoai-corpus nats/redis stuck
ImagePullBackOff 'name unknown: Repo not found'. util.ComponentImage derives
nats/redis from imageRepository (<repo>:nats-<tag>) or imageRegistry
(<reg>/nats:<tag>); with imageRegistry=registry.access.redhat.com (the default)
neither path yields a real nats/redis image. A single registry/repo can't serve
both the ACC images and stock nats/redis.

Add optional full-ref overrides honored before the ComponentImage fallback
(no behaviour change when unset). Set e.g. docker.io/library/nats:2.10-alpine /
docker.io/library/redis:7-alpine, OR mirror nats/redis into the single
imageRepository. Built against current main (ComponentImage model, post-#55).

String value fields => deepcopy-safe. acc1: make manifests + go build/test
before deploy; promote to flg77/acc once tested.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
flg77 added a commit that referenced this pull request Aug 23, 2026
…acks

The ACC Assistant now knows the @acc/supply-chain-roles pack and the guardrails
it must honor and surface when infusing/using it — so packaging work stays
governed end-to-end.

seed_context additions:
- list @acc/supply-chain-roles (packaging_engineer — RPM/DEB hardened, signed,
  attested builds) among the canonical first-party packs
- a general "rules of engagement — governance-sensitive packs" rule: before
  PROPOSE_INFUSE of such a pack, read its manifest rules of engagement
  (catalog_query / acc-pkg inspect) and state them back to the operator. The
  supply-chain pack is the reference case: builds in STAGING and only RECOMMENDS
  promotion (promotion to trusted/prod is CRITICAL, human-in-the-loop, never
  autonomous); signing keys referenced never placed in the workspace; hardening
  fail-closed; unjustified HIGH/CRITICAL CVE HOLDs the package. Propose the
  infuse + staging build, but route the promote decision to the operator.

Pack is live in the ecosystem catalog (acc-ecosystem v1.4.0, signed keypair +
keyless-OIDC); HowTo handed to acc-web (PR #55). Role source PR #7, tiers PR #8.

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