Skip to content

PRD: todo-debt-radar recipe (org-wide TODO debt ranking over Search Jobs API) #4

Description

@jdorfman

Problem Statement

Every large org carries thousands of TODO, FIXME, and HACK comments spread across hundreds of repos. Individually each is noise; collectively they are a debt ledger nobody can read. An engineering leader who asks "how much marked debt do we have, where is it concentrated, who owns it, and which of it sits in code we actually ship" gets shrugs, because interactive search truncates results and no tool correlates the markers with ownership and age at org scale.

Solution

A todo-debt-radar recipe: a CLI that runs one exhaustive Search Job for debt markers across every repository, downloads the complete JSONL result set, enriches each marker with ownership (CODEOWNERS), age (issue references and date strings in the comment text, plus repo-level signals), and path-based risk (production code versus tests/docs/vendored), and produces a ranked radar report: the hottest debt first, sliced by repo, by owner, and by marker type.

User Stories

  1. As an engineering leader, I want a count of all TODO/FIXME/HACK/XXX markers across every repo, so that I can size total marked debt in one number
  2. As an engineering leader, I want debt grouped by repository and ranked by marker density, so that I can see which codebases are debt hotspots
  3. As an engineering leader, I want debt grouped by owning team via CODEOWNERS, so that I can route cleanup work to the teams that own it
  4. As an engineering leader, I want a trend-ready JSONL export, so that I can re-run the radar monthly and chart debt over time
  5. As a tech lead, I want markers in production code paths ranked above markers in tests, docs, and vendored code, so that the report leads with debt that carries runtime risk
  6. As a tech lead, I want HACK and FIXME weighted above TODO, so that admitted hacks surface before routine notes
  7. As a tech lead, I want markers that reference issue trackers (TODO(JIRA-123), TODO: #4567) extracted with their ticket IDs, so that I can check whether the linked work is dead
  8. As a tech lead, I want markers with a named author (TODO(alice)) attributed to that name, so that I can ask the person who left it
  9. As a tech lead, I want the surrounding line of code shown for each top marker, so that I can judge severity without opening the repo
  10. As an individual engineer, I want to filter the radar to my team's CODEOWNERS paths, so that I see only debt I can act on
  11. As an individual engineer, I want direct Sourcegraph links for every reported marker, so that one click takes me to the code
  12. As a platform engineer, I want the exhaustive search to run as a single Search Job with count:all, so that the result set is complete rather than truncated
  13. As a platform engineer, I want CODEOWNERS files collected by a second Search Job rather than by cloning repos, so that the whole radar runs over the API alone
  14. As a platform engineer, I want raw JSONL kept on disk and enrichment run as a separate step, so that I can tweak ranking without re-searching the org
  15. As a developer running the recipe, I want it to work with only SRC_ENDPOINT and SRC_ACCESS_TOKEN set, so that setup matches every other recipe in the cookbook
  16. As a developer running the recipe, I want a --top N flag and sensible default report length, so that the output is a radar, not a landfill
  17. As a viewer of the video, I want a README that stands alone, so that I can run the radar without watching the video
  18. As a skeptical senior engineer, I want the ranking heuristics documented and each score decomposed in the JSONL output, so that I can audit why a marker ranked where it did

Implementation Decisions

  • New recipe directory following the cookbook rule: one directory, standalone README, runnable end to end.
  • TypeScript under bare node with zero dependencies, matching the search-jobs-api recipe; the recipe is about what the Search Jobs API enables, not about a framework.
  • Two Search Jobs total: one regex query for debt markers (TODO, FIXME, HACK, XXX as word-boundary matches in comments) with count:all, and one path query for CODEOWNERS files. Both reuse the create/poll/download flow established by the existing recipes.
  • Pipeline is two explicit phases with an on-disk boundary: collect (run jobs, write raw JSONL) and analyze (read JSONL, write report). Analyze is a pure transformation and can re-run offline.
  • Enrichment extracted per marker: marker type, attributed author from TODO(name) syntax, referenced ticket IDs by common patterns (JIRA-style keys, #123), file path class (production, test, docs, generated, vendored) by path heuristics.
  • Ownership resolved by longest-prefix match of the marker's path against that repo's CODEOWNERS rules; unowned paths reported as their own slice, since unowned debt is a finding in itself.
  • Risk score is a documented, decomposable weighted sum over marker type, path class, and ticket-reference staleness signals; every component appears in the JSONL output. No opaque scoring.
  • Report emitted as markdown to stdout (top N table, per-repo and per-owner roll-ups, unowned-debt section) and full enriched JSONL to a file.
  • Age is approximated from signals inside the result set (dates in comment text, ticket ID eras) rather than per-line git blame; blame across the org would need thousands of API calls and is out of scope for a recipe.

Testing Decisions

  • Tests exercise external behavior only: marker extraction (JSONL line in, enriched marker out), CODEOWNERS matching (rules plus path in, owner out), path classification, score decomposition, and report rendering (enriched fixtures in, markdown out).
  • No test touches the network or needs a token. Fixture JSONL checked into the recipe, following the prior art of the TUI recipe's token-free layout tests and checked-in JSONL files.

Out of Scope

  • Per-line git blame age and churn; approximated by in-comment signals instead.
  • Live ticket-tracker lookups (checking whether JIRA-123 is closed); the report extracts IDs, it does not resolve them.
  • Automated cleanup (opening PRs to delete stale TODOs).
  • Dashboards or persistent storage; the monthly JSONL export is the trend interface.
  • Language-aware comment parsing; regex over indexed text is the point of the demo.

Further Notes

Recipe in the Search Jobs API video series. Demo arc for the video: one query, count:all, watch the job chew through the whole org, then the reveal — a ranked table showing one team owning a third of all HACK markers in production paths. The count:all completeness is the differentiator over interactive search and should carry the narrative.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentPRD ready for agent implementation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions