diff --git a/presets/catalog.community.json b/presets/catalog.community.json index 0455818e78..19561d118b 100644 --- a/presets/catalog.community.json +++ b/presets/catalog.community.json @@ -671,11 +671,11 @@ "workflow-preset": { "name": "Workflow Preset", "id": "workflow-preset", - "version": "1.3.10", + "version": "1.3.11", "description": "Behavior-first specification, design artifacts, and agent-native handoff orchestration", "author": "bigsmartben", "repository": "https://github.com/bigsmartben/spec-kit-workflow-preset", - "download_url": "https://github.com/bigsmartben/spec-kit-workflow-preset/releases/download/v1.3.10/spec-kit-workflow-preset-v1.3.10.zip", + "download_url": "https://github.com/bigsmartben/spec-kit-workflow-preset/releases/download/v1.3.11/spec-kit-workflow-preset-v1.3.11.zip", "homepage": "https://github.com/bigsmartben/spec-kit-workflow-preset", "documentation": "https://github.com/bigsmartben/spec-kit-workflow-preset/blob/main/README.md", "license": "MIT", diff --git a/presets/catalog.json b/presets/catalog.json index 180d6eee6d..011f8f60f0 100644 --- a/presets/catalog.json +++ b/presets/catalog.json @@ -29,7 +29,7 @@ "workflow-preset": { "name": "Workflow Preset", "id": "workflow-preset", - "version": "1.3.10", + "version": "1.3.11", "description": "Behavior-first specification, design artifacts, and agent-native handoff orchestration", "author": "bigsmartben", "repository": "https://github.com/bigsmartben/spec-kit-workflow-preset", diff --git a/presets/workflow-preset/AGENTS.md b/presets/workflow-preset/AGENTS.md index 1de13d5efd..b1a159b9dc 100644 --- a/presets/workflow-preset/AGENTS.md +++ b/presets/workflow-preset/AGENTS.md @@ -24,6 +24,21 @@ This repository is a Spec Kit community preset named `workflow-preset`. - Validation strategy is derived by `/speckit.tasks` from behavior contracts, interface contracts, `research.md`, and `quickstart.md`; do not add standalone `test-plan.md` without intentionally updating the preset contract. - Do not move product requirements out of `spec.md`, domain model details out of `data-model.md`, interface schemas out of `contracts/`, or validation run guidance out of `quickstart.md`. +## Integration Boundary + +- This repository owns the `workflow-preset` source, tests, release artifact, + and source documentation. +- Do not open pull requests from this repository directly to `github/spec-kit`. +- Do not push branches to `github/spec-kit` or add workflow automation that + targets `github/spec-kit` for pull requests, repository dispatches, or direct + writes. +- If a Spec Kit catalog or bundled snapshot update is needed, target the + `bigsmartben/spec-kit` integration fork first. The integration fork owns any + downstream pull request to `github/spec-kit`. +- Source releases must provide source-backed metadata for the integration fork: + repository URL, release version, source commit SHA, download URL, and + validation evidence. + ## Handoff Boundaries When working from a generated handoff JSON: diff --git a/presets/workflow-preset/CHANGELOG.md b/presets/workflow-preset/CHANGELOG.md index a8be2d8538..3e4d33cbbe 100644 --- a/presets/workflow-preset/CHANGELOG.md +++ b/presets/workflow-preset/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Added constitution governance coverage for the fixed R/M/U/O mapping and Architecture SSOT boundary, with preset manifest, documentation, contract tests, and install smoke checks aligned to the constitution template. +- Fixed the preset artifact integration workflow to update both bundled and community catalog metadata before opening the `bigsmartben/spec-kit` fork PR. + ## 1.3.10 - Tightened implement handoff, manifest, and receipt shard IDs to the `S00-capability-00` format. diff --git a/presets/workflow-preset/README.md b/presets/workflow-preset/README.md index d5ae5c1d2e..5f87d87445 100644 --- a/presets/workflow-preset/README.md +++ b/presets/workflow-preset/README.md @@ -2,7 +2,7 @@ This Spec Kit community preset combines behavior-first specification, design-aware planning, scoped change governance, and agent-native handoff orchestration. -It wraps `/speckit.specify`, `/speckit.clarify`, `/speckit.checklist`, `/speckit.constitution`, `/speckit.plan`, `/speckit.tasks`, and `/speckit.analyze` with BDD, NFR, and applicable Visual Fidelity readiness gates, Change Scope Granularity governance, Phase 0 behavior projection, optional design artifacts for internal object design and service sequencing, visual restoration traceability, and task-time validation strategy derivation. It replaces `/speckit.implement` with a Core Agent, Vertical Planner Agent, and Worker Agent orchestration contract that writes handoffs to disk. +It wraps `/speckit.specify`, `/speckit.clarify`, `/speckit.checklist`, `/speckit.constitution`, `/speckit.plan`, `/speckit.tasks`, and `/speckit.analyze` with BDD, NFR, and applicable Visual Fidelity readiness gates, Change Scope Granularity and Architecture SSOT governance, Phase 0 behavior projection, optional design artifacts for internal object design and service sequencing, visual restoration traceability, and task-time validation strategy derivation. It replaces `/speckit.implement` with a Core Agent, Vertical Planner Agent, and Worker Agent orchestration contract that writes handoffs to disk. ## Goal @@ -48,8 +48,10 @@ Requirement capabilities: Governance capabilities: -- Wraps `/speckit.constitution` and the constitution template with Change Scope Granularity governance. -- Defines the R/M/U/O model: Repository or Workspace as environment context, Module or Capability as the hard outer boundary, Unit or Design Object as the primary planning boundary, and Operation or Detail as execution detail. +- Wraps `/speckit.constitution` and the constitution template with Change Scope Granularity and Architecture SSOT governance. +- Defines the fixed R/M/U/O model: R is Repository / Workspace, M is Module / Capability, U is Unit / Design Object, and O is Operation / Detail. These letters must not be renamed or expanded with alternate nouns. +- Blocks constitution writes when a generated draft changes the fixed R/M/U/O mapping. +- Routes architecture decisions, domain facts, object design, flows, and interface contracts to architecture SSOT artifacts instead of embedding concrete implementation content in ratified constitution principles. - Requires planning to lock M + U before execution maps units to concrete paths. - Treats unresolved U -> path mapping as a context gap instead of widening execution to repository-wide or broad module scope. @@ -119,7 +121,7 @@ Context-load controls: ## Workflow -1. `/speckit.constitution` preserves Change Scope Granularity when the project constitution is created or updated. +1. `/speckit.constitution` preserves Change Scope Granularity and Architecture SSOT governance when the project constitution is created or updated. 2. `/speckit.specify` keeps the core requirements output in `spec.md`. 3. `/speckit.clarify` resolves requirement ambiguity in `spec.md`. 4. `/speckit.checklist` checks BDD, NFR, and applicable Visual Fidelity readiness directly from `spec.md` and blocks planning when readiness gaps remain. @@ -149,7 +151,7 @@ Context-load controls: Release install: ```bash -specify preset add workflow-preset --from https://github.com/bigsmartben/spec-kit-workflow-preset/releases/download/v1.3.10/spec-kit-workflow-preset-v1.3.10.zip +specify preset add workflow-preset --from https://github.com/bigsmartben/spec-kit-workflow-preset/releases/download/v1.3.11/spec-kit-workflow-preset-v1.3.11.zip ``` Local development install: @@ -477,7 +479,7 @@ Release install smoke validation is intentionally owned by GitHub Actions, not b After tagging a release, validate archive installation: ```bash -specify preset add workflow-preset --from https://github.com/bigsmartben/spec-kit-workflow-preset/releases/download/v1.3.10/spec-kit-workflow-preset-v1.3.10.zip +specify preset add workflow-preset --from https://github.com/bigsmartben/spec-kit-workflow-preset/releases/download/v1.3.11/spec-kit-workflow-preset-v1.3.11.zip ``` ## Source Rationale diff --git a/presets/workflow-preset/commands/speckit.constitution.md b/presets/workflow-preset/commands/speckit.constitution.md index c172428584..7b25721ed7 100644 --- a/presets/workflow-preset/commands/speckit.constitution.md +++ b/presets/workflow-preset/commands/speckit.constitution.md @@ -1,5 +1,5 @@ --- -description: Wrap core constitution updates with change scope granularity governance. +description: Wrap core constitution updates with change scope granularity and architecture SSOT governance. strategy: wrap --- @@ -9,8 +9,46 @@ Always preserve the Change Scope Granularity principle in `.specify/memory/const Constitution updates must not remove, weaken, or contradict the principle's R/M/U/O model, boundary timing, or context-gap rule. Keep the principle normative, including `Planning locks M + U`. +The R/M/U/O letter mapping is fixed and MUST remain exact: + +- R: Repository / Workspace. Environment only; too broad for scoped changes. +- M: Module / Capability. Hard outer boundary. +- U: Unit / Design Object. Primary planning boundary. +- O: Operation / Detail. Execution detail. + +Do not paraphrase, expand, rename, translate, or substitute these letters with other nouns such as Requirement, Model, User/API Interface, or Operations. + +If a drafted constitution changes this mapping, discard the draft and report blocker code `CONSTITUTION_RMUO_MAPPING_DRIFT` instead of writing `.specify/memory/constitution.md`. + +When producing the Sync Impact Report, report template or command file status only after checking the actual path. If a path cannot be checked, report `CONSTITUTION_TEMPLATE_STATUS_UNCHECKED`; do not report it as missing. +If the root `.specify/templates/constitution-template.md` is still the core placeholder, do not treat that as the workflow-preset template being absent. Resolve or check `.specify/presets/workflow-preset/templates/constitution-template.md` before reporting preset template status. + +## Architecture SSOT Boundary + +Ratified constitution principles must be durable governance rules, not architecture fact storage. +Architecture decisions, domain facts, object design, flows, and interface contracts belong in their architecture SSOT artifacts: + +- `specs//data-model.md`: domain model and domain facts. +- `specs//class-diagram.md`: object, module, adapter, and internal design structure. +- `specs//contracts/sequences.md`: cross-boundary flow, sequencing, async, retry, rollback, and failure paths. +- `specs//contracts/`: interface and message contracts. +- `specs//research.md`: architecture decisions and tradeoffs that need evidence. + +Constitution updates MUST NOT capture, discover, extract, migrate, store, validate, or repair architecture facts. +If user input includes architecture facts, do not embed them in ratified principles. +In the Sync Impact Report, report blocker code `CONSTITUTION_ARCH_SSOT_GAP` and name the responsible workflow-preset SSOT artifact type when it can be classified. +Do not write concrete `specs//...` paths, check those paths, create or update those artifacts, or copy concrete implementation facts, temporary repository observations, or module responsibility inventories into ratified constitution principles. + +## Architecture SSOT Compliance + +Always preserve the Architecture SSOT Compliance principle in `.specify/memory/constitution.md`. + +Ratified constitution principles define the compliance rule only. Concrete architecture decisions, domain facts, object design, flows, and interface contracts MUST remain in their Architecture SSOT artifacts. + +Planning outputs MUST comply with existing Architecture SSOT artifacts. Planning MUST NOT contradict, relocate, weaken, or silently replace architecture SSOT content. If planning cannot produce outputs that comply with existing Architecture SSOT artifacts, it must report a planning blocker instead of generating inconsistent artifacts. + {CORE_TEMPLATE} ## Change Scope Granularity Reporting -Before finishing, report whether the constitution includes the Change Scope Granularity principle and still states `Planning locks M + U`. +Before finishing, report whether the constitution includes the Change Scope Granularity principle, still states `Planning locks M + U`, preserves the exact R/M/U/O letter mapping, routes architecture decisions, domain facts, object design, flows, and interface contracts to workflow-preset SSOT artifact types instead of embedding concrete implementation content in ratified principles, and requires planning outputs to comply with existing Architecture SSOT artifacts. diff --git a/presets/workflow-preset/preset.yml b/presets/workflow-preset/preset.yml index 6dc96077b4..c0d01dbeea 100644 --- a/presets/workflow-preset/preset.yml +++ b/presets/workflow-preset/preset.yml @@ -2,7 +2,7 @@ schema_version: '1.0' preset: id: workflow-preset name: Workflow Preset - version: 1.3.10 + version: 1.3.11 description: Behavior-first specification, design artifacts, and agent-native handoff orchestration author: bigsmartben @@ -21,7 +21,8 @@ provides: - type: template name: constitution-template file: templates/constitution-template.md - description: Add change scope granularity governance to the constitution template + description: Add change scope granularity and architecture SSOT governance to + the constitution template replaces: constitution-template strategy: wrap - type: template @@ -73,7 +74,8 @@ provides: - type: command name: speckit.constitution file: commands/speckit.constitution.md - description: Wrap core constitution updates with change scope granularity governance + description: Wrap core constitution updates with change scope granularity and + architecture SSOT governance replaces: speckit.constitution strategy: wrap - type: command diff --git a/presets/workflow-preset/templates/constitution-template.md b/presets/workflow-preset/templates/constitution-template.md index d6ae9418e4..70a2b30388 100644 --- a/presets/workflow-preset/templates/constitution-template.md +++ b/presets/workflow-preset/templates/constitution-template.md @@ -9,8 +9,31 @@ Spec Kit planning and execution MUST use R/M/U/O scope granularity: - U: Unit / Design Object. Primary planning boundary. - O: Operation / Detail. Execution detail. +The R/M/U/O letter mapping is fixed. Do not paraphrase, expand, rename, translate, or substitute these letters with other nouns. + Planning locks M + U. Execution maps U -> concrete paths -> O-level changes. If U -> concrete paths cannot be determined, report a context gap. Do not widen scope to R or broad M. This principle applies from planning onward. Requirement specification, clarification, and checklist readiness MUST NOT infer M/U/O boundaries. + +## Architecture SSOT Boundary + +Ratified constitution principles are durable governance rules, not architecture fact storage. +Architecture decisions, domain facts, object design, flows, and interface contracts belong in their architecture SSOT artifacts: + +- `specs//data-model.md`: domain model and domain facts. +- `specs//class-diagram.md`: object, module, adapter, and internal design structure. +- `specs//contracts/sequences.md`: cross-boundary flow, sequencing, async, retry, rollback, and failure paths. +- `specs//contracts/`: interface and message contracts. +- `specs//research.md`: architecture decisions and tradeoffs that need evidence. + +Constitution principles may reference these SSOT artifact types, but must not copy concrete implementation facts, temporary repository observations, or module responsibility inventories into ratified governance text. + +## Architecture SSOT Compliance + +Ratified constitution principles define the compliance rule only. Concrete architecture decisions, domain facts, object design, flows, and interface contracts MUST remain in their Architecture SSOT artifacts. + +Planning outputs MUST comply with existing Architecture SSOT artifacts. +Planning MUST NOT contradict, relocate, weaken, or silently replace architecture SSOT content. +If planning cannot produce outputs that comply with existing Architecture SSOT artifacts, report a planning blocker instead of generating inconsistent artifacts. diff --git a/presets/workflow-preset/tests/test_preset_contract.py b/presets/workflow-preset/tests/test_preset_contract.py index 1fc2caa14f..ddfd05ccea 100644 --- a/presets/workflow-preset/tests/test_preset_contract.py +++ b/presets/workflow-preset/tests/test_preset_contract.py @@ -577,7 +577,7 @@ def test_preset_manifest_contract(self) -> None: self.assertEqual("1.0", data["schema_version"]) self.assertEqual("workflow-preset", data["preset"]["id"]) self.assertEqual("Workflow Preset", data["preset"]["name"]) - self.assertEqual("1.3.10", data["preset"]["version"]) + self.assertEqual("1.3.11", data["preset"]["version"]) self.assertEqual( "Behavior-first specification, design artifacts, and agent-native handoff orchestration", data["preset"]["description"], @@ -696,11 +696,11 @@ def test_preset_manifest_contract(self) -> None: self.assertEqual("wrap", command["strategy"]) self.assertEqual( - "Wrap core constitution updates with change scope granularity governance", + "Wrap core constitution updates with change scope granularity and architecture SSOT governance", entries["speckit.constitution"]["description"], ) self.assertEqual( - "Add change scope granularity governance to the constitution template", + "Add change scope granularity and architecture SSOT governance to the constitution template", entries["constitution-template"]["description"], ) @@ -833,15 +833,49 @@ def test_plan_visual_substage_enhancement_contract(self) -> None: self.assertIn("contracts formalize visual interaction and state constraints", document) self.assertIn("contracts/sequences.md records visual state flow only when it affects cross-boundary sequencing", document) + self.assertIn( + "fixed R/M/U/O model: R is Repository / Workspace, M is Module / Capability, U is Unit / Design Object, and O is Operation / Detail", + readme, + ) + self.assertIn( + "Blocks constitution writes when a generated draft changes the fixed R/M/U/O mapping", + readme, + ) + self.assertIn( + "Routes architecture decisions, domain facts, object design, flows, and interface contracts to architecture SSOT artifacts instead of embedding concrete implementation content in ratified constitution principles", + readme, + ) + def test_constitution_change_scope_granularity_contract(self) -> None: command = CONSTITUTION_COMMAND_PATH.read_text(encoding="utf-8") template = CONSTITUTION_TEMPLATE_PATH.read_text(encoding="utf-8") + exact_mapping = [ + "R: Repository / Workspace. Environment only; too broad for scoped changes.", + "M: Module / Capability. Hard outer boundary.", + "U: Unit / Design Object. Primary planning boundary.", + "O: Operation / Detail. Execution detail.", + ] + forbidden_mapping_drift = [ + "R, Requirement", + "R: Requirement", + "M, Model", + "M: Model", + "U, User/API Interface", + "U: User/API Interface", + "O, Operations", + "O: Operations", + ] + for document in (command, template): self.assertIn("{CORE_TEMPLATE}", document) self.assertIn("Change Scope Granularity", document) self.assertIn("R/M/U/O", document) self.assertIn("Planning locks M + U", document) + for mapping in exact_mapping: + self.assertIn(mapping, document) + for forbidden in forbidden_mapping_drift: + self.assertNotIn(forbidden, document) self.assertIn("strategy: wrap", command) self.assertIn("Spec Kit planning and execution MUST use R/M/U/O scope granularity", template) @@ -849,6 +883,64 @@ def test_constitution_change_scope_granularity_contract(self) -> None: self.assertIn("Requirement specification, clarification, and checklist readiness MUST NOT infer M/U/O boundaries", template) self.assertIn("preserve the Change Scope Granularity principle", command) self.assertIn("must not remove, weaken, or contradict", command) + self.assertIn("The R/M/U/O letter mapping is fixed and MUST remain exact", command) + self.assertIn("preserves the exact R/M/U/O letter mapping", command) + self.assertIn("CONSTITUTION_RMUO_MAPPING_DRIFT", command) + self.assertIn("CONSTITUTION_TEMPLATE_STATUS_UNCHECKED", command) + self.assertIn("do not report it as missing", command) + self.assertIn("do not treat that as the workflow-preset template being absent", command) + self.assertIn("Architecture SSOT Boundary", command) + self.assertIn("Architecture SSOT Compliance", command) + self.assertIn("Ratified constitution principles must be durable governance rules, not architecture fact storage", command) + self.assertIn( + "Architecture decisions, domain facts, object design, flows, and interface contracts belong in their architecture SSOT artifacts", + command, + ) + self.assertIn("specs//data-model.md", command) + self.assertIn("specs//class-diagram.md", command) + self.assertIn("specs//contracts/sequences.md", command) + self.assertIn("specs//contracts/", command) + self.assertIn("specs//research.md", command) + self.assertIn( + "MUST NOT capture, discover, extract, migrate, store, validate, or repair architecture facts", + command, + ) + self.assertIn("do not embed them in ratified principles", command) + self.assertIn("name the responsible workflow-preset SSOT artifact type", command) + self.assertIn("Do not write concrete `specs//...` paths", command) + self.assertIn("check those paths", command) + self.assertIn("create or update those artifacts", command) + self.assertIn("CONSTITUTION_ARCH_SSOT_GAP", command) + self.assertIn("copy concrete implementation facts", command) + self.assertIn("Planning outputs MUST comply with existing Architecture SSOT artifacts", command) + self.assertIn("MUST NOT contradict, relocate, weaken, or silently replace architecture SSOT content", command) + self.assertIn("requires planning outputs to comply with existing Architecture SSOT artifacts", command) + self.assertIn( + "routes architecture decisions, domain facts, object design, flows, and interface contracts to workflow-preset SSOT artifact types", + command, + ) + self.assertNotIn("unless the current Spec Kit context already provides an existing feature path", command) + self.assertNotIn("required existing SSOT path is absent", command) + self.assertIn("The R/M/U/O letter mapping is fixed", template) + self.assertIn("Architecture SSOT Boundary", template) + self.assertIn("Architecture SSOT Compliance", template) + self.assertIn("Ratified constitution principles are durable governance rules, not architecture fact storage", template) + self.assertIn( + "Architecture decisions, domain facts, object design, flows, and interface contracts belong in their architecture SSOT artifacts", + template, + ) + self.assertIn("specs//data-model.md", template) + self.assertIn("specs//class-diagram.md", template) + self.assertIn("specs//contracts/sequences.md", template) + self.assertIn("specs//contracts/", template) + self.assertIn("specs//research.md", template) + self.assertIn("may reference these SSOT artifact types", template) + self.assertIn( + "must not copy concrete implementation facts, temporary repository observations, or module responsibility inventories", + template, + ) + self.assertIn("Planning outputs MUST comply with existing Architecture SSOT artifacts", template) + self.assertIn("Planning MUST NOT contradict, relocate, weaken, or silently replace architecture SSOT content", template) def test_change_scope_granularity_stage_references(self) -> None: plan = PLAN_COMMAND_PATH.read_text(encoding="utf-8") @@ -859,6 +951,8 @@ def test_change_scope_granularity_stage_references(self) -> None: self.assertIn("Apply the constitution's Change Scope Granularity principle.", plan) self.assertIn("During planning, lock the change scope to `M + U`", plan) self.assertIn("Do not lock operation-level implementation details or concrete write paths.", plan) + self.assertNotIn("Architecture SSOT Compliance", plan) + self.assertNotIn("PLANNING_ARCH_SSOT_CONFLICT", plan) self.assertIn("Preserve the planned `M + U` scope", tasks) self.assertIn("Do not generate execution metadata or write-path fields.", tasks) @@ -4270,6 +4364,7 @@ def test_github_actions_artifact_release_and_integration_pr_workflow(self) -> No 'PATH="${GITHUB_WORKSPACE}/.venv-specify-smoke/bin:${PATH}"', 'project_dir="$(mktemp -d "${RUNNER_TEMP}/workflow-preset-smoke.XXXXXX")"', 'resolve_out="${RUNNER_TEMP}/plan-template-resolve.txt"', + 'constitution_resolve_out="${RUNNER_TEMP}/constitution-template-resolve.txt"', "PIP_CONFIG_FILE: /dev/null", 'PYTEST_ADDOPTS: ""', 'export TMPDIR="${RUNNER_TEMP}"', @@ -4279,6 +4374,11 @@ def test_github_actions_artifact_release_and_integration_pr_workflow(self) -> No "specify preset remove workflow-preset", "specify preset add --dev", "specify preset resolve plan-template", + "specify preset resolve constitution-template", + "R: Repository / Workspace", + "M: Module / Capability", + "U: Unit / Design Object", + "O: Operation / Detail", ".claude/skills/speckit-implement/SKILL.md", "SPEC_KIT_FORK_PR_TOKEN", "bigsmartben/spec-kit", @@ -4286,6 +4386,10 @@ def test_github_actions_artifact_release_and_integration_pr_workflow(self) -> No "gh pr create", "gh pr edit", "WORKFLOW_PRESET_DOWNLOAD_URL", + "presets/catalog.community.json", + "community_catalog_path", + "community_catalog", + "download_url", 'assert entry\\["version"\\] == "[0-9]+\\.[0-9]+\\.[0-9]+"', "tests/test_presets.py", "tests/contracts/speckit-cross-agent-subagents.md", diff --git a/tests/test_presets.py b/tests/test_presets.py index 037981742f..df87032ebf 100644 --- a/tests/test_presets.py +++ b/tests/test_presets.py @@ -4530,7 +4530,7 @@ def test_workflow_preset_catalog_matches_manifest(self): assert catalog_updated_at >= datetime(2026, 6, 18, tzinfo=timezone.utc) assert entry["bundled"] is True - assert entry["version"] == "1.3.10" + assert entry["version"] == "1.3.11" assert entry["version"] == manifest["preset"]["version"] assert entry["repository"] == manifest["preset"]["repository"] assert entry["requires"]["speckit_version"] == manifest["requires"]["speckit_version"]