feat(capability): LLM parser + TUI Ecosystem live tables + how-to docs (Phase 4.4) - #8
Merged
Merged
Conversation
…how-to docs (Phase 4.4)
Closes the Phase 4 ladder: roles can now ACTUALLY invoke skills + MCP
tools through governed entry points, the TUI surfaces every loaded
capability live, and operators have step-by-step docs for adding
either kind.
acc/capability_dispatch.py (new)
parse_invocations(text) — strict regex extraction of every
[SKILL: <id> {<json>}] and [MCP: <server>.<tool> {<json>}] marker
in LLM output. Order-preserving (skills + MCPs interleave by
source position), single-line per marker, JSON args validated
via stdlib json. Malformed args captured as args_error rather
than raised so one bad marker doesn't drop neighbours.
dispatch_invocations(invs, core, role) — runs each parsed marker
through CognitiveCore.invoke_skill / invoke_mcp_tool (so Cat-A
A-017/A-018 fire before the adapter executes). Every exception
path funnels into InvocationOutcome.error so the agent task loop
has one shape to render in TUI / audit logs; one bad marker
never raises out of the dispatcher.
acc/agent.py
_handle_task: after process_task returns, parse the output for
capability markers, dispatch them, fold the (kind, target, ok,
error) tuples into the TASK_COMPLETE payload's new "invocations"
field. Full result dicts stay in the LanceDB episode (reachable
by episode_id) — the bus payload only carries summary metadata.
No-op when result.blocked or result.output empty.
acc/cognitive_core.py
build_system_prompt: the "Available skills" / "Available MCP
servers" blocks added in PR 4.3 now also document the
[SKILL:...] / [MCP:...] marker grammar so the LLM knows the
exact shape capability_dispatch will recognise.
acc/tui/screens/ecosystem.py
Replaces the two roadmap Static placeholders with live DataTables:
SKILLS table: Skill | Version | Risk | Requires
MCP SERVERS table: Server | Transport | Risk | Tools
Both populated at mount via SkillRegistry / MCPRegistry .load_from()
with $ACC_SKILLS_ROOT / $ACC_MCPS_ROOT discovery. Risk-level cells
carry colour markup (LOW=green / MEDIUM=yellow / HIGH=red /
CRITICAL=bold red), matching the Compliance screen palette.
Empty registries render a "no skills loaded — see howto-skills.md"
guidance row instead of a blank table. Lazy imports keep TUI
startup unchanged when acc.skills / acc.mcp are absent (e.g. in
the minimal CLI image).
docs/howto-skills.md (new)
Six-step walkthrough: directory layout → manifest → adapter → role
wiring → TUI verification → LLM marker invocation. Documents the
full marker grammar, A-017 enforcement points, CRITICAL oversight
semantics, and a troubleshooting table covering the five most
likely failure modes.
docs/howto-mcp.md (new)
Sister doc covering MCP server integration: prerequisites → manifest
→ role wiring → TUI verification → LLM marker invocation. Field
cheatsheet for every mcp.yaml entry, A-018 enforcement detail,
troubleshooting matrix, and a "when NOT to use an MCP server" note
that points readers back to howto-skills.md when the capability
could be a Skill instead.
Smoke tests (run locally — all green):
* parse_invocations: extracts 3 markers (mixed skill + MCP) in source
order, returns ParsedInvocation list with parsed args.
* Bad JSON: captured as args_error, not raised; marker not dispatched.
* dispatch happy path: returns adapter dict via invoke_skill.
* dispatch denied path: A-017 block surfaces as InvocationOutcome
with ok=False, error="SkillForbiddenError: A-017 blocked ...".
* build_system_prompt: marker grammar examples now appear in the
Available skills / Available MCP servers blocks.
* EcosystemScreen + helpers import cleanly; _risk_cell renders the
expected Rich markup for every level.
Existing test suite: 139 unit tests (config + role-store +
guardrails + compliance, with the lighthouse-OpenSSL-impaired Ed25519
class deselected) pass unchanged.
Phase 4 delivery complete.
flg77
added a commit
that referenced
this pull request
May 20, 2026
Bumps that resolve the open Dependabot alerts on the repo: - uv.lock: urllib3 2.6.3 -> 2.7.0 (#10 decompression-bomb High, #11 cross-origin sensitive headers High) - uv.lock: idna 3.13 -> 3.15 (#13 idna.encode bypass — supersedes Dependabot PR #92) - uv.lock: pytest 8.4.2 -> 9.0.3 (#9 tmpdir-handling CVE; the patched line is pytest 9.x, so pytest-asyncio bumps to 1.3.0 and pytest-cov to 7.1.0) - pyproject.toml: pytest>=9.0,<10 + pytest-asyncio>=1.0,<2.0 widened to let the resolver onto the patched line. - webgui/package.json: vite ^5.4.0 -> ^5.4.21 (#12 .map path traversal). #8 (transformers Trainer-class arbitrary-code execution) cannot be bumped today — the patched line is transformers 5.x but no sentence-transformers release supports transformers 5 yet. We do NOT use Trainer (only the SentenceTransformer encode() API for embeddings), so the vulnerable code is not in our execution path. The sentence- transformers range is widened to `<5.0` so the bump becomes a one-line uv-lock change once ST releases support. Documented in pyproject.toml; GitHub alert #8 to be dismissed with "vulnerable code not in execution path". 42 webgui tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
May 31, 2026
…3.42) (#8) Closes followup #37 IN CODE (not just a proposal). OpenSpec `20260531-orchestrator-repurpose-skills-mcp-specialist` Phase 1 ships the read-only catalog + NATS request/reply query subject. Phases 2–7 deferred behind operator-review gates (recommendation markers, gap analyser, [ROUTE:...] deprecation, marketplace mirror, dreamer M9 ride, final removal). Phase 1 is **purely additive**: existing routing paths (orchestrator's [ROUTE:role:reason] AND Assistant's [PROPOSE_ROUTE]) both keep working unchanged. Future phases retire the legacy marker. What landed: 1. `acc/capability_index.py` — `CapabilityIndex` class. Scans `roles/*/role.yaml` + `mcps/*/mcp.yaml` + (optional) SkillRegistry at boot; deterministic query path with kind/name/domain/task_type/limit filters; revision counter increments on rebuild; SIGHUP-reload on non-Windows. Pydantic v2 models with `extra="forbid"` reject malformed wire requests. Empty roots are non-fatal (slim-edge deploys). 2. `acc/signals.py` — `subject_capability_query(cid)` + `subject_capability_recommend(cid)` (the recommend subject is declared in Phase 1 so consumers can subscribe early; no producer emits until Phase 2). 3. `acc/agent.py` — two coupled hooks: * `_maybe_build_capability_index()` — boot-time, role-gated, builds the index when `self.config.agent.role == "orchestrator"`; logs `capability_index: built at boot revision=1`. * `_handle_capability_query` (inside `_task_loop`) — NATS request/reply handler; unpacks msgpack, validates via Pydantic, queries index, publishes reply on `msg.reply` inbox. 4. `roles/orchestrator/role.yaml` — bumped to `v3.0.0-beta1`. Purpose rewritten (Skills & MCP specialist). New allowed_actions: `capability_query`, `capability_reply`. Phase 1 RETAINS `can_route: true` for backward compat; Phase 4 deprecates with warning + auto-translate; Phase 3 flips it to false once the gap analyser ships. Seed_context narrative explains the repurpose. 5. `tests/test_capability_index.py` — 16 tests covering scan correctness, query filters, Pydantic strictness, revision counter, optional SkillRegistry integration, empty-roots edge case, and the 140-char summary truncation. Tests: - `pytest tests/test_capability_index.py` — 16 passed. - `pytest -k "orchestrator or capability or role_def or signals"` — 175 passed, 3 skipped, 0 failed. - Full sweep `pytest tests/ --ignore=tests/container -x` — **2435 passed, 38 skipped, 0 failed**. Downstream proposals unblocked (when their phases land): - Sub-collective editor Phase 5 — "Suggest skills/MCPs" button queries capability.query. - Dreamer Phase 6 — M9 distilled-skill ingest writes back to the catalog. - Role-package format Phase 5 — marketplace mirror surfaces here. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
May 31, 2026
…wiring (2026-05-31)
New OpenSpec proposal `20260531-assistant-action-loop`. Triggered by
live lighthouse trace 2026-05-31 18:51-18:56 where the Assistant
under AUTO mode (small llama-3.2-3B-FP8 model, v0.3.41 stack):
- Hallucinated non-existent role names (worker-pool, prompt) because
seed_context describes ACC concepts abstractly but doesn't list
what's actually available.
- Asked "which roles do you want to run?" while a coding_agent was
already running in the baseline roster.
- Reasoned correctly ("I will execute Option A, spawning the
agentset") but never emitted a [PROPOSE_SPAWN:...] marker.
Single architectural cause: the cognitive_core has no Observe step.
Every downstream primitive exists (CapabilityIndex shipped v0.3.42 PR
#8, AoA-P2b proposal queue v0.3.27, mode-aware dispatcher AoA-P2a
v0.3.26, sub-collective registry AoA-P3a v0.3.29) — but no wiring
connects them to the LLM call.
Proposal lands in 5 phases:
1. Perception snapshot + system-prompt injection (READY).
2. Hybrid dual-format marker emission (reasoning + JSON action).
3. AUTO contract enforcement (extractor → escalation).
4. Push-based roster snapshot.
5. Reflexion-style reasoning-vs-action reconciliation + SIP reward.
Phase 1 is purely additive: new acc/perception.py + new
subject_roster_snapshot + system-prompt `## Currently available`
block + marker dispatch validation against snapshot roster (rejects
hallucinated target_role).
Brainstorm + open questions captured in
Notes/.../ACC-Assistant-Action-Loop/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
flg77
added a commit
that referenced
this pull request
May 31, 2026
…ion + marker validation (v0.3.43) (#9) OpenSpec `20260531-assistant-action-loop` Phase 1. Today's lighthouse trace (2026-05-31 18:51-18:56, llama-3.2-3B under AUTO mode) showed the Assistant gatekeeper: - Hallucinating `worker-pool` and `prompt` role names (neither exists). - Asking "which roles do you want to run?" while coding_agent was already running in the baseline roster. - Reasoning correctly ("I will execute Option A, spawning the agentset") but never emitting a [PROPOSE_SPAWN:...] marker. Single architectural cause: cognitive_core had no Observe step. Every downstream primitive existed (CapabilityIndex v0.3.42 PR #8, AoA-P2b proposal queue v0.3.27, mode-aware dispatcher v0.3.26, sub- collective registry v0.3.29) — but no wiring connected them to the LLM call. Phase 1 adds the Observe step. Purely additive: non-Assistant roles see zero behaviour change. What landed (+685 / -7): 1. acc/perception.py — new module. `PerceptionSnapshot` Pydantic model with stale flags per source; `snapshot_for_assistant` parallel-fans-out capability_query + roster_snapshot under a 100ms budget; filesystem fallback when orchestrator is unreachable; `validate_marker_target` rejects hallucinated target roles; `render_currently_available_block` emits a token- conscious `## Currently available` block with running agents + available roles + MCPs + sub-collectives + a closing "roles not in this list do not exist" directive. 2. acc/signals.py — `subject_roster_snapshot(cid)`. Phase 1 RPC shape; Phase 4 will swap to push-broadcast. 3. acc/agent.py — two coupled wirings: * arbiter `_subscribe_worker_reconcile` gains a `_handle_roster_snapshot` reply handler that serves the live heartbeat-tracked roster grouped by role. * cognitive_core construction sets `core._bus = self.backends.signaling` (both code paths) so the perception module has a NATS handle. 4. acc/cognitive_core.py — three coupled changes: * `_perception` + `_bus` attributes initialised on __init__. * `_process_task_body` gains an Observe step BEFORE build_system_prompt: when `role_label == "assistant"` AND bus is set, call `snapshot_for_assistant`; assign to `self._perception`. * `build_system_prompt` renders `## Currently available` block from `_perception` if present (same composable pattern as AoA-P3b's sub-collective block). * Marker dispatch validates `target_role` against the snapshot; hallucinated roles (`worker-pool`) are dropped with a WARNING log line BEFORE they reach AoA-P2b dispatch. 5. roles/assistant/role.yaml — bumped to v2.2.0. seed_context gains an explicit "READ THE ## Currently available BLOCK BELOW FIRST" preamble + marker syntax reference + the AUTO-contract reminder ("Explaining without emitting a marker is an AUTO- contract violation"). 6. tests/test_perception_snapshot.py — 13 new tests: * Snapshot happy path (bus + roster reply merge). * Stale capability path (timeout → fallback to filesystem). * No-bus path (early boot / tests). * Sub-collectives pass-through. * `validate_marker_target` — accepts roster + catalog roles; REJECTS the lighthouse trace's `worker-pool` / `prompt` hallucinations. * `render_currently_available_block` — running-agents-first ordering; no duplication of running roles in "Available roles"; stale annotation; sub-collectives with DELEGATE marker hint; 25-role cap with "and N more"; grounding directive at close. Tests: - pytest tests/test_perception_snapshot.py — 13 passed. - pytest -k "cognitive or perception or assistant or marker or proposal or roster or arbiter" — 181 passed, 3 skipped. - Full sweep `pytest tests/ --ignore=tests/container -x` — **2449 passed, 38 skipped, 0 failed** (+14 vs v0.3.42). What this changes about today's trace: Same operator prompt + same small model under AUTO would now produce: - LLM sees `## Currently available` block listing assistant-1, arbiter, coding-1 (real running agents) + the 47 real roles in the catalog. - LLM's "use the worker-pool role" suggestion goes away (no such role in the block + closing directive forbids inventing). - IF the LLM emits `[PROPOSE_SPAWN:worker-pool:...]`, the marker dispatch's snapshot validation drops it with a WARNING. - IF the LLM emits `[PROPOSE_SPAWN:coding_agent:...]` for a role in the catalog, AoA-P2b queues it (ASK_PERMISSIONS default) or dispatches it (AUTO). Marker emission reliability on small models is Phase 2 (dual- format reasoning + JSON action). AUTO-contract enforcement when no marker emitted is Phase 3. Both deferred per proposal. Co-authored-by: Claude Opus 4.7 <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>
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
Closes the Phase 4 ladder. After this PR:
What's in the box
`acc/capability_dispatch.py` (new)
`acc/agent.py`
`_handle_task` now parses + dispatches after `process_task` returns (no-op when the task was blocked or output is empty), and folds the `(kind, target, ok, error)` tuples into the new `invocations` field of the `TASK_COMPLETE` payload. Full result dicts remain in the LanceDB episode (reachable by `episode_id`); the bus payload carries summary metadata only.
`acc/cognitive_core.py`
`build_system_prompt` now documents the marker grammar inside the "Available skills" / "Available MCP servers" blocks added in PR 4.3, so the LLM knows the exact shape the dispatcher will recognise.
`acc/tui/screens/ecosystem.py`
Two roadmap `Static` placeholders replaced with live DataTables:
Risk cells carry Rich colour markup (LOW=green, MEDIUM=yellow, HIGH=red, CRITICAL=bold red), matching the Compliance screen. Empty registries render a "no skills loaded — see howto-skills.md" guidance row instead of a blank table. Lazy imports keep the TUI startup time unchanged when `acc.skills` / `acc.mcp` are absent (e.g. in the minimal CLI image).
`docs/howto-skills.md` + `docs/howto-mcp.md` (new)
Six-step walkthroughs covering: directory layout → manifest → adapter (skills only) → role wiring → TUI verification → LLM marker invocation. Each includes the marker grammar, A-017 / A-018 enforcement detail, CRITICAL oversight semantics, and troubleshooting matrices.
Marker grammar
```
[SKILL: <skill_id> {}]
[SKILL: <skill_id>] # args default to {}
[MCP: <server_id>.<tool_name> {}]
[MCP: <server_id>.<tool_name>] # args default to {}
```
Single-line per marker. Tool names allow dots so nested namespacing (`fs.read`) is preserved. Malformed JSON is logged + skipped, not raised.
Smoke tests (all green locally)
Existing suite: 139 unit tests (config + role-store + guardrails + compliance, with the lighthouse-OpenSSL-impaired `TestEd25519Validation` class deselected) pass unchanged.
Test plan
Phase 4 delivery summary
After this lands, the cell can synthesise organelles in-house (Skills) and admit symbiotic bacteria (MCP servers), the membrane enforces both via Cat-A, and the operator can see both surfaces live from the TUI.