test_gs_paste_next_regen.py python
168 lines 5.3 KB
Raw
sha256:8461d44b77376fbf06fa7c3e085d309e3010fd8d5886d63c63e69ce118811ad4 docs: record AFF-b feature-tip SHAs after AFF-b-ISR commit. Human 4 days ago
1 """Unit tests for GS-PASTE NEXT / paste regeneration (§GSP.10 unit)."""
2
3 from __future__ import annotations
4
5 from pathlib import Path
6
7 from adapters.config import load_config
8 from tools.governance_hygiene.next_regen import (
9 compact_step_id,
10 decide_split_emission,
11 plan_next_regen,
12 render_next_session,
13 render_paste_ready,
14 select_unambiguous_next_row,
15 )
16 from tools.governance_hygiene.patch import _render_next_step_glance
17 from tools.governance_hygiene.types import QueueRow
18
19
20 def _roadmap(*rows: str) -> str:
21 header = (
22 "# Roadmap\n\n## Build queue\n\n"
23 "| Phase | Model | Status | Deliverable |\n"
24 "| --- | --- | --- | --- |\n"
25 )
26 return header + "\n".join(rows) + "\n"
27
28
29 def test_select_exactly_one_open_row() -> None:
30 text = _roadmap(
31 "| **Done** | Auto | **DONE** | x |",
32 "| **Open** | Auto | **NEXT** | y |",
33 )
34 row, reason = select_unambiguous_next_row(text)
35 assert reason is None
36 assert row is not None
37 assert "Open" in row.phase_label
38
39
40 def test_select_zero_open_rows() -> None:
41 text = _roadmap("| **Done** | Auto | **DONE** | x |")
42 row, reason = select_unambiguous_next_row(text)
43 assert row is None
44 assert reason == "zero_open_rows"
45
46
47 def test_select_multiple_open_rows() -> None:
48 text = _roadmap(
49 "| **A** | Auto | **TODO** | a |",
50 "| **B** | Auto | **WIP** | b |",
51 )
52 row, reason = select_unambiguous_next_row(text)
53 assert row is None
54 assert reason == "multiple_open_rows"
55
56
57 def test_select_invalid_model_ambiguous() -> None:
58 text = _roadmap("| **Open** | Operator choice | **NEXT** | y |")
59 row, reason = select_unambiguous_next_row(text)
60 assert row is None
61 assert reason == "invalid_model_label"
62
63
64 def test_thinking_to_auto_emit_b_when_freeze_pass(tmp_path: Path) -> None:
65 """Mechanical stamp alone no longer authorizes Auto (§FRV.6.5)."""
66 docs = tmp_path / "docs"
67 docs.mkdir()
68 (docs / "PHASE-GS-PASTE-READY-REGEN.md").write_text(
69 "# Freeze\n\n"
70 "```yaml\n"
71 "phase: GS-PASTE\n"
72 "outputs:\n"
73 " - id: a\n"
74 " path: docs/a.md\n"
75 " frozen: true\n"
76 "review_stamp:\n"
77 " verdict: pass\n"
78 "```\n",
79 encoding="utf-8",
80 )
81 config = load_config(Path(__file__).resolve().parents[1] / "fixtures" / "config-git-only.yaml")
82 row = QueueRow(
83 phase_label="**GS-PASTE**",
84 model="Thinking → Auto",
85 status="**NEXT**",
86 deliverable="docs/archive/phases/PHASE-GS-PASTE-READY-REGEN.md",
87 raw_line="",
88 )
89 emit_model, reason, is_b, advisory = decide_split_emission(row, tmp_path, config=config)
90 assert reason is None
91 assert emit_model == "Thinking"
92 assert is_b is False
93 assert advisory == "mechanical_only"
94
95
96 def test_thinking_to_auto_emit_a_without_freeze_pass(tmp_path: Path) -> None:
97 docs = tmp_path / "docs"
98 docs.mkdir()
99 config = load_config(Path(__file__).resolve().parents[1] / "fixtures" / "config-git-only.yaml")
100 row = QueueRow(
101 phase_label="**GS-PASTE**",
102 model="Thinking → Auto",
103 status="**NEXT**",
104 deliverable="freeze something",
105 raw_line="",
106 )
107 emit_model, reason, is_b, advisory = decide_split_emission(row, tmp_path, config=config)
108 assert reason is None
109 assert emit_model == "Thinking"
110 assert is_b is False
111 assert advisory is None
112
113
114 def test_rendered_next_contains_h3_h5_h6_substrings(tmp_path: Path) -> None:
115 config = load_config(
116 Path(__file__).resolve().parents[1] / "fixtures" / "config-git-only.yaml"
117 )
118 roadmap = _roadmap(
119 "| **Prior** | Auto | **DONE** | prior work |",
120 "| **GS-PASTE-b** | Auto | **NEXT** | regen paste |",
121 )
122 decision = plan_next_regen(
123 roadmap_text=roadmap,
124 handover_text="## NEXT SESSION — x\n",
125 config=config,
126 repo_root=tmp_path,
127 )
128 assert decision.row is not None
129 body = render_next_session(
130 decision=decision,
131 roadmap_text=roadmap,
132 config=config,
133 sync_date="2026-07-30",
134 )
135 assert "**Date:**" in body
136 assert "**Current position:**" in body
137 assert "**Model:**" in body
138 assert "### THE ONE NEXT STEP — **Model:" in body
139 assert "| **ID** |" in body
140 assert "| **Branch** |" in body
141 assert "| **Repo** |" in body
142 assert "| **Read first** |" in body
143 assert "| **Hard stops** |" in body
144 assert "### Paste-ready prompt" not in body
145
146 paste = render_paste_ready(decision=decision, config=config)
147 assert "### Paste-ready prompt —" in paste
148 assert "Model: Auto" in paste
149 assert "Repo:" in paste
150 assert "Step:" in paste
151 assert "Authority:" in paste
152 assert "build-verification-review" in paste
153
154
155 def test_glance_fail_closed_when_open_count_not_one() -> None:
156 multi = _roadmap(
157 "| **A** | Auto | **TODO** | a |",
158 "| **B** | Auto | **WIP** | b |",
159 )
160 glance = _render_next_step_glance(multi)
161 assert "No unambiguous NEXT row — operator authorship required." in glance
162
163 zero = _roadmap("| **A** | Auto | **DONE** | a |")
164 assert "No unambiguous NEXT row" in _render_next_step_glance(zero)
165
166
167 def test_compact_step_id_uses_first_segment() -> None:
168 assert compact_step_id("**GS-PASTE-b Paste regen**") == "GS-PASTE-b"
File History 1 commit
sha256:8461d44b77376fbf06fa7c3e085d309e3010fd8d5886d63c63e69ce118811ad4 docs: record AFF-b feature-tip SHAs after AFF-b-ISR commit. Human 4 days ago