Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/extension-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jobs:
run: |
python3 - <<'PY'
import os
import json
import re
import zipfile
from pathlib import Path
Expand Down Expand Up @@ -114,12 +115,45 @@ jobs:
if forbidden:
raise SystemExit(f"artifact contains forbidden entries: {forbidden[:10]}")

repository = os.environ["GITHUB_REPOSITORY"]
source_commit = os.environ["GITHUB_SHA"]
if tag_version:
download_url = f"https://github.com/{repository}/archive/refs/tags/v{version}.zip"
else:
download_url = f"https://github.com/{repository}/archive/{source_commit}.zip"
provenance = {
"repository_url": f"https://github.com/{repository}",
"release_version": version,
"source_commit_sha": source_commit,
"download_url": download_url,
"validation_evidence": {
"workflow": os.environ["GITHUB_WORKFLOW"],
"run_id": os.environ["GITHUB_RUN_ID"],
"artifact_name": zip_name,
"manifest_version": manifest_version,
"required_entries_verified": sorted(required),
"forbidden_prefixes_checked": list(forbidden_prefixes),
},
}
provenance_name = "release-provenance.json"
Path(provenance_name).write_text(
json.dumps(provenance, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
)

with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output:
output.write(f"zip_name={zip_name}\n")
output.write(f"provenance_name={provenance_name}\n")
PY

- name: Upload verified artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.artifact.outputs.zip_name }}
path: ${{ steps.artifact.outputs.zip_name }}

- name: Upload release provenance
uses: actions/upload-artifact@v4
with:
name: release-provenance
path: ${{ steps.artifact.outputs.provenance_name }}
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

### Added

- Added `/speckit.intake.ir` for structured UI acceptance IR with CI-friendly DOM, ARIA, token, state, locator, relation, and assertion evidence.
- Added structured IR schemas and `validate_structured_ir_intake.py` for source readiness, cross-reference, provider-evidence, product-ambiguity, locator, downstream-ownership, and CI assertion checks.

## [0.1.3] - 2026-06-29

### Added
Expand Down
46 changes: 42 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Spec Kit Intake Extension

Extract, normalize, and validate SDD-ready intake artifacts from PRDs, visual designs, Figma-derived HTML visual SSOT bundles, test cases, and other software sources before downstream Spec Kit workflows project them into requirements.
Extract, normalize, and validate SDD-ready intake artifacts from PRDs, visual designs, Figma-derived HTML visual SSOT bundles, structured UI acceptance IR, test cases, and other software sources before downstream Spec Kit workflows project them into requirements.

The first goal of intake is not to generate requirements. It is to preserve as much input information as possible and turn it into structured material that SDD `specify` can consume accurately.

Expand All @@ -16,6 +16,7 @@ Intake artifacts are validated in two layers: JSON Schema checks enforce the req
- PDF design packs and annotated review documents
- Figma files, pages, frames, nodes, components, variables, and exported screenshots
- Figma-derived HTML visual SSOT bundles with traceable component-state and page coverage
- Structured UI acceptance IR with CI-friendly DOM, ARIA, token, state, locator, relation, and assertion facts
- Existing test cases, Gherkin files, QA exports, and test management spreadsheets

## Intake Scenario Coverage
Expand All @@ -26,7 +27,8 @@ Intake commands are organized by vertical source domain. Each domain uses the sa
| --- | --- | --- | --- |
| PRD | product briefs, Markdown PRDs, exported docs, PDFs, issue or epic links, mixed stakeholder notes | `prd-intake.yaml` | source identity, product intent traceability, scope boundaries, acceptance evidence, clarification gaps |
| Visual design | static images, wireframes, PDF design packs, Markdown design briefs, Figma files or selected nodes | `visual-requirements.yaml` | source integrity, fidelity rules, visual requirement traceability, parity planning, Figma metadata completeness when relevant |
| Figma to HTML SSOT | Figma files or selected nodes projected into runnable HTML visual acceptance surfaces | `visual-spec.html` | Figma node coverage, component-instance-state coverage, page coverage, asset traceability, viewport screenshots, known gaps |
| Figma to HTML SSOT | Figma files or selected nodes projected into runnable HTML visual acceptance surfaces | `visual-spec.html` | Figma node coverage, component-state coverage, page coverage, asset traceability, viewport screenshots, known gaps |
| Structured UI acceptance IR | visual design evidence and optional HTML SSOT enhancement refs projected into deterministic UI acceptance facts | `structured-ir.yaml` and `ir-assertions.yaml` | source traceability, provider/product gap separation, provider-neutral locators, DOM/ARIA/token/state/relation assertions, CI-low-cost readiness |
| Test cases | automated tests, Gherkin files, manual QA cases, spreadsheets, test management exports, bug or issue repro steps | `test-case-intake.yaml` | scenario traceability, assertion extraction, fixture evidence, coverage gaps, flaky or skipped case reporting |

Vertical instructions should never convert source evidence directly into downstream-owned requirement IDs, implementation tasks, or code component names. They produce provider-neutral intake facts that downstream workflows can consume with source refs intact.
Expand All @@ -35,6 +37,7 @@ Vertical instructions should never convert source evidence directly into downstr

- `/speckit.intake.visual-design` captures or validates visual design evidence, source manifests, Figma metadata when available, inventories, and readiness for the active feature.
- `/speckit.intake.figma2htmlssot` creates or validates a Figma-derived HTML visual SSOT bundle with node, component-state, page, asset, viewport, and screenshot coverage.
- `/speckit.intake.ir` creates or validates structured UI acceptance IR for CI-friendly DOM, ARIA, token, state, locator, relation, and assertion checks.
- `/speckit.intake.prd` captures or validates PRD evidence and normalizes product intent, scope, business rules, acceptance criteria, and clarification items.
- `/speckit.intake.test-cases` captures or validates test case evidence and normalizes scenarios, assertions, fixtures, and coverage gaps.

Expand Down Expand Up @@ -62,6 +65,10 @@ specs/<feature>/intake/
│ ├── coverage-report.md
│ ├── known-gaps.md
│ └── screenshots/
│ └── structured-ir/
│ ├── structured-ir.yaml
│ ├── ir-assertions.yaml
│ └── ir-evidence-packet.md
└── test-cases/
├── source-manifest.yaml
├── source-files/
Expand All @@ -71,10 +78,11 @@ specs/<feature>/intake/

Figma metadata artifacts are required for Figma visual-design sources. Image, PDF, and Markdown visual-design sources use `design-source-manifest.yaml`, source-file checksums, extracted visual requirements, and visual parity evidence instead. PRD and test-case domains use their own source manifests and normalized intake files.

Machine-readable JSON Schemas live under `templates/schemas/` and are used by the validators before readiness rules run. HTML SSOT bundles use `figma-map.schema.json`, `assets-manifest.schema.json`, and `html-ssot-coverage.schema.json`.
Machine-readable JSON Schemas live under `templates/schemas/` and are used by the validators before readiness rules run. HTML SSOT bundles use `figma-map.schema.json`, `assets-manifest.schema.json`, and `html-ssot-coverage.schema.json`. Structured IR uses `structured-ir.schema.json` and `ir-assertions.schema.json`.

All intake commands provide capture instructions, evidence contracts, and readiness validation. Visual design validation additionally checks visual fidelity and Figma metadata parity.
HTML SSOT validation is owned by `scripts/python/validate_html_ssot.py`, including cross-file checks for selectors, assets, screenshots, coverage, and known gaps.
Structured IR validation is owned by `scripts/python/validate_structured_ir_intake.py`, including source readiness, schema, cross-reference, locator, downstream-ownership, provider-evidence, product-ambiguity, and CI assertion checks.

## Requirements

Expand All @@ -98,13 +106,23 @@ From a Spec Kit project:
specify extension add intake --from https://github.com/bigsmartben/spec-kit-intake/archive/refs/tags/v0.1.3.zip
```

Release artifacts must include source-backed provenance for the `bigsmartben/spec-kit` integration fork. The release workflow uploads `release-provenance.json` with:

- `repository_url`
- `release_version`
- `source_commit_sha`
- `download_url`
- `validation_evidence`

Then run:

```text
/speckit.intake.visual-design capture <image|pdf|markdown|figma source and scope>
/speckit.intake.visual-design validate
/speckit.intake.figma2htmlssot build <figma source or visual-design intake scope>
/speckit.intake.figma2htmlssot validate
/speckit.intake.ir build <visual-design intake scope or HTML SSOT enhancement refs>
/speckit.intake.ir validate
/speckit.intake.prd capture <prd source and scope>
/speckit.intake.prd validate
/speckit.intake.test-cases capture <test source and scope>
Expand Down Expand Up @@ -146,7 +164,21 @@ Figma-derived HTML SSOT passes only when:
- screenshot coverage and visual-diff status are recorded
- known gaps are explicit and no blocking gap remains unresolved

The HTML SSOT validator emits blocker codes such as `HTML_SSOT_REQUIRED_ARTIFACT_MISSING`, `HTML_SSOT_FIGMA_NODE_COVERAGE_INCOMPLETE`, `HTML_SSOT_COMPONENT_STATE_COVERAGE_INCOMPLETE`, `HTML_SSOT_PAGE_COVERAGE_INCOMPLETE`, `HTML_SSOT_ASSET_TRACEABILITY_INCOMPLETE`, `HTML_SSOT_VIEWPORT_CAPTURE_INCOMPLETE`, `HTML_SSOT_VISUAL_DIFF_BLOCKED`, and `HTML_SSOT_KNOWN_GAP_UNRESOLVED`.
The HTML SSOT validator emits blocker codes such as `HTML_SSOT_SOURCE_INTAKE_BLOCKED`, `HTML_SSOT_REQUIRED_ARTIFACT_MISSING`, `HTML_SSOT_SCHEMA_INVALID`, `HTML_SSOT_FIGMA_NODE_COVERAGE_INCOMPLETE`, `HTML_SSOT_COMPONENT_STATE_COVERAGE_INCOMPLETE`, `HTML_SSOT_PAGE_COVERAGE_INCOMPLETE`, `HTML_SSOT_ASSET_TRACEABILITY_INCOMPLETE`, `HTML_SSOT_VIEWPORT_CAPTURE_INCOMPLETE`, `HTML_SSOT_VISUAL_DIFF_BLOCKED`, and `HTML_SSOT_KNOWN_GAP_UNRESOLVED`.

## Structured IR Readiness Gate

Structured UI acceptance IR passes only when:

- upstream visual-design intake is ready
- `structured-ir.yaml`, `ir-assertions.yaml`, and `ir-evidence-packet.md` exist
- IR items preserve source refs, page, region, role, state, viewport, provider-neutral locator strategy, expectations, acceptance intent, confidence, status, and blockers
- assertions reference existing IR items and include ready `ci_low_cost` checks
- missing provider evidence and product ambiguity are represented with distinct blocker paths
- locator strategies avoid implementation-owned CSS selectors, XPath, generated class names, downstream test IDs, code component names, tasks, or requirement IDs
- HTML SSOT, screenshots, and visual diffs remain enhancement evidence rather than the primary acceptance substrate

The structured IR validator emits blocker codes such as `IR_SOURCE_INTAKE_BLOCKED`, `IR_REQUIRED_ARTIFACT_MISSING`, `IR_SCHEMA_INVALID`, `IR_INTAKE_INCOMPLETE`, `IR_PROVIDER_EVIDENCE_MISSING`, `IR_PRODUCT_AMBIGUITY_UNRESOLVED`, `IR_ASSERTION_COVERAGE_INCOMPLETE`, `IR_LOCATOR_STRATEGY_INVALID`, `IR_DOWNSTREAM_OWNERSHIP_LEAK`, and `IR_READY_WITHOUT_EVIDENCE`.

## Development

Expand All @@ -168,6 +200,12 @@ Validate HTML SSOT bundles:
python scripts/python/validate_html_ssot.py specs/<feature>/intake/visual-design/figma2htmlssot
```

Validate structured IR artifacts:

```bash
python scripts/python/validate_structured_ir_intake.py specs/<feature>/intake/visual-design/structured-ir
```

Validate PRD artifacts:

```bash
Expand Down
25 changes: 8 additions & 17 deletions commands/speckit.intake.figma2htmlssot.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Classify the input before proceeding:

## Goal

Create, update, or validate a Figma-to-HTML visual single source of truth (SSOT) bundle for the active Spec Kit feature. The HTML bundle defines visual requirements and acceptance surfaces by preserving Figma traceability, source coverage, component-instance-state granularity, page-level composition, assets, responsive behavior, and known gaps.
Create, update, or validate a Figma-to-HTML visual single source of truth (SSOT) bundle for the active Spec Kit feature. The HTML bundle defines visual requirements and acceptance surfaces by preserving Figma traceability, source coverage, component-state granularity, page-level composition, assets, responsive behavior, and known gaps.

Default output directory:

Expand Down Expand Up @@ -53,11 +53,11 @@ component instance + state + content sample + container constraint + viewport

Use this hierarchy:

- Component-instance-state: minimum runnable screenshot and comparison unit for tokens, local layout, states, overflow, and local interaction surfaces.
- Component-state: minimum runnable screenshot and comparison unit for tokens, local layout, states, overflow, and local interaction surfaces.
- Section: composition unit for spacing, ordering, alignment, and local responsive behavior across multiple component instances.
- Page: final release gate for information completeness, cross-section layout, first-viewport experience, scrolling, and target runtime acceptance.

Component-level acceptance cannot replace page-level acceptance. Page-level acceptance cannot replace required component-instance-state coverage.
Component-level acceptance cannot replace page-level acceptance. Page-level acceptance cannot replace required component-state coverage.

## Context Loading

Expand Down Expand Up @@ -105,7 +105,7 @@ data-required="true"

5. Preserve design tokens and visual facts in CSS custom properties or documented token mappings when available. Record unmapped tokens as gaps instead of silently flattening them.
6. Export or reference assets through `assets-manifest.json`; do not embed untraceable base64 assets unless the source ref and checksum are recorded.
7. Capture target runtime screenshots for every required component-instance-state, section, and page surface across the declared viewport set.
7. Capture target runtime screenshots for every required component-state, section, and page surface across the declared viewport set.
8. Compare Figma and HTML screenshots when tooling is available. Record thresholds, accepted exceptions, and blocking difference categories in `coverage-report.md`.
9. Validate the HTML SSOT bundle before reporting readiness:

Expand All @@ -126,20 +126,11 @@ python .specify/extensions/intake/scripts/python/validate_html_ssot.py <figma2ht

3. The validator confirms required bundle artifacts exist and are internally consistent:
- every required Figma node is covered by `figma-map.json` or recorded as an accepted exclusion
- every required component-instance-state has a runnable HTML selector, viewport, content sample, container constraint, and screenshot
- every required component-state has a runnable HTML selector, viewport, content sample, container constraint, and screenshot
- every required section and page has a runnable HTML selector, viewport coverage, and screenshot
- every referenced asset appears in `assets-manifest.json` with source refs and checksum
- every required HTML element has a stable Figma source ref
4. Apply these blocker codes when validation fails:
- `HTML_SSOT_SOURCE_INTAKE_BLOCKED`
- `HTML_SSOT_REQUIRED_ARTIFACT_MISSING`
- `HTML_SSOT_FIGMA_NODE_COVERAGE_INCOMPLETE`
- `HTML_SSOT_COMPONENT_STATE_COVERAGE_INCOMPLETE`
- `HTML_SSOT_PAGE_COVERAGE_INCOMPLETE`
- `HTML_SSOT_ASSET_TRACEABILITY_INCOMPLETE`
- `HTML_SSOT_VIEWPORT_CAPTURE_INCOMPLETE`
- `HTML_SSOT_VISUAL_DIFF_BLOCKED`
- `HTML_SSOT_KNOWN_GAP_UNRESOLVED`
4. Report blocker codes exactly as emitted by `scripts/python/validate_html_ssot.py`; do not infer or rewrite the validator output.
5. Mark readiness:
- `PASS` only when required artifacts exist, required coverage is complete, screenshots are captured, blockers are empty, and accepted exceptions are explicit.
- `BLOCKED` when any blocker code is present or any required coverage item lacks traceable evidence.
Expand All @@ -152,7 +143,7 @@ Use this precedence when sources disagree:
2. `figma-map.json`, `assets-manifest.json`, and screenshot captures are canonical for HTML SSOT traceability and runtime coverage.
3. `coverage-report.md` and `known-gaps.md` explain readiness, accepted exceptions, and blockers for human review.

Do not promote HTML as the visual SSOT when upstream Figma evidence is incomplete or when coverage cannot prove the minimum component-instance-state and page-level gates.
Do not promote HTML as the visual SSOT when upstream Figma evidence is incomplete or when coverage cannot prove the minimum component-state and page-level gates.

## Report

Expand All @@ -162,7 +153,7 @@ Return:
- output or validated directory
- Figma source scope and upstream visual-design intake readiness
- required viewport set
- component-instance-state, section, and page coverage counts
- component-state, section, and page coverage counts
- asset count and unresolved asset gaps
- screenshot and visual-diff status
- readiness result
Expand Down
Loading