docs: design the portable solution architect agent
Some checks failed
validation / verify (push) Failing after 10s

Record the direction and build plan for replacing the upstream
google-cloud-solution-architecture skill with a portable agent.

- ADR-0002: Agent Skills are the portable unit of behaviour, loaded by
  the framework's native skill runtime; discovery and grounding use
  each Cloud provider's hosted remote MCP servers.
- ADR-0003: LangGraph holds Execution state, checkpoints and
  interrupts; a ReAct Orchestrator and Specialists run as ADK
  LlmAgents with SkillToolset. Supersedes ADR-0001.
- CONTEXT.md: domain glossary (Execution, Phase, Approval, Revision,
  Orchestrator, Specialist, Deliverable, Dependency, Cloud provider).
- .scratch/solution-architect-agent/spec.md: build spec with the
  dependency graph, Revision rules, tool tiers, MCP allowlists, A2A
  interaction, tests and nine build increments.
- .scratch/phase-pipeline/spec.md: superseded; kept as decision log.
- CLAUDE.md and docs/agents/: agent skill configuration (local
  markdown issue tracker, triage labels, domain docs).
- README.md: direction note; flags current ADK classes as stubs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 18:09:26 +01:00
parent a24a44e28c
commit 4fefe0ab33
11 changed files with 1081 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
---
status: superseded by ADR-0003
---
# LangGraph orchestrates Phases, not Google ADK
Phases are orchestrated by a LangGraph `StateGraph`, as the KAB Workflow Agent standard (`kyndryl-agent-builder/docs/KAB_WORKFLOW_AGENT_IMPLEMENTATION_GUIDE.md`) requires, rather than by Google ADK `Runner`/`LoopAgent`. The earlier "ADK" orchestration was a local compatibility layer that never used the real `google-adk` package, so it added a pretend seam with one adapter and diverged from the platform standard; we deleted it. Real ADK remains welcome *inside* a Phase (e.g. an `LlmAgent` for LLM-driven design) — just not as the thing that sequences Phases.
> **Reopened (2026-09-15).** [ADR-0002](0002-skills-are-the-portable-unit-of-behaviour.md) makes Skills, loaded by a framework's own skill runtime, the portable unit of behaviour. This ADR assumed our code sequences the Phases. If the Skill sequences them instead, the choice here reduces to which skill runtime to wire first, and "ADK only inside a Phase" no longer holds. Still true regardless: the compat stubs are fiction and should go.
## Considered Options
- **Real `google-adk` as orchestrator**: rejected; departs from the KAB workflow standard and would require async event-stream plumbing for no capability LangGraph lacks (conditional edges cover the Review round).
- **Plain in-process pipeline, no framework**: rejected; neither KAB template uses it, and LangGraph already gives us conditional routing and a path to checkpointing if a human approval gate is added later.

View File

@@ -0,0 +1,25 @@
---
status: accepted
---
# Skills are the portable unit of behaviour
This agent exists to replace the [`google-cloud-solution-architecture`](https://github.com/google/skills/blob/main/skills/cloud/google-cloud-solution-architecture/SKILL.md) skill with an agent that runs anywhere. Its solution-architecture behaviour lives in Skills that follow the [Agent Skills specification](https://agentskills.io/specification) (`SKILL.md` plus `references/`, `assets/` and `scripts/`). The agent framework's own skill runtime loads them: Google ADK's `SkillToolset`, or LangChain's skills pattern (Deep Agents `skills=` / `SkillsMiddleware`). Our code supplies the tooling those Skills call on: grounding, IaC validation and environment scanning. It doesn't restate the work the Skills describe.
Google Cloud is the first and, for now, only Cloud provider. Other hyperscalers should be addable as new Skills plus new tooling, without rewriting the agent's core.
## Refinements (2026-09-15)
- **Hybrid sequencing.** Our code owns Phase boundaries and the Approvals between Phases. Within a Phase, the Skill, run by the skill runtime, decides the work. We rejected letting the Skill sequence everything: Phase checkpoints give us resumable, recordable, testable progress. We rejected code-owned Phase bodies because they would bypass the Skill.
- **Hierarchical and ReAct, not linear.** Work isn't a fixed chain. Agents are organised in a hierarchy that follows the dependencies between Deliverables. Work whose dependencies are satisfied may proceed independently, and every agent reasons and acts in a ReAct loop of thought, tool call and observation. An Orchestrator sits above one Specialist per Deliverable, and a Specialist fans out further only where its work splits into independent parts. Code declares the dependency graph, and the Orchestrator chooses what to do next within it. The engine is recorded in [ADR-0003](0003-langgraph-holds-state-adk-agents-reason.md).
- **Interactive by default.** Executions are multi-turn with user Approval, as the upstream Skill requires. A pre-approved mode serves batch and evaluation runs.
- **Vendored upstream Skill.** `google-cloud-solution-architecture` is copied unmodified and pinned to an upstream commit. Our additions live in separate Skills for our own tooling, so upstream changes arrive as a diff.
- **Discovery through the provider's own MCP servers.** Current-state discovery and documentation grounding go through the remote MCP servers each Cloud provider hosts, for example Google Cloud's Resource Manager, Asset Inventory, Compute, GKE and Developer Knowledge servers, and the AWS MCP Server. Code carries no hand-written cloud API clients. Only reviewed read-only MCP tools are exposed, and reading a user's cloud requires their permission.
- **Cloud provider as configuration.** A Cloud provider is a configured bundle of Skills, tools and remote MCP servers. There's no provider interface in code until a second Cloud provider exists, but core module names carry no provider prefix.
## Consequences
- Framework-specific code is confined to wiring a skill runtime and registering tools, so moving to another framework is a new wiring, not a rewrite.
- Skills in `app/skills/` must conform to the specification: kebab-case `name` matching the directory, a `description` of when to use the Skill, and no custom `phase:` key. They don't today.
- This reopens [ADR-0001](0001-langgraph-orchestrates-phases-not-google-adk.md) and the Phase pipeline spec (`.scratch/phase-pipeline/spec.md`). [ADR-0003](0003-langgraph-holds-state-adk-agents-reason.md) settles the engine and supersedes ADR-0001.
- Both known skill runtimes are young: ADK marks Skills *Experimental* (Python ≥ 1.25.0), and Deep Agents skills are new. Pin versions.

View File

@@ -0,0 +1,25 @@
---
status: accepted
supersedes: ADR-0001
---
# LangGraph holds Execution state; ADK agents reason and act
An Execution is a hierarchy of ReAct agents shaped by the dependencies between Deliverables ([ADR-0002](0002-skills-are-the-portable-unit-of-behaviour.md)).
- **LangGraph holds the Execution.** A LangGraph `StateGraph` holds the dependency graph and each Deliverable's state. It checkpoints after every step and pauses with `interrupt()` whenever the user must answer or approve. This follows the KAB workflow standard and the platform's `langgraph-workflow-agent`.
- **ADK agents reason and act.** The Orchestrator and every Specialist is an ADK `LlmAgent`, each running its own ReAct loop, with a `SkillToolset` for progressive Skill loading. This follows the platform's `google-adk-base-agent/app/skills_integration.py`.
- **Agents sit behind one interface.** Each agent runs behind a single agent-runtime interface, so LangChain Deep Agents can be added as a second implementation without touching the graph.
The dependency graph is declared as data in code. The Orchestrator picks what to do next through tools that refuse work whose dependencies aren't met. Dependencies are guaranteed by code, while ordering and parallelism are the model's choice.
## Considered Options
- **ADK end to end** (root `LlmAgent` with `sub_agents`/`AgentTool`, and ADK sessions for pauses): rejected. It departs from the KAB workflow standard, and LangGraph's checkpointed `interrupt()` is the proven platform path for resumable user Approvals.
- **Deep Agents end to end** (`create_deep_agent(skills=, subagents=)`): viable, and it compiles to LangGraph. It was deferred rather than rejected: ADK `SkillToolset` already has working prior art on this platform, and Deep Agents stays reachable as the second implementation of the agent-runtime interface.
- **Code runs the dependency graph with no Orchestrator model**: rejected. The top level wouldn't be ReAct, and the Skill's conversational flexibility (such as skipping work the user says is already approved) would need hand-coding.
## Consequences
- There are two frameworks in one process. Framework types stay inside the agent-runtime implementation and never appear in graph state.
- ADK Skills are *Experimental* (Python ≥ 1.25.0), so pin the version.