afv-library/skills/agentforce-architecture-analyze/references/architecture_sections.md

8.3 KiB

architecture.md section reference

Per-section rendering spec for scripts/render_architecture.py::render. One # Architecture H1, seven numbered ## N. ... sections, plus one conditional "Dependency graph" appendix. Source of truth: the metadata_tree.json schema produced by scripts/parse_wave.py at the end of phase 9.

Source of truth: the live tree — field shapes evolve as parse_wave learns new agent generations. When this doc disagrees with the metadata_tree.json written by parse_wave.py for an actual agent on your machine (under ~/.vibe/data/agentforce-architecture-analyze/<org>/<agent>__<ver>/), trust the live tree.

The Mermaid templates live at assets/mermaid/*.mmd and are the sole consumer of the renderer helpers; each {{PARAM}} contract is documented in the template's own header comment.


Per-diagram node caps

Default caps (override via render(..., max_mermaid_nodes={...})):

Diagram kind Default cap Over-cap behaviour
flowchart 200 summary placeholder + top-5 fan-out + catalog pointer
stateDiagram 40 summary placeholder (no fan-out — states are not nodes)
sequenceDiagram 60 summary placeholder + top-5 fan-out
graph 100 summary placeholder + top-5 fan-out

Cap is measured in rendered elements (nodes + edges for flowchart/graph, messages for sequenceDiagram, states + transitions for stateDiagram). Above cap, the renderer emits a > [diagram truncated: ...] blockquote with the element count, the top-5 nodes by fan-out (when applicable), and a pointer to the catalog section that enumerates the same data without compression.


1. Header + agent overview

Purpose: identify the agent and its planner in a single kv table.

Input fields (tree.agent.*):

  • api_name — agent developer name
  • versionv<N> label
  • master_label — human-readable name
  • description — prose summary
  • agent_typeEinsteinAgentKind / EinsteinCopilotForSalesforce / …
  • typeExternalCopilot / InternalCopilot / …
  • agent_template
  • bot_source
  • generationclassic / nga / search / byop
  • planner_name
  • planner_type
  • bot_id

Plus tree._schema_version.

Output shape: # <H1> with api_name + version, followed by a 2-col markdown table.

Empty/degenerate cases:

  • Missing api_name / version renders ? in the H1 (not None).
  • Any missing field renders - in its row — not empty, because GitHub table rendering collapses empty cells and the row loses alignment.

2. Anatomy summary

Purpose: one-paragraph executive summary plus health callouts.

Input fields:

  • tree._kind_counts — preferred source for topic / action / flow / apex / prompt counts.
  • tree.depth, tree.node_count — size metrics.
  • tree._partial, tree._partial_reason — health flag + prose reason.
  • tree._pending_fetches{"FLOW":[...],"APEX":[...], "PROMPT_TEMPLATE":[...],"STANDARD_ACTION":[...]}. Count determines the "pending fetches: N" line in the callout.
  • tree._unresolved — triggers a second warn callout with the count.
  • tree.agent.planner_name — missing -> warn callout.

Output shape: ## 2. Anatomy summary + paragraph + zero-to-three blockquote callouts. Callouts render as > **Health: PARTIAL.** / > **Health: WARN.** prefixes with bullet sub-lines.

Empty/degenerate cases: if _kind_counts is absent, the walker supplies counts from its own pass over the tree. Zero topics is valid (SequentialPlannerIntentClassifier).


3. Action tree

Purpose: the full declared action tree as a flowchart with per-topic subgraphs, plus a deterministic ASCII appendix for diff review.

Input fields:

  • Walker-derived topics[] -> one subgraph per topic.
  • Walker-derived edges[] -> parent_api_name --> child_api_name.
  • node._cycle_back_to -> dotted back-edge A -.->|cycle_back_to: X| B.
  • Planner-level actions (top-level GEN_AI_FUNCTION with no parent topic) -> synthetic _plannerActions subgraph.

Output shape: ```mermaid block with flowchart TB + subgraphs

  • edges, followed by a <details> with ASCII-tree appendix. When above cap, the mermaid block is replaced with the truncation placeholder; the ASCII appendix still renders.

Empty/degenerate cases:

  • No topics, no planner actions -> %% no topics + %% no edges mermaid comments; diagram still parses.
  • Cycle annotations render in both the mermaid (dotted edge) and the ASCII appendix ([cycle] marker on the node line).

4. Topic anatomy

Purpose: per-topic detail dump. One H3 per topic with a bullet list of actions.

Input fields:

  • Walker-derived topics[] with api_name, label, actions.
  • topic.raw.master_label (preferred) or api_name for the label.

Output shape: ## 4. Topic anatomy + one ### \<api_name>` block per topic + kv list (- Label:, - Action count:, - Actions:` with sub-bullets).

Empty/degenerate cases: 0 topics -> _No topics defined (planner exposes actions directly)._ italic fallback. This is the expected case for SequentialPlannerIntentClassifier.


5. Action catalog

Purpose: flat markdown table of every declared action.

Input fields:

  • Walker-derived actions[] with api_name, topic, raw.unwraps_to.

Output shape: 3-col table (Action | Topic | Unwraps to). Unwraps column renders as KIND \api_name`whenunwraps_tois present,-otherwise. Planner-level actions show(plannerAction)` in the topic column.

Empty/degenerate cases: no actions -> _No actions declared._ italic fallback.


6. Data flow / context propagation

Purpose: show which slot values propagate from user utterance through the planner into each action.

Input fields:

  • Walker-derived topics[] and actions[].
  • action.raw.planner_attr.variable_name + planner_attr.data_type — labels the edge A -->|var: Type| B. When absent, the edge is bare.

Output shape: flowchart LR via load_mermaid("data_flow", ...). Skeleton: User -> Planner -> each Topic -> each Action under that topic.

Empty/degenerate cases: no planner_attr metadata -> every edge is bare. 0 topics -> only User --> Planner renders (no action-level edges). Above cap -> truncation placeholder.


7. Flow / Apex / Prompt catalogs

Purpose: per-artifact detail section for every backing flow, apex class, and prompt template referenced by any action.

Input fields:

  • Walker-derived flows{}, apex{}, prompts{}, keyed on api_name.
  • node.signature (or _signature fallback) — signature block.

Output shape: ### Flows / ### Apex classes / ### Prompt templates H3 buckets, each containing #### \<api_name>`+ a fenced signature block orSignature not captured.` fallback. Prompt templates render as a flat bullet list (signature capture is per-template prose, not a flow/apex shape).

Empty/degenerate cases: no backing artifacts in the tree -> _No backing artifacts in tree._ italic fallback.


8. Unresolved refs + artifact pointers

Purpose: surface every _unresolved[] entry and point at the sidecar files the reader can open.

Input fields:

  • tree._unresolved[] — list of {kind, api_name, reason} records.

Output shape: Either a 3-col Kind | Api name | Reason table or an _No unresolved references._ italic fallback. Followed by an ### Artifact pointers sub-heading with a bullet list of relative paths (tree JSON, manifest, summary).

Empty/degenerate cases: always renders — the artifact-pointer list is unconditional.


Conditional: Dependency graph

Purpose: rendered only when tree._unresolved[] is non-empty OR the tree contains cycle annotations. Shows cross-artifact dependencies plus the unresolved nodes as dashed-outline markers.

Input fields:

  • Walker-derived edges[].
  • tree._unresolved[] — each becomes a :::unresolved styled node.
  • Walker-derived cycles[] — each becomes a dotted back-edge.

Output shape: graph LR via load_mermaid("dependency_graph", ...). Includes a classDef unresolved class marker at the bottom of the template so unresolved nodes render with stroke-dasharray.

Empty/degenerate cases: not rendered at all when both conditions are false. Above the graph cap -> truncation placeholder replaces the mermaid block.