381 lines
20 KiB
Markdown
381 lines
20 KiB
Markdown
---
|
||
description: Execute the implementation planning workflow for ss-tools (Python backend + Svelte frontend) and generate research, design, contracts, and quickstart artifacts.
|
||
handoffs:
|
||
- label: Create Tasks
|
||
agent: speckit.tasks
|
||
prompt: Break the plan into executable tasks for Python/Svelte implementation
|
||
send: true
|
||
- label: Create Checklist
|
||
agent: speckit.checklist
|
||
prompt: Create a requirements-quality checklist for the active feature
|
||
---
|
||
|
||
## User Input
|
||
|
||
```text
|
||
$ARGUMENTS
|
||
```
|
||
|
||
You **MUST** consider the user input before proceeding (if not empty).
|
||
|
||
## Outline
|
||
|
||
1. **Setup**: Run `.specify/scripts/bash/setup-plan.sh --json` from repo root and parse `FEATURE_SPEC`, `IMPL_PLAN`, `SPECS_DIR`, and `BRANCH`.
|
||
- `IMPL_PLAN` is the authoritative path for `plan.md` inside `specs/<feature>/`.
|
||
- Derive `FEATURE_DIR` from `IMPL_PLAN` and write every planning artifact there.
|
||
- Never treat `.kilo/plans/*` as workflow output for `/speckit.plan`.
|
||
|
||
2. **Load canonical planning context**:
|
||
- `README.md`
|
||
- `requirements.txt` (backend dependencies)
|
||
- `frontend/package.json` (frontend dependencies)
|
||
- `.specify/memory/constitution.md`
|
||
- `.opencode/skills/semantics-core/SKILL.md`
|
||
- `.opencode/skills/semantics-contracts/SKILL.md`
|
||
- `.opencode/skills/semantics-python/SKILL.md`
|
||
- `.opencode/skills/semantics-svelte/SKILL.md`
|
||
- `.opencode/skills/semantics-testing/SKILL.md`
|
||
- `.specify/templates/plan-template.md`
|
||
- `FEATURE_DIR/contracts/ux/screen-models.md` (if `/speckit.ux` was run)
|
||
- `FEATURE_DIR/contracts/ux/api-ux.md` (if `/speckit.ux` was run)
|
||
- `FEATURE_DIR/contracts/ux/*-ux.md` (per-screen UX contracts)
|
||
- relevant `docs/adr/*.md`
|
||
|
||
3. **Execute the planning workflow** using the template structure:
|
||
- Fill `Technical Context` for the current repository reality: Python 3.9+/FastAPI backend, SvelteKit 5/Tailwind frontend, PostgreSQL, Docker, semantic contracts, belief runtime.
|
||
- Fill `Constitution Check` using the local constitution.
|
||
- ERROR if a blocking constitutional or semantic conflict is discovered and cannot be justified.
|
||
- Phase 0: generate `research.md` in `FEATURE_DIR`, resolving all material unknowns.
|
||
- Phase 1: generate `data-model.md`, `contracts/modules.md`, optional machine-readable contract artifacts, and `quickstart.md` in `FEATURE_DIR`.
|
||
- Phase 1: if UX contracts exist, generate `traceability.md` — a requirements traceability matrix mapping Story → Model → API → Task → Test.
|
||
- Materialize blocking ADR references and planning decisions inside the plan and downstream contracts.
|
||
- Run `.specify/scripts/bash/update-agent-context.sh kilocode` after planning artifacts are written.
|
||
|
||
4. **Stop and report** after planning artifacts are complete. Report branch, `plan.md` path, generated artifacts, and blocking ADR/decision-memory outcomes.
|
||
|
||
## Phase 0: Research
|
||
|
||
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
|
||
- **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
|
||
|
||
**If `/speckit.ux` was run before plan:**
|
||
- `screen-models.md` defines Model inventory → use directly, don't re-discover
|
||
- `api-ux.md` defines API shapes → use as @DATA_CONTRACT source for backend Pydantic schemas
|
||
- `<screen>-ux.md` defines UX contracts → use as @UX_STATE/@UX_FEEDBACK source for component contracts
|
||
- Generated `.svelte.ts` model files in `frontend/src/lib/models/` → DO NOT regenerate; reference them via `@RELATION BINDS_TO` from component contracts
|
||
|
||
Write `research.md` with concise sections:
|
||
- Decision
|
||
- Rationale
|
||
- Alternatives Considered
|
||
- Impact On Contracts / Tasks
|
||
|
||
Use `[NEED_CONTEXT: target]` instead of inventing relation targets, DTO names, or module boundaries that cannot be grounded in repo context.
|
||
|
||
## Phase 1: Design, ADR Continuity, and Contracts
|
||
|
||
### Frontend Model & Component Reuse Scan (MANDATORY — before contract generation)
|
||
|
||
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`
|
||
2. `frontend/src/lib/components/ui/` — composite UI widgets: `SearchableMultiSelect.svelte`, `MultiSelect.svelte`
|
||
3. `frontend/src/lib/components/` — feature components that may be adaptable
|
||
4. Inline patterns in existing pages (`frontend/src/routes/`) — badges, skeletons, empty states, collapsibles
|
||
|
||
**For each found component, the scan MUST return:**
|
||
- Exact file path
|
||
- Props interface (what it accepts)
|
||
- Whether it's a direct fit, adaptable, or pattern-only
|
||
|
||
**Reuse decision tree:**
|
||
| Situation | Action |
|
||
|-----------|--------|
|
||
| Component exists and fits | `@RELATION DEPENDS_ON -> [ExistingComponent]` — zero new code |
|
||
| 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/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
|
||
- Building a custom `<Select>` when `$lib/ui/Select.svelte` exists
|
||
- Inventing a `<Toast>` system when `addToast()` from `$lib/toasts.js` is already wired
|
||
|
||
### UX / Interaction Validation
|
||
|
||
Validate the proposed design against `ux_reference.md` as an **interaction reference** for operators, API callers, CLI/operator flows, result envelopes, warnings, recovery guidance, and (when applicable) browser-based UI flows.
|
||
|
||
If the planned architecture degrades the promised interaction model, deterministic recovery path, or context-budget behavior, stop and warn the user.
|
||
|
||
### Attention Compliance Gate (MANDATORY — before generating contracts)
|
||
|
||
Every contract in `contracts/modules.md` MUST pass these checks. Contracts that fail are invisible to the model after context compression (per `semantics-core` §VIII):
|
||
|
||
| Rule | Check | Failure Consequence |
|
||
|------|-------|---------------------|
|
||
| **ATTN_1** | First anchor line: `#region Domain.Sub.Name [C:N] [TYPE Type] [SEMANTICS tag1,tag2]` — all on ONE line | CSA 4× pooling loses detail from multi-line anchors |
|
||
| **ATTN_2** | IDs are hierarchical: `Core.Auth.Login`, not `login_handler` | HCA 128× makes flat IDs indistinguishable from noise |
|
||
| **ATTN_3** | All contracts in a domain share primary `@SEMANTICS` keyword (e.g., all auth contracts use `[SEMANTICS auth, ...]`) | DSA Lightning Indexer fails to group domain contracts |
|
||
| **ATTN_4** | Contract ≤150 lines, module ≤400 lines | Contracts exceeding the sliding window are partially invisible |
|
||
|
||
**Cross-stack compliance (fullstack features only):**
|
||
- Backend Pydantic schema contract and frontend TypeScript DTO contract MUST have matching `@RELATION` edges crossing the stack boundary.
|
||
- Both MUST share at least one `@SEMANTICS` keyword so the DSA Indexer can link them.
|
||
|
||
### Data Model Output
|
||
|
||
Generate `data-model.md` for ss-tools domain entities such as:
|
||
- Pydantic request/response schemas
|
||
- SQLAlchemy models and relationships
|
||
- WebSocket message formats
|
||
- Task state transitions
|
||
- Git operation entities
|
||
- Plugin configuration schemas
|
||
- **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
|
||
|
||
Before task decomposition, planning must identify any repo-shaping decisions this feature depends on or extends:
|
||
- 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
|
||
|
||
### Contract Design Output
|
||
|
||
Generate `contracts/modules.md` as the primary design contract for implementation. Contracts must:
|
||
- use short hierarchical semantic IDs with 2-3 levels: `Domain.Name` (e.g., `Core.Auth.Login`, `Api.Dashboards`, `Users.ListModel`, `Test.Migration.RunTask`). NOT flat IDs like `login_handler` or `UserListModel`.
|
||
- 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, **Screen Models** (`.svelte.ts`), stores, and services instead of inventing MCP/backend layers
|
||
|
||
Complexity guidance for this repository:
|
||
- **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`)
|
||
|
||
### Function-Level Contracts for C3+ (MANDATORY for cross-stack and orchestration)
|
||
|
||
For every C3+ function, method, or Screen Model action that is:
|
||
- An API endpoint (FastAPI route handler)
|
||
- A Screen Model action with `@SIDE_EFFECT`
|
||
- A C4/C5 orchestration function (migration runner, task executor, auth flow)
|
||
|
||
Generate its full `#region` header in `contracts/modules.md` under its parent module. This header becomes the implementation contract that the coding agent MUST satisfy.
|
||
|
||
**Minimal header for C3 API endpoints:**
|
||
```
|
||
#region Domain.Resource.Action [C:3] [TYPE Function] [SEMANTICS domain,action]
|
||
# @ingroup Domain
|
||
# @BRIEF One-line purpose.
|
||
# @RELATION DEPENDS_ON -> [DependencyService]
|
||
# @RELATION DEPENDS_ON -> [DTO:RequestSchema]
|
||
```
|
||
|
||
**Full header for C4/C5 orchestration & cross-stack functions:**
|
||
```
|
||
#region Domain.Resource.Action [C:4] [TYPE Function] [SEMANTICS domain,action]
|
||
# @ingroup Domain
|
||
# @BRIEF One-line purpose.
|
||
# @PRE Precondition 1 (verifiable by guard clause).
|
||
# @POST Output guarantee 1 (testable assertion).
|
||
# @SIDE_EFFECT State mutation, I/O, or external call.
|
||
# @SIDE_EFFECT Logging (REASON/REFLECT/EXPLORE markers required).
|
||
# @RELATION DEPENDS_ON -> [ServiceDependency]
|
||
# @RELATION DEPENDS_ON -> [DTO:InputSchema]
|
||
# @DATA_CONTRACT InputDTO -> OutputDTO
|
||
# @RATIONALE Why this implementation approach.
|
||
# @REJECTED What alternative was considered and forbidden.
|
||
# @TEST_EDGE: scenario_name -> Expected failure behavior.
|
||
```
|
||
|
||
**Screen Model actions (Svelte `.svelte.ts`):**
|
||
```
|
||
// #region ScreenModel.actionName [C:4] [TYPE Function] [SEMANTICS domain,action]
|
||
// @BRIEF What this action does.
|
||
// @ACTION Public action — callable from components.
|
||
// @PRE Guards before execution.
|
||
// @POST State guarantees after completion.
|
||
// @SIDE_EFFECT API call, store mutation, model state update.
|
||
// @RELATION CALLS -> [apiClient]
|
||
// @TEST_EDGE: network_failure -> ScreenState = "error"
|
||
```
|
||
|
||
**Rules:**
|
||
- Function contract headers are **NOT implementation** — they are design contracts. The coding agent implements the body.
|
||
- C1/C2 functions do NOT need pre-generated contracts — only C3+.
|
||
- `@TEST_EDGE` declarations enable qa-tester to write tests BEFORE implementation (true TDD).
|
||
- `@DATA_CONTRACT` on API endpoints enables fullstack-coder to align frontend TypeScript DTOs.
|
||
- `@SIDE_EFFECT` with belief runtime markers ensures molecular CoT logging is wired from day one.
|
||
- Cross-stack functions MUST have matching `@DATA_CONTRACT` on both backend and frontend sides.
|
||
- All contracts MUST pass the Attention Compliance Gate (ATTN_1-4) above.
|
||
|
||
If a planned contract depends on unknown schema, relation target, or ADR identity, emit `[NEED_CONTEXT: target]` instead of fabricating placeholders.
|
||
|
||
### Fixture Generation (MANDATORY for C3+ contracts with @TEST_EDGE)
|
||
|
||
For every C3+ contract that declares `@TEST_EDGE`, `@POST`, or `@REJECTED` guardrails, generate **canonical test fixtures** in `FEATURE_DIR/fixtures/`. Canonical fixtures live beside the spec — they are the design-time source of truth. Executable fixtures are materialized into `tests/` later by `/speckit.tasks`.
|
||
|
||
**Output structure:**
|
||
|
||
```text
|
||
specs/<feature>/fixtures/
|
||
├── manifest.md # Fixture index with GRACE contracts
|
||
├── api/
|
||
│ ├── <contract>_valid.json
|
||
│ ├── <contract>_missing_field.json
|
||
│ ├── <contract>_invalid_type.json
|
||
│ ├── <contract>_external_fail.json
|
||
│ └── <contract>_rejected_path.json
|
||
└── model/
|
||
├── <model>_valid.json
|
||
├── <model>_edge_case.json
|
||
└── <model>_invariant.json
|
||
```
|
||
|
||
**`manifest.md` — fixture index with GRACE contracts:**
|
||
|
||
```markdown
|
||
#region FixtureManifest [C:3] [TYPE ADR] [SEMANTICS test,fixture,[DOMAIN]]
|
||
@defgroup Fixtures Canonical test fixtures for [FEATURE].
|
||
|
||
## @{ Fixture FX_Auth.Login.Valid [C:2] [TYPE Block] [SEMANTICS test,auth,fixture]
|
||
@BRIEF Valid login request/response pair.
|
||
@RELATION VERIFIES -> [Api.Auth.Login]
|
||
@TEST_FIXTURE: valid_login -> fixtures/api/auth_login_valid.json
|
||
@TEST_INVARIANT: TokenIssued -> VERIFIED_BY: [Test.Api.Auth]
|
||
## @} Fixture FX_Auth.Login.Valid
|
||
|
||
## @{ Fixture FX_Auth.Login.MissingPassword [C:2] [TYPE Block] [SEMANTICS test,auth,fixture]
|
||
@BRIEF Missing password field — @TEST_EDGE: missing_field.
|
||
@RELATION VERIFIES -> [Api.Auth.Login]
|
||
@TEST_EDGE: missing_field -> 422 VALIDATION_ERROR
|
||
@TEST_FIXTURE: missing_password -> fixtures/api/auth_login_missing_field.json
|
||
## @} Fixture FX_Auth.Login.MissingPassword
|
||
|
||
## @{ Fixture FX_Migration.EnvReset [C:2] [TYPE Block] [SEMANTICS test,migration,fixture]
|
||
@BRIEF Model invariant: changing source env resets selection.
|
||
@RELATION VERIFIES -> [Migration.Model]
|
||
@TEST_INVARIANT: env_reset_selection -> VERIFIED_BY: [Test.Migration.Model]
|
||
@TEST_FIXTURE: env_reset -> fixtures/model/migration_env_reset.json
|
||
## @} Fixture FX_Migration.EnvReset
|
||
```
|
||
|
||
**JSON fixture format:**
|
||
|
||
```json
|
||
{
|
||
"fixture_id": "FX_Auth.Login.MissingPassword",
|
||
"verifies": "Api.Auth.Login",
|
||
"edge": "missing_field",
|
||
"input": {
|
||
"username": "admin"
|
||
},
|
||
"expected": {
|
||
"status": 422,
|
||
"error_code": "VALIDATION_ERROR",
|
||
"error_detail": "Field 'password' is required"
|
||
}
|
||
}
|
||
```
|
||
|
||
**Generation rules:**
|
||
- **One JSON file per fixture** — named `<contract_snake>_<edge>.json`
|
||
- **Minimum 5 per C3+ contract**: valid, missing_field, invalid_type, external_fail, rejected_path
|
||
- **Expected values ALWAYS hardcoded** — never derived from implementation (anti-tautology)
|
||
- **Input values are concrete** — real strings, numbers, objects, not pseudocode
|
||
- **Fixture ID format**: `FX_<Domain>.<Name>` — hierarchical, matches contract hierarchy
|
||
- **@TEST_FIXTURE in manifest** points to the JSON file path
|
||
- **@RELATION VERIFIES** links fixture to production contract
|
||
- For `@REJECTED` paths: expected MUST include error/failure, proving the path is unreachable
|
||
- For model invariants: input = state before action, expected = state after action
|
||
- Do NOT generate executable test files here — only canonical JSON fixtures
|
||
|
||
### Fixture Traceability
|
||
|
||
Extend `traceability.md` with a Fixture column:
|
||
|
||
| Story | Model | Fixture | Task | Test |
|
||
|-------|-------|---------|------|------|
|
||
| US1 | Api.Auth.Login | FX_Auth.Login.Valid | T017 | Test.Api.Auth
|
||
|
||
### Quickstart Output
|
||
|
||
Generate `quickstart.md` using real repository verification paths:
|
||
- Backend: `cd backend && source .venv/bin/activate && python -m pytest -v`
|
||
- Frontend: `cd frontend && npm run test`
|
||
- Lint: `cd backend && python -m ruff check .`
|
||
- Frontend lint: `cd frontend && npm run lint`
|
||
- Docker: `docker compose up --build`
|
||
|
||
### Traceability Matrix Output
|
||
|
||
If UX contracts exist (`contracts/ux/` was generated by `/speckit.ux`), generate `traceability.md` — a requirements traceability matrix (RTM) mapping every user story through its implementation chain:
|
||
|
||
```markdown
|
||
#region Traceability [C:3] [TYPE ADR] [SEMANTICS traceability,rtm,[DOMAIN]]
|
||
@defgroup Trace Matrix Requirements → Model → API → Task → Test for [FEATURE].
|
||
|
||
## Traceability Matrix
|
||
|
||
| Story | Screen | Model | Fixture | API Endpoint | Backend Task | Frontend Task | Test |
|
||
|-------|--------|-------|---------|-------------|-------------|--------------|------|
|
||
| US1: [Title] | /route | Domain.Model | FX_Domain.Valid | GET /api/... | T017 | T015 | Test.Domain |
|
||
| US1: [Title] | /route | Domain.Model | FX_Domain.MissingField | POST /api/... | T018 | T019 | Test.Domain.Edge |
|
||
|
||
## Impact Analysis Quick Reference
|
||
|
||
| If you change... | These fixtures verify it | These tests verify it | These screens depend |
|
||
|-----------------|------------------------|----------------------|---------------------|
|
||
| `GET /api/dashboards` | FX_Dashboards.Hub.* | Test.Dashboards.Hub | /dashboards, /migration |
|
||
| `Dashboards.Hub` model | FX_Dashboards.EnvReset | Test.Dashboards.Hub | /dashboards |
|
||
|
||
#endregion Traceability
|
||
```
|
||
|
||
**Generation rules:**
|
||
- One row per unique (Story, API Endpoint, Screen) tuple
|
||
- Model column: `[TYPE Model]` contract ID from `screen-models.md`
|
||
- API column: endpoint from `api-ux.md` or `contracts/modules.md`
|
||
- Task columns: task IDs from `tasks.md` (to be filled after `/speckit.tasks` — leave as `T???` if tasks not yet generated)
|
||
- Test column: test contract ID pattern `Test.<Domain>.<Name>`
|
||
- Impact table: derived from `@RELATION` edges in contracts — invert the dependency graph
|
||
- Grep-friendly: `grep "Dashboards.Hub" traceability.md` → all rows for that model
|
||
- Agent zombie mode: without MCP tools, `grep "<contract>" traceability.md` replaces `impact_analysis`
|
||
|
||
## Key Rules
|
||
|
||
- Use absolute paths in workflow execution.
|
||
- Planning must reflect the current repository structure (`backend/src/**/*.py`, `frontend/src/**/*.svelte`, `backend/tests/`, `docs/adr/*`).
|
||
- Do not reference `.ai/*` or `.kilocode/*` paths (use `.opencode/` for skills).
|
||
- Do not write any feature planning artifact outside `specs/<feature>/...`.
|
||
- Do not hand off to `speckit.tasks` until blocking ADR continuity and rejected-path guardrails are explicit.
|