diff --git a/.github/workflows/community-smoke.yml b/.github/workflows/community-smoke.yml index 6e9f16b4e6..a21d78be51 100644 --- a/.github/workflows/community-smoke.yml +++ b/.github/workflows/community-smoke.yml @@ -79,6 +79,7 @@ jobs: test -f .specify/presets/workflow-preset/schemas/speckit.behavior.scenario-instances.v1.schema.json test -f .specify/presets/workflow-preset/schemas/speckit.behavior.data-fixtures.v1.schema.json test -f .specify/presets/workflow-preset/schemas/speckit.behavior.assertions.v1.schema.json + test -f .specify/presets/workflow-preset/schemas/speckit.design.visual-item-matrix.v1.schema.json test -f .specify/presets/workflow-preset/schemas/speckit.implement.manifest.v1.schema.json test -f .specify/presets/workflow-preset/schemas/speckit.implement.handoff.v2.schema.json test -f .specify/presets/workflow-preset/schemas/speckit.implement.receipt.v1.schema.json diff --git a/.github/workflows/workflow-preset-integration.yml b/.github/workflows/workflow-preset-integration.yml index b0d7e70e78..684aeee41f 100644 --- a/.github/workflows/workflow-preset-integration.yml +++ b/.github/workflows/workflow-preset-integration.yml @@ -117,6 +117,7 @@ jobs: test -f .specify/presets/workflow-preset/preset.yml test -f .specify/presets/workflow-preset/templates/plan-template.md test -f .specify/presets/workflow-preset/templates/constitution-template.md + test -f .specify/presets/workflow-preset/schemas/speckit.design.visual-item-matrix.v1.schema.json test -f .specify/templates/tasks-template.md test -f .specify/presets/workflow-preset/commands/speckit.constitution.md test -f .specify/presets/workflow-preset/commands/speckit.plan.md diff --git a/presets/catalog.json b/presets/catalog.json index e465f46b86..21ea4775f7 100644 --- a/presets/catalog.json +++ b/presets/catalog.json @@ -40,7 +40,7 @@ }, "provides": { "commands": 8, - "templates": 26 + "templates": 27 }, "tags": [ "behavior", diff --git a/presets/workflow-preset/2026-05-15-plan-design-artifacts-proposal.md b/presets/workflow-preset/2026-05-15-plan-design-artifacts-proposal.md deleted file mode 100644 index 77ca871eac..0000000000 --- a/presets/workflow-preset/2026-05-15-plan-design-artifacts-proposal.md +++ /dev/null @@ -1,432 +0,0 @@ -# Plan Design Artifacts Proposal - -> Superseded in the current preset contract: `test-plan.md` is no longer a standalone artifact. Test strategy is derived by `/speckit.tasks` from behavior contracts, interface contracts, `research.md`, and `quickstart.md`; object design and service sequencing remain optional planning artifacts. - -## Purpose - -This proposal refines the expected output boundary of `/speckit.plan`. -The current planning workflow produces `plan.md`, `research.md`, -`data-model.md`, `contracts/`, and `quickstart.md`. That covers the -technical approach, domain model, interface contracts, and a key validation -path, but it leaves three design concerns without stable homes: - -1. Internal object structure: design patterns, inheritance, composition, - dependencies, and references between implementation objects. -2. Service-call behavior: the order of calls across APIs, services, external - systems, asynchronous events, and failure branches. -3. Test design: the testing scope, testing levels, scenario matrix, data - strategy, and traceability from requirements to validation. - -The goal is to add explicit planning artifacts for these concerns without -turning `plan.md` into a large mixed-purpose document. `plan.md` should remain -the technical decision summary and navigation point. Detailed design should -live in dedicated files that can be consumed by `/speckit.tasks`, -`/speckit.implement`, and reviewers. - -## Recommended File Layout - -Use independent planning artifacts under the feature directory: - -```text -specs// -├── plan.md -├── research.md -├── data-model.md -├── contracts/ -│ ├── -│ └── sequences.md -├── class-diagram.md -├── test-plan.md -└── quickstart.md -``` - -The three proposed additions are: - -- `class-diagram.md`: internal implementation object design. -- `contracts/sequences.md`: service-call and interface-flow sequencing. -- `test-plan.md`: testing strategy and test scenario design. - -## Planning Granularity - -`/speckit.plan` operates at technical design granularity. It should provide -enough structure for `/speckit.tasks` to create executable tasks and for -`/speckit.implement` to preserve the intended architecture, but it should not -expand into task numbering, source code, test functions, or method-level -implementation details. - -```text -spec.md - product behavior, user stories, acceptance criteria - -plan.md - technical approach, decisions, constraints, artifact navigation - -research.md - unresolved technical questions, decisions, rationale, alternatives - -data-model.md - domain entities, business fields, relationships, validation, states - -contracts/ - external interface contracts and observable service interaction behavior - -class-diagram.md - internal object structure, patterns, inheritance, composition, references - -test-plan.md - testing strategy, coverage intent, scenario matrix, validation levels - -quickstart.md - minimal executable validation path - -tasks.md - concrete tasks, files, ordering, parallelization -``` - -## Artifact Contracts - -### `class-diagram.md` - -**Responsibility** - -`class-diagram.md` captures internal implementation design. It explains how -the code should be organized around core classes, interfaces, abstract types, -design patterns, inheritance, composition, aggregation, dependencies, and -references. - -It is the right place for diagrams involving objects such as services, -repositories, adapters, strategies, factories, controllers, coordinators, -interfaces, and abstract base classes. - -**Upstream inputs** - -- `spec.md`: user stories, feature behavior, and domain language. -- `plan.md`: selected architecture, project structure, platform, and - implementation constraints. -- `research.md`: decisions about design patterns, framework constraints, - extensibility, or dependency direction. -- `data-model.md`: domain entities that need representation in the - implementation object model. -- `contracts/`: external boundaries that internal objects must satisfy. - -**Downstream consumers** - -- `/speckit.tasks`: derives implementation tasks for services, adapters, - repositories, strategies, factories, interfaces, and other core objects. -- `/speckit.implement`: preserves object boundaries, dependency direction, - inheritance, and composition choices. -- Code review: checks whether implementation drifted from the intended design - pattern or object responsibilities. - -**Boundary** - -`class-diagram.md` does not define API request or response fields. Those belong -in `contracts/`. - -It does not replace `data-model.md`. Domain entity fields, business validation, -relationships, and state transitions remain in `data-model.md`. A class diagram -may reference a domain entity only when needed to explain object collaboration. - -It does not define test strategy or test cases. Those belong in `test-plan.md`. - -It does not define task IDs, file-by-file implementation steps, or execution -order. Those belong in `tasks.md`. - -**Granularity** - -The artifact should describe core implementation types and their relationships: - -- Key classes, interfaces, and abstract types. -- Responsibilities of each core type. -- Inheritance, composition, aggregation, dependency, and reference - relationships. -- Design pattern participants and extension points. -- Lifecycle or ownership rules when they affect implementation structure. - -It should not list every helper, DTO, private utility, or method. It may include -important methods only when they are necessary to explain a design pattern or -object contract. - -**Decision rule** - -If the question is "how are internal implementation objects organized?", use -`class-diagram.md`. - -If the question is "what business fields does the entity have?", use -`data-model.md`. - -If the question is "what does the external interface accept or return?", use -`contracts/`. - -### `contracts/sequences.md` - -**Responsibility** - -`contracts/sequences.md` captures service-call-level sequencing. It explains -how an API request, command, event, or external interaction flows across -components, services, infrastructure, and third-party systems. - -It is the right place for sequence diagrams covering synchronous calls, -asynchronous events, callbacks, retries, compensation, rollback, and observable -failure behavior. - -**Upstream inputs** - -- `spec.md`: user workflows, acceptance scenarios, and externally observable - behavior. -- `plan.md`: service boundaries, architecture, deployment assumptions, and - external dependencies. -- `research.md`: integration decisions, failure-handling decisions, and - framework constraints. -- `contracts/`: endpoint, command, event, or message contracts. -- `data-model.md`: state changes or persistence boundaries affected by the - service flow. - -**Downstream consumers** - -- `/speckit.tasks`: derives tasks for integrations, service orchestration, - transaction boundaries, async event handling, retries, and failure paths. -- `/speckit.implement`: implements the intended call order, service boundaries, - compensation behavior, and error propagation. -- `test-plan.md`: derives integration, contract, and end-to-end scenarios from - the documented flows. - -**Boundary** - -`contracts/sequences.md` does not define request and response field schemas. -Those belong in the interface contract files under `contracts/`. - -It does not describe internal inheritance, composition, or class relationships. -Those belong in `class-diagram.md`. - -It does not define the testing matrix. That belongs in `test-plan.md`. - -It does not provide user-facing run instructions. Those belong in -`quickstart.md`. - -**Granularity** - -The artifact should describe participants, message order, service boundaries, -and critical branches: - -- Calling actor or system. -- API, service, worker, database, queue, or external system participants. -- Main success path. -- Important alternate paths. -- Failure handling, retries, compensation, rollback, and idempotency behavior. -- Async event publication and consumption when applicable. - -It should not expand into individual private function calls unless a function -represents a meaningful service or integration boundary. - -**Decision rule** - -If the question is "how does a request, command, or event flow across -components or services?", use `contracts/sequences.md`. - -If the question is "what fields are in the interface?", use the relevant -contract schema under `contracts/`. - -If the question is "which classes collaborate internally?", use -`class-diagram.md`. - -### `test-plan.md` - -**Responsibility** - -`test-plan.md` captures test design. It defines how the feature should be -validated across test levels, what is in scope, what is out of scope, which -data is needed, and how requirements trace to validation scenarios. - -It should include a test case matrix as one section, not reduce the whole -artifact to a matrix. The plan should explain the strategy behind the matrix. - -**Upstream inputs** - -- `spec.md`: user stories, acceptance criteria, edge cases, and priorities. -- `plan.md`: testing framework, technical stack, project structure, and - constraints. -- `research.md`: test tooling decisions and tradeoffs. -- `data-model.md`: validation rules, state transitions, and data combinations. -- `contracts/`: interface contracts that need contract tests. -- `contracts/sequences.md`: integration flows, async flows, and failure paths. -- `quickstart.md`: minimal executable validation path. - -**Downstream consumers** - -- `/speckit.tasks`: derives test tasks, including unit, contract, integration, - and end-to-end validation tasks. -- `/speckit.implement`: executes validation according to the planned testing - levels and coverage intent. -- CI and review: check whether delivered tests match the planned coverage. -- `quickstart.md`: remains the minimal manual or scripted validation path and - can be referenced by the test plan. - -**Boundary** - -`test-plan.md` does not implement test code. Test files, test functions, -fixtures, and assertions are created during implementation. - -It does not replace `quickstart.md`. `quickstart.md` is the shortest executable -validation path; `test-plan.md` is the broader test design. - -It does not redefine product requirements. Requirements remain in `spec.md`. - -It does not redefine interface schemas. Schemas remain in `contracts/`. - -It does not assign task IDs or execution order. Those belong in `tasks.md`. - -**Granularity** - -The artifact should describe validation intent at scenario and test-level -granularity: - -- Test objectives. -- In-scope and out-of-scope areas. -- Unit, contract, integration, and end-to-end testing strategy. -- Test data, fixture, and mock strategy. -- Requirement-to-test traceability. -- Test case matrix with scenario, preconditions, inputs, expected result, test - level, and source requirement. -- Non-functional validation when required by the feature, such as performance, - security, compatibility, or accessibility. - -It should not include exact test function bodies, assertion code, or complete -fixture file contents. - -**Decision rule** - -If the question is "what should be tested and at what level?", use -`test-plan.md`. - -If the question is "how can a user or reviewer quickly verify the feature -works?", use `quickstart.md`. - -If the question is "which test file should be created first?", use `tasks.md`. - -## `plan.md` Boundary - -`plan.md` should remain the decision summary and navigation file. It should -reference the detailed artifacts rather than embedding their full contents. - -Recommended `plan.md` section: - -```markdown -## Design Artifacts - -- Internal object design: ./class-diagram.md -- Service sequences: ./contracts/sequences.md -- Test plan: ./test-plan.md -- Data model: ./data-model.md -- Interface contracts: ./contracts/ -- Validation path: ./quickstart.md -``` - -`plan.md` owns: - -- Technical approach. -- Technology choices. -- Project structure. -- Constitution and architecture checks. -- Complexity justification. -- Links to detailed design artifacts. - -`plan.md` does not own: - -- Complete class diagrams. -- Complete sequence diagrams. -- Complete test matrices. -- Task IDs or file-level implementation steps. -- Source code or test code. - -## Reasoning Flow - -The proposed artifacts form a dependency chain that preserves the current -spec-driven workflow while making design responsibilities explicit: - -```text - ┌──────────────┐ - │ spec.md │ - └──────┬───────┘ - ↓ - ┌──────────────┐ - │ plan.md │ - └──────┬───────┘ - ↓ - ┌───────────────┼────────────────┐ - ↓ ↓ ↓ -┌──────────────┐ ┌──────────────┐ ┌──────────────┐ -│ data-model.md│ │ contracts/ │ │ research.md │ -└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ - ↓ ↓ ↓ -┌──────────────┐ ┌──────────────┐ ┌──────────────┐ -│class-diagram │ │ sequences.md │ │ test-plan.md │ -└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ - └───────────────┬┴───────────────┘ - ↓ - ┌──────────────┐ - │ tasks.md │ - └──────────────┘ -``` - -The dependency direction is intentional: - -- `spec.md` defines the product behavior. -- `plan.md` chooses the technical approach and points to design artifacts. -- `research.md` resolves unknowns that influence design decisions. -- `data-model.md` defines domain state and business data. -- `contracts/` defines externally visible interfaces. -- `class-diagram.md` translates domain and architecture decisions into internal - object structure. -- `contracts/sequences.md` translates interface boundaries into observable - service flows. -- `test-plan.md` derives validation strategy from requirements, data, - contracts, and service flows. -- `tasks.md` converts the design artifacts into ordered executable work. - -## Expected Downstream Behavior - -If this proposal is accepted, `/speckit.tasks` should treat these files as -optional but first-class planning inputs: - -- Read `class-diagram.md` when present and generate implementation tasks that - preserve the documented object model. -- Read `contracts/sequences.md` when present and generate integration, - orchestration, async-flow, and failure-path tasks. -- Read `test-plan.md` when present and generate test tasks that reflect the - planned test levels and scenario matrix. - -`/speckit.implement` should also read these files when present: - -- Use `class-diagram.md` to keep implementation object boundaries aligned. -- Use `contracts/sequences.md` to implement service flows and failure behavior. -- Use `test-plan.md` to validate the delivered feature against the planned - coverage. - -## Non-Goals - -This proposal does not require all features to produce large diagrams or a -large test plan. Simple features may produce concise files or mark sections as -not applicable with a concrete reason. - -This proposal does not move product requirements out of `spec.md`. - -This proposal does not replace `data-model.md`, `contracts/`, or -`quickstart.md`. - -This proposal does not require source code changes by itself. It defines a -reviewable target design for possible future changes to the Spec Kit templates -and command instructions. - -## Review Questions - -1. Should `class-diagram.md`, `contracts/sequences.md`, and `test-plan.md` be - required for every `/speckit.plan` run, or optional artifacts generated only - when relevant? -2. Should `/speckit.tasks` generate test tasks automatically whenever - `test-plan.md` exists, even if the user did not explicitly request TDD? -3. Should sequence diagrams be stored only in `contracts/sequences.md`, or - should projects with no external contracts place them at - `specs//sequences.md`? -4. Should `class-diagram.md` use Mermaid class diagrams as the default format, - or remain format-neutral so teams can use PlantUML or text tables? diff --git a/presets/workflow-preset/CHANGELOG.md b/presets/workflow-preset/CHANGELOG.md index eef347d0c5..127c988987 100644 --- a/presets/workflow-preset/CHANGELOG.md +++ b/presets/workflow-preset/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +- Added Final Code Review visual consistency checks for implemented UI states, viewport behavior, visual proof evidence, and Client Asset Contract bindings. +- Clarified that `/speckit.tasks` defines validation, visual verification, contract validation, data-side-effect validation, integration/e2e validation, and scope-aware code review tasks, while `/speckit.implement` only executes those tasks and records receipt evidence without inventing validation strategy or widening scope. +- Added Visual Item Matrix and Visual Restoration Trace fields so Figma/provider evidence can carry stable UI/UX restoration refs into `spec.md` and Visual Fidelity readiness. +- Added a normalized Visual Item Matrix JSON schema and validator checks for deterministic UI/UX restoration intake. +- Clarified that provider evidence artifacts may record screenshot/proof refs and provider blockers, while only the checklist Visual Fidelity Evidence Matrix decides visual planning readiness, proof sufficiency, Gate Status, Blocking Items, and accepted exception rules. + ## 1.3.8 - Aligned code review receipt validation with the receipt schema for data side-effect review required fields. diff --git a/presets/workflow-preset/README.md b/presets/workflow-preset/README.md index f869dff871..3e35672597 100644 --- a/presets/workflow-preset/README.md +++ b/presets/workflow-preset/README.md @@ -167,6 +167,12 @@ provider for the current toolchain; other providers can supply screenshots, prototype documents, design-system documentation, or other design evidence. Requirement Merge resolves Product Requirement and Design Requirement inputs into `spec.md` while leaving unresolved conflicts as `[NEEDS CLARIFICATION]`. +For UI/UX restoration, provider evidence should preserve stable Visual Item ID +trace refs from frame/node evidence through Design Requirement Intake, `spec.md`, +and the Visual Fidelity Evidence Matrix. +`/speckit.specify` does not translate Figma variants into code props or decide +component reuse. It records observed states, requirement-level component roles, +and explicit use constraints only when the input evidence already states them. ### Screenshot Evidence @@ -188,6 +194,7 @@ requirements. Missing screenshot evidence blocks readiness when `spec.md` declares visual proof required and the checklist template requires the missing screenshot level. Responsive visual requirements block PASS only when they are complex, multi-state, or declare L2 or L3 visual proof; missing viewport-specific evidence then sets Gate Status: BLOCKED and lists the item in Blocking Items. The Visual Fidelity Evidence Matrix is the single visual readiness record; visual evidence decisions should not be duplicated outside the matrix and Blocking Items. +Provider evidence artifacts may record screenshot refs, proof refs, coverage gaps, and provider blockers as source facts, but only the Visual Fidelity Evidence Matrix decides visual planning readiness, proof sufficiency, accepted exception rules, Gate Status, and Blocking Items. Ordinary UI screenshots remain recommended unless `spec.md` declares visual proof required. ### Figma Provider Input @@ -211,6 +218,12 @@ not generate the artifact instances. Figma-derived requirements are ready only when the packet records raw metadata completeness, metadata index completeness proof, node inventory parity, and no blocker lint errors. +For visual fidelity work, the external intake can additionally provide a +normalized `speckit.design.visual_item_matrix.v1` JSON artifact validated by +`schemas/speckit.design.visual-item-matrix.v1.schema.json`; this improves field +determinism for Visual Item IDs, variant/state evidence, explicit component use +constraints, screenshot refs, blockers, and spec targets without replacing raw +Figma evidence. Then run agent-native orchestrated implementation: @@ -301,14 +314,16 @@ Development-only contract helpers: `checklists/behavior-testability.md` is the BDD, NFR, and applicable Visual Fidelity readiness gate. It checks `spec.md` before planning so behavior, NFRs, design-derived evidence, and product-side visual requirements such as pixel-perfect, brand-critical, responsive visual, or UI visual acceptance requirements are ready for behavior projection and planning. Its Case Coverage Matrix uses one row per story or capability case type; rows mark Required, Not Applicable, or Unknown, cite source sections, and list Blocker IDs while Scenario IDs remain a `/speckit.plan` output. Its Visual Fidelity Evidence Matrix uses one row per visual requirement or visual proof obligation and is the single visual readiness record for source section, fidelity scope, screenshot level, evidence refs, visual proof requirement, blocking item ID, and exception rule. Missing Required case coverage, Unknown case applicability, or missing NFR criteria blocks planning when it affects downstream behavior projection or design. -`templates/design-requirement-intake-template.md` defines the provider-neutral Design Requirement Intake shape for page inventory, hierarchy, user paths, component states, visual tokens, layout, responsive, motion, state coverage, visual acceptance requirements, screenshot traceability, and traceability. +`templates/design-requirement-intake-template.md` defines the provider-neutral Design Requirement Intake shape for page inventory, hierarchy, user paths, component states, visual tokens, layout, responsive, motion, state coverage, visual acceptance requirements, Visual Restoration Trace rows, screenshot traceability, and traceability. `templates/requirement-merge-report-template.md` defines how Product Requirement and Design Requirement inputs are reconciled before baseline `spec.md` generation. It records merge rules, product-owned facts, design-owned facts, design requirement promotion rules, conflicts, clarification outputs, and the `spec.md` handoff. -`templates/figma-evidence-packet-template.md` defines how Figma-derived provider evidence is normalized before Design Requirement Intake and `/speckit.specify` write requirements. It separates observed design facts, screenshot evidence, structural inferences, missing requirements, and excluded scope so Figma evidence does not get treated as complete product behavior. It references Figma provider source readiness contract results for raw metadata completeness, metadata index completeness proof, node inventory parity, and blocker lint errors before Figma-derived requirements can be treated as ready. +`templates/figma-evidence-packet-template.md` defines how Figma-derived provider evidence is normalized before Design Requirement Intake and `/speckit.specify` write requirements. It separates observed design facts, Visual Item Matrix rows, screenshot evidence, structural inferences, missing requirements, and excluded scope so Figma evidence does not get treated as complete product behavior. It references Figma provider source readiness contract results for raw metadata completeness, metadata index completeness proof, node inventory parity, and blocker lint errors before Figma-derived requirements can be treated as provider-ready. It does not decide visual planning readiness. `templates/figma-intake-contract.md` defines the raw Figma provider source readiness contract for `figma-metadata.part-*.xml`, `figma-metadata.index.yaml`, and `figma-node-inventory.yaml`. It owns raw metadata completeness, metadata index completeness proof, node inventory parity, blocker lint errors, and the ready gate; the Evidence Packet references those results as normalized provider input for `spec.md`. +`schemas/speckit.design.visual-item-matrix.v1.schema.json` defines the normalized Visual Item Matrix JSON contract for machine-checkable UI/UX restoration intake. It validates field shape for visual item source refs, fidelity scope, observed variant/state evidence, explicit component/copy/drawing constraints, screenshot refs, visual proof level, blockers, and spec requirement targets while raw Figma evidence remains the source of truth. + `behavior/bdd.draft.feature` captures Phase 0 behavior projection in readable Given/When/Then form. `behavior/behavior-scenarios.draft.json`, `behavior/uif.intent.json`, and `behavior/data-fixtures.intent.json` make the same draft behavior machine-readable enough for planning formalization. `contracts/bdd/`, `contracts/uif/`, and `contracts/behavior/` contain planning-phase formal behavior contracts. They are generated from Phase 0 drafts after planning has resolved fixture strategy, data model, interface contracts, and validation paths, unless planning records `N/A or blocker` for missing planning input. `contracts/behavior/scenario-instances.json` carries `case_coverage_blockers` for Required cases that cannot be formalized. Failure scenarios must be structured enough to constrain implementation, including error code, failure feedback, and state invariant, rollback, or compensation assertion references. @@ -319,7 +334,7 @@ Development-only contract helpers: For visual planning, research.md records visual validation decisions by Visual Item ID, including viewport and state coverage, asset or fixture strategy, visual proof strategy, related contracts, and quickstart validation paths. contracts formalize visual interaction and state constraints by linking accepted visual items to Expected UIF, behavior scenarios, assertions, and supporting API/data schemas. contracts/sequences.md records visual state flow only when it affects cross-boundary sequencing, async results, retries, rollback, compensation, or error propagation; it does not redefine layout, tokens, screenshot matrices, or visual readiness. -Test strategy derivation happens during `/speckit.tasks`. The command derives unit, contract, integration, and end-to-end validation work from BDD contracts, Expected UIF contracts, behavior contracts, interface contracts, `research.md`, and `quickstart.md`, then writes the strategy inline on the relevant `tasks.md` checklist items. +Test strategy derivation happens during `/speckit.tasks`. The command derives unit, contract, integration, and end-to-end validation work from BDD contracts, Expected UIF contracts, behavior contracts, interface contracts, `research.md`, and `quickstart.md`, then writes the strategy inline on the relevant `tasks.md` checklist items. It also defines visual verification, contract validation, data-side-effect validation, integration/e2e validation, and scope-aware code review tasks in `tasks.md`; `/speckit.implement` executes those tasks and records receipt evidence without inventing validation strategy, changing requirements, updating contracts, or widening scope. The handoff context digest includes relevant design constraints, visual fidelity requirements, screenshot refs, visual proof refs, Design Requirement trace refs, validation decisions, quickstart paths, and behavior contracts when present, so Worker Agents can preserve object boundaries, service flows, visual intent, and validation intent without reading full planning documents by default. diff --git a/presets/workflow-preset/commands/speckit.checklist.md b/presets/workflow-preset/commands/speckit.checklist.md index b10c6dda3e..eca3940db9 100644 --- a/presets/workflow-preset/commands/speckit.checklist.md +++ b/presets/workflow-preset/commands/speckit.checklist.md @@ -48,7 +48,9 @@ Check Visual Fidelity Readiness when `spec.md` contains design-derived requireme Use the behavior-testability checklist template as the visual gate authority. Require source traceability, provider readiness status, evidence refs, and blockers, and clear visual requirements for state, responsive, accessibility, component mapping, and accepted exception coverage. Build a Visual Fidelity Evidence Matrix with one row per visual requirement or visual proof obligation. Record Screenshot evidence level, declared visual proof required, provider evidence refs or screenshot refs, and any Gate Status: BLOCKED item in Blocking Items. +The Visual Fidelity Evidence Matrix alone decides visual planning readiness, proof level sufficiency, screenshot sufficiency, accepted exception rules, Gate Status, and Blocking Items. Use one Visual Fidelity Evidence Matrix as the single visual readiness record; do not duplicate visual evidence decisions outside the matrix and Blocking Items. +Read visual facts from `spec.md` and evidence refs; do not call Figma, re-extract Figma evidence, rebuild provider matrices, or create another visual readiness path. Do not add historical visual rules or alternate visual decision paths. Responsive visual requirements block PASS only when they are complex, multi-state, or declare L2 or L3 visual proof; missing viewport-specific evidence then sets Gate Status: BLOCKED and lists the item in Blocking Items. Screenshots support visual facts but do not create product semantics. diff --git a/presets/workflow-preset/commands/speckit.implement.md b/presets/workflow-preset/commands/speckit.implement.md index 62948f891f..7c7267dbc2 100644 --- a/presets/workflow-preset/commands/speckit.implement.md +++ b/presets/workflow-preset/commands/speckit.implement.md @@ -57,7 +57,7 @@ Map planned `U` design objects to concrete source, test, fixture, configuration, - read only `allowed_read_paths` - write only `allowed_write_paths` - write `task_status_update.receipt_path` as `speckit.implement.receipt.v1` -- validation_evidence must reference the relevant BDD scenario, behavior assertion, API contract, or quickstart path when the handoff context includes behavior contracts +- execute validation and code review only when those tasks are already present in `tasks.md`; do not invent validation strategy, add lifecycle roles, change requirements, update contracts, or widen scope during implementation; validation_evidence must reference the relevant BDD scenario, behavior assertion, API contract, or quickstart path when the handoff context includes behavior contracts - asset binding must map Client Asset Contract entries to local asset paths or code asset mappings from the handoff context; missing required client visual assets, mappings, variants, or fallbacks become `context_gaps` - Code review tasks must echo `task_type: code_review`, write `review_conclusion.checked_sources`, `data_side_effect_review`, `consistency_repairs`, and `deferred_validation_todos`; use empty arrays or objects when there are no entries - For data side-effect review, inspect the actual implementation diff for runtime database writes and field-level update/delete behavior, bulk writes, soft deletes, ORM whole-object saves, migrations/backfills, retries, rollback/compensation, and external-system writes diff --git a/presets/workflow-preset/commands/speckit.plan.md b/presets/workflow-preset/commands/speckit.plan.md index 3840258a1b..1427eb7870 100644 --- a/presets/workflow-preset/commands/speckit.plan.md +++ b/presets/workflow-preset/commands/speckit.plan.md @@ -91,7 +91,7 @@ When visual requirements are in scope, keep `plan.md` navigation linked to visua When visual requirements are in scope, planning must keep the Visual Fidelity Evidence Matrix as the upstream readiness record and split visual carry-forward across the existing planning outputs: -- `research.md`: add Visual validation decisions for each relevant Visual Item ID. Record selected test level, fixture or asset strategy, viewport/state coverage strategy, visual regression or baseline proof strategy, screenshot refs, visual proof refs, Design Requirement trace refs, related quickstart validation path, and related UIF or behavior contract path. Do not copy the Visual Fidelity Evidence Matrix into `research.md`, do not create new visual requirements, and do not call Figma or other provider tools. +- `research.md`: add Visual validation decisions for each relevant Visual Item ID. Record selected test level, fixture or asset strategy, viewport/state coverage strategy, visual regression or baseline proof strategy, screenshot refs, visual proof refs, Design Requirement trace refs, related quickstart validation path, and related UIF or behavior contract path. Do not copy the Visual Fidelity Evidence Matrix into `research.md`, do not create new visual requirements, do not call Figma or other provider tools, and do not rebuild provider evidence matrices. - `contracts/uif/` and `contracts/behavior/`: formalize accepted visual interaction and state constraints only when they affect observable behavior. Expected UIF contracts may carry visual_item_refs, viewport_matrix_refs, state_matrix_refs, visual_proof_refs, and accepted_exception_refs. Behavior contracts may reference visual assertion IDs or blockers when a visual state cannot be formalized without inventing requirements. Interface contracts in `contracts/` may model only API or data fields needed to support UI states, assets, or feedback; they must not contain layout rules or screenshot proof decisions. - `contracts/sequences.md`: add UI interaction sequence, visual state handoff points, responsive branch trigger refs, and visual proof references only when visual states affect cross-boundary order, async callbacks, retries, rollback, compensation, or error propagation. Keep visual style, tokens, layout breakpoints, screenshot matrices, and validation commands out of `contracts/sequences.md`. diff --git a/presets/workflow-preset/commands/speckit.specify.md b/presets/workflow-preset/commands/speckit.specify.md index 13c8dde864..abe96c877f 100644 --- a/presets/workflow-preset/commands/speckit.specify.md +++ b/presets/workflow-preset/commands/speckit.specify.md @@ -26,7 +26,7 @@ Design Requirement Input Policy: run specification as staged intake and merge wo Product intake input: PRD, user prompt, product notes, and explicit product constraints. Product intake output: product-owned requirement facts in `spec.md`, including stories, functional requirements, non-functional requirements, assumptions, and product `[NEEDS CLARIFICATION]` markers. ### Stage 1: Design Requirement Intake -Design intake input: provider-neutral design evidence, provider source packets, screenshots, visual proof, and source refs. Design intake output: evidence-backed design facts recorded only in `spec.md`, including Client Asset Contract facts: source refs, asset source strategy, required variants, fallback policy, and blocker status. +Design intake input: provider-neutral design evidence, provider source packets, screenshots, visual proof, and source refs. Design intake output: evidence-backed design facts recorded only in `spec.md`, including stable Visual Item ID trace refs, observed variant/state facts, and Client Asset Contract facts: source refs, asset source strategy, required variants, fallback policy, and blocker status. If the design source is a Figma URL and a ready packet is supplied by a runtime agent or external Figma intake that has Figma MCP access: @@ -37,11 +37,12 @@ If the design source is a Figma URL and a ready packet is supplied by a runtime Use `Observed from Figma` as design evidence. Treat `Inferred from Structure`, `Missing / Needs Clarification`, and `Out of Scope` as interpretation, unresolved requirements, and excluded evidence respectively. Screenshots support visual facts only; screenshots must not create product semantics. Screenshot-implied business rules stay `[NEEDS CLARIFICATION]`. +Do not invent code props, code state names, component reuse decisions, self-drawing bans, or copy restrictions from Figma structure. Record component use, no-self-draw, and no-new-copy constraints only when product input or qualified provider evidence states them explicitly. If Figma MCP access is unavailable, Continue to write only `spec.md` and record `[BLOCKED: PROVIDER_EVIDENCE]` for the missing Figma Evidence Packet, screenshots, or design facts. ### Stage 2: Requirement Merge -Merge input: product facts from Stage 0 plus qualified design facts from Stage 1. Merge output: confirmed baseline requirements, conflicts, assumptions, clarification markers, and provider blockers recorded in `spec.md`. Apply Design Requirement Promotion Rules: promote only evidence-backed visual, layout, state, interaction, responsive, accessibility, and acceptance facts; product semantics implied only by provider evidence stay `[NEEDS CLARIFICATION]`. +Merge input: product facts from Stage 0 plus qualified design facts from Stage 1. Merge output: confirmed baseline requirements, conflicts, assumptions, clarification markers, and provider blockers recorded in `spec.md`. Apply Design Requirement Promotion Rules: promote only evidence-backed visual, layout, state, interaction, responsive, accessibility, and acceptance facts with source refs; preserve Visual Item ID trace refs for visual requirements. Product semantics implied only by provider evidence stay `[NEEDS CLARIFICATION]`. ### Stage 3: Generate baseline spec.md Baseline spec output: one implementation-agnostic `spec.md` contract containing confirmed product requirements, qualified design-derived requirements, source refs, `[NEEDS CLARIFICATION]`, and `[BLOCKED: PROVIDER_EVIDENCE]` items. diff --git a/presets/workflow-preset/commands/speckit.tasks.md b/presets/workflow-preset/commands/speckit.tasks.md index 0ab64a2280..a1ae3ceb8d 100644 --- a/presets/workflow-preset/commands/speckit.tasks.md +++ b/presets/workflow-preset/commands/speckit.tasks.md @@ -25,8 +25,12 @@ If any listed file exists under FEATURE_DIR, task generation must consume it as Use these inputs to derive implementation, integration, orchestration, failure-handling, and validation tasks. For behavior contracts, derive test-first tasks in user-story order: fixture setup, BDD/E2E or contract test, implementation, and verification evidence. Keep task output in the existing checklist format and user-story organization. +Tasks owns validation and review task definition. `/speckit.implement` executes only tasks already present in `tasks.md` and records receipt evidence; it must not invent validation strategy, add lifecycle roles, change requirements, update contracts, or widen scope during execution. + For Client Asset Contract entries, derive asset preparation, binding, implementation, and validation tasks in dependency order. Missing required client visual assets become readiness blockers; do not generate handoff fields or `allowed_write_paths`. +Use Visual Fidelity Readiness as the only visual planning readiness source. Do not create a second readiness rule from Screenshot Coverage Matrix, Visual Item Matrix, Visual Restoration Trace, or provider evidence artifacts; if required visual evidence is missing, report a readiness blocker instead of deriving complete-looking UI tasks. + Missing Required case scenarios must become blockers, not silently skipped tasks. If `checklists/behavior-testability.md` marks a case type Required but the matching BDD or behavior contract is absent and no `N/A or blocker` exists, report the missing case instead of generating a complete-looking task list. ## Test Strategy Derivation @@ -50,11 +54,20 @@ Use this data and external-system strategy: Every generated test or validation task must include an inline evidence requirement. Evidence must name at least one relevant BDD scenario, behavior assertion, API contract, UIF path, quickstart validation path, visual proof ref, screenshot ref, or command output. +Generate explicit validation tasks for the applicable scope instead of relying on final code review to perform first-line validation: + +- Contract validation tasks bind contract ref -> implementation surface -> validation command -> evidence. If the mapping cannot be derived from `contracts/`, `research.md`, `quickstart.md`, or task context, report a readiness blocker instead of generating an implementation task that can drift from the interface contract. +- Visual verification or UI acceptance tasks bind Visual Item ID -> Visual Fidelity Readiness row -> viewport/state coverage -> proof level -> screenshot refs or visual proof refs -> quickstart validation path -> evidence. +- Data-side-effect validation tasks bind affected entity or state transition -> expected write behavior -> rollback, compensation, retry, migration, backfill, or invariant assertion when applicable -> validation command or evidence path. +- Integration or e2e validation tasks bind user-visible journey or cross-boundary flow -> scenario/assertion refs -> external-system strategy -> quickstart validation path -> captured command output. + Example task shape: ```markdown - [ ] T012 [US2] Add contract test for SCN-004 using fixture FX-002; level: contract; strategy: fixture factory + payment sandbox mock; evidence: BDD scenario SCN-004, AST-007, contracts/api/refunds.openapi.yaml - [ ] T013 [US2] Run integration validation for payment sandbox callback path; level: integration; strategy: sandbox callback replay; evidence: quickstart validation path QV-003 and captured command output +- [ ] T014 [US2] Run contract validation for contracts/api/refunds.openapi.yaml#/paths/~1refunds/post against src/routes/refunds.ts; level: contract; evidence: quickstart validation path QV-API-002 and captured command output +- [ ] T015 [US2] Run visual verification for Visual Item ID VI-REFUND-001 / VIS-001 at desktop and mobile default/error states; level: e2e; evidence: screenshot refs, visual proof ref VP-004, quickstart validation path QV-VIS-001, and captured command output ``` Behavior task derivation must be explicit: @@ -72,14 +85,24 @@ UI implementation and acceptance tasks must be paired when a user story includes - Each UI acceptance task must name the required state coverage from the accepted contracts or readiness matrix, such as default, hover, focus, active, disabled, loading, empty, and error states. - Each UI acceptance task must name the required viewport coverage from `research.md`, Visual Fidelity Readiness, or `quickstart.md` when responsive visual behavior is in scope. - Each UI acceptance task must include evidence refs: at least one relevant UIF path, BDD or behavior scenario, visual proof ref, screenshot ref, quickstart validation path, API contract, or captured command output. -- If a required visual proof ref, screenshot ref, viewport/state coverage rule, Client Asset Contract entry, asset variant, or fallback policy is missing, report a readiness blocker instead of generating a complete-looking UI implementation or acceptance task. +- If a required visual proof ref, screenshot ref, viewport/state coverage rule, Client Asset Contract entry, asset variant, or fallback policy is missing, report a readiness blocker from Visual Fidelity Readiness instead of generating a complete-looking UI implementation or acceptance task. + +For each applicable Visual Fidelity Readiness row, generate a paired visual verification or UI acceptance task unless the row is Not Applicable or blocked. Do not read Figma, re-extract provider evidence, rebuild Visual Item Matrix, or re-decide visual readiness in tasks. + +When an implementation task depends on `contracts/`, include a paired contract validation task that names the contract ref, expected implementation surface, validation command or quickstart path, and evidence requirement. Do not instruct implementers to modify `spec.md`, `contracts/`, readiness checklists, or Visual Fidelity Readiness to make implementation pass; report a blocker if implementation requires requirement or contract changes. + +When persistence, migrations, external writes, retries, rollback, or compensation are in scope, include a data-side-effect validation task before final code review. The task must name the affected entity, expected mutation behavior, invariant or rollback/compensation assertion, and evidence source. ## Final Code Review -When generating `tasks.md`, append the final phase after user-story tasks in the same checklist format. Add code review tasks that check design, sequence, and contract consistency against `class-diagram.md`, `contracts/sequences.md`, `contracts/`, `research.md`, and `quickstart.md`, plus data side-effect review and real e2e environment readiness. +When generating `tasks.md`, append the final phase after user-story tasks in the same checklist format. Add code review tasks with review scopes: boundary, interface_contract, visual, data_side_effect, behavior_contract, sequence_consistency, and asset_binding when applicable. These tasks check design, sequence, visual implementation, and contract consistency against `class-diagram.md`, `contracts/sequences.md`, `contracts/`, `contracts/uif/`, `research.md`, `quickstart.md`, `spec.md` visual acceptance requirements, `spec.md` Client Asset Contract entries, and `checklists/behavior-testability.md` Visual Fidelity Readiness, plus data side-effect review and real e2e environment readiness. Code review task text must require review of the actual implementation diff for runtime database writes and other persistent data changes, especially field-level update/delete behavior, bulk writes, soft deletes, ORM whole-object saves, migrations/backfills, retries, rollback/compensation, and external-system writes. Do not generate field-level mutation allowlists or pre-implementation data-write gates in normal tasks. +Code review task text must require boundary review: changed paths stay within the implement handoff boundary, implementation matches the referenced contracts, validation evidence covers quickstart or contract paths, and no implementation task changed `spec.md`, `contracts/`, readiness checklists, or Visual Fidelity Readiness to make execution pass. + +Code review task text must require visual consistency review when UI or visual acceptance was in scope. The review must reconcile implemented UI states and viewport behavior with Visual Fidelity Readiness, UIF paths, screenshot refs, visual proof refs, and Client Asset Contract bindings, variants, and fallback policy. Visual implementation drift must be recorded as review findings or repaired through `consistency_repairs` when the repair path is authorized. + Code review task evidence must require a `speckit.implement.receipt.v1` review receipt with `task_type: code_review`, `review_conclusion.checked_sources`, `data_side_effect_review`, `review_conclusion`, `consistency_repairs`, and `deferred_validation_todos`; empty arrays or objects indicate no entries. The task text must require quickstart/contract validation command evidence and state that implementation drift from the plan, sequences, contracts, or data side-effect review is repaired during `/speckit.implement` when the repair path is authorized; real e2e environment gaps are recorded as todos instead of treated as passing evidence. {CORE_TEMPLATE} diff --git a/presets/workflow-preset/docs/extension-governance.md b/presets/workflow-preset/docs/extension-governance.md index 35a2797685..92d5fbf3fb 100644 --- a/presets/workflow-preset/docs/extension-governance.md +++ b/presets/workflow-preset/docs/extension-governance.md @@ -30,8 +30,8 @@ Design Requirement Intake and Requirement Merge templates may define provider-neutral design facts and merge reports. Figma is a provider-specific design source; Screenshot is provider evidence and visual proof. Screenshots must not become the primary Design Requirement Intake carrier or a source of product semantics. -Figma MCP execution, hooks, adapter scripts, and authentication are external -integration concerns and remain outside this preset. +Provider evidence artifacts may record screenshot refs, visual proof refs, coverage gaps, and provider evidence blockers as source facts. They must not decide visual planning readiness, proof sufficiency, accepted exception rules, checklist Gate Status, or checklist Blocking Items. +Figma MCP execution, hooks, adapter scripts, and authentication are external integration concerns and remain outside this preset. ## Template And Command Ownership @@ -54,12 +54,12 @@ Stage ownership: - `/speckit.analyze`: vertical consistency checks across requirements, behavior drafts, contracts, and tasks only. - `/speckit.implement`: implementation handoff execution only. -When Design Requirement Intake or a Figma Evidence Packet has already been -written into `spec.md`, `/speckit.clarify` may clarify those requirement gaps -from `spec.md`, but extraction remains outside clarification. +`/speckit.tasks` owns implementation, validation, visual verification, contract validation, data-side-effect validation, integration/e2e validation, and code review task definition in `tasks.md`. `/speckit.implement` may execute those tasks and record receipt evidence, but it must not invent validation strategy, add lifecycle roles, change requirements, update contracts, or widen scope during execution. + +When Design Requirement Intake or a Figma Evidence Packet has already been written into `spec.md`, `/speckit.clarify` may clarify those requirement gaps from `spec.md`, but extraction remains outside clarification. external design extraction is not a clarification responsibility. -Visual Fidelity readiness applies to design-derived and product-side visual requirements such as pixel-perfect, brand-critical, responsive visual, or UI visual acceptance requirements. The Visual Fidelity Evidence Matrix is the single visual readiness record and uses one row per visual requirement or visual proof obligation with Source `spec.md` section, Fidelity Scope, Screenshot Level, Evidence Refs, Visual Proof Required, Blocking Item ID, and Exception Rule. Responsive visual requirements block PASS only when they are complex, multi-state, or declare L2 or L3 visual proof. +Visual Fidelity readiness applies to design-derived and product-side visual requirements such as pixel-perfect, brand-critical, responsive visual, or UI visual acceptance requirements. The Visual Fidelity Evidence Matrix is the single visual readiness record and uses one row per visual requirement or visual proof obligation with Source `spec.md` section, Fidelity Scope, Screenshot Level, Evidence Refs, Visual Proof Required, Blocking Item ID, and Exception Rule. It is the only artifact that decides visual planning readiness, visual proof level sufficiency, screenshot sufficiency, accepted exception rules, checklist Gate Status, and checklist Blocking Items. Provider source readiness remains separate: provider intake may prove raw metadata completeness, metadata index completeness proof, node inventory parity, and blocker lint errors, but that proof is not the Visual Fidelity readiness gate. Responsive visual requirements block PASS only when they are complex, multi-state, or declare L2 or L3 visual proof. ## Structured Artifact Rules diff --git a/presets/workflow-preset/preset.yml b/presets/workflow-preset/preset.yml index 75c2c72de4..669b0d7079 100644 --- a/presets/workflow-preset/preset.yml +++ b/presets/workflow-preset/preset.yml @@ -203,6 +203,12 @@ provides: description: Schema for formal behavior assertions replaces: speckit-behavior-assertions-v1-schema strategy: replace + - type: template + name: speckit-design-visual-item-matrix-v1-schema + file: schemas/speckit.design.visual-item-matrix.v1.schema.json + description: Schema for normalized design visual item matrix intake + replaces: speckit-design-visual-item-matrix-v1-schema + strategy: replace - type: template name: speckit-implement-manifest-v1-schema file: schemas/speckit.implement.manifest.v1.schema.json diff --git a/presets/workflow-preset/schemas/speckit.design.visual-item-matrix.v1.schema.json b/presets/workflow-preset/schemas/speckit.design.visual-item-matrix.v1.schema.json new file mode 100644 index 0000000000..e79c970c42 --- /dev/null +++ b/presets/workflow-preset/schemas/speckit.design.visual-item-matrix.v1.schema.json @@ -0,0 +1,184 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "speckit.design.visual-item-matrix.v1.schema.json", + "title": "Spec Kit Design Visual Item Matrix", + "type": "object", + "additionalProperties": false, + "required": ["contract_type", "source", "readiness", "visual_items"], + "properties": { + "contract_type": { + "const": "speckit.design.visual_item_matrix.v1" + }, + "source": { + "type": "object", + "additionalProperties": false, + "required": ["provider", "source_refs"], + "properties": { + "provider": {"enum": ["figma", "screenshot", "design_doc", "other"]}, + "source_refs": { + "type": "array", + "minItems": 1, + "items": {"type": "string", "minLength": 1} + }, + "capture_timestamp": {"type": "string", "minLength": 1} + } + }, + "readiness": { + "type": "object", + "additionalProperties": false, + "required": [ + "status", + "raw_metadata_complete", + "node_inventory_coverage", + "parity_passed", + "blocker_lint_errors" + ], + "properties": { + "status": {"enum": ["PASS", "BLOCKED"]}, + "raw_metadata_complete": {"type": "boolean"}, + "node_inventory_coverage": {"type": "number", "minimum": 0, "maximum": 100}, + "parity_passed": {"type": "boolean"}, + "blocker_lint_errors": { + "type": "array", + "items": {"type": "string", "minLength": 1} + } + } + }, + "visual_items": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "source_refs", + "requirement_target", + "ui_surface", + "fidelity_scope", + "variant_state_evidence", + "component_requirement_role", + "component_use_constraint", + "constraint_source_refs", + "copy_content_constraint", + "drawing_asset_constraint", + "required_states", + "required_viewport_coverage", + "screenshot_refs", + "visual_proof_level", + "allowed_deviations", + "blockers", + "spec_requirement_target" + ], + "properties": { + "id": {"type": "string", "minLength": 1}, + "source_refs": { + "type": "array", + "minItems": 1, + "items": {"type": "string", "minLength": 1} + }, + "requirement_target": {"type": "string", "minLength": 1}, + "ui_surface": {"type": "string", "minLength": 1}, + "fidelity_scope": { + "enum": [ + "functional-equivalent", + "design-system-faithful", + "pixel-perfect", + "brand-critical", + "responsive-visual" + ] + }, + "layout_facts": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "typography_facts": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "color_token_facts": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "effect_facts": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "asset_refs": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "variant_state_evidence": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": ["source_refs", "observed_state_or_role", "confidence"], + "properties": { + "variant_ref": {"type": "string", "minLength": 1}, + "source_refs": { + "type": "array", + "minItems": 1, + "items": {"type": "string", "minLength": 1} + }, + "observed_state_or_role": {"type": "string", "minLength": 1}, + "confidence": {"enum": ["high", "medium", "low"]} + } + } + }, + "component_requirement_role": {"type": "string", "minLength": 1}, + "component_use_constraint": { + "enum": [ + "visual-reference-only", + "must-reuse-existing", + "figma-export-required", + "unspecified" + ] + }, + "constraint_source_refs": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "copy_content_constraint": { + "enum": [ + "no-new-copy", + "figma-copy-required", + "product-copy-required", + "unspecified" + ] + }, + "drawing_asset_constraint": { + "enum": [ + "no-self-draw", + "figma-export-required", + "existing-asset-required", + "unspecified" + ] + }, + "required_states": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "required_viewport_coverage": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "screenshot_refs": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "visual_proof_level": {"enum": ["L0", "L1", "L2", "L3"]}, + "allowed_deviations": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "blockers": { + "type": "array", + "items": {"type": "string", "minLength": 1} + }, + "spec_requirement_target": {"type": "string", "minLength": 1} + } + } + } + } +} diff --git a/presets/workflow-preset/templates/behavior/behavior-testability-checklist.md b/presets/workflow-preset/templates/behavior/behavior-testability-checklist.md index 4215018cd0..f488cfebbf 100644 --- a/presets/workflow-preset/templates/behavior/behavior-testability-checklist.md +++ b/presets/workflow-preset/templates/behavior/behavior-testability-checklist.md @@ -61,6 +61,8 @@ For each user story or capability, record one row per story or capability case t - [ ] Design-derived requirements identify the design source, provider source refs, and required fidelity. - [ ] Design-derived requirements record provider readiness status, evidence refs, and blockers when provider evidence is required. - [ ] Visual Fidelity Evidence Matrix rows cite source `spec.md` sections, evidence refs, required screenshot level, blocking item IDs, and accepted exception rules. +- [ ] Visual Fidelity Evidence Matrix is the only artifact that decides visual planning readiness, proof level sufficiency, screenshot sufficiency, accepted exception rules, Gate Status, and Blocking Items. +- [ ] Visual Fidelity Evidence Matrix reads visual facts from `spec.md` and evidence refs; it does not call Figma, re-extract provider evidence, rebuild provider matrices, or create another visual readiness path. - [ ] Use one Visual Fidelity Evidence Matrix as the single visual readiness record; do not duplicate visual evidence decisions outside the matrix and Blocking Items. - [ ] Do not add historical visual rules or alternate visual decision paths. diff --git a/presets/workflow-preset/templates/design-requirement-intake-template.md b/presets/workflow-preset/templates/design-requirement-intake-template.md index 8052e165f2..5d9a4fe0d7 100644 --- a/presets/workflow-preset/templates/design-requirement-intake-template.md +++ b/presets/workflow-preset/templates/design-requirement-intake-template.md @@ -34,7 +34,7 @@ Purpose: normalize provider-neutral design requirements before Requirement Merge - Component: - Required variants: - Source refs: -- Existing code mapping: +- Existing code constraint, only if explicitly provided: ## Component States @@ -97,6 +97,34 @@ Purpose: normalize provider-neutral design requirements before Requirement Merge - Accepted exceptions: - Accessibility requirements: +## Visual Restoration Trace + +Use one row per accepted Visual Item ID from provider evidence. Each row records the minimum facts needed to preserve UI/UX intent without re-reading provider tools. +Do not copy the full provider Visual Item Matrix. Record only requirement-level facts promoted toward `spec.md`, supporting evidence refs, and unresolved provider or requirement gaps. Visual Restoration Trace must not decide visual planning readiness, proof sufficiency, accepted exception rules, checklist Gate Status, or checklist Blocking Items. + +- Visual Item ID: +- Provider source refs: +- Requirement ID: +- UI surface: +- Fidelity scope: functional-equivalent|design-system-faithful|pixel-perfect|brand-critical|responsive-visual +- Layout constraints: +- Typography constraints: +- Color/token constraints: +- Effect constraints: +- Asset bindings: +- Requirement-level component role: +- Variant/state coverage: +- Component use constraint: visual-reference-only|must-reuse-existing|figma-export-required|unspecified +- Constraint source refs: +- Copy/content constraint: no-new-copy|figma-copy-required|product-copy-required|unspecified +- Drawing/asset constraint: no-self-draw|figma-export-required|existing-asset-required|unspecified +- Required states: +- Required viewport coverage: +- Screenshot refs: +- Visual proof refs: +- Allowed deviations: +- Blocking item: + ## Client Asset Contract - Asset ID: @@ -114,6 +142,7 @@ Design Requirement Intake remains provider-neutral. Screenshot-derived visual facts must include screenshot refs; screenshots must not create product semantics. Keep screenshot files in provider evidence or `sources/`; record only requirement-level references here. +Screenshot Traceability records supported facts and unsupported assumptions only. It must not create an independent visual readiness decision. - Requirement ID: - Screenshot refs: @@ -125,6 +154,7 @@ record only requirement-level references here. ## Traceability - Requirement ID: +- Visual Item ID: - Source refs: - Confidence: - Provider notes: diff --git a/presets/workflow-preset/templates/figma-evidence-packet-template.md b/presets/workflow-preset/templates/figma-evidence-packet-template.md index a4f2903d64..dec1bccbf6 100644 --- a/presets/workflow-preset/templates/figma-evidence-packet-template.md +++ b/presets/workflow-preset/templates/figma-evidence-packet-template.md @@ -23,6 +23,7 @@ Purpose: normalize Figma design evidence before Design Requirement Intake and Screenshot evidence must declare L0-L3 coverage and coverage gaps. Screenshots are visual proof, not the primary Design Requirement Intake carrier. Constraint: screenshot-derived visual facts require screenshot refs and must not replace Design Requirement Intake. +Screenshot evidence and the Screenshot Coverage Matrix record coverage facts and gaps only. They must not decide visual planning readiness, proof sufficiency, accepted exception rules, checklist Gate Status, or checklist Blocking Items. - Screenshot level: L0|L1|L2|L3 - L0: no screenshot evidence @@ -49,6 +50,8 @@ Constraint: screenshot-derived visual facts require screenshot refs and must not ## Figma Intake Readiness +Figma Intake Readiness is provider source readiness only. It proves raw Figma metadata and inventory completeness before evidence can be consumed; it is separate from Visual Fidelity planning readiness, which is decided only by the checklist Visual Fidelity Evidence Matrix. + - figma-metadata.part-*.xml: - figma-metadata.index.yaml: - figma-node-inventory.yaml: @@ -116,6 +119,36 @@ Record schema for observed, inferred, missing, and out-of-scope facts. - Accessibility evidence: - Accepted exceptions: +## Visual Item Matrix + +Use one row per restorable UI surface, component, state, or visual proof obligation. +Visual Item IDs must be stable enough to carry into Design Requirement Intake, `spec.md`, and the Visual Fidelity Evidence Matrix. +The Visual Item Matrix records provider-normalized visual facts, observed state and viewport evidence, proof refs, and provider evidence blockers. It must not decide visual planning readiness, proof level sufficiency, accepted exception rules, checklist Gate Status, or checklist Blocking Items. + +- Visual Item ID: +- Figma frame/node refs: +- Requirement target: +- UI surface: +- Required fidelity: functional-equivalent|design-system-faithful|pixel-perfect|brand-critical|responsive-visual +- Layout facts: +- Typography facts: +- Color/token facts: +- Effect facts: +- Asset refs: +- Variant/state evidence: +- Component requirement role: +- Component use constraint: visual-reference-only|must-reuse-existing|figma-export-required|unspecified +- Constraint source refs: +- Copy/content constraint: no-new-copy|figma-copy-required|product-copy-required|unspecified +- Drawing/asset constraint: no-self-draw|figma-export-required|existing-asset-required|unspecified +- Required states: +- Required viewport coverage: +- Screenshot refs: +- Visual proof level: L0|L1|L2|L3 +- Allowed deviations: +- Blockers: +- Spec requirement target: + ## Client Asset Inventory - Asset ID: @@ -130,9 +163,13 @@ Record schema for observed, inferred, missing, and out-of-scope facts. ## Component Mapping -- Figma component -> code component: -- Variant coverage: -- Missing mappings: +- Figma component -> requirement-level component role: +- Variant -> observed state or semantic role: +- Existing code component constraint, only if explicitly provided: +- Visual-reference-only components: +- Must-reuse-existing components: +- No self-draw / no new copy constraints: +- Missing mappings or constraints: ## Spec Handoff Notes diff --git a/presets/workflow-preset/templates/figma-intake-contract.md b/presets/workflow-preset/templates/figma-intake-contract.md index c667425be3..9c25a53621 100644 --- a/presets/workflow-preset/templates/figma-intake-contract.md +++ b/presets/workflow-preset/templates/figma-intake-contract.md @@ -72,13 +72,28 @@ Required parity rules: ## Evidence Readiness Gate -Figma intake is ready only when all conditions pass: +Figma intake is ready only when all conditions pass. This gate is provider source readiness only; it proves raw Figma metadata and node inventory completeness. +It must not decide Visual Fidelity planning readiness, proof sufficiency, accepted exception rules, checklist Gate Status, or checklist Blocking Items. - raw_metadata_complete: true - node_inventory_coverage: 100% - parity_passed: true - No blocker lint errors +## Normalized Visual Item Matrix + +When UI/UX visual fidelity is in scope, the external intake should also write a +normalized `speckit.design.visual_item_matrix.v1` JSON artifact that conforms to +`schemas/speckit.design.visual-item-matrix.v1.schema.json`. +This JSON is derived from the raw metadata shards, metadata index, node +inventory, screenshots, and qualified provider notes. It must not replace raw provider evidence. + +The normalized matrix carries Visual Item IDs, source refs, observed variant/state evidence, requirement-level component roles, explicit component use constraints, asset/copy/drawing constraints, screenshot refs, visual proof level, blockers, and `spec.md` requirement targets. +Its blockers are provider evidence blockers, not checklist Blocking Items, and +the matrix must not create a second visual readiness gate. +Explicit constraints such as must-reuse-existing, no-self-draw, or no-new-copy +must include constraint source refs. + ## Blocker Lint Errors - FIGMA_RAW_METADATA_MISSING diff --git a/presets/workflow-preset/tests/test_preset_contract.py b/presets/workflow-preset/tests/test_preset_contract.py index 2ddc435bfc..dc25f2e886 100644 --- a/presets/workflow-preset/tests/test_preset_contract.py +++ b/presets/workflow-preset/tests/test_preset_contract.py @@ -13,6 +13,7 @@ validate_behavior_case_coverage, validate_behavior_contract_bundle, validate_behavior_draft_contract, + validate_visual_item_matrix_contract, validate_implement_contract, validate_handoff_contract, validate_manifest_contract, @@ -93,6 +94,9 @@ / "schemas" / "speckit.behavior.assertions.v1.schema.json", } +VISUAL_ITEM_MATRIX_SCHEMA_PATH = ( + REPO_ROOT / "schemas" / "speckit.design.visual-item-matrix.v1.schema.json" +) BEHAVIOR_TEMPLATE_PATHS = { "behavior-bdd-draft-template": REPO_ROOT / "templates" / "behavior" / "bdd-draft.feature", "behavior-scenarios-draft-template": REPO_ROOT @@ -484,6 +488,58 @@ def minimal_behavior_assertions() -> dict: } +def minimal_visual_item_matrix() -> dict: + return { + "contract_type": "speckit.design.visual_item_matrix.v1", + "source": { + "provider": "figma", + "source_refs": ["figma://file/page/frame/node"], + "capture_timestamp": "2026-06-22T00:00:00Z", + }, + "readiness": { + "status": "PASS", + "raw_metadata_complete": True, + "node_inventory_coverage": 100, + "parity_passed": True, + "blocker_lint_errors": [], + }, + "visual_items": [ + { + "id": "VI-001", + "source_refs": ["figma://file/page/frame/node"], + "requirement_target": "Home screen header", + "ui_surface": "HomePage", + "fidelity_scope": "design-system-faithful", + "layout_facts": ["Header is aligned to the top safe area."], + "typography_facts": ["Title uses the observed display style."], + "color_token_facts": ["Primary action uses the observed brand token."], + "effect_facts": [], + "asset_refs": [], + "variant_state_evidence": [ + { + "variant_ref": "component=Button,state=disabled", + "source_refs": ["figma://component/button-disabled"], + "observed_state_or_role": "disabled", + "confidence": "high", + } + ], + "component_requirement_role": "primary action", + "component_use_constraint": "unspecified", + "constraint_source_refs": [], + "copy_content_constraint": "unspecified", + "drawing_asset_constraint": "unspecified", + "required_states": ["default", "disabled"], + "required_viewport_coverage": ["desktop"], + "screenshot_refs": ["screenshots/home-desktop.png"], + "visual_proof_level": "L1", + "allowed_deviations": [], + "blockers": [], + "spec_requirement_target": "spec.md#visual-requirements", + } + ], + } + + def minimal_exception_behavior_assertions() -> dict: return minimal_exception_behavior_assertions_with_intent("state_invariant") @@ -519,7 +575,7 @@ def test_preset_manifest_contract(self) -> None: ) provides = data["provides"]["templates"] - self.assertEqual(34, len(provides)) + self.assertEqual(35, len(provides)) entries = {entry["name"]: entry for entry in provides} self.assertNotIn("behavior-open-questions-template", entries) self.assertNotIn("speckit-behavior-open-questions-v1-schema", entries) @@ -671,6 +727,16 @@ def test_preset_manifest_contract(self) -> None: self.assertEqual(schema_name, schema["replaces"]) self.assertEqual("replace", schema["strategy"]) + visual_matrix_schema = entries["speckit-design-visual-item-matrix-v1-schema"] + self.assertEqual("template", visual_matrix_schema["type"]) + self.assertEqual( + "schemas/speckit.design.visual-item-matrix.v1.schema.json", + visual_matrix_schema["file"], + ) + self.assertIn("normalized design visual item matrix", visual_matrix_schema["description"]) + self.assertEqual("speckit-design-visual-item-matrix-v1-schema", visual_matrix_schema["replaces"]) + self.assertEqual("replace", visual_matrix_schema["strategy"]) + self.assertNotIn("scripts", data["provides"]) self.assertNotIn("files", data["provides"]) self.assertNotIn("workflows", data["provides"]) @@ -722,6 +788,7 @@ def test_plan_visual_substage_enhancement_contract(self) -> None: "viewport/state coverage strategy", "visual regression or baseline proof strategy", "Do not copy the Visual Fidelity Evidence Matrix into `research.md`", + "do not rebuild provider evidence matrices", "visual_item_refs", "viewport_matrix_refs", "state_matrix_refs", @@ -811,17 +878,38 @@ def test_tasks_command_wrapper_contract(self) -> None: self.assertIn("strategy: wrap", tasks) self.assertIn("implementation, integration, orchestration", tasks) self.assertIn("existing checklist format and user-story organization", tasks) + self.assertIn("Tasks owns validation and review task definition", tasks) + self.assertIn("executes only tasks already present in `tasks.md`", tasks) + self.assertIn("must not invent validation strategy", tasks) + self.assertIn("change requirements, update contracts, or widen scope", tasks) self.assertIn("Test Strategy Derivation", tasks) self.assertIn("derive the test level", tasks) self.assertIn("fixture/mock/sandbox/real-system strategy", tasks) self.assertIn("inline evidence requirement", tasks) + self.assertIn("Generate explicit validation tasks for the applicable scope", tasks) + self.assertIn("Contract validation tasks bind contract ref -> implementation surface -> validation command -> evidence", tasks) + self.assertIn("Visual verification or UI acceptance tasks bind Visual Item ID", tasks) + self.assertIn("Data-side-effect validation tasks bind affected entity or state transition", tasks) + self.assertIn("Integration or e2e validation tasks bind user-visible journey or cross-boundary flow", tasks) self.assertIn("Final Code Review", tasks) self.assertIn("append the final phase after user-story tasks", tasks) - self.assertIn("design, sequence, and contract consistency", tasks) + self.assertIn("review scopes: boundary, interface_contract, visual, data_side_effect, behavior_contract, sequence_consistency, and asset_binding", tasks) + self.assertIn("design, sequence, visual implementation, and contract consistency", tasks) + self.assertIn("`contracts/uif/`", tasks) + self.assertIn("`spec.md` Client Asset Contract entries", tasks) + self.assertIn("Visual Fidelity Readiness", tasks) self.assertIn("data side-effect review", tasks) self.assertIn("actual implementation diff", tasks) self.assertIn("field-level update/delete", tasks) self.assertIn("runtime database writes", tasks) + self.assertIn("boundary review", tasks) + self.assertIn("changed paths stay within the implement handoff boundary", tasks) + self.assertIn("no implementation task changed `spec.md`, `contracts/`, readiness checklists, or Visual Fidelity Readiness", tasks) + self.assertIn("visual consistency review", tasks) + self.assertIn("implemented UI states and viewport behavior", tasks) + self.assertIn("screenshot refs, visual proof refs", tasks) + self.assertIn("Client Asset Contract bindings, variants, and fallback policy", tasks) + self.assertIn("Visual implementation drift", tasks) self.assertIn("real e2e environment readiness", tasks) self.assertIn("task_type: code_review", tasks) self.assertIn("data_side_effect_review", tasks) @@ -831,6 +919,9 @@ def test_tasks_command_wrapper_contract(self) -> None: self.assertIn("deferred_validation_todos", tasks) self.assertIn("quickstart/contract validation command", tasks) self.assertIn("empty arrays or objects indicate no entries", tasks) + self.assertNotIn("task_type: visual_verification", tasks) + self.assertNotIn("task_type: interface_validation", tasks) + self.assertNotIn("task_type: data_side_effect_validation", tasks) self.assertNotIn("must require a `speckit.implement.receipt.v1` review receipt with `review_conclusion`, `consistency_repairs`, and `deferred_validation_todos`", tasks) def test_behavior_first_command_wrapper_contracts(self) -> None: @@ -874,12 +965,15 @@ def test_behavior_first_command_wrapper_contracts(self) -> None: "Design intake input", "Design intake output", "recorded only in `spec.md`", + "stable Visual Item ID trace refs", + "observed variant/state facts", "provider-neutral design evidence", "source refs", "Stage 2: Requirement Merge", "Merge input", "Merge output", "Design Requirement Promotion Rules", + "preserve Visual Item ID trace refs for visual requirements", "conflicts", "provider blockers", "Stage 3: Generate baseline spec.md", @@ -912,6 +1006,8 @@ def test_behavior_first_command_wrapper_contracts(self) -> None: "fallback policy", "blocker status", "Screenshot-implied business rules", + "Do not invent code props, code state names, component reuse decisions, self-drawing bans, or copy restrictions from Figma structure", + "Record component use, no-self-draw, and no-new-copy constraints only when product input or qualified provider evidence states them explicitly", "Continue to write only `spec.md`", "stage-wise report", ): @@ -1186,17 +1282,38 @@ def test_behavior_first_plan_and_tasks_awareness_contract(self) -> None: "derive the test level", "fixture/mock/sandbox/real-system strategy", "inline evidence requirement", + "Tasks owns validation and review task definition", + "executes only tasks already present in `tasks.md`", + "Generate explicit validation tasks for the applicable scope", + "Contract validation tasks bind contract ref -> implementation surface -> validation command -> evidence", + "Visual verification or UI acceptance tasks bind Visual Item ID", + "Data-side-effect validation tasks bind affected entity or state transition", + "Integration or e2e validation tasks bind user-visible journey or cross-boundary flow", "Client Asset Contract", "derive asset preparation, binding, implementation, and validation tasks", "Missing required client visual assets become readiness blockers", + "Use Visual Fidelity Readiness as the only visual planning readiness source", + "Do not create a second readiness rule", + "Screenshot Coverage Matrix", + "Visual Restoration Trace", "do not generate handoff fields or `allowed_write_paths`", "Missing Required case scenarios must become blockers, not silently skipped tasks", "negative, boundary, permission, validation, state_conflict, or error behavior", "For each non-positive BehaviorScenarioInstance", "derive fixture, contract or BDD test, implementation, and verification evidence tasks", + "visual consistency review", + "implemented UI states and viewport behavior", + "Client Asset Contract bindings, variants, and fallback policy", + "Visual implementation drift", + "review scopes: boundary, interface_contract, visual, data_side_effect, behavior_contract, sequence_consistency, and asset_binding", + "boundary review", + "no implementation task changed `spec.md`, `contracts/`, readiness checklists, or Visual Fidelity Readiness", ): self.assertIn(term, tasks) + self.assertNotIn("task_type: visual_verification", tasks) + self.assertNotIn("task_type: interface_validation", tasks) + self.assertNotIn("task_type: data_side_effect_validation", tasks) self.assertNotIn("test-plan.md", tasks) self.assertIn("./behavior/bdd.draft.feature", template) @@ -1432,6 +1549,11 @@ def test_figma_evidence_packet_template_contract(self) -> None: "visual proof", "Screenshot evidence must declare L0-L3 coverage and coverage gaps", "not the primary Design Requirement Intake carrier", + "Screenshot evidence and the Screenshot Coverage Matrix record coverage facts and gaps only", + "must not decide visual planning readiness", + "proof sufficiency", + "checklist Gate Status", + "checklist Blocking Items", "Screenshot level: L0|L1|L2|L3", "L0: no screenshot evidence", "L1: static screenshot reference", @@ -1456,7 +1578,35 @@ def test_figma_evidence_packet_template_contract(self) -> None: "Missing / Needs Clarification", "Out of Scope", "Figma Intake Readiness", + "Figma Intake Readiness is provider source readiness only", + "separate from Visual Fidelity planning readiness", "Visual Facts for Spec", + "Visual Item Matrix", + "one row per restorable UI surface, component, state, or visual proof obligation", + "provider-normalized visual facts", + "provider evidence blockers", + "proof level sufficiency", + "Visual Item ID", + "Figma frame/node refs", + "Requirement target", + "UI surface", + "Required fidelity: functional-equivalent|design-system-faithful|pixel-perfect|brand-critical|responsive-visual", + "Layout facts", + "Typography facts", + "Color/token facts", + "Effect facts", + "Asset refs", + "Variant/state evidence", + "Component requirement role", + "Component use constraint: visual-reference-only|must-reuse-existing|figma-export-required|unspecified", + "Constraint source refs", + "Copy/content constraint: no-new-copy|figma-copy-required|product-copy-required|unspecified", + "Drawing/asset constraint: no-self-draw|figma-export-required|existing-asset-required|unspecified", + "Required states", + "Required viewport coverage", + "Visual proof level: L0|L1|L2|L3", + "Allowed deviations", + "Spec requirement target", "Client Asset Inventory", "Asset ID", "Asset role", @@ -1468,6 +1618,12 @@ def test_figma_evidence_packet_template_contract(self) -> None: "Fallback policy", "Blocker status", "Component Mapping", + "Figma component -> requirement-level component role", + "Variant -> observed state or semantic role", + "Existing code component constraint, only if explicitly provided", + "Visual-reference-only components", + "Must-reuse-existing components", + "No self-draw / no new copy constraints", "Spec Handoff Notes", "Open Questions", "Frame / Node IDs", @@ -1500,6 +1656,7 @@ def test_design_requirement_intake_template_contract(self) -> None: "Page Hierarchy", "User Paths", "Component Inventory", + "Existing code constraint, only if explicitly provided", "Component States", "Interaction Rules", "Visual Tokens", @@ -1508,6 +1665,27 @@ def test_design_requirement_intake_template_contract(self) -> None: "Motion Rules", "State Coverage", "Visual Acceptance Requirements", + "Visual Restoration Trace", + "accepted Visual Item ID", + "Do not copy the full provider Visual Item Matrix", + "Record only requirement-level facts promoted toward `spec.md`", + "must not decide visual planning readiness", + "checklist Gate Status", + "checklist Blocking Items", + "Provider source refs", + "Fidelity scope: functional-equivalent|design-system-faithful|pixel-perfect|brand-critical|responsive-visual", + "Layout constraints", + "Typography constraints", + "Color/token constraints", + "Effect constraints", + "Asset bindings", + "Requirement-level component role", + "Variant/state coverage", + "Component use constraint: visual-reference-only|must-reuse-existing|figma-export-required|unspecified", + "Constraint source refs", + "Copy/content constraint: no-new-copy|figma-copy-required|product-copy-required|unspecified", + "Drawing/asset constraint: no-self-draw|figma-export-required|existing-asset-required|unspecified", + "Required viewport coverage", "Client Asset Contract", "Asset ID", "Required resource type", @@ -1522,7 +1700,10 @@ def test_design_requirement_intake_template_contract(self) -> None: "Unsupported assumptions", "Screenshot-derived visual facts must include screenshot refs", "screenshots must not create product semantics", + "Screenshot Traceability records supported facts and unsupported assumptions only", + "must not create an independent visual readiness decision", "Traceability", + "Visual Item ID", "Source refs", "[NEEDS CLARIFICATION]", ] @@ -1586,6 +1767,14 @@ def test_visual_fidelity_screenshot_evidence_gate_contract(self) -> None: for term in ( "Use the behavior-testability checklist template as the visual gate authority", "provider readiness status, evidence refs, and blockers", + "Visual Fidelity Evidence Matrix alone decides visual planning readiness", + "proof level sufficiency", + "screenshot sufficiency", + "accepted exception rules", + "Read visual facts from `spec.md` and evidence refs", + "do not call Figma", + "rebuild provider matrices", + "another visual readiness path", CANONICAL_RESPONSIVE_VISUAL_RULE, "Use one Visual Fidelity Evidence Matrix as the single visual readiness record", "Do not add historical visual rules or alternate visual decision paths", @@ -1607,6 +1796,14 @@ def test_visual_fidelity_screenshot_evidence_gate_contract(self) -> None: "visual proof refs", "L0|L1|L2|L3", "declared visual proof required", + "only artifact that decides visual planning readiness", + "proof level sufficiency", + "screenshot sufficiency", + "accepted exception rules", + "does not call Figma", + "re-extract provider evidence", + "rebuild provider matrices", + "another visual readiness path", "Missing screenshot evidence sets Gate Status: BLOCKED", "High-fidelity requirements without L3 screenshot evidence set Gate Status: BLOCKED", "Pixel-perfect requirements without L3 screenshot evidence set Gate Status: BLOCKED", @@ -1673,6 +1870,7 @@ def test_figma_intake_contract_metadata_lint_rules(self) -> None: "## Metadata Index Completeness", "## Node Inventory Parity", "## Evidence Readiness Gate", + "## Normalized Visual Item Matrix", "## Blocker Lint Errors", "## Gap Rules", "## Preset Boundary", @@ -1698,6 +1896,11 @@ def test_figma_intake_contract_metadata_lint_rules(self) -> None: "truncated_raw_evidence == false", "node_inventory_coverage: 100%", "parity_passed: true", + "provider source readiness only", + "Visual Fidelity planning readiness", + "proof sufficiency", + "checklist Gate Status", + "checklist Blocking Items", "FIGMA_RAW_METADATA_MISSING", "FIGMA_RAW_METADATA_SUMMARY_SUBSTITUTION", "FIGMA_RAW_METADATA_TRUNCATED", @@ -1705,6 +1908,15 @@ def test_figma_intake_contract_metadata_lint_rules(self) -> None: "FIGMA_METADATA_INDEX_MISSING", "FIGMA_METADATA_PARITY_FAILED", "FIGMA_READY_WITHOUT_COMPLETENESS_PROOF", + "speckit.design.visual_item_matrix.v1", + "schemas/speckit.design.visual-item-matrix.v1.schema.json", + "must not replace raw provider evidence", + "provider evidence blockers, not checklist Blocking Items", + "must not create a second visual readiness gate", + "observed variant/state evidence", + "requirement-level component roles", + "Explicit constraints such as must-reuse-existing, no-self-draw, or no-new-copy", + "constraint source refs", "Required Figma intake artifacts and readiness gates", "must not call Figma MCP", "must not generate artifact instances", @@ -1832,6 +2044,8 @@ def test_implement_command_declares_deterministic_handoff_rules(self) -> None: self.assertIn("consistency_repairs", command) self.assertIn("deferred_validation_todos", command) self.assertIn("quickstart/contract validation command", command) + self.assertIn("execute validation and code review only when those tasks are already present in `tasks.md`", command) + self.assertIn("do not invent validation strategy, add lifecycle roles, change requirements, update contracts, or widen scope", command) self.assertIn("repair design, sequence, or contract drift", command) self.assertIn("real e2e cannot run", command) self.assertNotIn("test-plan.md", command) @@ -1900,6 +2114,56 @@ def test_behavior_first_schema_contracts_accept_minimal_examples(self) -> None: self.assertEqual(contract_type, schema["properties"]["contract_type"]["const"]) Draft202012Validator(schema).validate(examples[contract_type]) + def test_visual_item_matrix_schema_accepts_minimal_example(self) -> None: + schema = json.loads(VISUAL_ITEM_MATRIX_SCHEMA_PATH.read_text(encoding="utf-8")) + + self.assertEqual("object", schema["type"]) + self.assertIn("required", schema) + self.assertIn("properties", schema) + self.assertEqual( + "speckit.design.visual_item_matrix.v1", + schema["properties"]["contract_type"]["const"], + ) + self.assertIn("visual_items", schema["required"]) + Draft202012Validator(schema).validate(minimal_visual_item_matrix()) + + def test_visual_item_matrix_schema_rejects_missing_source_refs(self) -> None: + schema = json.loads(VISUAL_ITEM_MATRIX_SCHEMA_PATH.read_text(encoding="utf-8")) + matrix = minimal_visual_item_matrix() + matrix["visual_items"][0]["source_refs"] = [] + + with self.assertRaises(ValidationError): + Draft202012Validator(schema).validate(matrix) + + def test_visual_item_matrix_schema_accepts_responsive_visual_scope(self) -> None: + schema = json.loads(VISUAL_ITEM_MATRIX_SCHEMA_PATH.read_text(encoding="utf-8")) + matrix = minimal_visual_item_matrix() + matrix["visual_items"][0]["fidelity_scope"] = "responsive-visual" + + Draft202012Validator(schema).validate(matrix) + + def test_visual_item_matrix_validator_enforces_readiness_gate(self) -> None: + matrix = minimal_visual_item_matrix() + validate_visual_item_matrix_contract(matrix) + + matrix["readiness"]["node_inventory_coverage"] = 99 + with self.assertRaisesRegex(ValueError, "node_inventory_coverage 100"): + validate_visual_item_matrix_contract(matrix) + + def test_visual_item_matrix_validator_requires_sources_for_explicit_constraints(self) -> None: + matrix = minimal_visual_item_matrix() + matrix["visual_items"][0]["component_use_constraint"] = "must-reuse-existing" + + with self.assertRaisesRegex(ValueError, "constraint_source_refs"): + validate_visual_item_matrix_contract(matrix) + + def test_visual_item_matrix_validator_requires_l3_for_high_fidelity(self) -> None: + matrix = minimal_visual_item_matrix() + matrix["visual_items"][0]["fidelity_scope"] = "pixel-perfect" + + with self.assertRaisesRegex(ValueError, "requires L3 proof"): + validate_visual_item_matrix_contract(matrix) + def test_behavior_draft_schema_rejects_empty_given_when_then(self) -> None: schema = json.loads( BEHAVIOR_SCHEMA_PATHS["speckit.behavior.scenarios.draft.v1"].read_text( @@ -3457,6 +3721,11 @@ def test_readme_contract(self) -> None: self.assertIn("Design Requirement Intake", readme) self.assertIn("Requirement Merge", readme) self.assertIn("Product Requirement + Design Requirement", readme) + self.assertIn("stable Visual Item ID", readme) + self.assertIn("does not translate Figma variants into code props", readme) + self.assertIn("requirement-level component roles", readme) + self.assertIn("Visual Restoration Trace rows", readme) + self.assertIn("Visual Item Matrix rows", readme) self.assertIn("Figma is a Design Requirement provider", readme) self.assertIn("Figma Evidence Packet", readme) self.assertIn("direct Figma URL input", readme) @@ -3481,6 +3750,10 @@ def test_readme_contract(self) -> None: self.assertIn("Visual Fidelity Evidence Matrix", readme) self.assertIn("visual requirement or visual proof obligation", readme) self.assertIn("single visual readiness record", readme) + self.assertIn("Provider evidence artifacts may record screenshot refs", readme) + self.assertIn("only the Visual Fidelity Evidence Matrix decides visual planning readiness", readme) + self.assertIn("proof sufficiency", readme) + self.assertIn("accepted exception rules", readme) self.assertIn("preset defines the required design intake and provider readiness artifact structure", readme) self.assertIn("runtime agent or external Figma intake", readme) self.assertIn("does not generate the artifact instances", readme) @@ -3492,6 +3765,11 @@ def test_readme_contract(self) -> None: ) self.assertIn("raw metadata completeness", readme) self.assertIn("node inventory parity", readme) + self.assertIn("speckit.design.visual_item_matrix.v1", readme) + self.assertIn("schemas/speckit.design.visual-item-matrix.v1.schema.json", readme) + self.assertIn("raw Figma evidence remains the source of truth", readme) + self.assertIn("provider-ready", readme) + self.assertIn("It does not decide visual planning readiness", readme) self.assertIn("does not provide Figma MCP connection, authentication, or execution", readme) self.assertIn("clarifies design-derived gaps already written in `spec.md`", readme) self.assertIn("does not call Figma", readme) @@ -3518,6 +3796,8 @@ def test_readme_contract(self) -> None: "error code, failure feedback, and state invariant, rollback, or compensation assertion", readme, ) + self.assertIn("visual verification, contract validation, data-side-effect validation, integration/e2e validation, and scope-aware code review tasks", readme) + self.assertIn("without inventing validation strategy, changing requirements, updating contracts, or widening scope", readme) self.assertIn("validation_evidence", readme) self.assertIn("Context-load controls", readme) self.assertIn("context-load controls", changelog) @@ -3533,6 +3813,7 @@ def test_readme_contract(self) -> None: self.assertIn("Hardened behavior contract quality gates", changelog) self.assertIn("formalization blockers", changelog) self.assertIn("behavior-linked validation evidence", changelog) + self.assertIn("only the checklist Visual Fidelity Evidence Matrix decides visual planning readiness", changelog) self.assertNotIn("run-orchestrated-implement.py", readme) self.assertNotIn("speckit-implement-handoff.py", readme) self.assertNotIn("--dry-run true --run-id manual", readme) @@ -3553,6 +3834,8 @@ def test_readme_contract(self) -> None: self.assertIn("## 1.0.3", changelog) self.assertIn("Final Code Review", changelog) self.assertIn("structured code review receipts", changelog) + self.assertIn("/speckit.tasks` defines validation, visual verification, contract validation, data-side-effect validation, integration/e2e validation", changelog) + self.assertIn("/speckit.implement` only executes those tasks and records receipt evidence", changelog) self.assertIn("agent-native handoff orchestration", changelog) self.assertIn("Removed Python dispatch tooling", changelog) @@ -3658,6 +3941,10 @@ def test_extension_governance_document_contract(self) -> None: "Figma Evidence Packet", "Screenshot is provider evidence", "Screenshots must not become the primary Design Requirement Intake carrier", + "Provider evidence artifacts may record screenshot refs, visual proof refs", + "They must not", + "decide visual planning readiness", + "proof sufficiency", "Visual Fidelity Evidence Matrix", "one row per visual requirement or visual proof obligation", "Source `spec.md` section", @@ -3669,11 +3956,21 @@ def test_extension_governance_document_contract(self) -> None: "Exception Rule", CANONICAL_RESPONSIVE_VISUAL_RULE, "single visual readiness record", + "only artifact that decides visual planning readiness", + "visual proof level sufficiency", + "screenshot sufficiency", + "accepted exception rules", + "checklist Gate Status", + "checklist Blocking Items", + "Provider source readiness remains separate", "packaged evidence templates are allowed preset artifacts", "Figma MCP execution, hooks, adapter scripts, and authentication", "external design extraction is not a clarification responsibility", "NFR readiness belongs in `spec.md` product requirements", "`/speckit.plan`: Phase 0 behavior projection, planning artifacts, and formal contracts", + "`/speckit.tasks` owns implementation, validation, visual verification, contract validation, data-side-effect validation, integration/e2e validation, and code review task definition in `tasks.md`", + "`/speckit.implement` may execute those tasks and record receipt evidence", + "must not invent validation strategy, add lifecycle roles, change requirements, update contracts, or widen scope during execution", "Handoff extensions must update schema, validator, command, and cross-agent documentation together", "Do not bump preset version or release archive URLs until release preparation", "Use extensions, not presets, for new tooling", diff --git a/presets/workflow-preset/validators/speckit_implement_contract.py b/presets/workflow-preset/validators/speckit_implement_contract.py index 741c9af87a..60ce3bf40c 100644 --- a/presets/workflow-preset/validators/speckit_implement_contract.py +++ b/presets/workflow-preset/validators/speckit_implement_contract.py @@ -6,6 +6,21 @@ VALID_EXECUTION_MODES = {"isolated_subagent", "manual_fresh_worker_session"} CASE_TYPES = {"positive", "negative", "boundary", "permission", "validation", "state_conflict"} FAILURE_CASE_TYPES = {"negative", "permission", "validation", "state_conflict"} +EXPLICIT_COMPONENT_USE_CONSTRAINTS = { + "visual-reference-only", + "must-reuse-existing", + "figma-export-required", +} +EXPLICIT_COPY_CONSTRAINTS = { + "no-new-copy", + "figma-copy-required", + "product-copy-required", +} +EXPLICIT_DRAWING_CONSTRAINTS = { + "no-self-draw", + "figma-export-required", + "existing-asset-required", +} def _duplicate_ids(items: list[dict[str, Any]], *, key: str, context: str) -> set[str]: @@ -259,6 +274,46 @@ def validate_behavior_case_coverage( raise ValueError(f"Required case {context} missing quickstart.md evidence") +def validate_visual_item_matrix_contract(matrix: dict[str, Any]) -> None: + readiness = matrix.get("readiness", {}) + if readiness.get("status") == "PASS": + if readiness.get("raw_metadata_complete") is not True: + raise ValueError("visual item matrix PASS requires raw_metadata_complete") + if readiness.get("node_inventory_coverage") != 100: + raise ValueError("visual item matrix PASS requires node_inventory_coverage 100") + if readiness.get("parity_passed") is not True: + raise ValueError("visual item matrix PASS requires parity_passed") + if readiness.get("blocker_lint_errors"): + raise ValueError("visual item matrix PASS requires no blocker_lint_errors") + + visual_items = matrix.get("visual_items", []) + if not visual_items: + raise ValueError("visual item matrix must include visual_items") + _duplicate_ids(visual_items, key="id", context="visual item matrix") + + for item in visual_items: + item_id = item.get("id", "") + explicit_component = item.get("component_use_constraint") in EXPLICIT_COMPONENT_USE_CONSTRAINTS + explicit_copy = item.get("copy_content_constraint") in EXPLICIT_COPY_CONSTRAINTS + explicit_drawing = item.get("drawing_asset_constraint") in EXPLICIT_DRAWING_CONSTRAINTS + if (explicit_component or explicit_copy or explicit_drawing) and not item.get( + "constraint_source_refs" + ): + raise ValueError( + f"visual item {item_id} explicit constraints require constraint_source_refs" + ) + + if item.get("fidelity_scope") in {"pixel-perfect", "brand-critical"}: + if item.get("visual_proof_level") != "L3": + raise ValueError( + f"visual item {item_id} pixel-perfect or brand-critical requires L3 proof" + ) + if not item.get("screenshot_refs"): + raise ValueError( + f"visual item {item_id} pixel-perfect or brand-critical requires screenshot_refs" + ) + + def _handoff_has_behavior_contract_context(handoff: dict[str, Any]) -> bool: markers = ( "contracts/bdd/", diff --git a/tests/test_presets.py b/tests/test_presets.py index 35d34f6b10..faa28135b4 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -4459,6 +4459,10 @@ def test_workflow_preset_integration_release_payload_contract(self): assert "specify preset resolve tasks-template" in workflow_text assert 'grep -F "(top layer from: core)" preset-resolve-tasks-template.txt' in workflow_text assert "test -f .specify/templates/tasks-template.md" in workflow_text + assert ( + "test -f .specify/presets/workflow-preset/schemas/" + "speckit.design.visual-item-matrix.v1.schema.json" + ) in workflow_text def test_community_smoke_checks_wheel_assets_and_extension_dev_reinstall(self): """Community smoke validates wheel assets and extension dev reinstall skills.""" @@ -4497,6 +4501,10 @@ def test_community_smoke_checks_wheel_assets_and_extension_dev_reinstall(self): assert 'manifest_version == "1.3.' not in verify_run assert 'registry_version == "1.3.' not in verify_run assert "registry_version == manifest_version" in verify_run + assert ( + "test -f .specify/presets/workflow-preset/schemas/" + "speckit.design.visual-item-matrix.v1.schema.json" + ) in verify_run assert ( 'for extension_id in arch preview repository-governance; do' in verify_run