prizmkit 1.1.112 → 1.1.113
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/bundled/VERSION.json +3 -3
- package/bundled/adapters/codex/skill-adapter.js +4 -0
- package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +10 -10
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +1 -0
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +7 -0
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +7 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +7 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +7 -1
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-commit-report.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +7 -1
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +7 -1
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +87 -21
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +14 -0
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +42 -0
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/bug-planner/scripts/validate-bug-list.py +43 -3
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +6 -6
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +7 -16
- package/bundled/skills/feature-workflow/SKILL.md +8 -7
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +2 -2
- package/bundled/skills/prizmkit-deploy/references/database-setup.md +12 -3
- package/bundled/skills/prizmkit-prizm-docs/references/op-init.md +11 -13
- package/bundled/skills/prizmkit-test/SKILL.md +1 -1
- package/bundled/skills/prizmkit-test/references/boundary-coverage-protocol.md +1 -1
- package/bundled/skills/prizmkit-test/references/examples.md +2 -2
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +3 -2
- package/bundled/skills/refactor-workflow/SKILL.md +6 -5
- package/package.json +1 -1
package/bundled/VERSION.json
CHANGED
|
@@ -21,6 +21,10 @@ function applyCodexInteractionCompatibility(content) {
|
|
|
21
21
|
|
|
22
22
|
return content
|
|
23
23
|
.replace(/\bAskUserQuestion\b/g, 'request_user_input')
|
|
24
|
+
.replace(
|
|
25
|
+
/Use `request_user_input`; do not render path options as plain text\./g,
|
|
26
|
+
fallbackInstruction
|
|
27
|
+
)
|
|
24
28
|
.replace(
|
|
25
29
|
/Do NOT render options as plain text — the user must be able to click\/select\./g,
|
|
26
30
|
fallbackInstruction
|
|
@@ -81,8 +81,8 @@ acceptance_criteria, status
|
|
|
81
81
|
|
|
82
82
|
**Optional fields:**
|
|
83
83
|
```
|
|
84
|
-
priority, affected_feature, affected_modules, environment, critic,
|
|
85
|
-
critic_count, model
|
|
84
|
+
priority, dependencies, affected_feature, affected_modules, environment, critic,
|
|
85
|
+
critic_count, model, browser_interaction
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
| Property | Type | Enum/Pattern | Notes |
|
|
@@ -95,7 +95,8 @@ critic_count, model
|
|
|
95
95
|
| `error_source` | object | type enum: `stack_trace, user_report, failed_test, log_pattern, monitoring_alert` | ✓ REQUIRED |
|
|
96
96
|
| `verification_type` | string | `automated, manual, hybrid` | ✓ REQUIRED |
|
|
97
97
|
| `acceptance_criteria` | array | N/A | minItems: 1 |
|
|
98
|
-
| `status` | string | `pending,
|
|
98
|
+
| `status` | string | `pending, in_progress, completed, failed, skipped, needs_info` | ✓ REQUIRED; external list status only |
|
|
99
|
+
| `dependencies` | array | Pattern: `^B-\d{3}$` | Optional; bug IDs that must complete first |
|
|
99
100
|
| `affected_feature` | string | Pattern: `^F-\d{3}(-[A-Z])?$` | Optional; link to original feature |
|
|
100
101
|
| `affected_modules` | array | N/A | Optional; module names |
|
|
101
102
|
| `environment` | object | N/A | Optional; os, runtime, browser, version |
|
|
@@ -209,12 +210,11 @@ design_system, ci_pipeline
|
|
|
209
210
|
pending, in_progress, completed, failed, skipped, split, auto_skipped
|
|
210
211
|
```
|
|
211
212
|
|
|
212
|
-
**Bug Fix Status (
|
|
213
|
+
**Bug Fix Status (6 external values):**
|
|
213
214
|
```
|
|
214
|
-
pending,
|
|
215
|
+
pending, in_progress, completed, failed, skipped, needs_info
|
|
215
216
|
```
|
|
216
|
-
*
|
|
217
|
-
*NO "split" or "auto_skipped"*
|
|
217
|
+
*External bug-list status stays coarse. Fine-grained triage/reproduction/fix/verification phases belong in logs, checkpoints, and session metadata, not `bugs[].status`.*
|
|
218
218
|
|
|
219
219
|
**Refactor Status (5 values):**
|
|
220
220
|
```
|
|
@@ -227,10 +227,10 @@ pending, in_progress, completed, failed, skipped
|
|
|
227
227
|
| Schema | Dependencies | Pattern |
|
|
228
228
|
|--------|--------------|---------|
|
|
229
229
|
| Feature | `dependencies` (required) | `^F-\d{3}(-[A-Z])?$` - can reference sub-features |
|
|
230
|
-
| Bug Fix |
|
|
230
|
+
| Bug Fix | `dependencies` (optional) | `^B-\d{3}$` - can reference prerequisite bug fixes |
|
|
231
231
|
| Refactor | `dependencies` (required) | `^R-\d{3}$` - ONLY refactor IDs, no sub-IDs |
|
|
232
232
|
|
|
233
|
-
**
|
|
233
|
+
**Contract:** Bug Fix dependencies are supported as optional prerequisites. Runtime selects eligible bugs in stable list order after dependencies are completed.
|
|
234
234
|
|
|
235
235
|
### 4.5 Acceptance Criteria vs Task Lists
|
|
236
236
|
|
|
@@ -493,7 +493,7 @@ Located in `/dev-pipeline/templates/`:
|
|
|
493
493
|
|
|
494
494
|
### Status Enums
|
|
495
495
|
- **Feature**: `[pending, in_progress, completed, failed, skipped, split, auto_skipped]` (7 values)
|
|
496
|
-
- **Bug Fix**: `[pending,
|
|
496
|
+
- **Bug Fix**: `[pending, in_progress, completed, failed, skipped, needs_info]` (6 external values)
|
|
497
497
|
- **Refactor**: `[pending, in_progress, completed, failed, skipped]` (5 values)
|
|
498
498
|
|
|
499
499
|
### Complexity/Estimated Complexity Enums
|
|
@@ -1906,6 +1906,7 @@ def build_replacements(args, feature, features, global_context, script_dir):
|
|
|
1906
1906
|
"{{HAS_PLAN}}": "true" if artifacts["has_plan"] else "false",
|
|
1907
1907
|
"{{BROWSER_VERIFY_STEPS}}": browser_verify_steps,
|
|
1908
1908
|
"{{BROWSER_TOOL}}": browser_tool,
|
|
1909
|
+
"{{BROWSER_BLOCKING}}": "true" if browser_blocking else "false",
|
|
1909
1910
|
"{{AC_CHECKLIST}}": format_ac_checklist(
|
|
1910
1911
|
feature.get("acceptance_criteria", [])
|
|
1911
1912
|
),
|
|
@@ -417,6 +417,13 @@ def assemble_bugfix_sections(pipeline_mode, sections_dir, critic_enabled, browse
|
|
|
417
417
|
sections.append(("phase-browser", load_section(sections_dir, "phase-browser-verification-auto.md")))
|
|
418
418
|
if manual_gate:
|
|
419
419
|
sections.append(("bugfix-manual-gate", load_section(sections_dir, "bugfix-phase-manual-verification.md")))
|
|
420
|
+
sections.extend([
|
|
421
|
+
("bugfix-session-status", load_section(sections_dir, "bugfix-session-status.md")),
|
|
422
|
+
("bugfix-critical-paths", load_section(sections_dir, "bugfix-critical-paths.md")),
|
|
423
|
+
("failure-capture", load_section(sections_dir, "failure-capture.md")),
|
|
424
|
+
("bugfix-reminders", load_section(sections_dir, "bugfix-reminders.md")),
|
|
425
|
+
])
|
|
426
|
+
return sections
|
|
420
427
|
sections.extend([
|
|
421
428
|
("bugfix-phase-commit-report", load_section(sections_dir, "bugfix-phase-commit-report.md")),
|
|
422
429
|
("bugfix-session-status", load_section(sections_dir, "bugfix-session-status.md")),
|
|
@@ -338,7 +338,13 @@ Append results to `context-snapshot.md`:
|
|
|
338
338
|
Browser cleanup: confirmed
|
|
339
339
|
```
|
|
340
340
|
|
|
341
|
-
|
|
341
|
+
Browser blocking policy: `{{BROWSER_BLOCKING}}`.
|
|
342
|
+
|
|
343
|
+
If verification fails:
|
|
344
|
+
- If `{{BROWSER_BLOCKING}}` is `true`: mark checkpoint step `browser-verification` as `failed`, write `failure-log.md` with browser evidence, clean up the dev server/browser, and stop before commit.
|
|
345
|
+
- If `{{BROWSER_BLOCKING}}` is `false`: log the failure details, mark checkpoint step `browser-verification` according to the evidence, clean up the dev server/browser, and continue.
|
|
346
|
+
|
|
347
|
+
You MUST attempt verification and MUST clean up the dev server in both cases.
|
|
342
348
|
{{END_IF_BROWSER_INTERACTION}}
|
|
343
349
|
|
|
344
350
|
### Phase 4: Architecture Sync & Commit (SINGLE COMMIT)
|
|
@@ -488,7 +488,13 @@ Append results to `context-snapshot.md`:
|
|
|
488
488
|
Browser cleanup: confirmed
|
|
489
489
|
```
|
|
490
490
|
|
|
491
|
-
|
|
491
|
+
Browser blocking policy: `{{BROWSER_BLOCKING}}`.
|
|
492
|
+
|
|
493
|
+
If verification fails:
|
|
494
|
+
- If `{{BROWSER_BLOCKING}}` is `true`: mark checkpoint step `browser-verification` as `failed`, write `failure-log.md` with browser evidence, clean up the dev server/browser, and stop before commit.
|
|
495
|
+
- If `{{BROWSER_BLOCKING}}` is `false`: log the failure details, mark checkpoint step `browser-verification` according to the evidence, clean up the dev server/browser, and continue.
|
|
496
|
+
|
|
497
|
+
You MUST attempt verification and MUST clean up the dev server in both cases.
|
|
492
498
|
{{END_IF_BROWSER_INTERACTION}}
|
|
493
499
|
|
|
494
500
|
### Phase 6: Architecture Sync & Commit (SINGLE COMMIT)
|
|
@@ -483,7 +483,13 @@ Append results to `context-snapshot.md`:
|
|
|
483
483
|
Browser cleanup: confirmed
|
|
484
484
|
```
|
|
485
485
|
|
|
486
|
-
|
|
486
|
+
Browser blocking policy: `{{BROWSER_BLOCKING}}`.
|
|
487
|
+
|
|
488
|
+
If verification fails:
|
|
489
|
+
- If `{{BROWSER_BLOCKING}}` is `true`: mark checkpoint step `browser-verification` as `failed`, write `failure-log.md` with browser evidence, clean up the dev server/browser, and stop before commit.
|
|
490
|
+
- If `{{BROWSER_BLOCKING}}` is `false`: log the failure details, mark checkpoint step `browser-verification` according to the evidence, clean up the dev server/browser, and continue.
|
|
491
|
+
|
|
492
|
+
You MUST attempt verification and MUST clean up the dev server in both cases.
|
|
487
493
|
{{END_IF_BROWSER_INTERACTION}}
|
|
488
494
|
|
|
489
495
|
### Phase 6: Retrospective & Commit (SINGLE COMMIT) — DO NOT SKIP
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
### Phase 4: Commit & Learn
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This phase is included only for sessions allowed to commit. Fresh manual/hybrid bugfix prompts omit this phase entirely and stop as partial before retrospective/commit.
|
|
4
4
|
|
|
5
5
|
**Bug Fix Documentation Policy**:
|
|
6
6
|
- Default: run `/prizmkit-retrospective` with structural sync only.
|
|
@@ -117,5 +117,11 @@ Append results to `context-snapshot.md`:
|
|
|
117
117
|
Browser cleanup: confirmed
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
Browser blocking policy: `{{BROWSER_BLOCKING}}`.
|
|
121
|
+
|
|
122
|
+
If verification fails:
|
|
123
|
+
- If `{{BROWSER_BLOCKING}}` is `true`: mark checkpoint step `browser-verification` as `failed`, write `failure-log.md` with browser evidence, clean up the dev server/browser, and stop before commit.
|
|
124
|
+
- If `{{BROWSER_BLOCKING}}` is `false`: log the failure details, mark checkpoint step `browser-verification` according to the evidence, clean up the dev server/browser, and continue.
|
|
125
|
+
|
|
126
|
+
You MUST attempt verification and MUST clean up the dev server in both cases.
|
|
121
127
|
|
|
@@ -114,5 +114,11 @@ Append results to `context-snapshot.md`:
|
|
|
114
114
|
Browser cleanup: confirmed
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
Browser blocking policy: `{{BROWSER_BLOCKING}}`.
|
|
118
|
+
|
|
119
|
+
If verification fails:
|
|
120
|
+
- If `{{BROWSER_BLOCKING}}` is `true`: mark checkpoint step `browser-verification` as `failed`, write `failure-log.md` with browser evidence, clean up the dev server/browser, and stop before commit.
|
|
121
|
+
- If `{{BROWSER_BLOCKING}}` is `false`: log the failure details, mark checkpoint step `browser-verification` according to the evidence, clean up the dev server/browser, and continue.
|
|
122
|
+
|
|
123
|
+
You MUST attempt verification and MUST clean up the dev server in both cases.
|
|
118
124
|
|
|
@@ -101,5 +101,11 @@ Server cleanup: confirmed
|
|
|
101
101
|
Browser cleanup: confirmed
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
Browser blocking policy: `{{BROWSER_BLOCKING}}`.
|
|
105
|
+
|
|
106
|
+
If verification fails:
|
|
107
|
+
- If `{{BROWSER_BLOCKING}}` is `true`: mark checkpoint step `browser-verification` as `failed`, write `failure-log.md` with browser evidence, clean up the dev server/browser, and stop before commit.
|
|
108
|
+
- If `{{BROWSER_BLOCKING}}` is `false`: log the failure details, mark checkpoint step `browser-verification` according to the evidence, clean up the dev server/browser, and continue.
|
|
109
|
+
|
|
110
|
+
You MUST attempt verification and MUST clean up the dev server in both cases.
|
|
105
111
|
|
|
@@ -1100,7 +1100,10 @@ def _ensure_agent_files(project, platforms=("claude", "codex")):
|
|
|
1100
1100
|
(agents_dir / f"prizm-dev-team-{name}{suffix}").write_text("agent\n", encoding="utf-8")
|
|
1101
1101
|
|
|
1102
1102
|
|
|
1103
|
-
def _render_bugfix_prompt(
|
|
1103
|
+
def _render_bugfix_prompt(
|
|
1104
|
+
tmp_path, platform="claude", explicit_platform=None,
|
|
1105
|
+
bug_overrides=None, retry_count="0", resume_phase="null",
|
|
1106
|
+
):
|
|
1104
1107
|
from generate_bugfix_prompt import main as bugfix_main
|
|
1105
1108
|
|
|
1106
1109
|
project = tmp_path / "bugfix-project"
|
|
@@ -1112,8 +1115,11 @@ def _render_bugfix_prompt(tmp_path, platform="claude", explicit_platform=None):
|
|
|
1112
1115
|
_ensure_agent_files(project)
|
|
1113
1116
|
bug_list = project / ".prizmkit" / "plans" / "bug-fix-list.json"
|
|
1114
1117
|
bug_list.parent.mkdir(parents=True)
|
|
1118
|
+
bug = {"id": "B-001", "title": "Broken", "description": "Fix it", "acceptance_criteria": ["Works"]}
|
|
1119
|
+
if bug_overrides:
|
|
1120
|
+
bug.update(bug_overrides)
|
|
1115
1121
|
bug_list.write_text(json.dumps({
|
|
1116
|
-
"bugs": [
|
|
1122
|
+
"bugs": [bug],
|
|
1117
1123
|
"global_context": {"language": "Python"},
|
|
1118
1124
|
}), encoding="utf-8")
|
|
1119
1125
|
output = project / "bugfix-prompt.md"
|
|
@@ -1130,8 +1136,8 @@ def _render_bugfix_prompt(tmp_path, platform="claude", explicit_platform=None):
|
|
|
1130
1136
|
"--bug-id", "B-001",
|
|
1131
1137
|
"--session-id", "session-1",
|
|
1132
1138
|
"--run-id", "run-1",
|
|
1133
|
-
"--retry-count",
|
|
1134
|
-
"--resume-phase",
|
|
1139
|
+
"--retry-count", retry_count,
|
|
1140
|
+
"--resume-phase", resume_phase,
|
|
1135
1141
|
"--state-dir", str(project / ".prizmkit" / "state" / "bugfix"),
|
|
1136
1142
|
"--project-root", str(project),
|
|
1137
1143
|
"--output", str(output),
|
|
@@ -1150,7 +1156,7 @@ def _render_bugfix_prompt(tmp_path, platform="claude", explicit_platform=None):
|
|
|
1150
1156
|
return output.read_text(encoding="utf-8")
|
|
1151
1157
|
|
|
1152
1158
|
|
|
1153
|
-
def _render_refactor_prompt(tmp_path, platform="claude", explicit_platform=None):
|
|
1159
|
+
def _render_refactor_prompt(tmp_path, platform="claude", explicit_platform=None, refactor_overrides=None):
|
|
1154
1160
|
from generate_refactor_prompt import main as refactor_main
|
|
1155
1161
|
|
|
1156
1162
|
project = tmp_path / "refactor-project"
|
|
@@ -1162,14 +1168,17 @@ def _render_refactor_prompt(tmp_path, platform="claude", explicit_platform=None)
|
|
|
1162
1168
|
_ensure_agent_files(project)
|
|
1163
1169
|
refactor_list = project / ".prizmkit" / "plans" / "refactor-list.json"
|
|
1164
1170
|
refactor_list.parent.mkdir(parents=True)
|
|
1171
|
+
refactor = {
|
|
1172
|
+
"id": "R-001",
|
|
1173
|
+
"title": "Restructure",
|
|
1174
|
+
"description": "Preserve behavior",
|
|
1175
|
+
"acceptance_criteria": ["Behavior preserved"],
|
|
1176
|
+
"scope": {"files": ["src/a.py"], "modules": ["src"]},
|
|
1177
|
+
}
|
|
1178
|
+
if refactor_overrides:
|
|
1179
|
+
refactor.update(refactor_overrides)
|
|
1165
1180
|
refactor_list.write_text(json.dumps({
|
|
1166
|
-
"refactors": [
|
|
1167
|
-
"id": "R-001",
|
|
1168
|
-
"title": "Restructure",
|
|
1169
|
-
"description": "Preserve behavior",
|
|
1170
|
-
"acceptance_criteria": ["Behavior preserved"],
|
|
1171
|
-
"scope": {"files": ["src/a.py"], "modules": ["src"]},
|
|
1172
|
-
}],
|
|
1181
|
+
"refactors": [refactor],
|
|
1173
1182
|
"global_context": {"language": "Python"},
|
|
1174
1183
|
}), encoding="utf-8")
|
|
1175
1184
|
output = project / "refactor-prompt.md"
|
|
@@ -1189,18 +1198,14 @@ def _render_refactor_prompt(tmp_path, platform="claude", explicit_platform=None)
|
|
|
1189
1198
|
"--retry-count", "0",
|
|
1190
1199
|
"--resume-phase", "null",
|
|
1191
1200
|
"--state-dir", str(project / ".prizmkit" / "state" / "refactor"),
|
|
1201
|
+
"--project-root", str(project),
|
|
1192
1202
|
"--output", str(output),
|
|
1193
1203
|
]
|
|
1194
|
-
old_cwd = os.getcwd()
|
|
1195
|
-
os.chdir(project)
|
|
1196
1204
|
try:
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
raise
|
|
1202
|
-
finally:
|
|
1203
|
-
os.chdir(old_cwd)
|
|
1205
|
+
refactor_main()
|
|
1206
|
+
except SystemExit as exc:
|
|
1207
|
+
if exc.code not in (0, None):
|
|
1208
|
+
raise
|
|
1204
1209
|
finally:
|
|
1205
1210
|
os.sys.argv = old_argv
|
|
1206
1211
|
if old_platform is None:
|
|
@@ -1210,6 +1215,67 @@ def _render_refactor_prompt(tmp_path, platform="claude", explicit_platform=None)
|
|
|
1210
1215
|
return output.read_text(encoding="utf-8")
|
|
1211
1216
|
|
|
1212
1217
|
|
|
1218
|
+
class TestBrowserBlockingPromptPolicy:
|
|
1219
|
+
def test_feature_bugfix_refactor_blocking_browser_policy_stops_before_commit(self, tmp_path):
|
|
1220
|
+
browser_interaction = {
|
|
1221
|
+
"tool": "auto",
|
|
1222
|
+
"blocking": True,
|
|
1223
|
+
"verify_steps": ["Open the page"],
|
|
1224
|
+
}
|
|
1225
|
+
prompts = [
|
|
1226
|
+
_render_feature_prompt(tmp_path / "feature-browser-blocking", browser_interaction=browser_interaction),
|
|
1227
|
+
_render_bugfix_prompt(tmp_path / "bugfix-browser-blocking", bug_overrides={"browser_interaction": browser_interaction}),
|
|
1228
|
+
_render_refactor_prompt(tmp_path / "refactor-browser-blocking", refactor_overrides={"browser_interaction": browser_interaction}),
|
|
1229
|
+
]
|
|
1230
|
+
|
|
1231
|
+
for prompt in prompts:
|
|
1232
|
+
assert "Browser blocking policy: `true`" in prompt
|
|
1233
|
+
assert "stop before commit" in prompt
|
|
1234
|
+
assert "Failures do NOT block the commit" not in prompt
|
|
1235
|
+
|
|
1236
|
+
def test_feature_bugfix_refactor_nonblocking_browser_policy_continues(self, tmp_path):
|
|
1237
|
+
browser_interaction = {
|
|
1238
|
+
"tool": "auto",
|
|
1239
|
+
"blocking": False,
|
|
1240
|
+
"verify_steps": ["Open the page"],
|
|
1241
|
+
}
|
|
1242
|
+
prompts = [
|
|
1243
|
+
_render_feature_prompt(tmp_path / "feature-browser-nonblocking", browser_interaction=browser_interaction),
|
|
1244
|
+
_render_bugfix_prompt(tmp_path / "bugfix-browser-nonblocking", bug_overrides={"browser_interaction": browser_interaction}),
|
|
1245
|
+
_render_refactor_prompt(tmp_path / "refactor-browser-nonblocking", refactor_overrides={"browser_interaction": browser_interaction}),
|
|
1246
|
+
]
|
|
1247
|
+
|
|
1248
|
+
for prompt in prompts:
|
|
1249
|
+
assert "Browser blocking policy: `false`" in prompt
|
|
1250
|
+
assert "clean up the dev server/browser, and continue" in prompt
|
|
1251
|
+
assert "Failures do NOT block the commit" not in prompt
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
class TestManualHybridBugfixPromptPolicy:
|
|
1255
|
+
def test_fresh_manual_bugfix_prompt_stops_before_commit_phase(self, tmp_path):
|
|
1256
|
+
prompt = _render_bugfix_prompt(
|
|
1257
|
+
tmp_path / "fresh-manual-bugfix",
|
|
1258
|
+
bug_overrides={"verification_type": "manual"},
|
|
1259
|
+
)
|
|
1260
|
+
|
|
1261
|
+
assert "Manual / Hybrid Verification Gate" in prompt
|
|
1262
|
+
assert "Stop before `/prizmkit-retrospective` and `/prizmkit-committer`" in prompt
|
|
1263
|
+
assert "### Phase 4: Commit & Learn" not in prompt
|
|
1264
|
+
assert "Run `/prizmkit-committer` with commit prefix" not in prompt
|
|
1265
|
+
|
|
1266
|
+
def test_recovery_manual_bugfix_prompt_includes_commit_phase_with_substitution_policy(self, tmp_path):
|
|
1267
|
+
prompt = _render_bugfix_prompt(
|
|
1268
|
+
tmp_path / "recovery-manual-bugfix",
|
|
1269
|
+
bug_overrides={"verification_type": "manual"},
|
|
1270
|
+
retry_count="1",
|
|
1271
|
+
)
|
|
1272
|
+
|
|
1273
|
+
assert "Manual / Hybrid Verification Gate" not in prompt
|
|
1274
|
+
assert "Recovery-class session: automated verification may substitute for manual/hybrid UAT" in prompt
|
|
1275
|
+
assert "### Phase 4: Commit & Learn" in prompt
|
|
1276
|
+
assert "Run `/prizmkit-committer` with commit prefix" in prompt
|
|
1277
|
+
|
|
1278
|
+
|
|
1213
1279
|
class TestHeadlessPromptCleanupF033:
|
|
1214
1280
|
def test_rendered_feature_bugfix_refactor_prompts_are_clean(self, tmp_path):
|
|
1215
1281
|
prompts = []
|
|
@@ -307,6 +307,20 @@ def test_template_source_is_clean_for_headless_prompt_contract():
|
|
|
307
307
|
assert forbidden not in content
|
|
308
308
|
|
|
309
309
|
|
|
310
|
+
def test_bugfix_prompt_keeps_fine_grained_phases_out_of_external_status_contract():
|
|
311
|
+
content = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
|
|
312
|
+
old_statuses = ["triaging", "reproducing", "fixing", "verifying"]
|
|
313
|
+
|
|
314
|
+
assert "external bug-list status field" in content
|
|
315
|
+
assert "pending`, `in_progress`, `completed`, `failed`, `skipped`, or `needs_info`" in content
|
|
316
|
+
for status in old_statuses:
|
|
317
|
+
assert f"status=\"{status}\"" not in content
|
|
318
|
+
assert f"status = \"{status}\"" not in content
|
|
319
|
+
assert f"status='{status}'" not in content
|
|
320
|
+
assert f"status = '{status}'" not in content
|
|
321
|
+
assert f"Set bug status to `{status}`" not in content
|
|
322
|
+
|
|
323
|
+
|
|
310
324
|
# ---------------------------------------------------------------------------
|
|
311
325
|
# Anti-Bash regression guardrails (F-039)
|
|
312
326
|
# Note: grep -n, sed -n, grep -q, wc -l excluded — referenced in bugfix context
|
|
@@ -514,6 +514,48 @@ def test_init_scripts_reject_missing_self_and_cycle_dependencies(tmp_path):
|
|
|
514
514
|
assert any(expected_fragments[scenario] in error for error in payload["errors"])
|
|
515
515
|
|
|
516
516
|
|
|
517
|
+
def test_bug_planner_validator_rejects_dependency_cycles():
|
|
518
|
+
from importlib.util import module_from_spec, spec_from_file_location
|
|
519
|
+
|
|
520
|
+
script_path = REPO_ROOT / "core" / "skills" / "orchestration-skill" / "pipelines" / "bug-planner" / "scripts" / "validate-bug-list.py"
|
|
521
|
+
spec = spec_from_file_location("bug_planner_validate_bug_list", script_path)
|
|
522
|
+
module = module_from_spec(spec)
|
|
523
|
+
spec.loader.exec_module(module)
|
|
524
|
+
|
|
525
|
+
result = module.validate({
|
|
526
|
+
"$schema": "dev-pipeline-bug-fix-list-v1",
|
|
527
|
+
"project_name": "Fake",
|
|
528
|
+
"bugs": [
|
|
529
|
+
{
|
|
530
|
+
"id": "B-001",
|
|
531
|
+
"title": "First",
|
|
532
|
+
"description": "First bug",
|
|
533
|
+
"severity": "medium",
|
|
534
|
+
"error_source": {"type": "user_report"},
|
|
535
|
+
"verification_type": "manual",
|
|
536
|
+
"acceptance_criteria": ["fixed"],
|
|
537
|
+
"dependencies": ["B-002"],
|
|
538
|
+
"status": "pending",
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
"id": "B-002",
|
|
542
|
+
"title": "Second",
|
|
543
|
+
"description": "Second bug",
|
|
544
|
+
"severity": "medium",
|
|
545
|
+
"error_source": {"type": "user_report"},
|
|
546
|
+
"verification_type": "manual",
|
|
547
|
+
"acceptance_criteria": ["fixed"],
|
|
548
|
+
"dependencies": ["B-001"],
|
|
549
|
+
"status": "pending",
|
|
550
|
+
},
|
|
551
|
+
],
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
assert result["valid"] is False
|
|
555
|
+
assert any("Dependency cycle detected" in error for error in result["errors"])
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
517
559
|
def _family_items(kind, entries):
|
|
518
560
|
items = []
|
|
519
561
|
for item_id, dependencies, status in entries:
|
|
@@ -34,6 +34,38 @@ BUG_ID_PATTERN = re.compile(r"^B-\d{3}$")
|
|
|
34
34
|
SCHEMA_VERSION = "dev-pipeline-bug-fix-list-v1"
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
def _find_dependency_cycle(dep_map, item_ids):
|
|
38
|
+
"""Return one dependency cycle as a list of bug IDs, or an empty list."""
|
|
39
|
+
visiting = set()
|
|
40
|
+
visited = set()
|
|
41
|
+
stack = []
|
|
42
|
+
|
|
43
|
+
def visit(node):
|
|
44
|
+
visiting.add(node)
|
|
45
|
+
stack.append(node)
|
|
46
|
+
for dep in dep_map.get(node, []):
|
|
47
|
+
if dep not in item_ids:
|
|
48
|
+
continue
|
|
49
|
+
if dep in visiting:
|
|
50
|
+
start = stack.index(dep)
|
|
51
|
+
return stack[start:] + [dep]
|
|
52
|
+
if dep not in visited:
|
|
53
|
+
cycle = visit(dep)
|
|
54
|
+
if cycle:
|
|
55
|
+
return cycle
|
|
56
|
+
stack.pop()
|
|
57
|
+
visiting.remove(node)
|
|
58
|
+
visited.add(node)
|
|
59
|
+
return []
|
|
60
|
+
|
|
61
|
+
for bug_id in sorted(item_ids):
|
|
62
|
+
if bug_id not in visited:
|
|
63
|
+
cycle = visit(bug_id)
|
|
64
|
+
if cycle:
|
|
65
|
+
return cycle
|
|
66
|
+
return []
|
|
67
|
+
|
|
68
|
+
|
|
37
69
|
def _err(msg):
|
|
38
70
|
"""Print an error message to stderr."""
|
|
39
71
|
print("ERROR: {}".format(msg), file=sys.stderr)
|
|
@@ -181,15 +213,23 @@ def validate(data, feature_ids=None):
|
|
|
181
213
|
for bug in bugs
|
|
182
214
|
if BUG_ID_PATTERN.match(str(bug.get("id", "")))
|
|
183
215
|
}
|
|
216
|
+
dep_map = {bug_id: [] for bug_id in known_ids}
|
|
184
217
|
for i, bug in enumerate(bugs):
|
|
185
218
|
bug_id = bug.get("id", "")
|
|
186
219
|
deps = bug.get("dependencies", []) or []
|
|
187
220
|
if not isinstance(deps, list):
|
|
188
221
|
continue
|
|
189
222
|
for dep in deps:
|
|
190
|
-
if isinstance(dep, str) and BUG_ID_PATTERN.match(dep)
|
|
191
|
-
|
|
192
|
-
|
|
223
|
+
if isinstance(dep, str) and BUG_ID_PATTERN.match(dep):
|
|
224
|
+
if dep not in known_ids:
|
|
225
|
+
errors.append("bugs[{}] ({}): dependency '{}' does not exist".format(
|
|
226
|
+
i, bug_id, dep))
|
|
227
|
+
elif BUG_ID_PATTERN.match(str(bug_id)):
|
|
228
|
+
dep_map.setdefault(bug_id, []).append(dep)
|
|
229
|
+
|
|
230
|
+
cycle = _find_dependency_cycle(dep_map, known_ids)
|
|
231
|
+
if cycle:
|
|
232
|
+
errors.append("Dependency cycle detected: {}".format(" -> ".join(cycle)))
|
|
193
233
|
|
|
194
234
|
return {
|
|
195
235
|
"valid": len(errors) == 0,
|
|
@@ -5,7 +5,7 @@ description: "Launch and manage the bugfix pipeline from within an AI CLI sessio
|
|
|
5
5
|
|
|
6
6
|
# Bugfix-Pipeline Launcher
|
|
7
7
|
|
|
8
|
-
Launch the autonomous bug fix pipeline from within an AI CLI conversation.
|
|
8
|
+
Launch the autonomous bug fix pipeline from within an AI CLI conversation. Only Background daemon mode is fully detached and survives AI CLI session closure; Foreground runs in the current session, and Manual prints commands without launching.
|
|
9
9
|
|
|
10
10
|
### Execution Mode
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ Three execution modes are available. The user chooses one before configuring oth
|
|
|
15
15
|
2. **Background daemon** — `python3 ./.prizmkit/dev-pipeline/cli.py daemon bugfix start .prizmkit/plans/bug-fix-list.json`. Runs fully detached, survives AI CLI session closure.
|
|
16
16
|
3. **Manual** — Display the assembled command(s) only. Do not execute anything. User runs them on their own.
|
|
17
17
|
|
|
18
|
-
**Background mode traceability**: Daemon mode metadata and logs are written by the Python runtime (`daemon bugfix start/status/logs`). Do not
|
|
18
|
+
**Background mode traceability**: Daemon mode metadata and logs are written by the Python runtime (`daemon bugfix start/status/logs`). Do not create any extra launcher-managed audit file.
|
|
19
19
|
|
|
20
20
|
### When to Use
|
|
21
21
|
|
|
@@ -90,7 +90,6 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
90
90
|
data = json.load(f)
|
|
91
91
|
bugs = data.get('bugs', [])
|
|
92
92
|
severity_order = {'critical': 0, 'high': 1, 'medium': 2, 'low': 3}
|
|
93
|
-
bugs_sorted = sorted(bugs, key=lambda b: (severity_order.get(b.get('severity', 'medium'), 2), b.get('priority', 99)))
|
|
94
93
|
print(f'Total bugs: {len(bugs)}')
|
|
95
94
|
sev_counts = {}
|
|
96
95
|
for b in bugs:
|
|
@@ -98,7 +97,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
98
97
|
sev_counts[s] = sev_counts.get(s, 0) + 1
|
|
99
98
|
print(f'By severity: {dict(sorted(sev_counts.items(), key=lambda x: severity_order.get(x[0], 2)))}')
|
|
100
99
|
print()
|
|
101
|
-
for b in
|
|
100
|
+
for b in bugs:
|
|
102
101
|
print(f\" {b['id']}: [{b.get('severity','?').upper()}] {b.get('title', 'untitled')}\")
|
|
103
102
|
"
|
|
104
103
|
```
|
|
@@ -165,6 +164,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
165
164
|
- Summarize results: total bugs, fixed, failed, skipped
|
|
166
165
|
- If all fixed: each bug session has already run `prizmkit-retrospective` internally (structural sync by default; full retrospective when the fix changed interfaces, dependencies, or observable behavior). Ask user what's next.
|
|
167
166
|
- If some failed: show failed bug IDs and suggest `python3 ./.prizmkit/dev-pipeline/cli.py reset bugfix <B-XXX> --clean --run` for a fresh retry
|
|
167
|
+
- **Browser verification**: Bug sessions with `browser_interaction` perform their own verification attempts during execution. After completion, use `python3 ./.prizmkit/dev-pipeline/cli.py bugfix status .prizmkit/plans/bug-fix-list.json` and per-bug session logs as the source of truth before summarizing browser verification results.
|
|
168
168
|
|
|
169
169
|
**If background daemon**:
|
|
170
170
|
1. Verify launch:
|
|
@@ -264,9 +264,9 @@ Read `${SKILL_DIR}/references/configuration.md` for the full error handling tabl
|
|
|
264
264
|
### Integration Notes
|
|
265
265
|
|
|
266
266
|
- **After bug-planner**: This is the natural next step. When user finishes bug planning and has `.prizmkit/plans/bug-fix-list.json`, suggest launching the bugfix pipeline.
|
|
267
|
-
- **Session independence**:
|
|
267
|
+
- **Session independence**: Only Background daemon mode runs detached. Foreground runs in the current AI CLI session, and Manual mode prints commands without launching.
|
|
268
268
|
- **Single instance per family**: Only one bugfix pipeline can run at a time. Different pipeline families may coexist because they use separate daemon metadata and state directories.
|
|
269
|
-
- **
|
|
269
|
+
- **Pipeline coexistence**: Bugfix, feature, and refactor pipelines use separate state directories (`.prizmkit/state/bugfix/`, `.prizmkit/state/features/`, `.prizmkit/state/refactor/`), so all three can run simultaneously without conflict.
|
|
270
270
|
- **State preservation**: Stopping and restarting the bugfix pipeline resumes from where it left off -- completed bugs are not re-fixed.
|
|
271
271
|
- **Bug ordering**: Dependencies are active. Runtime selects eligible bugs in stable list order after dependencies are completed; planners should order unrelated bugs by severity/priority before launch.
|
|
272
272
|
- **Background mode traceability**: Daemon mode metadata/logging is runtime-owned; use `daemon bugfix status` and `daemon bugfix logs`.
|
|
@@ -309,22 +309,13 @@ Notes:
|
|
|
309
309
|
|
|
310
310
|
After pipeline completion, if features have `browser_interaction` fields and the corresponding browser tool (`playwright-cli` or `opencli`) is installed:
|
|
311
311
|
|
|
312
|
-
If list status may be stale,
|
|
312
|
+
If list status may be stale, use the runtime status command as the source of truth for completion state:
|
|
313
313
|
`python3 ./.prizmkit/dev-pipeline/cli.py feature status .prizmkit/plans/feature-list.json`.
|
|
314
314
|
|
|
315
|
-
1. **Check which features
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
with open('.prizmkit/plans/feature-list.json') as f:
|
|
320
|
-
data = json.load(f)
|
|
321
|
-
for feat in data.get('features', []):
|
|
322
|
-
bi = feat.get('browser_interaction')
|
|
323
|
-
if bi and feat.get('status') == 'completed':
|
|
324
|
-
tool = bi.get('tool', 'auto') if isinstance(bi, dict) else 'auto'
|
|
325
|
-
print(f\" {feat['id']}: {feat.get('title','')} (tool: {tool})\")
|
|
326
|
-
" 2>/dev/null
|
|
327
|
-
```
|
|
315
|
+
1. **Check which completed features have browser verification configured**:
|
|
316
|
+
- Read `browser_interaction` configuration from `.prizmkit/plans/feature-list.json`.
|
|
317
|
+
- Use the runtime status command output to decide which configured features are actually completed.
|
|
318
|
+
- Do not rely on list-file `status` alone when runtime state exists, because daemon/foreground bookkeeping may be newer than the plan file.
|
|
328
319
|
|
|
329
320
|
2. **Ask user**: "N features have browser verification configured. Run browser verification now? (Y/n)"
|
|
330
321
|
|
|
@@ -352,8 +343,8 @@ Read `${SKILL_DIR}/references/configuration.md` for the full error handling tabl
|
|
|
352
343
|
### Integration Notes
|
|
353
344
|
|
|
354
345
|
- **After feature-planner**: This is the natural next step. When user finishes planning and has `.prizmkit/plans/feature-list.json`, suggest launching the pipeline.
|
|
355
|
-
- **Session independence**:
|
|
346
|
+
- **Session independence**: Only Background daemon mode runs detached. Foreground runs in the current AI CLI session, and Manual mode prints commands without launching.
|
|
356
347
|
- **Single instance per family**: Only one feature pipeline can run at a time. Different pipeline families may coexist because they use separate daemon metadata and state directories.
|
|
357
|
-
- **Pipeline coexistence**: Feature and
|
|
348
|
+
- **Pipeline coexistence**: Feature, bugfix, and refactor pipelines use separate state directories (`.prizmkit/state/features/`, `.prizmkit/state/bugfix/`, `.prizmkit/state/refactor/`), so all three can run simultaneously without conflict.
|
|
358
349
|
- **State preservation**: Stopping and restarting the pipeline resumes from where it left off -- completed features are not re-run.
|
|
359
350
|
- **HANDOFF**: After pipeline completes all features, each session has already run `prizmkit-retrospective` internally. Ask user what's next.
|
|
@@ -87,7 +87,7 @@ For existing-project feature work:
|
|
|
87
87
|
Question: How would you like to proceed?
|
|
88
88
|
Header: Approach
|
|
89
89
|
Options:
|
|
90
|
-
- Implement now (Fast Path) — current session/current workspace via /prizmkit-plan -> /prizmkit-implement -> review/retro/
|
|
90
|
+
- Implement now (Fast Path) — current session/current workspace via simplified /prizmkit-plan -> /prizmkit-implement -> conditional test/review/retro -> /prizmkit-committer
|
|
91
91
|
- Use Pipeline Path — feature-planner creates/reviews feature-list.json, then feature-pipeline-launcher configures execution
|
|
92
92
|
- Continue clarifying — ask a few more route-level questions before choosing
|
|
93
93
|
```
|
|
@@ -166,12 +166,13 @@ Do not generate `feature-list.json` inside this workflow; `feature-planner` owns
|
|
|
166
166
|
|
|
167
167
|
Use Fast Path only after explicit user selection.
|
|
168
168
|
|
|
169
|
-
1. Invoke `/prizmkit-plan` with the handoff brief.
|
|
169
|
+
1. Invoke `/prizmkit-plan` with the handoff brief; use simplified planning for this scoped feature.
|
|
170
170
|
2. Invoke `/prizmkit-implement` after the plan is ready.
|
|
171
|
-
3. Run `/prizmkit-
|
|
172
|
-
4. Run `/prizmkit-
|
|
173
|
-
5. Run `/prizmkit-
|
|
174
|
-
6.
|
|
171
|
+
3. Run `/prizmkit-test` only when risk triggers match: behavior, public interface, data model, security/permission/payment, deployment readiness, or explicit user verification request.
|
|
172
|
+
4. Run `/prizmkit-code-review` when the user requested review, implementation uncertainty is high, or Full-path-level risk appears during implementation.
|
|
173
|
+
5. Run `/prizmkit-retrospective` only when structure, interfaces, dependencies, behavior, or durable project knowledge changed.
|
|
174
|
+
6. Run `/prizmkit-committer` with a `feat(<scope>):` message.
|
|
175
|
+
7. End the workflow after commit; do not call `feature-planner`, `feature-pipeline-launcher`, or monitoring.
|
|
175
176
|
|
|
176
177
|
If implementation scope grows beyond the Fast Path criteria, pause and ask whether to switch to Pipeline Path.
|
|
177
178
|
|
|
@@ -236,6 +237,6 @@ For start/stop/logs/retry execution, hand off to `feature-pipeline-launcher`; do
|
|
|
236
237
|
|
|
237
238
|
## Output
|
|
238
239
|
|
|
239
|
-
- Fast Path: `spec.md`, `plan.md`, code changes, review
|
|
240
|
+
- Fast Path: concise `spec.md`, simplified `plan.md`, code changes, conditional test/review evidence when triggered, Prizm docs sync only when durable knowledge changed, and one feature commit.
|
|
240
241
|
- Pipeline Path: handoff brief, validated `.prizmkit/plans/feature-list.json` from `feature-planner`, and pipeline launch/status handled by `feature-pipeline-launcher`.
|
|
241
242
|
- Greenfield path: app-level planning artifacts from `app-planner`, optionally followed by feature planning and launch.
|
|
@@ -12,7 +12,7 @@ You are the dedicated PrizmKit Reviewer agent (`prizm-dev-team-reviewer`). Revie
|
|
|
12
12
|
{architecture decisions and task list from plan.md}
|
|
13
13
|
|
|
14
14
|
## Scoped Test Report
|
|
15
|
-
{summary from artifact_dir/test-report-path.txt and test-report.md, including Scope, Generated / Updated Tests, In-Scope Failures, Baseline Failures, Out of Scope Gaps, Boundary Matrix / Boundary Completion Gate if present, and Verdict. If no scoped report exists for a
|
|
15
|
+
{summary from artifact_dir/test-report-path.txt and test-report.md, including Scope, Generated / Updated Tests, In-Scope Failures, Baseline Failures, Out of Scope Gaps, Boundary Matrix / Boundary Completion Gate if present, and Verdict. If no scoped report exists for a change artifact, write "No scoped /prizmkit-test report found (expected for pre-test review)." Treat that absence as informational unless the calling workflow explicitly requires a prior test report.}
|
|
16
16
|
|
|
17
17
|
## Workspace Context
|
|
18
18
|
{git status, unstaged diff summary, staged diff summary, current working directory, expected active checkout git top-level, and new-file paths captured by the Main Agent in Phase 0 from the active checkout. This is your primary review scope — use this context to understand what changed. Request targeted file reads only when you need specific line-level detail for a finding, not to re-discover or re-index the repository. Do not read files that are not in the workspace context unless you need them to verify impact (callers, dependents, shared patterns). Do not switch to a separate worktree or repository copy — the Main Agent has provided everything needed to understand the change set.}
|
|
@@ -49,7 +49,7 @@ Evaluate the changes across these dimensions (focus on what's relevant):
|
|
|
49
49
|
3. **Completeness**: Files that should have been changed but weren't? Missing tests, types, imports, exports?
|
|
50
50
|
4. **Consistency**: Do changes follow the project's existing patterns, naming conventions, and code style?
|
|
51
51
|
5. **Security**: Hardcoded secrets, injection vulnerabilities, unsafe operations.
|
|
52
|
-
6. **Test quality**: If a scoped `/prizmkit-test` report is present, verify the report scope is `this-change`, the artifact dir matches the
|
|
52
|
+
6. **Test quality**: If a scoped `/prizmkit-test` report is present, verify the report scope is `this-change`, the artifact dir matches the reviewed change, generated/updated tests assert real behavior rather than mock success or empty assertions, in-scope failures are not mislabeled as baseline failures, baseline failures are genuinely unrelated or pre-existing, out-of-scope gaps were not turned into unrelated test changes, and the report verdict is compatible with proceeding.
|
|
53
53
|
7. **Rules compliance**: (Skip this dimension if no dev rules were provided.) Do changes follow the per-layer dev rules? Flag violations of framework conventions, naming patterns, state management, or other rules defined for that layer.
|
|
54
54
|
|
|
55
55
|
## Output Format
|
|
@@ -10,7 +10,14 @@ During Discovery Step 1 (Project Detection), database drivers were already scann
|
|
|
10
10
|
> - **Yes** → proceed with database installation
|
|
11
11
|
> - **No** → skip, record in deploy.md with note "database must be configured by user"
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Secrets file safety
|
|
14
|
+
|
|
15
|
+
Before writing `.prizmkit/deploy/secrets.local.json`:
|
|
16
|
+
|
|
17
|
+
1. Verify `.gitignore` or an equivalent ignore rule covers `.prizmkit/deploy/secrets.local.json` and any `.prizmkit/deploy/*.local.json` pattern used by the project.
|
|
18
|
+
2. If the ignore rule is missing, pause and add or request the ignore rule before writing secrets.
|
|
19
|
+
3. Set the secrets file permissions to current-user read/write only, for example `chmod 600 .prizmkit/deploy/secrets.local.json` on POSIX systems.
|
|
20
|
+
4. Record only presence metadata in deploy config, docs, reports, and history. Never copy raw passwords, connection strings, passphrases, decryption keys, unsalted hashes, or full env var values into committed files.
|
|
14
21
|
|
|
15
22
|
```
|
|
16
23
|
apt-get install -y postgresql postgresql-contrib
|
|
@@ -21,7 +28,8 @@ sudo -u postgres psql -c "GRANT ALL ON DATABASE <project> TO <project>;"
|
|
|
21
28
|
|
|
22
29
|
- Generate a secure random password (32 chars, alphanumeric + symbols).
|
|
23
30
|
- Write the connection string to `.prizmkit/deploy/secrets.local.json`: `DATABASE_URL=postgresql://<project>:<password>@localhost:5432/<project>`.
|
|
24
|
-
-
|
|
31
|
+
- Set `.prizmkit/deploy/secrets.local.json` permissions to current-user read/write only after writing.
|
|
32
|
+
- In deploy.md, write: "PostgreSQL installed, connection info recorded in `.prizmkit/deploy/secrets.local.json` (gitignored; raw value not committed)".
|
|
25
33
|
|
|
26
34
|
## MySQL setup (future)
|
|
27
35
|
|
|
@@ -37,10 +45,11 @@ redis-cli CONFIG REWRITE
|
|
|
37
45
|
|
|
38
46
|
- Bind to localhost only (modify `/etc/redis/redis.conf` if needed).
|
|
39
47
|
- Write `REDIS_URL=redis://:<password>@localhost:6379` to `.prizmkit/deploy/secrets.local.json`.
|
|
48
|
+
- Set `.prizmkit/deploy/secrets.local.json` permissions to current-user read/write only after writing.
|
|
40
49
|
|
|
41
50
|
## Security notes
|
|
42
51
|
|
|
43
52
|
- Never write database passwords to deploy.md, because deploy.md may be committed to git and passwords would leak.
|
|
44
|
-
- Passwords stored in `.prizmkit/deploy/secrets.local.json`
|
|
53
|
+
- Passwords stored in `.prizmkit/deploy/secrets.local.json` only after verifying the file is ignored by git and locked down to current-user read/write permissions.
|
|
45
54
|
- Default: database binds to localhost, no external access, because most indie projects only need local connections.
|
|
46
55
|
- Record a `"database-setup"` event in deploy history (presence metadata only, no passwords).
|
|
@@ -21,8 +21,8 @@ STEPS:
|
|
|
21
21
|
- Top-level module M → write .prizmkit/prizm-docs/<M>.prizm (include SUBDIRS section with pointers to sub-module docs)
|
|
22
22
|
- Sub-module S inside M → write .prizmkit/prizm-docs/<M>/<S>.prizm
|
|
23
23
|
Each L1 includes MODULE (full relative path), FILES count, RESPONSIBILITY, SUBDIRS with pointers, KEY_FILES (5-10 most important), DEPENDENCIES (imports, imported-by, external), RULES (1-3 most critical only). L1 does NOT include INTERFACES, DATA_FLOW, TRAPS, or DECISIONS (those are L2, generated lazily). Max 4KB each.
|
|
24
|
-
6. Skip L2 docs during init — L2
|
|
25
|
-
7. Configure UserPromptSubmit hook in platform settings per ${SKILL_DIR}/assets/prizm-docs-format.md
|
|
24
|
+
6. Skip L2 docs during init — L2 docs are created after real context exists, not as placeholders. During implementation, if relevant L2 is missing, the implementing skill reads target source files as fallback and proceeds. `/prizmkit-retrospective` creates or updates L2 after the change only when durable structure, behavior, dependencies, interfaces, or TRAPS exist. Explicit `/prizmkit-prizm-docs` repair/rebuild may also create L2 when fixing out-of-band doc drift.
|
|
25
|
+
7. Configure UserPromptSubmit hook in platform settings per ${SKILL_DIR}/assets/prizm-docs-format.md Section 11.
|
|
26
26
|
8. Validate all generated docs: size limits (L0 <= 4KB, L1 <= 4KB), pointer resolution (every -> reference resolves), no circular dependencies, KEY: value format compliance, no anti-patterns (prose, code blocks, markdown headers), L1 does not contain INTERFACES/DATA_FLOW/TRAPS/DECISIONS, no CHANGELOG sections/files, no UPDATED/date metadata, no feature/bug/refactor/task/session/run/pipeline/workflow IDs, no branch names, no absolute worktree paths, and no `.prizmkit/specs` / `.prizmkit/dev-pipeline` artifact paths.
|
|
27
27
|
9. Report summary: modules discovered, L1 docs generated, files excluded, warnings.
|
|
28
28
|
|
|
@@ -30,16 +30,14 @@ OUTPUT: List of generated files, module count, and validation results.
|
|
|
30
30
|
|
|
31
31
|
## Post-Init Behavior
|
|
32
32
|
|
|
33
|
-
After initialization, L2 docs are created
|
|
33
|
+
After initialization, L2 docs are created only when durable context exists:
|
|
34
34
|
|
|
35
|
-
ON_MODIFY
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- This ensures L2 docs have real depth, written when AI has actual context
|
|
35
|
+
ON_MODIFY behavior:
|
|
36
|
+
- When an AI modifies a file in sub-module S within module M and `.prizmkit/prizm-docs/<M>/<S>.prizm` does not exist, the implementation reads the source files in S as fallback context and proceeds.
|
|
37
|
+
- Do not block implementation only to create a placeholder L2 doc.
|
|
38
|
+
- After the change, run `/prizmkit-retrospective` when structure, interfaces, dependencies, behavior, or durable TRAPS changed; retrospective creates or updates L2 then.
|
|
40
39
|
|
|
41
|
-
ON_DEEP_READ
|
|
42
|
-
- When AI needs
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- This ensures L2 docs are available for read-heavy analysis tasks, not just modifications
|
|
40
|
+
ON_DEEP_READ behavior:
|
|
41
|
+
- When an AI needs deep understanding but L2 is absent, read the relevant source files directly as fallback context.
|
|
42
|
+
- Create L2 through `/prizmkit-retrospective` after normal development work, or through explicit `/prizmkit-prizm-docs` repair/rebuild when fixing out-of-band doc drift.
|
|
43
|
+
- Do not create L2 merely because a module was read; L2 should capture durable knowledge, not transient investigation notes.
|
|
@@ -100,7 +100,7 @@ Interactive mode options:
|
|
|
100
100
|
|
|
101
101
|
1. Full project
|
|
102
102
|
2. Single module
|
|
103
|
-
3. Single feature/spec directory
|
|
103
|
+
3. Single historical feature/spec directory
|
|
104
104
|
4. Current change artifact when an artifact directory is available
|
|
105
105
|
|
|
106
106
|
For `scope=this-change`, build the in-scope source set using this priority:
|
|
@@ -4,7 +4,7 @@ Use this protocol during `/prizmkit-test` Phase 4 and update it during Phase 5.
|
|
|
4
4
|
|
|
5
5
|
## Required Boundary Matrix
|
|
6
6
|
|
|
7
|
-
Build this matrix before writing tests and update it after generated tests pass or produce `needs-review` findings. In `scope=this-change`, build the matrix only for in-
|
|
7
|
+
Build this matrix before writing tests and update it after generated tests pass or produce `needs-review` findings. In `scope=this-change`, build the matrix only for interfaces/endpoints in the reviewed change artifact or changed-file set; unrelated interfaces are recorded under `Out of Scope Gaps` and do not trigger generated tests.
|
|
8
8
|
|
|
9
9
|
| Module | Interface | Service Type | Happy Path | Request Validation | Auth / Permission / Ownership | Domain Invariants | Collection / Pagination | Date / Time | State Transitions | Dependency Failure | Response Contract | N/A Reasons | Final Status |
|
|
10
10
|
|--------|-----------|--------------|------------|--------------------|-------------------------------|-------------------|-------------------------|-------------|-------------------|-------------------|-------------------|-------------|--------------|
|
|
@@ -118,7 +118,7 @@ Do not report `user` as covered just because both endpoints have success tests.
|
|
|
118
118
|
|
|
119
119
|
**Caller**: `/prizmkit-test scope=this-change artifact_dir=.prizmkit/specs/{{FEATURE_SLUG}}/`
|
|
120
120
|
|
|
121
|
-
For non-feature changes, use the same command shape with any explicit change artifact directory that contains `spec.md` + `plan.md` and has a changed-files source.
|
|
121
|
+
For non-feature changes, use the same command shape with any explicit change artifact directory that contains `spec.md` + `plan.md` and has a changed-files source. The `{{FEATURE_SLUG}}` path below is a compatibility example for existing feature artifacts; it does not limit `scope=this-change` to feature work.
|
|
122
122
|
|
|
123
123
|
**Expected behavior**:
|
|
124
124
|
- Reads the change artifact's `spec.md`, `plan.md`, and optional `context-snapshot.md`.
|
|
@@ -136,7 +136,7 @@ For non-feature changes, use the same command shape with any explicit change art
|
|
|
136
136
|
- Generation Policy: in-scope-only
|
|
137
137
|
|
|
138
138
|
## Out of Scope Gaps
|
|
139
|
-
- payment: missing legacy tests, but this
|
|
139
|
+
- payment: missing legacy tests, but this change did not affect payment code.
|
|
140
140
|
|
|
141
141
|
## Verdict
|
|
142
142
|
PASS
|
|
@@ -169,7 +169,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
169
169
|
- No (default) — Use defaults for critic review and failure behavior
|
|
170
170
|
- Yes — Configure critic review, stop-on-failure, and reasoning effort options
|
|
171
171
|
|
|
172
|
-
Note: Refactor filter defaults to all refactor items
|
|
172
|
+
Note: Refactor filter defaults to all refactor items. Runtime selects eligible refactors in stable list order after dependencies are completed; planners should order unrelated refactors by user priority before launch. If the user selects "Other" on any option, handle their custom input.
|
|
173
173
|
|
|
174
174
|
**If user chose "Yes" to Advanced config**, run the advanced configuration round (a second `AskUserQuestion` round, plus a reasoning-effort follow-up). It applies to a minority of sessions, so the full question set lives in `${SKILL_DIR}/references/configuration.md` → **Advanced Configuration Round**. Default Critic to Off unless refactor items have `priority: "critical"` (in which case default to On).
|
|
175
175
|
|
|
@@ -225,6 +225,7 @@ Detect user intent from their message, then follow the corresponding workflow:
|
|
|
225
225
|
- Summarize results: total refactors, succeeded, failed, skipped
|
|
226
226
|
- If all succeeded: each refactor session has already run `prizmkit-retrospective` internally. Ask user what's next.
|
|
227
227
|
- If some failed: show failed refactor IDs and suggest `python3 ./.prizmkit/dev-pipeline/cli.py reset refactor <R-XXX> --clean --run` for a fresh retry
|
|
228
|
+
- **Browser verification**: Refactor sessions with `browser_interaction` perform supplemental UI verification during execution. After completion, use `python3 ./.prizmkit/dev-pipeline/cli.py refactor status .prizmkit/plans/refactor-list.json` and per-refactor session logs as the source of truth before summarizing browser verification results.
|
|
228
229
|
|
|
229
230
|
**If background daemon**:
|
|
230
231
|
1. Verify launch:
|
|
@@ -328,7 +329,7 @@ Read the error-handling table in `${SKILL_DIR}/references/configuration.md` for
|
|
|
328
329
|
### Integration Notes
|
|
329
330
|
|
|
330
331
|
- **After refactor-planner**: This is the natural next step. When user finishes refactor planning and has `.prizmkit/plans/refactor-list.json`, suggest launching the refactor pipeline.
|
|
331
|
-
- **Session independence**:
|
|
332
|
+
- **Session independence**: Only Background daemon mode runs detached. Foreground runs in the current AI CLI session, and Manual mode prints commands without launching.
|
|
332
333
|
- **Single instance per family**: Only one refactor pipeline can run at a time. Different pipeline families may coexist because they use separate daemon metadata and state directories.
|
|
333
334
|
- **Pipeline coexistence**: Refactor pipeline uses `.prizmkit/state/refactor/` separate from `.prizmkit/state/features/` (features) and `.prizmkit/state/bugfix/` (bugs), so all three pipelines can run simultaneously without conflict.
|
|
334
335
|
- **State preservation**: Stopping and restarting the pipeline resumes from where it left off -- completed refactors are not re-run.
|
|
@@ -172,10 +172,11 @@ Use Fast Path only after explicit user selection.
|
|
|
172
172
|
1. Invoke `/prizmkit-plan` with the handoff brief and behavior-preservation expectations.
|
|
173
173
|
2. Invoke `/prizmkit-implement` after the plan is ready.
|
|
174
174
|
3. Run behavior-preservation checks identified in the plan.
|
|
175
|
-
4. Run `/prizmkit-
|
|
176
|
-
5. Run `/prizmkit-
|
|
177
|
-
6. Run `/prizmkit-
|
|
178
|
-
7.
|
|
175
|
+
4. Run `/prizmkit-test` only when risk triggers match: public contracts, data models, migration behavior, weak behavior-preservation evidence, or explicit user verification request.
|
|
176
|
+
5. Run `/prizmkit-code-review` when the user requested review, behavior-preservation uncertainty is high, or Full-path-level risk appears during implementation.
|
|
177
|
+
6. Run `/prizmkit-retrospective` only when structure, interfaces, dependencies, behavior, or durable project knowledge changed.
|
|
178
|
+
7. Run `/prizmkit-committer` with a `refactor(<scope>):` message.
|
|
179
|
+
8. End the workflow after commit; do not call `refactor-planner`, `refactor-pipeline-launcher`, or monitoring.
|
|
179
180
|
|
|
180
181
|
If the refactor starts changing behavior or grows beyond Fast Path criteria, pause and ask whether to switch to `feature-workflow` or Pipeline Path.
|
|
181
182
|
|
|
@@ -241,5 +242,5 @@ For start/stop/logs/retry execution, hand off to `refactor-pipeline-launcher`; d
|
|
|
241
242
|
|
|
242
243
|
## Output
|
|
243
244
|
|
|
244
|
-
- Fast Path: `spec.md`, `plan.md`, behavior-preserving code changes, behavior-check evidence, review
|
|
245
|
+
- Fast Path: `spec.md`, `plan.md`, behavior-preserving code changes, behavior-check evidence, conditional test/review evidence when triggered, Prizm docs sync only when durable knowledge changed, and one refactor commit.
|
|
245
246
|
- Pipeline Path: handoff brief, validated `.prizmkit/plans/refactor-list.json` from `refactor-planner`, and pipeline launch/status handled by `refactor-pipeline-launcher`.
|