Skip to content

[Bug] health_file_metrics.analyzed_commit is never populated, so get_health cannot report stale health data (sibling of #1747) #1864

Description

@SimplicityGuy

Summary

Stored code-health rows carry no commit provenance at all, and get_health surrounds them with freshness fields that describe the index rather than the health fold. A consumer therefore sees index_behind: false and indexed_commit: <current HEAD> sitting directly beside health numbers that may have been computed at an arbitrarily older commit, with no field available to tell the difference.

The schema already has the field that would make this detectable — health_file_metrics.analyzed_commit VARCHAR(40) — but it is never populated.

This is the sibling of #1747. There, a provenance SHA exists and goes stale. Here, the provenance SHA exists and is never written, so the staleness is not merely mislabelled — it is unobservable.

Version

  • Repowise 0.44.0 (.repowise/state.jsonwritten_by_version: 0.44.0, store_format_version: 2, health_analyzer_version: 1).
  • Store inspected directly with sqlite3 as well as through the MCP get_health tool; both agree.

Measured evidence

Public repo, 2,376 indexed files, index at a3fd169a.

1. Every health row's provenance column is NULL.

sqlite> SELECT COALESCE(analyzed_commit,'<NULL>') AS c, COUNT(*)
        FROM health_file_metrics GROUP BY c;
<NULL>|2376

The column exists in the schema:

CREATE TABLE health_file_metrics (
        ...
        updated_at DATETIME NOT NULL, "analyzed_commit" VARCHAR(40),
        ...
)

2. get_health's _meta advertises index freshness next to those rows. Verbatim from an MCP get_health response taken against this store:

"_meta": {
  "index_age_days": 0,
  "indexed_commit": "a3fd169a1951",
  "index_behind": false,
  "embedder": "mock",
  "embedder_degraded": false,
  "semantic_search": false,
  "health_analyzed_at": "2026-08-22T08:21:46.227992",
  "timing_ms": 285.3
}

indexed_commit is the repository row's head (repositories.head_commit = a3fd169a… = git rev-parse HEAD), not the commit the health rows describe. health_analyzed_at is a wall-clock timestamp with no commit attached, so it cannot be compared to anything. There is no health_analyzed_commit, and no derived staleness flag.

3. repowise update does not run the health fold. Measured by running repowise update on an unchanged tree and diffing the store: health_file_metrics, health_findings and coverage_files were left byte-identical to the microsecond. Consistent with the documented scope of the command — repowise update --help describes updating wiki pages, re-parsing files, rebuilding the dependency graph and refreshing git/dead-code artifacts, and never mentions health; repowise health is a separate command ("Compute code-health scores from markers"). So the behaviour may well be by design. The bug being reported is not that update skips the fold — it is that nothing anywhere lets a consumer detect that it did.

4. What a correct read looks like, for contrast. repowise health --file <path> recomputes in-process and agreed exactly with the stored rows in this case (score 5.0, CCN 13, NLOC 443, coverage 100/100) — i.e. the store happened to be fresh. That agreement is the only way we could establish freshness, and it requires an extra full recompute per file. There is no cheap signal.

Why this is worth fixing

The numbers are always plausible. A stale health read looks exactly like a real "nothing changed" result, so the failure is silent and self-confirming:

  • Any before/after refactor comparison can report "no movement" when in truth nothing was recomputed.
  • CI gates or dashboards built on get_health will report a frozen snapshot as a current measurement.
  • Agent tooling is especially exposed: guidance around these tools reasonably tells consumers to trust verified: true / index_behind: false and not re-read. An agent following that has no reason to suspect the health figures, and index_age_days: 0 actively reassures it.

We hit this on a code-quality programme whose entire premise was repowise measurements, and caught it only because one task happened to require re-measuring a specific number after a change and asking why it had not moved.

Suggested fix

In rough priority order — (1) alone would be a large improvement:

  1. Populate analyzed_commit on health_file_metrics (and ideally health_findings / health_snapshots) whenever the fold runs, from the same authoritative commit identity #1747 discusses (last_sync_commit or equivalent single source of truth).
  2. Surface it in get_health's _meta as e.g. health_analyzed_commit, alongside a derived boolean such as health_stale / health_behind computed by comparing it to indexed_commit. That gives consumers the cheap staleness signal that does not exist today.
  3. Make the ambiguity impossible to read past. Today index_age_days and index_behind are the most freshness-looking fields in the payload and neither says anything about health. Either rename/scope them, or emit an explicit warning in the response when the health fold predates the indexed commit.
  4. Consider whether repowise update should run the fold (perhaps behind a flag, given the cost), or state plainly in update --help that health scores are not refreshed and repowise health is required. Either resolution is fine; the silent divergence is the problem.

A NULL analyzed_commit should probably be reported as provenance-unknown rather than treated as current — same reasoning as #1747's closing point, that ignoring the field removes the only protection against genuinely stale data.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions