A C4-style view of SYRIS as a modular monolith, its runtime topology, and the seams designed for future extraction.
syris/
├── core/
│ └── syris_core/
│ ├── pyproject.toml
│ └── src/syris_core/
│ ├── main.py # Boot: wire loops + API
│ ├── schemas/ # Pure Pydantic v2 — no DB, no logic
│ │ ├── events.py # MessageEvent, RoutingDecision
│ │ ├── tasks.py # Task, Step
│ │ ├── tools.py # ToolCall, ToolResult
│ │ ├── audit.py # AuditEvent
│ │ ├── approvals.py # Approval
│ │ ├── safety.py # AutonomyLevel, RiskLevel enums
│ │ └── common.py # shared value types
│ ├── pipeline/ # Thin stage orchestrators
│ │ ├── normalizer.py
│ │ ├── router.py
│ │ ├── executor.py
│ │ └── runner.py # Main pipeline loop
│ ├── routing/ # Router internals
│ │ ├── filters.py # Hard filters: spam, quiet hours
│ │ ├── fastpath.py # Deterministic intent DSL
│ │ ├── rules_eval.py # Rules engine evaluation
│ │ └── llm_fallback.py # LLM — last resort only
│ ├── tasks/ # Task engine
│ │ ├── engine.py
│ │ ├── step_runner.py
│ │ ├── state.py # State machine enforcement
│ │ └── recovery.py # Restart reconciliation
│ ├── tools/ # Tool runtime
│ │ ├── registry.py
│ │ ├── executor.py # Gates + idempotency + audit
│ │ ├── idempotency.py
│ │ ├── adapter.py # BaseTool ABC
│ │ └── builtin/noop.py
│ ├── integrations/
│ │ ├── inbound/base.py # InboundAdapter ABC
│ │ ├── outbound/base.py # OutboundAdapter ABC
│ │ └── mcp/ # Milestone 6
│ │ ├── connection.py
│ │ ├── provider.py
│ │ ├── adapter.py
│ │ └── trust.py
│ ├── scheduler/
│ │ ├── scheduler.py
│ │ ├── watchers/
│ │ │ ├── base.py
│ │ │ └── heartbeat.py
│ │ └── rules/
│ │ ├── engine.py
│ │ └── models.py
│ ├── safety/
│ │ ├── autonomy.py
│ │ ├── risk.py
│ │ ├── gates.py
│ │ └── dryrun.py
│ ├── observability/
│ │ ├── audit.py # AuditWriter — sole emit point
│ │ ├── projections.py # Sync updaters (in-transaction)
│ │ ├── health.py
│ │ └── alarms.py
│ ├── secrets/store.py # get_secret() only
│ ├── storage/
│ │ ├── db.py
│ │ ├── models.py # ORM models (separate from schemas)
│ │ ├── repos/ # One repo per aggregate root
│ │ └── migrations/ # Alembic
│ ├── api/
│ │ ├── app.py
│ │ ├── auth.py
│ │ └── routes/
│ └── workers/ # Milestone 7 skeleton
└── tests/
├── unit/
└── integration/[Inbound Adapters] ──► [normalizer.py] ──► [router.py] ──► [pipeline/executor.py]
│ │ │
│ │ persists MessageEvent + AuditEvent ├─ fast ──► [tools/executor.py]
│ │ ├─ task ──► [tasks/engine.py]
│ │ ├─ gated ──► [safety/gates.py]
│ │ └─ sandbox──► [workers/manager.py]
│
└── Scheduler / Watchers / Rules also emit events into normalizerControl Plane (always-on process)
├── Ingestion loops (webhooks / pollers)
├── Scheduler loop
├── Watcher loop
├── Task engine loop (claim → execute → checkpoint)
└── API server (FastAPI + uvicorn)
Worker(s) (optional, gated)
└── Sandbox jobs; heavy analysis; artifact productionprojections.py updaters run synchronously today; can be replaced by an async projector without changing callers. See observability/projections.