koala73 / koala73/worldmonitor

obs(military): OpenSky tier health is invisible — seed-meta reports 'wingbits' while OpenSky is billed

Open
#6,246 2 comments 0 reactions 0 assignees View on GitHub
area: infrastructure area: military bug P2
Dominant language
TypeScript
Stars
86.6k
Forks
13.1k
Avg merge
8h 4m
Merged PRs (30d)
825

Description

## Summary

#6222 halved the OpenSky credit burn but did not fix **why nobody noticed the burn for so
long**: the tier's health is invisible in every surface that has a consumer.

`source` is set to `wingbits` whenever Wingbits returns anything, and the OpenSky path only
overwrites it when it is still `none`:

```js
// scripts/seed-military-flights.mjs — fetchOpenSkyGlobal
if (source.value === 'none') source.value = 'opensky-auth';
```

```js
// scripts/seed-military-flights.mjs — publish
await writeFreshnessMetadata('military', 'flights', flights.length, source);
```

So `seed-meta:military-flights` reports `sourceVersion: "wingbits"` on every healthy run while
OpenSky is being billed 4 credits — which is exactly the symptom
[the diagnosis doc](https://github.com/koala73/worldmonitor/blob/main/docs/solutions/integration-issues/opensky-bbox-area-billing-flat-top-tier.md)
names as root cause: *"the quota burn is silent."*

The only OpenSky signal the seeder emits is `fetchSources.regions[0].authStatus`, written to
`military:classification-audit:v1`. Grepping the repo for `classification-audit`,
`classificationAudit`, `fetchSources`, `unknownTypeRate`, and `rejectedFlights` outside
`seed-military-flights.mjs` returns **zero consumers**.

## Why it matters

If the account exhausts again, `authStatus` becomes `error:HTTP 429` in a key nobody reads,
`source` stays `wingbits`, freshness stays green, and the tier dies exactly as silently as
before. The difference after #6222 is only that tests now assert OpenSky is *called* — nothing
asserts it *contributes*.

The seeder already logs the number that answers this:

```js
if (added > 0) console.log(` [OpenSky] +${added} new from GLOBAL (total: ${allStates.length})`);
```

`+N new` is the tier's marginal value — aircraft Wingbits never saw. It reaches stdout and
stops there.

## Proposed work

Pick one; the first is smallest.

1. Make `source` compound — `wingbits+opensky` vs `wingbits` — so `seed-meta` distinguishes
*contributed* from *dead*. Note `normalizeSourceFamily` in `scripts/_military-surges.mjs`
buckets anything starting with `opensky`, so check the surge-baseline interaction before
changing the token shape.
2. Emit `fetchSources.openSkyAuthSuccess` and `regions[].statesAdded` to Axiom, and alarm on N
consecutive runs with `statesAdded === 0` while OAuth is configured.

## Acceptance criteria

- [ ] A run where OpenSky returned nothing is distinguishable from one where it contributed,
from a surface something actually reads.
- [ ] Sustained OpenSky failure raises an alarm rather than resolving to green freshness.

## Related

- #6222 / #6244 — reduced the spend; this closes the silence that hid it.
- #6241 — the seeder also ignores `429`/`Retry-After`.

Contributor guide

Open the contributing guide

Research direction

Start in scripts/seed-military-flights.mjs, tracing fetchOpenSkyGlobal, publish, and the existing fetchSources metadata. Read normalizeSourceFamily in scripts/_military-surges.mjs before choosing a source representation, then inspect the documented consumers of seed-meta and classification-audit. Done means OpenSky contribution or failure is visible to a consuming surface and sustained failure can raise the specified alarm.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
backend, observability-sre
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.