Skip to content

fix(health): a status:'error' seed-meta downgrades a vanished panel from EMPTY/crit to a warn, fleet-wide #6263

Description

@koala73

Surfaced while reviewing the market-implications health fix (#6259). All three are pre-existing and were deliberately left out of that PR's scope.

1. seedError preempts the missing-data verdict fleet-wide

classifyKey in api/health.js orders the fault branches:

else if (synthesisFailure?.warning && hasData) status = 'SEED_ERROR';
else if (seedError) status = 'SEED_ERROR';
else if (!hasData) { ... status = 'EMPTY'; }

#6259 added the && hasData guard to the synthesisFailure arm, because a seed-meta (7-day TTL) routinely outlives its data key, and a warning that means "degraded but still serving" must not outrank "nothing is being served."

The seedError arm immediately below has the same flaw and was left alone because it applies to every key in the fleet. Concretely: a producer that writes status:'error' and then stops leaves a blank panel reporting SEED_ERROR (warn) instead of EMPTY (crit) until the meta expires.

Verified on marketImplications:

meta state data key classification
degraded (post-#6259) absent EMPTY / crit — correct
status:'error' absent SEED_ERROR / warn — wrong
clean success absent EMPTY / crit — correct

The fix is presumably the same one-word guard, but the blast radius is every SEED_META key, so it needs its own sweep of which keys legitimately report status:'error' while their data key is absent.

2. The synthesisFailure contract is undocumented

docs/health-endpoints.mdx documents neither the newsInsights contract (shipped earlier) nor the marketImplications one added in #6259. Consumers of /api/health now receive consecutiveFailures, lastAttemptAt, lastSuccessAt, servedGeneratedAt, synthesisFailureAgeMin, and lastSynthesisFailureCode on those keys with no published contract, and — more consequentially — no documentation that records and status on such a key describe what is served rather than the outcome of the last run.

3. api/seed-health.js has no market-implications entry

It carries 'news:insights' but no intelligence:market-implications, so the sibling endpoint's intervalMin/status view cannot reflect the key at all, let alone the new escalation contract. Pre-dates #6259; worth deciding whether the key belongs there.

Non-issues, recorded so they are not re-litigated

  • writeMarketImplicationsFailureMeta issues two sequential Redis GETs where readInputKeys has a pipeline helper. Measured as immaterial: the branch runs once per invocation, only after the LLM call has already failed, and the payload is a few capped cards. The sibling preserveMarketImplicationsLastGoodOnStarve uses the same sequential idiom, so changing one without the other would create divergence.
  • The per-call RegExp literal fallback in readSeedMeta allocates at most two literals per probe and carries no g/y flag, so there is no lastIndex hazard.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions