specweave 0.22.13 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/README.md +2 -2
- package/CLAUDE.md +447 -52
- package/README.md +33 -10
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js +1 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +4 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.d.ts +9 -0
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js +10 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js.map +1 -1
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js +2 -2
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/types.d.ts +1 -1
- package/dist/src/cli/commands/import-external.d.ts +22 -0
- package/dist/src/cli/commands/import-external.d.ts.map +1 -0
- package/dist/src/cli/commands/import-external.js +282 -0
- package/dist/src/cli/commands/import-external.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +359 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/github-repo-selector.d.ts +59 -0
- package/dist/src/cli/helpers/github-repo-selector.d.ts.map +1 -0
- package/dist/src/cli/helpers/github-repo-selector.js +265 -0
- package/dist/src/cli/helpers/github-repo-selector.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +41 -24
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/config/import-config.d.ts +69 -0
- package/dist/src/config/import-config.d.ts.map +1 -0
- package/dist/src/config/import-config.js +136 -0
- package/dist/src/config/import-config.js.map +1 -0
- package/dist/src/config/types.d.ts +26 -26
- package/dist/src/core/increment/ac-status-manager.d.ts.map +1 -1
- package/dist/src/core/increment/ac-status-manager.js +4 -2
- package/dist/src/core/increment/ac-status-manager.js.map +1 -1
- package/dist/src/core/increment/completion-validator.d.ts +30 -1
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +151 -3
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.d.ts +25 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +130 -3
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.d.ts +37 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +262 -18
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts +17 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +25 -0
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +16 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +56 -1
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts +2 -2
- package/dist/src/core/living-docs/task-project-specific-generator.js +2 -2
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts +2 -2
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.js +3 -15
- package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +3 -6
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +4 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/spec-content-sync.js +139 -4
- package/dist/src/core/spec-content-sync.js.map +1 -1
- package/dist/src/core/spec-task-mapper.d.ts.map +1 -1
- package/dist/src/core/spec-task-mapper.js +9 -8
- package/dist/src/core/spec-task-mapper.js.map +1 -1
- package/dist/src/core/status-line-validator.d.ts +63 -0
- package/dist/src/core/status-line-validator.d.ts.map +1 -0
- package/dist/src/core/status-line-validator.js +253 -0
- package/dist/src/core/status-line-validator.js.map +1 -0
- package/dist/src/core/sync/bidirectional-engine.d.ts +10 -1
- package/dist/src/core/sync/bidirectional-engine.d.ts.map +1 -1
- package/dist/src/core/sync/bidirectional-engine.js +10 -1
- package/dist/src/core/sync/bidirectional-engine.js.map +1 -1
- package/dist/src/core/sync/profile-manager.d.ts.map +1 -1
- package/dist/src/core/sync/profile-manager.js +3 -0
- package/dist/src/core/sync/profile-manager.js.map +1 -1
- package/dist/src/core/sync/project-context.d.ts.map +1 -1
- package/dist/src/core/sync/project-context.js +3 -0
- package/dist/src/core/sync/project-context.js.map +1 -1
- package/dist/src/core/sync/status-sync-engine.d.ts +1 -1
- package/dist/src/core/sync/status-sync-engine.js +1 -1
- package/dist/src/core/sync/sync-event-logger.d.ts +15 -1
- package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -1
- package/dist/src/core/sync/sync-event-logger.js +39 -1
- package/dist/src/core/sync/sync-event-logger.js.map +1 -1
- package/dist/src/core/types/origin-metadata.d.ts +153 -0
- package/dist/src/core/types/origin-metadata.d.ts.map +1 -0
- package/dist/src/core/types/origin-metadata.js +166 -0
- package/dist/src/core/types/origin-metadata.js.map +1 -0
- package/dist/src/core/types/sync-config-validator.d.ts +57 -0
- package/dist/src/core/types/sync-config-validator.d.ts.map +1 -0
- package/dist/src/core/types/sync-config-validator.js +116 -0
- package/dist/src/core/types/sync-config-validator.js.map +1 -0
- package/dist/src/core/types/sync-profile.d.ts +8 -2
- package/dist/src/core/types/sync-profile.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.js.map +1 -1
- package/dist/src/core/types/sync-settings.d.ts +73 -0
- package/dist/src/core/types/sync-settings.d.ts.map +1 -0
- package/dist/src/core/types/sync-settings.js +90 -0
- package/dist/src/core/types/sync-settings.js.map +1 -0
- package/dist/src/core/utils/permission-checker.d.ts +100 -0
- package/dist/src/core/utils/permission-checker.d.ts.map +1 -0
- package/dist/src/core/utils/permission-checker.js +166 -0
- package/dist/src/core/utils/permission-checker.js.map +1 -0
- package/dist/src/generators/spec/spec-parser.js +3 -3
- package/dist/src/generators/spec/spec-parser.js.map +1 -1
- package/dist/src/generators/spec/task-parser.js +4 -4
- package/dist/src/generators/spec/task-parser.js.map +1 -1
- package/dist/src/id-generators/task-id-generator.d.ts +96 -0
- package/dist/src/id-generators/task-id-generator.d.ts.map +1 -0
- package/dist/src/id-generators/task-id-generator.js +143 -0
- package/dist/src/id-generators/task-id-generator.js.map +1 -0
- package/dist/src/id-generators/us-id-generator.d.ts +96 -0
- package/dist/src/id-generators/us-id-generator.d.ts.map +1 -0
- package/dist/src/id-generators/us-id-generator.js +143 -0
- package/dist/src/id-generators/us-id-generator.js.map +1 -0
- package/dist/src/importers/ado-importer.d.ts +43 -0
- package/dist/src/importers/ado-importer.d.ts.map +1 -0
- package/dist/src/importers/ado-importer.js +234 -0
- package/dist/src/importers/ado-importer.js.map +1 -0
- package/dist/src/importers/duplicate-detector.d.ts +107 -0
- package/dist/src/importers/duplicate-detector.d.ts.map +1 -0
- package/dist/src/importers/duplicate-detector.js +189 -0
- package/dist/src/importers/duplicate-detector.js.map +1 -0
- package/dist/src/importers/external-importer.d.ts +96 -0
- package/dist/src/importers/external-importer.d.ts.map +1 -0
- package/dist/src/importers/external-importer.js +13 -0
- package/dist/src/importers/external-importer.js.map +1 -0
- package/dist/src/importers/github-importer.d.ts +37 -0
- package/dist/src/importers/github-importer.d.ts.map +1 -0
- package/dist/src/importers/github-importer.js +161 -0
- package/dist/src/importers/github-importer.js.map +1 -0
- package/dist/src/importers/import-coordinator.d.ts +105 -0
- package/dist/src/importers/import-coordinator.d.ts.map +1 -0
- package/dist/src/importers/import-coordinator.js +224 -0
- package/dist/src/importers/import-coordinator.js.map +1 -0
- package/dist/src/importers/item-converter.d.ts +96 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -0
- package/dist/src/importers/item-converter.js +246 -0
- package/dist/src/importers/item-converter.js.map +1 -0
- package/dist/src/importers/jira-importer.d.ts +42 -0
- package/dist/src/importers/jira-importer.d.ts.map +1 -0
- package/dist/src/importers/jira-importer.js +221 -0
- package/dist/src/importers/jira-importer.js.map +1 -0
- package/dist/src/importers/rate-limiter.d.ts +128 -0
- package/dist/src/importers/rate-limiter.d.ts.map +1 -0
- package/dist/src/importers/rate-limiter.js +200 -0
- package/dist/src/importers/rate-limiter.js.map +1 -0
- package/dist/src/init/compliance/types.d.ts +2 -2
- package/dist/src/init/repo/types.d.ts +2 -2
- package/dist/src/integrations/ado/ado-client.d.ts +6 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +23 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-client.d.ts +6 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +38 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.d.ts +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +149 -0
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -0
- package/dist/src/living-docs/fs-id-allocator.js +325 -0
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -0
- package/dist/src/living-docs/id-registry.d.ts +124 -0
- package/dist/src/living-docs/id-registry.d.ts.map +1 -0
- package/dist/src/living-docs/id-registry.js +230 -0
- package/dist/src/living-docs/id-registry.js.map +1 -0
- package/dist/src/progress/us-progress-tracker.d.ts +68 -0
- package/dist/src/progress/us-progress-tracker.d.ts.map +1 -0
- package/dist/src/progress/us-progress-tracker.js +120 -0
- package/dist/src/progress/us-progress-tracker.js.map +1 -0
- package/dist/src/sync/external-item-sync-service.d.ts +150 -0
- package/dist/src/sync/external-item-sync-service.d.ts.map +1 -0
- package/dist/src/sync/external-item-sync-service.js +241 -0
- package/dist/src/sync/external-item-sync-service.js.map +1 -0
- package/dist/src/sync/format-preservation-sync.d.ts +90 -0
- package/dist/src/sync/format-preservation-sync.d.ts.map +1 -0
- package/dist/src/sync/format-preservation-sync.js +173 -0
- package/dist/src/sync/format-preservation-sync.js.map +1 -0
- package/dist/src/sync/index.d.ts +8 -0
- package/dist/src/sync/index.d.ts.map +1 -0
- package/dist/src/sync/index.js +6 -0
- package/dist/src/sync/index.js.map +1 -0
- package/dist/src/sync/sync-coordinator.d.ts +49 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -0
- package/dist/src/sync/sync-coordinator.js +248 -0
- package/dist/src/sync/sync-coordinator.js.map +1 -0
- package/dist/src/sync/sync-metadata.d.ts +75 -0
- package/dist/src/sync/sync-metadata.d.ts.map +1 -0
- package/dist/src/sync/sync-metadata.js +100 -0
- package/dist/src/sync/sync-metadata.js.map +1 -0
- package/dist/src/types/living-docs-us-file.d.ts +63 -0
- package/dist/src/types/living-docs-us-file.d.ts.map +1 -0
- package/dist/src/types/living-docs-us-file.js +27 -0
- package/dist/src/types/living-docs-us-file.js.map +1 -0
- package/dist/src/validators/format-preservation-validator.d.ts +127 -0
- package/dist/src/validators/format-preservation-validator.d.ts.map +1 -0
- package/dist/src/validators/format-preservation-validator.js +187 -0
- package/dist/src/validators/format-preservation-validator.js.map +1 -0
- package/package.json +3 -2
- package/plugins/specweave/.claude-plugin/plugin.json +36 -2
- package/plugins/specweave/agents/architect/AGENT.md +11 -2
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +81 -25
- package/plugins/specweave/commands/specweave-archive-features.md +11 -1
- package/plugins/specweave/commands/specweave-import-external.md +407 -0
- package/plugins/specweave/commands/specweave-progress.md +45 -97
- package/plugins/specweave/hooks/post-edit-spec.sh +41 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +168 -26
- package/plugins/specweave/hooks/post-increment-planning.sh +148 -4
- package/plugins/specweave/hooks/post-spec-update.sh +0 -0
- package/plugins/specweave/hooks/post-task-completion.sh +75 -5
- package/plugins/specweave/hooks/post-write-spec.sh +37 -0
- package/plugins/specweave/lib/hooks/auto-transition.js +1 -1
- package/plugins/specweave/lib/hooks/auto-transition.ts +1 -1
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js +1 -1
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +1 -1
- package/plugins/specweave/lib/hooks/sync-cache.js +294 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js +67 -2
- package/plugins/specweave/lib/hooks/sync-us-tasks.js +200 -14
- package/plugins/specweave/lib/hooks/translate-file.js +1 -1
- package/plugins/specweave/lib/hooks/translate-file.ts +1 -1
- package/plugins/specweave/lib/hooks/update-ac-status.js +1 -1
- package/plugins/specweave/lib/hooks/update-ac-status.ts +1 -1
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.d.ts +115 -0
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js +345 -0
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.d.ts +106 -0
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js +220 -0
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.d.ts +60 -0
- package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js +192 -0
- package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.d.ts +52 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +276 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +163 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +541 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +157 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.js +191 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.js.map +1 -0
- package/plugins/specweave/lib/vendor/generators/spec/task-parser.d.ts +95 -0
- package/plugins/specweave/lib/vendor/generators/spec/task-parser.js +301 -0
- package/plugins/specweave/lib/vendor/generators/spec/task-parser.js.map +1 -0
- package/plugins/specweave/lib/vendor/utils/logger.d.ts +48 -0
- package/plugins/specweave/lib/vendor/utils/logger.js +53 -0
- package/plugins/specweave/lib/vendor/utils/logger.js.map +1 -0
- package/plugins/specweave/lib/vendor/utils/translation.d.ts +187 -0
- package/plugins/specweave/lib/vendor/utils/translation.js +414 -0
- package/plugins/specweave/lib/vendor/utils/translation.js.map +1 -0
- package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
- package/plugins/specweave-ado/lib/conflict-resolver.ts +1 -1
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-backend/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-confluent/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-figma/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/commands/specweave-github-update-user-story.md +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +37 -22
- package/plugins/specweave-github/lib/ThreeLayerSyncManager.ts +1 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.js +1 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.js +2 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +4 -1
- package/plugins/specweave-github/lib/github-spec-sync.js +1 -1
- package/plugins/specweave-github/lib/github-spec-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.js +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.ts +10 -1
- package/plugins/specweave-github/lib/progress-comment-builder.js +1 -1
- package/plugins/specweave-github/lib/progress-comment-builder.ts +2 -2
- package/plugins/specweave-github/lib/types.ts +1 -1
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +1 -1
- package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kubernetes/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ml/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-mobile/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-payments/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-testing/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ui/.claude-plugin/plugin.json +1 -1
- package/src/templates/.env.example +5 -0
- package/src/templates/config-permissions-guide.md +413 -0
- package/src/templates/config.json.template +68 -0
- package/src/templates/tasks.md.template +180 -201
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -5442
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Preservation Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates sync operations to ensure external items maintain their original format.
|
|
5
|
+
* Prevents unintended modifications to external item titles, descriptions, and ACs.
|
|
6
|
+
*
|
|
7
|
+
* Key validations:
|
|
8
|
+
* - External items (format_preservation=true) → only comments allowed
|
|
9
|
+
* - Internal items (format_preservation=false) → full sync allowed
|
|
10
|
+
* - Title immutability for external items
|
|
11
|
+
* - Description immutability for external items
|
|
12
|
+
* - AC modifications blocked for external items
|
|
13
|
+
*
|
|
14
|
+
* Part of increment 0047-us-task-linkage (T-034C)
|
|
15
|
+
*/
|
|
16
|
+
import type { Logger } from '../utils/logger.js';
|
|
17
|
+
/**
|
|
18
|
+
* Sync operation to validate
|
|
19
|
+
*/
|
|
20
|
+
export interface SyncOperation {
|
|
21
|
+
/** User Story ID (e.g., "US-009") */
|
|
22
|
+
usId: string;
|
|
23
|
+
/** Format preservation enabled flag */
|
|
24
|
+
formatPreservation: boolean;
|
|
25
|
+
/** Fields to update (e.g., ['title', 'description', 'comments']) */
|
|
26
|
+
updates: string[];
|
|
27
|
+
/** Origin (internal | external) */
|
|
28
|
+
origin?: 'internal' | 'external';
|
|
29
|
+
/** Proposed title change (if any) */
|
|
30
|
+
proposedTitle?: string;
|
|
31
|
+
/** Current title (for validation) */
|
|
32
|
+
currentTitle?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validation result
|
|
36
|
+
*/
|
|
37
|
+
export interface ValidationResult {
|
|
38
|
+
/** Validation passed flag */
|
|
39
|
+
valid: boolean;
|
|
40
|
+
/** Validation errors */
|
|
41
|
+
errors?: string[];
|
|
42
|
+
/** Validation warnings (non-blocking) */
|
|
43
|
+
warnings?: string[];
|
|
44
|
+
/** Allowed fields (after filtering blocked fields) */
|
|
45
|
+
allowedFields?: string[];
|
|
46
|
+
/** Blocked fields */
|
|
47
|
+
blockedFields?: string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Format Preservation Validator
|
|
51
|
+
*
|
|
52
|
+
* Ensures external items maintain their original format during sync operations.
|
|
53
|
+
*/
|
|
54
|
+
export declare class FormatPreservationValidator {
|
|
55
|
+
private logger;
|
|
56
|
+
constructor(options?: {
|
|
57
|
+
logger?: Logger;
|
|
58
|
+
});
|
|
59
|
+
/**
|
|
60
|
+
* Validate sync operation
|
|
61
|
+
*
|
|
62
|
+
* Checks if the proposed sync operation violates format preservation rules.
|
|
63
|
+
*
|
|
64
|
+
* Rules:
|
|
65
|
+
* 1. External items (format_preservation=true) → ONLY comments allowed
|
|
66
|
+
* 2. Title updates → BLOCKED for external items
|
|
67
|
+
* 3. Description updates → BLOCKED for external items
|
|
68
|
+
* 4. AC updates → BLOCKED for external items
|
|
69
|
+
* 5. Status updates → ALLOWED (external tools control lifecycle)
|
|
70
|
+
* 6. Comments → ALWAYS ALLOWED
|
|
71
|
+
*
|
|
72
|
+
* @param operation - Sync operation to validate
|
|
73
|
+
* @returns Validation result
|
|
74
|
+
*/
|
|
75
|
+
validate(operation: SyncOperation): ValidationResult;
|
|
76
|
+
/**
|
|
77
|
+
* Check if field is blocked for external items
|
|
78
|
+
*
|
|
79
|
+
* @param field - Field name (e.g., 'title', 'description', 'comments')
|
|
80
|
+
* @returns True if field is blocked for external items
|
|
81
|
+
*/
|
|
82
|
+
private isBlockedField;
|
|
83
|
+
/**
|
|
84
|
+
* Get error message for blocked field
|
|
85
|
+
*
|
|
86
|
+
* @param field - Blocked field name
|
|
87
|
+
* @param usId - User Story ID
|
|
88
|
+
* @returns Error message
|
|
89
|
+
*/
|
|
90
|
+
private getBlockedFieldError;
|
|
91
|
+
/**
|
|
92
|
+
* Validate batch sync operations
|
|
93
|
+
*
|
|
94
|
+
* Validates multiple sync operations and returns results for each.
|
|
95
|
+
*
|
|
96
|
+
* @param operations - Array of sync operations
|
|
97
|
+
* @returns Array of validation results
|
|
98
|
+
*/
|
|
99
|
+
validateBatch(operations: SyncOperation[]): ValidationResult[];
|
|
100
|
+
/**
|
|
101
|
+
* Quick check: Is sync allowed?
|
|
102
|
+
*
|
|
103
|
+
* Simplified validation that returns true/false without detailed errors.
|
|
104
|
+
*
|
|
105
|
+
* @param formatPreservation - Format preservation flag
|
|
106
|
+
* @param proposedUpdates - Fields to update
|
|
107
|
+
* @returns True if sync is allowed
|
|
108
|
+
*/
|
|
109
|
+
isSyncAllowed(formatPreservation: boolean, proposedUpdates: string[]): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Filter allowed fields from sync operation
|
|
112
|
+
*
|
|
113
|
+
* Returns only the fields that are allowed for the given operation.
|
|
114
|
+
*
|
|
115
|
+
* @param operation - Sync operation
|
|
116
|
+
* @returns Array of allowed field names
|
|
117
|
+
*/
|
|
118
|
+
filterAllowedFields(operation: SyncOperation): string[];
|
|
119
|
+
/**
|
|
120
|
+
* Get validation summary for logging
|
|
121
|
+
*
|
|
122
|
+
* @param result - Validation result
|
|
123
|
+
* @returns Human-readable summary
|
|
124
|
+
*/
|
|
125
|
+
getValidationSummary(result: ValidationResult): string;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=format-preservation-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-preservation-validator.d.ts","sourceRoot":"","sources":["../../../src/validators/format-preservation-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IAEb,uCAAuC;IACvC,kBAAkB,EAAE,OAAO,CAAC;IAE5B,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAEjC,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,KAAK,EAAE,OAAO,CAAC;IAEf,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,qBAAqB;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,2BAA2B;IACtC,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAI7C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,gBAAgB;IAsDpD;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAatB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;;;;;OAOG;IACH,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE;IAI9D;;;;;;;;OAQG;IACH,aAAa,CAAC,kBAAkB,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO;IAU9E;;;;;;;OAOG;IACH,mBAAmB,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,EAAE;IASvD;;;;;OAKG;IACH,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;CAWvD"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Preservation Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates sync operations to ensure external items maintain their original format.
|
|
5
|
+
* Prevents unintended modifications to external item titles, descriptions, and ACs.
|
|
6
|
+
*
|
|
7
|
+
* Key validations:
|
|
8
|
+
* - External items (format_preservation=true) → only comments allowed
|
|
9
|
+
* - Internal items (format_preservation=false) → full sync allowed
|
|
10
|
+
* - Title immutability for external items
|
|
11
|
+
* - Description immutability for external items
|
|
12
|
+
* - AC modifications blocked for external items
|
|
13
|
+
*
|
|
14
|
+
* Part of increment 0047-us-task-linkage (T-034C)
|
|
15
|
+
*/
|
|
16
|
+
import { consoleLogger } from '../utils/logger.js';
|
|
17
|
+
/**
|
|
18
|
+
* Format Preservation Validator
|
|
19
|
+
*
|
|
20
|
+
* Ensures external items maintain their original format during sync operations.
|
|
21
|
+
*/
|
|
22
|
+
export class FormatPreservationValidator {
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
this.logger = options.logger ?? consoleLogger;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Validate sync operation
|
|
28
|
+
*
|
|
29
|
+
* Checks if the proposed sync operation violates format preservation rules.
|
|
30
|
+
*
|
|
31
|
+
* Rules:
|
|
32
|
+
* 1. External items (format_preservation=true) → ONLY comments allowed
|
|
33
|
+
* 2. Title updates → BLOCKED for external items
|
|
34
|
+
* 3. Description updates → BLOCKED for external items
|
|
35
|
+
* 4. AC updates → BLOCKED for external items
|
|
36
|
+
* 5. Status updates → ALLOWED (external tools control lifecycle)
|
|
37
|
+
* 6. Comments → ALWAYS ALLOWED
|
|
38
|
+
*
|
|
39
|
+
* @param operation - Sync operation to validate
|
|
40
|
+
* @returns Validation result
|
|
41
|
+
*/
|
|
42
|
+
validate(operation) {
|
|
43
|
+
const errors = [];
|
|
44
|
+
const warnings = [];
|
|
45
|
+
const blockedFields = [];
|
|
46
|
+
const allowedFields = [];
|
|
47
|
+
// Internal items → full sync allowed, no validation needed
|
|
48
|
+
if (!operation.formatPreservation) {
|
|
49
|
+
return {
|
|
50
|
+
valid: true,
|
|
51
|
+
allowedFields: operation.updates,
|
|
52
|
+
blockedFields: []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// External items → validate each field
|
|
56
|
+
for (const field of operation.updates) {
|
|
57
|
+
if (this.isBlockedField(field)) {
|
|
58
|
+
blockedFields.push(field);
|
|
59
|
+
errors.push(this.getBlockedFieldError(field, operation.usId));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
allowedFields.push(field);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Validate title immutability (if title change proposed)
|
|
66
|
+
if (operation.proposedTitle && operation.currentTitle) {
|
|
67
|
+
if (operation.proposedTitle !== operation.currentTitle) {
|
|
68
|
+
errors.push(`Title immutability violation for ${operation.usId}: ` +
|
|
69
|
+
`Cannot change external item title from "${operation.currentTitle}" to "${operation.proposedTitle}"`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Log validation result
|
|
73
|
+
if (errors.length > 0) {
|
|
74
|
+
this.logger.warn(` ⚠️ Format preservation validation failed for ${operation.usId}:`);
|
|
75
|
+
errors.forEach(err => this.logger.warn(` - ${err}`));
|
|
76
|
+
}
|
|
77
|
+
if (warnings.length > 0) {
|
|
78
|
+
warnings.forEach(warn => this.logger.warn(` ⚠️ ${warn}`));
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
valid: errors.length === 0,
|
|
82
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
83
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
84
|
+
allowedFields,
|
|
85
|
+
blockedFields
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Check if field is blocked for external items
|
|
90
|
+
*
|
|
91
|
+
* @param field - Field name (e.g., 'title', 'description', 'comments')
|
|
92
|
+
* @returns True if field is blocked for external items
|
|
93
|
+
*/
|
|
94
|
+
isBlockedField(field) {
|
|
95
|
+
const BLOCKED_FIELDS = [
|
|
96
|
+
'title',
|
|
97
|
+
'description',
|
|
98
|
+
'acceptance_criteria',
|
|
99
|
+
'acs',
|
|
100
|
+
'body',
|
|
101
|
+
'overview'
|
|
102
|
+
];
|
|
103
|
+
return BLOCKED_FIELDS.includes(field.toLowerCase());
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get error message for blocked field
|
|
107
|
+
*
|
|
108
|
+
* @param field - Blocked field name
|
|
109
|
+
* @param usId - User Story ID
|
|
110
|
+
* @returns Error message
|
|
111
|
+
*/
|
|
112
|
+
getBlockedFieldError(field, usId) {
|
|
113
|
+
const fieldName = field.toLowerCase();
|
|
114
|
+
switch (fieldName) {
|
|
115
|
+
case 'title':
|
|
116
|
+
return `Cannot update title for ${usId} (external item with format preservation enabled). Original title must be preserved.`;
|
|
117
|
+
case 'description':
|
|
118
|
+
case 'body':
|
|
119
|
+
case 'overview':
|
|
120
|
+
return `Cannot update description/body for ${usId} (external item with format preservation enabled). Original description must be preserved.`;
|
|
121
|
+
case 'acceptance_criteria':
|
|
122
|
+
case 'acs':
|
|
123
|
+
return `Cannot update acceptance criteria for ${usId} (external item with format preservation enabled). Original ACs must be preserved.`;
|
|
124
|
+
default:
|
|
125
|
+
return `Cannot update field "${field}" for ${usId} (external item with format preservation enabled).`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Validate batch sync operations
|
|
130
|
+
*
|
|
131
|
+
* Validates multiple sync operations and returns results for each.
|
|
132
|
+
*
|
|
133
|
+
* @param operations - Array of sync operations
|
|
134
|
+
* @returns Array of validation results
|
|
135
|
+
*/
|
|
136
|
+
validateBatch(operations) {
|
|
137
|
+
return operations.map(op => this.validate(op));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Quick check: Is sync allowed?
|
|
141
|
+
*
|
|
142
|
+
* Simplified validation that returns true/false without detailed errors.
|
|
143
|
+
*
|
|
144
|
+
* @param formatPreservation - Format preservation flag
|
|
145
|
+
* @param proposedUpdates - Fields to update
|
|
146
|
+
* @returns True if sync is allowed
|
|
147
|
+
*/
|
|
148
|
+
isSyncAllowed(formatPreservation, proposedUpdates) {
|
|
149
|
+
// Internal items → always allowed
|
|
150
|
+
if (!formatPreservation) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
// External items → check if any blocked fields
|
|
154
|
+
return !proposedUpdates.some(field => this.isBlockedField(field));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Filter allowed fields from sync operation
|
|
158
|
+
*
|
|
159
|
+
* Returns only the fields that are allowed for the given operation.
|
|
160
|
+
*
|
|
161
|
+
* @param operation - Sync operation
|
|
162
|
+
* @returns Array of allowed field names
|
|
163
|
+
*/
|
|
164
|
+
filterAllowedFields(operation) {
|
|
165
|
+
if (!operation.formatPreservation) {
|
|
166
|
+
return operation.updates; // All fields allowed for internal items
|
|
167
|
+
}
|
|
168
|
+
// For external items, filter out blocked fields
|
|
169
|
+
return operation.updates.filter(field => !this.isBlockedField(field));
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get validation summary for logging
|
|
173
|
+
*
|
|
174
|
+
* @param result - Validation result
|
|
175
|
+
* @returns Human-readable summary
|
|
176
|
+
*/
|
|
177
|
+
getValidationSummary(result) {
|
|
178
|
+
if (result.valid) {
|
|
179
|
+
return `✅ Validation passed (${result.allowedFields?.length || 0} fields allowed)`;
|
|
180
|
+
}
|
|
181
|
+
const errorCount = result.errors?.length || 0;
|
|
182
|
+
const warningCount = result.warnings?.length || 0;
|
|
183
|
+
const blockedCount = result.blockedFields?.length || 0;
|
|
184
|
+
return `❌ Validation failed: ${errorCount} error(s), ${warningCount} warning(s), ${blockedCount} field(s) blocked`;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=format-preservation-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-preservation-validator.js","sourceRoot":"","sources":["../../../src/validators/format-preservation-validator.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"clean": "rm -rf dist/",
|
|
12
|
-
"build": "tsc && npm run copy:locales && npm run copy:plugins",
|
|
12
|
+
"build": "tsc && npm run copy:locales && npm run copy:plugins && npm run copy:hook-deps",
|
|
13
13
|
"rebuild": "npm run clean && npm run build",
|
|
14
14
|
"copy:locales": "node scripts/copy-locales.js",
|
|
15
15
|
"copy:plugins": "node scripts/copy-plugin-js.js",
|
|
16
|
+
"copy:hook-deps": "node scripts/copy-hook-dependencies.js",
|
|
16
17
|
"dev": "tsc --watch",
|
|
17
18
|
"prepare": "npm run build",
|
|
18
19
|
"prepublishOnly": "npm run rebuild",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
3
|
"description": "SpecWeave framework. Provides increment planning (PM, Architect, Tech Lead agents), specification generation, TDD workflow, living docs sync, and brownfield support. Essential for all SpecWeave projects.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.22.14",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SpecWeave Team",
|
|
7
7
|
"url": "https://spec-weave.com"
|
|
@@ -18,5 +18,39 @@
|
|
|
18
18
|
"pm",
|
|
19
19
|
"architect",
|
|
20
20
|
"living-docs"
|
|
21
|
-
]
|
|
21
|
+
],
|
|
22
|
+
"hooks": {
|
|
23
|
+
"PostToolUse": [
|
|
24
|
+
{
|
|
25
|
+
"matcher": "TodoWrite",
|
|
26
|
+
"hooks": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-task-completion.sh",
|
|
30
|
+
"timeout": 10
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"matcher": "Edit",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-edit-spec.sh",
|
|
40
|
+
"timeout": 5
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"matcher": "Write",
|
|
46
|
+
"hooks": [
|
|
47
|
+
{
|
|
48
|
+
"type": "command",
|
|
49
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-write-spec.sh",
|
|
50
|
+
"timeout": 5
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
22
56
|
}
|
|
@@ -885,7 +885,11 @@ Before marking your work complete, verify:
|
|
|
885
885
|
- Use template: Context → Decision → Consequences
|
|
886
886
|
- Explain WHY not just WHAT
|
|
887
887
|
- Document alternatives considered
|
|
888
|
-
- Save to `.specweave/docs/internal/architecture/adr
|
|
888
|
+
- **CRITICAL**: Save to `.specweave/docs/internal/architecture/adr/XXXX-decision-title.md`
|
|
889
|
+
- ✅ CORRECT: `0007-github-first-task-sync.md` (4-digit number, kebab-case)
|
|
890
|
+
- ❌ WRONG: `adr-0007-github-first-task-sync.md` (NO `adr-` prefix!)
|
|
891
|
+
- ❌ WRONG: `ADR-0007-github-first-task-sync.md` (lowercase filename)
|
|
892
|
+
- **Why**: The `adr-` prefix is redundant (already in `/adr/` directory)
|
|
889
893
|
|
|
890
894
|
3. **Design API Contracts**
|
|
891
895
|
- RESTful API design (resources, verbs, status codes)
|
|
@@ -945,8 +949,13 @@ High-level description of the system.
|
|
|
945
949
|
```
|
|
946
950
|
|
|
947
951
|
### ADR Template
|
|
952
|
+
|
|
953
|
+
**IMPORTANT**: Filename format vs. content header:
|
|
954
|
+
- **Filename**: `XXXX-decision-title.md` (e.g., `0007-github-first-task-sync.md`)
|
|
955
|
+
- **Header**: `# ADR-XXXX: Decision Title` (includes `ADR-` prefix for clarity in document)
|
|
956
|
+
|
|
948
957
|
```markdown
|
|
949
|
-
# ADR
|
|
958
|
+
# ADR-XXXX: [Decision Title]
|
|
950
959
|
|
|
951
960
|
**Date**: YYYY-MM-DD
|
|
952
961
|
**Status**: [Proposed | Accepted | Deprecated | Superseded]
|
|
@@ -73,17 +73,24 @@ The test-aware-planner agent is responsible for generating `tasks.md` with **emb
|
|
|
73
73
|
|
|
74
74
|
---
|
|
75
75
|
|
|
76
|
-
## Task Format (NEW -
|
|
76
|
+
## Task Format (NEW - v0.23.0: Hierarchical US-Task Linkage)
|
|
77
|
+
|
|
78
|
+
**CRITICAL**: v0.23.0+ requires hierarchical structure grouped by User Story.
|
|
77
79
|
|
|
78
80
|
Each task in `tasks.md` follows this format:
|
|
79
81
|
|
|
80
82
|
```markdown
|
|
83
|
+
## User Story: US-001 - User Story Title
|
|
84
|
+
|
|
85
|
+
**Linked ACs**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
86
|
+
**Tasks**: X total, 0 completed
|
|
87
|
+
|
|
81
88
|
### T-001: Implement Feature X
|
|
82
89
|
|
|
83
|
-
**User Story**:
|
|
84
|
-
**
|
|
85
|
-
**Priority**: P1
|
|
86
|
-
**
|
|
90
|
+
**User Story**: US-001
|
|
91
|
+
**Satisfies ACs**: AC-US1-01, AC-US1-02
|
|
92
|
+
**Priority**: P0 (Critical) | P1 (Important) | P2 (Nice-to-have)
|
|
93
|
+
**Estimated Effort**: 4 hours
|
|
87
94
|
**Status**: [ ] pending
|
|
88
95
|
|
|
89
96
|
**Test Plan**:
|
|
@@ -667,44 +674,88 @@ If TDD mode is enabled (check frontmatter: `test_mode: TDD`), add TDD workflow s
|
|
|
667
674
|
|
|
668
675
|
### Phase 3: File Generation
|
|
669
676
|
|
|
670
|
-
**Step 3.1: Generate tasks.md Frontmatter**
|
|
677
|
+
**Step 3.1: Generate tasks.md Frontmatter (v0.23.0+)**
|
|
671
678
|
|
|
672
679
|
```markdown
|
|
673
680
|
---
|
|
674
|
-
increment: {increment-id}
|
|
675
681
|
total_tasks: {count}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
682
|
+
completed: 0
|
|
683
|
+
by_user_story:
|
|
684
|
+
US-001: {count_for_us1}
|
|
685
|
+
US-002: {count_for_us2}
|
|
686
|
+
US-003: {count_for_us3}
|
|
687
|
+
test_mode: {TDD|test-after}
|
|
688
|
+
coverage_target: {percentage}
|
|
679
689
|
---
|
|
680
690
|
|
|
681
|
-
#
|
|
691
|
+
# Tasks: {Increment Title}
|
|
682
692
|
```
|
|
683
693
|
|
|
684
|
-
**Rules
|
|
685
|
-
- `increment`: Use increment ID from folder name
|
|
694
|
+
**Rules (v0.23.0+)**:
|
|
686
695
|
- `total_tasks`: Count all generated tasks
|
|
687
|
-
- `
|
|
688
|
-
- `
|
|
689
|
-
- `
|
|
696
|
+
- `completed`: Always starts at 0
|
|
697
|
+
- `by_user_story`: Map of US-ID → task count (REQUIRED for progress tracking)
|
|
698
|
+
- `test_mode`: TDD or test-after (no "standard")
|
|
699
|
+
- `coverage_target`: Number without % (e.g., 85, not 85%)
|
|
690
700
|
|
|
691
|
-
**
|
|
701
|
+
**Example**:
|
|
702
|
+
```yaml
|
|
703
|
+
---
|
|
704
|
+
total_tasks: 22
|
|
705
|
+
completed: 0
|
|
706
|
+
by_user_story:
|
|
707
|
+
US-001: 4
|
|
708
|
+
US-002: 3
|
|
709
|
+
US-003: 5
|
|
710
|
+
US-004: 3
|
|
711
|
+
US-005: 4
|
|
712
|
+
US-006: 3
|
|
713
|
+
test_mode: test-after
|
|
714
|
+
coverage_target: 90
|
|
715
|
+
---
|
|
716
|
+
```
|
|
692
717
|
|
|
693
|
-
|
|
718
|
+
**Step 3.2: Assemble All Tasks (v0.23.0+: Hierarchical by User Story)**
|
|
719
|
+
|
|
720
|
+
**CRITICAL**: Tasks MUST be grouped by User Story with section headers:
|
|
694
721
|
|
|
695
722
|
```markdown
|
|
696
|
-
|
|
723
|
+
## User Story: US-001 - User Story Title
|
|
724
|
+
|
|
725
|
+
**Linked ACs**: AC-US1-01, AC-US1-02, AC-US1-03
|
|
726
|
+
**Tasks**: 4 total, 0 completed
|
|
727
|
+
|
|
728
|
+
### T-001: [First task for US-001]
|
|
729
|
+
**User Story**: US-001
|
|
730
|
+
**Satisfies ACs**: AC-US1-01, AC-US1-02
|
|
697
731
|
[Full task format from Phase 2]
|
|
698
732
|
|
|
699
|
-
### T-002: [
|
|
733
|
+
### T-002: [Second task for US-001]
|
|
734
|
+
**User Story**: US-001
|
|
735
|
+
**Satisfies ACs**: AC-US1-03
|
|
700
736
|
[Full task format from Phase 2]
|
|
701
737
|
|
|
702
|
-
|
|
738
|
+
---
|
|
703
739
|
|
|
704
|
-
|
|
740
|
+
## User Story: US-002 - Another User Story Title
|
|
741
|
+
|
|
742
|
+
**Linked ACs**: AC-US2-01, AC-US2-02
|
|
743
|
+
**Tasks**: 3 total, 0 completed
|
|
744
|
+
|
|
745
|
+
### T-003: [First task for US-002]
|
|
746
|
+
**User Story**: US-002
|
|
747
|
+
**Satisfies ACs**: AC-US2-01
|
|
705
748
|
[Full task format from Phase 2]
|
|
749
|
+
|
|
750
|
+
...
|
|
706
751
|
```
|
|
707
752
|
|
|
753
|
+
**Rules**:
|
|
754
|
+
- Group tasks by User Story using `## User Story: US-XXX - Title` headers
|
|
755
|
+
- Each section shows linked ACs and task count
|
|
756
|
+
- Tasks within section MUST link to that User Story
|
|
757
|
+
- Use `---` separator between User Story sections
|
|
758
|
+
|
|
708
759
|
**Step 3.3: Write tasks.md**
|
|
709
760
|
|
|
710
761
|
Save the complete file to:
|
|
@@ -719,9 +770,14 @@ Save the complete file to:
|
|
|
719
770
|
|
|
720
771
|
Before finalizing, validate the generated tasks.md:
|
|
721
772
|
|
|
722
|
-
**Validation Checklist
|
|
773
|
+
**Validation Checklist (v0.23.0+)**:
|
|
723
774
|
|
|
724
|
-
- [ ] **AC-ID Coverage**: Every AC-ID from spec.md is referenced in at least one task
|
|
775
|
+
- [ ] **AC-ID Coverage**: Every AC-ID from spec.md is referenced in at least one task (100% coverage required)
|
|
776
|
+
- [ ] **US-Task Linkage**: Every task has **User Story** field linking to valid US-ID
|
|
777
|
+
- [ ] **AC Linkage**: Every task has **Satisfies ACs** field with valid AC-IDs
|
|
778
|
+
- [ ] **Hierarchical Structure**: Tasks grouped by User Story with section headers
|
|
779
|
+
- [ ] **by_user_story Map**: Frontmatter includes by_user_story with correct counts
|
|
780
|
+
- [ ] **No Orphan Tasks**: All tasks link to at least one AC
|
|
725
781
|
- [ ] **Task Format**: Each task follows the standard format (header, test plan, test cases, implementation)
|
|
726
782
|
- [ ] **Test Plans**: All testable tasks have Given/When/Then
|
|
727
783
|
- [ ] **Test Cases**: Test file paths follow project conventions
|
|
@@ -731,7 +787,7 @@ Before finalizing, validate the generated tasks.md:
|
|
|
731
787
|
- [ ] **TDD Workflow**: Included if test_mode is TDD
|
|
732
788
|
- [ ] **Estimates**: Realistic (2-8 hours typical per task)
|
|
733
789
|
- [ ] **Dependencies**: Tasks ordered by dependencies
|
|
734
|
-
- [ ] **Frontmatter**: Correct
|
|
790
|
+
- [ ] **Frontmatter**: Correct total_tasks, by_user_story map, test_mode, coverage_target
|
|
735
791
|
|
|
736
792
|
**Validation Script Example:**
|
|
737
793
|
|
|
@@ -19,6 +19,7 @@ Archive features and epics based on their increment archive status. Features are
|
|
|
19
19
|
- `--update-links`: Update all links to archived items (default: true)
|
|
20
20
|
- `--preserve-active`: Don't archive features with active projects (default: true)
|
|
21
21
|
- `--orphaned`: Also archive orphaned features/epics with no increments/features
|
|
22
|
+
- `--reason <text>`: Optional reason for archiving (for audit trail, AC-US13-07)
|
|
22
23
|
|
|
23
24
|
## Examples
|
|
24
25
|
|
|
@@ -31,6 +32,9 @@ Archive features and epics based on their increment archive status. Features are
|
|
|
31
32
|
|
|
32
33
|
# Archive including orphaned features
|
|
33
34
|
/specweave:archive-features --orphaned
|
|
35
|
+
|
|
36
|
+
# Archive with custom reason for audit trail (AC-US13-07)
|
|
37
|
+
/specweave:archive-features --reason="Obsolete after product pivot"
|
|
34
38
|
```
|
|
35
39
|
|
|
36
40
|
## Archive Rules
|
|
@@ -80,12 +84,18 @@ task.run(async () => {
|
|
|
80
84
|
const archiver = new FeatureArchiver(process.cwd());
|
|
81
85
|
|
|
82
86
|
// Parse options
|
|
87
|
+
const reasonIndex = process.argv.indexOf('--reason');
|
|
88
|
+
const customReason = reasonIndex !== -1 && reasonIndex + 1 < process.argv.length
|
|
89
|
+
? process.argv[reasonIndex + 1]
|
|
90
|
+
: undefined;
|
|
91
|
+
|
|
83
92
|
const options = {
|
|
84
93
|
dryRun: process.argv.includes('--dry-run'),
|
|
85
94
|
updateLinks: !process.argv.includes('--no-update-links'),
|
|
86
95
|
preserveActiveFeatures: !process.argv.includes('--no-preserve-active'),
|
|
87
96
|
archiveOrphanedFeatures: process.argv.includes('--orphaned'),
|
|
88
|
-
archiveOrphanedEpics: process.argv.includes('--orphaned')
|
|
97
|
+
archiveOrphanedEpics: process.argv.includes('--orphaned'),
|
|
98
|
+
customReason: customReason
|
|
89
99
|
};
|
|
90
100
|
|
|
91
101
|
// Execute archiving
|