anchors.py file-level

at sha256:a · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:6 fix(ISR): default require_independent_second_reviewer to require Opera… · aaronrene · Sep 2, 2026
1 """Named anchor markers for templated section replacement (§4)."""
2
3 from __future__ import annotations
4
5 import re
6
7 ANCHOR_OPEN = "<!-- overseer:anchor:{name} -->"
8 ANCHOR_CLOSE = "<!-- /overseer:anchor:{name} -->"
9
10
11 def anchor_open(name: str) -> str:
12 return ANCHOR_OPEN.format(name=name)
13
14
15 def anchor_close(name: str) -> str:
16 return ANCHOR_CLOSE.format(name=name)
17
18
19 HANDOVER_ANCHORS = frozenset(
20 {
21 "vcs-table",
22 "done-recently",
23 "verified-snapshot",
24 "change-log",
25 "next-session",
26 "paste-ready-prompt",
27 }
28 )
29
30 ROADMAP_ANCHORS = frozenset(
31 {
32 "build-queue",
33 "next-step-glance",
34 }
35 )
36
37
38 def replace_anchor_block(text: str, name: str, new_body: str) -> str:
39 """Replace content between named anchors; insert anchors if the block is missing."""
40 open_marker = anchor_open(name)
41 close_marker = anchor_close(name)
42 body = new_body.strip("\n")
43 block = f"{open_marker}\n{body}\n{close_marker}"
44
45 pattern = re.compile(
46 re.escape(open_marker) + r"\n.*?\n" + re.escape(close_marker),
47 re.DOTALL,
48 )
49 if pattern.search(text):
50 return pattern.sub(block, text, count=1)
51
52 return _insert_anchor_fallback(text, name, block)
53
54
55 def _insert_anchor_fallback(text: str, name: str, block: str) -> str:
56 """Insert or replace anchor block near a known heading when markers are absent.
57
58 ``next-session`` / ``paste-ready-prompt`` use region bounds (§GSP.5.3) so nested
59 paste-inside-NEXT dogfood is not swallowed on first regen.
60 """
61 if name == "next-session":
62 replaced = _replace_next_session_region(text, block)
63 if replaced is not None:
64 return replaced
65 if name == "paste-ready-prompt":
66 replaced = _replace_paste_ready_region(text, block)
67 if replaced is not None:
68 return replaced
69
70 heading_map = {
71 "vcs-table": "## VCS (verified",
72 "done-recently": "### What just landed",
73 "verified-snapshot": "## Verified snapshot",
74 "change-log": "## Change log",
75 "next-session": "## NEXT SESSION",
76 "paste-ready-prompt": "### Paste-ready prompt",
77 "build-queue": "## Build queue",
78 "next-step-glance": "## Next step at a glance",
79 }
80 heading = heading_map.get(name)
81 if heading and heading in text:
82 return text.replace(heading, block + "\n\n" + heading, 1)
83 return text.rstrip() + "\n\n" + block + "\n"
84
85
86 def _replace_next_session_region(text: str, block: str) -> str | None:
87 """Replace from ``## NEXT SESSION`` through line before paste heading or snapshot ``---``."""
88 lines = text.splitlines(keepends=True)
89 start: int | None = None
90 end: int | None = None
91 for index, line in enumerate(lines):
92 if start is None and line.startswith("## NEXT SESSION"):
93 start = index
94 continue
95 if start is None:
96 continue
97 stripped = line.strip()
98 if stripped.startswith("### Paste-ready prompt"):
99 end = index
100 break
101 if stripped == "---":
102 # Prefer the --- that precedes ## Verified snapshot when no paste heading.
103 ahead = "".join(lines[index + 1 : index + 6])
104 if "## Verified snapshot" in ahead or "<!-- overseer:anchor:verified-snapshot" in ahead:
105 end = index
106 break
107 if start is None:
108 return None
109 if end is None:
110 end = len(lines)
111 prefix = "".join(lines[:start])
112 suffix = "".join(lines[end:])
113 body = block if block.endswith("\n") else block + "\n"
114 return prefix + body + ("\n" if suffix and not body.endswith("\n\n") else "") + suffix
115
116
117 def _replace_paste_ready_region(text: str, block: str) -> str | None:
118 """Replace from ``### Paste-ready prompt`` through the first fenced code block close."""
119 lines = text.splitlines(keepends=True)
120 start: int | None = None
121 fence_open = False
122 end: int | None = None
123 for index, line in enumerate(lines):
124 if start is None:
125 if line.strip().startswith("### Paste-ready prompt"):
126 start = index
127 continue
128 stripped = line.strip()
129 if not fence_open and stripped.startswith("```"):
130 fence_open = True
131 continue
132 if fence_open and stripped.startswith("```"):
133 end = index + 1
134 break
135 if start is None or end is None:
136 return None
137 prefix = "".join(lines[:start])
138 suffix = "".join(lines[end:])
139 body = block if block.endswith("\n") else block + "\n"
140 return prefix + body + suffix