Skip to content

docs(openspec): operator feature parity for D + E epics (plan for #49–#52) - #48

Merged
flg77 merged 2 commits into
mainfrom
docs/op-parity-openspec
May 8, 2026
Merged

docs(openspec): operator feature parity for D + E epics (plan for #49–#52)#48
flg77 merged 2 commits into
mainfrom
docs/op-parity-openspec

Conversation

@flg77

@flg77 flg77 commented May 8, 2026

Copy link
Copy Markdown
Owner

Summary

Audit findings (verified against main)

  1. agents[].role enum locked to legacy 5 roles → rejects all 11 new personas at admission.
  2. roles/, skills/, mcps/ are not delivered to agent pods — the operator only mounts acc-config + wasm-governance + a tiny inline acc-role ConfigMap.
  3. No MCP-server reconciler — the three E2 MCPs and echo_server exist only as Podman Compose services.
  4. CSV alm-examples and config samples are stale (no autoresearcher / coding-split demo).
  5. TUI sample lacks ACC_ROLES_ROOT + roles/ mount that compose has.
  6. Compile bug: agentcollective_types.go:91-94RoleDefinition struct missing closing } before AgentRoleSpec.

Implementation PR sequence (this is the plan, not the code)

Note: this proposal was originally drafted assuming PRs #48#51 but landed as #48 itself, shifting the four implementation slots to #49#52. Documented in commit 7dcdeb2 as a real-world example of the renumber clause.

Coordination protocol

Each task in tasks.md has a claimed by: slot. Before starting work an instance:

  1. git pull and check unclaimed slots.
  2. Edit a single line, commit, push immediately — the push is the lock.
  3. Branch naming: feat/op-pr<NN>-<short-slug>. Open as draft on first push.

Test plan

  • Reviewer reads proposal.mddesign.mdtasks.mdspecs/operator/spec.md in that order.
  • Confirm the four-PR breakdown is reviewable independently and the cluster keeps working after each merge (each PR is additive or strict-loosening).
  • Confirm backwards-compat checklist in design.md: existing sol-corpus and rhoai-corpus samples still apply clean after the schema changes in PR-49.

🤖 Generated with Claude Code

flg77 and others added 2 commits May 8, 2026 23:56
…51)

Audits the operator install path against PRs #34#46 and lays out the
four-PR sequence to land autoresearcher (E1–E6) and coding-split-skills
(D1–D6) on Kubernetes — role enum loosening + webhook catalogue,
ConfigMap-based manifest delivery, MCP server reconciler, and demo
samples + CSV bump.

Also serves as the lock board for two Claude instances coordinating on
the same repo: tasks.md carries a 'claimed by:' slot per task; the push
of a single-file edit is the lock acquisition.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This proposal landed as #48, so the four implementation PRs shift by
one. Real-world demonstration of the lock-board protocol — exactly
what the 'renumber if PR drift' clause was for.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@flg77 flg77 changed the title docs(openspec): operator feature parity for D + E epics (plan for #48–#51) docs(openspec): operator feature parity for D + E epics (plan for #49–#52) May 8, 2026
@flg77
flg77 merged commit e9fa57a into main May 8, 2026
@flg77
flg77 deleted the docs/op-parity-openspec branch May 8, 2026 22:15
flg77 added a commit that referenced this pull request May 9, 2026
feat(operator): API & CRD foundations for D + E parity (PR-49 of #48)
flg77 added a commit that referenced this pull request May 9, 2026
* chore(openspec): claim PR-50 slot from acc1

Lock acquisition for the manifest delivery reconciler PR. Single-file
edit pushed immediately so the other Claude instance (10.199.12.8)
sees the claim on next git pull.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(openspec): renumber to PR-51/52/53 — drift caught

Slot #50 went to an unrelated docs PR
(docs(index): cross-link to acc-podman-desktop extension), so the
manifest delivery PR landed as #51, the MCP reconciler will be #52,
and the demo samples PR will be #53.

Updates tasks.md headings, design.md cross-refs, and proposal.md
PR-slot summary. Local branch name (feat/op-pr50-manifest-delivery)
left as-is — already pushed and the PR is open.

This is the second drift encountered on this openspec change, both
absorbed cleanly by the renumber clause. No content changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* build(operator): sync-manifests target + .gitignore for data mirror

The ManifestDeliveryReconciler ships next on this branch and uses
//go:embed over operator/internal/reconcilers/manifests/data/. embed
paths can't escape the Go module, so the trees have to be mirrored
into the operator subtree at build time.

Adds:
  make sync-manifests  — mirrors ../roles, ../skills, ../mcps into
                         internal/reconcilers/manifests/data/ and
                         strips __pycache__, *.pyc, *.pyo, .DS_Store
                         (so flat-key round-trip k→k.replace("__","/")
                         in the reconciler is safe).

Wires sync-manifests as a prerequisite for: generate, build, run,
test, test-unit, docker-build. Existing developers running any of
those targets get the mirror automatically.

The mirror is gitignored — it's a build artefact, not source.

Verified: 183 files mirrored from the live trees (47 roles ×
~2-3 files + 14 skills + 5 mcps + supporting docs/data). No
__pycache__ leakage.

Refs openspec/changes/20260508-operator-feature-parity-d-e/tasks.md
PR-51 task 1 (build-side prep).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(operator): ManifestDeliveryReconciler — embed.FS to ConfigMaps

Adds operator/internal/reconcilers/manifests/delivery.go: a
SubReconciler that emits three corpus-namespace ConfigMaps holding
the operator-baked roles/, skills/, and mcps/ trees. Agent pods get
these mounted at /etc/acc/{roles,skills,mcps} via volume injection
landing in a follow-up commit on this branch.

Design choices:

  * embed.FS over data/roles, data/skills, data/mcps (mirrored at
    build time by `make sync-manifests`). Build-time embed avoids
    runtime fetches and lets the operator GC ConfigMap ownership
    cleanly via SetControllerReference.

  * ConfigMap data keys flatten "/" to "__" because Kubernetes
    rejects "/" in keys. Round-trip is safe: the sync target strips
    __pycache__ et al, and no real path contains "__". The
    agent_deployment volume's items[] reverses the flatten via
    UnflattenKey() so the in-pod filesystem sees the original tree
    shape.

  * Opt-out gate: spec.manifestDelivery == "none" skips the upsert
    and clears status.manifestDeliveryReady, leaving any
    pre-existing user-managed ConfigMaps alone.

  * Public helpers (FlattenPath, UnflattenKey, ConfigMapName,
    Suffixes, RolesMountPath / SkillsMountPath / MCPsMountPath
    consts) so agent_deployment can reference the same naming and
    path rules without duplicating logic.

Smoke-tested locally: walkTree returns 149 role files, 28 skill
files, 6 mcp files (matches `find ../{roles,skills,mcps} -type f`
after the sync filters), and the round-trip on
coding_agent_implementer/role.yaml is byte-stable.

Refs openspec/changes/20260508-operator-feature-parity-d-e/tasks.md
PR-51 task 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(operator): wire ManifestDeliveryReconciler into chain (slot 2)

Slots the new manifest delivery reconciler immediately after
PrerequisiteReconciler and before UpgradeReconciler. The
acc-{roles,skills,mcps} ConfigMaps must exist before any agent
Deployment is built — slot 2 puts the upsert before the upgrade
pre-checks and before every infra reconciler that doesn't depend on
the manifest tree. Order matches the design.md table for PR-51 wire-in.

Verified: go build ./... and go vet ./... clean.

Refs openspec/changes/20260508-operator-feature-parity-d-e/tasks.md
PR-51 task 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(operator): inject manifest volumes + ACC_*_ROOT env in agent pods

Wires the corpus-scoped acc-roles, acc-skills, and acc-mcps ConfigMaps
emitted by ManifestDeliveryReconciler into every agent pod via:

  /etc/acc/roles   ← corpus.Name + "-acc-roles"   ConfigMap
  /etc/acc/skills  ← corpus.Name + "-acc-skills"  ConfigMap
  /etc/acc/mcps    ← corpus.Name + "-acc-mcps"    ConfigMap

  ACC_ROLES_ROOT=/etc/acc/roles
  ACC_SKILLS_ROOT=/etc/acc/skills
  ACC_MCPS_ROOT=/etc/acc/mcps

The Volume sources use an explicit items[] projection list — keys are
read from the live ConfigMap and projected via
manifests.UnflattenKey(key) so the in-pod filesystem sees the original
slash-separated paths instead of the flattened "key__like__this"
ConfigMap data keys.

Behavioural choices:

  * spec.manifestDelivery == "none" returns empty slices — no mounts,
    no env vars. Lets users bake the trees into a custom agent image
    if they prefer.

  * If a ConfigMap is not yet present at agent_deployment time, that
    tree's mount is skipped (not errored). The manifest reconciler
    runs earlier in the parent chain so this only happens during the
    first reconcile pass; the next cycle picks it up cleanly.

  * Reads CM data from the API client, not from any cached structure,
    so adding a new role at runtime (regenerate + redeploy operator)
    propagates into the items[] list and triggers a Deployment update
    via the Upsert MergeFrom patch.

go build ./... and go vet ./... clean.

Refs openspec/changes/20260508-operator-feature-parity-d-e/tasks.md
PR-51 task 4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(operator): TUI sample mounts acc-roles + acc-skills ConfigMaps

Closes the parity gap with container/production/podman-compose.yml:464
(TUI service, ACC_ROLES_ROOT=/app/roles): the operator-managed TUI
Deployment now reads the same operator-baked roles/, skills/ trees
that agent pods do, so the Ecosystem screen has data to render in
operator-mode just as it does in compose-mode.

Adds:
  env vars  ACC_ROLES_ROOT=/etc/acc/roles, ACC_SKILLS_ROOT=/etc/acc/skills
  mounts    /etc/acc/roles  ← {corpus}-acc-roles  ConfigMap (read-only)
            /etc/acc/skills ← {corpus}-acc-skills ConfigMap (read-only)

The ConfigMap volumes are mounted with optional: true so first-apply
races against the manifest reconciler don't ImagePullBack the TUI;
the next reconcile cycle resolves both objects cleanly.

Documented caveat in the file header: the operator flattens "/" → "__"
in CM keys (Kubernetes rejects "/"), so without an items[] projection
the TUI sees flat-keyed entries. Acceptable for the Ecosystem screen
which only enumerates role names; a TUI screen needing the nested
shape should call the role_loader's operator-mode helper that splits
"__" back to "/" — tracked separately.

Refs openspec/changes/20260508-operator-feature-parity-d-e/tasks.md
PR-51 task 5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(operator): unit coverage for manifest delivery reconciler

Adds two test files:

  internal/reconcilers/manifests/delivery_test.go  (white-box, 4 tests)
    - walkTree returns the right keys for a known persona spread
      (analyst legacy, coding_agent_implementer D3, research_planner E4)
    - round-trip safety: every flat key unflattens back to a valid path
      with no spurious "/" introductions, across all three trees
    - FlattenPath / UnflattenKey direct round-trip on six explicit cases
    - Suffixes() returns the exact strings agent_deployment relies on

  test/unit/manifest_delivery_test.go  (black-box, 4 tests)
    - End-to-end Reconcile against a fake controller-runtime client:
      asserts three corpus-scoped ConfigMaps are created with non-empty
      Data and the operator-managed manifest-tree label
    - ConfigMap keys never contain "/", and unflatten produces multi-
      segment paths (proving the projection contract holds)
    - spec.manifestDelivery="none" short-circuits the reconciler:
      no CMs created, status.ManifestDeliveryReady stays false
    - Idempotency: two Reconcile calls leave Data sizes equal

go mod tidy was needed (fake client pulled in
gopkg.in/evanphx/json-patch.v4 as an indirect dep — already present
in go.sum via transitive github.com/evanphx/json-patch).

Refs openspec/changes/20260508-operator-feature-parity-d-e/tasks.md
PR-51 task 6.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(openspec): mark PR-51 tasks complete

All seven PR-51 tasks (1 build prep + 6 plan items) landed across
commits baa60f0, 72a8650, 93783ee, a6ac7c1, adf1f90, 6ba5b0f. Updates
the lock board to status=ready-for-review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77 added a commit that referenced this pull request Jun 11, 2026
…47, #48) (#59)

* feat(demos): PR-DEMO1 — coding + financial demo collectives (proposal 018)

Two runnable demo collectives + a parent hosting both as sub-collectives,
showcasing the proposal-019 catalog-aware assistant routing prompts to
the genuinely best-matched specialist.

examples/collectives/:
  - demo-financial.yaml — the financial-specialist demo the operator
    asked for: assistant/orchestrator/reviewer/compliance_officer control
    plane + financial_analyst, fpa_analyst, contract_analyst,
    risk_compliance_analyst, account_executive, business_analyst from
    @acc/business-roles.
  - demo-coding.yaml — coding + devops from @acc/workspace-roles +
    @acc/devops-roles.
  - demo-multi.yaml — parent hub hosting both as managed sub-collectives
    (AoA-P3); hub assistant delegates by domain.

All three validate against the CURRENT schema — the proposal-018 draft
used operating_mode:, per-agent workspace_access:, autonomous_loop:, and
sub-collective path:, NONE of which exist on CollectiveSpec/AgentSpec/
SubCollectiveSpec (extra='forbid').  Shipped YAMLs use only real fields
+ real models.yaml ids (claude-haiku workers, claude-sonnet reviewer).

tests/test_demo_collectives.py — 13 tests: all three load, every agent
role resolves (CONTROL + installed packs), required_packages declared,
finance specialists present, sub-collectives wired, models registered.

docs/DEMOS.md — operator runbook showing the 019 capabilities live
(catalog_query routing rationale, PROPOSE_SPAWN/INFUSE, ROLE_GAP).

Deferred (proposal 018 PR-DEMO2..4): golden-prompt suite, WorkflowGraph
+ Prompt-pane Workflow tab.  Branched off main — independently mergeable.

Sweep: 3074 passed, 69 skipped (delta +13).

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

* feat(demos): demo golden prompts incl. the MOTD regression guard (proposal 018)

Four hand-authored golden prompts in the existing PR-K schema, flat in
examples/golden_prompts/ so the Diagnostics-pane runner picks them up —
the operator's "added to our prompt history within the golden prompts;
benchmark against after a role or model change."

  - demo_coding_motd_playbook.yaml — the exact MOTD/Ansible scenario
    that opened the autonomy investigation, pinned as a re-runnable
    benchmark (target devops_engineer).  Permanent regression guard.
  - demo_coding_unit_test.yaml — coding_agent writes a pytest.
  - demo_financial_runway_forecast.yaml — financial_analyst forecast.
  - demo_financial_contract_risk.yaml — contract_analyst risk memo.

Each targets the specialist role directly (stable benchmark, not the
model-dependent assistant routing output) and asserts reply_non_empty +
domain keyword content.  Richer MOTD assertions (dnf-not-pip, no-OS-hedge)
need proposal-016 perception + a negative-match expects field — tracked
there, not asserted here.

tests/test_demo_golden_prompts.py — 9 tests (load + schema-valid +
target real roles + MOTD scenario pinned).  Existing golden-suite tests
use tmp_path, so adding files to examples/golden_prompts/ doesn't
perturb them.

Sweep: 3083 passed, 69 skipped (delta +9).

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

* docs: proposal 019 (assistant as system operator) + demo walkthrough (#48)

Full implementation documentation + lighthouse test runbook for the
proposals 016-019 work (PRs #42-#47), with TUI screenshots captured via
the acc-tui-docs screenshot tool.

docs/proposal-019-screens/:
  - walkthrough.md — what shipped (catalog_query skill, PROPOSE_INFUSE
    authorization, role-gap discovery, demo collectives, demo golden
    prompts), the operator workflow across panes with "behind the
    scenes" NATS/arbiter/cognitive-core mechanics, and a step-by-step
    "how to test on lighthouse" runbook (deploy demo-financial.yaml →
    catalog-aware routing → gap/infusion paths → golden-prompt
    benchmarks → sub-collective multi demo).
  - scenario.yaml — reproducible tui_screenshots scenario (the durable
    artifact; re-run on UI change).
  - 01_prompt_financial.svg, 02_ecosystem_assistant.svg,
    03_compliance.svg, 04_diagnostics.svg — headless Textual renders
    (wiring/layout; data screens show empty state — captioned honestly).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

---------

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