Core changes: - Add @defgroup/@ingroup to 1791 C2+ contracts (555 files) for HCA 128× pre-training DSA grouping - Add §0.1 Pre-Training Frequency matrix to semantics-core - Add §VIII Attention Architecture rules (ATTN_1-4) with MLA/CSA/HCA/DSA mechanics - Add @defgroup/@ingroup to canonical syntax (§II) and all contract examples Agent prompts (5 files): - Add ZERO-STATE RATIONALE with MLA/CSA/HCA/DSA compression mechanics - Add pre-training note: @RATIONALE/@REJECTED are in-context learned tags - svelte-coder: add missing #region contract, fix Svelte rule violations - python-coder/fullstack-coder: honor function contracts from speckit plan - qa-tester: add attention compliance audit (P3 ATTN_1-4 checks) Skills (6 files): - Translate all axiom_config descriptions to English - Fix doc_dirs to index .opencode/ and .specify/ - Deduplicate 5× complexity_rules → single global_tags catalog - Reduce semantics-svelte 591→485 lines (remove duplicate code blocks) - Fix semantics-testing: 'Short IDs' → 'Short hierarchical IDs' - Fix all examples: flat IDs → hierarchical Domain.Name format - Fix Svelte examples: replace raw Tailwind + <button> with semantic tokens + /ui Speckit workflow (commands + templates): - speckit.plan: add Function-Level Contracts for C3+ with @PRE/@POST/@TEST_EDGE - speckit.plan: add Attention Compliance Gate (ATTN_1-4 before contract generation) - speckit.tasks: add function contract inlining format (constraints in task description) - speckit.specify: load semantics-core for spec density rules - spec-template: add #region contract, @SEMANTICS grouping, hierarchical IDs - ux-reference-template: add #region wrapper - plan-template: add attention gate, @defgroup/@ingroup guidance - tasks-template: add attention audit + rebuild + orphan check tasks - constitution.md: translate to English, add Principle VIII (attention-optimized contracts) Reference modules rewritten (hierarchical IDs + full contracts): - Auth.Jwt: 6 child contracts with @RATIONALE/@REJECTED/@TEST_EDGE - Api.Auth: 5 endpoints with @TEST_EDGE + molecular CoT markers - Migration.Model: @defgroup Migration with 18 @ACTION + 6 @INVARIANT Scripts: - add_defgroup_ingroup.py: zero-risk additive @ingroup migration (1791 insertions) - migrate_hierarchical.py: flat→hierarchical ID dry-run analysis (792 contracts) - merge_prompts.py: merge all prompts/skills/commands into one review file Config: - axiom_config.yaml: 749→395 lines (-47%), English, doc_dirs include prompts - Fix test_datasets.py import collision (rename → test_datasets_routes.py) - Fix test_preview.py: SupersetClient→get_superset_client, AsyncMock, logger f-string
247 lines
9.0 KiB
Python
247 lines
9.0 KiB
Python
# #region ReportModels [C:3] [TYPE Module] [SEMANTICS pydantic, report, model, schema, task, task-type]
|
|
# @defgroup Models Module group.
|
|
# @BRIEF Canonical report schemas for unified task reporting across heterogeneous task types.
|
|
# @LAYER Domain
|
|
# @PRE Pydantic library and task manager models are available.
|
|
# @POST Provides validated schemas for cross-plugin reporting and UI consumption.
|
|
# @SIDE_EFFECT None (schema definition).
|
|
# @DATA_CONTRACT Model[TaskReport, ReportCollection, ReportDetailView]
|
|
# @RELATION DEPENDS_ON -> [TaskModels]
|
|
# @INVARIANT Canonical report fields are always present for every report item.
|
|
|
|
from datetime import datetime
|
|
from enum import Enum
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field, field_validator, model_validator
|
|
|
|
|
|
# #region TaskType [C:3] [TYPE Class] [SEMANTICS enum, type, task]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT Must contain valid generic task type mappings.
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
# @BRIEF Supported normalized task report types.
|
|
class TaskType(str, Enum):
|
|
LLM_VERIFICATION = "llm_verification"
|
|
BACKUP = "backup"
|
|
MIGRATION = "migration"
|
|
DOCUMENTATION = "documentation"
|
|
CLEAN_RELEASE = "clean_release"
|
|
UNKNOWN = "unknown"
|
|
|
|
|
|
# #endregion TaskType
|
|
|
|
|
|
# #region ReportStatus [C:3] [TYPE Class] [SEMANTICS enum, status, task]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT TaskStatus enum mapping logic holds.
|
|
# @BRIEF Supported normalized report status values.
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
class ReportStatus(str, Enum):
|
|
SUCCESS = "success"
|
|
FAILED = "failed"
|
|
IN_PROGRESS = "in_progress"
|
|
PARTIAL = "partial"
|
|
|
|
|
|
# #endregion ReportStatus
|
|
|
|
|
|
# #region ErrorContext [C:3] [TYPE Class] [SEMANTICS error, context, payload]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT The properties accurately describe error state.
|
|
# @BRIEF Error and recovery context for failed/partial reports.
|
|
#
|
|
# @TEST_CONTRACT ErrorContextModel ->
|
|
# {
|
|
# required_fields: {
|
|
# message: str
|
|
# },
|
|
# optional_fields: {
|
|
# code: str,
|
|
# next_actions: list[str]
|
|
# }
|
|
# }
|
|
# @TEST_FIXTURE basic_error -> {"message": "Connection timeout", "code": "ERR_504", "next_actions": ["retry"]}
|
|
# @TEST_EDGE missing_message -> {"code": "ERR_504"}
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
class ErrorContext(BaseModel):
|
|
code: str | None = None
|
|
message: str
|
|
next_actions: list[str] = Field(default_factory=list)
|
|
|
|
|
|
# #endregion ErrorContext
|
|
|
|
|
|
# #region TaskReport [C:3] [TYPE Class] [SEMANTICS report, model, summary]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT Must represent canonical task record attributes.
|
|
# @BRIEF Canonical normalized report envelope for one task execution.
|
|
#
|
|
# @TEST_CONTRACT TaskReportModel ->
|
|
# {
|
|
# required_fields: {
|
|
# report_id: str,
|
|
# task_id: str,
|
|
# task_type: TaskType,
|
|
# status: ReportStatus,
|
|
# updated_at: datetime,
|
|
# summary: str
|
|
# },
|
|
# invariants: [
|
|
# "report_id is a non-empty string",
|
|
# "task_id is a non-empty string",
|
|
# "summary is a non-empty string"
|
|
# ]
|
|
# }
|
|
# @TEST_FIXTURE valid_task_report ->
|
|
# {
|
|
# report_id: "rep-123",
|
|
# task_id: "task-456",
|
|
# task_type: "migration",
|
|
# status: "success",
|
|
# updated_at: "2026-02-26T12:00:00Z",
|
|
# summary: "Migration completed successfully"
|
|
# }
|
|
# @TEST_EDGE empty_report_id -> {"report_id": " ", "task_id": "task-456", "task_type": "migration", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}
|
|
# @TEST_EDGE empty_summary -> {"report_id": "rep-123", "task_id": "task-456", "task_type": "migration", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": ""}
|
|
# @TEST_EDGE invalid_task_type -> {"report_id": "rep-123", "task_id": "task-456", "task_type": "invalid_type", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}
|
|
# @TEST_INVARIANT non_empty_validators -> verifies: [empty_report_id, empty_summary]
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
class TaskReport(BaseModel):
|
|
report_id: str
|
|
task_id: str
|
|
task_type: TaskType
|
|
status: ReportStatus
|
|
started_at: datetime | None = None
|
|
updated_at: datetime
|
|
summary: str
|
|
details: dict[str, Any] | None = None
|
|
validation_record: dict[str, Any] | None = None # Extended for US2
|
|
error_context: ErrorContext | None = None
|
|
source_ref: dict[str, Any] | None = None
|
|
|
|
@field_validator("report_id", "task_id", "summary")
|
|
@classmethod
|
|
def _non_empty_str(cls, value: str) -> str:
|
|
if not isinstance(value, str) or not value.strip():
|
|
raise ValueError("Value must be a non-empty string")
|
|
return value.strip()
|
|
|
|
|
|
# #endregion TaskReport
|
|
|
|
|
|
# #region ReportQuery [C:3] [TYPE Class] [SEMANTICS query, filter, search]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT Time and pagination queries are mutually consistent.
|
|
# @BRIEF Query object for server-side report filtering, sorting, and pagination.
|
|
#
|
|
# @TEST_CONTRACT ReportQueryModel ->
|
|
# {
|
|
# optional_fields: {
|
|
# page: int, page_size: int, task_types: list[TaskType], statuses: list[ReportStatus],
|
|
# time_from: datetime, time_to: datetime, search: str, sort_by: str, sort_order: str
|
|
# },
|
|
# invariants: [
|
|
# "page >= 1", "1 <= page_size <= 100",
|
|
# "sort_by in {'updated_at', 'status', 'task_type'}",
|
|
# "sort_order in {'asc', 'desc'}",
|
|
# "time_from <= time_to if both exist"
|
|
# ]
|
|
# }
|
|
# @TEST_FIXTURE valid_query -> {"page": 1, "page_size":20, "sort_by": "updated_at", "sort_order": "desc"}
|
|
# @TEST_EDGE invalid_page_size_large -> {"page_size": 150}
|
|
# @TEST_EDGE invalid_sort_by -> {"sort_by": "unknown_field"}
|
|
# @TEST_EDGE invalid_time_range -> {"time_from": "2026-02-26T12:00:00Z", "time_to": "2026-02-25T12:00:00Z"}
|
|
# @TEST_INVARIANT attribute_constraints_enforced -> verifies: [invalid_page_size_large, invalid_sort_by, invalid_time_range]
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
class ReportQuery(BaseModel):
|
|
page: int = Field(default=1, ge=1)
|
|
page_size: int = Field(default=20, ge=1, le=100)
|
|
task_types: list[TaskType] = Field(default_factory=list)
|
|
statuses: list[ReportStatus] = Field(default_factory=list)
|
|
time_from: datetime | None = None
|
|
time_to: datetime | None = None
|
|
search: str | None = Field(default=None, max_length=200)
|
|
sort_by: str = Field(default="updated_at")
|
|
sort_order: str = Field(default="desc")
|
|
|
|
@field_validator("sort_by")
|
|
@classmethod
|
|
def _validate_sort_by(cls, value: str) -> str:
|
|
allowed = {"updated_at", "status", "task_type"}
|
|
if value not in allowed:
|
|
raise ValueError(f"sort_by must be one of: {', '.join(sorted(allowed))}")
|
|
return value
|
|
|
|
@field_validator("sort_order")
|
|
@classmethod
|
|
def _validate_sort_order(cls, value: str) -> str:
|
|
if value not in {"asc", "desc"}:
|
|
raise ValueError("sort_order must be 'asc' or 'desc'")
|
|
return value
|
|
|
|
@model_validator(mode="after")
|
|
def _validate_time_range(self):
|
|
if self.time_from and self.time_to and self.time_from > self.time_to:
|
|
raise ValueError("time_from must be less than or equal to time_to")
|
|
return self
|
|
|
|
|
|
# #endregion ReportQuery
|
|
|
|
|
|
# #region ReportCollection [C:3] [TYPE Class] [SEMANTICS collection, pagination]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT Represents paginated data correctly.
|
|
# @BRIEF Paginated collection of normalized task reports.
|
|
#
|
|
# @TEST_CONTRACT ReportCollectionModel ->
|
|
# {
|
|
# required_fields: {
|
|
# items: list[TaskReport], total: int, page: int, page_size: int, has_next: bool, applied_filters: ReportQuery
|
|
# },
|
|
# invariants: ["total >= 0", "page >= 1", "page_size >= 1"]
|
|
# }
|
|
# @TEST_FIXTURE empty_collection -> {"items": [], "total": 0, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
|
# @TEST_EDGE negative_total -> {"items": [], "total": -5, "page": 1, "page_size": 20, "has_next": False, "applied_filters": {}}
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
class ReportCollection(BaseModel):
|
|
items: list[TaskReport]
|
|
total: int = Field(ge=0)
|
|
page: int = Field(ge=1)
|
|
page_size: int = Field(ge=1)
|
|
has_next: bool
|
|
applied_filters: ReportQuery
|
|
|
|
|
|
# #endregion ReportCollection
|
|
|
|
|
|
# #region ReportDetailView [C:3] [TYPE Class] [SEMANTICS view, detail, logs]
|
|
# @defgroup Models Module group.
|
|
# @INVARIANT Incorporates a report and logs correctly.
|
|
# @BRIEF Detailed report representation including diagnostics and recovery actions.
|
|
#
|
|
# @TEST_CONTRACT ReportDetailViewModel ->
|
|
# {
|
|
# required_fields: {report: TaskReport},
|
|
# optional_fields: {timeline: list[dict], diagnostics: dict, next_actions: list[str]}
|
|
# }
|
|
# @TEST_FIXTURE valid_detail -> {"report": {"report_id": "rep-1", "task_id": "task-1", "task_type": "backup", "status": "success", "updated_at": "2026-02-26T12:00:00Z", "summary": "Done"}}
|
|
# @TEST_EDGE missing_report -> {}
|
|
# @RELATION DEPENDS_ON -> ReportModels
|
|
class ReportDetailView(BaseModel):
|
|
report: TaskReport
|
|
timeline: list[dict[str, Any]] = Field(default_factory=list)
|
|
diagnostics: dict[str, Any] | None = None
|
|
next_actions: list[str] = Field(default_factory=list)
|
|
|
|
|
|
# #endregion ReportDetailView
|
|
|
|
# #endregion ReportModels
|