prizmkit 1.1.104 → 1.1.105
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/dev-pipeline/README.md +6 -7
- package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +3 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +357 -158
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +98 -9
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +37 -28
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +4 -3
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +62 -38
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +57 -49
- package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -1
- package/bundled/dev-pipeline/templates/sections/critical-paths-full.md +0 -1
- package/bundled/dev-pipeline/templates/sections/directory-convention-agent.md +2 -2
- package/bundled/dev-pipeline/templates/sections/directory-convention-full.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +1 -0
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +1 -0
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +46 -0
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +100 -0
- package/bundled/skills/_metadata.json +1 -1
- package/package.json +1 -1
- package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +0 -71
|
@@ -53,6 +53,9 @@ class AISessionConfig:
|
|
|
53
53
|
total_timeout_seconds: float | None = None
|
|
54
54
|
stale_kill_threshold_seconds: float = 0
|
|
55
55
|
stale_kill_grace_seconds: float = 10
|
|
56
|
+
live_progress_interval_seconds: float = 30
|
|
57
|
+
live_banner: bool = True
|
|
58
|
+
suppress_stream_output: bool = False
|
|
56
59
|
codex_subagent_timeout_seconds: int = 3300
|
|
57
60
|
extra_args: tuple[str, ...] = ()
|
|
58
61
|
environment_overrides: Mapping[str, str] = field(default_factory=dict)
|
|
@@ -376,6 +379,70 @@ def _emit_live_output(line: str) -> None:
|
|
|
376
379
|
sys.stdout.flush()
|
|
377
380
|
|
|
378
381
|
|
|
382
|
+
def _format_bytes(size: int) -> str:
|
|
383
|
+
if size >= 1024 * 1024:
|
|
384
|
+
return f"{round(size / (1024 * 1024))}MB"
|
|
385
|
+
if size >= 1024:
|
|
386
|
+
return f"{round(size / 1024)}KB"
|
|
387
|
+
return f"{size}B"
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def _format_elapsed(seconds: float) -> str:
|
|
391
|
+
total = max(0, int(seconds))
|
|
392
|
+
minutes, remainder = divmod(total, 60)
|
|
393
|
+
return f"{minutes}m{remainder:02d}s"
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _read_json_object(path: Path | None) -> dict[str, object]:
|
|
397
|
+
if path is None or not path.is_file():
|
|
398
|
+
return {}
|
|
399
|
+
try:
|
|
400
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
401
|
+
except (OSError, json.JSONDecodeError):
|
|
402
|
+
return {}
|
|
403
|
+
return data if isinstance(data, dict) else {}
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def _compact_progress_line(started_epoch: float, session_log: Path, progress_path: Path | None) -> str:
|
|
407
|
+
data = _read_json_object(progress_path)
|
|
408
|
+
try:
|
|
409
|
+
log_size = session_log.stat().st_size
|
|
410
|
+
except OSError:
|
|
411
|
+
log_size = 0
|
|
412
|
+
parts = [
|
|
413
|
+
f" ▶ [HEARTBEAT] {_format_elapsed(time.time() - started_epoch)}",
|
|
414
|
+
f"log: {_format_bytes(log_size)}",
|
|
415
|
+
]
|
|
416
|
+
child_bytes = int(data.get("child_total_bytes") or 0)
|
|
417
|
+
subagents = int(data.get("subagent_spawn_count") or 0)
|
|
418
|
+
if child_bytes or subagents:
|
|
419
|
+
child = _format_bytes(child_bytes)
|
|
420
|
+
if subagents:
|
|
421
|
+
child = f"{child}/{subagents}"
|
|
422
|
+
parts.append(f"child: {child}")
|
|
423
|
+
phase = str(data.get("current_phase") or "").strip()
|
|
424
|
+
if phase:
|
|
425
|
+
parts.append(f"phase: {phase}")
|
|
426
|
+
tool = str(data.get("current_tool") or "").strip()
|
|
427
|
+
if tool:
|
|
428
|
+
parts.append(f"tool: {tool}")
|
|
429
|
+
messages = int(data.get("message_count") or 0)
|
|
430
|
+
if messages:
|
|
431
|
+
parts.append(f"msgs: {messages}")
|
|
432
|
+
tool_calls = int(data.get("total_tool_calls") or 0)
|
|
433
|
+
if tool_calls:
|
|
434
|
+
parts.append(f"{tool_calls} tool calls")
|
|
435
|
+
return " | ".join(parts)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _emit_progress_tick(started_epoch: float, session_log: Path, progress_path: Path | None, last_line: str) -> str:
|
|
439
|
+
line = _compact_progress_line(started_epoch, session_log, progress_path)
|
|
440
|
+
if line != last_line:
|
|
441
|
+
_emit_live_line(line)
|
|
442
|
+
return line
|
|
443
|
+
return last_line
|
|
444
|
+
|
|
445
|
+
|
|
379
446
|
def _emit_session_start(config: AISessionConfig, command: AISessionCommand, session_log: Path, backup_log: Path) -> None:
|
|
380
447
|
_emit_live_line("[prizmkit] AI session started")
|
|
381
448
|
_emit_live_line(f"[prizmkit] Provider: {command.provider}")
|
|
@@ -387,7 +454,7 @@ def _emit_session_start(config: AISessionConfig, command: AISessionCommand, sess
|
|
|
387
454
|
if config.heartbeat_path is not None:
|
|
388
455
|
_emit_live_line(f"[prizmkit] Heartbeat: {config.heartbeat_path}")
|
|
389
456
|
if config.verbose:
|
|
390
|
-
_emit_live_line("[prizmkit] VERBOSE=1:
|
|
457
|
+
_emit_live_line("[prizmkit] VERBOSE=1: compact live progress enabled")
|
|
391
458
|
|
|
392
459
|
|
|
393
460
|
def _emit_session_finish(result: AISessionResult) -> None:
|
|
@@ -509,7 +576,7 @@ class AISessionLauncher:
|
|
|
509
576
|
environment_unsets=("CLAUDECODE",),
|
|
510
577
|
stdin_text=command.stdin_text,
|
|
511
578
|
)
|
|
512
|
-
if self.config.live_output:
|
|
579
|
+
if self.config.live_output and self.config.live_banner:
|
|
513
580
|
_emit_session_start(self.config, command, session_log, backup_log)
|
|
514
581
|
|
|
515
582
|
handle = launch_process(spec, stderr=subprocess.STDOUT)
|
|
@@ -523,7 +590,7 @@ class AISessionLauncher:
|
|
|
523
590
|
backup_log,
|
|
524
591
|
output_queue,
|
|
525
592
|
self.config.progress_path,
|
|
526
|
-
self.config.live_output and self.config.verbose,
|
|
593
|
+
self.config.live_output and self.config.verbose and not self.config.suppress_stream_output,
|
|
527
594
|
),
|
|
528
595
|
daemon=True,
|
|
529
596
|
)
|
|
@@ -557,12 +624,34 @@ class AISessionLauncher:
|
|
|
557
624
|
timed_out = False
|
|
558
625
|
termination_reason = None
|
|
559
626
|
stale_marker = None
|
|
627
|
+
last_progress_line = ""
|
|
628
|
+
last_progress_emit = 0.0
|
|
560
629
|
try:
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
630
|
+
while True:
|
|
631
|
+
timeout = 0.2
|
|
632
|
+
if self.config.total_timeout_seconds is not None:
|
|
633
|
+
remaining = self.config.total_timeout_seconds - (time.time() - started)
|
|
634
|
+
if remaining <= 0:
|
|
635
|
+
timed_out = True
|
|
636
|
+
termination_reason = "timeout"
|
|
637
|
+
terminate_process_tree(handle, "timeout", grace_seconds=self.config.stale_kill_grace_seconds)
|
|
638
|
+
break
|
|
639
|
+
timeout = min(timeout, remaining)
|
|
640
|
+
try:
|
|
641
|
+
handle.popen.wait(timeout=timeout)
|
|
642
|
+
break
|
|
643
|
+
except subprocess.TimeoutExpired:
|
|
644
|
+
if self.config.live_output and (not self.config.verbose or self.config.suppress_stream_output):
|
|
645
|
+
interval = max(1.0, float(self.config.live_progress_interval_seconds or 30))
|
|
646
|
+
now = time.time()
|
|
647
|
+
if last_progress_emit == 0.0 or now - last_progress_emit >= interval:
|
|
648
|
+
last_progress_line = _emit_progress_tick(started, session_log, self.config.progress_path, last_progress_line)
|
|
649
|
+
last_progress_emit = now
|
|
650
|
+
except KeyboardInterrupt:
|
|
651
|
+
terminate_process_tree(handle, "interrupted", grace_seconds=self.config.stale_kill_grace_seconds)
|
|
652
|
+
raise
|
|
653
|
+
if self.config.live_output and (not self.config.verbose or self.config.suppress_stream_output):
|
|
654
|
+
_emit_progress_tick(started, session_log, self.config.progress_path, last_progress_line)
|
|
566
655
|
reader.join(timeout=5)
|
|
567
656
|
heartbeat_result = heartbeat.stop() if heartbeat is not None else None
|
|
568
657
|
if heartbeat_result and heartbeat_result.killed:
|
|
@@ -605,6 +694,6 @@ class AISessionLauncher:
|
|
|
605
694
|
started_epoch=started,
|
|
606
695
|
ended_epoch=ended,
|
|
607
696
|
)
|
|
608
|
-
if self.config.live_output:
|
|
697
|
+
if self.config.live_output and self.config.live_banner:
|
|
609
698
|
_emit_session_finish(result)
|
|
610
699
|
return result
|
|
@@ -1296,32 +1296,36 @@ def load_section(sections_dir, name):
|
|
|
1296
1296
|
return f.read()
|
|
1297
1297
|
|
|
1298
1298
|
|
|
1299
|
-
|
|
1300
|
-
"""
|
|
1299
|
+
ACTIVE_AGENT_PROMPTS = {
|
|
1300
|
+
"critic-plan-challenge.md": "{{AGENT_PROMPT_CRITIC_PLAN_CHALLENGE}}",
|
|
1301
|
+
"reviewer-review.md": "{{AGENT_PROMPT_REVIEWER_REVIEW}}",
|
|
1302
|
+
"dev-fix.md": "{{AGENT_PROMPT_DEV_FIX}}",
|
|
1303
|
+
"dev-resume.md": "{{AGENT_PROMPT_DEV_RESUME}}",
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1301
1306
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1307
|
+
def load_active_agent_prompts(templates_dir):
|
|
1308
|
+
"""Load explicit active agent prompt templates.
|
|
1309
|
+
|
|
1310
|
+
The retired top-level Dev implementation prompt is intentionally not loaded;
|
|
1311
|
+
feature implementation is performed by the main orchestrator. Remaining
|
|
1312
|
+
prompt placeholders support Critic/Reviewer and review-fix helper flows.
|
|
1304
1313
|
"""
|
|
1305
1314
|
agent_prompts_dir = os.path.join(templates_dir, "agent-prompts")
|
|
1306
1315
|
if not os.path.isdir(agent_prompts_dir):
|
|
1307
1316
|
LOGGER.debug("No agent-prompts/ directory found, skipping")
|
|
1308
1317
|
return {}
|
|
1309
1318
|
|
|
1310
|
-
# Map filename -> placeholder name
|
|
1311
|
-
# e.g. dev-implement.md -> {{AGENT_PROMPT_DEV_IMPLEMENT}}
|
|
1312
1319
|
prompt_map = {}
|
|
1313
|
-
for filename in
|
|
1314
|
-
if not filename.endswith(".md"):
|
|
1315
|
-
continue
|
|
1316
|
-
stem = filename[:-3] # remove .md
|
|
1317
|
-
placeholder = "{{{{AGENT_PROMPT_{}}}}}".format(
|
|
1318
|
-
stem.upper().replace("-", "_")
|
|
1319
|
-
)
|
|
1320
|
+
for filename, placeholder in ACTIVE_AGENT_PROMPTS.items():
|
|
1320
1321
|
filepath = os.path.join(agent_prompts_dir, filename)
|
|
1322
|
+
if not os.path.isfile(filepath):
|
|
1323
|
+
LOGGER.debug("Active agent prompt not found, skipping: %s", filename)
|
|
1324
|
+
continue
|
|
1321
1325
|
try:
|
|
1322
1326
|
with open(filepath, "r", encoding="utf-8") as f:
|
|
1323
1327
|
prompt_map[placeholder] = f.read().strip()
|
|
1324
|
-
LOGGER.debug("Loaded agent prompt: %s -> %s", filename, placeholder)
|
|
1328
|
+
LOGGER.debug("Loaded active agent prompt: %s -> %s", filename, placeholder)
|
|
1325
1329
|
except IOError as exc:
|
|
1326
1330
|
LOGGER.warning("Failed to load agent prompt %s: %s", filename, exc)
|
|
1327
1331
|
|
|
@@ -1345,10 +1349,13 @@ def _tier_header(pipeline_mode):
|
|
|
1345
1349
|
"orchestrator implements directly (P0-6).\n",
|
|
1346
1350
|
),
|
|
1347
1351
|
"full": (
|
|
1348
|
-
"# Dev-Pipeline Session Bootstrap — Tier 3
|
|
1349
|
-
"
|
|
1350
|
-
"
|
|
1351
|
-
"
|
|
1352
|
+
"# Dev-Pipeline Session Bootstrap — Tier 3 "
|
|
1353
|
+
"(Orchestrator + Critic/Reviewer)\n",
|
|
1354
|
+
"**Tier 3 — Orchestrator + Critic/Reviewer**: For complex "
|
|
1355
|
+
"features, the main orchestrator handles context, planning, "
|
|
1356
|
+
"and implementation directly. Critic challenges the plan "
|
|
1357
|
+
"when enabled, Reviewer reviews, and no top-level Dev "
|
|
1358
|
+
"implementation subagent is spawned.\n",
|
|
1352
1359
|
),
|
|
1353
1360
|
}
|
|
1354
1361
|
return headers.get(pipeline_mode, headers["lite"])
|
|
@@ -1392,11 +1399,12 @@ def _tier_reminders(pipeline_mode, critic_enabled=False):
|
|
|
1392
1399
|
]
|
|
1393
1400
|
else: # full
|
|
1394
1401
|
specific = [
|
|
1395
|
-
"- Tier 3: full
|
|
1396
|
-
"(
|
|
1402
|
+
"- Tier 3: full orchestration — orchestrator implements "
|
|
1403
|
+
"directly (no top-level Dev subagent), Critic challenges "
|
|
1404
|
+
"plan, Reviewer reviews",
|
|
1397
1405
|
"- context-snapshot.md is append-only: orchestrator writes "
|
|
1398
|
-
"Sections 1-4
|
|
1399
|
-
"
|
|
1406
|
+
"Sections 1-4 + Implementation Log, Reviewer appends "
|
|
1407
|
+
"Review Notes",
|
|
1400
1408
|
"- Gate checks enforce Implementation Log and Review Notes are "
|
|
1401
1409
|
"written before proceeding",
|
|
1402
1410
|
"- Do NOT use `run_in_background=true` when spawning normal work "
|
|
@@ -1638,10 +1646,10 @@ def render_from_sections(sections, replacements):
|
|
|
1638
1646
|
"""
|
|
1639
1647
|
content = "\n".join(text for _, text in sections)
|
|
1640
1648
|
|
|
1641
|
-
# Replace all placeholders — run twice to handle agent prompt
|
|
1642
|
-
# that contain their own {{PLACEHOLDER}} variables.
|
|
1643
|
-
#
|
|
1644
|
-
#
|
|
1649
|
+
# Replace all placeholders — run twice to handle active agent prompt
|
|
1650
|
+
# templates that contain their own {{PLACEHOLDER}} variables. First pass
|
|
1651
|
+
# injects prompt content (for example, Critic plan challenge text); second
|
|
1652
|
+
# pass replaces inner feature/session variables.
|
|
1645
1653
|
for _pass in range(2):
|
|
1646
1654
|
for placeholder, value in replacements.items():
|
|
1647
1655
|
content = content.replace(placeholder, value)
|
|
@@ -2077,8 +2085,9 @@ def main():
|
|
|
2077
2085
|
args, feature, features, global_context, script_dir
|
|
2078
2086
|
)
|
|
2079
2087
|
|
|
2080
|
-
# Load agent prompt templates and merge into replacements
|
|
2081
|
-
|
|
2088
|
+
# Load active agent prompt templates and merge into replacements.
|
|
2089
|
+
# The retired top-level Dev implementation prompt is intentionally absent.
|
|
2090
|
+
agent_prompt_replacements = load_active_agent_prompts(templates_dir)
|
|
2082
2091
|
replacements.update(agent_prompt_replacements)
|
|
2083
2092
|
|
|
2084
2093
|
if is_continuation(args):
|
|
@@ -42,10 +42,11 @@ BUGFIX_PHASES = {
|
|
|
42
42
|
"Branch Setup",
|
|
43
43
|
"""\
|
|
44
44
|
Check current branch. You should already be on a fix/* branch from the
|
|
45
|
-
interrupted session. If so, continue on it
|
|
46
|
-
a new fix branch
|
|
45
|
+
interrupted session. If so, continue on it and do not create an additional
|
|
46
|
+
recovery branch. If somehow on main, create a new fix branch only as a
|
|
47
|
+
last-resort fallback:
|
|
47
48
|
```bash
|
|
48
|
-
git checkout -b fix/{bug_id}
|
|
49
|
+
git checkout -b fix/{bug_id}
|
|
49
50
|
```""",
|
|
50
51
|
),
|
|
51
52
|
1: (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Dev-Pipeline Session Bootstrap — Tier 2 (
|
|
1
|
+
# Dev-Pipeline Session Bootstrap — Tier 2 (Orchestrator + Critic/Reviewer)
|
|
2
2
|
|
|
3
3
|
## Session Context
|
|
4
4
|
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
You are the **session orchestrator**. Implement Feature {{FEATURE_ID}}: "{{FEATURE_TITLE}}".
|
|
12
12
|
|
|
13
|
-
**CRITICAL**: You MUST NOT exit until ALL work is complete and committed. When you spawn
|
|
13
|
+
**CRITICAL**: You MUST NOT exit until ALL work is complete and committed. When you spawn Critic or Reviewer agents, wait for each to finish (run_in_background=false).
|
|
14
14
|
|
|
15
|
-
**Tier 2 —
|
|
15
|
+
**Tier 2 — Orchestrator + Critic/Reviewer**: You handle context, planning, and implementation directly. Critic challenges the plan when enabled, Reviewer reviews. Do not spawn a top-level Dev subagent for implementation.
|
|
16
16
|
|
|
17
17
|
**Agent spawn failure policy (all Agent tool calls)**:
|
|
18
|
-
- If spawning
|
|
18
|
+
- If spawning Reviewer or Critic fails with team/config/lock errors, retry at most once.
|
|
19
19
|
- If the second attempt fails, do not keep spawning variants and do not enter artifact polling for Implementation Log, challenge report, or review report markers.
|
|
20
|
-
- Use the documented inline/recovery fallback for that phase: write the required report yourself where possible, complete remaining
|
|
20
|
+
- Use the documented inline/recovery fallback for that phase: write the required report yourself where possible, complete remaining work directly in the orchestrator when safe, or write `failure-log.md` with the spawn error and last observable state before stopping for recovery.
|
|
21
21
|
- Apply the same cap to any re-spawn for report repair or resume prompts; do not burn multiple minutes on identical team/config/lock failures.
|
|
22
22
|
|
|
23
23
|
### Feature Description
|
|
@@ -71,11 +71,11 @@ You are running in **headless non-interactive mode** with a FINITE context windo
|
|
|
71
71
|
## PrizmKit Directory Convention
|
|
72
72
|
|
|
73
73
|
```
|
|
74
|
-
.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md ← orchestrator writes Sections 1-4
|
|
74
|
+
.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md ← orchestrator writes Sections 1-4 + Implementation Log; Reviewer appends Review Notes
|
|
75
75
|
.prizmkit/specs/{{FEATURE_SLUG}}/plan.md ← includes Tasks section
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
**`context-snapshot.md`** is the shared knowledge base. Orchestrator writes Sections 1-4
|
|
78
|
+
**`context-snapshot.md`** is the shared knowledge base. Orchestrator writes Sections 1-4 and the Implementation Log; Reviewer appends Review Notes. Append-only after initial creation.
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
@@ -267,38 +267,63 @@ After all critics return, read all 3 reports:
|
|
|
267
267
|
**CP-2.5**: Plan challenges reviewed and resolved.
|
|
268
268
|
{{END_IF_CRITIC_ENABLED}}
|
|
269
269
|
|
|
270
|
-
###
|
|
270
|
+
### Implement — Orchestrator Direct (no Dev subagent)
|
|
271
271
|
|
|
272
|
-
**
|
|
272
|
+
**Rationale**: Development is deterministic plan execution — the orchestrator already built full context in Phase 1. Spawning a Dev subagent forces it to rebuild context (re-reading files the orchestrator already read), wastes context, and risks worktree double-edit. The orchestrator implements directly.
|
|
273
273
|
|
|
274
|
-
|
|
274
|
+
Before starting, check plan.md Tasks:
|
|
275
|
+
```bash
|
|
276
|
+
grep -c '^\- \[ \]' .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null || true
|
|
277
|
+
```
|
|
278
|
+
- If result is `0` (all tasks already `[x]`) → **SKIP to Review**.
|
|
279
|
+
- If non-zero → implement directly below.
|
|
275
280
|
|
|
276
|
-
|
|
281
|
+
**Build artifacts rule**: After any build/compile command, ensure output is in `.gitignore`. Never commit binaries/build output.
|
|
277
282
|
|
|
278
|
-
|
|
279
|
-
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
280
|
-
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
281
|
-
> ⚠️ DO NOT re-read source files already listed in Section 4 File Manifest unless you need implementation detail beyond the interface summary.
|
|
282
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` for full context.
|
|
283
|
-
> 2. Run `/prizmkit-implement` to execute the tasks in plan.md. Run tests with: `{{TEST_CMD}}`. Known baseline failures (pre-existing, not your fault): `{{BASELINE_FAILURES}}`.
|
|
284
|
-
> 3. If plan.md has more than 5 tasks: update durable checkpoints/artifacts after every 3 tasks, minimize output, and rely on runner continuation if context overflow occurs. In an interactive Claude Code session operated manually outside the headless pipeline, `/compact` may be used as an optional convenience only.
|
|
285
|
-
> 4. **Verification Gate Self-Check (BLOCKING)**: before returning, write a `### Gate Evidence` section to Implementation Log — one evidence line per gate (test name / file:line / fixture path). Any gate without evidence is BLOCKED, not success.
|
|
286
|
-
> 5. **Layered test strategy**: debug with single-file tests (`npx vitest run <file> -t '<name>'`), only run full suite as gate when single-file is green. Never run full suite while a single-file test is still red.
|
|
287
|
-
> 6. **Anti re-read**: 20-step window (full Read forbidden within 20 tool calls of last read), 3-strike (3 full Reads same file → BLOCKED). Use `grep -n`+`sed -n` for specific lines.
|
|
288
|
-
> 7. **Read offset safety**: if Read returns "shorter than offset"/"empty"/"wasted" — run `wc -l` then `sed -n`, do NOT retry same offset. 2 consecutive → STOP Reading that file.
|
|
289
|
-
> 8. **Hard Round Cap**: after 6 total test-fix rounds, STOP trial-and-error. Write failure-log. Switch to read-once-then-rewrite strategy. Do NOT exceed 7 rounds.
|
|
290
|
-
> 9. After implement completes, verify the '## Implementation Log' section (with Gate Evidence) was written to context-snapshot.md.
|
|
291
|
-
> 10. Do NOT execute any git commands (no git add/commit/reset/push).
|
|
292
|
-
> Do NOT exit until all tasks are [x] and the '## Implementation Log' section (with Gate Evidence) is written in context-snapshot.md."
|
|
293
|
-
|
|
294
|
-
Wait for Dev to return. All tasks must be `[x]`, tests pass.
|
|
295
|
-
|
|
296
|
-
**Gate Check — Implementation Log**:
|
|
297
|
-
After Dev agent returns, verify the Implementation Log was written:
|
|
283
|
+
**3a.** Detect test commands and record baseline:
|
|
298
284
|
```bash
|
|
299
|
-
|
|
285
|
+
($TEST_CMD) 2>&1 | tee /tmp/test-baseline.txt | tail -20
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**3b.** Run `/prizmkit-implement` directly — you (the orchestrator) execute the full cycle:
|
|
289
|
+
- Read plan.md Tasks from `.prizmkit/specs/{{FEATURE_SLUG}}/`
|
|
290
|
+
- Use context-snapshot.md Section 4 File Manifest for targeted reads — do NOT re-read files already summarized there
|
|
291
|
+
- Implements task-by-task, marking each `[x]` immediately
|
|
292
|
+
- Creates/updates L2 `.prizm` docs when creating new modules
|
|
293
|
+
- Defers scoped/full test execution until after the code-review loop completes
|
|
294
|
+
- If plan.md has >5 tasks: update checkpoints after every 3 tasks
|
|
295
|
+
|
|
296
|
+
**3c. Focused checks only (no test gate here)**:
|
|
297
|
+
- During implementation, do not run mandatory periodic or full-suite tests.
|
|
298
|
+
- If a tiny targeted check is needed to understand a local failure, run only the smallest relevant command and capture output to `/tmp/test-out.txt`.
|
|
299
|
+
- The scoped feature test gate runs after code review; do not declare implementation success based on an early full-suite run.
|
|
300
|
+
|
|
301
|
+
**3d. Verification Gate Self-Check (BLOCKING — before declaring implement done)**:
|
|
302
|
+
For each Verification Gate from the Task Contract, write one evidence line to Implementation Log:
|
|
303
|
+
```
|
|
304
|
+
### Gate Evidence
|
|
305
|
+
- [x] G1: <gate text> — Evidence: <test name / file:line / fixture path>
|
|
306
|
+
- [ ] G3: <gate text> — BLOCKED: <reason> ← no evidence = BLOCKED, not success
|
|
300
307
|
```
|
|
301
|
-
|
|
308
|
+
|
|
309
|
+
**3e.** Append `## Implementation Log` (with Gate Evidence) to `context-snapshot.md`:
|
|
310
|
+
- files changed/created
|
|
311
|
+
- key decisions
|
|
312
|
+
- deviations from plan
|
|
313
|
+
- test results
|
|
314
|
+
- Gate Evidence section
|
|
315
|
+
- unresolved blockers
|
|
316
|
+
|
|
317
|
+
**CP-2**: All tasks `[x]`, Implementation Log written with Gate Evidence, and blocked gates documented in `failure-log.md`. Test execution is deferred until after code review.
|
|
318
|
+
|
|
319
|
+
**Checkpoint update**:
|
|
320
|
+
```bash
|
|
321
|
+
python3 $PIPELINE_DIR/scripts/update-checkpoint.py \
|
|
322
|
+
--checkpoint-path .prizmkit/specs/{{FEATURE_SLUG}}/workflow-checkpoint.json \
|
|
323
|
+
--step prizmkit-implement \
|
|
324
|
+
--status completed
|
|
325
|
+
```
|
|
326
|
+
|
|
302
327
|
|
|
303
328
|
### Scoped Feature Test Gate — PrizmKit Test
|
|
304
329
|
|
|
@@ -584,7 +609,6 @@ Rules for writing completion notes:
|
|
|
584
609
|
|----------|------|
|
|
585
610
|
| Feature Artifacts Dir | `.prizmkit/specs/{{FEATURE_SLUG}}/` |
|
|
586
611
|
| Context Snapshot | `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` |
|
|
587
|
-
| Dev Agent Def | {{DEV_SUBAGENT_PATH}} |
|
|
588
612
|
| Reviewer Agent Def | {{REVIEWER_SUBAGENT_PATH}} |
|
|
589
613
|
{{IF_CRITIC_ENABLED}}
|
|
590
614
|
| Critic Agent Def | {{CRITIC_SUBAGENT_PATH}} |
|
|
@@ -610,11 +634,11 @@ If you encounter an unrecoverable error, context overflow, or are about to exit
|
|
|
610
634
|
|
|
611
635
|
## Reminders
|
|
612
636
|
|
|
613
|
-
- Tier 2: orchestrator builds context+plan
|
|
614
|
-
- Build context-snapshot.md FIRST;
|
|
615
|
-
- context-snapshot.md is append-only: orchestrator writes Sections 1-4
|
|
637
|
+
- Tier 2: orchestrator builds context+plan and implements directly; Critic challenges plan when enabled; Reviewer reviews
|
|
638
|
+
- Build context-snapshot.md FIRST; use it throughout instead of re-reading source files
|
|
639
|
+
- context-snapshot.md is append-only: orchestrator writes Sections 1-4 + Implementation Log, Reviewer appends Review Notes
|
|
616
640
|
- Gate checks enforce Implementation Log and Review Notes are written before proceeding
|
|
617
|
-
- Do NOT use `run_in_background=true` when spawning
|
|
641
|
+
- Do NOT use `run_in_background=true` when spawning Critic or Reviewer agents
|
|
618
642
|
- **NEVER delete, modify, or touch any file under `.prizmkit/state/`** — those are pipeline runtime files managed by the runner
|
|
619
643
|
- NEVER run `rm -rf`, `git clean`, or any destructive filesystem operations
|
|
620
644
|
- `/prizmkit-committer` is mandatory, and must not be replaced with manual git commit commands
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Dev-Pipeline Session Bootstrap — Tier 3 (
|
|
1
|
+
# Dev-Pipeline Session Bootstrap — Tier 3 (Orchestrator + Critic/Reviewer)
|
|
2
2
|
|
|
3
3
|
## Session Context
|
|
4
4
|
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
|
|
11
11
|
You are the **session orchestrator**. Implement Feature {{FEATURE_ID}}: "{{FEATURE_TITLE}}".
|
|
12
12
|
|
|
13
|
-
**CRITICAL**: You MUST NOT exit until ALL work is complete and committed. When you spawn
|
|
13
|
+
**CRITICAL**: You MUST NOT exit until ALL work is complete and committed. When you spawn Critic or Reviewer agents, wait for each to finish (run_in_background=false). Do NOT spawn agents in background and exit — that kills the session.
|
|
14
14
|
|
|
15
|
-
**Tier 3 —
|
|
15
|
+
**Tier 3 — Orchestrator + Critic/Reviewer**: For complex features, the main orchestrator handles context, planning, and implementation directly. Critic challenges the plan and Reviewer reviews. Do not spawn a top-level Dev implementation agent.
|
|
16
16
|
|
|
17
17
|
**Agent spawn failure policy (all Agent tool calls)**:
|
|
18
|
-
- If spawning
|
|
18
|
+
- If spawning Reviewer or Critic fails with team/config/lock errors, retry at most once.
|
|
19
19
|
- If the second attempt fails, do not keep spawning variants and do not enter artifact polling for Implementation Log, challenge report, or review report markers.
|
|
20
|
-
- Use the documented inline/recovery fallback for that phase: write the required report yourself where possible, complete remaining
|
|
20
|
+
- Use the documented inline/recovery fallback for that phase: write the required report yourself where possible, complete remaining work directly in the orchestrator when safe, or write `failure-log.md` with the spawn error and last observable state before stopping for recovery.
|
|
21
21
|
- Apply the same cap to any re-spawn for report repair or resume prompts; do not burn multiple minutes on identical team/config/lock failures.
|
|
22
22
|
|
|
23
23
|
### Feature Description
|
|
@@ -71,12 +71,12 @@ You are running in **headless non-interactive mode** with a FINITE context windo
|
|
|
71
71
|
## PrizmKit Directory Convention
|
|
72
72
|
|
|
73
73
|
```
|
|
74
|
-
.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md ← orchestrator writes Sections 1-4
|
|
74
|
+
.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md ← orchestrator writes Sections 1-4 + Implementation Log; Reviewer appends Review Notes
|
|
75
75
|
.prizmkit/specs/{{FEATURE_SLUG}}/spec.md
|
|
76
76
|
.prizmkit/specs/{{FEATURE_SLUG}}/plan.md ← includes Tasks section
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
**`context-snapshot.md`** is the shared knowledge base. Orchestrator writes Sections 1-4
|
|
79
|
+
**`context-snapshot.md`** is the shared knowledge base. Orchestrator writes Sections 1-4 and the Implementation Log; Reviewer appends Review Notes. This eliminates redundant I/O across review and orchestration phases.
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
@@ -268,55 +268,64 @@ After all critics return, read all 3 reports:
|
|
|
268
268
|
**CP-2.5**: Plan challenges reviewed and resolved.
|
|
269
269
|
{{END_IF_CRITIC_ENABLED}}
|
|
270
270
|
|
|
271
|
-
###
|
|
271
|
+
### Implement — Orchestrator Direct (no Dev subagent)
|
|
272
272
|
|
|
273
|
-
**
|
|
273
|
+
**Rationale**: Development is deterministic plan execution — the orchestrator already built full context in Phase 1-2. Spawning a Dev subagent forces it to rebuild context (re-reading files the orchestrator already read), wastes context, and risks worktree double-edit. The orchestrator implements directly.
|
|
274
274
|
|
|
275
|
-
Before
|
|
275
|
+
Before starting, check plan.md Tasks:
|
|
276
276
|
```bash
|
|
277
277
|
grep -c '^\- \[ \]' .prizmkit/specs/{{FEATURE_SLUG}}/plan.md 2>/dev/null || true
|
|
278
278
|
```
|
|
279
|
-
- If result is `0` (all tasks already `[x]`) → **SKIP
|
|
280
|
-
- If
|
|
279
|
+
- If result is `0` (all tasks already `[x]`) → **SKIP to Review**.
|
|
280
|
+
- If non-zero → implement directly below.
|
|
281
281
|
|
|
282
|
-
|
|
282
|
+
**Build artifacts rule**: After any build/compile command, ensure output is in `.gitignore`. Never commit binaries/build output.
|
|
283
283
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
Prompt:
|
|
287
|
-
> "Read {{DEV_SUBAGENT_PATH}}. Implement feature {{FEATURE_ID}} (slug: {{FEATURE_SLUG}}).
|
|
288
|
-
> **IMPORTANT**: Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` FIRST — Section 3 has Prizm Context (TRAPS/RULES), Section 4 has File Manifest with paths and interfaces.
|
|
289
|
-
> ⚠️ DO NOT re-read source files already listed in Section 4 File Manifest unless you need implementation detail beyond the interface summary.
|
|
290
|
-
> 1. Read `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` for full context.
|
|
291
|
-
> 2. Run `/prizmkit-implement` to execute the tasks in plan.md. Run tests with: `{{TEST_CMD}}`. Known baseline failures (pre-existing, not your fault): `{{BASELINE_FAILURES}}`.
|
|
292
|
-
> 3. If plan.md has more than 5 tasks: update durable checkpoints/artifacts after every 3 tasks, minimize output, and rely on runner continuation if context overflow occurs. In an interactive Claude Code session operated manually outside the headless pipeline, `/compact` may be used as an optional convenience only.
|
|
293
|
-
> 4. **Verification Gate Self-Check (BLOCKING)**: before returning, write a `### Gate Evidence` section to Implementation Log — one evidence line per gate (test name / file:line / fixture path). Any gate without evidence is BLOCKED, not success.
|
|
294
|
-
> 5. **Layered test strategy**: debug with single-file tests (`npx vitest run <file> -t '<name>'`), only run full suite as gate when single-file is green. Never run full suite while a single-file test is still red.
|
|
295
|
-
> 6. **Anti re-read**: 20-step window (full Read forbidden within 20 tool calls of last read), 3-strike (3 full Reads same file → BLOCKED). Use `grep -n`+`sed -n` for specific lines.
|
|
296
|
-
> 7. **Read offset safety**: if Read returns "shorter than offset"/"empty"/"wasted" — run `wc -l` then `sed -n`, do NOT retry same offset. 2 consecutive → STOP Reading that file.
|
|
297
|
-
> 8. **Hard Round Cap**: after 6 total test-fix rounds, STOP trial-and-error. Write failure-log. Switch to read-once-then-rewrite strategy. Do NOT exceed 7 rounds.
|
|
298
|
-
> 9. After implement completes, verify the '## Implementation Log' section (with Gate Evidence) was written to context-snapshot.md.
|
|
299
|
-
> 10. Do NOT execute any git commands (no git add/commit/reset/push).
|
|
300
|
-
> Do NOT exit until all tasks are [x] and the '## Implementation Log' section (with Gate Evidence) is written in context-snapshot.md."
|
|
301
|
-
|
|
302
|
-
**Gate Check — Implementation Log**:
|
|
303
|
-
After Dev agent returns, verify the Implementation Log was written:
|
|
284
|
+
**3a.** Detect test commands and record baseline:
|
|
304
285
|
```bash
|
|
305
|
-
|
|
286
|
+
($TEST_CMD) 2>&1 | tee /tmp/test-baseline.txt | tail -20
|
|
287
|
+
```
|
|
288
|
+
Save pre-existing failing tests as `BASELINE_FAILURES`.
|
|
289
|
+
|
|
290
|
+
**3b.** Run `/prizmkit-implement` directly — you (the orchestrator) execute the full cycle:
|
|
291
|
+
- Read plan.md Tasks from `.prizmkit/specs/{{FEATURE_SLUG}}/`
|
|
292
|
+
- Use context-snapshot.md Section 4 File Manifest for targeted reads — do NOT re-read files already summarized there
|
|
293
|
+
- Implements task-by-task, marking each `[x]` immediately
|
|
294
|
+
- Creates/updates L2 `.prizm` docs when creating new modules
|
|
295
|
+
- Defers scoped/full test execution until after the code-review loop completes
|
|
296
|
+
- If plan.md has >5 tasks: update checkpoints after every 3 tasks
|
|
297
|
+
|
|
298
|
+
**3c. Focused checks only (no test gate here)**:
|
|
299
|
+
- During implementation, do not run mandatory periodic or full-suite tests.
|
|
300
|
+
- If a tiny targeted check is needed to understand a local failure, run only the smallest relevant command and capture output to `/tmp/test-out.txt`.
|
|
301
|
+
- The scoped feature test gate runs after code review; do not declare implementation success based on an early full-suite run.
|
|
302
|
+
|
|
303
|
+
**3d. Verification Gate Self-Check (BLOCKING — before declaring implement done)**:
|
|
304
|
+
For each Verification Gate from the Task Contract, write one evidence line to Implementation Log:
|
|
305
|
+
```
|
|
306
|
+
### Gate Evidence
|
|
307
|
+
- [x] G1: <gate text> — Evidence: <test name / file:line / fixture path>
|
|
308
|
+
- [ ] G3: <gate text> — BLOCKED: <reason> ← no evidence = BLOCKED, not success
|
|
306
309
|
```
|
|
307
|
-
If GATE:MISSING — send message to Dev (re-spawn if needed): "Write the '## Implementation Log' section to context-snapshot.md before I can proceed to review. Include: files changed/created, key decisions, deviations from plan, notable discoveries."
|
|
308
310
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
311
|
+
**3e.** Append `## Implementation Log` (with Gate Evidence) to `context-snapshot.md`:
|
|
312
|
+
- files changed/created
|
|
313
|
+
- key decisions
|
|
314
|
+
- deviations from plan
|
|
315
|
+
- test results
|
|
316
|
+
- Gate Evidence section
|
|
317
|
+
- unresolved blockers
|
|
318
|
+
|
|
319
|
+
**CP-2**: All tasks `[x]`, Implementation Log written with Gate Evidence, and blocked gates documented in `failure-log.md`. Test execution is deferred until after code review.
|
|
320
|
+
|
|
321
|
+
**Checkpoint update**:
|
|
322
|
+
```bash
|
|
323
|
+
python3 $PIPELINE_DIR/scripts/update-checkpoint.py \
|
|
324
|
+
--checkpoint-path .prizmkit/specs/{{FEATURE_SLUG}}/workflow-checkpoint.json \
|
|
325
|
+
--step prizmkit-implement \
|
|
326
|
+
--status completed
|
|
327
|
+
```
|
|
318
328
|
|
|
319
|
-
All tasks `[x]`, tests pass.
|
|
320
329
|
|
|
321
330
|
### Scoped Feature Test Gate — PrizmKit Test
|
|
322
331
|
|
|
@@ -618,7 +627,6 @@ Rules for writing completion notes:
|
|
|
618
627
|
| Feature Artifacts Dir | `.prizmkit/specs/{{FEATURE_SLUG}}/` |
|
|
619
628
|
| Context Snapshot | `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` |
|
|
620
629
|
| Team Config | `{{TEAM_CONFIG_PATH}}` |
|
|
621
|
-
| Dev Agent Def | {{DEV_SUBAGENT_PATH}} |
|
|
622
630
|
| Reviewer Agent Def | {{REVIEWER_SUBAGENT_PATH}} |
|
|
623
631
|
{{IF_CRITIC_ENABLED}}
|
|
624
632
|
| Critic Agent Def | {{CRITIC_SUBAGENT_PATH}} |
|
|
@@ -645,10 +653,10 @@ If you encounter an unrecoverable error, context overflow, or are about to exit
|
|
|
645
653
|
|
|
646
654
|
## Reminders
|
|
647
655
|
|
|
648
|
-
- Tier 3:
|
|
649
|
-
- context-snapshot.md is append-only: orchestrator writes Sections 1-4
|
|
656
|
+
- Tier 3: orchestrator implements directly; Critic challenges plan; Reviewer reviews
|
|
657
|
+
- context-snapshot.md is append-only: orchestrator writes Sections 1-4 + Implementation Log, Reviewer appends Review Notes
|
|
650
658
|
- Gate checks enforce Implementation Log and Review Notes are written before proceeding
|
|
651
|
-
- Do NOT use `run_in_background=true` when spawning
|
|
659
|
+
- Do NOT use `run_in_background=true` when spawning Critic or Reviewer agents
|
|
652
660
|
- Commit phase must use `/prizmkit-committer`; do NOT replace with manual git commit commands
|
|
653
661
|
- **NEVER delete, modify, or touch any file under `.prizmkit/state/`** — those are pipeline runtime files managed by the runner
|
|
654
662
|
- NEVER run `rm -rf`, `git clean`, or any destructive filesystem operations
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|----------|------|
|
|
5
5
|
| Feature Artifacts Dir | `.prizmkit/specs/{{FEATURE_SLUG}}/` |
|
|
6
6
|
| Context Snapshot | `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` |
|
|
7
|
-
| Dev Agent Def | {{DEV_SUBAGENT_PATH}} |
|
|
8
7
|
| Reviewer Agent Def | {{REVIEWER_SUBAGENT_PATH}} |
|
|
9
8
|
| Critic Agent Def (if enabled) | {{CRITIC_SUBAGENT_PATH}} |
|
|
10
9
|
| Project Root | {{PROJECT_ROOT}} |
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
| Feature Artifacts Dir | `.prizmkit/specs/{{FEATURE_SLUG}}/` |
|
|
6
6
|
| Context Snapshot | `.prizmkit/specs/{{FEATURE_SLUG}}/context-snapshot.md` |
|
|
7
7
|
| Team Config | `{{TEAM_CONFIG_PATH}}` |
|
|
8
|
-
| Dev Agent Def | {{DEV_SUBAGENT_PATH}} |
|
|
9
8
|
| Reviewer Agent Def | {{REVIEWER_SUBAGENT_PATH}} |
|
|
10
9
|
| Critic Agent Def | {{CRITIC_SUBAGENT_PATH}} |
|
|
11
10
|
| Project Root | {{PROJECT_ROOT}} |
|