docs(validation): update agent configs, skills, ADRs, specs

- qa-tester: add validation v2 testing checklist
- speckit.plan: add component reuse scan for frontend
- molecular-cot-logging: add Svelte logger + CLI reader
- semantics-svelte: add RSM model-first protocol, frontend stack
- templates: update plan/tasks/ux-reference templates
- ADR-0004: add llm_dashboard_validation plugin registration
- ADR-0008: add assistant tool registry for v2 validation
- Specs: update 017 tasks from 51 to 99
This commit is contained in:
2026-05-31 22:32:32 +03:00
parent 40c9f849b2
commit 05ef6cdff8
10 changed files with 241 additions and 223 deletions

View File

@@ -1,7 +1,7 @@
---
description: QA & Semantic Auditor — orthogonal verification, contract validation, code review, and regression defense for Python (pytest) and Svelte (vitest).
mode: all
model: deepseek/deepseek-v4-flash
model: opencode/mimo-v2.5-free
temperature: 0.1
permission:
edit: allow

View File

@@ -53,11 +53,13 @@ You **MUST** consider the user input before proceeding (if not empty).
Research must resolve only implementation-shaping unknowns that matter for this repository, such as:
- module placement under `backend/src/` or `frontend/src/`
- **Screen Model topology**: which screens need a `[TYPE Model]` (`.svelte.ts`), which atoms each model declares, which invariants cross widget boundaries
- API endpoint design (REST routes, WebSocket channels)
- database schema changes (SQLAlchemy models, migrations)
- Svelte component hierarchy and store topology
- async task orchestration patterns
- test strategy (pytest + vitest) and required fixture coverage
- **TypeScript DTO alignment**: frontend `types/` matching backend Pydantic schemas
- test strategy (pytest + vitest; L1 model invariants without render + L2 UX contracts with render)
- belief runtime instrumentation for C4/C5 flows
- semantic validation boundaries and static verification workflow
@@ -71,9 +73,17 @@ Use `[NEED_CONTEXT: target]` instead of inventing relation targets, DTO names, o
## Phase 1: Design, ADR Continuity, and Contracts
### Frontend Component Reuse Scan (MANDATORY — before contract generation)
### Frontend Model & Component Reuse Scan (MANDATORY — before contract generation)
Before designing any new Svelte component, execute a **component inventory scan** of the existing codebase to maximise reuse and prevent duplicate primitives. Use a subagent with `subagent_type: "explore"` to scan:
Before designing any new screen, execute a **model-first inventory scan** followed by a **component inventory scan** of the existing codebase to maximise reuse and prevent duplicate primitives.
**Step 1: Screen Model scan** (use a subagent with `subagent_type: "explore"`):
- Search `frontend/src/lib/models/` for existing `[TYPE Model]` contracts
- Use `axiom_semantic_discovery search_contracts type="Model" query="<domain>"` for structured search
- Check model atoms, actions, and invariants — reuse if the screen state maps to an existing model
- New models use `.svelte.ts` extension, `[TYPE Model]` contract, `@STATE`/`@ACTION`/`@INVARIANT` tags
**Step 2: Component scan** (priority order):
**Scan targets** (priority order):
1. `frontend/src/lib/ui/` — design-system atoms: `Button.svelte`, `Select.svelte`, `Input.svelte`, `Card.svelte`
@@ -93,7 +103,7 @@ Before designing any new Svelte component, execute a **component inventory scan*
| Pattern exists (badge, skeleton, tooltip) | Document the Tailwind classes to replicate; no component extraction |
| No reusable asset exists | Create new component only then |
**Output:** The `contracts/modules.md` for every frontend contract MUST include `@RELATION` edges to reused components and a `@RATIONALE` noting WHY the component is reused rather than rebuilt. For pattern-only reuse, the contract MUST reference the source page/file where the pattern was observed.
**Output:** The `contracts/modules.md` for every frontend contract MUST include `@RELATION` edges to reused components/models and a `@RATIONALE` noting WHY the asset is reused rather than rebuilt. For pattern-only reuse, the contract MUST reference the source page/file where the pattern was observed. Components that bind to a Screen Model declare `@RELATION BINDS_TO -> [ModelId]`.
**Forbidden patterns:**
- Creating a new `<Modal>` when `confirm()` suffices
@@ -115,7 +125,8 @@ Generate `data-model.md` for ss-tools domain entities such as:
- Task state transitions
- Git operation entities
- Plugin configuration schemas
- Frontend TypeScript types (when feature is fullstack)
- **Frontend TypeScript DTOs** in `frontend/src/types/` — MUST match backend Pydantic schemas across the stack boundary
- **Screen Model interfaces** — typed atoms, FSM state unions, action payloads for `.svelte.ts` models
### Global ADR Continuity
@@ -123,27 +134,28 @@ Before task decomposition, planning must identify any repo-shaping decisions thi
- Python module layout and decomposition
- FastAPI route organization
- SvelteKit routing and component hierarchy
- **Screen Model topology**: which screens need a model, model-atom boundaries, invariant scope
- belief-state runtime behavior (JSON structured logging / console markers)
- semantic comment-anchor rules
- **TypeScript-first frontend architecture** (`.svelte.ts` models, typed props, typed API boundaries)
- payload/schema stability decisions
For each durable choice, ensure the plan references the relevant ADR and explicitly records accepted and rejected paths.
### Contract Design Output
Generate `contracts/modules.md` as the primary design contract for implementation. Contracts must:
- use short semantic IDs
- classify each planned module/component with `@COMPLEXITY` 1-5
- use short semantic IDs (e.g., `MigrationModel`, `GitManager`, `DashboardApi`)
- classify each planned module/component/model with `[C:N]` complexity in the `#region` anchor (NOT `@COMPLEXITY N`)
- use canonical anchor syntax: `#region Id [C:N] [TYPE TypeName] [SEMANTICS tags]` / `#endregion Id`
- use canonical relation syntax `@RELATION PREDICATE -> TARGET_ID`
- preserve accepted-path and rejected-path memory via `@RATIONALE` and `@REJECTED` where needed
- describe Python modules, FastAPI routes, Svelte components, stores, and services instead of inventing MCP/backend layers
- describe Python modules, FastAPI routes, Svelte components, **Screen Models** (`.svelte.ts`), stores, and services instead of inventing MCP/backend layers
Complexity guidance for this repository:
- **Complexity 1**: anchors only (DTOs, simple Pydantic schemas)
- **Complexity 2**: `@PURPOSE` (pure functions, utility helpers)
- **Complexity 3**: `@PURPOSE`, `@RELATION` (service modules, route handlers)
- **Complexity 4**: `@PURPOSE`, `@RELATION`, `@PRE`, `@POST`, `@SIDE_EFFECT`; orchestration paths should account for belief runtime markers before mutation or return
- **Complexity 5**: level 4 plus `@DATA_CONTRACT`, `@INVARIANT`, and explicit decision-memory continuity
- **C1**: anchors only (DTOs, simple Pydantic schemas, pure constants)
- **C2**: typically adds `@BRIEF` (pure functions, utility helpers)
- **C3**: typically adds `@RELATION` (service modules, route handlers); Svelte components also `@UX_STATE`
- **C4**: typically adds `@PRE`, `@POST`, `@SIDE_EFFECT`; **Screen Models** also `@STATE`, `@ACTION`, `@INVARIANT`; orchestration paths should account for belief runtime markers
- **C5**: C4 + `@DATA_CONTRACT`, `@INVARIANT`, and explicit decision-memory continuity (`@RATIONALE`/`@REJECTED`)
If a planned contract depends on unknown schema, relation target, or ADR identity, emit `[NEED_CONTEXT: target]` instead of fabricating placeholders.

View File

@@ -260,70 +260,67 @@ def _summarise_args(args, kwargs) -> dict:
## V. Svelte / Frontend Pattern
```javascript
// ── trace-id from HTTP response header ──────────────────────
let _traceId = $state("");
The frontend implementation lives at `frontend/src/lib/cot-logger.ts` (installed as `$lib/cot-logger`).
export function initTraceId() {
// Called once from root layout after first fetch
}
### API
export function setTraceId(id) { _traceId = id; }
export function getTraceId() { return _traceId; }
```typescript
function log(
src: string, // e.g. "MigrationModel.executeMigration"
marker: LogMarker, // "REASON" | "REFLECT" | "EXPLORE"
intent: string, // human-readable one-liner
payload?: Record<string, unknown>, // params, result snippet
error?: string, // required for EXPLORE
): void;
```
// ── Component-level CoT logger ──────────────────────────────
export function log(src, marker, intent, payload, error) {
const record = {
ts: new Date().toISOString(),
level: marker === "EXPLORE" ? "WARNING" : "INFO",
trace_id: _traceId || "no-trace",
src,
marker,
intent,
};
if (payload) record.payload = payload;
if (error) record.error = error;
### Import
const line = JSON.stringify(record);
if (marker === "EXPLORE") {
console.warn(line);
} else {
console.info(line);
}
}
```typescript
import { log, setTraceId, getTraceId } from "$lib/cot-logger";
```
### Usage in a Svelte component
```svelte
<script>
<script lang="ts">
import { log } from "$lib/cot-logger";
import { fetchApi } from "$lib/api";
import { page } from "$app/stores";
let { jobId } = $props();
let { jobId }: { jobId: string } = $props();
async function loadJob() {
log("JobDetail.loadJob", "REASON", "Fetch job details", { jobId });
async function loadJob(): Promise<void> {
log("JobDetail", "REASON", "Fetch job details", { jobId });
try {
const resp = await fetchApi(`/api/jobs/${jobId}`);
if (!resp.ok) throw new Error(`Status ${resp.status}`);
const data = await resp.json();
log("JobDetail.loadJob", "REFLECT", "Job details loaded",
log("JobDetail", "REFLECT", "Job details loaded",
{ rows: data.records?.length });
return data;
} catch (e) {
log("JobDetail.loadJob", "EXPLORE", "Failed to load job",
{ jobId }, error = e.message);
} catch (e: unknown) {
log("JobDetail", "EXPLORE", "Failed to load job",
{ jobId }, e instanceof Error ? e.message : "Unknown");
throw e;
}
}
</script>
```
### trace_id Propagation
The trace ID is set automatically when the backend returns it. Call `setTraceId(id)` manually if needed:
```typescript
import { setTraceId } from "$lib/cot-logger";
import { requestApi } from "$lib/api";
const res = await requestApi("/api/endpoint");
if (res.trace_id) setTraceId(res.trace_id);
```
## VI. CLI / Stdout Reader (for humans)
To make JSON lines readable in development:

View File

@@ -277,6 +277,21 @@ search_contracts query="users" type="Model"
Frontend logging uses `log()` from `$lib/cot-logger`, emitting **JSON lines** per MolecularCoTLogging protocol.
Import: `import { log } from "$lib/cot-logger";`
The logger is a TypeScript module at `frontend/src/lib/cot-logger.ts` with full type support:
```typescript
import { log } from "$lib/cot-logger";
// Before an operation:
log("ComponentName", "REASON", "What we are about to do", { param: value });
// After successful verification:
log("ComponentName", "REFLECT", "Operation completed", { result: value });
// On error or fallback:
log("ComponentName", "EXPLORE", "Operation failed", { param: value }, "Error description");
```
### Marker Reference
| Marker | When | Signature |