semantics

This commit is contained in:
2026-03-27 21:27:31 +03:00
parent 7c85552132
commit 2ed66bfebc
182 changed files with 21186 additions and 10254 deletions

View File

@@ -1,65 +1,79 @@
# Module Contracts: Frontend Style Unification
## [DEF:FrontendStyleSystem:Module]
@TIER: CRITICAL
@PURPOSE: Define and enforce unified visual primitives and page-shell rules across targeted frontend routes.
@RELATION: DEPENDS_ON -> [DEF:Std:UI_Svelte]
@RELATION: DEPENDS_ON -> [DEF:Std:Semantics]
@RELATION: BINDS_TO -> [DEF:StyleTokenGroup:Entity]
@RELATION: BINDS_TO -> [DEF:UIPatternRule:Entity]
@PRE: Target routes/components for unification are identified and included in scope.
@PRE: Existing behavior-critical user flows remain available for validation.
@POST: Shared visual primitives and shell patterns are applied consistently in targeted scope.
@POST: No critical functional flow is removed by style refactor.
@UX_STATE: Default -> Users see consistent hierarchy (title/actions/content) across targeted pages.
@UX_STATE: Loading -> Loading visuals appear in consistent zones without disruptive layout jumps.
@UX_STATE: Error -> Error blocks use consistent emphasis and include a clear recovery action.
@UX_STATE: Success -> Confirmation messages follow one tone/placement pattern.
@INVARIANT: Unified styling must not regress accessibility-visible focus and readable contrast behavior.
# [DEF:FrontendStyleSystem:Module]
# @TIER: CRITICAL
# @PURPOSE: Define and enforce unified visual primitives and page-shell rules across targeted frontend routes.
# @RELATION: DEPENDS_ON -> [DEF:Std:UI_Svelte:Standard]
# @RELATION: DEPENDS_ON -> [DEF:Std:Semantics:Standard]
# @RELATION: BINDS_TO -> [DEF:StyleTokenGroup:Block]
# @RELATION: BINDS_TO -> [DEF:UIPatternRule:Block]
# @PRE: Target routes/components for unification are identified and included in scope.
# @PRE: Existing behavior-critical user flows remain available for validation.
# @POST: Shared visual primitives and shell patterns are applied consistently in targeted scope.
# @POST: No critical functional flow is removed by style refactor.
# @UX_STATE: Default -> Users see consistent hierarchy (title/actions/content) across targeted pages.
# @UX_STATE: Loading -> Loading visuals appear in consistent zones without disruptive layout jumps.
# @UX_STATE: Error -> Error blocks use consistent emphasis and include a clear recovery action.
# @UX_STATE: Success -> Confirmation messages follow one tone/placement pattern.
# @INVARIANT: Unified styling must not regress accessibility-visible focus and readable contrast behavior.
---
## [DEF:RouteShellContract:Component]
@TIER: CRITICAL
@PURPOSE: Standardize route shell structure for primary pages (dashboards, tasks, reports, settings).
@RELATION: DEPENDS_ON -> [DEF:FrontendStyleSystem:Module]
@PRE: Route provides title context and action area metadata.
@POST: Route renders canonical shell order: context/breadcrumbs, title block, action region, content container.
@UX_STATE: Default -> Primary action location is discoverable quickly and consistently.
@UX_STATE: Empty -> Empty-state container is visually aligned with shell and includes next-step guidance.
@UX_RECOVERY: Empty -> User can recover using explicit action (refresh/filter adjust/create flow).
# [/DEF:FrontendStyleSystem:Module]
##
# [DEF:RouteShellContract:Component]
# @TIER: CRITICAL
# @PURPOSE: Standardize route shell structure for primary pages (dashboards, tasks, reports, settings).
# @RELATION: DEPENDS_ON -> [DEF:FrontendStyleSystem:Module]
# @PRE: Route provides title context and action area metadata.
# @POST: Route renders canonical shell order: context/breadcrumbs, title block, action region, content container.
# @UX_STATE: Default -> Primary action location is discoverable quickly and consistently.
# @UX_STATE: Empty -> Empty-state container is visually aligned with shell and includes next-step guidance.
# @UX_RECOVERY: Empty -> User can recover using explicit action (refresh/filter adjust/create flow).
---
## [DEF:StateFeedbackContract:Component]
@TIER: CRITICAL
@PURPOSE: Normalize loading/empty/error/success feedback rendering and wording across modules.
@RELATION: DEPENDS_ON -> [DEF:StatePresentationPattern:Entity]
@PRE: Module can expose current state category (loading/empty/error/success).
@POST: State-specific UI uses canonical placement, tone, and recovery behavior.
@UX_STATE: Loading -> Consistent indicator style and placement with stable layout rhythm.
@UX_STATE: Empty -> Neutral message + guidance action rendered in standard block.
@UX_STATE: Error -> Actionable error messaging with retry/fix path.
@UX_STATE: Success -> Concise confirmation in standard visual language.
@UX_FEEDBACK: Error -> Emphasis clearly distinguishes failure from neutral status.
@UX_RECOVERY: Error -> Retry or corrective action is always visible when recoverable.
@INVARIANT: State texts use canonical terminology and remain i18n-compatible.
# [/DEF:RouteShellContract:Component]
##
# [DEF:StateFeedbackContract:Component]
# @TIER: CRITICAL
# @PURPOSE: Normalize loading/empty/error/success feedback rendering and wording across modules.
# @RELATION: DEPENDS_ON -> [DEF:StatePresentationPattern:Block]
# @PRE: Module can expose current state category (loading/empty/error/success).
# @POST: State-specific UI uses canonical placement, tone, and recovery behavior.
# @UX_STATE: Loading -> Consistent indicator style and placement with stable layout rhythm.
# @UX_STATE: Empty -> Neutral message + guidance action rendered in standard block.
# @UX_STATE: Error -> Actionable error messaging with retry/fix path.
# @UX_STATE: Success -> Concise confirmation in standard visual language.
# @UX_FEEDBACK: Error -> Emphasis clearly distinguishes failure from neutral status.
# @UX_RECOVERY: Error -> Retry or corrective action is always visible when recoverable.
# @INVARIANT: State texts use canonical terminology and remain i18n-compatible.
---
## [DEF:TerminologyConsistencyContract:Module]
@TIER: STANDARD
@PURPOSE: Keep user-facing wording consistent across page shells and state blocks.
@RELATION: DEPENDS_ON -> [DEF:Std:Constitution]
@PRE: Canonical term list for targeted flows is defined.
@POST: Targeted modules avoid mixed synonyms for the same concept.
@UX_STATE: Default -> UI labels and status texts remain concise and confidence-building.
@INVARIANT: User-facing text remains compatible with existing localization workflow.
# [/DEF:StateFeedbackContract:Component]
##
# [DEF:TerminologyConsistencyContract:Module]
# @TIER: STANDARD
# @PURPOSE: Keep user-facing wording consistent across page shells and state blocks.
# @RELATION: DEPENDS_ON -> [DEF:Std:Constitution:Standard]
# @PRE: Canonical term list for targeted flows is defined.
# @POST: Targeted modules avoid mixed synonyms for the same concept.
# @UX_STATE: Default -> UI labels and status texts remain concise and confidence-building.
# @INVARIANT: User-facing text remains compatible with existing localization workflow.
---
## Contract Usage Simulation (Key Scenario)
# [/DEF:TerminologyConsistencyContract:Module]
**Scenario**: User navigates from dashboards to reports and encounters a failed data load.
1. `RouteShellContract` ensures both pages keep identical shell rhythm and action placement.
@@ -67,4 +81,4 @@
3. `StateFeedbackContract` renders failure using canonical error block with explicit retry action.
4. `TerminologyConsistencyContract` ensures error wording and action labels are aligned across pages.
**Continuity Check**: No interface mismatch detected between shell-level structure and state-level feedback contracts.
**Continuity Check**: No interface mismatch detected between shell-level structure and state-level feedback contracts.

View File

@@ -1,6 +1,6 @@
# Implementation Plan: Frontend Navigation Redesign
**Branch**: `015-frontend-nav-redesign` | **Date**: 2026-01-26 | **Spec**: [specs/015-frontend-nav-redesign/spec.md](../spec.md)
**Branch**: `015-frontend-nav-redesign` | **Date**: 2026-01-26 | **Spec**: [specs/015-frontend-nav-redesign/spec.md](./spec.md)
**Input**: Feature specification from `specs/015-frontend-nav-redesign/spec.md`
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow.

View File

@@ -2,8 +2,8 @@
**Feature Branch**: `015-frontend-nav-redesign`
**Status**: Completed
**Spec**: [specs/015-frontend-nav-redesign/spec.md](../spec.md)
**Plan**: [specs/015-frontend-nav-redesign/plan.md](../plan.md)
**Spec**: [specs/015-frontend-nav-redesign/spec.md](./spec.md)
**Plan**: [specs/015-frontend-nav-redesign/plan.md](./plan.md)
## Phase 1: Setup
@@ -114,4 +114,4 @@
1. **Setup**: Create the new directory structure.
2. **Dashboard & Navbar**: Quick wins to reshape the navigation.
3. **Backup UI**: The core development effort. Connect to existing backend.
4. **Cleanup**: Remove old code once the new flows are verified.
4. **Cleanup**: Remove old code once the new flows are verified.

View File

@@ -21,15 +21,15 @@
# @PURPOSE: Analyze dashboard health using screenshot and logs.
# @PRE: Dashboard ID exists and provider is configured.
# @POST: ValidationResult is persisted and notification sent if failed.
# [/DEF:validate_dashboard]
# [/DEF:validate_dashboard:Function]
# [DEF:generate_documentation:Function]
# @PURPOSE: Generate and apply metadata descriptions for datasets.
# @PRE: Dataset is accessible and schema is valid.
# @POST: Dataset metadata is updated in the database.
# [/DEF:generate_documentation]
# [/DEF:generate_documentation:Function]
# [/DEF:backend/src/plugins/llm_analysis/plugin.py]
# [/DEF:backend/src/plugins/llm_analysis/plugin.py:Module]
```
### LLM Service
@@ -49,9 +49,9 @@
# @PRE: Provider is active and quota is available.
# @POST: Returns structured analysis or raises RetryError.
# @SIDE_EFFECT: Makes external HTTP request.
# [/DEF:analyze_multimodal]
# [/DEF:analyze_multimodal:Function]
# [/DEF:backend/src/plugins/llm_analysis/service.py]
# [/DEF:backend/src/plugins/llm_analysis/service.py:Module]
```
### Provider Management Service
@@ -69,9 +69,9 @@
# @PURPOSE: Instantiate an authenticated LLM client for a specific provider.
# @PRE: Provider ID exists and is active.
# @POST: Returns configured client instance with decrypted key.
# [/DEF:get_provider_client]
# [/DEF:get_provider_client:Function]
# [/DEF:backend/src/services/llm_provider.py]
# [/DEF:backend/src/services/llm_provider.py:Module]
```
### Data Models
@@ -82,7 +82,7 @@
# @SEMANTICS: dto, pydantic, schema
# @PURPOSE: Define Pydantic models for configuration, requests, and results.
# @LAYER: Domain/Data
# [/DEF:backend/src/plugins/llm_analysis/models.py]
# [/DEF:backend/src/plugins/llm_analysis/models.py:Module]
```
## Frontend Components
@@ -94,7 +94,7 @@
<!-- @TIER: STANDARD -->
<!-- @PURPOSE: Form for adding/editing LLM providers with connection testing. -->
<!-- @RELATION: CALLS -> /api/settings/llm/providers -->
<!-- [/DEF:frontend/src/components/llm/ProviderConfig.svelte] -->
<!-- [/DEF:frontend/src/components/llm/ProviderConfig.svelte:Component] -->
```
### Validation Report
@@ -104,4 +104,4 @@
<!-- @TIER: STANDARD -->
<!-- @PURPOSE: Display formatted analysis results including screenshot and issues list. -->
<!-- @INVARIANT: Must handle missing screenshots gracefully. -->
<!-- [/DEF:frontend/src/components/llm/ValidationReport.svelte] -->
<!-- [/DEF:frontend/src/components/llm/ValidationReport.svelte:Component] -->

View File

@@ -196,7 +196,7 @@ export const sidebarStore = writable({
export function toggleSidebar() { /* ... */ }
export function setActiveItem(path) { /* ... */ }
// [/DEF:SidebarStore]
// [/DEF:SidebarStore:Store]
```
### TaskDrawerStore (frontend/src/lib/stores/taskDrawer.js)
@@ -221,7 +221,7 @@ export const taskDrawerStore = writable({
export function openDrawerForTask(taskId) { /* ... */ }
export function closeDrawer() { /* ... */ }
export function updateResourceTask(resourceId, taskId, status) { /* ... */ }
// [/DEF:TaskDrawerStore]
// [/DEF:TaskDrawerStore:Store]
```
### ActivityStore (frontend/src/lib/stores/activity.js)
@@ -238,5 +238,5 @@ export const activityStore = derived(taskDrawerStore, ($drawer) => {
.filter(t => t.status === 'RUNNING').length;
return { activeCount };
});
// [/DEF:ActivityStore]
// [/DEF:ActivityStore:Store]
```

View File

@@ -53,7 +53,7 @@ export function setActiveCategory(category) { /* ... */ }
export function setActiveItem(path) { /* ... */ }
export function openMobileSidebar() { /* ... */ }
export function closeMobileSidebar() { /* ... */ }
// [/DEF:SidebarStore]
// [/DEF:SidebarStore:Store]
```
---
@@ -105,7 +105,7 @@ export function openDrawerForTask(taskId) { /* ... */ }
export function closeDrawer() { /* ... */ }
export function updateResourceTask(resourceId, taskId, status) { /* ... */ }
export function clearCompletedTasks() { /* ... */ }
// [/DEF:TaskDrawerStore]
// [/DEF:TaskDrawerStore:Store]
```
---
@@ -143,7 +143,7 @@ export const activityStore = derived(
return { activeCount, recentTasks };
}
);
// [/DEF:ActivityStore]
// [/DEF:ActivityStore:Store]
```
---
@@ -187,7 +187,7 @@ export const activityStore = derived(
{ id: 'admin', label: 'ADMIN', items: [{ path: '/users', label: 'Users' }, { path: '/settings', label: 'Settings' }], adminOnly: true }
];
</script>
<!-- [/DEF:Sidebar] -->
<!-- [/DEF:Sidebar:Component] -->
```
---
@@ -225,7 +225,7 @@ export const activityStore = derived(
export let logoText = 'Superset Tools';
export let searchPlaceholder = 'Search...';
</script>
<!-- [/DEF:TopNavbar] -->
<!-- [/DEF:TopNavbar:Component] -->
```
---
@@ -270,7 +270,7 @@ export const activityStore = derived(
export let width = 480; // px
export let closeOnOutsideClick = false;
</script>
<!-- [/DEF:TaskDrawer] -->
<!-- [/DEF:TaskDrawer:Component] -->
```
---
@@ -323,7 +323,7 @@ export const activityStore = derived(
let searchQuery = '';
let environmentId = null;
</script>
<!-- [/DEF:DashboardHub] -->
<!-- [/DEF:DashboardHub:Component] -->
```
---
@@ -374,7 +374,7 @@ export const activityStore = derived(
let searchQuery = '';
let environmentId = null;
</script>
<!-- [/DEF:DatasetHub] -->
<!-- [/DEF:DatasetHub:Component] -->
```
---
@@ -406,7 +406,7 @@ export const activityStore = derived(
export let items = []; // [{ label: string, path: string | null }]
export let maxVisible = 3;
</script>
<!-- [/DEF:Breadcrumbs] -->
<!-- [/DEF:Breadcrumbs:Component] -->
```
---
@@ -445,7 +445,7 @@ export const activityStore = derived(
# Endpoint: POST /api/dashboards/backup
# Body: { env_id, dashboard_ids, schedule (optional cron) }
# Response: { task_id }
# [/DEF:DashboardsAPI]
# [/DEF:DashboardsAPI:Module]
```
---
@@ -482,7 +482,7 @@ export const activityStore = derived(
# Endpoint: POST /api/datasets/generate-docs
# Body: { env_id, dataset_ids, llm_provider, options }
# Response: { task_id }
# [/DEF:DatasetsAPI]
# [/DEF:DatasetsAPI:Module]
```
---
@@ -506,7 +506,7 @@ export const activityStore = derived(
# Endpoint: GET /api/activity
# Response: { active_count: number, recent_tasks: [...] }
# [/DEF:ActivityAPI]
# [/DEF:ActivityAPI:Module]
```
---
@@ -535,7 +535,7 @@ class ResourceService:
async def fetch_datasets(env_id: str, search: str = None) -> list[Dataset]: ...
async def get_git_status(env_id: str, resource_id: str) -> GitStatus: ...
async def get_last_task(resource_type: str, resource_id: str) -> TaskSummary: ...
# [/DEF:ResourceService]
# [/DEF:ResourceService:Class]
```
---

View File

@@ -15,7 +15,7 @@
# @POST: Response contains normalized reports with deterministic ordering and total metadata.
# @POST: Unknown task type is mapped to fallback type "unknown" and remains visible.
# @POST: Partial payloads are rendered with placeholders, never causing report omission.
# [/DEF:ReportsAggregationModule]
# [/DEF:ReportsAggregationModule:Module]
---
@@ -33,7 +33,7 @@
# @POST: List endpoint returns {items, total, page, page_size, has_next, applied_filters}.
# @POST: Detail endpoint returns a single normalized report with diagnostics/next actions when available.
# @POST: Validation errors are explicit (400-range) and machine-readable.
# [/DEF:ReportsApiContract]
# [/DEF:ReportsApiContract:Module]
---
@@ -59,7 +59,7 @@
* @UX_FEEDBACK: On filter apply, list updates with immediate visual acknowledgment.
* @UX_RECOVERY: Retry failed loads, clear filters, and continue reading partial reports with placeholders.
*/
<!-- [/DEF:UnifiedReportsPage] -->
<!-- [/DEF:UnifiedReportsPage:Component] -->
---
@@ -75,7 +75,7 @@
# @INVARIANT: Native fetch is not used directly; existing wrapper-based request path is preserved.
# @PRE: Valid auth token is present when required by backend.
# @POST: Returns parsed report payload or structured error object for UI-state mapping.
# [/DEF:ReportsApiClient]
# [/DEF:ReportsApiClient:Module]
---
@@ -90,7 +90,7 @@
# @INVARIANT: Exactly one fallback profile exists and is used for unknown task types.
# @PRE: Input task_type may be known or unknown.
# @POST: Returns profile with display label and variant tokens required for rendering.
# [/DEF:ReportTypeProfileRegistry]
# [/DEF:ReportTypeProfileRegistry:Module]
---
@@ -106,4 +106,4 @@ Scenario traced: Operator finds failed migration quickly and triages.
6. `ReportsApiContract` detail endpoint returns diagnostics + `next_actions`.
7. UI shows actionable failure context and recovery guidance without changing page context.
Continuity check: No interface mismatch found across contracts for list/filter/detail path.
Continuity check: No interface mismatch found across contracts for list/filter/detail path.

View File

@@ -15,7 +15,7 @@
# @PRE: Authenticated user context and non-empty user message are provided.
# @POST: Returns one of deterministic states: needs_clarification, denied, needs_confirmation, started, success, failed.
# @POST: Long-running operation responses include task_id when task is created.
# [/DEF:AssistantOrchestratorModule]
# [/DEF:AssistantOrchestratorModule:Module]
---
@@ -30,7 +30,7 @@
# @INVARIANT: Parsed intent always includes confidence score and risk_level.
# @PRE: Input text is available and sanitized.
# @POST: Returns normalized intent or unknown intent with low confidence.
# [/DEF:AssistantIntentParserModule]
# [/DEF:AssistantIntentParserModule:Module]
---
@@ -46,7 +46,7 @@
# @INVARIANT: Dangerous operations never execute without explicit confirmation token.
# @PRE: Normalized intent and authenticated user context are available.
# @POST: Returns one of {denied, needs_confirmation, allowed}.
# [/DEF:AssistantSecurityGuardModule]
# [/DEF:AssistantSecurityGuardModule:Module]
---
@@ -65,7 +65,7 @@
# @INVARIANT: Adapter reuses existing execution paths and does not duplicate domain logic.
# @PRE: ExecutionRequest is validated and authorized.
# @POST: Returns operation result or started task_id for async flows.
# [/DEF:AssistantExecutionAdapterModule]
# [/DEF:AssistantExecutionAdapterModule:Module]
---
@@ -80,7 +80,7 @@
# @INVARIANT: Every processed command emits one audit record.
# @PRE: Command processing context is available.
# @POST: Structured audit entry persisted with decision/outcome/task_id (if present).
# [/DEF:AssistantAuditLogModule]
# [/DEF:AssistantAuditLogModule:Module]
---
@@ -97,7 +97,7 @@
# @POST: Message endpoint returns assistant response state + metadata.
# @POST: Confirm endpoint executes pending dangerous command exactly once.
# @POST: Cancel endpoint prevents execution of pending dangerous command.
# [/DEF:AssistantApiContract]
# [/DEF:AssistantApiContract:Module]
---
@@ -110,7 +110,7 @@
* @PURPOSE: Render in-app assistant conversation and operational command interactions.
* @LAYER: UI
* @RELATION: DEPENDS_ON -> [DEF:AssistantApiClient]
* @RELATION: USES -> [DEF:TaskDrawerStore]
* @RELATION: BINDS_TO -> [DEF:TaskDrawerStore:Store]
* @INVARIANT: Every assistant response is rendered with explicit state badge.
* @PRE: User is authenticated and assistant panel is accessible.
* @POST: User can send command, receive response, and confirm/cancel risky operations.
@@ -121,7 +121,7 @@
* @UX_STATE: Error -> Error card with retry/rephrase guidance displayed.
* @UX_RECOVERY: User can rephrase ambiguous command or retry after error.
*/
<!-- [/DEF:AssistantChatPanel] -->
<!-- [/DEF:AssistantChatPanel:Component] -->
---
@@ -136,7 +136,7 @@
# @INVARIANT: No direct native fetch bypassing project API wrapper conventions.
# @PRE: Valid auth context/token exists.
# @POST: Returns typed assistant response payload or structured error object.
# [/DEF:AssistantApiClient]
# [/DEF:AssistantApiClient:Module]
---

View File

@@ -1,10 +1,10 @@
[DEF:specs.023-clean-repo-enterprise.checklists.release-readiness:Module]
@TIER: STANDARD
@SEMANTICS: release-readiness, compliance, evidence, enterprise-clean
@PURPOSE: Checklist template for packaging compliance evidence before release publication.
@LAYER: Domain
@RELATION: BINDS_TO -> specs/023-clean-repo-enterprise/quickstart.md
@INVARIANT: Release is publishable only when compliance status is COMPLIANT.
# [DEF:specs.023-clean-repo-enterprise.checklists.release-readiness:Module]
# @TIER: STANDARD
# @SEMANTICS: release-readiness, compliance, evidence, enterprise-clean
# @PURPOSE: Checklist template for packaging compliance evidence before release publication.
# @LAYER: Domain
# @RELATION: BINDS_TO -> specs/023-clean-repo-enterprise/quickstart.md
# @INVARIANT: Release is publishable only when compliance status is COMPLIANT.
# Release Readiness Checklist: Enterprise Clean Compliance
@@ -42,4 +42,4 @@
- [ ] Ответственный за выпуск подтвердил допуск кандидата к публикации
- [ ] Артефакт чеклиста сохранён вместе с релизной документацией
[/DEF:specs.023-clean-repo-enterprise.checklists.release-readiness:Module]
# [/DEF:specs.023-clean-repo-enterprise.checklists.release-readiness:Module]

View File

@@ -183,9 +183,9 @@ module CleanReleaseRouter:
# @SEMANTICS: clean-release, config, yaml, policy-source, declarative
# @PURPOSE: Load and validate .clean-release.yaml from repository root, providing typed config to all pipeline stages.
# @LAYER: Infrastructure
# @RELATION: CONSUMED_BY -> backend.src.services.clean_release.policy_engine
# @RELATION: CONSUMED_BY -> backend.src.services.clean_release.compliance_orchestrator
# @INVARIANT: Config load must fail fast on invalid/missing required fields for enterprise-clean profile.
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.policy_engine
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.compliance_orchestrator
# @TEST_CONTRACT: YamlFilePath -> CleanReleaseConfig
# @TEST_FIXTURE: valid_enterprise_config -> {"profile":"enterprise-clean","scan_mode":"repo","prohibited_categories":["test-data"],"allowed_sources":["*.corp.local"]}
# @TEST_EDGE: missing_yaml -> repo without .clean-release.yaml must raise ConfigNotFoundError
@@ -212,8 +212,8 @@ class CleanReleaseConfigLoader:
# @PURPOSE: Scan filesystem (repo/build/docker) for prohibited artifacts and external URLs in text files.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.config_loader
# @RELATION: CONSUMED_BY -> backend.src.services.clean_release.compliance_orchestrator
# @INVARIANT: Scanner must respect ignore_paths and never modify scanned files.
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.compliance_orchestrator
# @TEST_CONTRACT: ScanTarget + CleanReleaseConfig -> ScanResult
# @TEST_FIXTURE: repo_with_test_data -> {"path":"test/data.csv","category":"test-data","classification":"excluded-prohibited"}
# @TEST_EDGE: binary_file_skip -> binary files must be skipped during URL extraction
@@ -240,8 +240,8 @@ class FilesystemScanner:
# @PURPOSE: Execute database cleanup rules from .clean-release.yaml to remove test users and demo data.
# @LAYER: Domain
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.config_loader
# @RELATION: CONSUMED_BY -> backend.src.services.clean_release.compliance_orchestrator
# @INVARIANT: Preserve-listed records must never be deleted regardless of condition match.
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.compliance_orchestrator
# @TEST_CONTRACT: DatabaseCleanupConfig -> CleanupResult
# @TEST_FIXTURE: cleanup_test_users -> {"table":"ab_user","condition":"username IN ('test_user')","preserve":["admin"]}
# @TEST_EDGE: preserve_overrides_condition -> preserved record matching condition must survive cleanup
@@ -271,4 +271,4 @@ class DatabaseCleanupExecutor:
3. [`policy_engine`](#defbackendsrcservicesclean_releasepolicy_enginemodule) обнаруживает `external-source` нарушение и возвращает fail stage + violation.
4. [`compliance_orchestrator`](#defbackendsrcservicesclean_releasecompliance_orchestratormodule) завершает run статусом BLOCKED.
5. [`report_builder`](#defbackendsrcservicesclean_releasereport_buildermodule) формирует отчёт с remediation.
6. [`clean_release_tui`](#defbackendsrcscriptsclean_release_tuimodule) отображает BLOCKED + таблицу нарушений + путь восстановления.
6. [`clean_release_tui`](#defbackendsrcscriptsclean_release_tuimodule) отображает BLOCKED + таблицу нарушений + путь восстановления.

View File

@@ -164,7 +164,7 @@ frontend/
**Gate Result (post-design)**: PASS
**Operational Note (resolved)**: конфликт numeric prefix `020` устранён governance-решением: enterprise clean feature закреплён под уникальным префиксом `023` (ветка и feature-directory: `023-clean-repo-enterprise`). Проверка prereqs и speckit-поток выполняются с `FEATURE_DIR=specs/023-clean-repo-enterprise` без неоднозначности с [`specs/020-task-reports-design`](../020-task-reports-design).
**Operational Note (resolved)**: конфликт numeric prefix `020` устранён governance-решением: enterprise clean feature закреплён под уникальным префиксом `023` (ветка и feature-directory: `023-clean-repo-enterprise`). Проверка prereqs и speckit-поток выполняются с `FEATURE_DIR=specs/023-clean-repo-enterprise` без неоднозначности с [`specs/020-task-reports-design`](../020-task-reports-design) и тестовым маршрутом [`backend/src/api/routes/__tests__/test_clean_release_api.py`](../../backend/src/api/routes/__tests__/test_clean_release_api.py).
## Implementation Traceability & Final Notes
@@ -172,7 +172,7 @@ frontend/
- Новое расширение (post-release hardening, 2026-03-13): добавлен scope на управляемый bootstrap администратора через `.env.enterprise-clean` и docker startup flow.
- Ключевые подтверждения polish-фазы:
- T039: smoke TUI сценария зафиксирован в [`quickstart.md`](./quickstart.md).
- T040: контрактная проверка API подтверждена тестом [`backend/tests/api/routes/test_clean_release_api.py`](../../backend/tests/api/routes/test_clean_release_api.py).
- T040: контрактная проверка API подтверждена тестом [`backend/src/api/routes/__tests__/test_clean_release_api.py`](../../backend/src/api/routes/__tests__/test_clean_release_api.py).
- T041: создан чеклист evidence package [`checklists/release-readiness.md`](./checklists/release-readiness.md).
- T042: governance conflict по префиксу закрыт и задокументирован.
- T043: добавлена итоговая traceability-нотация в текущем плане.

View File

@@ -142,8 +142,8 @@ cd /home/busya/dev/ss-tools
- `cd backend && .venv/bin/python3 -m src.scripts.clean_release_tui`
- Результат: `PASS` (exit code 0, состояние `READY`, панель внутренних источников отображается).
- API contract smoke command:
- `cd backend && .venv/bin/python3 -m pytest tests/api/routes/test_clean_release_api.py -q`
- `cd backend && .venv/bin/python3 -m pytest src/api/routes/__tests__/test_clean_release_api.py -q`
- Результат: `PASS` (`2 passed`), shape контрактов `/api/clean-release/checks*` и `/api/clean-release/reports/{id}` подтверждён.
Примечание:
- В тестовом прогоне есть существующие проектные предупреждения (Pydantic/FastAPI deprecations), но блокирующих ошибок для feature smoke-проверки не обнаружено.
- В тестовом прогоне есть существующие проектные предупреждения (Pydantic/FastAPI deprecations), но блокирующих ошибок для feature smoke-проверки не обнаружено.

View File

@@ -96,7 +96,7 @@
- [X] T026 [P] [US3] Add orchestrator state machine tests for stage pass/fail transitions in `backend/tests/services/clean_release/test_compliance_orchestrator.py`
- [X] T027 [P] [US3] Add report builder validation tests for counters and blocking violations in `backend/tests/services/clean_release/test_report_builder.py`
- [X] T028 [P] [US3] Add API contract tests for `/api/clean-release/checks*` and `/api/clean-release/reports/{id}` in `backend/tests/api/routes/test_clean_release_api.py`
- [X] T028 [P] [US3] Add API contract tests for `/api/clean-release/checks*` and `/api/clean-release/reports/{id}` in `backend/src/api/routes/__tests__/test_clean_release_api.py`
### Implementation for User Story 3
@@ -133,7 +133,7 @@
**Purpose**: Финализация, smoke-проверки и governance-замыкание.
- [X] T039 [P] Run end-to-end smoke validation of TUI scenario from `quickstart.md` and record results in `specs/023-clean-repo-enterprise/quickstart.md`
- [X] T040 [P] Validate OpenAPI contract consistency against implemented routes in `backend/tests/api/routes/test_clean_release_api.py`
- [X] T040 [P] Validate OpenAPI contract consistency against implemented routes in `backend/src/api/routes/__tests__/test_clean_release_api.py`
- [X] T041 Add release checklist artifact template for compliance evidence packaging in `specs/023-clean-repo-enterprise/checklists/release-readiness.md`
- [X] T042 Resolve numeric-prefix governance conflict note (`020-*`) and document decision in `specs/023-clean-repo-enterprise/plan.md`
- [X] T043 Update feature status traceability and final notes in `specs/023-clean-repo-enterprise/plan.md`
@@ -220,4 +220,4 @@ Task: "T024 [US2] Update TUI view model for Allowed Internal Sources and blockin
- Tasks explicitly preserve TUI/ncurses interaction model from [`ux_reference.md`](./ux_reference.md).
- No task introduces web UI replacement for the primary operator flow.
- Each user story phase contains a mandatory UX conformance verification task.
- Each user story phase contains a mandatory UX conformance verification task.

View File

@@ -1,3 +1,8 @@
# [DEF:specs.023-clean-repo-enterprise.tests.README:Module]
# @COMPLEXITY: 1
# @PURPOSE: Test Strategy and coverage matrices for Clean Repository Enterprise Profile.
# [/DEF:specs.023-clean-repo-enterprise.tests.README:Module]
# Test Strategy: Clean Repository Enterprise Profile
## Overview
@@ -17,5 +22,5 @@ This directory contains strategy, coverage matrices, and execution reports for t
## Execution
Run testing via Pytest targeting backend test modules:
```bash
cd backend && .venv/bin/python3 -m pytest tests/services/clean_release tests/api/routes/test_clean_release_api.py tests/api/routes/test_clean_release_source_policy.py -v
cd backend && .venv/bin/python3 -m pytest tests/services/clean_release src/api/routes/__tests__/test_clean_release_api.py src/api/routes/__tests__/test_clean_release_source_policy.py -v
```

View File

@@ -149,29 +149,27 @@ module DashboardProfileFilterExtension:
---
<!-- [DEF:frontend.src.routes.profile.+page:Module] -->
<!--
@TIER: CRITICAL
@SEMANTICS: profile-page, preferences, lookup, save, ux-states
@PURPOSE: Provide profile UI for binding Superset account and saving default "my dashboards" preference.
@LAYER: UI
@RELATION: BINDS_TO -> frontend.src.lib.api
@RELATION: BINDS_TO -> frontend.src.lib.i18n
@INVARIANT: Save action never updates another user's preference.
@UX_STATE: Default -> Current preference shown with environment selector, account input, and toggle.
@UX_STATE: LookupLoading -> Account candidate list shows loading indicator for selected environment.
@UX_STATE: LookupError -> Inline warning shown; manual username entry remains enabled.
@UX_STATE: Saving -> Save button disabled and shows progress.
@UX_STATE: SaveSuccess -> Success toast appears and form reflects persisted values.
@UX_STATE: SaveError -> Error feedback shown without losing user input.
@UX_FEEDBACK: Toasts for save result, inline validation and lookup fallback messaging.
@UX_RECOVERY: User can retry lookup, manually enter username, or disable toggle to continue.
@TEST_CONTRACT: ProfilePageInteraction -> PreferencePersisted
@TEST_FIXTURE: bind_account_happy_path -> {"env_id":"dev","candidate":"j.doe","toggle":true}
@TEST_EDGE: lookup_failed_manual_fallback -> save still possible with manually entered username
@TEST_EDGE: invalid_username -> save blocked with inline validation error
@TEST_EDGE: cancel_changes -> persisted state remains unchanged
@TEST_INVARIANT: lookup_does_not_block_manual_save -> VERIFIED_BY: [lookup_failed_manual_fallback, bind_account_happy_path]
-->
<!-- @TIER: CRITICAL -->
<!-- @SEMANTICS: profile-page, preferences, lookup, save, ux-states -->
<!-- @PURPOSE: Provide profile UI for binding Superset account and saving default "my dashboards" preference. -->
<!-- @LAYER: UI -->
<!-- @RELATION: BINDS_TO -> frontend.src.lib.api -->
<!-- @RELATION: BINDS_TO -> frontend.src.lib.i18n -->
<!-- @INVARIANT: Save action never updates another user's preference. -->
<!-- @UX_STATE: Default -> Current preference shown with environment selector, account input, and toggle. -->
<!-- @UX_STATE: LookupLoading -> Account candidate list shows loading indicator for selected environment. -->
<!-- @UX_STATE: LookupError -> Inline warning shown; manual username entry remains enabled. -->
<!-- @UX_STATE: Saving -> Save button disabled and shows progress. -->
<!-- @UX_STATE: SaveSuccess -> Success toast appears and form reflects persisted values. -->
<!-- @UX_STATE: SaveError -> Error feedback shown without losing user input. -->
<!-- @UX_FEEDBACK: Toasts for save result, inline validation and lookup fallback messaging. -->
<!-- @UX_RECOVERY: User can retry lookup, manually enter username, or disable toggle to continue. -->
<!-- @TEST_CONTRACT: ProfilePageInteraction -> PreferencePersisted -->
<!-- @TEST_FIXTURE: bind_account_happy_path -> {"env_id":"dev","candidate":"j.doe","toggle":true} -->
<!-- @TEST_EDGE: lookup_failed_manual_fallback -> save still possible with manually entered username -->
<!-- @TEST_EDGE: invalid_username -> save blocked with inline validation error -->
<!-- @TEST_EDGE: cancel_changes -> persisted state remains unchanged -->
<!-- @TEST_INVARIANT: lookup_does_not_block_manual_save -> VERIFIED_BY: [lookup_failed_manual_fallback, bind_account_happy_path] -->
module ProfilePage:
/** @PURPOSE Render profile preference form and orchestrate lookup/save flows. */
function renderAndHandleState() {}
@@ -180,26 +178,24 @@ module ProfilePage:
---
<!-- [DEF:frontend.src.routes.dashboards.+page.profile_filter_ui_extension:Module] -->
<!--
@TIER: CRITICAL
@SEMANTICS: dashboards-page, profile-filter-indicator, override, empty-state
@PURPOSE: Apply profile-default filter context on main dashboards page and provide temporary "show all" override.
@LAYER: UI
@RELATION: BINDS_TO -> frontend.src.lib.api
@RELATION: BINDS_TO -> frontend.src.routes.profile.+page
@INVARIANT: Temporary override never mutates saved profile preference.
@UX_STATE: FilterActive -> Visible badge "My Dashboards Only" with clear action.
@UX_STATE: OverrideActive -> Full list shown with hint that preference remains saved.
@UX_STATE: EmptyFiltered -> Friendly no-match message with path to profile adjustment.
@UX_FEEDBACK: Immediate list refresh after profile save and after override toggle.
@UX_RECOVERY: User can clear override or edit profile binding and reload list.
@TEST_CONTRACT: DashboardsFilterUiAction -> DashboardsGridState
@TEST_FIXTURE: default_profile_filter_applied -> {"saved_toggle":true,"username":"j.doe"}
@TEST_EDGE: no_matching_dashboards -> EmptyFiltered state rendered
@TEST_EDGE: temporary_show_all -> list restored while saved preference preserved
@TEST_EDGE: return_to_page -> FilterActive restored from saved preference
@TEST_INVARIANT: override_non_persistent -> VERIFIED_BY: [temporary_show_all, return_to_page]
-->
<!-- @TIER: CRITICAL -->
<!-- @SEMANTICS: dashboards-page, profile-filter-indicator, override, empty-state -->
<!-- @PURPOSE: Apply profile-default filter context on main dashboards page and provide temporary "show all" override. -->
<!-- @LAYER: UI -->
<!-- @RELATION: BINDS_TO -> frontend.src.lib.api -->
<!-- @RELATION: BINDS_TO -> frontend.src.routes.profile.+page -->
<!-- @INVARIANT: Temporary override never mutates saved profile preference. -->
<!-- @UX_STATE: FilterActive -> Visible badge "My Dashboards Only" with clear action. -->
<!-- @UX_STATE: OverrideActive -> Full list shown with hint that preference remains saved. -->
<!-- @UX_STATE: EmptyFiltered -> Friendly no-match message with path to profile adjustment. -->
<!-- @UX_FEEDBACK: Immediate list refresh after profile save and after override toggle. -->
<!-- @UX_RECOVERY: User can clear override or edit profile binding and reload list. -->
<!-- @TEST_CONTRACT: DashboardsFilterUiAction -> DashboardsGridState -->
<!-- @TEST_FIXTURE: default_profile_filter_applied -> {"saved_toggle":true,"username":"j.doe"} -->
<!-- @TEST_EDGE: no_matching_dashboards -> EmptyFiltered state rendered -->
<!-- @TEST_EDGE: temporary_show_all -> list restored while saved preference preserved -->
<!-- @TEST_EDGE: return_to_page -> FilterActive restored from saved preference -->
<!-- @TEST_INVARIANT: override_non_persistent -> VERIFIED_BY: [temporary_show_all, return_to_page] -->
module DashboardsProfileFilterUI:
/** @PURPOSE Render active-filter indicator and manage temporary override state. */
function renderFilterIndicatorAndOverride() {}
@@ -211,12 +207,12 @@ module DashboardsProfileFilterUI:
Scenario: User binds Superset account from environment and sees filtered dashboards by default.
1. [`frontend.src.routes.profile.+page`](#deffrontendsrcroutesprofilepagemodule) requests account candidates for selected environment.
2. [`backend.src.api.routes.profile`](#defbackendsrcapiroutesprofilemodule) validates self-scope and forwards lookup request.
3. [`backend.src.services.profile_service`](#defbackendsrcservicesprofile_servicemodule) orchestrates lookup via [`backend.src.core.superset_profile_lookup`](#defbackendsrccoresuperset_profile_lookupmodule).
4. User saves preference; profile service normalizes username and persists [`backend.src.models.profile`](#defbackendsrcmodelsprofilemodule).
5. On `/dashboards`, [`backend.src.api.routes.dashboards.profile_filter_extension`](#defbackendsrcapiroutesdashboardsprofile_filter_extensionmodule) applies `owners OR modified_by` matching and returns effective filter metadata.
6. [`frontend.src.routes.dashboards.+page.profile_filter_ui_extension`](#deffrontendsrcroutesdashboardspageprofile_filter_ui_extensionmodule) shows active badge and supports temporary "show all" override.
1. `frontend.src.routes.profile.+page` requests account candidates for the selected environment.
2. `backend.src.api.routes.profile` validates self-scope and forwards the lookup request.
3. `backend.src.services.profile_service` orchestrates lookup via `backend.src.core.superset_profile_lookup`.
4. User saves preference; the profile service normalizes the username and persists `backend.src.models.profile`.
5. On `/dashboards`, `backend.src.api.routes.dashboards.profile_filter_extension` applies `owners OR modified_by` matching and returns effective filter metadata.
6. `frontend.src.routes.dashboards.+page.profile_filter_ui_extension` shows the active badge and supports temporary "show all" override.
---
@@ -230,4 +226,4 @@ Scenario: User binds Superset account from environment and sees filtered dashboa
| `owners OR modified_by` normalization contract | `backend/src/api/routes/__tests__/test_dashboards.py::test_get_dashboards_profile_filter_contract_owners_or_modified_by` | ✅ |
| `override_show_all` semantics | `backend/src/api/routes/__tests__/test_dashboards.py::test_get_dashboards_override_show_all_contract` | ✅ |
| `no_match_results` under active profile filter | `backend/src/api/routes/__tests__/test_dashboards.py::test_get_dashboards_profile_filter_no_match_results_contract` | ✅ |
| page-scoped override restore UX | `frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js` | ✅ |
| page-scoped override restore UX | `frontend/src/routes/dashboards/__tests__/dashboard-profile-override.integration.test.js` | ✅ |

View File

@@ -17,7 +17,7 @@
# @TEST_EDGE: publish_without_approval -> reject transition
# @TEST_EDGE: mutate_existing_manifest -> reject update
# @TEST_INVARIANT: lifecycle_integrity -> VERIFIED_BY: [approve_without_passed_report, publish_without_approval, mutate_existing_manifest]
# [/DEF:CleanReleaseDomainModule]
# [/DEF:CleanReleaseDomainModule:Module]
---
@@ -43,7 +43,7 @@
# @TEST_EDGE: illegal_transition -> returns transition error
# @TEST_EDGE: missing_policy_snapshot -> returns trusted-source error
# @TEST_INVARIANT: thin_client_boundary -> VERIFIED_BY: [missing_candidate, illegal_transition, missing_policy_snapshot]
# [/DEF:CleanReleaseFacadeModule]
# [/DEF:CleanReleaseFacadeModule:Module]
---
@@ -66,7 +66,7 @@
# @TEST_EDGE: malformed_artifact_payload -> reject import
# @TEST_EDGE: empty_artifact_set -> reject mark_prepared
# @TEST_INVARIANT: candidate_input_integrity -> VERIFIED_BY: [duplicate_candidate_id, malformed_artifact_payload, empty_artifact_set]
# [/DEF:CandidatePreparationServiceModule]
# [/DEF:CandidatePreparationServiceModule:Module]
---
@@ -89,7 +89,7 @@
# @TEST_EDGE: build_with_changed_artifacts -> create new version
# @TEST_EDGE: overwrite_existing_manifest -> reject mutation
# @TEST_INVARIANT: manifest_snapshot_integrity -> VERIFIED_BY: [build_without_candidate, build_with_changed_artifacts, overwrite_existing_manifest]
# [/DEF:ManifestServiceModule]
# [/DEF:ManifestServiceModule:Module]
---
@@ -111,7 +111,7 @@
# @TEST_EDGE: registry_missing -> reject request
# @TEST_EDGE: ui_override_attempt -> ignore override and fail validation
# @TEST_INVARIANT: trusted_input_boundary -> VERIFIED_BY: [missing_profile, registry_missing, ui_override_attempt]
# [/DEF:PolicyResolutionServiceModule]
# [/DEF:PolicyResolutionServiceModule:Module]
---
@@ -138,7 +138,7 @@
# @TEST_EDGE: task_crash_mid_run -> final_status ERROR with preserved partial evidence
# @TEST_EDGE: blocked_violation_without_report -> reject finalization
# @TEST_INVARIANT: run_report_consistency -> VERIFIED_BY: [run_without_manifest, task_crash_mid_run, blocked_violation_without_report]
# [/DEF:ComplianceExecutionServiceModule]
# [/DEF:ComplianceExecutionServiceModule:Module]
---
@@ -153,7 +153,7 @@
# @INVARIANT: Mandatory stages execute in stable order unless run stops on terminal error policy.
# @PRE: Compliance context contains candidate, manifest, policy snapshot and registry snapshot.
# @POST: Each stage returns decision, violations and details without mutating trusted snapshots.
# [/DEF:StagePipelineModule]
# [/DEF:StagePipelineModule:Module]
---
@@ -177,7 +177,7 @@
# @TEST_EDGE: duplicate_approve_terminal_state -> reject or preserve existing state deterministically
# @TEST_EDGE: reject_then_publish -> publish remains blocked until a later valid approve
# @TEST_INVARIANT: approval_gate_integrity -> VERIFIED_BY: [approve_blocked_report, approve_foreign_report, duplicate_approve_terminal_state, reject_then_publish]
# [/DEF:ApprovalServiceModule]
# [/DEF:ApprovalServiceModule:Module]
---
@@ -200,7 +200,7 @@
# @TEST_EDGE: revoke_unknown_publication -> reject request
# @TEST_EDGE: republish_after_revoke -> deterministic policy required
# @TEST_INVARIANT: publication_gate_integrity -> VERIFIED_BY: [publish_without_approval, revoke_unknown_publication, republish_after_revoke]
# [/DEF:PublicationServiceModule]
# [/DEF:PublicationServiceModule:Module]
---
@@ -219,7 +219,7 @@
# @INVARIANT: Audit records are append-only in real mode.
# @PRE: Event context contains actor and operation identifiers.
# @POST: One structured audit event is persisted per critical lifecycle mutation.
# [/DEF:AuditServiceModule]
# [/DEF:AuditServiceModule:Module]
---
@@ -231,7 +231,7 @@
# @PURPOSE: Persist and query release candidates and candidate overview projections.
# @LAYER: Infra
# @INVARIANT: Candidate writes honor lifecycle guards defined in the domain module.
# [/DEF:CandidateRepositoryModule]
# [/DEF:CandidateRepositoryModule:Module]
# [DEF:ArtifactRepositoryModule:Module]
# @TIER: STANDARD
@@ -239,7 +239,7 @@
# @PURPOSE: Persist and query candidate artifacts with checksum metadata.
# @LAYER: Infra
# @INVARIANT: Artifact checksum/path records remain stable after import.
# [/DEF:ArtifactRepositoryModule]
# [/DEF:ArtifactRepositoryModule:Module]
# [DEF:ManifestRepositoryModule:Module]
# @TIER: STANDARD
@@ -247,7 +247,7 @@
# @PURPOSE: Persist immutable manifests and provide latest-version lookup.
# @LAYER: Infra
# @INVARIANT: Existing manifest versions are read-only.
# [/DEF:ManifestRepositoryModule]
# [/DEF:ManifestRepositoryModule:Module]
# [DEF:PolicySnapshotRepositoryModule:Module]
# @TIER: STANDARD
@@ -255,7 +255,7 @@
# @PURPOSE: Persist immutable policy and registry snapshots used by runs.
# @LAYER: Infra
# @INVARIANT: Snapshot content cannot be mutated after persistence.
# [/DEF:PolicySnapshotRepositoryModule]
# [/DEF:PolicySnapshotRepositoryModule:Module]
# [DEF:ComplianceRepositoryModule:Module]
# @TIER: STANDARD
@@ -263,7 +263,7 @@
# @PURPOSE: Persist compliance runs, stage records and violations.
# @LAYER: Infra
# @INVARIANT: Historical run evidence is append-only in real mode.
# [/DEF:ComplianceRepositoryModule]
# [/DEF:ComplianceRepositoryModule:Module]
# [DEF:ReportRepositoryModule:Module]
# @TIER: STANDARD
@@ -271,7 +271,7 @@
# @PURPOSE: Persist immutable compliance reports and support report lookup by run and candidate.
# @LAYER: Infra
# @INVARIANT: Completed reports remain immutable.
# [/DEF:ReportRepositoryModule]
# [/DEF:ReportRepositoryModule:Module]
# [DEF:ApprovalRepositoryModule:Module]
# @TIER: STANDARD
@@ -279,7 +279,7 @@
# @PURPOSE: Persist immutable approval decisions and query latest decision state.
# @LAYER: Infra
# @INVARIANT: Approval decisions are historical facts, not mutable flags.
# [/DEF:ApprovalRepositoryModule]
# [/DEF:ApprovalRepositoryModule:Module]
# [DEF:PublicationRepositoryModule:Module]
# @TIER: STANDARD
@@ -287,7 +287,7 @@
# @PURPOSE: Persist publication and revocation records.
# @LAYER: Infra
# @INVARIANT: Publication history is append-only.
# [/DEF:PublicationRepositoryModule]
# [/DEF:PublicationRepositoryModule:Module]
# [DEF:TrustedPolicyStoreModule:Module]
# @TIER: STANDARD
@@ -295,7 +295,7 @@
# @PURPOSE: Abstract the trusted read-only source of policies and source registries.
# @LAYER: Infra
# @INVARIANT: Store reads are side-effect free for clean release operations.
# [/DEF:TrustedPolicyStoreModule]
# [/DEF:TrustedPolicyStoreModule:Module]
---
@@ -319,7 +319,7 @@
# @TEST_EDGE: invalid_input_http -> 422 validation error
# @TEST_EDGE: reject_without_passed_report_http -> 409 conflict
# @TEST_INVARIANT: api_contract_stability -> VERIFIED_BY: [invalid_transition_http, missing_candidate_http, invalid_input_http, reject_without_passed_report_http]
# [/DEF:CleanReleaseApiContract]
# [/DEF:CleanReleaseApiContract:Module]
---
@@ -340,7 +340,7 @@
# @TEST_EDGE: cli_blocked_run -> exit code 1
# @TEST_EDGE: cli_system_error -> exit code 3
# @TEST_INVARIANT: cli_headless_integrity -> VERIFIED_BY: [cli_missing_manifest, cli_blocked_run, cli_system_error]
# [/DEF:CleanReleaseCliContract]
# [/DEF:CleanReleaseCliContract:Module]
---
@@ -370,7 +370,7 @@
* @TEST_EDGE: blocked_report_on_F8 -> approve action disabled
* @TEST_INVARIANT: tui_thin_client_boundary -> VERIFIED_BY: [no_tty_environment, missing_manifest_on_F5, blocked_report_on_F8]
*/
<!-- [/DEF:CleanReleaseTuiApp] -->
<!-- [/DEF:CleanReleaseTuiApp:Component] -->
---

View File

@@ -2,7 +2,7 @@
## Backend Contracts
### [DEF:ValidationPolicyModel:Class]
# [DEF:ValidationPolicyModel:Class]
# @TIER: STANDARD
# @SEMANTICS: SQLAlchemy, Model
# @PURPOSE: Database model for storing validation scheduling rules.
@@ -10,17 +10,17 @@
# @RELATION: DEPENDS_ON -> SQLAlchemy declarative base
# @PRE: Policy payload contains valid window_start and window_end strings.
# @POST: Policy is persisted with default `is_active=True`.
[/DEF:ValidationPolicyModel]
# [/DEF:ValidationPolicyModel:Class]
### [DEF:ValidationPolicySchema:Class]
# [DEF:ValidationPolicySchema:Class]
# @TIER: TRIVIAL
# @SEMANTICS: Pydantic, Schema
# @PURPOSE: API contract for reading and writing Validation Policies.
# @LAYER: API
# @RELATION: DEPENDS_ON -> ValidationPolicyModel
[/DEF:ValidationPolicySchema]
# [/DEF:ValidationPolicySchema:Class]
### [DEF:HealthService:Class]
# [DEF:HealthService:Class]
# @TIER: CRITICAL
# @SEMANTICS: Service, Aggregation
# @PURPOSE: Aggregates dashboard metadata with the latest ValidationRecord to produce health summaries.
@@ -34,9 +34,9 @@
# @TEST_FIXTURE: test_health_aggregation_success -> mock_dashboards_and_records
# @TEST_EDGE: test_health_aggregation_no_records -> Returns UNKNOWN status for dashboards without records.
# @TEST_INVARIANT: latest_record_wins -> VERIFIED_BY: [test_health_aggregation_success]
[/DEF:HealthService]
# [/DEF:HealthService:Class]
### [DEF:HealthRouter:Module]
# [DEF:HealthRouter:Module]
# @TIER: STANDARD
# @SEMANTICS: FastAPI, Route
# @PURPOSE: API endpoints for the Health Center UI.
@@ -44,9 +44,9 @@
# @RELATION: CALLS -> HealthService
# @PRE: Request includes valid authentication token.
# @POST: Returns JSON list of dashboard health statuses.
[/DEF:HealthRouter]
# [/DEF:HealthRouter:Module]
### [DEF:NotificationService:Class]
# [DEF:NotificationService:Class]
# @TIER: CRITICAL
# @SEMANTICS: Service, PubSub
# @PURPOSE: Evaluates policies and routes formatted notifications to dynamically resolved owners and explicit channels.
@@ -61,18 +61,18 @@
# @TEST_FIXTURE: test_owner_routing -> mock_profile_with_telegram
# @TEST_EDGE: test_missing_profile_contact -> Skips owner if no valid contact info is found without crashing.
# @TEST_INVARIANT: async_dispatch -> VERIFIED_BY: [test_owner_routing]
[/DEF:NotificationService]
# [/DEF:NotificationService:Class]
### [DEF:NotificationProvider:Interface]
# [DEF:NotificationProvider:Class]
# @TIER: STANDARD
# @SEMANTICS: Interface, Strategy
# @PURPOSE: Base abstraction for sending formatted alerts to external systems (SMTP, Slack, Telegram).
# @LAYER: Infra
# @PRE: Receives a standardized AlertPayload (text + image links).
# @POST: Delivers the payload to the external system.
[/DEF:NotificationProvider]
# [/DEF:NotificationProvider:Class]
### [DEF:ThrottledSchedulerConfigurator:Module]
# [DEF:ThrottledSchedulerConfigurator:Module]
# @TIER: CRITICAL
# @SEMANTICS: Scheduler, APScheduler
# @PURPOSE: Reads active ValidationPolicies and generates distributed cron/date triggers within the defined execution window.
@@ -86,11 +86,11 @@
# @TEST_FIXTURE: test_window_distribution -> policy_1hr_60tasks
# @TEST_EDGE: test_window_too_small -> 100 tasks in 1 min -> Falls back to minimum safe interval or logs warning.
# @TEST_INVARIANT: distribution_bounds -> VERIFIED_BY: [test_window_distribution, test_window_too_small]
[/DEF:ThrottledSchedulerConfigurator]
# [/DEF:ThrottledSchedulerConfigurator:Module]
## Frontend Contracts
### [DEF:HealthMatrix:Component]
# [DEF:HealthMatrix:Component]
# @TIER: STANDARD
# @SEMANTICS: Svelte, UI
# @PURPOSE: Displays traffic light summary cards (Pass, Warn, Fail).
@@ -100,9 +100,9 @@
# @POST: Renders three numeric summary cards with distinct colors.
# @UX_STATE: Loading -> Skeleton cards.
# @UX_STATE: Idle -> Distinct colored counts.
[/DEF:HealthMatrix]
# [/DEF:HealthMatrix:Component]
### [DEF:HealthCenterPage:Page]
# [DEF:HealthCenterPage:Component]
# @TIER: CRITICAL
# @SEMANTICS: SvelteKit, Route
# @PURPOSE: Main monitoring view for dashboard validation health.
@@ -115,9 +115,9 @@
# @UX_STATE: Error -> Toast notification and empty state.
# @UX_STATE: Success -> Matrix and populated table.
# @UX_TEST: FilterClick -> {click: "Fail only", expected: table shows only RED rows}
[/DEF:HealthCenterPage]
# [/DEF:HealthCenterPage:Component]
### [DEF:AutomationPoliciesPage:Page]
# [DEF:AutomationPoliciesPage:Component]
# @TIER: STANDARD
# @SEMANTICS: SvelteKit, Route
# @PURPOSE: Settings view to create and manage validation policies.
@@ -127,9 +127,9 @@
# @POST: Renders list of policies and 'Create Rule' modal.
# @UX_STATE: Creating -> Modal is open with form.
# @UX_FEEDBACK: SaveSuccess -> Toast "Policy scheduled".
[/DEF:AutomationPoliciesPage]
# [/DEF:AutomationPoliciesPage:Component]
### [DEF:SidebarHealthBadge:Store]
# [DEF:SidebarHealthBadge:Store]
# @TIER: STANDARD
# @SEMANTICS: Svelte Store
# @PURPOSE: Derived or fetched state to show `[🔴 N]` badge on the sidebar.
@@ -137,4 +137,4 @@
# @RELATION: DEPENDS_ON -> ActivityStore or specific Health poll
# @PRE: User is logged in.
# @POST: Provides integer count of currently failing dashboards.
[/DEF:SidebarHealthBadge]
# [/DEF:SidebarHealthBadge:Store]