Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions tests/test_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,19 @@ def test_duplicate_targets_deduplicated(self):
)
self.assertEqual(fm_line.count("invoice-compare"), 1)

def test_existing_real_value_overwritten(self):
"""Regression: a second link-ingest run must overwrite an existing real
related_skills value, not leave it stale. Previously only placeholder
sentinels (none / PLACEHOLDER / [PLACEHOLDER]) were matched, so this
silently skipped the frontmatter update while still rewriting the body
table — leaving frontmatter and body inconsistent."""
text = _make_skill("file-delivery", related_skills_value="invoice-compare")
links = [{"to": "payment-method", "type": "calls", "reason": "needs payment"}]
result = _apply_links(text, links)
fm_line = next(l for l in result.splitlines() if l.startswith("related_skills:"))
self.assertEqual(fm_line, "related_skills: payment-method",
"existing related_skills value must be replaced, not left stale")


class TestApplyLinksRelatedSkillsTable(unittest.TestCase):
def test_table_row_inserted(self):
Expand Down
20 changes: 13 additions & 7 deletions tools/skill_generator/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,19 @@ def _apply_links(text: str, links: list) -> str:
"""Update frontmatter `related_skills:` and the body Related Skills table."""
targets = [ln["to"] for ln in links]
joined = ", ".join(sorted(set(targets)))
text = re.sub(
r"^related_skills:\s*(?:PLACEHOLDER|none|\[PLACEHOLDER\])\s*$",
f"related_skills: {joined}",
text,
count=1,
flags=re.MULTILINE,
)
# Update the frontmatter field for any existing value — not just placeholder
# sentinels. Prior to this fix, a second link-ingest run (e.g., after a
# Phase 2 update) left the frontmatter stale while rewriting the body table,
# creating a schema inconsistency. Guard against empty joined so a caller
# with no links doesn't blank out an existing value.
if joined:
text = re.sub(
r"^related_skills:\s*.*$",
f"related_skills: {joined}",
text,
count=1,
flags=re.MULTILINE,
)
table_rows = "\n".join(
f"| {ln['to']} | {ln.get('type', 'calls')} | {ln.get('reason', '')} |"
for ln in links
Expand Down