Skip to content

Add aim-tracking-freshness skill for oversight INDEX rebuild and staleness detection#146

Open
Hidden-History wants to merge 1 commit into
mainfrom
feature/plan-028-p04c-tracking-freshness
Open

Add aim-tracking-freshness skill for oversight INDEX rebuild and staleness detection#146
Hidden-History wants to merge 1 commit into
mainfrom
feature/plan-028-p04c-tracking-freshness

Conversation

@Hidden-History
Copy link
Copy Markdown
Owner

Summary

Adds the aim-tracking-freshness POV skill (PLAN-028 P0-4(c)) — a read-only staleness reporter and INDEX regenerator for the oversight tracking system.

  • --check mode: scans every oversight/bugs/BUG-*.md and oversight/tech-debt/TECH-DEBT-*.md, classifies each record open/closed from its authoritative **Status** header, and reports divergences against the current INDEX files (BUG-301-class misfilings, orphan INDEX rows, records missing from the INDEX, companion files excluded).
  • --write mode: runs the same analysis, then regenerates both bugs/INDEX.md and tech-debt/INDEX.md from scratch — title, severity, and verbatim status extracted from each file's own header fields.
  • Exits non-zero when any divergence, orphan, or missing record is found, making it suitable for CI/hook invocation.

This closes the P0-4(c) work item in PLAN-028 (memory-system correctness), completing the full P0 baseline-rebuild and drift-prevention track.

Key design decisions

  • Status header authority: the **Status** field in each record file is the single source of truth; INDEX placement is never inferred.
  • Leading-token classification: closed-class tokens (FIXED, RESOLVED, IMPLEMENTED, NOT A BUG, FIX APPLIED, etc.) match only at the operative leading position of the normalized status — never mid-text. This correctly handles statuses like REOPENED … Previously: FIXED … where a historical clause would otherwise trigger a false CLOSED classification.
  • Three Status header formats: colon-outside-bold (**Status**: v), colon-inside-bold (**Status:** v), and table-row (| **Status** | v |) — all confirmed against the live oversight tree.
  • Title extraction: three-level fallback — explicit **Title**: field, H1/H2 heading with ID prefix stripped (handles BUG-NNN:, BUG-NNN —, TECH-DEBT-NNN: separators), then de-slugified filename.
  • Severity normalization: leading [A-Z]+ token extracted after stripping markdown bold; aliases Major→HIGH, Minor→LOW, Blocker→CRITICAL; non-severity values (N/A, Closed) return empty.
  • Companion-file exclusion: among files sharing a numeric ID, the alphabetically-first is the primary record; all others are listed explicitly in the report output.
  • Oversight root: configurable via --oversight-root flag or AI_MEMORY_OVERSIGHT_ROOT env var; defaults to ./oversight relative to CWD. Zero hardcoded absolute paths.

Usage

# Read-only staleness report (no writes):
python ~/.ai-memory/_ai-memory/pov/skills/aim-tracking-freshness/scripts/tracking_freshness.py \
  --check --oversight-root /path/to/oversight

# Regenerate both INDEX.md files + print report:
python ~/.ai-memory/_ai-memory/pov/skills/aim-tracking-freshness/scripts/tracking_freshness.py \
  --write --oversight-root /path/to/oversight

No .claude/skills/ shim is needed — the installer auto-generates POV skill shims at install time.

Files changed

File Change
_ai-memory/pov/skills/aim-tracking-freshness/SKILL.md New — skill descriptor with frontmatter and usage docs
_ai-memory/pov/skills/aim-tracking-freshness/scripts/tracking_freshness.py New — backing script (~430 lines)
tests/unit/test_tracking_freshness_skill.py New — 99 unit tests
CHANGELOG.md Updated — [Unreleased] ### Added entry

Test plan

  • CI lint (black + ruff + isort) passes
  • CI unit tests pass (99 tests across TestStatusClassification, TestCompanionExclusion, TestTitleExtraction, TestSeverityNormalization, TestStatusVerbatim)
  • Key classification cases: REOPENED … Previously: FIXED … → OPEN; FIXED … leading → CLOSED; NOT A BUG leading → CLOSED; LIKELY FIXED → OPEN; IMPLEMENTED (TD) → CLOSED; DEFERRED (TD) → OPEN
  • --check against the live oversight tree: surfaces the known BUG-301 misfiling (REOPENED bug in Closed section of the PM #296 hand-built INDEX) as 1 divergence
  • --write on a copy: regenerates both INDEX files; subsequent --check shows 0 divergences (idempotent)

Introduces the `aim-tracking-freshness` POV skill (PLAN-028 P0-4c) to
replace the manual per-PM rebuild of `oversight/bugs/INDEX.md` and
`oversight/tech-debt/INDEX.md` that caused 80-day tracking drift.

The backing script (`tracking_freshness.py`) scans every
`bugs/BUG-*.md` and `tech-debt/TECH-DEBT-*.md`, classifies each record
as open or closed from its authoritative `**Status**` header, and
either reports staleness divergences (--check, read-only) or
regenerates both INDEX files (--write).

Key design decisions:
- Handles all three Status header formats found in the live tree:
  colon-outside-bold (**Status**: value, most common), colon-inside-bold
  (**Status:** value, 10 files), and table-row format (54 files).
- Separate closed-class token sets for bugs (FIXED, RESOLVED,
  NOT A BUG, DUPLICATE, RECLASSIFIED, FIX APPLIED) and tech-debt
  (IMPLEMENTED, RESOLVED, FIXED).
- LIKELY FIXED edge case explicitly guarded as open.
- Companion files (duplicate numeric ID) excluded from INDEX
  generation and listed explicitly in report output.
- Oversight root configurable via --oversight-root or
  AI_MEMORY_OVERSIGHT_ROOT env var; no hardcoded absolute path.
- Staleness report surfaces divergences prominently (e.g. records
  in the wrong INDEX section), orphan rows, and missing records.
- Exit code 1 when issues found (CI/hook friendly).

Live --check against the full 90-bug / 68-TD oversight tree reports
0 no-status warnings, 0 divergences, 0 orphans, 0 missing.

Includes 68 unit tests covering status classification (both colon
variants + table-row) and companion exclusion. All three lint tools
(black + ruff + isort) pass.
@Hidden-History Hidden-History force-pushed the feature/plan-028-p04c-tracking-freshness branch from 1ff1ff1 to e04a2d1 Compare May 18, 2026 21:06
re.IGNORECASE,
)

_EMOJI_RE = re.compile(r"[\U0001F000-\U0001FFFF☀-➿✂-➰⌀-⏿️]")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants