Skip to content

Update outdated README architecture diagram to explain per-turn tool/skill/agent lookup #147

Description

@k5s-bot

Summary

The System architecture Mermaid diagram in README.md (lines ~39–70) is badly outdated. It presents the orchestrator's interaction with Tool/Skill/Agent resources as a static, boot-time picture and therefore fails at what a top-level diagram should do best: explain how the agent looks up the right tool / skill / agent on each turn. The actual per-turn algorithm is well documented in docs/orchestrator.md and apps/agent-orchestrator/README.md, but none of it is visible in the README diagram a newcomer sees first.

Related: #142 was filed earlier today on the same subject. If the maintainers consider that one canonical, this can be closed as a duplicate — logged here because the task that generated it asked for a fresh issue.

What the current diagram gets wrong

Two edges do all the damage:

Orchestrator -->|RAG skill + tool selection| Qdrant
Orchestrator -->|reads CRs at startup| ToolCR & SkillCR
  1. "reads CRs at startup" describes only indexing, not lookup. CRs are embedded into Qdrant at startup and watched live for hot-reload (ADR 0020) — but far more importantly, the diagram gives the impression the catalog is consumed once at boot. The interesting behavior is the per-request resolution loop (the LangGraph graph, docs/orchestrator.md §1), which the diagram never shows.

  2. The per-turn decision path is entirely absent. None of these steps appear:

    • check-active-skill (ADR 0012) — if the conversation already has an active skill, re-fetch it under the caller's current roles and run a cheap Structured-Outputs fit-check. On a fit, retrieval + selection are skipped; a miss falls through to the full path (a miss is not an error).
    • retrieve-skills — similarity search over the skills Qdrant collection, filtered to skills whose derived audience includes the caller.
    • select-skill → load-skill-tools — the chosen skill's tool ids are resolved directly via VectorStore.getByIds (RBAC re-checked as defense-in-depth), not re-ranked by a second semantic search.
    • plan-action — an LLM call (skill markdown as the system prompt) that decides to respond directly or call one of that skill's tools. A turn can end here with no Job launched at all.
  3. RAG skill + tool selection conflates a two-layer design into one flat search. Retrieval is two-layered (ADR 0008): RAG runs over the skills collection; tools are then resolved by id from the selected skill. The label implies a single flat RAG over the whole tool catalog — precisely the design the project moved away from.

  4. RBAC filtering on lookup is invisible. Skills carry no allowedRoles of their own (ADR 0011); a skill's retrieval audience is the intersection of its tools' allowedRoles, computed at index time. The diagram shows no identity/role gating on retrieval.

  5. Sub-agents aren't connected to the turn loop. AgentCR / AgentRunCR sit as loose boxes. The diagram never conveys that a sub-agent is launched by the same launch-job path as a tool — the orchestrator's own image with a narrower task (docs/orchestrator.md §1, §5) — which is the whole point of the "one execution architecture" claim in the README intro.

Proposed change

Update the top-level diagram (or add a second, lookup-focused one) so a reader can trace the per-turn path, roughly:

resolve-identity
  → check-active-skill (ADR 0012)  ──fit──▶ load-skill-tools
        │ miss
        ▼
  retrieve-skills   (RAG over the skills collection, filtered by derived RBAC audience)
        ▼
  select-skill
        ▼
  load-skill-tools  (resolve skill.toolIds directly via getByIds; RBAC re-check)
        ▼
  plan-action  ──respond──▶ done (no Job)
        │ call tool / sub-agent
        ▼
  launch-job  (Tool Job  ·or·  Agent Job = orchestrator image, narrower task)
        ▼
  await-result (HMAC callback) → fold into state → response

Specific asks:

  • Separate startup indexing (Tool/Skill CRs → Qdrant embeddings, watched via ADR 0020) from the per-turn lookup, so "at startup" no longer stands in for the whole catalog interaction.
  • Label the Qdrant edge as the skills RAG collection and show the distinct direct tool-id resolution step.
  • Show the identity → derived-audience filter on skill retrieval (ADR 0011).
  • Show that plan-action can end a turn without launching a Job, and that sub-agents reuse the tool launch path.
  • Consider reusing or linking the existing High-level flow sequence diagram in docs/orchestrator.md so README and design doc stay consistent.

References

  • README.md — System architecture diagram (lines ~39–70)
  • docs/orchestrator.md — High-level flow sequence diagram + §1 Agent core (LangGraph nodes)
  • apps/agent-orchestrator/README.md — "What it does", steps 3–8
  • ADRs: 0008 (skill-mediated / two-layer tool retrieval), 0011 (skill access derived from tools), 0012 (session-scoped skill lifecycle / per-turn fit-check), 0020 (CRD catalog hot-reload via watch)

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions