# Service Actor, Service Event, and Automation Architecture

> Canonical path: `specs/architecture/service-actor-event-automation.md`
> Status: living-spec
> Scope: durable boundaries between AgentTeam core collaboration, service actors, service event delivery, and AgentTeam-owned automation.
>
> Related specs:
> - [`specs/identity/identity.md`](../identity/identity.md)
> - [`specs/service/service-actor-platform.md`](../service/service-actor-platform.md)
> - [`specs/service/service-event-delivery.md`](../service/service-event-delivery.md)
> - [`specs/app/app-notification.md`](../app/app-notification.md)
> - [`specs/automation/run-effect-contract.md`](../automation/run-effect-contract.md)
> - [`specs/schedule/schedule.md`](../schedule/schedule.md)
> - [`specs/collaboration/source-projection-delivery.md`](../collaboration/source-projection-delivery.md)
> - [`specs/architecture/service-architecture-migration-cutover.md`](./service-architecture-migration-cutover.md)

## 1. Purpose

AgentTeam separates four responsibilities that previously shared implementation paths:

```text
AgentTeam Core
  workspace / channel / thread / message / task / member / author / source

Service Actor Platform
  runtime service kind: app
  target service kind/contract: service_account
  App ingress/capability patterns: provider webhook, App runtime
  owns service identity, installation, members, capabilities, target bindings,
  webhooks, and service-authored message writes.

Service Event Platform
  current product family: GitHub/Gitea pull request subscriptions
  future families: additional App or provider events
  owns event subscriptions, webhook receipts, delivery ledgers, idempotency,
  delivery status, and delivery effects for service-owned events.

Automation Platform
  current product kind: schedule
  future product kind: workflow
  owns AgentTeam-managed definitions, occurrences, runs, attempts, effects, and audit.
```

The split is intentionally not an event bus. It is a domain ownership contract:
service-owned events use service event delivery; AgentTeam-owned timed or workflow
execution uses automation runs; ordinary service posts use normal message write
plus audit rather than a run ledger.

## 2. Actor, source, and run boundaries

The core actor family remains:

```text
human | agent | service
```

`app` is the current service kind, and every installed App uses an `app`-kind
service actor. Runtime-capable Apps declare `capabilities.runtime`; provider
Apps may instead use provider-specific ingress. Future service products may
register additional service kinds on the same platform rather than introducing
another message author family. `schedule`, `trigger`, `automation`, `provider`,
and external event names are not displayed author families.

Message source explains why a contribution exists. It is separate from the
visible author:

```text
human_compose       -> human-authored contribution
agent_runtime       -> agent-authored contribution
service_direct_post -> service actor wrote directly
service_callback    -> service actor wrote after a callback/action
provider_event      -> service_event_delivery
schedule_run        -> automation_run
future service_run  -> automation_run
```

Only AgentTeam-owned automation creates `automation_runs`:

```text
schedule -> automation_run
future service automation -> automation_run
```

Service event deliveries do not become automation runs. They use their own
service event delivery ledger because the external service actor owns the event
subscription and delivery semantics.

## 3. Service event versus automation

GitHub/Gitea pull request subscriptions are service event subscriptions:

```text
GitHub/Gitea webhook
  -> service webhook receipt
  -> matching service event subscriptions
  -> service event deliveries
  -> service member writes a normal AgentTeam message or task discussion
```

The resulting message source is:

```text
kind = provider_event
refType = service_event_delivery
refId = service_event_delivery.id
```

It must not be represented as a schedule, an automation run, or a generic
trigger run. Agent management uses the App-hosted GitHub/Gitea Extension
actions; storage, runtime, read models, and source projection use the service
event model.

Schedule is AgentTeam-owned automation:

```text
schedule_definition
  -> automation_run(automation_kind=schedule)
  -> normal AgentTeam message or task discussion
```

The resulting message source is:

```text
kind = schedule_run
refType = automation_run
refId = automation_run.id
```

## 4. Direct service posts

A service actor that already has final content posts through the normal message
write path using its service member identity. Direct service posts do not create
an `automation_run` and do not require a `service_event_delivery` unless they are
an effect of a recorded service event. Tool invocation or API audit may record
who acted and which capability was used, but that audit is not the message source
of truth.

App proactive notifications follow this split:

```text
App notification create/update -> service_direct_post + ordinary MessagePlan
Human interactive-card action  -> service_event_delivery to App runtime
```

The notification message remains an ordinary scope message. After its create
transaction commits, the App notification service hands the new message to the
same process-level fanout owner used by ordinary message APIs. That owner
projects browser and unread effects and completes the message outbox; the
durable outbox retains ordinary-message retry and replay semantics. The card
action delivery owns callback/runner attempts and effects, while the linked
business domain owns its object state and version.

## 5. Shared effect contract

`ServiceEventDelivery` and `AutomationRun` are different ledgers, but they share
a common effect contract:

```text
status
idempotency key
attempt count
attempted/completed timestamps
effect kind
effect ref / message id
error code / detail
```

The shared contract keeps idempotency, retries, and diagnostics consistent while
preserving the domain boundary: service event delivery belongs to the service
actor platform; automation runs belong to AgentTeam automation.

## 6. Stable product facades

Trigger-shaped schedule routes and provider-watch App routes remain stable
product vocabulary, but they are thin facades over the canonical schedule and
service-event stores. New product, runtime, storage, DTO, source, Web, desktop,
and guardrail code must use the canonical stores and typed ledger references;
facades must not add storage fallbacks, aliases, replay, or dual writes.
