-
Notifications
You must be signed in to change notification settings - Fork 3.2k
gbrain doctor --remediation-plan prints contradictory verdict — "Target unreachable" followed by "Brain is at target" #2150
Description
What happened?
On a brain that is below target AND cannot reach target autonomously, gbrain doctor --remediation-plan prints three
lines in sequence, two of which contradict each other:
Brain score: 45/100 → target 90
Target unreachable: max with autonomous remediation is 70/100.
No remediations needed. Brain is at target.
The first two lines are correct (45 current, 70 ceiling, 90 target). The third is wrong: target is 90, brain is 45,
several remediations ARE applicable (they just can't reach the target without manual prereq config). The bad line makes
the operator think the brain is healthy when it is not, and it hides the real next step.
Diagnosis: runRemediationPlan (in src/commands/doctor.ts around line 7600+) prints Target unreachable: max with autonomous remediation is ${plan.max_reachable_score}/100 when plan.target_unreachable is true, then unconditionally
falls through to the empty-plan branch which prints No remediations needed. Brain is at target. The two messages were
never gated against each other.
What did you expect?
When the plan is empty AND the brain is below target, do NOT print the "Brain is at target" line. The unreachable
message above is the user-facing explanation; the Blocked checks block below the plan surfaces the manual gap.
Steps to reproduce (deterministic)
gbrain initagainst a fresh PGLite (or Postgres) engine.gbrain sources add <id> --path <dir-with-markdown> --federated.gbrain sync --source <id>: drivesembed_coverageto 100% but leaveslink_density = 0andtimeline_coverage = 0.gbrain doctor --remediation-plan: prints the three contradictory lines above.
Observed on master at 4ee530f3 (v0.42.42.0), Postgres 16 + pgvector 0.8.2, brain_score reported as 45/100 (per the
formula in postgres-engine.ts:4715: 35 embed + 0 link_density + 0 timeline + 0 no_orphans + 10 no_dead_links).
Environment
- gbrain version: master at
4ee530f3(v0.42.42.0) - OS: Linux
- Bun: 1.3.14
- Database: PGLite + Postgres 16 / pgvector 0.8.2 (both reproduce)
gbrain doctor --json output
Not material to the bug, because the JSON-mode short-circuit in runRemediationPlan returns the plan envelope verbatim
and is unaffected. The bug lives in the human-render branch only.
Adjacent context
This is one of a handful of doctor diagnostics that quietly mislead operators. Others include schema_version reporting
ok when the DB is AHEAD of the client, reranker_health reporting ok while every rerank fails on auth, and
orphan_ratio recommending a fix that backlink counting structurally excludes. Same systemic class; each instance is a
small, scoped fix.
Proposed fix
Gate the "Brain is at target" line on brain_score_current >= targetScore. When the plan is empty AND the brain is
below target, leave the unreachable line as the explanation and let the Blocked checks section below surface the
manual gap.
A small refactor to make the renderer testable in isolation is included in the paired PR:
renderRemediationPlanLines(plan, targetScore): string[] is exported alongside runRemediationPlan. The latter joins
the lines and prints them through console.log, so behavior is byte-identical for every case other than the fixed
contradiction. The renderer extraction makes the regression test pure-functional (no console.log spy needed).
Paired PR ready to open; see feat/doctor-remediation-verdict on
brettdavies/gbrain.