Includes AirPlan design documents, AircOding-alpha1-plan, AirPlanV2, AirPlan-ParaV2, AirPlan-Para V1 reference docs, and all working code changes across packages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1261 lines
26 KiB
Markdown
Executable File
1261 lines
26 KiB
Markdown
Executable File
# AirCoding Event Payload Registry V1
|
|
|
|
Date: 2026-05-27
|
|
Status: Canonical event and payload registry for V1.0.0 Alpha skeleton
|
|
|
|
This document defines the V1 RuntimeEvent type registry, persistence policy, payload shapes, and producer/consumer rules.
|
|
|
|
Event envelope is defined in `baselineV1.md` and `packages/contracts/event.ts`:
|
|
|
|
```ts
|
|
interface RuntimeEvent<T = unknown> {
|
|
id: string
|
|
type: string
|
|
version: number
|
|
timestamp: string
|
|
session_id: string
|
|
project_id?: string
|
|
source: EventSource
|
|
route: string[]
|
|
payload: T
|
|
}
|
|
```
|
|
|
|
Registry rule:
|
|
|
|
```text
|
|
event_type → payload schema → persistence policy → domain transaction → producer → consumers
|
|
```
|
|
|
|
Event producers must not decide persistence ad hoc. `EventStore` owns persistence policy by event type.
|
|
|
|
## 1. Common Payload Conventions
|
|
|
|
All payloads use snake_case JSON keys to match persisted DB column names and artifact metadata.
|
|
|
|
Common aliases:
|
|
|
|
```ts
|
|
type ISOTimeString = string
|
|
type JsonObject = Record<string, unknown>
|
|
type EventPersistence = "durable" | "ephemeral"
|
|
type EventDelivery = "eventbus" | "eventbus_and_db"
|
|
```
|
|
|
|
Common lightweight references:
|
|
|
|
`EntityRef` is defined in `interface-contracts-v1.md` §4 with the canonical `EntityType` enum (12 values including `capability` and `provider`). This document uses `EntityRef` by reference.
|
|
|
|
```ts
|
|
interface EvidenceLink {
|
|
evidence_ref_id?: string
|
|
artifact_id?: string
|
|
diagnostic_id?: string
|
|
claim: string
|
|
}
|
|
|
|
interface FailurePayload {
|
|
error: AirError
|
|
evidence_refs?: EvidenceLink[]
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
Payloads should contain identifiers needed for routing/querying even when the same identifiers are also extracted into top-level event columns and domain tables.
|
|
|
|
## 2. Persistence and Transaction Rules
|
|
|
|
Persistence categories:
|
|
|
|
```text
|
|
durable → inserted into events table and applied to domain tables in one transaction
|
|
ephemeral → published on EventBus only, not required for crash recovery
|
|
```
|
|
|
|
Rules:
|
|
|
|
1. Durable event insert and corresponding domain table update must happen in the same SQLite transaction.
|
|
2. Ephemeral events may be throttled or coalesced by EventBus/ProjectionStore.
|
|
3. Ephemeral events that become important for diagnosis should be captured as artifacts or durable summaries, not promoted ad hoc.
|
|
4. Streaming deltas are ephemeral; completed message/tool/command records are durable.
|
|
5. `route` is append-only. Forwarders append their route segment; they never rewrite earlier route entries.
|
|
6. `route_text` in SQLite is derived from `route.join("/")` for indexing.
|
|
7. Payload schema changes require incrementing the event `version` for that event type.
|
|
|
|
## 3. Durable Event Registry
|
|
|
|
### 3.1 Session Events
|
|
|
|
#### `session.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Producer: Main Agent / CLI startup.
|
|
|
|
Domain update: insert `sessions` row.
|
|
|
|
```ts
|
|
interface SessionCreatedPayload {
|
|
session_id: string
|
|
project_id: string
|
|
project_root: string
|
|
title?: string
|
|
model_provider_id?: string
|
|
model_id?: string
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `session.archived` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `sessions.status = archived`.
|
|
|
|
```ts
|
|
interface SessionArchivedPayload {
|
|
session_id: string
|
|
reason?: string
|
|
}
|
|
```
|
|
|
|
#### `session.deleted` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `sessions.status = deleted`.
|
|
|
|
```ts
|
|
interface SessionDeletedPayload {
|
|
session_id: string
|
|
reason?: string
|
|
}
|
|
```
|
|
|
|
### 3.2 Message Events
|
|
|
|
#### `user.message.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `messages` row.
|
|
|
|
```ts
|
|
interface UserMessageCreatedPayload {
|
|
message_id: string
|
|
canonical_format: "anthropic"
|
|
content_json: unknown
|
|
parent_message_id?: string
|
|
token_estimate?: number
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `assistant.message.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert/update `message_drafts` row with `status = streaming`.
|
|
|
|
```ts
|
|
interface AssistantMessageStartedPayload {
|
|
message_id: string
|
|
canonical_format: "anthropic"
|
|
parent_message_id?: string
|
|
route?: string[]
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `assistant.message.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `messages` row and delete matching `message_drafts` row.
|
|
|
|
```ts
|
|
interface AssistantMessageCreatedPayload {
|
|
message_id: string
|
|
canonical_format: "anthropic"
|
|
content_json: unknown
|
|
parent_message_id?: string
|
|
route?: string[]
|
|
token_estimate?: number
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `assistant.message.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `message_drafts.status = error` or create failure artifact if draft is absent.
|
|
|
|
```ts
|
|
interface AssistantMessageFailedPayload extends FailurePayload {
|
|
message_id: string
|
|
partial_content_json?: unknown
|
|
}
|
|
```
|
|
|
|
### 3.3 Agent Events
|
|
|
|
#### `agent.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `agents` row with `status = running` or `starting`.
|
|
|
|
```ts
|
|
interface AgentStartedPayload {
|
|
agent_id: string
|
|
agent_type: "executor" | "reviewer" | "debugger" | "compactor" | "experience_miner"
|
|
task_id?: string
|
|
pid?: number
|
|
model_provider_id?: string
|
|
model_id?: string
|
|
workspace_id?: string
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `agent.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `agents.status = completed`.
|
|
|
|
```ts
|
|
interface AgentCompletedPayload {
|
|
agent_id: string
|
|
task_id?: string
|
|
summary: string
|
|
worker_result_ref?: string
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `agent.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `agents.status = failed`.
|
|
|
|
```ts
|
|
interface AgentFailedPayload extends FailurePayload {
|
|
agent_id: string
|
|
task_id?: string
|
|
}
|
|
```
|
|
|
|
#### `agent.lost` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `agents.status = lost`.
|
|
|
|
```ts
|
|
interface AgentLostPayload {
|
|
agent_id: string
|
|
task_id?: string
|
|
last_heartbeat_at?: ISOTimeString
|
|
detection_reason: "heartbeat_timeout" | "process_exit_without_result" | "ipc_broken"
|
|
}
|
|
```
|
|
|
|
#### `agent.cancelled` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `agents.status = cancelled`.
|
|
|
|
```ts
|
|
interface AgentCancelledPayload {
|
|
agent_id: string
|
|
task_id?: string
|
|
reason: string
|
|
}
|
|
```
|
|
|
|
### 3.4 Task Events
|
|
|
|
#### `task.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `tasks` row and optional `task_dependencies` rows.
|
|
|
|
```ts
|
|
interface TaskDependencySpec {
|
|
depends_on_task_id: string
|
|
dependency_type: "hard" | "soft" | "conflict" | "serialization"
|
|
reason?: string
|
|
source?: "architecture" | "scheduler" | "worker" | "user" | "system"
|
|
}
|
|
|
|
interface TaskCreatedPayload {
|
|
task_id: string
|
|
type: "execute" | "review" | "debug" | "compact" | "mine_experience"
|
|
title: string
|
|
task_spec_json: unknown
|
|
dependencies?: TaskDependencySpec[]
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `task.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = running`, set `started_at`, `assigned_agent_id`, `workspace_id`; insert `task_attempts` row.
|
|
|
|
```ts
|
|
interface TaskStartedPayload {
|
|
task_id: string
|
|
agent_id: string
|
|
attempt_id: string
|
|
attempt_index: number
|
|
workspace_id?: string
|
|
}
|
|
```
|
|
|
|
#### `task.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = completed`, set `worker_result_json`, `completed_at`; update `task_attempts`.
|
|
|
|
```ts
|
|
interface TaskCompletedPayload {
|
|
task_id: string
|
|
agent_id?: string
|
|
attempt_id?: string
|
|
worker_result_json: unknown
|
|
summary: string
|
|
changed_files?: string[]
|
|
evidence_refs?: EvidenceLink[]
|
|
}
|
|
```
|
|
|
|
#### `task.blocked` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = blocked`; update `task_attempts` if applicable.
|
|
|
|
```ts
|
|
interface TaskBlockedPayload {
|
|
task_id: string
|
|
agent_id?: string
|
|
reason: string
|
|
blocker_kind: "user_decision" | "architecture_decision" | "environment" | "permission" | "dependency" | "external"
|
|
evidence_refs?: EvidenceLink[]
|
|
suggested_next_step?: string
|
|
}
|
|
```
|
|
|
|
#### `task.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = failed`; update `task_attempts.failure_*`.
|
|
|
|
```ts
|
|
interface TaskFailedPayload extends FailurePayload {
|
|
task_id: string
|
|
agent_id?: string
|
|
attempt_id?: string
|
|
}
|
|
```
|
|
|
|
#### `task.cancelled` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = cancelled`.
|
|
|
|
```ts
|
|
interface TaskCancelledPayload {
|
|
task_id: string
|
|
reason: string
|
|
cancelled_by: "user" | "main" | "scheduler" | "system"
|
|
}
|
|
```
|
|
|
|
#### `task.interrupted` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = interrupted`.
|
|
|
|
```ts
|
|
interface TaskInterruptedPayload {
|
|
task_id: string
|
|
reason: string
|
|
resumable: boolean
|
|
resume_ref?: string
|
|
}
|
|
```
|
|
|
|
#### `task.removed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: delete `tasks` row (only for pending status); insert event record.
|
|
|
|
```ts
|
|
interface TaskRemovedPayload {
|
|
task_id: string
|
|
reason: string
|
|
removed_by: string
|
|
}
|
|
```
|
|
|
|
#### `task.invalidated` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tasks.status = invalidated`; insert event record.
|
|
|
|
```ts
|
|
interface TaskInvalidatedPayload {
|
|
task_id: string
|
|
adr_id: string
|
|
reason: string
|
|
rollback_ref?: string
|
|
}
|
|
```
|
|
|
|
### 3.5 Tool Events
|
|
|
|
#### `tool.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `tool_runs` row with `status = running`.
|
|
|
|
```ts
|
|
interface ToolStartedPayload {
|
|
tool_run_id: string
|
|
tool_name: string
|
|
task_id?: string
|
|
agent_id?: string
|
|
origin_message_id?: string
|
|
input_json: unknown
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `tool.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tool_runs.status = ok`, set output/artifacts/evidence/duration.
|
|
|
|
```ts
|
|
interface ToolCompletedPayload {
|
|
tool_run_id: string
|
|
output_json?: unknown
|
|
duration_ms?: number
|
|
artifact_ids?: string[]
|
|
evidence_refs?: EvidenceLink[]
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `tool.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tool_runs.status = error`.
|
|
|
|
```ts
|
|
interface ToolFailedPayload extends FailurePayload {
|
|
tool_run_id: string
|
|
duration_ms?: number
|
|
}
|
|
```
|
|
|
|
#### `tool.cancelled` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `tool_runs.status = cancelled`.
|
|
|
|
```ts
|
|
interface ToolCancelledPayload {
|
|
tool_run_id: string
|
|
reason: string
|
|
}
|
|
```
|
|
|
|
### 3.6 Command Events
|
|
|
|
#### `command.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `command_runs` row.
|
|
|
|
```ts
|
|
interface CommandStartedPayload {
|
|
command_run_id: string
|
|
task_id?: string
|
|
agent_id?: string
|
|
origin_message_id?: string
|
|
tool_run_id?: string
|
|
command: string
|
|
cwd: string
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `command.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `command_runs.exit_code`, artifact refs, diagnostics, duration.
|
|
|
|
```ts
|
|
interface CommandCompletedPayload {
|
|
command_run_id: string
|
|
exit_code: number
|
|
duration_ms?: number
|
|
stdout_artifact_id?: string
|
|
stderr_artifact_id?: string
|
|
combined_artifact_id?: string
|
|
diagnostic_ids?: string[]
|
|
parsed_diagnostics_json?: unknown
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `command.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `command_runs.exit_code` when available and create failure artifacts.
|
|
|
|
```ts
|
|
interface CommandFailedPayload extends FailurePayload {
|
|
command_run_id: string
|
|
exit_code?: number
|
|
duration_ms?: number
|
|
stdout_artifact_id?: string
|
|
stderr_artifact_id?: string
|
|
combined_artifact_id?: string
|
|
}
|
|
```
|
|
|
|
### 3.7 Artifact, Diagnostic, and Evidence Events
|
|
|
|
#### `artifact.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `artifacts` row after file has been written temp → atomic rename.
|
|
|
|
```ts
|
|
interface ArtifactCreatedPayload {
|
|
artifact_id: string
|
|
type: string
|
|
uri: string
|
|
path: string
|
|
original_name?: string
|
|
size_bytes?: number
|
|
sha256?: string
|
|
task_id?: string
|
|
agent_id?: string
|
|
tool_run_id?: string
|
|
command_run_id?: string
|
|
associated_entity_type?: string
|
|
associated_entity_id?: string
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `diagnostic.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `diagnostics` row.
|
|
|
|
```ts
|
|
interface DiagnosticCreatedPayload {
|
|
diagnostic_id: string
|
|
task_id?: string
|
|
agent_id?: string
|
|
command_run_id?: string
|
|
artifact_id?: string
|
|
language?: string
|
|
toolchain?: string
|
|
severity?: string
|
|
file?: string
|
|
line?: number
|
|
column?: number
|
|
code?: string
|
|
message: string
|
|
semantic_signature: string
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
#### `evidence.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `evidence_refs` row.
|
|
|
|
```ts
|
|
interface EvidenceCreatedPayload {
|
|
evidence_ref_id: string
|
|
kind: string
|
|
ref: string
|
|
location_json?: unknown
|
|
claim: string
|
|
task_id?: string
|
|
agent_id?: string
|
|
tool_run_id?: string
|
|
command_run_id?: string
|
|
artifact_id?: string
|
|
diagnostic_id?: string
|
|
message_id?: string
|
|
}
|
|
```
|
|
|
|
### 3.8 Context and Summary Events
|
|
|
|
#### `context.compaction.requested` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert compaction task if Scheduler accepts it.
|
|
|
|
```ts
|
|
interface ContextCompactionRequestedPayload {
|
|
reason: "token_budget" | "user_request" | "session_checkpoint" | "manual"
|
|
range_start_message_id?: string
|
|
range_end_message_id?: string
|
|
target_budget_tokens?: number
|
|
}
|
|
```
|
|
|
|
#### `context.compaction.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: mark compaction task running.
|
|
|
|
```ts
|
|
interface ContextCompactionStartedPayload {
|
|
task_id: string
|
|
agent_id: string
|
|
range_start_message_id?: string
|
|
range_end_message_id?: string
|
|
}
|
|
```
|
|
|
|
#### `context.compaction.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: mark compaction task complete. The `summaries` row is inserted by `summary.created`, not by this event.
|
|
|
|
```ts
|
|
interface ContextCompactionCompletedPayload {
|
|
task_id?: string
|
|
agent_id?: string
|
|
summary_id: string
|
|
range_start_message_id?: string
|
|
range_end_message_id?: string
|
|
token_estimate_before?: number
|
|
token_estimate_after?: number
|
|
}
|
|
```
|
|
|
|
#### `context.compaction.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: mark compaction task failed or blocked.
|
|
|
|
```ts
|
|
interface ContextCompactionFailedPayload extends FailurePayload {
|
|
task_id?: string
|
|
agent_id?: string
|
|
range_start_message_id?: string
|
|
range_end_message_id?: string
|
|
}
|
|
```
|
|
|
|
#### `summary.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `summaries` row.
|
|
|
|
```ts
|
|
interface SummaryCreatedPayload {
|
|
summary_id: string
|
|
type: string
|
|
range_start_message_id?: string
|
|
range_end_message_id?: string
|
|
content_json: unknown
|
|
metadata?: JsonObject
|
|
}
|
|
```
|
|
|
|
### 3.9 Permission Events
|
|
|
|
#### `permission.decision.recorded` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append permission decision record to events; optional future projection table.
|
|
|
|
```ts
|
|
interface PermissionDecisionRecordedPayload {
|
|
decision_id: string
|
|
subject: "tool" | "command" | "path" | "network" | "dependency" | "migration"
|
|
action: "allow" | "deny" | "ask_user" | "block" | "refuse" | "announce_then_run"
|
|
grant_scope: "none" | "once" | "session" | "project" | "global"
|
|
reason?: string
|
|
risk_level: "low" | "medium" | "high" | "critical"
|
|
decided_by: "user" | "policy" | "high_permission_mode" | "system"
|
|
scope_json?: unknown
|
|
expires_at?: ISOTimeString
|
|
}
|
|
```
|
|
|
|
#### `permission.prompt.requested` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event; optional UI projection.
|
|
|
|
```ts
|
|
interface PermissionPromptRequestedPayload {
|
|
prompt_id: string
|
|
subject: string
|
|
risk_level: "low" | "medium" | "high" | "critical"
|
|
reason: string
|
|
options: string[]
|
|
default_option?: string
|
|
request_ref?: EntityRef
|
|
}
|
|
```
|
|
|
|
#### `permission.prompt.resolved` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and create `permission.decision.recorded` if applicable.
|
|
|
|
```ts
|
|
interface PermissionPromptResolvedPayload {
|
|
prompt_id: string
|
|
selected_option: string
|
|
decision_id?: string
|
|
resolved_by: "user" | "timeout" | "system"
|
|
}
|
|
```
|
|
|
|
### 3.10 Doctor and Dependency Events
|
|
|
|
#### `doctor.run.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and create optional report artifact later.
|
|
|
|
```ts
|
|
interface DoctorRunStartedPayload {
|
|
run_id: string
|
|
mode: "read_only" | "fix"
|
|
trigger: "startup" | "manual" | "dependency_request" | "release_gate"
|
|
}
|
|
```
|
|
|
|
#### `doctor.issue.found` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and optional diagnostic/report artifact.
|
|
|
|
```ts
|
|
interface DoctorIssueFoundPayload {
|
|
run_id: string
|
|
issue_id: string
|
|
severity: "info" | "warning" | "error" | "blocking"
|
|
capability?: string
|
|
dependency?: string
|
|
message: string
|
|
fix_available: boolean
|
|
fix_requires_confirmation?: boolean
|
|
}
|
|
```
|
|
|
|
#### `doctor.fix.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and optional command/tool run rows.
|
|
|
|
```ts
|
|
interface DoctorFixStartedPayload {
|
|
run_id: string
|
|
issue_id: string
|
|
fix_id: string
|
|
strategy: string
|
|
}
|
|
```
|
|
|
|
#### `doctor.fix.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and update report artifact.
|
|
|
|
```ts
|
|
interface DoctorFixCompletedPayload {
|
|
run_id: string
|
|
issue_id: string
|
|
fix_id: string
|
|
evidence_refs?: EvidenceLink[]
|
|
}
|
|
```
|
|
|
|
#### `doctor.fix.failed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and update report artifact.
|
|
|
|
```ts
|
|
interface DoctorFixFailedPayload extends FailurePayload {
|
|
run_id: string
|
|
issue_id: string
|
|
fix_id: string
|
|
}
|
|
```
|
|
|
|
#### `doctor.run.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and create doctor report artifact.
|
|
|
|
```ts
|
|
interface DoctorRunCompletedPayload {
|
|
run_id: string
|
|
status: "passed" | "issues_found" | "fixed" | "failed"
|
|
issue_count: number
|
|
blocking_issue_count: number
|
|
report_artifact_id?: string
|
|
}
|
|
```
|
|
|
|
### 3.11 Requirement and Architecture Events
|
|
|
|
#### `requirement.changed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and mark impacted tasks when Scheduler applies it.
|
|
|
|
```ts
|
|
interface RequirementChangedPayload {
|
|
change_id: string
|
|
origin_message_id: string
|
|
summary: string
|
|
change_type: "clarification" | "scope_change" | "architecture_change" | "constraint_change" | "cancellation"
|
|
affected_refs?: EntityRef[]
|
|
}
|
|
```
|
|
|
|
#### `architecture.plan.updated` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and artifact/plan references.
|
|
|
|
```ts
|
|
interface ArchitecturePlanUpdatedPayload {
|
|
plan_ref: string
|
|
update_kind: "created" | "revised" | "superseded"
|
|
summary: string
|
|
affected_task_ids?: string[]
|
|
adr_refs?: string[]
|
|
c4_refs?: string[]
|
|
}
|
|
```
|
|
|
|
#### `architecture.impact.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event; Scheduler consumes to continue/replan/block.
|
|
|
|
```ts
|
|
interface ArchitectureImpactCompletedPayload {
|
|
assessment_id: string
|
|
requirement_change_id?: string
|
|
impact_level: "implementation" | "interface" | "architecture" | "product"
|
|
decision: "silent_continue" | "requires_user_confirmation" | "requires_replan" | "reject_or_escalate"
|
|
summary: string
|
|
affected_task_ids?: string[]
|
|
evidence_refs?: EvidenceLink[]
|
|
}
|
|
```
|
|
|
|
### 3.12 Workspace and Merge Events
|
|
|
|
#### `workspace.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert `workspaces` row.
|
|
|
|
```ts
|
|
interface WorkspaceCreatedPayload {
|
|
workspace_id: string
|
|
task_id?: string
|
|
agent_id?: string
|
|
path: string
|
|
strategy: "main" | "worktree" | "isolated_copy"
|
|
base_ref?: string
|
|
branch_name?: string
|
|
}
|
|
```
|
|
|
|
#### `workspace.merge.started` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and mark workspace merge in progress in metadata.
|
|
|
|
```ts
|
|
interface WorkspaceMergeStartedPayload {
|
|
workspace_id: string
|
|
task_id?: string
|
|
strategy: "fast_forward" | "patch_apply" | "manual_merge" | "copy_back"
|
|
target_ref?: string
|
|
}
|
|
```
|
|
|
|
#### `workspace.merge.completed` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `workspaces.status = merged`, set `merged_at`.
|
|
|
|
```ts
|
|
interface WorkspaceMergeCompletedPayload {
|
|
workspace_id: string
|
|
task_id?: string
|
|
merged_ref?: string
|
|
diff_artifact_id?: string
|
|
}
|
|
```
|
|
|
|
#### `workspace.merge.conflicted` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `workspaces.status = conflicted`.
|
|
|
|
```ts
|
|
interface WorkspaceMergeConflictedPayload {
|
|
workspace_id: string
|
|
task_id?: string
|
|
conflict_files: string[]
|
|
conflict_artifact_id?: string
|
|
suggested_resolution?: "retry_serial" | "debugger" | "architecture_review" | "user_decision"
|
|
}
|
|
```
|
|
|
|
#### `workspace.cleaned` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: update `workspaces.status = cleaned` or append cleanup metadata.
|
|
|
|
```ts
|
|
interface WorkspaceCleanedPayload {
|
|
workspace_id: string
|
|
reason: "merged" | "cancelled" | "abandoned" | "manual"
|
|
}
|
|
```
|
|
|
|
### 3.13 Memory and Debug Knowledge Events
|
|
|
|
#### `memory.candidate.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event; future memory table may project it.
|
|
|
|
```ts
|
|
interface MemoryCandidateCreatedPayload {
|
|
candidate_id: string
|
|
source_ref: EntityRef
|
|
memory_type: "project_rule" | "toolchain_rule" | "skill_update" | "debug_experience"
|
|
summary: string
|
|
evidence_refs?: EvidenceLink[]
|
|
}
|
|
```
|
|
|
|
#### `memory.promoted` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and update `.air/shared/rules`, skill, or `learned-memory.db` through the owning subsystem.
|
|
|
|
```ts
|
|
interface MemoryPromotedPayload {
|
|
candidate_id: string
|
|
target_ref: string
|
|
promoted_by: "user" | "curator" | "system"
|
|
summary: string
|
|
}
|
|
```
|
|
|
|
#### `memory.archived` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: append event and mark memory inactive in owning subsystem.
|
|
|
|
```ts
|
|
interface MemoryArchivedPayload {
|
|
candidate_id?: string
|
|
memory_ref?: string
|
|
reason: string
|
|
}
|
|
```
|
|
|
|
#### `debug.record.created` v1
|
|
|
|
Persistence: durable.
|
|
|
|
Domain update: insert/update `debug-records.db` and append event in session DB.
|
|
|
|
```ts
|
|
interface DebugRecordCreatedPayload {
|
|
debug_record_id: string
|
|
task_id?: string
|
|
failure_signature: string
|
|
summary: string
|
|
evidence_refs?: EvidenceLink[]
|
|
verification_refs?: EvidenceLink[]
|
|
}
|
|
```
|
|
|
|
## 4. Ephemeral Event Registry
|
|
|
|
Ephemeral events are for live rendering, streaming, and heartbeat. They are not required for crash recovery.
|
|
|
|
### `agent.heartbeat` v1
|
|
|
|
Producer: child agent process.
|
|
|
|
Consumer: Scheduler, ProjectionStore.
|
|
|
|
```ts
|
|
interface AgentHeartbeatPayload {
|
|
agent_id: string
|
|
task_id?: string
|
|
status: "starting" | "running"
|
|
progress_text?: string
|
|
current_step?: string
|
|
resource_snapshot?: {
|
|
pid?: number
|
|
cpu_percent?: number
|
|
memory_bytes?: number
|
|
}
|
|
}
|
|
```
|
|
|
|
### `task.progress` v1
|
|
|
|
Producer: Scheduler or worker agent.
|
|
|
|
Consumer: ProjectionStore, Main Agent summaries.
|
|
|
|
```ts
|
|
interface TaskProgressPayload {
|
|
task_id: string
|
|
agent_id?: string
|
|
phase?: string
|
|
progress_text: string
|
|
percent?: number
|
|
}
|
|
```
|
|
|
|
### `assistant.message.delta` v1
|
|
|
|
Producer: Main Agent / provider adapter.
|
|
|
|
Consumer: ProjectionStore; `message_drafts` may be periodically flushed by draft writer.
|
|
|
|
```ts
|
|
interface AssistantMessageDeltaPayload {
|
|
message_id: string
|
|
delta: unknown
|
|
sequence: number
|
|
}
|
|
```
|
|
|
|
### `tool.progress` v1
|
|
|
|
Producer: streaming tool.
|
|
|
|
Consumer: ProjectionStore, command/tool monitor.
|
|
|
|
```ts
|
|
interface ToolProgressPayload {
|
|
tool_run_id: string
|
|
message: string
|
|
progress_json?: unknown
|
|
}
|
|
```
|
|
|
|
### `command.stdout.delta` v1 and `command.stderr.delta` v1
|
|
|
|
Producer: shell/command runner.
|
|
|
|
Consumer: ProjectionStore, artifact writer.
|
|
|
|
```ts
|
|
interface CommandStreamDeltaPayload {
|
|
command_run_id: string
|
|
chunk: string
|
|
sequence: number
|
|
truncated?: boolean
|
|
}
|
|
```
|
|
|
|
### `hud.frame.rendered` v1
|
|
|
|
Producer: TUI/HUD.
|
|
|
|
Consumer: local performance/debug logging only.
|
|
|
|
```ts
|
|
interface HudFrameRenderedPayload {
|
|
frame_id: string
|
|
duration_ms?: number
|
|
dropped_frame_count?: number
|
|
}
|
|
```
|
|
|
|
## 5. Producer and Consumer Boundaries
|
|
|
|
Producer responsibilities:
|
|
|
|
1. Emit valid RuntimeEvent envelopes.
|
|
2. Provide IDs generated by the subsystem that owns the entity.
|
|
3. Append route segment when forwarding.
|
|
4. Never update SQLite domain tables directly unless the producer is the owning store/service.
|
|
|
|
EventStore responsibilities:
|
|
|
|
1. Validate event version and payload schema.
|
|
2. Apply durable events and domain table updates transactionally.
|
|
3. Derive query columns such as `task_id`, `agent_id`, `tool_run_id`, `command_run_id`, `route_text`.
|
|
4. Publish committed durable events to EventBus after commit.
|
|
5. Reject unknown durable event types unless explicitly allowed by development-mode config.
|
|
|
|
ProjectionStore responsibilities:
|
|
|
|
1. Hydrate from DB at startup/resume.
|
|
2. Apply live durable and ephemeral events.
|
|
3. Coalesce noisy deltas for TUI/HUD.
|
|
4. Never become the source of truth for scheduling or recovery.
|
|
|
|
Scheduler responsibilities:
|
|
|
|
1. Consume task/agent/workspace/architecture events.
|
|
2. Drive retries, dependency unblocking, merge waves, and escalation.
|
|
3. Treat missing heartbeat as `agent.lost` and persist that durable event.
|
|
|
|
## 6. V1 Event Type Index
|
|
|
|
Durable:
|
|
|
|
```text
|
|
session.created
|
|
session.archived
|
|
session.deleted
|
|
user.message.created
|
|
assistant.message.started
|
|
assistant.message.created
|
|
assistant.message.failed
|
|
agent.started
|
|
agent.completed
|
|
agent.failed
|
|
agent.lost
|
|
agent.cancelled
|
|
task.created
|
|
task.started
|
|
task.completed
|
|
task.blocked
|
|
task.failed
|
|
task.cancelled
|
|
task.interrupted
|
|
tool.started
|
|
tool.completed
|
|
tool.failed
|
|
tool.cancelled
|
|
command.started
|
|
command.completed
|
|
command.failed
|
|
artifact.created
|
|
diagnostic.created
|
|
evidence.created
|
|
context.compaction.requested
|
|
context.compaction.started
|
|
context.compaction.completed
|
|
context.compaction.failed
|
|
summary.created
|
|
permission.decision.recorded
|
|
permission.prompt.requested
|
|
permission.prompt.resolved
|
|
doctor.run.started
|
|
doctor.issue.found
|
|
doctor.fix.started
|
|
doctor.fix.completed
|
|
doctor.fix.failed
|
|
doctor.run.completed
|
|
requirement.changed
|
|
architecture.plan.updated
|
|
architecture.impact.completed
|
|
workspace.created
|
|
workspace.merge.started
|
|
workspace.merge.completed
|
|
workspace.merge.conflicted
|
|
workspace.cleaned
|
|
memory.candidate.created
|
|
memory.promoted
|
|
memory.archived
|
|
debug.record.created
|
|
```
|
|
|
|
Ephemeral:
|
|
|
|
```text
|
|
agent.heartbeat
|
|
task.progress
|
|
assistant.message.delta
|
|
tool.progress
|
|
command.stdout.delta
|
|
command.stderr.delta
|
|
hud.frame.rendered
|
|
```
|
|
|
|
## 7. V1.0.0 Alpha Cut Line
|
|
|
|
The V1.0.0 Alpha skeleton must implement schema validation and EventStore handling for all durable event names in the V1 index, even if some subsystem producers are initially stubs.
|
|
|
|
The first implementation may keep payload schemas in TypeScript with runtime validation generated from the same definitions. Unknown plugin/capability events must use a namespaced prefix and must not be durable until registered.
|