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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user