Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

188 lines
8.5 KiB
Markdown

# OpenSRE architecture
How the OpenSRE codebase is structured: the seven first-party packages, what
each is responsible for, and which may depend on which. These dependency rules
are CI-enforced (`make check-imports`), so they are real invariants rather than
aspirations.
## The layer stack
The packages sit in four tiers. **Higher tiers may import lower tiers; a lower
tier may never import a higher one.** Packages on the same tier are peers — the
last column says whether peers may import each other.
| Tier | Packages | May import | Must never import | Peer rule |
| --- | --- | --- | --- | --- |
| 1 (top) | `surfaces`, `gateway` | `tools`, `integrations`, `core`, `platform`, `config` | — | Independent: must not import each other. |
| 2 | `tools` | `integrations`, `core`, `platform`, `config` | `surfaces`, `gateway` | May use an integration's client, so `integrations` effectively sits below it. |
| 2 | `integrations` | `core`, `platform`, `config` | `tools`, `surfaces`, `gateway` | Must never import `tools`; stays reusable below the tool layer. |
| 3 | `core`, `platform` | `config` | `surfaces`, `gateway`, `tools`, `integrations` | Siblings: **may** cross-import each other. |
| 4 (bottom) | `config` | — (nothing first-party) | everything above | Independent — imports no other first-party package. |
The shortcut: **dependencies point downward only.** A surface can reach all the
way down; `config` can reach nothing. The single deliberate exception is
`core ⟷ platform`, a mutually-dependent pair by design (see below).
```mermaid
flowchart TD
subgraph T1["Tier 1 — surfaces"]
SURFACES[surfaces]
GATEWAY[gateway]
end
subgraph T2["Tier 2 — capability"]
TOOLS[tools]
INTEGRATIONS[integrations]
end
subgraph T3["Tier 3 — runtime + platform"]
CORE[core]
PLATFORM[platform]
end
subgraph T4["Tier 4 — config"]
CONFIG[config]
end
SURFACES --> TOOLS
SURFACES --> INTEGRATIONS
GATEWAY --> TOOLS
GATEWAY --> INTEGRATIONS
TOOLS --> CORE
TOOLS --> PLATFORM
INTEGRATIONS --> CORE
INTEGRATIONS --> PLATFORM
CORE <--> PLATFORM
CORE --> CONFIG
PLATFORM --> CONFIG
```
The arrows show edges between **adjacent** tiers to keep the diagram readable.
The actual rule is broader: a tier may import **any** tier below it, not only
the one directly beneath — so a surface may import `config` directly, and a
tool may import `platform`. Refer to the "May import" column above for the
complete set of allowed edges.
## The layers in detail
### Tier 1 — `surfaces` and `gateway`
The entry points a human or an external system talks to. Nothing first-party
may import from here, so a surface can be added or removed without touching the
layers below it.
- **`surfaces/`** — one folder per UI/client: `surfaces/cli` (the stateless
`opensre <command>` runner), `surfaces/interactive_shell` (the stateful
REPL), `surfaces/slack_app` (Slack bot), and `surfaces/shared` for code two
or more surfaces use. A surface owns its own I/O, prompts, and presentation,
and composes lower layers to do the actual work.
- **`gateway/`** — the standalone messaging gateway for inbound chat platforms
(`gateway/polling`, `gateway/session`, `gateway/storage`). A peer of
`surfaces`, not a child: the two never import each other.
### Tier 2 — `tools` and `integrations`
The capability layer — "do a thing against the outside world" — split by
responsibility:
- **`integrations/`** — the boundary for **user config and external clients**:
per-vendor config normalization, verification (`verifier.py`), API clients
(`client.py`), the store/catalog that resolves credentials, and
integration-local helpers. One folder per vendor (`integrations/datadog`,
`integrations/grafana`, `integrations/github`, …) plus cross-cutting pieces
like `integrations/hermes` and `integrations/llm_cli`.
- **`tools/`** — the **agent-callable** boundary: every `@tool(...)` function
and `BaseTool` subclass, the tool registry, framework subsystems
(`tools/investigation`, `tools/interactive_shell`), `tools/system/` for
tools with no vendor in their domain purpose (`fleet_monitoring`,
`python_execution_tool`, `sre_guidance_tool`, `watch_dog`), and
`tools/cross_vendor/` for tools whose logic spans 2+ vendor integrations
(`fix_sentry_issue`). See
[tool-placement-policy.md](tool-placement-policy.md) for the full decision
rule, including when a tool belongs under `integrations/<vendor>/tools/`
instead. A tool is what the planner selects and the runtime executes.
The import rule between them is one-directional: `integrations` must never
import `tools` (or `surfaces`), so a vendor client never depends on the agent
layer and stays reusable on its own. The reverse edge is allowed and common — a
tool reaches an integration's client for external data — so `integrations`
effectively sits one step below `tools` in the dependency graph. Do **not**
reintroduce top-level `vendors/` or `services/` packages — external-system code
belongs in `integrations/`, agent-callable code in `tools/`.
### Tier 3 — `core` and `platform`
The shared runtime and cross-cutting services the capability layer is built on.
- **`core/`** — the provider-agnostic agent runtime: the think → call tools →
observe loop (`core.agent.Agent`), agent/investigation state (`core/state`) and
context-budget enforcement (`core/context_budget.py`), the tool framework primitives
(`core/tool_framework`), shared LLM clients (`core/llm`), agent-harness
session handling (`core/agent_harness`), and pure domain rules (`core/domain`).
- **`platform/`** — cross-cutting services with no investigation logic of their
own: guardrails, masking, sandbox, analytics, auth, notifications,
observability, scheduler, and deployment. It deliberately shadows the stdlib
`platform` name and re-exposes it, so `import platform` still works.
These two are the one bidirectional pair by design: `core` reaches `platform`
for guardrails, masking, observability, and evidence/log compaction, while
`platform` reaches back into `core` for the shared state and session types
(`core.state`, `core.agent_harness.session`). Splitting them into
separate tiers would forbid that edge, so they share a tier as siblings.
### Tier 4 — `config`
The floor: shared constants, prompts, and UI theme. Everything above may
read from `config`, but `config`
imports no other first-party package — keeping it a leaf means constants can be
imported anywhere without dragging runtime along.
## Cross-layer flows
Two worked examples showing how control descends the stack and results flow back
up. Arrows only ever cross a boundary downward.
### An investigation from the CLI
```mermaid
flowchart LR
A["surfaces/cli\n opensre investigate"] --> B["tools/investigation\n capability + lifecycle"]
B --> C["core\n Agent runtime, context budget, LLM"]
B --> D["integrations\n vendor clients + credentials"]
C --> E["platform\n guardrails, masking, sandbox, observability"]
B --> F["config\n prompts + constants"]
```
1. `surfaces/cli` parses the command and hands off to the investigation
capability in `tools/investigation` — the surface never runs pipeline logic
itself.
2. `tools/investigation` drives the six-stage pipeline (see
[`investigation-pipeline-architecture.md`](investigation-pipeline-architecture.md)),
asking `core` to run the ReAct loop and select/execute tools.
3. Evidence-gathering tools reach `integrations` for vendor clients and resolved
credentials; `core` and `platform` supply the runtime, guardrails, and
masking around every call.
4. The structured diagnosis flows back up to the surface, which owns how it is
presented or delivered.
### An inbound gateway message
```mermaid
flowchart LR
A["gateway/polling\n inbound chat message"] --> B["gateway/session + storage\n resolve conversation state"]
B --> C["tools + core\n run the requested capability"]
C --> D["platform\n notifications, observability"]
```
`gateway` receives a message, resolves session state from its own storage, then
composes the same tier-2/tier-3 capability code a surface would — without ever
importing `surfaces`, since the two are independent tier-1 peers.
## Related docs
- [`AGENTS.md`](https://github.com/Tracer-Cloud/opensre/blob/main/AGENTS.md) —
repo map and per-area "files to touch" guides.
- [`investigation-pipeline-architecture.md`](investigation-pipeline-architecture.md)
— how a single investigation runs end-to-end within the `tools` + `core`
layers.