fix(reset): target the headings the shipped skill files actually have (#519)

* fix(reset): target the headings the shipped skill files actually have

Two of /reset profile's Step 3 targets had drifted from the files they
rewrite.

The 05-cv-templates.md step anchored on a section beginning
"**Profile statement templates", a line the guide has never contained
(its heading is "**Create 2-3 profile statement templates for your main
role types:**"), so the wipe found nothing: the user's role-tailored
profile statements, and any *[Used for: ...]* statements /setup Path A
extracted from archived applications, survived a reset that reported
success.

The 02-behavioral-profile.md skeleton used headings the shipped file
does not have ("Strongest Behavioral Traits", "How I Work Best", a
truncated "Growth Areas") and dropped "## Core Behavioral Drives" - the
assessment table /setup collects and /interview reads - so one reset
left the file's headings permanently different from every other fork's.

Anchor on the real heading and re-emit it in the replacement; carry the
shipped headings in order in the skeleton. 01-candidate-profile.md and
07-interview-prep.md were already correct. Two new tests derive both
checks from the shipped files, so a renamed heading fails until /reset
follows it; both fail on master.

* test(reset): place the heading guards above the __main__ guard so a direct run sees them

python tests/test_reset_command.py ran only the five old tests; unittest
discover imports the module and saw all seven, which is why CI was green.
Also drop the CHANGELOG's claim that /setup and /interview name the Core
Behavioral Drives table - neither does.
This commit is contained in:
Ayobami Adegoke authored and GitHub committed 2026-10-08 21:23:59 +02:00
1 parent 8dbc941642
commit a011214d60
3 files changed
+102 -6

No files matched your search

+77
View File
@@ -163,6 +163,83 @@ class TestResetCoversEveryPersonalizedSkillFile(unittest.TestCase):
f"{mislabeled}",
)
SKILL_DIR = REPO / ".claude" / "skills" / "job-application-assistant"
def skeleton_block(reset_text, filename):
"""The fenced markdown /reset writes over `filename` in Step 3."""
marker = f"**For `{filename}`**, replace the file content with:"
start = reset_text.index(marker)
fence_open = reset_text.index("```markdown", start) + len("```markdown")
fence_close = reset_text.index("```", fence_open)
return reset_text[fence_open:fence_close]
def h2_headings(text):
return [line.strip() for line in text.splitlines() if line.startswith("## ")]
class TestResetTargetsTheHeadingsTheShippedFilesHave(unittest.TestCase):
"""Step 3's skeletons and anchors must name sections that exist.
Two of them drifted from the files they rewrite. The behavioral-profile
skeleton used "Strongest Behavioral Traits" / "How I Work Best" / "Growth
Areas" where the shipped file has "Strongest Behaviors" / "How You Work
Best" / "Growth Areas (frame positively in applications)", and dropped
"Core Behavioral Drives" - the structured assessment table /setup collects
and /interview reads - so one reset left the file's headings permanently
different from every other fork's. The CV-guide step anchored on a line
beginning "**Profile statement templates", which the guide has never
contained (its heading is "**Create 2-3 profile statement templates for
your main role types:**"), so the wipe found nothing and the user's
role-tailored statements survived a reset that reported success. Both are
derived here from the shipped files, so a renamed heading fails this test
until /reset follows it.
"""
def setUp(self):
self.reset = RESET.read_text(encoding="utf-8")
def test_full_file_skeletons_keep_the_shipped_headings(self):
for filename in ("01-candidate-profile.md", "02-behavioral-profile.md"):
with self.subTest(file=filename):
shipped = (SKILL_DIR / filename).read_text(encoding="utf-8")
self.assertEqual(
h2_headings(skeleton_block(self.reset, filename)),
h2_headings(shipped),
f"/reset's skeleton for {filename} must carry exactly the shipped "
"## headings, in order - a reset must not rename or drop sections",
)
def test_partial_anchors_exist_in_the_files_they_target(self):
# (reset.md anchor phrase, file, heading the replacement must re-emit)
cases = (
(
r"locate the section that begins with the line `([^`]+)`",
"05-cv-templates.md",
),
(
r"The entire `([^`]+)` section",
"07-interview-prep.md",
),
)
for pattern, filename in cases:
with self.subTest(file=filename):
match = re.search(pattern, self.reset)
self.assertIsNotNone(match, f"reset.md no longer states its anchor for {filename}")
anchor = match.group(1)
shipped = (SKILL_DIR / filename).read_text(encoding="utf-8")
self.assertIn(
anchor,
shipped,
f"/reset anchors {filename} on {anchor!r}, which the shipped file does not contain - "
"the wipe would silently find nothing",
)
# The replacement block re-emits the anchor line so the heading survives the wipe.
step = self.reset[match.start():]
block_start = step.index("```markdown") + len("```markdown")
block = step[block_start: step.index("```", block_start)]
self.assertIn(anchor, block, f"the replacement for {filename} must keep the heading {anchor!r}")
if __name__ == "__main__":
unittest.main()