feat(kaizen): parse tag/first_seen/age per signal

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
sjat 2026-06-14 21:17:03 +02:00
parent 859732b04d
commit 72b9262f34
2 changed files with 46 additions and 0 deletions

View file

@ -16,6 +16,9 @@ import re
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
FRICTION = os.path.join(REPO_ROOT, "docs", "FRICTION.md")
TAG_RE = re.compile(r"`\[(friction|gotcha|recurring|unused)\]`")
DATE_RE = re.compile(r"(\d{4})-(\d{2})-(\d{2})")
def extract_open_section(text):
"""Return the body between '## Open signals' and the next '## ' heading."""
@ -59,5 +62,27 @@ def split_signals(section):
return [s for s in signals if s]
def parse_signal(raw, today):
"""Turn one raw signal block into a structured dict."""
tag_m = TAG_RE.search(raw)
date_m = DATE_RE.search(raw)
if date_m:
first_seen = date_m.group(0)
seen = datetime.date(int(date_m.group(1)), int(date_m.group(2)), int(date_m.group(3)))
age_days = (today - seen).days
else:
first_seen = None
age_days = None
return {
"tag": tag_m.group(1) if tag_m else None,
"first_seen": first_seen,
"age_days": age_days,
"recurrence_count": 1, # refined in Task 3
"referenced_paths": [], # filled in Task 3
"still_exists": True, # filled in Task 3
"text": " ".join(raw.split()),
}
if __name__ == "__main__": # pragma: no cover (filled in Task 4)
pass

View file

@ -38,3 +38,24 @@ def test_split_signals_finds_two_items_and_joins_continuations():
assert len(signals) == 2
assert "continuation line two" in signals[0]
assert signals[1].startswith("`[friction]`")
import datetime
TODAY = datetime.date(2026, 6, 15)
def test_parse_signal_extracts_tag_and_date_and_age():
raw = fs.split_signals(fs.extract_open_section(SAMPLE))[0]
sig = fs.parse_signal(raw, TODAY)
assert sig["tag"] == "gotcha"
assert sig["first_seen"] == "2026-06-01"
assert sig["age_days"] == 14
assert "First thing" in sig["text"]
def test_parse_signal_handles_missing_date():
sig = fs.parse_signal("`[unused]` **No date here** something", TODAY)
assert sig["tag"] == "unused"
assert sig["first_seen"] is None
assert sig["age_days"] is None