codeforge-dev 1.9.0 → 1.10.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/.devcontainer/.env +3 -0
- package/.devcontainer/CHANGELOG.md +56 -0
- package/.devcontainer/CLAUDE.md +29 -8
- package/.devcontainer/README.md +61 -2
- package/.devcontainer/config/defaults/main-system-prompt.md +162 -128
- package/.devcontainer/config/defaults/rules/spec-workflow.md +10 -2
- package/.devcontainer/connect-external-terminal.sh +17 -17
- package/.devcontainer/devcontainer.json +143 -144
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +4 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +3 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +21 -11
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +186 -13
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/spec-reminder.py +2 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-check/SKILL.md +22 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/SKILL.md +7 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/backlog-template.md +19 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/roadmap-template.md +28 -8
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/SKILL.md +15 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/references/template.md +24 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-refine/SKILL.md +194 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-update/SKILL.md +19 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +19 -12
- package/.devcontainer/scripts/check-setup.sh +24 -25
- package/.devcontainer/scripts/setup-aliases.sh +88 -76
- package/.devcontainer/scripts/setup-projects.sh +172 -131
- package/.devcontainer/scripts/setup-terminal.sh +48 -0
- package/.devcontainer/scripts/setup-update-claude.sh +49 -107
- package/.devcontainer/scripts/setup.sh +4 -17
- package/README.md +2 -2
- package/package.json +1 -1
|
@@ -30,15 +30,15 @@ echo "Searching for running devcontainer..."
|
|
|
30
30
|
CONTAINER_ID=$(docker ps --filter "label=$CONTAINER_LABEL" --format "{{.ID}}" | head -n1)
|
|
31
31
|
|
|
32
32
|
if [ -z "$CONTAINER_ID" ]; then
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
echo ""
|
|
34
|
+
echo "ERROR: No running devcontainer found."
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Make sure your devcontainer is running:"
|
|
37
|
+
echo " 1. Open VS Code"
|
|
38
|
+
echo " 2. Open the folder containing .devcontainer/"
|
|
39
|
+
echo " 3. Use 'Dev Containers: Reopen in Container'"
|
|
40
|
+
echo ""
|
|
41
|
+
exit 1
|
|
42
42
|
fi
|
|
43
43
|
|
|
44
44
|
# Get container name for display
|
|
@@ -47,10 +47,10 @@ echo "Found container: $CONTAINER_NAME ($CONTAINER_ID)"
|
|
|
47
47
|
echo ""
|
|
48
48
|
|
|
49
49
|
# Check if tmux is available in the container
|
|
50
|
-
if ! docker exec "$CONTAINER_ID" which tmux
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
if ! docker exec "$CONTAINER_ID" which tmux >/dev/null 2>&1; then
|
|
51
|
+
echo "ERROR: tmux is not installed in the container."
|
|
52
|
+
echo "Rebuild the devcontainer to install the tmux feature."
|
|
53
|
+
exit 1
|
|
54
54
|
fi
|
|
55
55
|
|
|
56
56
|
echo "Connecting to tmux session '$TMUX_SESSION'..."
|
|
@@ -68,14 +68,14 @@ echo ""
|
|
|
68
68
|
# Pass UTF-8 locale so tmux renders Unicode correctly (not as underscores)
|
|
69
69
|
# Use tmux -u to force UTF-8 mode as a belt-and-suspenders measure
|
|
70
70
|
exec docker exec -it \
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
-e LANG=en_US.UTF-8 \
|
|
72
|
+
-e LC_ALL=en_US.UTF-8 \
|
|
73
|
+
--user vscode "$CONTAINER_ID" bash -c "
|
|
74
74
|
export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
|
|
75
75
|
if tmux has-session -t '$TMUX_SESSION' 2>/dev/null; then
|
|
76
76
|
tmux -u attach-session -t '$TMUX_SESSION'
|
|
77
77
|
else
|
|
78
|
-
tmux -u new-session -d -s '$TMUX_SESSION' -c
|
|
78
|
+
tmux -u new-session -d -s '$TMUX_SESSION' -c \"\${WORKSPACE_ROOT:-/workspaces}\"
|
|
79
79
|
sleep 0.5
|
|
80
80
|
tmux send-keys -t '$TMUX_SESSION' 'cc' Enter
|
|
81
81
|
tmux -u attach-session -t '$TMUX_SESSION'
|
|
@@ -1,144 +1,143 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "CodeForge - ${localWorkspaceFolderBasename}",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.14",
|
|
4
|
+
|
|
5
|
+
"workspaceFolder": "/workspaces",
|
|
6
|
+
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces,type=bind",
|
|
7
|
+
|
|
8
|
+
"remoteEnv": {
|
|
9
|
+
"WORKSPACE_ROOT": "/workspaces",
|
|
10
|
+
"CLAUDE_CONFIG_DIR": "/workspaces/.claude",
|
|
11
|
+
"GH_CONFIG_DIR": "/workspaces/.gh",
|
|
12
|
+
"TMPDIR": "/workspaces/.tmp"
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
// Feature install order: external runtimes first (Node, uv, Go, Bun),
|
|
16
|
+
// then Claude Code (needs Node), then custom features.
|
|
17
|
+
// npm-dependent features (agent-browser, ccusage, ccburn, biome, lsp-servers)
|
|
18
|
+
// must come after Node. uv-dependent features (ruff, claude-monitor) must
|
|
19
|
+
// come after uv. notify-hook is last (lightweight, no dependencies).
|
|
20
|
+
"overrideFeatureInstallOrder": [
|
|
21
|
+
"ghcr.io/devcontainers/features/node",
|
|
22
|
+
"ghcr.io/devcontainers/features/github-cli",
|
|
23
|
+
"ghcr.io/devcontainers/features/docker-outside-of-docker",
|
|
24
|
+
"ghcr.io/devcontainers-extra/features/uv",
|
|
25
|
+
"ghcr.io/rails/devcontainer/features/bun",
|
|
26
|
+
"ghcr.io/anthropics/devcontainer-features/claude-code",
|
|
27
|
+
"./features/tmux",
|
|
28
|
+
"./features/agent-browser",
|
|
29
|
+
"./features/claude-monitor",
|
|
30
|
+
"./features/ccusage",
|
|
31
|
+
"./features/ccburn",
|
|
32
|
+
"./features/ccstatusline",
|
|
33
|
+
"./features/ast-grep",
|
|
34
|
+
"./features/tree-sitter",
|
|
35
|
+
"./features/lsp-servers",
|
|
36
|
+
"./features/ruff",
|
|
37
|
+
"./features/shfmt",
|
|
38
|
+
"./features/dprint",
|
|
39
|
+
"./features/shellcheck",
|
|
40
|
+
"./features/hadolint",
|
|
41
|
+
"./features/biome",
|
|
42
|
+
"./features/notify-hook"
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
"features": {
|
|
46
|
+
"ghcr.io/devcontainers/features/node:1": {
|
|
47
|
+
"version": "lts",
|
|
48
|
+
"nodeGypDependencies": true
|
|
49
|
+
},
|
|
50
|
+
"ghcr.io/devcontainers/features/github-cli:1": {},
|
|
51
|
+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
|
|
52
|
+
"moby": false
|
|
53
|
+
},
|
|
54
|
+
"ghcr.io/devcontainers-extra/features/uv:1": {},
|
|
55
|
+
"ghcr.io/rails/devcontainer/features/bun:1.0.2": {},
|
|
56
|
+
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {},
|
|
57
|
+
"./features/tmux": {},
|
|
58
|
+
"./features/ccusage": {
|
|
59
|
+
"version": "latest",
|
|
60
|
+
"shells": "both",
|
|
61
|
+
"username": "automatic"
|
|
62
|
+
},
|
|
63
|
+
"./features/claude-monitor": {
|
|
64
|
+
"version": "latest",
|
|
65
|
+
"installer": "uv",
|
|
66
|
+
"username": "automatic"
|
|
67
|
+
},
|
|
68
|
+
"./features/ccburn": {
|
|
69
|
+
"version": "latest",
|
|
70
|
+
"shells": "both",
|
|
71
|
+
"username": "automatic"
|
|
72
|
+
},
|
|
73
|
+
"./features/ccstatusline": {
|
|
74
|
+
"username": "automatic"
|
|
75
|
+
},
|
|
76
|
+
"./features/ast-grep": {},
|
|
77
|
+
"./features/tree-sitter": {},
|
|
78
|
+
"./features/lsp-servers": {},
|
|
79
|
+
"./features/agent-browser": {},
|
|
80
|
+
"./features/ruff": {
|
|
81
|
+
"version": "latest",
|
|
82
|
+
"username": "automatic"
|
|
83
|
+
},
|
|
84
|
+
"./features/shfmt": { "version": "none" },
|
|
85
|
+
"./features/dprint": {
|
|
86
|
+
"version": "none",
|
|
87
|
+
"username": "automatic"
|
|
88
|
+
},
|
|
89
|
+
"./features/shellcheck": { "version": "none" },
|
|
90
|
+
"./features/hadolint": { "version": "none" },
|
|
91
|
+
"./features/biome": {},
|
|
92
|
+
"./features/notify-hook": {
|
|
93
|
+
"enableBell": true,
|
|
94
|
+
"enableOsc": true
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
"postStartCommand": "bash ${containerWorkspaceFolder}/.devcontainer/scripts/setup.sh",
|
|
99
|
+
|
|
100
|
+
"remoteUser": "vscode",
|
|
101
|
+
"containerUser": "vscode",
|
|
102
|
+
|
|
103
|
+
"customizations": {
|
|
104
|
+
"vscode": {
|
|
105
|
+
"settings": {
|
|
106
|
+
"terminal.integrated.profiles.linux": {
|
|
107
|
+
"bash": {
|
|
108
|
+
"path": "bash"
|
|
109
|
+
},
|
|
110
|
+
"Claude Teams (tmux)": {
|
|
111
|
+
"path": "bash",
|
|
112
|
+
"args": [
|
|
113
|
+
"-c",
|
|
114
|
+
"if tmux has-session -t claude-teams 2>/dev/null; then exec tmux -u new-session -t claude-teams; else exec tmux -u new-session -s claude-teams; fi"
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"terminal.integrated.defaultProfile.linux": "bash",
|
|
119
|
+
"terminal.integrated.enableBell": true,
|
|
120
|
+
"terminal.integrated.commandsToSkipShell": [
|
|
121
|
+
"-workbench.action.quickOpen",
|
|
122
|
+
"-workbench.action.terminal.focusFind"
|
|
123
|
+
],
|
|
124
|
+
"remote.extensionKind": {
|
|
125
|
+
"wenbopan.vscode-terminal-osc-notifier": ["ui"]
|
|
126
|
+
},
|
|
127
|
+
"projectManager.git.baseFolders": ["/workspaces"],
|
|
128
|
+
"projectManager.git.maxDepthRecursion": 2,
|
|
129
|
+
"projectManager.showProjectNameInStatusBar": true,
|
|
130
|
+
"projectManager.openInNewWindowWhenClickingInStatusBar": false,
|
|
131
|
+
"projectManager.projectsLocation": "/workspaces/.config/project-manager"
|
|
132
|
+
},
|
|
133
|
+
"extensions": [
|
|
134
|
+
"wenbopan.vscode-terminal-osc-notifier",
|
|
135
|
+
"GitHub.vscode-github-actions",
|
|
136
|
+
"fabiospampinato.vscode-todo-plus",
|
|
137
|
+
"alefragnani.project-manager"
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
"runArgs": ["--memory=6g", "--memory-swap=12g"]
|
|
143
|
+
}
|
|
@@ -171,8 +171,9 @@ Based on your exploration:
|
|
|
171
171
|
or update. Distinguish:
|
|
172
172
|
- **Roadmap entry**: one-line description of what the version delivers (no
|
|
173
173
|
implementation detail — that belongs in specs)
|
|
174
|
-
- **Feature spec**:
|
|
175
|
-
Status, Intent, Acceptance Criteria, Key Files, Schema, API, Dependencies)
|
|
174
|
+
- **Feature spec**: file following the standard template (Version,
|
|
175
|
+
Status, Intent, Acceptance Criteria, Key Files, Schema, API, Dependencies).
|
|
176
|
+
Aim for ~200 lines; split into sub-specs if significantly longer.
|
|
176
177
|
- **As-built update**: if modifying an existing feature, identify which spec
|
|
177
178
|
to update post-implementation
|
|
178
179
|
Plans that mix roadmap-level and spec-level detail produce artifacts too
|
|
@@ -239,7 +240,7 @@ List the 3-7 files most critical for implementing this plan:
|
|
|
239
240
|
- `/path/to/test_file.py` — Brief reason (e.g., "Test patterns to follow")
|
|
240
241
|
|
|
241
242
|
### Documentation Outputs
|
|
242
|
-
- New spec: `.specs/vX.Y.0/feature-name.md`
|
|
243
|
+
- New spec: `.specs/vX.Y.0/feature-name.md`
|
|
243
244
|
- Updated spec: `.specs/vX.Y.0/existing-feature.md` — changes: [list]
|
|
244
245
|
- Roadmap update: `.specs/roadmap.md` — add `[ ] feature` to vX.Y.0
|
|
245
246
|
|
|
@@ -160,9 +160,9 @@ For large codebases, focus on the public API surface rather than trying to docum
|
|
|
160
160
|
|
|
161
161
|
Produce documentation that serves the target audience. Different doc types have different readers.
|
|
162
162
|
|
|
163
|
-
**Sizing
|
|
164
|
-
should
|
|
165
|
-
independently useful without requiring other docs in the same context window.
|
|
163
|
+
**Sizing guideline:** Documentation files consumed by AI (CLAUDE.md, specs, architecture docs)
|
|
164
|
+
should aim for ~200 lines each. Split large documents by concern when practical. Each file
|
|
165
|
+
should be independently useful without requiring other docs in the same context window.
|
|
166
166
|
|
|
167
167
|
## Documentation Types
|
|
168
168
|
|
|
@@ -20,6 +20,7 @@ skills:
|
|
|
20
20
|
- spec-update
|
|
21
21
|
- spec-check
|
|
22
22
|
- spec-init
|
|
23
|
+
- spec-refine
|
|
23
24
|
---
|
|
24
25
|
|
|
25
26
|
# Spec Writer Agent
|
|
@@ -57,10 +58,14 @@ When uncertain, investigate first — read the code, check the docs — rather t
|
|
|
57
58
|
- **NEVER** make assumptions about behavior without checking the codebase. Use `Read`, `Glob`, and `Grep` to understand the current system before specifying changes.
|
|
58
59
|
- **NEVER** write vague requirements like "the system should be fast" or "the UI should be user-friendly." Every requirement must be specific, measurable, and testable.
|
|
59
60
|
- **NEVER** combine multiple independent requirements into a single statement. One requirement per line — this makes requirements individually testable and trackable.
|
|
60
|
-
- **NEVER**
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
- **NEVER** present decisions as settled facts unless the user explicitly approved them. Tech choices, architecture decisions, scope boundaries, performance targets, and behavioral defaults that you chose without user input MUST go in `## Open Questions` with options and trade-offs — not in Requirements as decided items.
|
|
62
|
+
- **ALL** requirements you generate MUST be tagged `[assumed]`. You never produce `[user-approved]` requirements — only `/spec-refine` does that after explicit user validation.
|
|
63
|
+
- **ALL** specs you produce MUST carry `**Approval:** draft`. After presenting a draft, state: "This spec requires `/spec-refine` before implementation can begin. All requirements are marked [assumed] until user-approved."
|
|
64
|
+
- **Aim for ~200 lines per spec.** When a spec grows beyond that, recommend
|
|
65
|
+
splitting into sub-specs in a feature subdirectory with a parent overview
|
|
66
|
+
that links them. Shorter specs are easier to consume and maintain, but
|
|
67
|
+
complex features sometimes need more space — don't sacrifice completeness
|
|
68
|
+
for an arbitrary cap.
|
|
64
69
|
- **NEVER** reproduce source code, SQL schemas, or type definitions inline.
|
|
65
70
|
Reference file paths instead (e.g., "see `src/engine/db/migrations/002.sql`
|
|
66
71
|
lines 48-70"). The code is the source of truth; duplicated snippets go stale.
|
|
@@ -116,9 +121,10 @@ Write the specification using the formats below.
|
|
|
116
121
|
3. **Write acceptance criteria** — Given/When/Then scenarios that define "done."
|
|
117
122
|
4. **Define non-functional requirements** — Performance, security, accessibility where relevant.
|
|
118
123
|
5. **List open questions** — Any unresolved decisions or unknowns that need stakeholder input.
|
|
119
|
-
6. **Check length** —
|
|
120
|
-
sub-specs by feature boundary
|
|
121
|
-
|
|
124
|
+
6. **Check length** — If the draft exceeds ~200 lines, consider whether it
|
|
125
|
+
would be clearer as sub-specs split by feature boundary with a parent
|
|
126
|
+
overview linking them. Each sub-spec should be independently loadable.
|
|
127
|
+
If the length is justified by complexity, note it and proceed.
|
|
122
128
|
7. **Reference, don't reproduce** — Scan your draft for inline code blocks
|
|
123
129
|
containing schemas, SQL, type definitions, or configuration. Replace with
|
|
124
130
|
file path references and brief descriptions of what's there.
|
|
@@ -235,6 +241,7 @@ Present specifications in this structure:
|
|
|
235
241
|
**Version:** v0.X.0
|
|
236
242
|
**Status:** planned
|
|
237
243
|
**Last Updated:** YYYY-MM-DD
|
|
244
|
+
**Approval:** draft
|
|
238
245
|
|
|
239
246
|
## Intent
|
|
240
247
|
[Problem statement + why — what exists now, what should change, who is affected]
|
|
@@ -258,18 +265,21 @@ Present specifications in this structure:
|
|
|
258
265
|
## Requirements
|
|
259
266
|
|
|
260
267
|
### Functional Requirements
|
|
261
|
-
FR-1: [EARS requirement]
|
|
262
|
-
FR-2: [EARS requirement]
|
|
268
|
+
FR-1 [assumed]: [EARS requirement]
|
|
269
|
+
FR-2 [assumed]: [EARS requirement]
|
|
263
270
|
...
|
|
264
271
|
|
|
265
272
|
### Non-Functional Requirements
|
|
266
|
-
NFR-1: [EARS requirement]
|
|
267
|
-
NFR-2: [EARS requirement]
|
|
273
|
+
NFR-1 [assumed]: [EARS requirement]
|
|
274
|
+
NFR-2 [assumed]: [EARS requirement]
|
|
268
275
|
...
|
|
269
276
|
|
|
270
277
|
## Dependencies
|
|
271
278
|
- [External system or module this feature depends on]
|
|
272
279
|
|
|
280
|
+
## Resolved Questions
|
|
281
|
+
[Populated by `/spec-refine`. Decisions explicitly approved by the user.]
|
|
282
|
+
|
|
273
283
|
## Open Questions
|
|
274
284
|
[Group related unknowns. For each question, provide:]
|
|
275
285
|
1. [Question] — **Type**: missing info / ambiguous behavior / policy decision
|