@fission-ai/openspec 1.3.0 → 1.4.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.
Files changed (179) hide show
  1. package/README.md +9 -6
  2. package/bin/openspec.js +3 -1
  3. package/dist/cli/index.d.ts +4 -1
  4. package/dist/cli/index.js +46 -2
  5. package/dist/commands/completion.js +7 -0
  6. package/dist/commands/config.js +64 -5
  7. package/dist/commands/context-store.d.ts +3 -0
  8. package/dist/commands/context-store.js +475 -0
  9. package/dist/commands/initiative.d.ts +13 -0
  10. package/dist/commands/initiative.js +318 -0
  11. package/dist/commands/workflow/index.d.ts +2 -0
  12. package/dist/commands/workflow/index.js +1 -0
  13. package/dist/commands/workflow/initiative-link.d.ts +24 -0
  14. package/dist/commands/workflow/initiative-link.js +47 -0
  15. package/dist/commands/workflow/instructions.d.ts +1 -1
  16. package/dist/commands/workflow/instructions.js +46 -83
  17. package/dist/commands/workflow/new-change.d.ts +6 -0
  18. package/dist/commands/workflow/new-change.js +114 -17
  19. package/dist/commands/workflow/set-change.d.ts +13 -0
  20. package/dist/commands/workflow/set-change.js +87 -0
  21. package/dist/commands/workflow/shared.d.ts +5 -3
  22. package/dist/commands/workflow/shared.js +6 -6
  23. package/dist/commands/workflow/status.js +24 -9
  24. package/dist/commands/workflow/templates.js +5 -4
  25. package/dist/commands/workspace/context-status.d.ts +4 -0
  26. package/dist/commands/workspace/context-status.js +59 -0
  27. package/dist/commands/workspace/open-target-selection.d.ts +13 -0
  28. package/dist/commands/workspace/open-target-selection.js +146 -0
  29. package/dist/commands/workspace/open-view.d.ts +62 -0
  30. package/dist/commands/workspace/open-view.js +249 -0
  31. package/dist/commands/workspace/open.d.ts +37 -0
  32. package/dist/commands/workspace/open.js +110 -0
  33. package/dist/commands/workspace/opener-selection.d.ts +11 -0
  34. package/dist/commands/workspace/opener-selection.js +98 -0
  35. package/dist/commands/workspace/operations.d.ts +29 -0
  36. package/dist/commands/workspace/operations.js +543 -0
  37. package/dist/commands/workspace/prompt-theme.d.ts +29 -0
  38. package/dist/commands/workspace/prompt-theme.js +24 -0
  39. package/dist/commands/workspace/registration.d.ts +13 -0
  40. package/dist/commands/workspace/registration.js +84 -0
  41. package/dist/commands/workspace/selection.d.ts +9 -0
  42. package/dist/commands/workspace/selection.js +115 -0
  43. package/dist/commands/workspace/setup-prompts.d.ts +13 -0
  44. package/dist/commands/workspace/setup-prompts.js +121 -0
  45. package/dist/commands/workspace/types.d.ts +103 -0
  46. package/dist/commands/workspace/types.js +36 -0
  47. package/dist/commands/workspace.d.ts +6 -0
  48. package/dist/commands/workspace.js +587 -0
  49. package/dist/core/artifact-graph/index.d.ts +3 -1
  50. package/dist/core/artifact-graph/index.js +1 -0
  51. package/dist/core/artifact-graph/instruction-loader.d.ts +41 -1
  52. package/dist/core/artifact-graph/instruction-loader.js +51 -9
  53. package/dist/core/artifact-graph/outputs.d.ts +14 -0
  54. package/dist/core/artifact-graph/outputs.js +39 -0
  55. package/dist/core/artifact-graph/state.js +2 -25
  56. package/dist/core/artifact-graph/types.d.ts +0 -5
  57. package/dist/core/artifact-graph/types.js +0 -14
  58. package/dist/core/change-metadata/index.d.ts +2 -0
  59. package/dist/core/change-metadata/index.js +2 -0
  60. package/dist/core/change-metadata/schema.d.ts +18 -0
  61. package/dist/core/change-metadata/schema.js +28 -0
  62. package/dist/core/change-status-policy.d.ts +50 -0
  63. package/dist/core/change-status-policy.js +70 -0
  64. package/dist/core/collections/index.d.ts +3 -0
  65. package/dist/core/collections/index.js +3 -0
  66. package/dist/core/collections/initiatives/collection.d.ts +4 -0
  67. package/dist/core/collections/initiatives/collection.js +17 -0
  68. package/dist/core/collections/initiatives/index.d.ts +6 -0
  69. package/dist/core/collections/initiatives/index.js +6 -0
  70. package/dist/core/collections/initiatives/operations.d.ts +49 -0
  71. package/dist/core/collections/initiatives/operations.js +175 -0
  72. package/dist/core/collections/initiatives/resolution.d.ts +87 -0
  73. package/dist/core/collections/initiatives/resolution.js +374 -0
  74. package/dist/core/collections/initiatives/schema.d.ts +41 -0
  75. package/dist/core/collections/initiatives/schema.js +134 -0
  76. package/dist/core/collections/initiatives/templates.d.ts +12 -0
  77. package/dist/core/collections/initiatives/templates.js +90 -0
  78. package/dist/core/collections/runtime.d.ts +46 -0
  79. package/dist/core/collections/runtime.js +194 -0
  80. package/dist/core/completions/command-registry.d.ts +1 -5
  81. package/dist/core/completions/command-registry.js +532 -32
  82. package/dist/core/completions/completion-provider.d.ts +11 -0
  83. package/dist/core/completions/completion-provider.js +27 -0
  84. package/dist/core/completions/generators/bash-generator.d.ts +3 -0
  85. package/dist/core/completions/generators/bash-generator.js +60 -4
  86. package/dist/core/completions/generators/fish-generator.js +3 -0
  87. package/dist/core/completions/generators/powershell-generator.d.ts +3 -0
  88. package/dist/core/completions/generators/powershell-generator.js +63 -4
  89. package/dist/core/completions/generators/zsh-generator.d.ts +3 -0
  90. package/dist/core/completions/generators/zsh-generator.js +46 -22
  91. package/dist/core/completions/installers/zsh-installer.d.ts +0 -8
  92. package/dist/core/completions/installers/zsh-installer.js +3 -31
  93. package/dist/core/completions/shared-flags.d.ts +12 -0
  94. package/dist/core/completions/shared-flags.js +28 -0
  95. package/dist/core/completions/templates/bash-templates.d.ts +1 -1
  96. package/dist/core/completions/templates/bash-templates.js +6 -0
  97. package/dist/core/completions/templates/fish-templates.d.ts +1 -1
  98. package/dist/core/completions/templates/fish-templates.js +6 -0
  99. package/dist/core/completions/templates/powershell-templates.d.ts +1 -1
  100. package/dist/core/completions/templates/powershell-templates.js +9 -0
  101. package/dist/core/completions/templates/zsh-templates.d.ts +1 -1
  102. package/dist/core/completions/templates/zsh-templates.js +9 -0
  103. package/dist/core/completions/types.d.ts +23 -1
  104. package/dist/core/config.js +3 -1
  105. package/dist/core/context-store/binding.d.ts +53 -0
  106. package/dist/core/context-store/binding.js +197 -0
  107. package/dist/core/context-store/errors.d.ts +20 -0
  108. package/dist/core/context-store/errors.js +22 -0
  109. package/dist/core/context-store/foundation.d.ts +55 -0
  110. package/dist/core/context-store/foundation.js +321 -0
  111. package/dist/core/context-store/index.d.ts +6 -0
  112. package/dist/core/context-store/index.js +6 -0
  113. package/dist/core/context-store/operations.d.ts +85 -0
  114. package/dist/core/context-store/operations.js +528 -0
  115. package/dist/core/context-store/registry.d.ts +45 -0
  116. package/dist/core/context-store/registry.js +229 -0
  117. package/dist/core/global-config.d.ts +6 -1
  118. package/dist/core/global-config.js +15 -16
  119. package/dist/core/index.d.ts +5 -1
  120. package/dist/core/index.js +4 -0
  121. package/dist/core/parsers/change-parser.js +7 -3
  122. package/dist/core/parsers/markdown-parser.d.ts +4 -0
  123. package/dist/core/parsers/markdown-parser.js +41 -1
  124. package/dist/core/parsers/requirement-blocks.js +5 -5
  125. package/dist/core/parsers/spec-structure.d.ts +9 -0
  126. package/dist/core/parsers/spec-structure.js +88 -0
  127. package/dist/core/planning-home.d.ts +21 -0
  128. package/dist/core/planning-home.js +108 -0
  129. package/dist/core/profiles.d.ts +1 -1
  130. package/dist/core/profiles.js +1 -1
  131. package/dist/core/specs-apply.js +9 -1
  132. package/dist/core/templates/workflows/apply-change.js +10 -4
  133. package/dist/core/templates/workflows/archive-change.js +21 -15
  134. package/dist/core/templates/workflows/bulk-archive-change.js +14 -10
  135. package/dist/core/templates/workflows/continue-change.js +6 -4
  136. package/dist/core/templates/workflows/explore.js +8 -10
  137. package/dist/core/templates/workflows/ff-change.js +8 -6
  138. package/dist/core/templates/workflows/new-change.js +6 -6
  139. package/dist/core/templates/workflows/onboard.js +13 -15
  140. package/dist/core/templates/workflows/propose.js +8 -6
  141. package/dist/core/templates/workflows/sync-specs.js +28 -10
  142. package/dist/core/templates/workflows/verify-change.js +16 -10
  143. package/dist/core/update.d.ts +5 -0
  144. package/dist/core/update.js +20 -0
  145. package/dist/core/validation/validator.d.ts +11 -0
  146. package/dist/core/validation/validator.js +28 -2
  147. package/dist/core/workspace/foundation.d.ts +67 -0
  148. package/dist/core/workspace/foundation.js +295 -0
  149. package/dist/core/workspace/index.d.ts +8 -0
  150. package/dist/core/workspace/index.js +8 -0
  151. package/dist/core/workspace/legacy-state.d.ts +28 -0
  152. package/dist/core/workspace/legacy-state.js +200 -0
  153. package/dist/core/workspace/link-input.d.ts +9 -0
  154. package/dist/core/workspace/link-input.js +32 -0
  155. package/dist/core/workspace/open-surface.d.ts +45 -0
  156. package/dist/core/workspace/open-surface.js +215 -0
  157. package/dist/core/workspace/openers.d.ts +21 -0
  158. package/dist/core/workspace/openers.js +124 -0
  159. package/dist/core/workspace/registry.d.ts +24 -0
  160. package/dist/core/workspace/registry.js +146 -0
  161. package/dist/core/workspace/skills.d.ts +57 -0
  162. package/dist/core/workspace/skills.js +334 -0
  163. package/dist/core/workspace/state-io.d.ts +10 -0
  164. package/dist/core/workspace/state-io.js +119 -0
  165. package/dist/telemetry/config.d.ts +7 -1
  166. package/dist/telemetry/config.js +87 -19
  167. package/dist/telemetry/index.js +19 -0
  168. package/dist/utils/change-metadata.d.ts +5 -2
  169. package/dist/utils/change-metadata.js +7 -13
  170. package/dist/utils/change-utils.d.ts +9 -0
  171. package/dist/utils/change-utils.js +7 -5
  172. package/dist/utils/file-system.d.ts +5 -0
  173. package/dist/utils/file-system.js +21 -1
  174. package/package.json +2 -1
  175. package/schemas/workspace-planning/schema.yaml +72 -0
  176. package/schemas/workspace-planning/templates/design.md +33 -0
  177. package/schemas/workspace-planning/templates/proposal.md +28 -0
  178. package/schemas/workspace-planning/templates/spec.md +9 -0
  179. package/schemas/workspace-planning/templates/tasks.md +15 -0
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import * as yaml from 'yaml';
4
- import { ChangeMetadataSchema } from '../core/artifact-graph/types.js';
4
+ import { ChangeMetadataSchema } from '../core/change-metadata/index.js';
5
5
  import { listSchemas } from '../core/artifact-graph/resolver.js';
6
6
  import { readProjectConfig } from '../core/project-config.js';
7
7
  const METADATA_FILENAME = '.openspec.yaml';
@@ -114,24 +114,18 @@ export function readChangeMetadata(changeDir, projectRoot) {
114
114
  * @param explicitSchema - Optional explicit schema override
115
115
  * @returns The resolved schema name
116
116
  */
117
- export function resolveSchemaForChange(changeDir, explicitSchema) {
117
+ export function resolveSchemaForChange(changeDir, explicitSchema, projectRootOverride, options = {}) {
118
118
  // Derive project root from changeDir (changeDir is typically projectRoot/openspec/changes/change-name)
119
- const projectRoot = path.resolve(changeDir, '../../..');
119
+ const projectRoot = projectRootOverride ?? path.resolve(changeDir, '../../..');
120
120
  // 1. Explicit override wins
121
121
  if (explicitSchema) {
122
122
  return explicitSchema;
123
123
  }
124
- // 2. Try reading from metadata
125
- try {
126
- const metadata = readChangeMetadata(changeDir, projectRoot);
127
- if (metadata?.schema) {
128
- return metadata.schema;
129
- }
130
- }
131
- catch {
132
- // If metadata read fails, continue to next option
124
+ const metadata = options.metadata !== undefined ? options.metadata : readChangeMetadata(changeDir, projectRoot);
125
+ if (metadata?.schema) {
126
+ return metadata.schema;
133
127
  }
134
- // 3. Try reading from project config
128
+ // 3. Try reading from project config when metadata is absent.
135
129
  try {
136
130
  const config = readProjectConfig(projectRoot);
137
131
  if (config?.schema) {
@@ -1,9 +1,16 @@
1
+ import type { ChangeMetadata } from '../core/change-metadata/index.js';
1
2
  /**
2
3
  * Options for creating a change.
3
4
  */
4
5
  export interface CreateChangeOptions {
5
6
  /** The workflow schema to use (default: 'spec-driven') */
6
7
  schema?: string;
8
+ /** Default schema to use when no explicit schema or project config is present */
9
+ defaultSchema?: string;
10
+ /** Directory that should contain the change directories */
11
+ changesDir?: string;
12
+ /** Additional metadata to persist in the change's .openspec.yaml */
13
+ metadata?: Partial<Pick<ChangeMetadata, 'goal' | 'affected_areas' | 'initiative'>>;
7
14
  }
8
15
  /**
9
16
  * Result of creating a change.
@@ -11,6 +18,8 @@ export interface CreateChangeOptions {
11
18
  export interface CreateChangeResult {
12
19
  /** The schema that was actually used (resolved from options, config, or default) */
13
20
  schema: string;
21
+ /** Absolute path to the created change directory */
22
+ changeDir: string;
14
23
  }
15
24
  /**
16
25
  * Result of validating a change name.
@@ -84,7 +84,8 @@ export async function createChange(projectRoot, name, options = {}) {
84
84
  if (!validation.valid) {
85
85
  throw new Error(validation.error);
86
86
  }
87
- // Determine schema: explicit option → project config → hardcoded default
87
+ const defaultSchema = options.defaultSchema ?? DEFAULT_SCHEMA;
88
+ // Determine schema: explicit option → project config → supplied default
88
89
  let schemaName;
89
90
  if (options.schema) {
90
91
  schemaName = options.schema;
@@ -93,17 +94,17 @@ export async function createChange(projectRoot, name, options = {}) {
93
94
  // Try to read from project config
94
95
  try {
95
96
  const config = readProjectConfig(projectRoot);
96
- schemaName = config?.schema ?? DEFAULT_SCHEMA;
97
+ schemaName = config?.schema ?? defaultSchema;
97
98
  }
98
99
  catch {
99
100
  // If config read fails, use default
100
- schemaName = DEFAULT_SCHEMA;
101
+ schemaName = defaultSchema;
101
102
  }
102
103
  }
103
104
  // Validate the resolved schema
104
105
  validateSchemaName(schemaName, projectRoot);
105
106
  // Build the change directory path
106
- const changeDir = path.join(projectRoot, 'openspec', 'changes', name);
107
+ const changeDir = path.join(options.changesDir ?? path.join(projectRoot, 'openspec', 'changes'), name);
107
108
  // Check if change already exists
108
109
  if (await FileSystemUtils.directoryExists(changeDir)) {
109
110
  throw new Error(`Change '${name}' already exists at ${changeDir}`);
@@ -115,7 +116,8 @@ export async function createChange(projectRoot, name, options = {}) {
115
116
  writeChangeMetadata(changeDir, {
116
117
  schema: schemaName,
117
118
  created: today,
119
+ ...options.metadata,
118
120
  }, projectRoot);
119
- return { schema: schemaName };
121
+ return { schema: schemaName, changeDir };
120
122
  }
121
123
  //# sourceMappingURL=change-utils.js.map
@@ -4,6 +4,11 @@ export declare class FileSystemUtils {
4
4
  * Essential for cross-platform compatibility with glob libraries like fast-glob.
5
5
  */
6
6
  static toPosixPath(p: string): string;
7
+ /**
8
+ * Returns a canonical absolute path when the target exists.
9
+ * Falls back to path.resolve() so callers can still produce a stable absolute path.
10
+ */
11
+ static canonicalizeExistingPath(targetPath: string): string;
7
12
  private static isWindowsBasePath;
8
13
  private static normalizeSegments;
9
14
  static joinPath(basePath: string, ...segments: string[]): string;
@@ -1,5 +1,7 @@
1
- import { promises as fs, constants as fsConstants } from 'fs';
1
+ import * as nodeFs from 'fs';
2
2
  import path from 'path';
3
+ const fs = nodeFs.promises;
4
+ const { constants: fsConstants } = nodeFs;
3
5
  function isMarkerOnOwnLine(content, markerIndex, markerLength) {
4
6
  let leftIndex = markerIndex - 1;
5
7
  while (leftIndex >= 0 && content[leftIndex] !== '\n') {
@@ -37,6 +39,24 @@ export class FileSystemUtils {
37
39
  static toPosixPath(p) {
38
40
  return p.replace(/\\/g, '/');
39
41
  }
42
+ /**
43
+ * Returns a canonical absolute path when the target exists.
44
+ * Falls back to path.resolve() so callers can still produce a stable absolute path.
45
+ */
46
+ static canonicalizeExistingPath(targetPath) {
47
+ try {
48
+ // Prefer the native resolver so Windows short-path aliases are expanded.
49
+ return nodeFs.realpathSync.native(targetPath);
50
+ }
51
+ catch {
52
+ try {
53
+ return nodeFs.realpathSync(targetPath);
54
+ }
55
+ catch {
56
+ return path.resolve(targetPath);
57
+ }
58
+ }
59
+ }
40
60
  static isWindowsBasePath(basePath) {
41
61
  return /^[A-Za-z]:[\\/]/.test(basePath) || basePath.startsWith('\\');
42
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fission-ai/openspec",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "AI-native system for spec-driven development",
5
5
  "keywords": [
6
6
  "openspec",
@@ -56,6 +56,7 @@
56
56
  "@inquirer/prompts": "^7.8.0",
57
57
  "chalk": "^5.5.0",
58
58
  "commander": "^14.0.0",
59
+ "cross-spawn": "7.0.6",
59
60
  "fast-glob": "^3.3.3",
60
61
  "ora": "^8.2.0",
61
62
  "posthog-node": "^5.20.0",
@@ -0,0 +1,72 @@
1
+ name: workspace-planning
2
+ version: 1
3
+ description: Workspace planning workflow for cross-area changes
4
+ artifacts:
5
+ - id: proposal
6
+ generates: proposal.md
7
+ description: Shared workspace proposal with the product goal, scope, affected areas, and impact
8
+ template: proposal.md
9
+ instruction: |
10
+ Create the workspace-level proposal that captures the shared product goal once.
11
+
12
+ Sections:
13
+ - **Why**: Explain the product goal or problem in 1-2 concise paragraphs.
14
+ - **What Changes**: List the cross-area behavior, workflow, or capability changes.
15
+ - **Affected Areas**: Name known affected areas using registered workspace link names where applicable. If scope is still being explored, say what remains unresolved.
16
+ - **Capabilities**: Identify workspace-scoped capabilities that need specs. Area-specific requirements should later live under `specs/<area-or-repo>/<capability>/spec.md`.
17
+ - **Impact**: Summarize user-facing impact, planning impact, and likely implementation homes without creating repo-local artifacts.
18
+
19
+ Keep linked repos and folders as exploration context until an explicit implementation workflow selects an affected area.
20
+ requires: []
21
+
22
+ - id: specs
23
+ generates: "specs/**/*.md"
24
+ description: Workspace-scoped specs organized by affected area and capability
25
+ template: spec.md
26
+ instruction: |
27
+ Create workspace-scoped specification files that define WHAT should change.
28
+
29
+ Use `specs/<area-or-repo>/<capability>/spec.md` for area-specific requirements. The first path segment should be a registered workspace link name when a registered area owns the requirement. If the area is unresolved, use an exploratory area name and make the unresolved question explicit in the requirement or scenario.
30
+
31
+ These specs are planning artifacts under the workspace change root. Do not create repo-local spec files in linked repos during workspace planning.
32
+
33
+ Delta operations (use ## headers):
34
+ - **ADDED Requirements**: New workspace-scoped behavior.
35
+ - **MODIFIED Requirements**: Changed behavior; include the full updated requirement.
36
+ - **REMOVED Requirements**: Deprecated behavior with Reason and Migration.
37
+ - **RENAMED Requirements**: Name changes only; use FROM:/TO: format.
38
+
39
+ Each requirement must use SHALL/MUST language and include at least one `#### Scenario:` block.
40
+ requires:
41
+ - proposal
42
+
43
+ - id: design
44
+ generates: design.md
45
+ description: Cross-area technical design and coordination decisions
46
+ template: design.md
47
+ instruction: |
48
+ Create the cross-area design document for workspace planning.
49
+
50
+ Focus on decisions that affect multiple areas, handoffs between areas, shared constraints, sequencing risks, and how the workspace plan should stay the source of truth. Avoid line-by-line implementation details and do not instruct agents to edit linked repos until an explicit implementation workflow provides an allowed edit root.
51
+ requires:
52
+ - proposal
53
+
54
+ - id: tasks
55
+ generates: tasks.md
56
+ description: Coordination checklist for workspace planning and later affected-area implementation
57
+ template: tasks.md
58
+ instruction: |
59
+ Create the workspace coordination task list.
60
+
61
+ Group tasks by phase or affected area as useful. Each actionable item must be a checkbox using `- [ ]`. When implementation tasks are area-specific, name the affected area and keep the task at planning granularity until a later implementation workflow selects an allowed edit root.
62
+ requires:
63
+ - specs
64
+ - design
65
+
66
+ apply:
67
+ requires: [tasks]
68
+ tracks: tasks.md
69
+ instruction: |
70
+ Read the workspace planning context from status and instructions output before applying.
71
+ Select an affected area and confirm an allowed edit root before making implementation edits.
72
+ Until an explicit implementation context is available, treat linked repos and folders as read-only exploration context.
@@ -0,0 +1,33 @@
1
+ ## Context
2
+
3
+ Summarize the workspace planning context, relevant linked areas, and constraints.
4
+
5
+ ## Goals / Non-Goals
6
+
7
+ **Goals:**
8
+ -
9
+
10
+ **Non-Goals:**
11
+ - Creating repo-local implementation artifacts before an affected area is selected.
12
+
13
+ ## Decisions
14
+
15
+ ### Decision: <title>
16
+
17
+ <decision and rationale>
18
+
19
+ Alternative considered: <alternative and why it was not chosen>
20
+
21
+ ## Risks / Trade-offs
22
+
23
+ - <risk> -> <mitigation>
24
+
25
+ ## Coordination Notes
26
+
27
+ - Affected areas:
28
+ - Open handoffs:
29
+ - Implementation entry criteria:
30
+
31
+ ## Open Questions
32
+
33
+ -
@@ -0,0 +1,28 @@
1
+ ## Why
2
+
3
+ Describe the shared product goal, problem, or opportunity that makes this workspace-level change worth planning.
4
+
5
+ ## What Changes
6
+
7
+ -
8
+
9
+ ## Affected Areas
10
+
11
+ - Known:
12
+ - Unresolved:
13
+
14
+ ## Capabilities
15
+
16
+ ### New Capabilities
17
+
18
+ -
19
+
20
+ ### Modified Capabilities
21
+
22
+ -
23
+
24
+ ## Impact
25
+
26
+ - Workspace planning:
27
+ - Linked repos or folders:
28
+ - User-facing behavior:
@@ -0,0 +1,9 @@
1
+ ## ADDED Requirements
2
+
3
+ ### Requirement: <workspace requirement name>
4
+ The workspace plan SHALL describe the required behavior and affected area without creating repo-local artifacts during planning.
5
+
6
+ #### Scenario: <scenario name>
7
+ - **GIVEN** <context>
8
+ - **WHEN** <action>
9
+ - **THEN** <observable result>
@@ -0,0 +1,15 @@
1
+ ## 1. Workspace Planning
2
+
3
+ - [ ] 1.1 Confirm the shared product goal and unresolved scope questions.
4
+ - [ ] 1.2 Identify affected areas using registered workspace link names where applicable.
5
+ - [ ] 1.3 Review workspace-scoped specs and design before selecting implementation areas.
6
+
7
+ ## 2. Affected Area Implementation
8
+
9
+ - [ ] 2.1 Select an affected area and confirm its allowed edit root before implementation.
10
+ - [ ] 2.2 Create or update repo-local implementation artifacts only after the area is selected.
11
+
12
+ ## 3. Verification
13
+
14
+ - [ ] 3.1 Verify workspace planning artifacts remain the source of truth.
15
+ - [ ] 3.2 Record manual acceptance evidence and follow-up fixes.