diff --git a/.github/workflows/community-smoke.yml b/.github/workflows/community-smoke.yml index 10f231689d..0378486f46 100644 --- a/.github/workflows/community-smoke.yml +++ b/.github/workflows/community-smoke.yml @@ -48,6 +48,7 @@ jobs: test -f .specify/extensions/arch/extension.yml test -f .specify/extensions/preview/extension.yml test -f .specify/extensions/discovery/extension.yml + test -f .specify/extensions/inception/extension.yml test -f .specify/extensions/intake/extension.yml test -f .specify/extensions/repository-governance/extension.yml test -f .specify/presets/workflow-preset/preset.yml @@ -99,6 +100,8 @@ jobs: done test -f .claude/skills/speckit-preview-wireflow/SKILL.md test -f .claude/skills/speckit-discovery-contract/SKILL.md + test -f .claude/skills/speckit-inception-product/SKILL.md + test -f .claude/skills/speckit-inception-arch/SKILL.md test -f .claude/skills/speckit-intake-visual-design/SKILL.md test -f .claude/skills/speckit-intake-prd/SKILL.md test -f .claude/skills/speckit-intake-test-cases/SKILL.md @@ -119,7 +122,7 @@ jobs: grep -q "Vertical Planner Agent" .claude/skills/speckit-implement/SKILL.md grep -q "Worker Agent" .claude/skills/speckit-implement/SKILL.md - for extension_id in arch discovery intake preview repository-governance; do + for extension_id in arch discovery inception intake preview repository-governance; do /tmp/specify-community-smoke-venv/bin/specify extension remove "$extension_id" --force test ! -d ".specify/extensions/$extension_id" case "$extension_id" in @@ -132,6 +135,9 @@ jobs: discovery) test "$(find .claude/skills -maxdepth 1 -type d -name 'speckit-discovery-*' | wc -l)" -eq 0 ;; + inception) + test "$(find .claude/skills -maxdepth 1 -type d -name 'speckit-inception-*' | wc -l)" -eq 0 + ;; intake) test "$(find .claude/skills -maxdepth 1 -type d -name 'speckit-intake-*' | wc -l)" -eq 0 ;; @@ -141,7 +147,7 @@ jobs: esac done - for extension_id in arch discovery intake preview repository-governance; do + for extension_id in arch discovery inception intake preview repository-governance; do /tmp/specify-community-smoke-venv/bin/specify extension add "$GITHUB_WORKSPACE/extensions/$extension_id" --dev case "$extension_id" in arch) @@ -157,6 +163,12 @@ jobs: test -f .claude/skills/speckit-discovery-contract/SKILL.md grep -q "interface-contract discovery facilitator" .claude/skills/speckit-discovery-contract/SKILL.md ;; + inception) + test -f .claude/skills/speckit-inception-product/SKILL.md + test -f .claude/skills/speckit-inception-arch/SKILL.md + grep -q "Conversation Workflow" .claude/skills/speckit-inception-product/SKILL.md + grep -q "API POC Workflow" .claude/skills/speckit-inception-arch/SKILL.md + ;; intake) test -f .claude/skills/speckit-intake-visual-design/SKILL.md test -f .claude/skills/speckit-intake-prd/SKILL.md diff --git a/README.md b/README.md index 988e88ae1b..7869f893ab 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ 如果你只是想知道这个仓库相比基础流程多了什么,可以先看这三件事: -- 默认扩展:`arch`、`discovery`、`intake`、`preview`、`repository-governance`。 +- 默认扩展:`arch`、`discovery`、`inception`、`intake`、`preview`、`repository-governance`。 - 默认预设:`workflow-preset`。 - 自动上下文扩展:`agent-context`。 @@ -66,6 +66,7 @@ specify init my-project --integration codex --ignore-agent-tools | 自动扩展 | `agent-context` | `extensions/agent-context` | 维护 AGENTS、CLAUDE、Copilot 等 agent context 文件里的 Spec Kit 受管段。 | | 默认扩展 | `arch` | `extensions/arch` | 生成或反向生成面向 `/speckit.plan` 的架构规划契约。 | | 默认扩展 | `discovery` | `extensions/discovery` | 在正式计划前做可行性、技术选型、旧代码评估、接口理解、PoC 和场景化技术决策。 | +| 默认扩展 | `inception` | `extensions/inception` | 在正式 SDD 前通过对话收敛产品 UC、wireflow、架构边界和真实 API POC 证据。 | | 默认扩展 | `intake` | `extensions/intake` | 把 PRD、设计稿、Figma、视觉规格资产包、preview 覆盖证据、测试用例等来源归一化为 SDD 可消费的证据包。 | | 默认扩展 | `preview` | `extensions/preview` | 从规格和计划生成低、中、高保真 Markdown 或自包含 HTML 预览。 | | 默认扩展 | `repository-governance` | `extensions/repository-governance` | 生成仓库治理 SSOT,帮助 agent 明确目录责任、读取顺序和事实证据。 | @@ -75,6 +76,38 @@ specify init my-project --integration codex --ignore-agent-tools ## 默认扩展 +### `inception` + +`inception` 是正式规格化和工程迭代之前的启动设计阶段。它通过对话确认推进,不新增 workflow 命名层;命令会引导用户确认产品和架构前置材料,并用模板生成 `/inception/` 下的产物。 + +常用命令: + +```text +/speckit.inception.product +/speckit.inception.arch +``` + +主要产物: + +```text +inception/product/uc.md +inception/product/wireflow-medium.html +inception/product/wireflow-high.html +inception/arch/api-capability.md +inception/arch/api-poc.md +inception/arch/system-boundary.md +inception/arch/domain-model.md +inception/arch/arch.md +inception/arch/api-poc-runs/ +``` + +使用建议: + +- 先跑 `/speckit.inception.product`,把产品想法收敛成 UC 和 medium/high wireflow。 +- 再跑 `/speckit.inception.arch`,只从 UC 出发做能力、边界、领域和架构前置设计。 +- API POC 不是伪代码;运行前必须确认目标能力、验证假设、环境、依赖、配置、样例输入、外部访问、允许副作用和停止条件,运行资产只写入 `inception/arch/api-poc-runs/`。 +- `inception` 不生成 `spec.md`、`plan.md`、`tasks.md`、OpenAPI、数据库 schema、生产代码或测试套件变更。 + ### `arch` `arch` 给项目补一层架构记忆。它不是 feature 计划,也不是实现设计;它负责把项目级边界、约束、已定决策、禁止方向、开放问题和 plan review checklist 写成唯一的规划契约。 @@ -157,35 +190,25 @@ specs//intake/test-cases/ ### `preview` -`preview` 在实现前生成评审产物。它不改应用源码,不替代实现;它用当前 feature 的规格、计划和契约生成可以讨论的 wireflow 或 HTML 预览。 +`preview` 在实现前生成评审产物。它不改应用源码,不替代实现;它用当前 feature 的规格、计划和契约生成可以讨论的自包含 HTML wireflow。 常用命令: ```text -/speckit.preview.low-md -/speckit.preview.low-html -/speckit.preview.mid-md -/speckit.preview.mid-html -/speckit.preview.high-md -/speckit.preview.high-html +/speckit.preview.wireflow [design focus] ``` 主要产物: ```text -specs//preview/wireflow-low.md -specs//preview/wireflow-low.html -specs//preview/wireflow-mid.md -specs//preview/wireflow-mid.html -specs//preview/wireflow-high.md -specs//preview/wireflow-high.html +specs//preview/wireflow.html ``` 使用建议: -- 需求还早期:用 `low-md` 或 `low-html` 看主路径和分支。 -- 产品、设计和工程需要一起评审:用 `mid-md` 或 `mid-html`。 -- 交互、状态、权限、响应式和错误反馈要确认:用 `high-md` 或 `high-html`。 +- 需求还早期:用 `low` 看主路径和分支。 +- 产品、设计和工程需要一起评审:用 `mid`。 +- 交互、状态、权限、响应式和错误反馈要确认:用 `high`。 ### `repository-governance` @@ -409,12 +432,14 @@ specify bundle build --path ./my-bundle ```text /speckit.constitution +/speckit.inception.product +/speckit.inception.arch /speckit.arch.generate /speckit.specify /speckit.clarify /speckit.discovery.feasibility /speckit.plan -/speckit.preview.mid-html +/speckit.preview.wireflow mid /speckit.tasks /speckit.analyze /speckit.implement @@ -449,9 +474,9 @@ specify bundle build --path ./my-bundle ```text /speckit.intake.visual-design /speckit.specify -/speckit.preview.low-md +/speckit.preview.wireflow low /speckit.plan -/speckit.preview.mid-html +/speckit.preview.wireflow mid /speckit.tasks /speckit.implement ``` @@ -501,8 +526,10 @@ specify extension add bug | --- | --- | --- | | `.specify/memory/architecture.md` | `arch` | 面向 `/speckit.plan` 的架构规划契约。 | | `.specify/memory/repository-governance.md` | `repository-governance` | 内部仓库治理 SSOT。 | +| `inception/product/` | `inception` | 产品 UC 和 medium/high wireflow 启动设计产物。 | +| `inception/arch/` | `inception` | 架构前置设计、真实 API POC 证据和运行资产。 | | `specs//intake/` | `intake` | PRD、视觉设计、测试用例的结构化证据包。 | -| `specs//preview/` | `preview` | Markdown wireflow 和自包含 HTML 预览。 | +| `specs//preview/` | `preview` | 单一自包含 HTML wireflow 预览。 | | `specs//contracts/bdd/` | `workflow-preset` | BDD 行为契约。 | | `specs//contracts/uif/` | `workflow-preset` | UI flow / interface fidelity 契约。 | | `specs//contracts/behavior/` | `workflow-preset` | 行为场景、fixture、assertion 等正式契约。 | diff --git a/docs/quickstart.md b/docs/quickstart.md index ef93733cc6..a3dd0c5150 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -14,13 +14,15 @@ ```text /speckit.constitution +/speckit.inception.product +/speckit.inception.arch /speckit.arch.generate /speckit.repository-governance.generate /speckit.specify /speckit.clarify /speckit.plan /speckit.checklist -/speckit.preview.mid-html +/speckit.preview.wireflow mid /speckit.tasks /speckit.analyze /speckit.implement @@ -178,16 +180,16 @@ specs//checklists/behavior-testability.md 对 UI、流程或交互有不确定性时,先生成保真度合适的预览产物: ```text -/speckit.preview.mid-html mobile album browsing and reorder flow +/speckit.preview.wireflow mid mobile album browsing and reorder flow ``` 打开输出文件评审: ```text -specs//preview/wireflow-mid.html +specs//preview/wireflow.html ``` -这个文件只用于实现前评审 flow、信息架构、状态和交互假设,不会修改生产代码。也可以按需要使用 `/speckit.preview.low-md`、`/speckit.preview.low-html`、`/speckit.preview.high-md` 或 `/speckit.preview.high-html`。 +这个文件只用于实现前评审 flow、信息架构、状态和交互假设,不会修改生产代码。也可以按需要使用 `/speckit.preview.wireflow low` 或 `/speckit.preview.wireflow high`。 ## 7. 生成计划与行为契约 @@ -289,6 +291,7 @@ specify workflow search ```bash specify extension add arch +specify extension add inception specify extension add preview specify extension add repository-governance specify preset add workflow-preset diff --git a/extensions/catalog.json b/extensions/catalog.json index 8d19786a6d..a366100d5e 100644 --- a/extensions/catalog.json +++ b/extensions/catalog.json @@ -69,6 +69,29 @@ "core" ] }, + "inception": { + "name": "SDD Inception", + "id": "inception", + "version": "1.0.0", + "description": "Guide pre-iteration product and architecture inception through conversational workflows before formal Spec Kit stages", + "author": "bigsmartben", + "repository": "https://github.com/bigsmartben/spec-kit", + "license": "MIT", + "bundled": true, + "requires": { + "speckit_version": ">=0.8.10.dev0" + }, + "provides": { + "commands": 2 + }, + "tags": [ + "inception", + "sdd", + "product", + "architecture", + "workflow" + ] + }, "intake": { "name": "Intake", "id": "intake", diff --git a/extensions/inception/CHANGELOG.md b/extensions/inception/CHANGELOG.md new file mode 100644 index 0000000000..84cddbadc3 --- /dev/null +++ b/extensions/inception/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## 1.0.0 + +- Add product and architecture inception workflow commands. +- Add template-backed inception artifacts under `inception/product/` and `inception/arch/`. +- Require user-confirmed preparation before running real API POC code. diff --git a/extensions/inception/LICENSE b/extensions/inception/LICENSE new file mode 100644 index 0000000000..7a62eb18f5 --- /dev/null +++ b/extensions/inception/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 bigsmartben + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extensions/inception/README.md b/extensions/inception/README.md new file mode 100644 index 0000000000..af465b85b5 --- /dev/null +++ b/extensions/inception/README.md @@ -0,0 +1,69 @@ +# SDD Inception Extension + +Run the pre-iteration inception stage before formal Spec Kit specification and planning. + +This extension provides two conversational workflow commands: + +```text +/speckit.inception.product +/speckit.inception.arch +``` + +The commands guide the user through confirmation points, then write only inception artifacts under the project root `inception/` directory. + +## Product Inception + +`/speckit.inception.product` converges product ideas into: + +```text +inception/product/uc.md +inception/product/wireflow-medium.html +inception/product/wireflow-high.html +``` + +`wireflow-medium.html` and `wireflow-high.html` are derived from `uc.md`. They must not create new product facts and must not overwrite the product boundary established in `uc.md`. + +## Architecture Inception + +`/speckit.inception.arch` uses one formal input: + +```text +inception/product/uc.md +``` + +It writes: + +```text +inception/arch/api-capability.md +inception/arch/api-poc.md +inception/arch/system-boundary.md +inception/arch/domain-model.md +inception/arch/arch.md +inception/arch/api-poc-runs/ +``` + +`api-capability.md` includes a technology selection matrix that compares candidate options for high-value or high-risk capabilities, then records recommended, backup, and rejected options with tradeoff rationale. + +`api-poc.md` records real code execution evidence. Before running any POC code, the command must confirm the target capability, validation hypothesis, runtime environment, dependencies, credential/config needs, sample input, external service access, allowed side effects, and stop conditions with the user. + +POC code and outputs are confined to: + +```text +inception/arch/api-poc-runs// +``` + +## Boundaries + +The inception commands do not create formal Spec Kit artifacts: + +```text +spec.md +plan.md +tasks.md +OpenAPI +database schema +application implementation +test suite changes +``` + +Use `/speckit.specify` after product inception, and use `/speckit.plan` after formal specs and architecture context are ready. diff --git a/extensions/inception/commands/speckit.inception.arch.md b/extensions/inception/commands/speckit.inception.arch.md new file mode 100644 index 0000000000..9911fa081f --- /dev/null +++ b/extensions/inception/commands/speckit.inception.arch.md @@ -0,0 +1,212 @@ +--- +description: Derive inception architecture artifacts from product UC and confirmed API POC evidence. +--- + +## User Input + +```text +$ARGUMENTS +``` + +You **MUST** consider the user input before proceeding when it is not empty. + +## Goal + +Guide a conversational architecture inception workflow from the product UC to these artifacts: + +```text +inception/arch/api-capability.md +inception/arch/api-poc.md +inception/arch/system-boundary.md +inception/arch/domain-model.md +inception/arch/arch.md +inception/arch/api-poc-runs/ +``` + +This command answers: + +- How do all architecture inception artifacts roll up into complete architecture pre-design: capabilities, boundaries, domain-model constraints, security, error handling, NFRs, architecture decisions, risks, and constraints for `plan.md`? +- Which system capabilities are required by the confirmed UC? +- Which technical options are viable for each high-value or high-risk capability? +- Which option is recommended, which option is retained as backup, and which options are rejected? +- Which capabilities need real POC validation? +- Where are the client, server, data, permission, and third-party boundaries? +- What domain concepts and invariants constrain later formal planning? +- What did real POC code prove, fail to prove, or constrain? + +It does not create formal API contracts, implementation plans, tasks, production code, or test-suite changes. +It is not an implementation plan; it is architecture input for later formal planning. + +## Formal Input + +The only formal input is: + +```text +inception/product/uc.md +``` + +If it is missing, stop and ask the user to run `/speckit.inception.product` or provide the UC. + +You may read existing files under `inception/arch/` only as refresh baselines. These existing files do not outrank the current UC. + +Forbidden sources as architecture evidence: + +```text +inception/product/wireflow-medium.html +inception/product/wireflow-high.html +spec.md +plan.md +tasks.md +contracts/ +OpenAPI files +database schemas +application source code +tests +``` + +If a forbidden source is used as evidence, stop with blocker `SOURCE_PRIORITY_VIOLATION`. + +## Templates + +Template structure is authoritative. Load these templates before writing output: + +```text +.specify/extensions/inception/templates/arch/api-capability-template.md +.specify/extensions/inception/templates/arch/api-poc-template.md +.specify/extensions/inception/templates/arch/system-boundary-template.md +.specify/extensions/inception/templates/arch/domain-model-template.md +.specify/extensions/inception/templates/arch/arch-template.md +``` + +When running from the extension repository, use: + +```text +templates/arch/api-capability-template.md +templates/arch/api-poc-template.md +templates/arch/system-boundary-template.md +templates/arch/domain-model-template.md +templates/arch/arch-template.md +``` + +Do not invent output sections, table columns, POC evidence fields, or quality gates outside the templates. If a template is missing, stop with blocker `TEMPLATE_BYPASS`. + +## Conversation Workflow + +Before writing architecture artifacts, confirm: + +1. UC scope and product boundaries from `inception/product/uc.md`. +2. Capability inventory and each capability's UC source. +3. Risk level for each capability. +4. Candidate technical options for each high-value or high-risk capability. +5. Technical option fit, complexity, dependency risk, performance/security/cost impact, team familiarity, maintainability, and POC necessity. +6. Recommended option, backup option, rejected options, and tradeoff rationale for each high-value or high-risk capability. +7. Which capabilities require real POC code. +8. System boundaries and non-goals. +9. Domain-model facts to record in `domain-model.md`, including objects, state transitions, invariants, and open questions. For `arch.md`, reference only the domain-model constraints that affect architecture decisions. + +If a needed architecture conclusion is not supported by UC or confirmed POC evidence, record it as an open question instead of writing it as fact. + +## API POC Workflow + +`api-poc.md` is not pseudocode. It records real code execution evidence. + +Before running any POC code, you **MUST** confirm the preparation packet with the user: + +```text +target capability +validation hypothesis +runtime environment +dependencies +credential/config needs +sample input +external service access +allowed side effects +stop conditions +``` + +If this confirmation is missing, stop with blocker `POC_CONFIRMATION_MISSING`. + +After confirmation: + +- Create POC assets only under `inception/arch/api-poc-runs//`. +- Keep POC code disposable and explicitly labeled as validation-only. +- Run the POC code when the confirmed environment allows it. +- Capture the exact command, environment summary, input, output, failure details, conclusion, and formal-iteration constraints in `api-poc.md`. + +POC code must not modify: + +```text +application source +production configuration +database migrations +formal API contract +OpenAPI files +SDKs +test suites +build configuration +deployment files +``` + +If `api-poc.md` lacks real run command/output/result evidence for a completed POC, stop with blocker `POC_RUN_EVIDENCE_MISSING`. + +## Operating Boundaries + +Write only: + +```text +inception/arch/api-capability.md +inception/arch/api-poc.md +inception/arch/system-boundary.md +inception/arch/domain-model.md +inception/arch/arch.md +inception/arch/api-poc-runs// +``` + +Do not create or modify: + +```text +spec.md +plan.md +tasks.md +api-contract +openapi.yaml +database schema +application source code outside `inception/arch/api-poc-runs/` +tests +build configuration +production assets +``` + +If any output path falls outside `inception/arch/`, stop with blocker `OUTPUT_PATH_MISMATCH`. + +## Procedure + +1. Load `inception/product/uc.md`. +2. Load architecture templates. +3. Run the conversation workflow and confirm architecture scope. +4. Extract system capabilities from `uc.md`. +5. Compare technical candidates for high-value or high-risk capabilities in `api-capability.md`. +6. Record recommended, backup, and rejected options with tradeoff rationale. +7. Confirm POC preparation packets for high-risk capabilities. +8. Run confirmed POC code under `api-poc-runs//` when approved and feasible. +9. Render `api-poc.md` from real POC evidence. +10. Render `system-boundary.md`, `domain-model.md`, and `arch.md`. +11. Re-check every rendered artifact against the quality gates. +12. Report written paths, POC run directories, exact run commands, blockers, risks, and open questions. + +`arch.md` must not include a mock strategy section. Mock handling, fixtures, sandboxing, or test doubles belong to later formal planning/task artifacts or to separate boundary notes, not to the primary architecture inception artifact. +`arch.md` must not include a standalone state model section. State enumerations, transitions, domain rules, and business invariants belong in `domain-model.md`; `arch.md` may reference only the key domain-model constraints needed for architecture decisions. + +## Quality Gates + +- `OUTPUT_PATH_MISMATCH`: a write target is outside `inception/arch/`. +- `SOURCE_PRIORITY_VIOLATION`: a forbidden source was used as evidence. +- `POC_CONFIRMATION_MISSING`: POC code would run before the user confirms the preparation packet. +- `POC_RUN_EVIDENCE_MISSING`: `api-poc.md` lacks real command, output, or result evidence for a completed POC. +- `SCOPE_LEAK`: output includes formal spec, plan, task, API contract, OpenAPI, database schema, application implementation, or test-suite changes. +- `UNSUPPORTED_INFERENCE`: an unconfirmed item is written as fact. +- `TECH_SELECTION_MISSING`: a high-value or high-risk capability lacks candidate technical options, a recommended option, or tradeoff rationale. +- `EMPTY_PRIMARY_ARTIFACT`: `arch.md` lacks overview, UC context, capability architecture, boundaries, domain model, decisions, risks, or handoff constraints. +- `TEMPLATE_BYPASS`: templates were not loaded or the output structure bypasses them. + +If any blocker is present, report the blocker code and do not claim the inception architecture artifacts are ready. diff --git a/extensions/inception/commands/speckit.inception.product.md b/extensions/inception/commands/speckit.inception.product.md new file mode 100644 index 0000000000..d38e7635db --- /dev/null +++ b/extensions/inception/commands/speckit.inception.product.md @@ -0,0 +1,151 @@ +--- +description: Converge product intent into inception product UC and wireflow artifacts. +--- + +## User Input + +```text +$ARGUMENTS +``` + +You **MUST** consider the user input before proceeding when it is not empty. + +## Goal + +Guide a conversational product inception workflow and write only these artifacts: + +```text +inception/product/uc.md +inception/product/wireflow-medium.html +inception/product/wireflow-high.html +``` + +This command answers: + +- Who is the user? +- What goal are they trying to complete? +- What is the product boundary for this inception round? +- How does the user journey flow at medium and high fidelity? + +It does not create formal Spec Kit feature artifacts. + +## Templates + +Template structure is authoritative. Load these templates before writing output: + +```text +.specify/extensions/inception/templates/product/uc-template.md +.specify/extensions/inception/templates/product/wireflow-medium-template.html +.specify/extensions/inception/templates/product/wireflow-high-template.html +``` + +When running from the extension repository, use: + +```text +templates/product/uc-template.md +templates/product/wireflow-medium-template.html +templates/product/wireflow-high-template.html +``` + +Do not invent output sections, table columns, HTML structure, or quality gates outside the templates. If a template is missing, stop with blocker `TEMPLATE_BYPASS`. + +## Conversation Workflow + +Proceed through these confirmation points before writing: + +1. Confirm the product idea, target users, and primary job-to-be-done. +2. Confirm business assumptions and success criteria. +3. Confirm core user scenarios, alternate paths, exception paths, and permission boundaries. +4. Confirm out-of-scope items for this inception round. +5. Confirm unresolved questions and mark them as `[NEEDS CLARIFICATION]`. + +If any confirmation is missing and the artifact would otherwise turn an assumption into fact, stop with blocker `UNSUPPORTED_INFERENCE`. + +## Context Loading + +1. Verify the current directory is a Spec Kit project by checking for `.specify/`. +2. Read user-provided product input from `$ARGUMENTS`. +3. Read existing `inception/product/uc.md` only when refreshing prior product inception work. +4. Read existing `inception/product/wireflow-medium.html` and `inception/product/wireflow-high.html` only to preserve still-valid design notes and open questions. + +Forbidden sources: + +```text +spec.md +plan.md +tasks.md +inception/arch/ +docs/technical/ +contracts/ +OpenAPI files +database schemas +source code +tests +``` + +If a forbidden source is used as evidence, stop with blocker `SOURCE_PRIORITY_VIOLATION`. + +## Product Artifact Rules + +- `uc.md` is the primary product fact artifact. +- `wireflow-medium.html` and `wireflow-high.html` are derived from `uc.md`. +- Wireflow artifacts must not add new product facts, new business rules, new permissions, or new validation rules that are absent from `uc.md`. +- Unsupported requested items must be recorded as open questions, not silently invented. +- Use stable evidence labels: `confirmed`, `needs-clarification`, `derived-from-uc`, `unsupported`. + +`wireflow-high.html` must cover these UI states when relevant to the confirmed UC: + +```text +loading +success +empty +error +disabled +permission denied +submitting +submitted +``` + +## Operating Boundaries + +Write only the three product inception paths listed in Goal. + +Do not create or modify: + +```text +spec.md +arch.md +plan.md +tasks.md +api-contract +openapi.yaml +database schema +domain model +source code +tests +build configuration +production assets +``` + +If any output path falls outside `inception/product/`, stop with blocker `OUTPUT_PATH_MISMATCH`. + +## Procedure + +1. Load the product templates. +2. Run the conversation workflow and resolve missing confirmations. +3. Render `inception/product/uc.md` first. +4. Derive `inception/product/wireflow-medium.html` from `uc.md`. +5. Derive `inception/product/wireflow-high.html` from `uc.md`. +6. Re-check every rendered artifact against the quality gates. +7. Report written paths, confirmed product facts, derived wireflow coverage, unsupported requests, and open questions. + +## Quality Gates + +- `OUTPUT_PATH_MISMATCH`: a write target is outside `inception/product/`. +- `SOURCE_PRIORITY_VIOLATION`: a forbidden source was used as evidence. +- `SCOPE_LEAK`: output includes formal spec, plan, task, API contract, database schema, domain model, code implementation, or test-suite work. +- `UNSUPPORTED_INFERENCE`: an unconfirmed item is written as fact. +- `EMPTY_PRIMARY_ARTIFACT`: `uc.md` lacks roles, goals, main flow, success criteria, or out-of-scope sections. +- `TEMPLATE_BYPASS`: templates were not loaded or the output structure bypasses them. + +If any blocker is present, report the blocker code and do not claim the inception product artifacts are ready. diff --git a/extensions/inception/extension.yml b/extensions/inception/extension.yml new file mode 100644 index 0000000000..af21c21733 --- /dev/null +++ b/extensions/inception/extension.yml @@ -0,0 +1,32 @@ +schema_version: "1.0" + +extension: + id: inception + name: "SDD Inception" + version: "1.0.0" + description: "Guide pre-iteration product and architecture inception through conversational workflows before formal Spec Kit stages" + author: "bigsmartben" + repository: "https://github.com/bigsmartben/spec-kit" + homepage: "https://github.com/bigsmartben/spec-kit" + license: "MIT" + category: "process" + effect: "read-write" + +requires: + speckit_version: ">=0.8.10.dev0" + +provides: + commands: + - name: "speckit.inception.product" + file: "commands/speckit.inception.product.md" + description: "Converge product intent into inception/product UC and wireflow artifacts" + - name: "speckit.inception.arch" + file: "commands/speckit.inception.arch.md" + description: "Derive inception architecture artifacts from the product UC and confirmed POC evidence" + +tags: + - "inception" + - "sdd" + - "product" + - "architecture" + - "workflow" diff --git a/extensions/inception/templates/arch/api-capability-template.md b/extensions/inception/templates/arch/api-capability-template.md new file mode 100644 index 0000000000..86e7c41c7c --- /dev/null +++ b/extensions/inception/templates/arch/api-capability-template.md @@ -0,0 +1,47 @@ +# API Capability Inception + +## Metadata + +- **Artifact**: `inception/arch/api-capability.md` +- **Command**: `/speckit.inception.arch` +- **Formal Input**: `inception/product/uc.md` +- **Status**: draft | ready | blocked + +## Capability Inventory + +| Capability ID | Capability | UC Source | Risk Level | Needs POC | This Round Handling | +| --- | --- | --- | --- | --- | --- | +| CAP-001 | | | low | no | implement | + +Allowed handling values: `implement`, `mock`, `defer`. + +## Risk Notes + +| Capability ID | Risk | Evidence | Required Decision | +| --- | --- | --- | --- | +| CAP-001 | | UC | | + +## Technology Selection Matrix + +| Capability ID | Capability | Candidate Option | Fit | Complexity | Risk | Cost | Team Familiarity | POC Required | Decision | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| CAP-001 | | | high / medium / low | high / medium / low | high / medium / low | high / medium / low | high / medium / low | yes / no | recommend / backup / reject | + +## Technology Selection Rationale + +| Capability ID | Recommended Option | Why This Option | Rejected Options | Open Questions | +| --- | --- | --- | --- | --- | +| CAP-001 | | | | | + +## Open Questions + +- [NEEDS CLARIFICATION: ] + +## Quality Gate + +- `OUTPUT_PATH_MISMATCH`: not evaluated | pass | blocked +- `SOURCE_PRIORITY_VIOLATION`: not evaluated | pass | blocked +- `SCOPE_LEAK`: not evaluated | pass | blocked +- `UNSUPPORTED_INFERENCE`: not evaluated | pass | blocked +- `TECH_SELECTION_MISSING`: not evaluated | pass | blocked +- `TEMPLATE_BYPASS`: not evaluated | pass | blocked diff --git a/extensions/inception/templates/arch/api-poc-template.md b/extensions/inception/templates/arch/api-poc-template.md new file mode 100644 index 0000000000..99964c7189 --- /dev/null +++ b/extensions/inception/templates/arch/api-poc-template.md @@ -0,0 +1,61 @@ +# API POC Evidence + +## Metadata + +- **Artifact**: `inception/arch/api-poc.md` +- **Command**: `/speckit.inception.arch` +- **Formal Input**: `inception/product/uc.md` +- **POC Run Root**: `inception/arch/api-poc-runs/` +- **Status**: not-required | planned | running | passed | failed | blocked + +## Preparation Packet + +Confirm this packet with the user before running any POC code. + +| Field | Confirmed Value | +| --- | --- | +| Target capability | | +| Validation hypothesis | | +| Runtime environment | | +| Dependencies | | +| Credential/config needs | | +| Sample input | | +| External service access | | +| Allowed side effects | | +| Stop conditions | | + +## POC Runs + +| Capability | Run Directory | Command | Environment Summary | Input | Output | Result | +| --- | --- | --- | --- | --- | --- | --- | +| | `inception/arch/api-poc-runs//` | | | | | blocked | + +Allowed result values: `pass`, `fail`, `blocked`. + +## Failure Details + +| Capability | Failure | Evidence | Follow-up | +| --- | --- | --- | --- | +| | | | | + +## Risk Conclusion + +State what the real POC run proved, failed to prove, and constrains for formal iteration. + +## Formal Iteration Constraints + +- TBD + +## Open Questions + +- [NEEDS CLARIFICATION: ] + +## Quality Gate + +- `POC_CONFIRMATION_MISSING`: not evaluated | pass | blocked +- `POC_RUN_EVIDENCE_MISSING`: not evaluated | pass | blocked +- `OUTPUT_PATH_MISMATCH`: not evaluated | pass | blocked +- `SOURCE_PRIORITY_VIOLATION`: not evaluated | pass | blocked +- `SCOPE_LEAK`: not evaluated | pass | blocked +- `UNSUPPORTED_INFERENCE`: not evaluated | pass | blocked +- `TEMPLATE_BYPASS`: not evaluated | pass | blocked diff --git a/extensions/inception/templates/arch/arch-template.md b/extensions/inception/templates/arch/arch-template.md new file mode 100644 index 0000000000..09ba7cba53 --- /dev/null +++ b/extensions/inception/templates/arch/arch-template.md @@ -0,0 +1,91 @@ +# Architecture Inception + +## Metadata + +- **Artifact**: `inception/arch/arch.md` +- **Command**: `/speckit.inception.arch` +- **Formal Input**: `inception/product/uc.md` +- **Status**: draft | ready | blocked + +## 1. Architecture Overview + +Summarize the product-anchored architecture direction. + +## 2. Architecture Goals + +- TBD + +## 3. UC Context + +Reference only `inception/product/uc.md`. + +## 4. Capability Architecture + +Summarize `api-capability.md`. + +## 5. System Boundary + +Summarize runtime system boundaries from `system-boundary.md`. + +## 6. Domain Model + +Reference key constraints from `domain-model.md` only when they affect architecture decisions. Do not expand object state details. + +## 7. Application Architecture + +Describe architectural layers and responsibilities without implementation tasks or code. + +## 8. Client Architecture + +Describe client responsibilities and boundaries only. + +## 9. Server Architecture + +Describe server responsibilities and boundaries only. + +## 10. API Architecture + +Describe API capability shape and constraints. Do not define final endpoints, DTOs, OpenAPI, or SDKs. + +## 11. Security and Permission Boundary + +Describe permission boundaries and unresolved risks. + +## 12. Error Handling Architecture + +Describe error categories and recovery principles. + +## 13. Non-Functional Constraints + +- TBD + +## 14. Architecture Decisions + +| Decision | Source | Consequence | +| --- | --- | --- | +| | UC | | + +## 15. Risks and Mitigations + +| Risk | Mitigation | Evidence | +| --- | --- | --- | +| | | | + +## 16. Out of Scope + +- TBD + +## 17. Handoff to plan.md + +List constraints that formal planning must preserve. Do not create `plan.md`. + +## Quality Gate + +- `OUTPUT_PATH_MISMATCH`: not evaluated | pass | blocked +- `SOURCE_PRIORITY_VIOLATION`: not evaluated | pass | blocked +- `POC_CONFIRMATION_MISSING`: not evaluated | pass | blocked +- `POC_RUN_EVIDENCE_MISSING`: not evaluated | pass | blocked +- `SCOPE_LEAK`: not evaluated | pass | blocked +- `UNSUPPORTED_INFERENCE`: not evaluated | pass | blocked +- `EMPTY_PRIMARY_ARTIFACT`: not evaluated | pass | blocked +- `TEMPLATE_BYPASS`: not evaluated | pass | blocked diff --git a/extensions/inception/templates/arch/domain-model-template.md b/extensions/inception/templates/arch/domain-model-template.md new file mode 100644 index 0000000000..fb1d226562 --- /dev/null +++ b/extensions/inception/templates/arch/domain-model-template.md @@ -0,0 +1,35 @@ +# Domain Model Inception + +## Metadata + +- **Artifact**: `inception/arch/domain-model.md` +- **Command**: `/speckit.inception.arch` +- **Formal Input**: `inception/product/uc.md` + +## Domain Objects + +| Object | Responsibility | Relationship | UC Source | +| --- | --- | --- | --- | +| | | | | + +## Aggregate Boundaries + +| Aggregate | Owns | Does Not Own | Invariant | +| --- | --- | --- | --- | +| | | | | + +## State Enumerations + +| Object | State | Meaning | Transition Trigger | +| --- | --- | --- | --- | +| | | | | + +## Domain Rules + +| Rule | Invariant | UC Source | Open Risk | +| --- | --- | --- | --- | +| | | | | + +## Open Questions + +- [NEEDS CLARIFICATION: ] diff --git a/extensions/inception/templates/arch/system-boundary-template.md b/extensions/inception/templates/arch/system-boundary-template.md new file mode 100644 index 0000000000..9a58603516 --- /dev/null +++ b/extensions/inception/templates/arch/system-boundary-template.md @@ -0,0 +1,27 @@ +# System Boundary Inception + +## Metadata + +- **Artifact**: `inception/arch/system-boundary.md` +- **Command**: `/speckit.inception.arch` +- **Formal Input**: `inception/product/uc.md` + +## Boundaries + +| Boundary Type | In Scope | Out of Scope | UC Source | Open Risk | +| --- | --- | --- | --- | --- | +| Client | | | | | +| Server | | | | | +| Third Party | | | | | +| Data | | | | | +| State | | | | | +| Permission | | | | | +| Mock | | | | | + +## Non-Goals + +- TBD + +## Open Questions + +- [NEEDS CLARIFICATION: ] diff --git a/extensions/inception/templates/product/uc-template.md b/extensions/inception/templates/product/uc-template.md new file mode 100644 index 0000000000..81d180eeb1 --- /dev/null +++ b/extensions/inception/templates/product/uc-template.md @@ -0,0 +1,69 @@ +# Product Inception UC + +## Metadata + +- **Artifact**: `inception/product/uc.md` +- **Command**: `/speckit.inception.product` +- **Status**: draft | ready | blocked +- **Last Updated**: + +## Product Idea + +Describe the confirmed product idea in one paragraph. + +## Target Users + +| Role | Goal | Context | Evidence | +| --- | --- | --- | --- | +| | | | confirmed | needs-clarification | + +## User Goals + +| Goal ID | User Goal | Success Signal | Evidence | +| --- | --- | --- | --- | +| UG-001 | | | confirmed | + +## Main Flow + +1. TBD + +## Alternate Flows + +| Flow ID | Trigger | User Path | Outcome | Evidence | +| --- | --- | --- | --- | --- | +| AF-001 | | | | confirmed | + +## Exception Flows + +| Flow ID | Condition | User Feedback | Recovery | Evidence | +| --- | --- | --- | --- | --- | +| EF-001 | | | | confirmed | + +## Success Criteria + +| Criterion | Measurement | Evidence | +| --- | --- | --- | +| | | confirmed | + +## Business Boundaries + +| Boundary | In Scope | Out of Scope | Evidence | +| --- | --- | --- | --- | +| | | | confirmed | + +## This Round Will Not Do + +- TBD + +## Open Questions + +- [NEEDS CLARIFICATION: ] + +## Quality Gate + +- `OUTPUT_PATH_MISMATCH`: not evaluated | pass | blocked +- `SOURCE_PRIORITY_VIOLATION`: not evaluated | pass | blocked +- `SCOPE_LEAK`: not evaluated | pass | blocked +- `UNSUPPORTED_INFERENCE`: not evaluated | pass | blocked +- `EMPTY_PRIMARY_ARTIFACT`: not evaluated | pass | blocked +- `TEMPLATE_BYPASS`: not evaluated | pass | blocked diff --git a/extensions/inception/templates/product/wireflow-high-template.html b/extensions/inception/templates/product/wireflow-high-template.html new file mode 100644 index 0000000000..b3edaffcf8 --- /dev/null +++ b/extensions/inception/templates/product/wireflow-high-template.html @@ -0,0 +1,75 @@ + + + + + + Product Inception Wireflow High + + + +
+

Product Inception Wireflow High

+

Source: inception/product/uc.md

+ +
+

High-Fidelity Screen Flow

+
+

Screen derived from UC

+

Layout, fields, controls, and feedback must trace to UC evidence.

+
+
+ +
+

Required State Coverage

+ loading + success + empty + error + disabled + permission denied + submitting + submitted +
+ +
+

Interaction Matrix

+ + + + + + + +
ControlUser ActionSystem ResponseState ChangeUC Evidence
derived-from-uc
+
+ +
+

Visual Acceptance Standards

+ + + + + + + +
SurfaceAcceptance RuleEvidence
derived-from-uc
+
+ +
+

Open Questions

+
    +
  • [NEEDS CLARIFICATION: ]
  • +
+
+
+ + diff --git a/extensions/inception/templates/product/wireflow-medium-template.html b/extensions/inception/templates/product/wireflow-medium-template.html new file mode 100644 index 0000000000..ba788d1bf2 --- /dev/null +++ b/extensions/inception/templates/product/wireflow-medium-template.html @@ -0,0 +1,61 @@ + + + + + + Product Inception Wireflow Medium + + + +
+

Product Inception Wireflow Medium

+

Source: inception/product/uc.md

+ +
+

Page Flow

+
Start node derived from UC
+
Decision or interaction node derived from UC
+
Outcome node derived from UC
+
+ +
+

Page Responsibilities

+ + + + + + + +
Page or NodeResponsibilityUser ActionSystem FeedbackUC Evidence
derived-from-uc
+
+ +
+

Branch and Exception Paths

+ + + + + + + +
ConditionPathFeedbackRecoveryUC Evidence
derived-from-uc
+
+ +
+

Open Questions

+
    +
  • [NEEDS CLARIFICATION: ]
  • +
+
+
+ + diff --git a/pyproject.toml b/pyproject.toml index 05a96027dc..fb7d50c8a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ packages = ["src/specify_cli"] "extensions/arch" = "specify_cli/core_pack/extensions/arch" "extensions/discovery" = "specify_cli/core_pack/extensions/discovery" "extensions/git" = "specify_cli/core_pack/extensions/git" +"extensions/inception" = "specify_cli/core_pack/extensions/inception" "extensions/intake" = "specify_cli/core_pack/extensions/intake" "extensions/preview" = "specify_cli/core_pack/extensions/preview" "extensions/repository-governance" = "specify_cli/core_pack/extensions/repository-governance" diff --git a/src/specify_cli/commands/init.py b/src/specify_cli/commands/init.py index 80c5c46877..d65245c933 100644 --- a/src/specify_cli/commands/init.py +++ b/src/specify_cli/commands/init.py @@ -30,6 +30,7 @@ "arch", "discovery", "git", + "inception", "intake", "preview", "repository-governance", diff --git a/tests/extensions/inception/__init__.py b/tests/extensions/inception/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/tests/extensions/inception/__init__.py @@ -0,0 +1 @@ + diff --git a/tests/extensions/inception/test_inception_extension.py b/tests/extensions/inception/test_inception_extension.py new file mode 100644 index 0000000000..e18d63a4fd --- /dev/null +++ b/tests/extensions/inception/test_inception_extension.py @@ -0,0 +1,210 @@ +from pathlib import Path + +from specify_cli.extensions import ExtensionManifest + + +REPO_ROOT = Path(__file__).resolve().parents[3] +EXTENSION_DIR = REPO_ROOT / "extensions" / "inception" + + +def _read(rel_path: str) -> str: + return (EXTENSION_DIR / rel_path).read_text(encoding="utf-8") + + +def _section(text: str, heading: str) -> str: + start = text.index(heading) + next_heading = text.find("\n## ", start + len(heading)) + if next_heading == -1: + return text[start:] + return text[start:next_heading] + + +def _assert_markdown_tables_are_rectangular(markdown: str): + table: list[str] = [] + for line in markdown.splitlines() + [""]: + if line.startswith("|"): + table.append(line) + continue + + if table: + pipe_count = table[0].count("|") + assert pipe_count > 1 + assert all(row.count("|") == pipe_count for row in table), table + table = [] + + +def test_manifest_declares_inception_commands(): + manifest = ExtensionManifest(EXTENSION_DIR / "extension.yml") + + assert manifest.id == "inception" + assert manifest.name == "SDD Inception" + assert [command["name"] for command in manifest.commands] == [ + "speckit.inception.product", + "speckit.inception.arch", + ] + assert [command["file"] for command in manifest.commands] == [ + "commands/speckit.inception.product.md", + "commands/speckit.inception.arch.md", + ] + + +def test_commands_reference_templates_and_inception_paths(): + product = _read("commands/speckit.inception.product.md") + arch = _read("commands/speckit.inception.arch.md") + + for expected in ( + "templates/product/uc-template.md", + "templates/product/wireflow-medium-template.html", + "templates/product/wireflow-high-template.html", + "inception/product/uc.md", + "inception/product/wireflow-medium.html", + "inception/product/wireflow-high.html", + ): + assert expected in product + + for expected in ( + "templates/arch/api-capability-template.md", + "templates/arch/api-poc-template.md", + "templates/arch/system-boundary-template.md", + "templates/arch/domain-model-template.md", + "templates/arch/arch-template.md", + "inception/product/uc.md", + "inception/arch/api-poc-runs/", + ): + assert expected in arch + + +def test_wireflow_uses_full_fidelity_names_not_abbreviated_files(): + combined = "\n".join( + [ + _read("extension.yml"), + _read("README.md"), + _read("commands/speckit.inception.product.md"), + _read("templates/product/wireflow-medium-template.html"), + _read("templates/product/wireflow-high-template.html"), + ] + ) + + assert "wireflow-medium.html" in combined + assert "wireflow-high.html" in combined + assert "wireflow-m.html" not in combined + assert "wireflow-h.html" not in combined + + +def test_api_poc_requires_real_run_confirmation_and_evidence(): + arch = _read("commands/speckit.inception.arch.md") + template = _read("templates/arch/api-poc-template.md") + combined = arch + "\n" + template + + assert "not pseudocode" in arch + assert "real code execution evidence" in arch + assert "Before running any POC code" in arch + for required in ( + "target capability", + "validation hypothesis", + "runtime environment", + "dependencies", + "credential/config needs", + "sample input", + "external service access", + "allowed side effects", + "stop conditions", + ): + assert required in combined + assert "inception/arch/api-poc-runs//" in combined + assert "POC_CONFIRMATION_MISSING" in combined + assert "POC_RUN_EVIDENCE_MISSING" in combined + + +def test_api_capability_requires_technology_selection_matrix(): + arch = _read("commands/speckit.inception.arch.md") + readme = _read("README.md") + template = _read("templates/arch/api-capability-template.md") + combined = arch + "\n" + template + + assert "## Technology Selection Matrix" in template + assert "## Technology Selection Rationale" in template + assert "technology selection matrix" in readme + for expected in ( + "Candidate Option", + "Team Familiarity", + "POC Required", + "Recommended Option", + "Rejected Options", + "Open Questions", + ): + assert expected in template + + for expected in ( + "Extract system capabilities from `uc.md`", + "Candidate technical options", + "Recommended option", + "backup option", + "tradeoff rationale", + "TECH_SELECTION_MISSING", + ): + assert expected in combined + + +def test_arch_templates_keep_tables_rectangular_and_blockers_in_quality_gate(): + api_capability = _read("templates/arch/api-capability-template.md") + api_poc = _read("templates/arch/api-poc-template.md") + arch_command = _read("commands/speckit.inception.arch.md") + + _assert_markdown_tables_are_rectangular(api_capability) + _assert_markdown_tables_are_rectangular(api_poc) + + api_capability_gate = _section(api_capability, "## Quality Gate") + arch_command_gate = _section(arch_command, "## Quality Gates") + + assert "TECH_SELECTION_MISSING" in api_capability_gate + assert "TECH_SELECTION_MISSING" in arch_command_gate + assert "POC_CONFIRMATION_MISSING" in _section(api_poc, "## Quality Gate") + assert "POC_RUN_EVIDENCE_MISSING" in _section(api_poc, "## Quality Gate") + + +def test_arch_template_excludes_mock_strategy(): + arch_command = _read("commands/speckit.inception.arch.md") + arch_template = _read("templates/arch/arch-template.md") + + assert "Mock Strategy" not in arch_template + assert "mock strategy" not in arch_template.lower() + assert "mock strategy section" in arch_command + assert "mock boundaries" not in arch_command + + +def test_arch_template_excludes_standalone_state_model(): + arch_command = _read("commands/speckit.inception.arch.md") + arch_template = _read("templates/arch/arch-template.md") + + assert "## 11. State Model" not in arch_template + assert "State Model" not in arch_template + assert "state ownership, transitions, and invariants" not in arch_template + assert "Do not expand object state details" in arch_template + assert "must not include a standalone state model section" in arch_command + assert "State enumerations, transitions, domain rules, and business invariants belong in `domain-model.md`" in arch_command + assert "state boundaries" not in arch_command + assert "For `arch.md`, reference only the domain-model constraints" in arch_command + + +def test_commands_include_required_blockers_and_scope_guards(): + product = _read("commands/speckit.inception.product.md") + arch = _read("commands/speckit.inception.arch.md") + + for blocker in ( + "OUTPUT_PATH_MISMATCH", + "SOURCE_PRIORITY_VIOLATION", + "SCOPE_LEAK", + "UNSUPPORTED_INFERENCE", + "TEMPLATE_BYPASS", + ): + assert blocker in product + assert blocker in arch + + assert "TECH_SELECTION_MISSING" in arch + assert "EMPTY_PRIMARY_ARTIFACT" in product + assert "EMPTY_PRIMARY_ARTIFACT" in arch + assert "spec.md" in product + assert "plan.md" in arch + assert "openapi.yaml" in arch + assert "source code" in arch diff --git a/tests/integrations/community_defaults.py b/tests/integrations/community_defaults.py index 962940e4e7..7b4d833a08 100644 --- a/tests/integrations/community_defaults.py +++ b/tests/integrations/community_defaults.py @@ -13,6 +13,7 @@ "arch", "discovery", "git", + "inception", "intake", "preview", "repository-governance", @@ -26,6 +27,8 @@ "speckit.git.remote", "speckit.git.initialize", "speckit.git.commit", + "speckit.inception.product", + "speckit.inception.arch", "speckit.intake.visual-design", "speckit.intake.prd", "speckit.intake.test-cases", diff --git a/tests/integrations/test_cli.py b/tests/integrations/test_cli.py index d65f118814..72f07dfa32 100644 --- a/tests/integrations/test_cli.py +++ b/tests/integrations/test_cli.py @@ -1021,7 +1021,7 @@ def test_community_extensions_and_workflow_preset_auto_installed(self, tmp_path) assert result.exit_code == 0, f"init failed: {result.output}" - for extension_id in ("arch", "discovery", "git", "intake", "preview", "repository-governance"): + for extension_id in ("arch", "discovery", "git", "inception", "intake", "preview", "repository-governance"): ext_dir = project / ".specify" / "extensions" / extension_id assert (ext_dir / "extension.yml").exists(), f"{extension_id} was not installed" @@ -1031,6 +1031,7 @@ def test_community_extensions_and_workflow_preset_auto_installed(self, tmp_path) "arch", "discovery", "git", + "inception", "intake", "preview", "repository-governance", @@ -1127,7 +1128,7 @@ def test_git_default_keeps_community_defaults(self, tmp_path): assert result.exit_code == 0, f"init failed: {result.output}" assert (project / ".specify" / "extensions" / "git" / "extension.yml").exists() - for extension_id in ("arch", "discovery", "intake", "preview", "repository-governance"): + for extension_id in ("arch", "discovery", "inception", "intake", "preview", "repository-governance"): ext_dir = project / ".specify" / "extensions" / extension_id assert (ext_dir / "extension.yml").exists(), f"{extension_id} was not installed" diff --git a/tests/test_extensions.py b/tests/test_extensions.py index 153f97259c..8c6f61abe8 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -262,6 +262,32 @@ def test_bundled_default_catalogs_match_manifest(self, extension_id): assert community_entry["download_url"].endswith(f"/refs/tags/v{manifest.version}.zip") assert default_commands == manifest_commands + def test_bundled_inception_catalog_matches_manifest(self): + """Inception is bundled locally but not mirrored into the community catalog.""" + from tests.integrations.community_defaults import DEFAULT_EXTENSION_COMMANDS + + repo_root = Path(__file__).resolve().parent.parent + manifest = ExtensionManifest(repo_root / "extensions" / "inception" / "extension.yml") + bundled_catalog = json.loads( + (repo_root / "extensions" / "catalog.json").read_text(encoding="utf-8") + ) + bundled_entry = bundled_catalog["extensions"]["inception"] + manifest_repository = manifest.data["extension"]["repository"] + manifest_commands = tuple(command["name"] for command in manifest.commands) + default_commands = tuple( + command + for command in DEFAULT_EXTENSION_COMMANDS + if command.startswith("speckit.inception.") + ) + + assert bundled_entry["name"] == manifest.name + assert bundled_entry["version"] == manifest.version + assert bundled_entry["description"] == manifest.description + assert bundled_entry["repository"] == manifest_repository + assert bundled_entry["bundled"] is True + assert bundled_entry["provides"]["commands"] == len(manifest.commands) + assert default_commands == manifest_commands + def test_missing_required_field(self, temp_dir): """Test manifest missing required field.""" import yaml diff --git a/tests/test_presets.py b/tests/test_presets.py index cce89590a6..b3b5c0628a 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -4754,7 +4754,7 @@ def test_community_smoke_checks_wheel_assets_and_extension_dev_reinstall(self): "speckit.implement.receipt.v1.schema.json" ) in verify_run assert ( - 'for extension_id in arch discovery intake preview repository-governance; do' + 'for extension_id in arch discovery inception intake preview repository-governance; do' in verify_run ) assert ( @@ -4763,6 +4763,7 @@ def test_community_smoke_checks_wheel_assets_and_extension_dev_reinstall(self): ) assert "find .claude/skills -maxdepth 1 -type d -name 'speckit-arch-*'" in verify_run assert "find .claude/skills -maxdepth 1 -type d -name 'speckit-discovery-*'" in verify_run + assert "find .claude/skills -maxdepth 1 -type d -name 'speckit-inception-*'" in verify_run assert "find .claude/skills -maxdepth 1 -type d -name 'speckit-intake-*'" in verify_run assert "speckit-preview-wireflow" in verify_run assert "test ! -d .claude/skills/speckit-preview-wireflow" in verify_run @@ -4791,6 +4792,18 @@ def test_community_smoke_checks_wheel_assets_and_extension_dev_reinstall(self): 'test -f .claude/skills/speckit-discovery-contract/SKILL.md' in verify_run ) + assert ( + 'test -f .claude/skills/speckit-inception-product/SKILL.md' + in verify_run + ) + assert ( + 'test -f .claude/skills/speckit-inception-arch/SKILL.md' + in verify_run + ) + assert ( + 'grep -q "API POC Workflow" .claude/skills/speckit-inception-arch/SKILL.md' + in verify_run + ) assert ( 'test -f .claude/skills/speckit-intake-visual-design/SKILL.md' in verify_run