prizmkit 1.1.106 → 1.1.108
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/bin/create-prizmkit.js +4 -0
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/prizmkit_runtime/config.py +81 -14
- package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +19 -8
- package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +0 -1
- package/bundled/dev-pipeline/prizmkit_runtime/launch_profiles.py +18 -0
- package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +22 -2
- package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +56 -5
- package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +0 -8
- package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +11 -1
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +298 -63
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +243 -37
- package/bundled/dev-pipeline/scripts/continuation.py +0 -5
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +10 -82
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +7 -64
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +40 -63
- package/bundled/dev-pipeline/scripts/utils.py +123 -0
- package/bundled/dev-pipeline/templates/agent-prompts/critic-plan-challenge.md +4 -3
- package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +5 -6
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +36 -35
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +53 -80
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +43 -78
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +5 -17
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +6 -18
- package/bundled/dev-pipeline/templates/sections/checkpoint-system.md +14 -48
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +7 -14
- package/bundled/dev-pipeline/templates/sections/feature-context.md +0 -4
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-auto.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification-opencli.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase-browser-verification.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +0 -14
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +0 -14
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-base.md +0 -2
- package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-lite-suffix.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan-full.md +6 -8
- package/bundled/dev-pipeline/templates/sections/phase-critic-plan.md +3 -7
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +4 -16
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +4 -17
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase-plan-agent.md +2 -9
- package/bundled/dev-pipeline/templates/sections/phase-plan-lite.md +1 -8
- package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +15 -16
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +3 -10
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +3 -10
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +2 -9
- package/bundled/dev-pipeline/templates/sections/phase0-init.md +0 -7
- package/bundled/dev-pipeline/templates/sections/phase0-test-baseline.md +2 -15
- package/bundled/dev-pipeline/tests/conftest.py +0 -1
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +395 -21
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +50 -14
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +154 -2
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +431 -3
- package/bundled/dev-pipeline/tests/test_unified_cli.py +857 -5
- package/bundled/skills/_metadata.json +4 -4
- package/bundled/skills/app-planner/SKILL.md +1 -1
- package/bundled/skills/app-planner/references/architecture-decisions.md +1 -1
- package/bundled/skills/bug-fix-workflow/SKILL.md +174 -128
- package/bundled/skills/bug-planner/SKILL.md +101 -15
- package/bundled/skills/bug-planner/references/severity-rules.md +20 -8
- package/bundled/skills/feature-planner/SKILL.md +87 -8
- package/bundled/skills/feature-planner/assets/planning-guide.md +34 -10
- package/bundled/skills/feature-workflow/SKILL.md +100 -81
- package/bundled/skills/{prizm-kit → prizmkit}/SKILL.md +1 -1
- package/bundled/skills/prizmkit-code-review/SKILL.md +12 -13
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +10 -10
- package/bundled/skills/refactor-planner/SKILL.md +88 -7
- package/bundled/skills/refactor-planner/references/fast-path.md +2 -1
- package/bundled/skills/refactor-planner/references/planning-phases.md +29 -11
- package/bundled/skills/refactor-workflow/SKILL.md +116 -57
- package/bundled/templates/project-memory-template.md +1 -1
- package/package.json +1 -1
- package/src/ai-cli-launch.js +194 -0
- package/src/config.js +26 -14
- package/src/index.js +11 -44
- package/src/platforms.js +10 -3
- package/src/prompts.js +60 -2
- package/src/scaffold.js +26 -14
- package/bundled/dev-pipeline/scripts/prizmkit-test-gate.py +0 -446
- package/bundled/dev-pipeline/templates/agent-prompts/dev-fix.md +0 -7
- package/bundled/dev-pipeline/templates/agent-prompts/dev-resume.md +0 -5
- package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +0 -20
- package/bundled/dev-pipeline/tests/test_prizmkit_test_gate.py +0 -107
- package/bundled/skills/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
|
@@ -12,10 +12,12 @@ from generate_bugfix_prompt import (
|
|
|
12
12
|
format_environment,
|
|
13
13
|
process_conditional_blocks,
|
|
14
14
|
render_template,
|
|
15
|
-
load_log_size_section,
|
|
16
15
|
)
|
|
17
16
|
from continuation import append_continuation_handoff
|
|
18
17
|
|
|
18
|
+
REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
|
|
19
|
+
REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
|
|
20
|
+
|
|
19
21
|
|
|
20
22
|
# ---------------------------------------------------------------------------
|
|
21
23
|
# find_bug
|
|
@@ -193,6 +195,14 @@ class TestExplicitProjectRoot:
|
|
|
193
195
|
)
|
|
194
196
|
assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
|
|
195
197
|
assert replacements["{{DEV_SUBAGENT_PATH}}"].startswith(str(execution_root.resolve()))
|
|
198
|
+
assert replacements["{{SESSION_LOG_PATH}}"].endswith(
|
|
199
|
+
".prizmkit/state/bugfix/B-001/sessions/session-1/logs/session.log"
|
|
200
|
+
)
|
|
201
|
+
assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
|
|
202
|
+
assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements
|
|
203
|
+
assert "### Checkpoint Update Helper" in replacements["{{CHECKPOINT_SYSTEM}}"]
|
|
204
|
+
assert "python3 .prizmkit/dev-pipeline/scripts/update-checkpoint.py" in replacements["{{CHECKPOINT_SYSTEM}}"]
|
|
205
|
+
assert "pipeline progress mechanism" not in replacements["{{CHECKPOINT_SYSTEM}}"]
|
|
196
206
|
|
|
197
207
|
|
|
198
208
|
# ---------------------------------------------------------------------------
|
|
@@ -218,23 +228,27 @@ class TestSharedHelpers:
|
|
|
218
228
|
# ---------------------------------------------------------------------------
|
|
219
229
|
|
|
220
230
|
class TestHeadlessRecoveryReframing:
|
|
221
|
-
def
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
assert "
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
def test_bugfix_source_has_no_deleted_log_size_injection(self):
|
|
232
|
+
deleted_section = "log-size-" + "awareness.md"
|
|
233
|
+
loader = "load_" + "log_size_section"
|
|
234
|
+
placeholder = "{{LOG_" + "SIZE_AWARENESS}}"
|
|
235
|
+
deleted_title = "Session " + "Checkpoint Awareness"
|
|
236
|
+
source = Path("dev-pipeline/scripts/generate-bugfix-prompt.py").read_text(encoding="utf-8")
|
|
237
|
+
template = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
|
|
238
|
+
|
|
239
|
+
assert (Path("dev-pipeline/templates/sections") / deleted_section).exists() is False
|
|
240
|
+
for content in (source, template):
|
|
241
|
+
for forbidden in (deleted_section, loader, placeholder, deleted_title):
|
|
242
|
+
assert forbidden not in content
|
|
233
243
|
|
|
234
244
|
def test_bugfix_template_does_not_spawn_monitor_or_require_compact(self):
|
|
235
245
|
content = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
|
|
236
246
|
|
|
237
247
|
assert "Do not spawn persistent background subagents for headless recovery" in content
|
|
248
|
+
assert REMOVED_MAX_LOG_ENV not in content
|
|
249
|
+
assert REMOVED_MAX_LOG_HUMAN not in content
|
|
250
|
+
assert ("209" + "7152") not in content
|
|
251
|
+
assert ("2" + "MB") not in content
|
|
238
252
|
assert "log-size monitor" not in content
|
|
239
253
|
assert "monitor-log" not in content
|
|
240
254
|
assert "COMPACT_NEEDED" not in content
|
|
@@ -263,6 +277,28 @@ class TestBugfixContinuationHandoff:
|
|
|
263
277
|
|
|
264
278
|
assert prompt.startswith("BUGFIX PROMPT")
|
|
265
279
|
assert "This is an automatic continuation after context overflow." in prompt
|
|
266
|
-
assert "Do not attempt `/compact` as the recovery mechanism." in prompt
|
|
280
|
+
assert "Do not attempt `/compact` as the recovery mechanism." not in prompt
|
|
281
|
+
assert ("Log " + "monitor") not in prompt
|
|
282
|
+
assert ("log-" + "monitor") not in prompt
|
|
267
283
|
assert (tmp_path / ".prizmkit/specs/B-007/continuation-summary.md").exists()
|
|
268
284
|
assert (tmp_path / ".prizmkit/bugfix/B-007/continuation-summary.md").exists()
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
HEADLESS_FORBIDDEN_PROMPT_STRINGS = [
|
|
288
|
+
"### Interactive Claude Code Note",
|
|
289
|
+
"### Project Conventions",
|
|
290
|
+
"Scaffold / generated file awareness",
|
|
291
|
+
"### Resume Behavior",
|
|
292
|
+
"[NEEDS CLARIFICATION]",
|
|
293
|
+
"pause for interactive input",
|
|
294
|
+
"prizmkit-test-gate.py",
|
|
295
|
+
"/compact",
|
|
296
|
+
"Session " + "Checkpoint Awareness",
|
|
297
|
+
"{{LOG_" + "SIZE_AWARENESS}}",
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def test_template_source_is_clean_for_headless_prompt_contract():
|
|
302
|
+
content = Path("dev-pipeline/templates/bugfix-bootstrap-prompt.md").read_text(encoding="utf-8")
|
|
303
|
+
for forbidden in HEADLESS_FORBIDDEN_PROMPT_STRINGS:
|
|
304
|
+
assert forbidden not in content
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
"""Tests for generate-refactor-prompt.py continuation behavior."""
|
|
2
2
|
|
|
3
3
|
from argparse import Namespace
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
|
|
5
6
|
from continuation import append_continuation_handoff
|
|
6
|
-
from generate_refactor_prompt import
|
|
7
|
+
from generate_refactor_prompt import (
|
|
8
|
+
build_replacements,
|
|
9
|
+
generate_refactor_checkpoint,
|
|
10
|
+
merge_refactor_checkpoint_state,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
REMOVED_MAX_LOG_ENV = "MAX_" + "LOG_SIZE"
|
|
14
|
+
REMOVED_MAX_LOG_HUMAN = REMOVED_MAX_LOG_ENV + "_HUMAN"
|
|
7
15
|
|
|
8
16
|
|
|
9
17
|
class TestRefactorContinuationHandoff:
|
|
@@ -26,7 +34,9 @@ class TestRefactorContinuationHandoff:
|
|
|
26
34
|
|
|
27
35
|
assert prompt.startswith("REFACTOR PROMPT")
|
|
28
36
|
assert "This is a fresh headless AI CLI session for the same task." in prompt
|
|
29
|
-
assert "Do not attempt `/compact` as the recovery mechanism." in prompt
|
|
37
|
+
assert "Do not attempt `/compact` as the recovery mechanism." not in prompt
|
|
38
|
+
assert ("Log " + "monitor") not in prompt
|
|
39
|
+
assert ("log-" + "monitor") not in prompt
|
|
30
40
|
assert (tmp_path / ".prizmkit/specs/R-007/continuation-summary.md").exists()
|
|
31
41
|
assert (tmp_path / ".prizmkit/refactor/R-007/continuation-summary.md").exists()
|
|
32
42
|
|
|
@@ -41,3 +51,145 @@ class TestRefactorCheckpointMerge:
|
|
|
41
51
|
|
|
42
52
|
assert merged["steps"][0]["status"] == "skipped"
|
|
43
53
|
assert merged["steps"][1]["status"] == "pending"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class TestExplicitProjectRoot:
|
|
57
|
+
def test_build_replacements_infers_project_root_from_refactor_list(self, tmp_path, monkeypatch):
|
|
58
|
+
monkeypatch.delenv("PRIZMKIT_PLATFORM", raising=False)
|
|
59
|
+
project = tmp_path / "project"
|
|
60
|
+
plan_path = project / ".prizmkit" / "plans" / "refactor-list.json"
|
|
61
|
+
plan_path.parent.mkdir(parents=True)
|
|
62
|
+
(project / ".prizmkit" / "config.json").write_text(
|
|
63
|
+
'{"platform":"claude","ai_cli":"claude"}', encoding="utf-8"
|
|
64
|
+
)
|
|
65
|
+
args = Namespace(
|
|
66
|
+
refactor_list=str(plan_path),
|
|
67
|
+
refactor_id="R-001",
|
|
68
|
+
session_id="session-1",
|
|
69
|
+
run_id="run-1",
|
|
70
|
+
retry_count="0",
|
|
71
|
+
resume_phase="null",
|
|
72
|
+
state_dir=str(project / ".prizmkit" / "state" / "refactor"),
|
|
73
|
+
output=str(project / "out.md"),
|
|
74
|
+
template=None,
|
|
75
|
+
mode=None,
|
|
76
|
+
critic=None,
|
|
77
|
+
)
|
|
78
|
+
refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
|
|
79
|
+
|
|
80
|
+
replacements = build_replacements(
|
|
81
|
+
args, refactor, [refactor], {}, str(Path("dev-pipeline/scripts").resolve())
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
assert replacements["{{PROJECT_ROOT}}"] == str(project.resolve())
|
|
85
|
+
assert replacements["{{REVIEWER_SUBAGENT_PATH}}"].endswith(
|
|
86
|
+
".claude/agents/prizm-dev-team-reviewer.md"
|
|
87
|
+
)
|
|
88
|
+
assert replacements["{{REVIEWER_SUBAGENT_PATH}}"].startswith(str(project.resolve()))
|
|
89
|
+
assert replacements["{{SESSION_STATUS_PATH}}"] == str(
|
|
90
|
+
project / ".prizmkit" / "state" / "refactor" / "R-001" /
|
|
91
|
+
"sessions" / "session-1" / "session-status.json"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def test_build_replacements_uses_cli_project_root_for_rendered_paths(self, tmp_path, monkeypatch):
|
|
95
|
+
monkeypatch.setenv("PRIZMKIT_PLATFORM", "claude")
|
|
96
|
+
execution_root = tmp_path / "worktree"
|
|
97
|
+
main_checkout = tmp_path / "main"
|
|
98
|
+
execution_root.mkdir()
|
|
99
|
+
main_checkout.mkdir()
|
|
100
|
+
args = Namespace(
|
|
101
|
+
refactor_list=str(main_checkout / ".prizmkit" / "plans" / "refactor-list.json"),
|
|
102
|
+
refactor_id="R-001",
|
|
103
|
+
session_id="session-1",
|
|
104
|
+
run_id="run-1",
|
|
105
|
+
retry_count="0",
|
|
106
|
+
resume_phase="null",
|
|
107
|
+
state_dir=str(main_checkout / ".prizmkit" / "state" / "refactor"),
|
|
108
|
+
output=str(main_checkout / ".prizmkit" / "state" / "refactor" / "R-001" / "sessions" / "session-1" / "bootstrap-prompt.md"),
|
|
109
|
+
template=None,
|
|
110
|
+
mode=None,
|
|
111
|
+
critic=None,
|
|
112
|
+
project_root=str(execution_root),
|
|
113
|
+
)
|
|
114
|
+
refactor = {"id": "R-001", "title": "Worktree Refactor", "description": "d"}
|
|
115
|
+
|
|
116
|
+
replacements = build_replacements(
|
|
117
|
+
args,
|
|
118
|
+
refactor,
|
|
119
|
+
[refactor],
|
|
120
|
+
{},
|
|
121
|
+
str(main_checkout / "dev-pipeline" / "scripts"),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
assert replacements["{{PROJECT_ROOT}}"] == str(execution_root.resolve())
|
|
125
|
+
assert replacements["{{SESSION_STATUS_PATH}}"] == str(
|
|
126
|
+
main_checkout / ".prizmkit" / "state" / "refactor" / "R-001" /
|
|
127
|
+
"sessions" / "session-1" / "session-status.json"
|
|
128
|
+
)
|
|
129
|
+
assert not replacements["{{SESSION_STATUS_PATH}}"].startswith(str(execution_root.resolve()))
|
|
130
|
+
assert replacements["{{DEV_SUBAGENT_PATH}}"].startswith(str(execution_root.resolve()))
|
|
131
|
+
assert "### Checkpoint Update Helper" in replacements["{{CHECKPOINT_SYSTEM}}"]
|
|
132
|
+
assert "python3 .prizmkit/dev-pipeline/scripts/update-checkpoint.py" in replacements["{{CHECKPOINT_SYSTEM}}"]
|
|
133
|
+
assert "pipeline progress mechanism" not in replacements["{{CHECKPOINT_SYSTEM}}"]
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TestRefactorPromptMaxLogRemoval:
|
|
137
|
+
def test_refactor_source_has_no_deleted_log_size_injection(self):
|
|
138
|
+
deleted_section = "log-size-" + "awareness.md"
|
|
139
|
+
loader = "load_" + "log_size_section"
|
|
140
|
+
placeholder = "{{LOG_" + "SIZE_AWARENESS}}"
|
|
141
|
+
deleted_title = "Session " + "Checkpoint Awareness"
|
|
142
|
+
source = Path("dev-pipeline/scripts/generate-refactor-prompt.py").read_text(encoding="utf-8")
|
|
143
|
+
template = Path("dev-pipeline/templates/refactor-bootstrap-prompt.md").read_text(encoding="utf-8")
|
|
144
|
+
|
|
145
|
+
assert (Path("dev-pipeline/templates/sections") / deleted_section).exists() is False
|
|
146
|
+
for content in (source, template):
|
|
147
|
+
for forbidden in (deleted_section, loader, placeholder, deleted_title):
|
|
148
|
+
assert forbidden not in content
|
|
149
|
+
|
|
150
|
+
def test_refactor_replacements_keep_session_log_without_max_log_placeholders(self, monkeypatch):
|
|
151
|
+
monkeypatch.setenv("PRIZMKIT_PLATFORM", "claude")
|
|
152
|
+
args = Namespace(
|
|
153
|
+
refactor_id="R-001",
|
|
154
|
+
session_id="session-1",
|
|
155
|
+
run_id="run-1",
|
|
156
|
+
retry_count="0",
|
|
157
|
+
resume_phase="null",
|
|
158
|
+
state_dir=None,
|
|
159
|
+
output="out.md",
|
|
160
|
+
template=None,
|
|
161
|
+
mode=None,
|
|
162
|
+
critic=None,
|
|
163
|
+
)
|
|
164
|
+
refactor = {"id": "R-001", "title": "Restructure", "description": "d"}
|
|
165
|
+
|
|
166
|
+
replacements = build_replacements(
|
|
167
|
+
args, refactor, [refactor], {}, str(Path("dev-pipeline/scripts").resolve())
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
assert replacements["{{SESSION_LOG_PATH}}"].endswith(
|
|
171
|
+
".prizmkit/state/refactor/R-001/sessions/session-1/logs/session.log"
|
|
172
|
+
)
|
|
173
|
+
assert "{{" + REMOVED_MAX_LOG_ENV + "}}" not in replacements
|
|
174
|
+
assert "{{" + REMOVED_MAX_LOG_HUMAN + "}}" not in replacements
|
|
175
|
+
assert "{{LOG_" + "SIZE_AWARENESS}}" not in replacements
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
HEADLESS_FORBIDDEN_PROMPT_STRINGS = [
|
|
179
|
+
"### Interactive Claude Code Note",
|
|
180
|
+
"### Project Conventions",
|
|
181
|
+
"Scaffold / generated file awareness",
|
|
182
|
+
"### Resume Behavior",
|
|
183
|
+
"[NEEDS CLARIFICATION]",
|
|
184
|
+
"pause for interactive input",
|
|
185
|
+
"prizmkit-test-gate.py",
|
|
186
|
+
"/compact",
|
|
187
|
+
"Session " + "Checkpoint Awareness",
|
|
188
|
+
"{{LOG_" + "SIZE_AWARENESS}}",
|
|
189
|
+
]
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def test_template_source_is_clean_for_headless_prompt_contract():
|
|
193
|
+
content = Path("dev-pipeline/templates/refactor-bootstrap-prompt.md").read_text(encoding="utf-8")
|
|
194
|
+
for forbidden in HEADLESS_FORBIDDEN_PROMPT_STRINGS:
|
|
195
|
+
assert forbidden not in content
|