# Модель данных Типы в этой таблице определяют семантику API. JSON Schema ниже задают машиночитаемую основу контракта; дополнительные межресурсные проверки выполняются сервисами | Сущность | Ключевые поля | Владелец | |---|---|---| | Tenant | id, name, policyRevision | Platform API | | Membership | tenantId, userId, roles | Identity / Platform API | | Package | id, tenantId, kind, name, visibility, ownerId | Catalog | | PackageVersion | id, packageId, version, manifest, artifactDigest | Catalog | | VersionPolicy | versionId, status, reason, revision | Catalog | | Agent | id, tenantId, ownerId, name, currentRevision | Platform API | | AgentRevision | id, agentId, revision, templateVersionId, config, connections, schemaDigest | Platform API | | Connection | id, tenantId, ownerId, providerId, authMode, placement, status, secretBindingRef | Secrets / Platform API | | Run | id, tenantId, agentRevisionId, status, specDigest, parentRunId | Platform API | | Attempt | id, runId, runnerId, leaseEpoch, leaseUntil, status | Dispatcher / Platform DB | | RunnerPool | id, tenantId, trustPolicy, quotas | Dispatcher / Platform DB | | Runner | id, poolId, capabilities, credentialStatus, lastSeenAt | Dispatcher / Platform DB | | Artifact | id, runId, attemptId, objectKey, digest, sizeBytes, mediaType | Platform API | | Schedule | id, agentId, agentRevisionId, cron, timezone, nextRunAt, overlapPolicy, misfirePolicy | Dispatcher / Platform DB | | Outbox | id, aggregateId, eventType, payload, deliveredAt | Пишущий сервис | ## Инварианты - Между БД нет внешних ключей: идентификаторы проверяются API. Каждый сервис владеет своими транзакциями и outbox - Run ссылается на immutable AgentRevision и ExecutionSpec; повторная проверка прав не изменяет их содержимое - Published PackageVersion не перезаписывается. Политика блокировки хранится отдельно - Попытка имеет только одного текущего владельца lease; epoch монотонно растёт при новом назначении - Terminal report и смена состояния сохраняются одной транзакцией вместе с событием outbox - Resource ID не является доказательством доступа. Tenant scope проверяется независимо - ConnectionRef никогда не содержит значение секрета - Artifact считается готовым после проверки объекта и digest, а не после выдачи upload URL ## Схемы - [Манифест пакета](package-manifest.schema.json) — общий envelope четырёх видов пакетов - [ExecutionSpec](execution-spec.schema.json) — конкретный состав запуска - [Событие](run-event.schema.json) — события исполнителя - [Пример manifest](examples/template-manifest.json) - [Пример ExecutionSpec](examples/execution-spec.json) Id — opaque string. Version — SemVer строка; разрешение диапазонов выполняет resolver до фиксации ExecutionSpec. Digest — SHA-256. Timestamps — RFC3339 UTC. UUID не навязывается публичным контрактом Package manifest с kind=template обязан указать harnessVersionId, configSchemaRef и зависимости. Harness обязан указать entrypoint и executionKind. Plugin и skill указывают совместимость supportedHarnesses. Отсутствующая optional capability означает, что возможность недоступна; поле не может быть выведено из названия пакета Run, Attempt, Schedule и reservations составляют одну транзакционную область Platform DB. Внешние Execution DB и Catalog DB не принимают бизнес-переходы Run. Подробнее: [исполнение](../execution.md) - [Assignment и AttemptContext](runner-assignment.schema.json): контекст попытки отдельно от неизменяемого spec - [ResultManifest](result-manifest.schema.json): результат и проверяемые артефакты - [Provider API](../api/provider-api.md): канонический ConnectionSummary; secretBindingRef остаётся серверным полем inputSchemaRef и outputSchemaRef обязательны для template. Все schemaRef — пути внутри проверенного архива версии; произвольные сетевые $ref запрещены. DSH-плагин указывает dshCompatibility; статус совместимости выставляется каталогом по отдельному отчёту, а не самим автором