chore(specs): move clean-repo-enterprise spec from 020 to 023
This commit is contained in:
253
specs/023-clean-repo-enterprise/data-model.md
Normal file
253
specs/023-clean-repo-enterprise/data-model.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# Data Model: Clean Repository Enterprise Preparation
|
||||
|
||||
## Overview
|
||||
|
||||
Модель данных описывает сущности, необходимые для подготовки и контроля enterprise clean-поставки в изолированном контуре без внешнего интернета.
|
||||
|
||||
---
|
||||
|
||||
## 1) ReleaseCandidate
|
||||
|
||||
**Purpose**: Представляет конкретный релиз-кандидат, проходящий clean-подготовку и compliance-проверку.
|
||||
|
||||
### Fields
|
||||
|
||||
- `candidate_id` (string, required, unique)
|
||||
Уникальный идентификатор релиз-кандидата.
|
||||
- `version` (string, required)
|
||||
Версия/метка релиза.
|
||||
- `profile` (enum, required)
|
||||
Допустимые значения: `enterprise-clean`, `development`.
|
||||
- `created_at` (datetime, required)
|
||||
- `created_by` (string, required)
|
||||
Идентификатор оператора/сервиса, создавшего candidate.
|
||||
- `source_snapshot_ref` (string, required)
|
||||
Ссылка на исходный снимок/состояние для воспроизводимости.
|
||||
- `status` (enum, required)
|
||||
`draft`, `prepared`, `compliant`, `blocked`, `released`.
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- `candidate_id` и `source_snapshot_ref` не могут быть пустыми.
|
||||
- Для `profile=enterprise-clean` переход в `released` разрешён только после `compliant`.
|
||||
- Переходы статусов должны быть монотонными по lifecycle (без недетерминированных откатов).
|
||||
|
||||
---
|
||||
|
||||
## 2) CleanProfilePolicy
|
||||
|
||||
**Purpose**: Формальная политика классификации артефактов и источников ресурсов для enterprise clean-профиля.
|
||||
|
||||
### Fields
|
||||
|
||||
- `policy_id` (string, required, unique)
|
||||
- `policy_version` (string, required)
|
||||
- `active` (boolean, required)
|
||||
- `prohibited_artifact_categories` (array[string], required)
|
||||
Примеры: `test-data`, `demo-data`, `load-test`, `sample-repository`.
|
||||
- `required_system_categories` (array[string], required)
|
||||
Примеры: `system-init`, `security-bootstrap`, `schema-migrations`.
|
||||
- `external_source_forbidden` (boolean, required; для enterprise-clean = true)
|
||||
- `internal_source_registry_ref` (string, required)
|
||||
Ссылка на реестр внутренних серверов.
|
||||
- `effective_from` (datetime, required)
|
||||
- `effective_to` (datetime, optional)
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- Политика не может быть активирована без `internal_source_registry_ref`.
|
||||
- Одновременная активность двух политик для одного профиля и периода запрещена.
|
||||
- Для `enterprise-clean` поле `external_source_forbidden` всегда `true`.
|
||||
|
||||
---
|
||||
|
||||
## 3) ResourceSourceRegistry
|
||||
|
||||
**Purpose**: Реестр разрешённых внутренних серверов компании, используемых для загрузки всех ресурсов.
|
||||
|
||||
### Fields
|
||||
|
||||
- `registry_id` (string, required, unique)
|
||||
- `name` (string, required)
|
||||
- `entries` (array[ResourceSourceEntry], required, min=1)
|
||||
- `updated_at` (datetime, required)
|
||||
- `updated_by` (string, required)
|
||||
- `status` (enum, required)
|
||||
`active`, `inactive`.
|
||||
|
||||
### ResourceSourceEntry (nested)
|
||||
|
||||
- `source_id` (string, required, unique within registry)
|
||||
- `host` (string, required)
|
||||
- `protocol` (enum, required)
|
||||
`http`, `https`, `ssh`, `file`.
|
||||
- `purpose` (string, required)
|
||||
Например: `artifact-repo`, `package-mirror`, `git-mirror`.
|
||||
- `allowed_paths` (array[string], optional)
|
||||
- `enabled` (boolean, required)
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- В `entries` запрещены дубликаты `host + purpose`.
|
||||
- При `status=active` должен существовать хотя бы один `enabled=true` entry.
|
||||
- Внешние публичные хосты не допускаются в активном реестре enterprise clean-профиля.
|
||||
|
||||
---
|
||||
|
||||
## 4) DistributionManifest
|
||||
|
||||
**Purpose**: Зафиксированный состав итогового дистрибутива для аудита и воспроизводимости.
|
||||
|
||||
### Fields
|
||||
|
||||
- `manifest_id` (string, required, unique)
|
||||
- `candidate_id` (string, required, FK -> ReleaseCandidate)
|
||||
- `policy_id` (string, required, FK -> CleanProfilePolicy)
|
||||
- `generated_at` (datetime, required)
|
||||
- `generated_by` (string, required)
|
||||
- `items` (array[ManifestItem], required)
|
||||
- `summary` (ManifestSummary, required)
|
||||
- `deterministic_hash` (string, required)
|
||||
|
||||
### ManifestItem (nested)
|
||||
|
||||
- `path` (string, required)
|
||||
- `category` (string, required)
|
||||
- `classification` (enum, required)
|
||||
`required-system`, `allowed`, `excluded-prohibited`.
|
||||
- `reason` (string, required)
|
||||
- `checksum` (string, optional for included items)
|
||||
|
||||
### ManifestSummary (nested)
|
||||
|
||||
- `included_count` (integer, required, >=0)
|
||||
- `excluded_count` (integer, required, >=0)
|
||||
- `prohibited_detected_count` (integer, required, >=0)
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- `candidate_id` и `policy_id` должны ссылаться на существующие записи.
|
||||
- `deterministic_hash` должен быть одинаковым для идентичного входного состояния.
|
||||
- `included_count + excluded_count` должно совпадать с размером `items`.
|
||||
|
||||
---
|
||||
|
||||
## 5) ComplianceCheckRun
|
||||
|
||||
**Purpose**: Один запуск проверки соответствия clean/compliance для релиз-кандидата.
|
||||
|
||||
### Fields
|
||||
|
||||
- `check_run_id` (string, required, unique)
|
||||
- `candidate_id` (string, required, FK -> ReleaseCandidate)
|
||||
- `policy_id` (string, required, FK -> CleanProfilePolicy)
|
||||
- `started_at` (datetime, required)
|
||||
- `finished_at` (datetime, optional)
|
||||
- `final_status` (enum, required)
|
||||
`running`, `compliant`, `blocked`, `failed`.
|
||||
- `triggered_by` (string, required)
|
||||
- `execution_mode` (enum, required)
|
||||
`tui`, `ci`.
|
||||
- `checks` (array[CheckStageResult], required)
|
||||
|
||||
### CheckStageResult (nested)
|
||||
|
||||
- `stage` (enum, required)
|
||||
`data_purity`, `internal_sources_only`, `no_external_endpoints`, `manifest_consistency`.
|
||||
- `status` (enum, required)
|
||||
`pass`, `fail`, `skipped`.
|
||||
- `details` (string, optional)
|
||||
- `duration_ms` (integer, optional, >=0)
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- `final_status=compliant` допускается только при `pass` для всех обязательных стадий.
|
||||
- `final_status=blocked` обязателен при `fail` хотя бы одной обязательной стадии.
|
||||
- `execution_mode=ci` и `execution_mode=tui` должны быть сопоставимы по policy/version.
|
||||
|
||||
---
|
||||
|
||||
## 6) ComplianceViolation
|
||||
|
||||
**Purpose**: Нормализованная запись конкретного нарушения, найденного в ходе проверки.
|
||||
|
||||
### Fields
|
||||
|
||||
- `violation_id` (string, required, unique)
|
||||
- `check_run_id` (string, required, FK -> ComplianceCheckRun)
|
||||
- `category` (enum, required)
|
||||
`data-purity`, `external-source`, `manifest-integrity`, `policy-conflict`, `operational-risk`.
|
||||
- `severity` (enum, required)
|
||||
`critical`, `high`, `medium`, `low`.
|
||||
- `location` (string, required)
|
||||
Путь/endpoint/конфигурационный ключ.
|
||||
- `evidence` (string, optional)
|
||||
- `remediation` (string, required)
|
||||
- `blocked_release` (boolean, required)
|
||||
- `detected_at` (datetime, required)
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- Для `category=external-source` поле `blocked_release` всегда `true` в enterprise clean-профиле.
|
||||
- Для `severity=critical` поле `remediation` обязательно и непустое.
|
||||
- `check_run_id` должен ссылаться на существующий запуск проверки.
|
||||
|
||||
---
|
||||
|
||||
## 7) ComplianceReport
|
||||
|
||||
**Purpose**: Финальный отчёт проверки для оператора и аудита.
|
||||
|
||||
### Fields
|
||||
|
||||
- `report_id` (string, required, unique)
|
||||
- `check_run_id` (string, required, FK -> ComplianceCheckRun)
|
||||
- `candidate_id` (string, required)
|
||||
- `generated_at` (datetime, required)
|
||||
- `operator_summary` (string, required)
|
||||
- `structured_payload_ref` (string, required)
|
||||
Ссылка на машинно-читаемое представление.
|
||||
- `violations_count` (integer, required, >=0)
|
||||
- `blocking_violations_count` (integer, required, >=0)
|
||||
|
||||
### Validation Rules
|
||||
|
||||
- `blocking_violations_count` ≤ `violations_count`.
|
||||
- При `final_status=blocked` в связанном check run `blocking_violations_count` > 0.
|
||||
- Отчёт должен быть доступен для экспортирования из TUI сценария.
|
||||
|
||||
---
|
||||
|
||||
## Relationships
|
||||
|
||||
1. `ReleaseCandidate` 1—N `DistributionManifest`
|
||||
2. `CleanProfilePolicy` 1—N `DistributionManifest`
|
||||
3. `ReleaseCandidate` 1—N `ComplianceCheckRun`
|
||||
4. `CleanProfilePolicy` 1—N `ComplianceCheckRun`
|
||||
5. `ComplianceCheckRun` 1—N `ComplianceViolation`
|
||||
6. `ComplianceCheckRun` 1—1 `ComplianceReport`
|
||||
7. `ResourceSourceRegistry` 1—N `CleanProfilePolicy` (по ссылке active policy)
|
||||
|
||||
---
|
||||
|
||||
## State Model Highlights
|
||||
|
||||
### ReleaseCandidate lifecycle
|
||||
|
||||
`draft -> prepared -> compliant -> released`
|
||||
`draft|prepared -> blocked` (при нарушениях)
|
||||
|
||||
### ComplianceCheckRun lifecycle
|
||||
|
||||
`running -> compliant|blocked|failed`
|
||||
|
||||
---
|
||||
|
||||
## TUI Mapping Notes (from UX reference)
|
||||
|
||||
Состояния TUI из [`ux_reference.md`](./ux_reference.md) напрямую маппятся на сущности:
|
||||
|
||||
- `READY` -> `ReleaseCandidate.status in {draft, prepared}`
|
||||
- `RUNNING` -> `ComplianceCheckRun.final_status = running`
|
||||
- `COMPLIANT` -> `ComplianceCheckRun.final_status = compliant` + `ComplianceReport`
|
||||
- `BLOCKED` -> `ComplianceCheckRun.final_status = blocked` + `ComplianceViolation[*].blocked_release=true`
|
||||
Reference in New Issue
Block a user