[verified] docs: add Agent Control Center specification
This commit is contained in:
commit
37f058938c
10 changed files with 993 additions and 0 deletions
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Secrets and local configuration
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
*.p12
|
||||||
|
secrets/
|
||||||
|
|
||||||
|
# Editors / OS
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Build, cache and local state
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
coverage/
|
||||||
|
.cache/
|
||||||
|
.tmp/
|
||||||
|
.omo/
|
||||||
|
*.log
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
.venv/
|
||||||
|
|
||||||
|
# Specification rendering artifacts
|
||||||
|
*.tmp.docx
|
||||||
|
*.tmp.pdf
|
||||||
16
CONTRIBUTING.md
Normal file
16
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Contribution policy
|
||||||
|
|
||||||
|
Проект находится на стадии спецификации.
|
||||||
|
|
||||||
|
## До утверждения v1
|
||||||
|
|
||||||
|
Разрешены только изменения требований, архитектуры, исследований, ADR и validation tooling. Реализация продукта блокирована до явного operator approval и G1 PASS.
|
||||||
|
|
||||||
|
## Правила изменений
|
||||||
|
|
||||||
|
1. Каждое функциональное требование получает стабильный ID и acceptance test ID.
|
||||||
|
2. Изменение security boundary, API, данных, retention или integration contract требует обновить traceability и соответствующий ADR/open question.
|
||||||
|
3. Источники для внешних API должны быть официальными, с датой проверки.
|
||||||
|
4. Нельзя коммитить credentials, tokens, private keys, session exports или реальные пользовательские данные.
|
||||||
|
5. Перед локальным commit спецификационных изменений: structural validation, secret scan, `git diff --cached --check` и independent peer review точного staged-кандидата. Термин G2 зарезервирован за implementation gate из `SPECIFICATION.md` §12.3.
|
||||||
|
6. Local commit не означает разрешение на push; публикация проходит отдельный pre-publish gate.
|
||||||
40
README.md
Normal file
40
README.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Agent Control Center
|
||||||
|
|
||||||
|
Единое рабочее пространство для управления проектами, задачами и серверными ИИ-агентами с Web-, Desktop- и Android-клиентами.
|
||||||
|
|
||||||
|
## Статус
|
||||||
|
|
||||||
|
**Specification Draft v0.1.0 — implementation blocked.**
|
||||||
|
|
||||||
|
Репозиторий содержит требования и архитектурный baseline. Он не содержит реализации и не даёт разрешения начинать разработку. Перед реализацией обязательны:
|
||||||
|
|
||||||
|
1. закрытие блокирующих открытых решений;
|
||||||
|
2. утверждение спецификации оператором;
|
||||||
|
3. G1 requirement-completeness PASS;
|
||||||
|
4. отдельная явная команда на implementation.
|
||||||
|
|
||||||
|
## Документы
|
||||||
|
|
||||||
|
- [Каноническое ТЗ](docs/SPECIFICATION.md)
|
||||||
|
- [Архитектура](docs/ARCHITECTURE.md)
|
||||||
|
- [Исследование интеграций](docs/RESEARCH.md)
|
||||||
|
- [Матрица трассируемости](docs/TRACEABILITY.md)
|
||||||
|
- [Открытые решения](docs/OPEN-QUESTIONS.md)
|
||||||
|
- [Правила участия](CONTRIBUTING.md)
|
||||||
|
|
||||||
|
## Ключевой принцип
|
||||||
|
|
||||||
|
Agent Control Center не пытается унифицировать внутреннее устройство Hermes, OpenClaw, Claude Code, Codex, ChatGPT/OpenAI и Gemini. Серверный Connector подключает каждый runtime через версионируемый адаптер, публикующий нормализованные capabilities, события, checkpoints и usage-сигналы.
|
||||||
|
|
||||||
|
## Предлагаемый MVP
|
||||||
|
|
||||||
|
- Web/PWA, desktop wrapper и Android-клиент с общим интерфейсным ядром;
|
||||||
|
- рабочие пространства, проекты, Kanban-задачи и артефакты;
|
||||||
|
- реестр серверов, агентов и их capabilities;
|
||||||
|
- запуск, наблюдение, остановка и ручной handoff работы между агентами;
|
||||||
|
- общая проектная память, версионируемые skills и wiki;
|
||||||
|
- квоты/лимиты, approvals, аудит и безопасный outbound-only Connector.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
Лицензия пока не выбрана. Репозиторий приватный; отсутствие файла `LICENSE` означает отсутствие предоставленной публичной лицензии.
|
||||||
208
docs/ARCHITECTURE.md
Normal file
208
docs/ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
# Архитектура Agent Control Center
|
||||||
|
|
||||||
|
**Версия:** 0.1.0-draft
|
||||||
|
**Дата:** 2026-07-19
|
||||||
|
**Нормативность:** supporting architecture; при конфликте приоритет у `SPECIFICATION.md`.
|
||||||
|
|
||||||
|
## 1. Контекст
|
||||||
|
|
||||||
|
Система разделяется на центральный Control Plane и один или несколько Connector, установленных рядом с серверными агентами. Клиенты не подключаются к агентам напрямую. Connector устанавливает исходящее mTLS/WebSocket-соединение, поэтому MVP не требует открывать входящий порт на каждом сервере агента.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
W[Web / PWA] -->|HTTPS + WSS| API[Control Plane API]
|
||||||
|
D[Desktop] -->|HTTPS + WSS| API
|
||||||
|
M[Android] -->|HTTPS + WSS| API
|
||||||
|
API --> IAM[Identity & Policy]
|
||||||
|
API --> CORE[Projects / Tasks / Runs]
|
||||||
|
API --> CTX[Context Broker]
|
||||||
|
API --> REG[Memory / Skills / Wiki]
|
||||||
|
CORE --> BUS[Durable Event Bus]
|
||||||
|
CTX --> BUS
|
||||||
|
BUS --> GW[Connector Gateway]
|
||||||
|
GW <-->|outbound mTLS WSS| C1[Server Connector]
|
||||||
|
C1 --> H[Hermes adapter]
|
||||||
|
C1 --> O[OpenClaw adapter]
|
||||||
|
C1 --> C[Claude adapter]
|
||||||
|
C1 --> X[Codex adapter]
|
||||||
|
C1 --> G[Gemini adapter]
|
||||||
|
C1 --> P[Generic API/CLI/MCP adapter]
|
||||||
|
CORE --> PG[(PostgreSQL)]
|
||||||
|
REG --> OBJ[(Object Storage)]
|
||||||
|
REG --> VEC[(Vector Index)]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Клиенты
|
||||||
|
|
||||||
|
Предлагаемый baseline, подлежащий утверждению ADR:
|
||||||
|
|
||||||
|
- **UI core:** React + TypeScript, responsive design, offline-capable read cache.
|
||||||
|
- **Web:** PWA, основной административный клиент.
|
||||||
|
- **Desktop:** Tauri wrapper для native notifications, secure local storage и controlled file pickers.
|
||||||
|
- **Android:** Capacitor wrapper над тем же UI core; native bridge только для push, biometrics, share/open-file и encrypted storage.
|
||||||
|
|
||||||
|
Запрещено помещать provider/server credentials в web bundle. Desktop/Android хранят только refresh credential устройства в OS keystore. Все provider credentials остаются на Connector или в серверном secret manager.
|
||||||
|
|
||||||
|
## 3. Control Plane компоненты
|
||||||
|
|
||||||
|
| Компонент | Ответственность | Не отвечает за |
|
||||||
|
|---|---|---|
|
||||||
|
| API Gateway | REST/WS, schema validation, idempotency, rate limits | бизнес-оркестрацию |
|
||||||
|
| Identity & Policy | OIDC/local bootstrap, RBAC/ABAC, device sessions, approvals | provider auth внутри Connector |
|
||||||
|
| Project Service | workspaces, projects, tasks, dependencies, artifacts | запуск runtime |
|
||||||
|
| Run Orchestrator | run state machine, leases, retries, cancel, handoff | интерпретацию vendor payload |
|
||||||
|
| Connector Gateway | регистрацию Connector, command/event delivery, health | исполнение adapter process |
|
||||||
|
| Context Broker | сбор bounded context bundle, redaction, token budgeting | хранение скрытого chain-of-thought |
|
||||||
|
| Memory Service | scoped/versioned memory, provenance, conflicts, retrieval | автоматическое объявление непроверенных выводов фактами |
|
||||||
|
| Skill Registry | immutable versions, review/signature state, compatibility | молчаливое выполнение skill-кода |
|
||||||
|
| Wiki Service | Markdown pages, versions, links, search | замена source artifacts |
|
||||||
|
| Usage Service | нормализованные usage/quota/budget signals | обещание точного остатка при отсутствии API |
|
||||||
|
| Audit Service | append-only security and lifecycle events | хранение секретов и полного sensitive content |
|
||||||
|
| Notification Service | in-app/push/email hooks, dedupe | authoritative task state |
|
||||||
|
|
||||||
|
## 4. Connector
|
||||||
|
|
||||||
|
### 4.1 Trust boundary
|
||||||
|
|
||||||
|
Connector — отдельный сервис с уникальной identity и минимальными правами. Он:
|
||||||
|
|
||||||
|
1. устанавливает только исходящее соединение;
|
||||||
|
2. исполняет команды с lease/idempotency key;
|
||||||
|
3. запускает adapters в отдельных OS identities/containers, где возможно;
|
||||||
|
4. не передаёт секреты в Control Plane;
|
||||||
|
5. redacts события до отправки;
|
||||||
|
6. хранит короткий encrypted spool при разрыве связи;
|
||||||
|
7. не принимает новый destructive action без policy/approval token.
|
||||||
|
|
||||||
|
### 4.2 Agent Adapter Protocol (AAP)
|
||||||
|
|
||||||
|
Версионированный внутренний контракт:
|
||||||
|
|
||||||
|
```text
|
||||||
|
handshake() -> identity, adapter_version, runtime_version, capabilities
|
||||||
|
health() -> status, latency, active_runs
|
||||||
|
start(run_spec, context_bundle, approval_token?) -> native_run_ref
|
||||||
|
stream(native_run_ref, cursor) -> ordered normalized events
|
||||||
|
checkpoint(native_run_ref, reason) -> observable checkpoint
|
||||||
|
cancel(native_run_ref, mode) -> outcome
|
||||||
|
resume(native_run_ref | checkpoint) -> outcome
|
||||||
|
usage(scope) -> measured|estimated|unknown signal
|
||||||
|
artifacts(native_run_ref) -> metadata + content references
|
||||||
|
```
|
||||||
|
|
||||||
|
Обязательные envelope-поля: `schema_version`, `connector_id`, `agent_id`, `run_id`, `event_id`, `sequence`, `occurred_at`, `classification`, `payload`, `vendor_extension`. Команды идемпотентны; события дедуплицируются по `(connector_id,event_id)`.
|
||||||
|
|
||||||
|
Capabilities включают как минимум: `stream`, `cancel`, `native_resume`, `checkpoint`, `approvals`, `tools`, `mcp`, `artifacts`, `usage_exact`, `usage_estimated`, `filesystem_scope`, `structured_output`. Отсутствующая capability никогда не симулируется молча.
|
||||||
|
|
||||||
|
## 5. Run и handoff state machine
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
stateDiagram-v2
|
||||||
|
[*] --> queued
|
||||||
|
queued --> dispatching
|
||||||
|
dispatching --> running
|
||||||
|
running --> waiting_approval
|
||||||
|
waiting_approval --> running
|
||||||
|
running --> checkpointing
|
||||||
|
checkpointing --> handoff_ready
|
||||||
|
handoff_ready --> dispatching: target selected
|
||||||
|
running --> succeeded
|
||||||
|
running --> failed
|
||||||
|
running --> cancelling
|
||||||
|
cancelling --> cancelled
|
||||||
|
dispatching --> blocked
|
||||||
|
handoff_ready --> blocked
|
||||||
|
blocked --> handoff_ready: user requests target selection
|
||||||
|
```
|
||||||
|
|
||||||
|
Handoff — новая attempt в рамках той же TaskRun lineage, а не перенос непрозрачной provider session. Handoff bundle содержит objective, acceptance criteria, bounded conversation, verified memory, decisions, completed/pending work, artifact refs, observed errors и provenance. Target adapter подтверждает ingestion; только после этого lease предыдущего attempt закрывается.
|
||||||
|
|
||||||
|
Автоматический fallback в MVP может **предложить** target, но не запускает платный или более привилегированный runtime без policy и, где требуется, user approval. Из `blocked` пользователь возвращает run в `handoff_ready`, чтобы выбрать совместимый target, либо явно отменяет run через обычный cancel flow.
|
||||||
|
|
||||||
|
## 6. Общий контекст
|
||||||
|
|
||||||
|
### 6.1 Scopes
|
||||||
|
|
||||||
|
`organization -> workspace -> project -> task -> run`; отдельно существуют `user-private` и `agent-private`. Более узкая область наследует разрешённые записи широкой области, но не наоборот.
|
||||||
|
|
||||||
|
### 6.2 Memory entry
|
||||||
|
|
||||||
|
Поля: `id`, `scope`, `kind`, `content`, `summary`, `provenance`, `confidence`, `verification_state`, `sensitivity`, `valid_from`, `valid_until`, `supersedes`, `acl`, `created_by`, `created_at`, `content_hash`.
|
||||||
|
|
||||||
|
Kinds: fact, decision, constraint, preference, lesson, entity, artifact_reference, run_summary. Непроверенный вывод агента имеет `verification_state=unverified`; conflict не перезаписывается, а создаёт новую версию и conflict record.
|
||||||
|
|
||||||
|
### 6.3 Skills
|
||||||
|
|
||||||
|
Skill package содержит manifest, Markdown instructions, optional assets/scripts, compatibility, permissions, provenance, digest, signature/review state. Версии immutable. Активация executable части требует policy review; downloaded/untrusted package по умолчанию quarantined.
|
||||||
|
|
||||||
|
### 6.4 Wiki
|
||||||
|
|
||||||
|
Markdown source, immutable revisions, backlinks, aliases, attachments, ACL и full-text/semantic search. Автосформированная страница сначала draft и показывает источники; публикация в authoritative namespace требует review.
|
||||||
|
|
||||||
|
## 7. Данные
|
||||||
|
|
||||||
|
Основные сущности:
|
||||||
|
|
||||||
|
- Organization, User, DeviceSession, RoleBinding;
|
||||||
|
- Workspace, Project, Task, TaskDependency, AcceptanceCriterion;
|
||||||
|
- Connector, Agent, Adapter, CapabilitySnapshot, CredentialReference;
|
||||||
|
- Conversation, Message, TaskRun, RunAttempt, RunEvent, Approval, Checkpoint;
|
||||||
|
- Artifact, ArtifactVersion;
|
||||||
|
- MemoryEntry, MemoryVersion, MemoryConflict;
|
||||||
|
- Skill, SkillVersion, SkillActivation;
|
||||||
|
- WikiPage, WikiRevision, WikiLink;
|
||||||
|
- UsageSignal, BudgetPolicy, AuditEvent, Notification.
|
||||||
|
|
||||||
|
PostgreSQL — authoritative metadata; object storage — artifacts/packages; vector index — derived retrieval index. Удаление vector index не должно уничтожать source content; индекс полностью перестраиваем.
|
||||||
|
|
||||||
|
## 8. API baseline
|
||||||
|
|
||||||
|
REST commands используют `Idempotency-Key`; event subscriptions — WSS с resume cursor.
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /v1/workspaces
|
||||||
|
GET /v1/projects/{projectId}
|
||||||
|
POST /v1/projects/{projectId}/tasks
|
||||||
|
PATCH /v1/tasks/{taskId}
|
||||||
|
POST /v1/connectors/enrollment-tokens
|
||||||
|
GET /v1/agents?project_id=&capability=
|
||||||
|
POST /v1/tasks/{taskId}/runs
|
||||||
|
POST /v1/runs/{runId}/approvals/{approvalId}
|
||||||
|
POST /v1/runs/{runId}/checkpoint
|
||||||
|
POST /v1/runs/{runId}/handoffs
|
||||||
|
POST /v1/runs/{runId}/cancel
|
||||||
|
GET /v1/runs/{runId}/events?cursor=
|
||||||
|
POST /v1/memory/query
|
||||||
|
POST /v1/memory/entries
|
||||||
|
POST /v1/skills/{skillId}/versions
|
||||||
|
POST /v1/skills/{skillId}/activations
|
||||||
|
PUT /v1/wiki/pages/{pageId}
|
||||||
|
GET /v1/usage/summary
|
||||||
|
GET /v1/audit/events
|
||||||
|
WS /v1/events?cursor=
|
||||||
|
```
|
||||||
|
|
||||||
|
Error envelope: `code`, `message`, `correlation_id`, `retryable`, `details`. Optimistic writes use `If-Match`/revision. Server timestamps are authoritative.
|
||||||
|
|
||||||
|
## 9. Deployment baseline
|
||||||
|
|
||||||
|
- self-hosted single-node MVP: container compose, PostgreSQL, S3-compatible storage, embedded/managed queue;
|
||||||
|
- production profile: redundant stateless API, managed PostgreSQL/object store, durable queue, separate workers;
|
||||||
|
- Connector upgrades are staged, signed, rollback-capable and never forced during active run;
|
||||||
|
- configuration is declarative; secrets supplied only through secret manager/file descriptors, not committed env files;
|
||||||
|
- migrations are forward-compatible for one release and have restore-tested rollback/roll-forward procedure.
|
||||||
|
|
||||||
|
## 10. Threat model summary
|
||||||
|
|
||||||
|
Threat actors: compromised agent, malicious skill, prompt injection in artifact/wiki, stolen device, rogue Connector, tenant user exceeding privilege, supply-chain compromise, replayed command, poisoned memory.
|
||||||
|
|
||||||
|
Controls: tenant isolation, mTLS device identity, short-lived command tokens, RBAC/ABAC, human approvals, immutable audit, content classification/redaction, egress policy, adapter sandbox, skill quarantine/signatures, provenance-aware retrieval, idempotency/replay protection, secret references, encrypted backup, revocation.
|
||||||
|
|
||||||
|
## 11. ADRs required before implementation
|
||||||
|
|
||||||
|
1. ADR-001 UI wrappers: Tauri + Capacitor versus alternative shared-client stack.
|
||||||
|
2. ADR-002 deployment topology and supported database/queue profile.
|
||||||
|
3. ADR-003 authentication: local bootstrap, OIDC providers, enterprise SSO phase.
|
||||||
|
4. ADR-004 vector backend and embedding data residency.
|
||||||
|
5. ADR-005 Connector sandbox baseline for Linux/Windows/macOS servers.
|
||||||
|
6. ADR-006 adapter SDK language and process isolation model.
|
||||||
42
docs/OPEN-QUESTIONS.md
Normal file
42
docs/OPEN-QUESTIONS.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Открытые решения
|
||||||
|
|
||||||
|
**Версия:** 0.1.0-draft
|
||||||
|
**Правило:** вопросы с severity `BLOCKER` должны быть закрыты ADR/approval до реализации затрагиваемой части.
|
||||||
|
|
||||||
|
| ID | Severity | Решение | Варианты / критерии | Владелец | Deadline | Статус |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| OQ-001 | BLOCKER | Модель продукта и deployment | single-tenant self-hosted first vs multi-tenant hosted; data residency, ops cost | Product/Architecture | До M0 exit | Open |
|
||||||
|
| OQ-002 | BLOCKER | Client stack | React+Tauri+Capacitor baseline vs Flutter/другое; security, parity, terminal/editor UX, team skills | Architecture | До M0 exit | Open |
|
||||||
|
| OQ-003 | BLOCKER | Auth baseline | local bootstrap + OIDC; enterprise SSO/SCIM phase; recovery and break-glass | Security/Product | До M1 | Open |
|
||||||
|
| OQ-004 | BLOCKER | Supported OS/Android API matrix | реальные устройства, distribution channels, update/signing ownership | Product/Release | До M0 exit | Open |
|
||||||
|
| OQ-005 | BLOCKER | Adapter MVP matrix | обязательны Hermes/OpenClaw; выбрать Claude/Codex/Gemini spike и exact pinned versions | Product/Integration | До M0 exit | Open |
|
||||||
|
| OQ-006 | BLOCKER | Connector sandbox | container/systemd users/Windows job objects/macOS sandbox; filesystem/network policies | Security/Architecture | До M2 | Open |
|
||||||
|
| OQ-007 | BLOCKER | Data classification/retention | classes, regions, default retention, legal hold/privacy delete | Security/Legal | До M1 | Open |
|
||||||
|
| OQ-008 | BLOCKER | Persistence/queue/vector stack | managed vs self-hosted; extensions, backup, data residency, rebuild | Architecture/Operations | До M1 | Open |
|
||||||
|
| OQ-009 | BLOCKER | Approval/risk policy | destructive definitions, dual-control, self-approval, in-flight budget action | Security/Product | До M1 | Open |
|
||||||
|
| OQ-010 | BLOCKER | License/business model | repository/product license, third-party redistribution, SDK/CLI terms | Owner/Legal | До external distribution | Open |
|
||||||
|
| OQ-011 | MAJOR | Offline mobile policy | exact safe mutation allowlist, cache sensitivity, retention and remote wipe | Product/Security | До M5 | Open |
|
||||||
|
| OQ-012 | MAJOR | Usage/cost normalization | currencies/units, authoritative providers, manual budgets, exchange rates | Product/Finance | До M3 | Open |
|
||||||
|
| OQ-013 | MAJOR | Memory embeddings | provider, local/remote, sensitivity, re-embedding version policy | Architecture/Security | До M4 | Open |
|
||||||
|
| OQ-014 | MAJOR | Skill signing/review | organization signing keys, scanner set, approval roles, revocation distribution | Security | До M4 | Open |
|
||||||
|
| OQ-015 | MAJOR | Handoff bundle limits | token/byte limits, summary algorithm, human preview UX, language handling | Product/Integration | До M3 | Open |
|
||||||
|
| OQ-016 | MAJOR | SLO ownership and pilot size | production profile, on-call, telemetry, capacity and pilot tenants | Operations/Product | До M6 | Open |
|
||||||
|
| OQ-017 | MINOR | Branding/localization | product name validation, Russian/English MVP, terminology | Product/Design | До UX freeze | Open |
|
||||||
|
| OQ-018 | MINOR | Notifications | FCM/email providers, privacy-safe previews, quiet hours | Product/Operations | До M5 | Open |
|
||||||
|
|
||||||
|
## Decision template
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# ADR-NNN: Title
|
||||||
|
Status: proposed | accepted | superseded
|
||||||
|
Date:
|
||||||
|
Owners:
|
||||||
|
Related: OQ-..., FR-..., NFR-...
|
||||||
|
|
||||||
|
## Context
|
||||||
|
## Options and evidence
|
||||||
|
## Decision
|
||||||
|
## Security/privacy/operational consequences
|
||||||
|
## Migration and rollback
|
||||||
|
## Validation
|
||||||
|
```
|
||||||
40
docs/RESEARCH.md
Normal file
40
docs/RESEARCH.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Исследование интеграционных поверхностей
|
||||||
|
|
||||||
|
**Дата проверки:** 2026-07-19
|
||||||
|
**Статус:** source notes for Specification v0.1.0
|
||||||
|
|
||||||
|
## Метод
|
||||||
|
|
||||||
|
Проверялись официальные страницы продуктов и протоколов. Сведения ниже описывают доступную интеграционную поверхность на дату проверки, но не гарантируют стабильность API или наличие функции в конкретном тарифе/версии. Перед реализацией каждого адаптера обязательны pinned-версия, contract tests и повторная проверка документации.
|
||||||
|
|
||||||
|
## Проверенные источники
|
||||||
|
|
||||||
|
| Runtime | Подтверждённая поверхность | Проектное решение | Источник |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Hermes Agent | HTTP API с `/v1/chat/completions`, `/v1/responses`, `/v1/runs`; session headers; отдельные profiles | Нативный HTTP adapter; capabilities определяются handshake, а не предположением | [Hermes API Server](https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server), [Profiles](https://hermes-agent.nousresearch.com/docs/user-guide/profiles) |
|
||||||
|
| OpenClaw | Gateway protocol предоставляет status, channels, models, chat, agent, sessions, nodes и approvals; схема является источником точного контракта | Нативный Gateway adapter с pinned schema/version и reconnect/resume | [Gateway protocol](https://docs.openclaw.ai/gateway/protocol), [Gateway CLI](https://docs.openclaw.ai/cli/gateway) |
|
||||||
|
| Claude Code | Agent SDK документирует sessions, permissions, hooks, subagents и MCP | SDK adapter; permission/approval события нормализуются без обхода политики Claude | [Agent SDK overview](https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-overview), [MCP](https://docs.anthropic.com/en/docs/claude-code/mcp) |
|
||||||
|
| OpenAI Codex | Для глубоких клиентов доступен app-server; также документированы SDK/headless use cases | App-server или SDK adapter после version-specific spike; CLI fallback только при структурированном выводе | [Codex App Server](https://learn.chatgpt.com/docs/app-server), [Codex resources](https://developers.openai.com/learn/codex) |
|
||||||
|
| OpenAI API / ChatGPT models | Responses API поддерживает conversation state; background mode допускает асинхронное выполнение | API adapter представляет API run, а не потребительский ChatGPT UI. Consumer ChatGPT account automation не входит в MVP | [Conversation state](https://platform.openai.com/docs/guides/conversation-state), [Background mode](https://platform.openai.com/docs/guides/background) |
|
||||||
|
| Gemini CLI | Документированы headless mode и MCP integration | Headless adapter с JSON output/exit semantics и explicit capability probe | [Gemini CLI](https://google-gemini.github.io/gemini-cli/), [Headless mode](https://google-gemini.github.io/gemini-cli/docs/cli/headless.html) |
|
||||||
|
| MCP | Стандартизирует discovery и вызов tools, resources и prompts | Используется как capability bridge, но не как полный lifecycle/session protocol | [Tools](https://modelcontextprotocol.io/specification/2025-06-18/server/tools), [Resources](https://modelcontextprotocol.io/specification/2025-06-18/server/resources), [Prompts](https://modelcontextprotocol.io/specification/2025-06-18/server/prompts) |
|
||||||
|
|
||||||
|
## Ограничения и выводы
|
||||||
|
|
||||||
|
1. **Нет универсальной семантики session/run/approval.** Нормализация должна сохранять vendor-specific payload в изолированном extension-поле и не скрывать потерю возможностей.
|
||||||
|
2. **MCP недостаточен для управления жизненным циклом агента.** Он полезен для tools/resources/prompts, но запуск, streaming, usage, cancel, checkpoint и resume задаются Agent Adapter Protocol.
|
||||||
|
3. **ChatGPT и OpenAI API — не одно и то же.** MVP не автоматизирует закрытый пользовательский UI ChatGPT и не извлекает из него токены/сессии.
|
||||||
|
4. **Лимиты не всегда доступны программно.** Connector принимает verified usage API, rate-limit headers, локальные метрики и ручные budget policies; приблизительные данные маркируются `estimated`.
|
||||||
|
5. **Handoff не переносит скрытые рассуждения.** Передаются только пользовательские сообщения, наблюдаемые tool results, проверенные факты, решения, артефакты, acceptance criteria и явно сформированный checkpoint.
|
||||||
|
6. **CLI-адаптеры рискованнее SDK/API.** Они требуют фиксированной версии, timeout/cancel contract, JSONL или иной структурированный канал, отдельный stderr и запрет parsing human UI как основного контракта.
|
||||||
|
7. **Capability negotiation обязательна.** UI не показывает resume, approvals, filesystem, terminal или usage как доступные, пока adapter handshake это не подтвердил.
|
||||||
|
|
||||||
|
## Неподтверждённые детали
|
||||||
|
|
||||||
|
Следующее не считается фактом до implementation spike:
|
||||||
|
|
||||||
|
- точная совместимость конкретных версий Codex app-server и Agent Control Center;
|
||||||
|
- полнота usage/quota API каждого провайдера;
|
||||||
|
- возможность безопасного resume после смены runtime без пользовательского checkpoint;
|
||||||
|
- лицензии на встраивание/redistribution каждого SDK и CLI;
|
||||||
|
- parity функций между personal, team и enterprise тарифами.
|
||||||
397
docs/SPECIFICATION.md
Normal file
397
docs/SPECIFICATION.md
Normal file
|
|
@ -0,0 +1,397 @@
|
||||||
|
# Техническое задание: Agent Control Center
|
||||||
|
|
||||||
|
| Поле | Значение |
|
||||||
|
|---|---|
|
||||||
|
| Версия | 0.1.0-draft |
|
||||||
|
| Дата | 2026-07-19 |
|
||||||
|
| Статус | **Draft — implementation blocked** |
|
||||||
|
| Владелец решения | Product owner / operator |
|
||||||
|
| Нормативный документ | Этот файл |
|
||||||
|
| Поддерживающие документы | `ARCHITECTURE.md`, `RESEARCH.md`, `OPEN-QUESTIONS.md` |
|
||||||
|
|
||||||
|
> Разработка продукта не начинается до закрытия блокирующих решений, G1 PASS и явного утверждения оператором. Формулировки MUST/SHALL обязательны; SHOULD требуют обоснования отклонения.
|
||||||
|
|
||||||
|
## 1. Назначение
|
||||||
|
|
||||||
|
Agent Control Center (ACC) — единое рабочее пространство для управления проектами, задачами и долгоживущими серверными ИИ-агентами через Web, Desktop и Android. Система обеспечивает контролируемый перенос наблюдаемого контекста между разными runtime, общую проектную память, реестр skills и wiki, не пытаясь переносить скрытые рассуждения модели или обходить политики провайдеров.
|
||||||
|
|
||||||
|
### 1.1 Цели и метрики результата
|
||||||
|
|
||||||
|
| Цель | Метрика MVP |
|
||||||
|
|---|---|
|
||||||
|
| Единое управление | ≥95% поддерживаемых run lifecycle действий доступны из всех трёх клиентов |
|
||||||
|
| Безопасный handoff | ≥99% принятых handoff не теряют objective, acceptance criteria, decisions и artifact refs по contract test |
|
||||||
|
| Общий контекст | 100% memory/wiki/skill результатов показывают scope и provenance |
|
||||||
|
| Контроль рисков | 100% destructive/high-risk действий имеют audit event; policy-required действия требуют approval |
|
||||||
|
| Наблюдаемость | ≥99% нормализованных run events доставлены либо восстановлены после reconnect в пределах retention |
|
||||||
|
| Практичность | p95 открытия проекта ≤2 с, p95 появления live event ≤1,5 с при целевой нагрузке |
|
||||||
|
|
||||||
|
### 1.2 Не-цели MVP
|
||||||
|
|
||||||
|
- замена IDE, Git hosting, CI/CD, issue tracker или model provider;
|
||||||
|
- автоматизация закрытого consumer UI ChatGPT либо извлечение browser cookies/session tokens;
|
||||||
|
- перенос hidden chain-of-thought, provider-internal state или секретов между агентами;
|
||||||
|
- полностью автономное переключение на платный/привилегированный агент без policy/approval;
|
||||||
|
- marketplace публичных skills;
|
||||||
|
- iOS-клиент;
|
||||||
|
- кросс-региональный active-active control plane;
|
||||||
|
- гарантированно точный остаток квоты, если runtime не предоставляет authoritative API.
|
||||||
|
|
||||||
|
## 2. Пользователи и роли
|
||||||
|
|
||||||
|
| Роль | Основные задачи |
|
||||||
|
|---|---|
|
||||||
|
| Organization Owner | tenant settings, billing/budgets, SSO, retention, emergency access |
|
||||||
|
| Workspace Admin | участники, connectors, agent policies, project templates |
|
||||||
|
| Project Lead | проекты, priorities, approvals, handoff, authoritative memory/wiki |
|
||||||
|
| Operator | наблюдение и управление runs, incidents, Connector health |
|
||||||
|
| Contributor | задачи, диалоги, artifacts, drafts memory/wiki |
|
||||||
|
| Viewer/Auditor | read-only view, audit export в разрешённой области |
|
||||||
|
| Server Connector | machine identity; исполняет только подписанные/авторизованные commands |
|
||||||
|
| AI Agent | untrusted workload identity с ограниченными capabilities и scope |
|
||||||
|
|
||||||
|
RBAC задаёт базовые права; ABAC учитывает tenant/workspace/project, sensitivity, action risk, agent capability и device assurance.
|
||||||
|
|
||||||
|
## 3. Термины
|
||||||
|
|
||||||
|
- **Agent** — зарегистрированная конфигурация runtime/model/tools на конкретном Connector.
|
||||||
|
- **Connector** — сервис рядом с агентами, устанавливающий исходящее защищённое соединение с Control Plane.
|
||||||
|
- **Adapter** — versioned integration с конкретным runtime.
|
||||||
|
- **TaskRun** — логическая попытка выполнить задачу; содержит один или несколько RunAttempt.
|
||||||
|
- **RunAttempt** — исполнение на одном агенте/runtime.
|
||||||
|
- **Checkpoint** — наблюдаемый, provenance-aware снимок переносимого состояния.
|
||||||
|
- **Handoff** — контролируемое создание следующего attempt из checkpoint.
|
||||||
|
- **Memory entry** — версионируемая запись факта/решения/ограничения и т. п. с scope и provenance.
|
||||||
|
- **Skill** — версионируемый пакет инструкций/ресурсов и, опционально, исполняемых assets.
|
||||||
|
- **Wiki** — версионируемое проектное знание в Markdown.
|
||||||
|
- **Capability** — функция, явно подтверждённая adapter handshake.
|
||||||
|
- **Measured/estimated/unknown usage** — authoritative, вычисленная или недоступная информация о лимитах.
|
||||||
|
|
||||||
|
## 4. Scope и релизы
|
||||||
|
|
||||||
|
### 4.1 MVP
|
||||||
|
|
||||||
|
- multi-tenant control plane и OIDC/local bootstrap;
|
||||||
|
- Web/PWA, Desktop, Android с общим UX contract;
|
||||||
|
- workspaces/projects/Kanban tasks/dependencies/artifacts;
|
||||||
|
- enrollment Connector, registry agent, capability/health view;
|
||||||
|
- run start/stream/approval/cancel/checkpoint/manual handoff;
|
||||||
|
- adapters: Hermes, OpenClaw и минимум один SDK/CLI runtime после spike; generic adapter contract;
|
||||||
|
- memory, skill registry, wiki, search;
|
||||||
|
- usage/budget signals, notifications, audit, backup/restore.
|
||||||
|
|
||||||
|
### 4.2 Post-MVP
|
||||||
|
|
||||||
|
- policy-governed automatic fallback;
|
||||||
|
- workflows/DAG orchestration и scheduled runs;
|
||||||
|
- enterprise SCIM/advanced DLP/legal hold;
|
||||||
|
- iOS and richer native integrations;
|
||||||
|
- public/organization skill catalog;
|
||||||
|
- analytics, cost optimization and provider routing.
|
||||||
|
|
||||||
|
## 5. Предпосылки и зависимости
|
||||||
|
|
||||||
|
1. Connector host поддерживает безопасное service execution и outbound TLS.
|
||||||
|
2. Runtime уже установлен/лицензирован владельцем; ACC не распространяет его без прав.
|
||||||
|
3. Provider credentials остаются в Connector-side secret store либо approved secret manager.
|
||||||
|
4. Control Plane располагает PostgreSQL, object storage, durable queue и backup destination.
|
||||||
|
5. Push notifications зависят от platform services и являются best-effort дополнением, не source of truth.
|
||||||
|
6. Семантика adapters определяется pinned version и contract tests; исследование — в `RESEARCH.md`.
|
||||||
|
7. Блокирующие продуктовые решения перечислены в `OPEN-QUESTIONS.md`.
|
||||||
|
|
||||||
|
## 6. Функциональные требования
|
||||||
|
|
||||||
|
Формат каждой строки: приоритет; предусловия; основной flow; ошибки/edge cases; acceptance test. `P0` обязателен для MVP, `P1` желателен при сохранении срока, `P2` post-MVP.
|
||||||
|
|
||||||
|
### 6.1 Identity, access, tenancy
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-IAM-001** | P0 | Новый deployment | Первый owner создаётся одноразовым bootstrap token; после первого успеха token инвалидируется | Повтор/expired token → 401 без user creation | **AT-FR-IAM-001:** второй вызов тем же token отклонён; ровно один owner и audit event |
|
||||||
|
| **FR-IAM-002** | P0 | Настроен IdP либо local auth | Login выдаёт short-lived access и rotating refresh credential, привязанный к device session | revoked/rotated credential → 401; replay отзывает credential family | **AT-FR-IAM-002:** rotation/replay integration test подтверждает отзыв и повторный login |
|
||||||
|
| **FR-IAM-003** | P0 | Actor состоит в tenant | Каждая операция проходит RBAC+ABAC и tenant scoping до чтения данных | IDOR/cross-tenant ID → 404, не раскрывая существование объекта | **AT-FR-IAM-003:** matrix test всех ролей и cross-tenant identifiers не обнаруживает утечек |
|
||||||
|
| **FR-IAM-004** | P0 | Risk policy требует approval | Создаётся approval с snapshot действия, approver scope и TTL; execution ждёт решение | self-approval запрещён политикой; expiry → blocked | **AT-FR-IAM-004:** high-risk command не доставлен Connector до валидного approval |
|
||||||
|
| **FR-IAM-005** | P1 | Пользователь управляет devices | Пользователь видит и отзывает device sessions; отзыв закрывает WS и refresh | offline client теряет write-доступ при следующей проверке | **AT-FR-IAM-005:** revoked device не обновляет task и получает auth event |
|
||||||
|
|
||||||
|
### 6.2 Connectors and agents
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-CON-001** | P0 | Admin создал одноразовый enrollment token | Connector регистрирует machine identity, public key, labels и version через outbound TLS | token reuse/tenant mismatch → reject и security audit | **AT-FR-CON-001:** повтор enrollment и подменённый tenant отклоняются |
|
||||||
|
| **FR-CON-002** | P0 | Connector enrolled | mTLS WSS поддерживает heartbeat, reconnect, cursor resume и encrypted bounded spool | duplicate/out-of-order events дедуплицируются/упорядочиваются; gap отмечается | **AT-FR-CON-002:** network fault test восстанавливает ordered stream без двойных side effects |
|
||||||
|
| **FR-CON-003** | P0 | Adapter установлен | Handshake публикует adapter/runtime versions, identity и capabilities snapshot | неизвестная schema/version → incompatible, запуск запрещён | **AT-FR-CON-003:** UI/API скрывают unsupported actions и блокируют forged capability |
|
||||||
|
| **FR-CON-004** | P0 | Admin имеет доступ | Agent создаётся из Connector+adapter+runtime config+policy; secret хранится только как reference | secret в request/log/event → validation failure/redaction alert | **AT-FR-CON-004:** secret canary отсутствует в DB, API, audit и logs |
|
||||||
|
| **FR-CON-005** | P0 | Agent зарегистрирован | Health показывает online/degraded/offline/incompatible, last seen, latency и active runs | stale heartbeat переводит в offline без удаления агента | **AT-FR-CON-005:** state transitions происходят по заданным thresholds и видны всем клиентам |
|
||||||
|
| **FR-CON-006** | P0 | Команда готова к dispatch | Каждая command имеет idempotency key, lease, deadline, policy digest и optional approval token | expired lease/replay/policy mismatch → не исполнять, вернуть typed outcome | **AT-FR-CON-006:** повтор start/cancel не создаёт второй native run/side effect |
|
||||||
|
| **FR-CON-007** | P1 | Доступна совместимая версия | Admin выполняет staged Connector/adapter upgrade с drain и rollback | active run не прерывается forced update; failed health → rollback | **AT-FR-CON-007:** upgrade fault test возвращает previous healthy version |
|
||||||
|
|
||||||
|
### 6.3 Workspaces, projects, tasks and artifacts
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-PRJ-001** | P0 | Authorized user | Создание workspace/project задаёт name, key, visibility, retention, default policies и wiki root | duplicate key → 409; invalid policy → 422 | **AT-FR-PRJ-001:** созданный project атомарно содержит defaults и audit event |
|
||||||
|
| **FR-PRJ-002** | P0 | Project существует | Task хранит title, description, status, priority, assignees, agent policy, acceptance criteria, labels, due date | stale revision → 409 с current revision | **AT-FR-PRJ-002:** optimistic concurrency не теряет параллельное изменение |
|
||||||
|
| **FR-PRJ-003** | P0 | Tasks существуют | Kanban поддерживает configurable columns, ordering, filters и bulk move в рамках policy | invalid transition/partial bulk → atomic reject с per-item reason | **AT-FR-PRJ-003:** одинаковый порядок/статусы наблюдаются Web/Desktop/Android |
|
||||||
|
| **FR-PRJ-004** | P0 | Tasks одного project | Dependencies образуют DAG; blocked task не стартует без authorized override | cycle/self-link → 422; deleted dependency сохраняет audit reference | **AT-FR-PRJ-004:** property test не позволяет создать цикл и корректно считает blocked |
|
||||||
|
| **FR-PRJ-005** | P0 | Actor имеет artifact permission | Artifact загружается multipart, получает hash, MIME, sensitivity, provenance и immutable version | hash mismatch/malware/policy violation → quarantine | **AT-FR-PRJ-005:** download проверяет ACL; изменённый blob не проходит integrity check |
|
||||||
|
| **FR-PRJ-006** | P1 | Есть Git integration | Project может хранить repository reference/branch/commit/PR metadata без provider secret | webhook replay/out-of-scope repo → reject | **AT-FR-PRJ-006:** task links commit metadata и не раскрывает integration token |
|
||||||
|
|
||||||
|
### 6.4 Runs, conversations, approvals and handoff
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-RUN-001** | P0 | Task runnable; agent online/capable | User выбирает agent, ввод, context scopes и budget; система создаёт TaskRun/Attempt и dispatch command | offline/incompatible/budget blocked → typed blocked state, без native start | **AT-FR-RUN-001:** successful start создаёт одну lineage и ordered initial events |
|
||||||
|
| **FR-RUN-002** | P0 | Attempt active | Нормализованные events stream в реальном времени: text, tool, progress, usage, approval, artifact, status | disconnect использует cursor resume; unsupported event сохраняется как vendor extension | **AT-FR-RUN-002:** reconnect не дублирует события и сохраняет sequence |
|
||||||
|
| **FR-RUN-003** | P0 | User sends message | Conversation message immutable после отправки, допускает correction message; sensitivity/redaction применяются до dispatch | слишком большой input → 413 с limits; prohibited secret → block | **AT-FR-RUN-003:** correction сохраняет original/provenance и agent получает разрешённую версию |
|
||||||
|
| **FR-RUN-004** | P0 | Adapter запрашивает approval | UI показывает точный action, args diff, risk, expiry и target; approve/deny подписывается actor identity | changed args после approval → approval invalid; timeout → denied/blocked policy | **AT-FR-RUN-004:** TOCTOU test блокирует command с изменённым digest |
|
||||||
|
| **FR-RUN-005** | P0 | Attempt active | Cancel поддерживает graceful и force (при праве), показывает acknowledgement и terminal outcome | lost Connector → cancelling_pending; повтор cancel идемпотентен | **AT-FR-RUN-005:** cancel fault test не переводит в cancelled без подтверждения/timeout policy |
|
||||||
|
| **FR-RUN-006** | P0 | Attempt имеет observable state | Checkpoint формирует objective, criteria, messages, verified facts, decisions, completed/pending work, errors, artifact refs и source hashes | hidden reasoning/secrets исключаются; oversized bundle bounded с manifest omissions | **AT-FR-RUN-006:** schema/secret tests и human-readable preview проходят до handoff |
|
||||||
|
| **FR-RUN-007** | P0 | Checkpoint valid; target capable | Manual handoff показывает source/target, estimated cost/limits и preview; создаёт новый Attempt, target подтверждает ingestion, затем source lease закрывается | target reject/timeout → source остаётся resumable; lineage не разрывается | **AT-FR-RUN-007:** fault injection в каждой фазе не теряет runnable state и не запускает два writer lease |
|
||||||
|
| **FR-RUN-008** | P0 | Usage/budget signal изменён | На rate limit/quota система классифицирует signal, ставит run в blocked/handoff_ready и предлагает совместимые targets | estimated signal явно маркируется; неизвестное не показывается как zero | **AT-FR-RUN-008:** 429/headers/local budget/unknown дают разные корректные UI states |
|
||||||
|
| **FR-RUN-009** | P1 | Run terminal | User может retry from checkpoint, fork с изменённым context или close; lineage и cost сохраняются | retry non-idempotent completed steps требует explicit plan/approval | **AT-FR-RUN-009:** retry не помечает старый attempt active и предупреждает о side effects |
|
||||||
|
|
||||||
|
### 6.5 Shared memory and retrieval
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-MEM-001** | P0 | Actor имеет write scope | Memory entry создаётся с kind, scope, provenance, verification, sensitivity, validity и content hash | отсутствующая provenance/запрещённый scope → 422/403 | **AT-FR-MEM-001:** запись без обязательных metadata не индексируется |
|
||||||
|
| **FR-MEM-002** | P0 | Entry существует | Update создаёт immutable version/supersedes link; concurrent contradiction создаёт conflict, не silent overwrite | stale revision → conflict response | **AT-FR-MEM-002:** concurrent property test сохраняет обе версии и conflict record |
|
||||||
|
| **FR-MEM-003** | P0 | Query authorized | Retrieval применяет ACL до lexical/semantic ranking, filters scope/time/type/verification и возвращает citations | недоступная запись не влияет даже через count/timing в заданном threat model | **AT-FR-MEM-003:** cross-scope leakage suite не находит content/metadata |
|
||||||
|
| **FR-MEM-004** | P0 | Context bundle строится | Context Broker выбирает bounded verified context по policy/token budget и записывает retrieval manifest | overflow сокращает низший приоритет и сообщает omissions | **AT-FR-MEM-004:** deterministic fixture даёт bounded bundle и воспроизводимый manifest |
|
||||||
|
| **FR-MEM-005** | P0 | Agent предлагает memory | Agent-created запись остаётся draft/unverified до policy либо human review | prompt injection не может повысить trust/scope | **AT-FR-MEM-005:** malicious artifact не создаёт authoritative memory |
|
||||||
|
| **FR-MEM-006** | P1 | Entry устарела/ошибочна | Authorized user revokes/expires/supersedes entry; прошлые runs сохраняют ссылку на использованную version | hard delete ограничен retention/privacy workflow | **AT-FR-MEM-006:** новый retrieval исключает revoked, старый manifest остаётся auditable |
|
||||||
|
| **FR-MEM-007** | P1 | Index повреждён/сменён | Derived vector/full-text index полностью перестраивается из authoritative source | rebuild failure не удаляет source; degraded search обозначен | **AT-FR-MEM-007:** empty-index restore даёт эквивалентный authorized result set |
|
||||||
|
|
||||||
|
### 6.6 Skills registry
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-SKL-001** | P0 | Contributor имеет publish-draft | Skill version загружается с manifest, digest, provenance, compatibility и permission declaration; version immutable | digest mismatch/zip traversal/oversize → quarantine | **AT-FR-SKL-001:** malicious package corpus не выходит из scanner sandbox |
|
||||||
|
| **FR-SKL-002** | P0 | Version scanned | Reviewer видит diff, permissions, executable assets и sources; устанавливает approved/rejected/quarantined | author self-approval запрещается policy | **AT-FR-SKL-002:** executable skill нельзя активировать без required review |
|
||||||
|
| **FR-SKL-003** | P0 | Approved compatible version | Project/agent activation pin-ит exact version и grants; Adapter получает только разрешённый bundle | incompatible runtime/capability → blocked | **AT-FR-SKL-003:** update latest не меняет pinned active run |
|
||||||
|
| **FR-SKL-004** | P0 | Новая version опубликована | UI показывает semantic diff, risk changes и rollout; rollback возвращает предыдущий pin | revoked vulnerable version нельзя активировать заново | **AT-FR-SKL-004:** staged rollout/rollback сохраняет audit и deterministic resolution |
|
||||||
|
| **FR-SKL-005** | P1 | User ищет skill | Search/filter по owner, tags, compatibility, review state; results показывают trust/provenance | quarantined скрыт для non-admin | **AT-FR-SKL-005:** ACL/trust filters согласованы API и все клиенты |
|
||||||
|
|
||||||
|
### 6.7 Wiki
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-WIK-001** | P0 | Project существует | Wiki page хранит Markdown, path/title, aliases, ACL, status draft/published и immutable revisions | path collision/stale revision → 409 | **AT-FR-WIK-001:** concurrent edit не теряет content и предлагает merge |
|
||||||
|
| **FR-WIK-002** | P0 | Pages/artifacts существуют | Backlinks, links и attachments резолвятся version-aware; broken links видимы | forbidden target не раскрывает title | **AT-FR-WIK-002:** link checker и ACL suite проходят на mixed-scope fixture |
|
||||||
|
| **FR-WIK-003** | P0 | Agent генерирует страницу | Generated content сохраняется draft с citations/provenance; authoritative publish требует policy review | unsupported citation → flagged, не published | **AT-FR-WIK-003:** agent не может самостоятельно повысить draft до authoritative |
|
||||||
|
| **FR-WIK-004** | P1 | Query authorized | Full-text/semantic search возвращает snippets, revision, scope и citations | stale index отмечается; ACL до ranking | **AT-FR-WIK-004:** index rebuild и leakage tests эквивалентны memory retrieval controls |
|
||||||
|
|
||||||
|
### 6.8 Usage, notifications and audit
|
||||||
|
|
||||||
|
| ID | Pri | Предусловия | Требование и основной flow | Ошибки / edge cases | Acceptance |
|
||||||
|
|---|---:|---|---|---|---|
|
||||||
|
| **FR-OPS-001** | P0 | Adapter/provider signal доступен | Usage Service нормализует units, window, reset, source и confidence measured/estimated/unknown | несопоставимые units не суммируются как одно значение | **AT-FR-OPS-001:** fixtures всех confidence states визуально/в API различимы |
|
||||||
|
| **FR-OPS-002** | P0 | Budget policy задана | Soft threshold уведомляет; hard threshold блокирует новый dispatch либо требует override approval | in-flight policy задаёт allow/checkpoint/cancel, не подразумевается | **AT-FR-OPS-002:** boundary tests на reset/race/timezone исполняют выбранную policy ровно один раз |
|
||||||
|
| **FR-OPS-003** | P0 | Event соответствует preference | In-app и push notification дедуплицируются, deep-link ведёт к объекту после auth | push failure не меняет authoritative state | **AT-FR-OPS-003:** duplicate event даёт одно notification; revoked user не получает content |
|
||||||
|
| **FR-OPS-004** | P0 | Security/lifecycle action | Append-only audit хранит actor/workload, action, target, result, policy, correlation, timestamp и safe diff | sensitive payload redacted; gap/tamper observable | **AT-FR-OPS-004:** audit completeness test покрывает auth, policy, run, handoff, skill и admin actions |
|
||||||
|
| **FR-OPS-005** | P1 | Auditor authorized | Filter/export audit формирует signed manifest и bounded export без запрещённых данных | oversized export асинхронен; expired link → 410 | **AT-FR-OPS-005:** export hash проверяется и obeys tenant/time/ACL boundaries |
|
||||||
|
|
||||||
|
## 7. Нефункциональные требования
|
||||||
|
|
||||||
|
### 7.1 Security and privacy
|
||||||
|
|
||||||
|
| ID | Требование | Проверка |
|
||||||
|
|---|---|---|
|
||||||
|
| **NFR-SEC-001** | TLS 1.3 предпочтительно, минимум TLS 1.2 по утверждённой policy; Connector mTLS; encryption at rest для DB/object/backup | **AT-NFR-SEC-001:** automated TLS/config scan и restore encrypted backup |
|
||||||
|
| **NFR-SEC-002** | Credentials только в approved secret store; API/log/audit/artifact проходят secret redaction; rotation без redeploy Control Plane | **AT-NFR-SEC-002:** canary secret e2e scan и rotation test |
|
||||||
|
| **NFR-SEC-003** | OWASP ASVS L2 baseline для web/API; mobile secure storage; desktop bridge allowlist и CSP | **AT-NFR-SEC-003:** SAST/DAST/dependency/mobile/desktop security gates без high findings |
|
||||||
|
| **NFR-SEC-004** | Tenant isolation enforced server-side and tested на direct IDs, search, events, exports, caches и vectors | **AT-NFR-SEC-004:** adversarial multi-tenant suite имеет zero cross-tenant disclosures |
|
||||||
|
| **NFR-SEC-005** | Prompt/tool output/artifacts считаются untrusted; provenance, quarantine, content-type validation, no instruction privilege escalation | **AT-NFR-SEC-005:** injection corpus не меняет policy/scope/approval state |
|
||||||
|
| **NFR-SEC-006** | Command replay protection, idempotency, signed policy/approval digest и server-authoritative time | **AT-NFR-SEC-006:** replay/TOCTOU/clock-skew suite не повторяет side effects |
|
||||||
|
| **NFR-SEC-007** | Data export/delete/privacy workflow с legal retention override; deletion tombstone и verified background purge | **AT-NFR-SEC-007:** lifecycle test подтверждает export completeness и purge по policy |
|
||||||
|
| **NFR-SEC-008** | SBOM, pinned dependencies, signed release artifacts и provenance; critical CVE policy блокирует release | **AT-NFR-SEC-008:** release gate проверяет SBOM/signature/provenance и policy thresholds |
|
||||||
|
|
||||||
|
### 7.2 Reliability, consistency and recovery
|
||||||
|
|
||||||
|
| ID | Требование | Проверка |
|
||||||
|
|---|---|---|
|
||||||
|
| **NFR-REL-001** | Production monthly availability target 99.5% без плановых окон; status component-wise | **AT-NFR-REL-001:** SLI calculation from synthetic checks and documented exclusions |
|
||||||
|
| **NFR-REL-002** | At-least-once command/event transport plus application idempotency; per-run ordering and explicit gap | **AT-NFR-REL-002:** chaos test disconnect/duplicate/reorder не повторяет side effects |
|
||||||
|
| **NFR-REL-003** | RPO ≤15 мин, RTO ≤4 ч для production profile; restore drill минимум ежеквартально | **AT-NFR-REL-003:** timed clean-environment restore meets RPO/RTO and integrity checks |
|
||||||
|
| **NFR-REL-004** | Run lease исключает двух concurrent writers; failover не заявляет success без runtime evidence | **AT-NFR-REL-004:** partition test preserves single-writer invariant |
|
||||||
|
| **NFR-REL-005** | Schema migrations resumable, backup-first, observable; совместимость server/client/Connector минимум N-1 | **AT-NFR-REL-005:** upgrade/rollback matrix N and N-1 passes with representative data |
|
||||||
|
|
||||||
|
### 7.3 Performance and capacity
|
||||||
|
|
||||||
|
Целевая MVP-нагрузка: 100 concurrent users, 50 connected Connectors, 500 registered agents, 200 concurrent runs, 10 000 projects, 1 000 000 tasks, 10 000 000 run events и 1 000 000 memory/wiki revisions на deployment. Увеличение требует capacity test, а не предположения линейности.
|
||||||
|
|
||||||
|
| ID | Требование | Проверка |
|
||||||
|
|---|---|---|
|
||||||
|
| **NFR-PERF-001** | p95 read API ≤500 мс, write acknowledgement ≤800 мс при target load, без provider runtime latency | **AT-NFR-PERF-001:** reproducible load profile; error rate <1% excluding intentional 4xx |
|
||||||
|
| **NFR-PERF-002** | p95 live event latency Connector→online client ≤1.5 с; reconnect catch-up 10k events ≤30 с | **AT-NFR-PERF-002:** instrumented streaming benchmark |
|
||||||
|
| **NFR-PERF-003** | Project/Kanban initial usable view p95 ≤2 с broadband и ≤4 с simulated 4G, warm cache | **AT-NFR-PERF-003:** Web/Desktop/Android performance test with declared devices |
|
||||||
|
| **NFR-PERF-004** | Search p95 ≤2 с на target corpus; context bundle p95 ≤3 с до runtime dispatch | **AT-NFR-PERF-004:** representative ACL-heavy corpus benchmark |
|
||||||
|
|
||||||
|
### 7.4 UX, accessibility and portability
|
||||||
|
|
||||||
|
| ID | Требование | Проверка |
|
||||||
|
|---|---|---|
|
||||||
|
| **NFR-UX-001** | Web соответствует WCAG 2.2 AA; keyboard, focus, contrast, screen-reader labels; native wrappers сохраняют semantics | **AT-NFR-UX-001:** automated scan + manual keyboard/screen-reader checklist on critical journeys |
|
||||||
|
| **NFR-UX-002** | Critical action показывает target, consequence, risk and status; destructive action требует confirmation/approval по policy | **AT-NFR-UX-002:** usability acceptance для run/cancel/handoff/skill activation/admin |
|
||||||
|
| **NFR-UX-003** | UI различает measured/estimated/unknown, queued/running/blocked/offline и stale/fresh data не только цветом | **AT-NFR-UX-003:** visual/accessibility state matrix passes |
|
||||||
|
| **NFR-PORT-001** | Web: последние 2 major Chrome/Edge/Firefox/Safari; responsive ≥360 CSS px | **AT-NFR-PORT-001:** browser matrix smoke/e2e |
|
||||||
|
| **NFR-PORT-002** | Desktop MVP: Windows 11, macOS current+previous, Ubuntu 24.04 LTS; final matrix утверждается ADR | **AT-NFR-PORT-002:** signed install/upgrade/uninstall and critical journeys per OS |
|
||||||
|
| **NFR-PORT-003** | Android MVP: API level определяется ADR, target current Play policy; degraded read cache offline, writes queued only для explicitly safe operations | **AT-NFR-PORT-003:** device/emulator matrix and offline conflict tests |
|
||||||
|
| **NFR-PORT-004** | Клиенты version-aware: unsupported server API получает upgrade-required, а не undefined behavior | **AT-NFR-PORT-004:** compatibility matrix N/N-1/incompatible versions |
|
||||||
|
|
||||||
|
### 7.5 Operations and observability
|
||||||
|
|
||||||
|
| ID | Требование | Проверка |
|
||||||
|
|---|---|---|
|
||||||
|
| **NFR-OPS-001** | Structured logs, metrics, traces с correlation/run/connector IDs; content/secrets excluded by default | **AT-NFR-OPS-001:** e2e trace links command to result; canary absent from telemetry |
|
||||||
|
| **NFR-OPS-002** | Alerts покрывают availability, queue lag, event gaps, Connector churn, auth anomalies, backup/restore, storage and error budgets | **AT-NFR-OPS-002:** alert tests reach on-call route with runbook links |
|
||||||
|
| **NFR-OPS-003** | Health/readiness различают process, dependencies and migration state; readiness false during unsafe state | **AT-NFR-OPS-003:** dependency fault matrix produces expected health codes |
|
||||||
|
| **NFR-OPS-004** | Retention configurable per tenant within operator bounds: audit ≥365d default, events 90d, artifacts/memory/wiki project policy, telemetry 30d; legal hold overrides purge | **AT-NFR-OPS-004:** time-travel retention suite validates purge/hold/export |
|
||||||
|
| **NFR-OPS-005** | Admin operations and incident recovery documented as executable runbooks; quarterly restore and Connector revocation drills | **AT-NFR-OPS-005:** fresh operator completes sampled runbooks without tribal knowledge |
|
||||||
|
|
||||||
|
## 8. UI/UX specification
|
||||||
|
|
||||||
|
### 8.1 Information architecture
|
||||||
|
|
||||||
|
Primary navigation: Home, Workspaces, Projects, Tasks, Runs, Agents, Memory, Skills, Wiki, Usage, Notifications; Admin adds Connectors, Members, Policies, Audit, System.
|
||||||
|
|
||||||
|
### 8.2 Critical screens
|
||||||
|
|
||||||
|
1. **Home:** assigned/blocked tasks, active runs, approvals, quota warnings, unhealthy Connectors.
|
||||||
|
2. **Project:** overview, Kanban/list, runs, artifacts, memory, skills, wiki, settings.
|
||||||
|
3. **Task detail:** requirements/criteria, dependencies, conversation, run timeline, agent selector, context preview, artifacts.
|
||||||
|
4. **Run console:** ordered event stream, status/usage, approvals, checkpoint/cancel/handoff controls, reconnect indicator.
|
||||||
|
5. **Handoff dialog:** reason, source/target capabilities, unavailable features, usage confidence, exact context preview/omissions, policy/approval impact.
|
||||||
|
6. **Agent registry:** runtime/adapter versions, Connector, health, capabilities, active work, limits, policy.
|
||||||
|
7. **Memory:** scope/type/trust filters, citations, conflicts, version history, revoke/supersede.
|
||||||
|
8. **Skills:** manifest/diff/permissions/trust, version pins, activation/rollout/rollback.
|
||||||
|
9. **Wiki:** tree/editor/preview/backlinks/history/citations/draft-publish state.
|
||||||
|
10. **Admin:** Connector enrollment/revocation, policies, audit and retention.
|
||||||
|
|
||||||
|
### 8.3 Client parity
|
||||||
|
|
||||||
|
Все клиенты MUST поддерживать read/triage, task updates, run observation, approvals и manual handoff. Server/Connector/retention/security administration MAY быть ограничено Web/Desktop, но Android показывает понятную причину и deep-link, а не скрывает существование операции.
|
||||||
|
|
||||||
|
### 8.4 Offline/conflicts
|
||||||
|
|
||||||
|
- Read cache показывает `last_synced_at` и может содержать только разрешённые non-secret данные.
|
||||||
|
- Offline write по умолчанию запрещён для approvals, run actions, policy, skill activation, membership и secrets.
|
||||||
|
- Safe task/wiki draft edits используют client mutation ID и base revision; conflict не разрешается last-write-wins молча.
|
||||||
|
|
||||||
|
## 9. API и event contract
|
||||||
|
|
||||||
|
Полный baseline endpoints описан в `ARCHITECTURE.md`. Общие правила:
|
||||||
|
|
||||||
|
- JSON UTF-8; version prefix `/v1`; UUID/ULID opaque IDs.
|
||||||
|
- Commands требуют `Idempotency-Key`; mutations возвращают revision/ETag.
|
||||||
|
- List: cursor pagination, stable ordering, bounded page size, explicit filters.
|
||||||
|
- Errors: `code`, localized-safe `message`, `correlation_id`, `retryable`, `details` без секретов.
|
||||||
|
- 401 — нет/истёк auth; 403 — известный actor без права; cross-tenant opaque object — 404; 409 — revision/state/idempotency conflict; 422 — semantic validation; 429 — rate/budget с source/confidence; 503 — dependency/runtime unavailable.
|
||||||
|
- WS events: schema version, globally unique ID, object/run sequence, timestamp, classification; client подтверждает cursor.
|
||||||
|
- Breaking change требует новой major API/AAP version и migration guide.
|
||||||
|
|
||||||
|
## 10. Data lifecycle
|
||||||
|
|
||||||
|
1. Authoritative records — PostgreSQL/object storage; search/vector — rebuildable derivatives.
|
||||||
|
2. Artifacts, wiki, memory и skills versioned; mutable metadata меняется optimistic concurrency.
|
||||||
|
3. Soft delete скрывает объект; purge идёт после retention/hold checks и создаёт non-sensitive tombstone.
|
||||||
|
4. Audit append-only; correction создаёт compensating event.
|
||||||
|
5. Backup охватывает DB, objects, encryption metadata, configuration manifests; секреты восстанавливаются отдельным approved process.
|
||||||
|
6. Tenant export включает schemas, versions, provenance and checksums, но не provider credentials/hidden reasoning.
|
||||||
|
|
||||||
|
## 11. State invariants
|
||||||
|
|
||||||
|
- Один TaskRun имеет не более одного writable active Attempt lease.
|
||||||
|
- Terminal Attempt не возвращается в active; retry/fork создаёт новый Attempt.
|
||||||
|
- Handoff не закрывает source resumability до подтверждения target ingestion.
|
||||||
|
- Capability используется только из актуального compatible handshake snapshot.
|
||||||
|
- Approval валиден только для exact action/policy/arguments digest и не переживает expiry/revocation.
|
||||||
|
- Memory/wiki/skill trust не повышается на основании инструкции внутри untrusted content.
|
||||||
|
- Cross-tenant references не существуют на уровне API, queue, cache, vector и export.
|
||||||
|
- `unknown` usage не преобразуется в `0` или `unlimited`.
|
||||||
|
|
||||||
|
## 12. Acceptance strategy и quality gates
|
||||||
|
|
||||||
|
### 12.1 Test layers
|
||||||
|
|
||||||
|
- unit/property tests: state machines, policies, DAG, idempotency, conflicts, redaction;
|
||||||
|
- contract tests: каждый AAP adapter против pinned runtime fixture;
|
||||||
|
- integration: DB/queue/object/Connector, auth, search, migration;
|
||||||
|
- e2e: Web/Desktop/Android critical journeys;
|
||||||
|
- security: tenant isolation, injection, replay, secrets, sandbox, supply chain;
|
||||||
|
- chaos/recovery: network partition, duplicate/reorder, process/DB/queue failure, restore;
|
||||||
|
- performance/accessibility/compatibility matrices;
|
||||||
|
- user acceptance на сценариях ниже.
|
||||||
|
|
||||||
|
Каждый `FR-*` и `NFR-*` имеет одноимённый `AT-*` в таблицах выше. CI/QA case может реализовать несколько AT, но отчёт MUST сохранять прямое отображение ID→результат→evidence.
|
||||||
|
|
||||||
|
### 12.2 End-to-end acceptance journeys
|
||||||
|
|
||||||
|
- **E2E-001 Onboarding:** owner bootstrap → IdP/local login → Connector enrollment → Hermes/OpenClaw agent discovery → capability view.
|
||||||
|
- **E2E-002 Project work:** project → dependent tasks → criteria → artifact → start run → live events → approval → success.
|
||||||
|
- **E2E-003 Quota handoff:** active run получает measured/estimated limit → checkpoint preview → manual compatible target → ingestion → continuation без duplicate writer.
|
||||||
|
- **E2E-004 Shared knowledge:** agent proposes memory/wiki draft → reviewer verifies → second agent retrieves citation → revoked version больше не попадает в новый context.
|
||||||
|
- **E2E-005 Skill lifecycle:** upload malicious/valid packages → quarantine/review → pin → staged activation → rollback.
|
||||||
|
- **E2E-006 Failure recovery:** Connector disconnect during run → spool/reconnect/cursor resume → no duplicate side effect → audit continuity.
|
||||||
|
- **E2E-007 Cross-client:** task/run started Web, approved Android, observed Desktop; state/revisions identical.
|
||||||
|
- **E2E-008 Tenant security:** attacker probes IDs/search/events/export/vector timing; no unauthorized disclosure.
|
||||||
|
|
||||||
|
### 12.3 Release gates
|
||||||
|
|
||||||
|
- G0 decisions: blocking open questions/ADRs approved.
|
||||||
|
- G1 requirements: completeness, traceability, measurable NFR, security/privacy review — PASS.
|
||||||
|
- G2 implementation: tests, independent review, migration/recovery evidence — PASS.
|
||||||
|
- P1 security: no unresolved critical/high; medium accepted by owner with expiry.
|
||||||
|
- P2 supply-chain/Watcher advisory: PASS or explicit operator disposition.
|
||||||
|
- P3 publish/deploy: exact candidate, clean tree, CI/evidence, rollback and explicit approval.
|
||||||
|
|
||||||
|
## 13. Delivery plan
|
||||||
|
|
||||||
|
| Milestone | Deliverable | Exit criteria |
|
||||||
|
|---|---|---|
|
||||||
|
| M0 Discovery/ADRs | decisions, threat model, UX prototypes, adapter spikes | all blocking questions closed; executable contract fixtures |
|
||||||
|
| M1 Platform skeleton | auth/tenant, project/task, audit, CI/CD, observability | isolation/security baseline and Web shell |
|
||||||
|
| M2 Connector/AAP | enrollment, command/event transport, Hermes/OpenClaw adapters | chaos/idempotency/compatibility tests pass |
|
||||||
|
| M3 Runs/handoff | console, approvals, checkpoint, manual handoff, usage | E2E-002/003/006 pass |
|
||||||
|
| M4 Knowledge | memory, skills, wiki, context broker | E2E-004/005 and leakage tests pass |
|
||||||
|
| M5 Clients | Desktop/Android wrappers, push/offline-safe flows | E2E-007 + platform/accessibility matrices |
|
||||||
|
| M6 Hardening/pilot | backup/restore, performance, runbooks, pilot migration | all gates, SLO evidence and operator sign-off |
|
||||||
|
|
||||||
|
Оценки срока/команды не фиксируются до M0 spikes и ADR; псевдоточные даты запрещены.
|
||||||
|
|
||||||
|
## 14. Риски и меры
|
||||||
|
|
||||||
|
| Риск | Влияние | Мера |
|
||||||
|
|---|---|---|
|
||||||
|
| Vendor API/CLI drift | adapter outage/data loss | pinned versions, capability handshake, contract CI, N-1 policy |
|
||||||
|
| Handoff semantic loss | повтор работы/ошибка | observable checkpoint schema, preview, provenance, target ack, lineage |
|
||||||
|
| Poisoned shared memory | persistent compromise | untrusted drafts, verification, provenance, ACL-before-retrieval, revoke |
|
||||||
|
| Skill supply chain | remote execution | quarantine, scanner, declared permissions, sandbox, signatures/review |
|
||||||
|
| Quota uncertainty | wrong routing expectation | measured/estimated/unknown, policies, no false precision |
|
||||||
|
| Secret leakage through agents | credential compromise | connector-side refs, redaction, DLP, least privilege, audit |
|
||||||
|
| Event duplication/partition | duplicate side effects | idempotency, leases, ordering, cursor, reconciliation |
|
||||||
|
| Cross-tenant search leak | privacy breach | server-side ACL before indexing/ranking, adversarial tests |
|
||||||
|
| Shared UI wrapper limitations | inconsistent UX/security | ADR/spike, narrow native bridge, parity contract |
|
||||||
|
| Scope expansion | delayed MVP | strict non-goals, P0/P1/P2, change-control and traceability |
|
||||||
|
|
||||||
|
## 15. Change control and Definition of Ready
|
||||||
|
|
||||||
|
Любое изменение P0 scope, trust boundary, data model, retention, API/AAP или supported platform требует обновить version, affected requirement IDs, ATs, risks, ADR/open question и migration impact.
|
||||||
|
|
||||||
|
Implementation task считается Ready только если:
|
||||||
|
|
||||||
|
- связана с утверждённым requirement/AT ID;
|
||||||
|
- входы, output, errors, permissions и telemetry определены;
|
||||||
|
- зависимости/миграция/rollback известны;
|
||||||
|
- test approach согласован;
|
||||||
|
- отсутствует unresolved blocking question;
|
||||||
|
- G1 не заблокирован.
|
||||||
|
|
||||||
|
## 16. Approval record
|
||||||
|
|
||||||
|
| Роль | Имя | Решение | Дата | Версия |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Product owner/operator | — | Pending | — | 0.1.0-draft |
|
||||||
|
| Architecture | — | Pending | — | 0.1.0-draft |
|
||||||
|
| Security/privacy | — | Pending | — | 0.1.0-draft |
|
||||||
|
| Operations | — | Pending | — | 0.1.0-draft |
|
||||||
46
docs/TRACEABILITY.md
Normal file
46
docs/TRACEABILITY.md
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
# Traceability matrix
|
||||||
|
|
||||||
|
**Версия:** 0.1.0-draft
|
||||||
|
**Статус значений:** `Specified` означает «описано и имеет acceptance contract», а не «реализовано».
|
||||||
|
|
||||||
|
## Пользовательский запрос → нормативные требования
|
||||||
|
|
||||||
|
| Верхнеуровневый запрос | Нормативные требования | Архитектурный артефакт | Acceptance evidence | Статус |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Единое рабочее пространство | FR-PRJ-001..006, FR-RUN-001..009, NFR-UX-001..003 | `ARCHITECTURE.md` §1–3 | E2E-002, E2E-007 | Specified |
|
||||||
|
| Проекты и задачи | FR-PRJ-001..006 | canonical entities + Project Service | AT-FR-PRJ-001..006 | Specified |
|
||||||
|
| Управление серверными ИИ-агентами | FR-CON-001..007, FR-RUN-001..009 | outbound Connector + AAP | E2E-001, E2E-002, E2E-006 | Specified |
|
||||||
|
| Hermes | FR-CON-003..006, AAP contract | Hermes native HTTP adapter; `RESEARCH.md` | pinned adapter contract suite (M2) | Specified; spike pending |
|
||||||
|
| OpenClaw | FR-CON-003..006, AAP contract | OpenClaw Gateway adapter; `RESEARCH.md` | pinned adapter contract suite (M2) | Specified; spike pending |
|
||||||
|
| Claude Code | FR-CON-003..006, AAP contract | Agent SDK adapter; `RESEARCH.md` | adapter spike/contract suite | Specified; OQ-005 open |
|
||||||
|
| OpenAI Codex | FR-CON-003..006, AAP contract | app-server/SDK adapter; `RESEARCH.md` | adapter spike/contract suite | Specified; OQ-005 open |
|
||||||
|
| ChatGPT/OpenAI | FR-CON-003..006, FR-RUN-001..009 | Responses/Conversations API adapter; consumer ChatGPT UI excluded | API adapter contract suite | Specified; boundary explicit |
|
||||||
|
| Gemini | FR-CON-003..006, AAP contract | headless structured adapter; `RESEARCH.md` | adapter spike/contract suite | Specified; OQ-005 open |
|
||||||
|
| Web-клиент | NFR-UX-001..003, NFR-PORT-001/004 | shared React UI/PWA baseline | E2E-007 + browser matrix | Specified; ADR-001 open |
|
||||||
|
| Desktop-клиент | NFR-UX-001..003, NFR-PORT-002/004 | Tauri wrapper baseline | E2E-007 + OS install/upgrade matrix | Specified; ADR-001/OQ-004 open |
|
||||||
|
| Android-клиент | NFR-UX-001..003, NFR-PORT-003/004 | Capacitor wrapper baseline | E2E-007 + device/offline matrix | Specified; ADR-001/OQ-004 open |
|
||||||
|
| Переключение при исчерпании лимитов | FR-RUN-006..009, FR-OPS-001..002, NFR-REL-004 | checkpoint/handoff state machine + Usage Service | E2E-003; fault/boundary tests | Specified |
|
||||||
|
| Общая память проекта | FR-MEM-001..007, NFR-SEC-004/005/007 | Context Broker + Memory Service | E2E-004; leakage/conflict/rebuild tests | Specified |
|
||||||
|
| База skills | FR-SKL-001..005, NFR-SEC-005/008 | Skill Registry + quarantine/review/pinning | E2E-005 | Specified |
|
||||||
|
| Wiki | FR-WIK-001..004 | Wiki Service + revision/citation model | E2E-004 + AT-FR-WIK-* | Specified |
|
||||||
|
| Безопасность, approvals, audit | FR-IAM-001..005, FR-OPS-004..005, NFR-SEC-001..008 | Identity/Policy/Audit + threat model | E2E-008 + security gates | Specified |
|
||||||
|
| Архитектура и модель данных | SPEC §9–11; ARCH §1–8 | `ARCHITECTURE.md` | structural G1 + later migration/contract tests | Specified |
|
||||||
|
| API и события | SPEC §9; FR-CON/RUN | REST/WSS/AAP baseline | adapter/API contract tests | Specified |
|
||||||
|
| Acceptance-тесты | каждый FR/NFR связан с одноимённым AT | SPEC §12 | `scripts/validate_spec.py`, QA evidence in implementation phase | Specified |
|
||||||
|
|
||||||
|
## Артефакты → назначение
|
||||||
|
|
||||||
|
| Файл | Назначение | Gate |
|
||||||
|
|---|---|---|
|
||||||
|
| `README.md` | входная точка, статус и запрет реализации | G1 |
|
||||||
|
| `docs/SPECIFICATION.md` | канонические требования и acceptance contract | G1 |
|
||||||
|
| `docs/ARCHITECTURE.md` | component/data/API/AAP baseline и trust boundaries | G1/ADR |
|
||||||
|
| `docs/RESEARCH.md` | source-backed integration constraints | G1 + implementation spikes |
|
||||||
|
| `docs/OPEN-QUESTIONS.md` | blocking decisions и owners | G0 |
|
||||||
|
| `docs/TRACEABILITY.md` | запрос → requirement → evidence mapping | G1 |
|
||||||
|
| `scripts/validate_spec.py` | machine-checkable structural invariants | G1/CI |
|
||||||
|
| `tests/test_validate_spec.py` | regression tests validator/trace mapping | G1/CI |
|
||||||
|
|
||||||
|
## Реализация
|
||||||
|
|
||||||
|
На момент этой версии отсутствует. Ни одна строка `Specified` не должна интерпретироваться как готовая функция. Переход к реализации разрешён только после G0/G1 и явного operator approval.
|
||||||
132
scripts/validate_spec.py
Normal file
132
scripts/validate_spec.py
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Structural validator for Agent Control Center specification documents."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
SPEC = ROOT / "docs" / "SPECIFICATION.md"
|
||||||
|
ARCH = ROOT / "docs" / "ARCHITECTURE.md"
|
||||||
|
RESEARCH = ROOT / "docs" / "RESEARCH.md"
|
||||||
|
QUESTIONS = ROOT / "docs" / "OPEN-QUESTIONS.md"
|
||||||
|
TRACEABILITY = ROOT / "docs" / "TRACEABILITY.md"
|
||||||
|
README = ROOT / "README.md"
|
||||||
|
VALIDATOR = ROOT / "scripts" / "validate_spec.py"
|
||||||
|
|
||||||
|
REQUIRED_FILES = [
|
||||||
|
SPEC,
|
||||||
|
ARCH,
|
||||||
|
RESEARCH,
|
||||||
|
QUESTIONS,
|
||||||
|
TRACEABILITY,
|
||||||
|
README,
|
||||||
|
VALIDATOR,
|
||||||
|
]
|
||||||
|
REQUIRED_SECTIONS = [
|
||||||
|
"Назначение",
|
||||||
|
"Не-цели MVP",
|
||||||
|
"Пользователи и роли",
|
||||||
|
"Функциональные требования",
|
||||||
|
"Нефункциональные требования",
|
||||||
|
"UI/UX specification",
|
||||||
|
"API и event contract",
|
||||||
|
"Data lifecycle",
|
||||||
|
"Acceptance strategy",
|
||||||
|
"Delivery plan",
|
||||||
|
"Риски и меры",
|
||||||
|
"Approval record",
|
||||||
|
]
|
||||||
|
REQ_RE = re.compile(r"\*\*((?:FR|NFR)-[A-Z]+-\d{3})\*\*")
|
||||||
|
AT_RE = re.compile(r"\*\*(AT-(?:FR|NFR)-[A-Z]+-\d{3})[:*]")
|
||||||
|
BLOCKER_RE = re.compile(r"\|\s*OQ-\d{3}\s*\|\s*BLOCKER\s*\|")
|
||||||
|
LOCAL_LINK_RE = re.compile(r"\[[^\]]+\]\((?!https?://|mailto:|#)([^)]+)\)")
|
||||||
|
|
||||||
|
|
||||||
|
def fail(message: str) -> None:
|
||||||
|
print(f"ERROR: {message}")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
errors = 0
|
||||||
|
for path in REQUIRED_FILES:
|
||||||
|
if not path.is_file() or path.stat().st_size == 0:
|
||||||
|
fail(f"missing or empty required file: {path.relative_to(ROOT)}")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
spec = SPEC.read_text(encoding="utf-8")
|
||||||
|
questions = QUESTIONS.read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
for section in REQUIRED_SECTIONS:
|
||||||
|
if section not in spec:
|
||||||
|
fail(f"missing required section: {section}")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
reqs = REQ_RE.findall(spec)
|
||||||
|
ats = AT_RE.findall(spec)
|
||||||
|
req_set = set(reqs)
|
||||||
|
at_targets = {at.removeprefix("AT-") for at in ats}
|
||||||
|
|
||||||
|
duplicates = sorted({req for req in reqs if reqs.count(req) > 1})
|
||||||
|
duplicate_ats = sorted({at for at in ats if ats.count(at) > 1})
|
||||||
|
if duplicates:
|
||||||
|
fail(f"duplicate requirement IDs: {', '.join(duplicates)}")
|
||||||
|
errors += 1
|
||||||
|
if duplicate_ats:
|
||||||
|
fail(f"duplicate acceptance test IDs: {', '.join(duplicate_ats)}")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
missing_at = sorted(req_set - at_targets)
|
||||||
|
orphan_at = sorted(at_targets - req_set)
|
||||||
|
if missing_at:
|
||||||
|
fail(f"requirements without acceptance test: {', '.join(missing_at)}")
|
||||||
|
errors += 1
|
||||||
|
if orphan_at:
|
||||||
|
fail(f"acceptance tests without requirement: {', '.join(orphan_at)}")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
for prefix, minimum in (("FR-", 35), ("NFR-", 20)):
|
||||||
|
count = sum(req.startswith(prefix) for req in req_set)
|
||||||
|
if count < minimum:
|
||||||
|
fail(f"too few {prefix} requirements: {count} < {minimum}")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
blockers = BLOCKER_RE.findall(questions)
|
||||||
|
if not blockers:
|
||||||
|
fail("OPEN-QUESTIONS.md must identify blocking decisions")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
for markdown in ROOT.rglob("*.md"):
|
||||||
|
text = markdown.read_text(encoding="utf-8")
|
||||||
|
for raw_target in LOCAL_LINK_RE.findall(text):
|
||||||
|
target = raw_target.split("#", 1)[0]
|
||||||
|
if target and not (markdown.parent / target).resolve().exists():
|
||||||
|
fail(
|
||||||
|
f"broken local Markdown link in {markdown.relative_to(ROOT)}: "
|
||||||
|
f"{raw_target}"
|
||||||
|
)
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
if "implementation blocked" not in spec.lower() or "implementation blocked" not in README.read_text(encoding="utf-8").lower():
|
||||||
|
fail("draft implementation block must be explicit in spec and README")
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
print(f"FAIL: {errors} structural issue(s)")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(
|
||||||
|
"PASS: specification structure valid; "
|
||||||
|
f"requirements={len(req_set)} (FR={sum(r.startswith('FR-') for r in req_set)}, "
|
||||||
|
f"NFR={sum(r.startswith('NFR-') for r in req_set)}); "
|
||||||
|
f"acceptance_tests={len(at_targets)}; blockers={len(blockers)}"
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
41
tests/test_validate_spec.py
Normal file
41
tests/test_validate_spec.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import importlib.util
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
VALIDATOR = ROOT / "scripts" / "validate_spec.py"
|
||||||
|
|
||||||
|
|
||||||
|
class ValidateSpecTests(unittest.TestCase):
|
||||||
|
def test_repository_specification_is_structurally_valid(self) -> None:
|
||||||
|
result = subprocess.run(
|
||||||
|
[sys.executable, str(VALIDATOR)],
|
||||||
|
cwd=ROOT,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
|
||||||
|
self.assertIn("PASS: specification structure valid", result.stdout)
|
||||||
|
|
||||||
|
def test_requirement_and_acceptance_ids_are_one_to_one(self) -> None:
|
||||||
|
module_spec = importlib.util.spec_from_file_location("validate_spec", VALIDATOR)
|
||||||
|
if module_spec is None or module_spec.loader is None:
|
||||||
|
self.fail("could not load specification validator module")
|
||||||
|
module = importlib.util.module_from_spec(module_spec)
|
||||||
|
module_spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
text = (ROOT / "docs" / "SPECIFICATION.md").read_text(encoding="utf-8")
|
||||||
|
requirements = module.REQ_RE.findall(text)
|
||||||
|
acceptance = [item.removeprefix("AT-") for item in module.AT_RE.findall(text)]
|
||||||
|
self.assertEqual(len(requirements), len(set(requirements)))
|
||||||
|
self.assertEqual(len(acceptance), len(set(acceptance)))
|
||||||
|
self.assertSetEqual(set(requirements), set(acceptance))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Loading…
Reference in a new issue