Skip to main content
Version: latest

X07 service architecture v1

This document freezes the first public vocabulary for X07-native backend services.

Why this exists​

Traditional backend architecture debates usually start with topology: monolith, modular monolith, microservices, serverless, event-driven services, and so on.

For X07, that is the wrong starting point.

X07 is designed for agentic coding.
That means the architecture should optimize for:

  • deterministic authoring
  • small reviewable units
  • explicit capabilities and trust boundaries
  • topology flexibility
  • operational control after deploy

The four core concepts​

1. Domain Pack​

The Domain Pack is the unit of authoring.

A Domain Pack contains:

  • pure domain kernels
  • schemas and invariants
  • state transition logic
  • fixtures and deterministic tests
  • service manifests
  • one or more Operational Cells

Agents should mostly edit Domain Pack code.

2. Operational Cell​

The Operational Cell is the unit of release, scaling, and trust review.

A cell has:

  • one ingress kind
  • one runtime class
  • one scale class
  • one capability / binding surface
  • one operational entry
  • one trust boundary for release evidence

Examples:

  • HTTP/API cell
  • event-consumer cell
  • scheduled-job cell
  • policy-service cell
  • workflow-service cell
  • MCP/tool cell

3. Topology Profile​

The Topology Profile decides how cells are placed at runtime.

A topology profile may:

  • colocate multiple cells into one deployable
  • split cells into independent deployables
  • choose a target kind such as hosted, Kubernetes, or wasmCloud
  • choose runtime class preferences such as Wasm component vs native process

Topology is data, not architecture religion.

4. Resource Binding​

A Resource Binding maps a logical dependency name to real infrastructure.

Examples:

  • db.primary
  • cache.default
  • msg.orders
  • obj.documents
  • secret.stripe
  • obs.otlp

Code should depend on logical bindings, not cloud-vendor SDKs.

Design principles​

Authoring is not deployment​

The unit an agent edits is not necessarily the unit that gets scaled.

  • authoring unit = Domain Pack
  • assurance unit = Operational Cell
  • runtime unit = topology group / deployment

Pure kernel + effectful shell​

Every service should prefer:

  • a small pure or mostly-pure kernel
  • a thin effectful shell around that kernel

This keeps the certifiable surface small and the operational surface explicit.

Topology late, boundaries early​

X07 should push topology choices later than most human-era service platforms.

Cells and bindings should be explicit immediately.
Co-location vs split deployment should remain a profile-level decision for as long as possible.

Canonical service tree​

Recommended layout for service-oriented X07 projects:

my-service/
x07.json
x07.lock.json
src/
main.x07.json
service/
api.x07.json
worker.x07.json
schedule.x07.json
domain/
order_core.x07.json
billing_rules.x07.json
arch/
manifest.x07arch.json
service/
index.x07service.json
trust/
profiles/
sandboxed_service_v1.json
policy/
run-os.json
tests/
tests.json
domain_core.x07.json

Service manifest v1​

The service manifest is stored in:

arch/service/index.x07service.json

It describes:

  • service identity
  • cells
  • topology profiles
  • binding declarations
  • trust defaults
  • runtime hints for probes, consumer metadata, schedules, rollout, and autoscaling

This is intentionally separate from x07.json:

  • x07.json stays the project/toolchain manifest
  • index.x07service.json becomes the service/runtime manifest

Canonical three-cell example​

One Domain Pack can expose multiple Operational Cells without turning topology into a design-time commitment:

{
"schema_version": "x07.service.manifest@0.1.0",
"service_id": "orders",
"display_name": "Orders",
"domain_pack": {
"id": "orders",
"display_name": "Orders"
},
"cells": [
{
"cell_key": "api",
"cell_kind": "api-cell",
"entry_symbol": "orders.api.main",
"ingress_kind": "http",
"runtime_class": "native-http",
"scale_class": "replicated-http",
"binding_refs": ["db.primary", "obj.documents"],
"topology_group": "frontdoor",
"runtime": {
"probes": {
"readiness": { "probe_kind": "http", "path": "/readyz", "port": 8080 },
"liveness": { "probe_kind": "http", "path": "/livez", "port": 8080 }
},
"rollout": { "strategy": "rolling", "max_unavailable": "25%", "max_surge": "25%" },
"autoscaling": { "min_replicas": 2, "max_replicas": 6, "target_cpu_utilization": 70 }
}
},
{
"cell_key": "events",
"cell_kind": "event-consumer",
"entry_symbol": "orders.consumer.main",
"ingress_kind": "event",
"runtime_class": "native-worker",
"scale_class": "partitioned-consumer",
"binding_refs": ["db.primary", "msg.orders"],
"topology_group": "async",
"runtime": {
"event": {
"binding_ref": "msg.orders",
"topic": "orders.created",
"consumer_group": "orders-workers",
"ack_mode": "manual"
},
"probes": {
"readiness": { "probe_kind": "exec", "command": ["check-consumer", "--ready"] },
"liveness": { "probe_kind": "exec", "command": ["check-consumer", "--alive"] }
},
"rollout": { "strategy": "rolling", "max_unavailable": "1" },
"autoscaling": { "min_replicas": 1, "max_replicas": 8, "target_inflight": 64 }
}
},
{
"cell_key": "settlement",
"cell_kind": "scheduled-job",
"entry_symbol": "orders.settlement.main",
"ingress_kind": "schedule",
"runtime_class": "native-worker",
"scale_class": "burst-batch",
"binding_refs": ["db.primary"],
"topology_group": "async",
"runtime": {
"schedule": {
"cron": "0 */6 * * *",
"timezone": "UTC",
"concurrency_policy": "forbid",
"retry_limit": 3
}
}
}
]
}

The example is one service, one Domain Pack, and three cells. A dev topology can still co-locate those cells, while a production topology can split them later.

Operational Cell shape​

Each cell should declare:

  • cell_key
  • cell_kind
  • entry_symbol
  • ingress_kind
  • runtime_class
  • scale_class
  • binding_refs
  • topology_group
  • runtime

runtime stays additive and target-agnostic:

  • runtime.probes describes HTTP or exec probes without baking in a provider object model
  • runtime.event carries the logical bus binding plus topic and consumer-group data for event-consumer
  • runtime.schedule carries cron, retry, and concurrency hints for scheduled-job
  • runtime.rollout and runtime.autoscaling describe first-wedge rollout and scaling hints for runtimes such as Kubernetes

Scale classes​

The initial enum should be:

  • replicated-http
  • partitioned-consumer
  • singleton-orchestrator
  • leased-worker
  • burst-batch
  • embedded-kernel

Runtime classes​

The initial enum should be:

  • wasm-component
  • native-http
  • native-worker
  • embedded-kernel

Binding kinds​

The initial binding kinds should be:

  • postgres
  • mysql
  • sqlite
  • redis
  • kafka
  • amqp (first-wave messaging lane for the built-in consumer and workflow archetypes)
  • s3
  • secret
  • otlp

First-wave archetypes​

The first scaffolded archetypes should be:

  • api-cell
  • event-consumer
  • scheduled-job
  • policy-service
  • workflow-service

What is out of scope for v1​

  • service mesh design
  • multi-region placement
  • vendor-specific cloud primitives in code
  • polyglot workload ingestion
  • generic monolith vs microservice guidance

Stability promise​

This document freezes the vocabulary and the public intent.
It does not claim that every downstream CLI, runtime, and platform surface is already stable.

Expert notes​

Use the architecture vocabulary to separate authoring from deployment pressure.

  • keep Domain Packs small enough that agents can review them as one unit
  • split Operational Cells when ingress, trust, or scaling policies diverge
  • postpone topology choices until operator evidence forces a more concrete deployment shape