Добавить дизайн Invest Harness и контракты платформы

This commit is contained in:
admin committed 2026-11-11 04:44:47 +00:00
1 parent 5d31a39aae
commit 2af6dd78ba
21 files changed
+1322 -2

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
# Модель данных
Типы в этой таблице определяют семантику 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, provider, scopes, encryptedSecretRef | Secrets / Platform API |
| Run | id, tenantId, agentRevisionId, status, specDigest, parentRunId | Platform API |
| Attempt | id, runId, runnerId, leaseEpoch, leaseUntil, status | Dispatcher |
| RunnerPool | id, tenantId, trustPolicy, quotas | Dispatcher |
| Runner | id, poolId, capabilities, credentialStatus, lastSeenAt | Dispatcher |
| Artifact | id, runId, attemptId, objectKey, digest, sizeBytes, mediaType | Platform API |
| Schedule | id, agentId, cron, timezone, nextRunAt, overlapPolicy | Dispatcher |
| 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 означает, что возможность недоступна; поле не может быть выведено из названия пакета.
@@ -0,0 +1,5 @@
{
"lookbackDays": 90,
"reportLanguage": "ru",
"includeSources": true
}
@@ -0,0 +1,34 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"title": "Настройки обзора компаний",
"additionalProperties": false,
"required": [
"lookbackDays",
"reportLanguage",
"includeSources"
],
"properties": {
"lookbackDays": {
"type": "integer",
"title": "Период анализа в днях",
"minimum": 1,
"maximum": 365,
"default": 90
},
"reportLanguage": {
"type": "string",
"title": "Язык отчёта",
"enum": [
"ru",
"en"
],
"default": "ru"
},
"includeSources": {
"type": "boolean",
"title": "Показывать источники",
"default": true
}
}
}
@@ -0,0 +1,44 @@
{
"protocolVersion": "1",
"runId": "run_example",
"agentRevisionId": "revision_example_1",
"templateVersionId": "template_example_1",
"packages": [
{
"packageVersionId": "template_example_1",
"kind": "template",
"digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"artifactRef": "artifact_template_example"
},
{
"packageVersionId": "harness_example_1",
"kind": "harness",
"digest": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"artifactRef": "registry.example.invalid/invest/runtime@sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
],
"configSchemaDigest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"config": {
"lookbackDays": 90,
"reportLanguage": "ru",
"includeSources": true
},
"input": {
"company": "Example Company"
},
"connections": {},
"limits": {
"cpuMillis": 1000,
"memoryBytes": 1073741824,
"timeoutSeconds": 900,
"outputBytes": 104857600
},
"requiredCapabilities": [
"oci-v1",
"cancel-v1"
],
"entrypoint": [
"/app/entrypoint",
"/input/execution.json"
]
}
@@ -0,0 +1,27 @@
{
"manifestVersion": "1",
"kind": "template",
"name": "company-review",
"version": "1.0.0",
"artifact": {
"ref": "artifact_template_example",
"digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"mediaType": "application/gzip"
},
"dependencies": [
{
"packageVersionId": "harness_example_1",
"digest": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
],
"harnessVersionId": "harness_example_1",
"configSchemaRef": "config.schema.json",
"defaultsRef": "config.defaults.json",
"uiSchemaRef": "ui.schema.json",
"requiredCapabilities": [
"oci-v1",
"cancel-v1"
],
"requiredPermissions": [],
"retrySafe": false
}
@@ -0,0 +1,17 @@
{
"type": "VerticalLayout",
"elements": [
{
"type": "Control",
"scope": "#/properties/lookbackDays"
},
{
"type": "Control",
"scope": "#/properties/reportLanguage"
},
{
"type": "Control",
"scope": "#/properties/includeSources"
}
]
}
@@ -0,0 +1,143 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ExecutionSpec v1",
"type": "object",
"additionalProperties": false,
"required": [
"protocolVersion",
"runId",
"agentRevisionId",
"templateVersionId",
"packages",
"configSchemaDigest",
"config",
"input",
"connections",
"limits",
"requiredCapabilities",
"entrypoint"
],
"properties": {
"protocolVersion": {
"const": "1"
},
"runId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"agentRevisionId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"templateVersionId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"packages": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"packageVersionId",
"kind",
"digest",
"artifactRef"
],
"properties": {
"packageVersionId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"kind": {
"enum": [
"harness",
"plugin",
"skill",
"template"
]
},
"digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"artifactRef": {
"type": "string",
"minLength": 1
}
}
}
},
"configSchemaDigest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"config": {
"type": "object"
},
"input": {},
"connections": {
"type": "object",
"additionalProperties": {
"type": "string",
"minLength": 1,
"maxLength": 128
}
},
"limits": {
"type": "object",
"additionalProperties": false,
"required": [
"cpuMillis",
"memoryBytes",
"timeoutSeconds",
"outputBytes"
],
"properties": {
"cpuMillis": {
"type": "integer",
"minimum": 1
},
"memoryBytes": {
"type": "integer",
"minimum": 1
},
"timeoutSeconds": {
"type": "integer",
"minimum": 1
},
"outputBytes": {
"type": "integer",
"minimum": 1
}
}
},
"requiredCapabilities": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
},
"entrypoint": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
}
},
"checkpointRef": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"resumeInput": {}
}
}
@@ -0,0 +1,188 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Invest Harness package manifest v1",
"type": "object",
"additionalProperties": false,
"required": [
"manifestVersion",
"kind",
"name",
"version",
"artifact",
"dependencies"
],
"properties": {
"manifestVersion": {
"const": "1"
},
"kind": {
"enum": [
"harness",
"plugin",
"skill",
"template"
]
},
"name": {
"type": "string",
"minLength": 1
},
"version": {
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z.-]+)?(\\+[0-9A-Za-z.-]+)?$"
},
"artifact": {
"type": "object",
"additionalProperties": false,
"required": [
"ref",
"digest",
"mediaType"
],
"properties": {
"ref": {
"type": "string",
"minLength": 1
},
"digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"mediaType": {
"type": "string",
"minLength": 1
}
}
},
"dependencies": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"packageVersionId",
"digest"
],
"properties": {
"packageVersionId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
}
}
}
},
"harnessVersionId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"configSchemaRef": {
"type": "string",
"minLength": 1
},
"defaultsRef": {
"type": "string",
"minLength": 1
},
"uiSchemaRef": {
"type": "string",
"minLength": 1
},
"executionKind": {
"enum": [
"oci",
"native"
]
},
"entrypoint": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
}
},
"supportedHarnesses": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 128
}
},
"requiredCapabilities": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
},
"requiredPermissions": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1
}
},
"retrySafe": {
"type": "boolean"
}
},
"allOf": [
{
"if": {
"properties": {
"kind": {
"const": "template"
}
}
},
"then": {
"required": [
"harnessVersionId",
"configSchemaRef"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "harness"
}
}
},
"then": {
"required": [
"executionKind",
"entrypoint"
]
}
},
{
"if": {
"properties": {
"kind": {
"enum": [
"plugin",
"skill"
]
}
}
},
"then": {
"required": [
"supportedHarnesses"
]
}
}
]
}
@@ -0,0 +1,46 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "RunEvent v1",
"type": "object",
"additionalProperties": false,
"required": [
"eventId",
"attemptId",
"sequence",
"occurredAt",
"type",
"payload"
],
"properties": {
"eventId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"attemptId": {
"type": "string",
"minLength": 1,
"maxLength": 128
},
"sequence": {
"type": "integer",
"minimum": 1
},
"occurredAt": {
"type": "string",
"format": "date-time"
},
"type": {
"enum": [
"progress",
"log",
"artifact_ready",
"input_requested",
"diagnostic"
]
},
"payload": {
"type": "object"
}
}
}