firebase deploy --only firestore:indexes on 2026-08-23 reported four composite indexes that exist in the live c2-server database but are absent from infra/firestore/firestore.indexes.json, and offered to delete them (declined — they back live queries):
The file is therefore not a description of the database. Two consequences:
1. Duplicated indexes. The file declares calls (org_id ASC, started_at ASC) while the live database already had calls (org_id ASC, started_at DESC). Both now exist. Firestore reverse-scans an index, so the DESC one already served orderBy("started_at","desc") — and every query in lib/useCalls.ts and lib/useIncidents.ts is desc. The ASC copy is redundant storage plus extra write amplification on every call document, forever. Same story for alert_events.
2. Nothing checks the drift. Deploying is a manual step run by hand from WSL (server-26#13), so the file is only compared against reality when someone happens to run it. That is how it got four indexes behind without anyone noticing.
Worth doing:
Reconcile the file against gcloud firestore indexes composite list --database=c2-server --project=discord-radio-bot-461301 — adopt the live DESC variants, drop the ASC duplicates, and add the two calls indexes that are plainly in use (system_id+ended_at, status+ended_at, most likely the node sweeper and stale-call paths in c2-core).
Delete the redundant ASC copies once nothing references them.
Longer term, whatever automates server-26#13 should fail loudly on drift instead of prompting interactively.
Note for anyone running the deploy: infra/firestore/firebase.json now pins "database": "c2-server". Without that key the CLI targets (default), reports success, and changes nothing the app can see.
`firebase deploy --only firestore:indexes` on 2026-08-23 reported four composite indexes that exist in the live `c2-server` database but are absent from `infra/firestore/firestore.indexes.json`, and offered to delete them (declined — they back live queries):
```
(calls) system_id ASC, ended_at ASC
(calls) status ASC, ended_at ASC
(calls) org_id ASC, started_at DESC
(alert_events) acknowledged ASC, triggered_at DESC
```
The file is therefore not a description of the database. Two consequences:
**1. Duplicated indexes.** The file declares `calls (org_id ASC, started_at ASC)` while the live database already had `calls (org_id ASC, started_at DESC)`. Both now exist. Firestore reverse-scans an index, so the DESC one already served `orderBy("started_at","desc")` — and every query in `lib/useCalls.ts` and `lib/useIncidents.ts` is `desc`. The ASC copy is redundant storage plus extra write amplification on every call document, forever. Same story for `alert_events`.
**2. Nothing checks the drift.** Deploying is a manual step run by hand from WSL (server-26#13), so the file is only compared against reality when someone happens to run it. That is how it got four indexes behind without anyone noticing.
Worth doing:
- Reconcile the file against `gcloud firestore indexes composite list --database=c2-server --project=discord-radio-bot-461301` — adopt the live DESC variants, drop the ASC duplicates, and add the two `calls` indexes that are plainly in use (`system_id+ended_at`, `status+ended_at`, most likely the node sweeper and stale-call paths in c2-core).
- Delete the redundant ASC copies once nothing references them.
- Longer term, whatever automates server-26#13 should fail loudly on drift instead of prompting interactively.
Note for anyone running the deploy: `infra/firestore/firebase.json` now pins `"database": "c2-server"`. Without that key the CLI targets `(default)`, reports success, and changes nothing the app can see.
Referenced by board minutes #42 (2026-08-23) - folded into Gate B condition B1 alongside #13.
The CISO (#39) drew the conclusion this issue implies but does not state: indexes and rules were deployed separately and inconsistently - indexes got partial attention on 2026-08-23, rules did not. That makes the deploy process itself manual, unaudited and silently drifting, which is exactly this issue's own point ("nothing checks the drift").
Gate B1 requires both halves reconciled, with the deployed ruleset ID recorded in #13, before anyone is charged.
**Referenced by board minutes #42 (2026-08-23) - folded into Gate B condition B1 alongside #13.**
The CISO (#39) drew the conclusion this issue implies but does not state: indexes and rules were deployed **separately and inconsistently** - indexes got partial attention on 2026-08-23, rules did not. That makes the deploy process itself manual, unaudited and silently drifting, which is exactly this issue's own point ("nothing checks the drift").
Gate B1 requires both halves reconciled, with the deployed ruleset ID recorded in #13, before anyone is charged.
Duplicate half is fixed; the drift half is not verifiable from the authoring machine.
Commit 7ef5704 (2026-08-23, "Make firestore.indexes.json describe the database again") is a confirmed ancestor of the live SHA a1bdccf.
Checked this morning: infra/firestore/firestore.indexes.json declares 7 indexes with zero duplicates, key-counted on (collectionGroup, ordered field tuple). The duplication this issue reports is gone.
What is not confirmed: that the file now matches the live Firestore database. That needs cloud-console or gcloud access this machine does not have. And there is still no automated deploy path for index or rule changes — that is #51, and it is the reason this class of drift recurs rather than staying fixed.
Leaving this open pending a live-database confirmation. If #51 lands, this closes with it rather than by inspection.
Ref 7ef5704. Found by the 2026-08-25 unattended session while auditing tracker-vs-repo drift.
(An earlier version of this comment was posted with its formatting mangled by a shell-quoting fault in the session tooling. This is the corrected text.)
**Duplicate half is fixed; the drift half is not verifiable from the authoring machine.**
Commit **`7ef5704`** (2026-08-23, "Make firestore.indexes.json describe the database again") is a confirmed ancestor of the live SHA `a1bdccf`.
Checked this morning: `infra/firestore/firestore.indexes.json` declares **7 indexes with zero duplicates**, key-counted on `(collectionGroup, ordered field tuple)`. The duplication this issue reports is gone.
What is **not** confirmed: that the file now matches the live Firestore database. That needs cloud-console or `gcloud` access this machine does not have. And there is still no automated deploy path for index or rule changes — that is **#51**, and it is the reason this class of drift recurs rather than staying fixed.
Leaving this open pending a live-database confirmation. If #51 lands, this closes with it rather than by inspection.
Ref `7ef5704`. Found by the 2026-08-25 unattended session while auditing tracker-vs-repo drift.
*(An earlier version of this comment was posted with its formatting mangled by a shell-quoting fault in the session tooling. This is the corrected text.)*
Live audit 2026-09-07 ~19:35 — Archive (/calls) is down with a 503, likely a missing/absent composite index on live c2-server.
GET https://api.drb.cusano.net/calls/search?limit=50&link=any&transcript=any:
no auth -> clean 401 in ~90ms (route is up, fails past auth)
valid owner token -> 503, server: uvicorn, browser surfaces it as TypeError: Failed to fetch (503 error responses skip CORSMiddleware so they carry no ACAO)
search_calls (routers/calls.py:44) runs exactly one Firestore composite query: calls where(org_id ==) order_by(started_at DESCENDING), everything else is Python-side. The //drift-2026-08-23 note in firestore.indexes.json claims a live calls(org_id ASC, started_at DESC) exists — the 503 suggests it does not, or the whole index set on live has drifted again.
Need docker compose ... logs c2-core --tail=200 from the VM to confirm it is FAILED_PRECONDITION. If so, the firebase deploy --only firestore:indexes from #51 fixes both this and /watch in one shot.
**Live audit 2026-09-07 ~19:35 — Archive (/calls) is down with a 503, likely a missing/absent composite index on live `c2-server`.**
`GET https://api.drb.cusano.net/calls/search?limit=50&link=any&transcript=any`:
- no auth -> clean 401 in ~90ms (route is up, fails past auth)
- valid owner token -> **503**, `server: uvicorn`, browser surfaces it as `TypeError: Failed to fetch` (503 error responses skip CORSMiddleware so they carry no ACAO)
`search_calls` (routers/calls.py:44) runs exactly one Firestore composite query: `calls where(org_id ==) order_by(started_at DESCENDING)`, everything else is Python-side. The `//drift-2026-08-23` note in `firestore.indexes.json` claims a live `calls(org_id ASC, started_at DESC)` exists — the 503 suggests it does not, or the whole index set on live has drifted again.
**Need `docker compose ... logs c2-core --tail=200` from the VM to confirm it is `FAILED_PRECONDITION`.** If so, the `firebase deploy --only firestore:indexes` from #51 fixes both this and /watch in one shot.
Resolved by PR #124 + the gcloud index creates on 2026-09-08. The ASC-only firestore.indexes.json was the root of the drift: it declared ASC indexes for the frontend/backend orderBy(desc) queries and Firestore refused to reverse-scan them. File now declares the DESC forms matching live; the CI step keeps them in sync. The old //drift-2026-08-23 note that told a deployer to delete calls/incidents (org_id, started_at DESC) as 'duplicates' is removed — those are the working indexes.
Resolved by PR #124 + the gcloud index creates on 2026-09-08. The ASC-only `firestore.indexes.json` was the root of the drift: it declared ASC indexes for the frontend/backend `orderBy(desc)` queries and Firestore refused to reverse-scan them. File now declares the DESC forms matching live; the CI step keeps them in sync. The old `//drift-2026-08-23` note that told a deployer to delete `calls/incidents (org_id, started_at DESC)` as 'duplicates' is removed — those are the working indexes.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
firebase deploy --only firestore:indexeson 2026-08-23 reported four composite indexes that exist in the livec2-serverdatabase but are absent frominfra/firestore/firestore.indexes.json, and offered to delete them (declined — they back live queries):The file is therefore not a description of the database. Two consequences:
1. Duplicated indexes. The file declares
calls (org_id ASC, started_at ASC)while the live database already hadcalls (org_id ASC, started_at DESC). Both now exist. Firestore reverse-scans an index, so the DESC one already servedorderBy("started_at","desc")— and every query inlib/useCalls.tsandlib/useIncidents.tsisdesc. The ASC copy is redundant storage plus extra write amplification on every call document, forever. Same story foralert_events.2. Nothing checks the drift. Deploying is a manual step run by hand from WSL (server-26#13), so the file is only compared against reality when someone happens to run it. That is how it got four indexes behind without anyone noticing.
Worth doing:
gcloud firestore indexes composite list --database=c2-server --project=discord-radio-bot-461301— adopt the live DESC variants, drop the ASC duplicates, and add the twocallsindexes that are plainly in use (system_id+ended_at,status+ended_at, most likely the node sweeper and stale-call paths in c2-core).Note for anyone running the deploy:
infra/firestore/firebase.jsonnow pins"database": "c2-server". Without that key the CLI targets(default), reports success, and changes nothing the app can see.Referenced by board minutes #42 (2026-08-23) - folded into Gate B condition B1 alongside #13.
The CISO (#39) drew the conclusion this issue implies but does not state: indexes and rules were deployed separately and inconsistently - indexes got partial attention on 2026-08-23, rules did not. That makes the deploy process itself manual, unaudited and silently drifting, which is exactly this issue's own point ("nothing checks the drift").
Gate B1 requires both halves reconciled, with the deployed ruleset ID recorded in #13, before anyone is charged.
Duplicate half is fixed; the drift half is not verifiable from the authoring machine.
Commit
7ef5704(2026-08-23, "Make firestore.indexes.json describe the database again") is a confirmed ancestor of the live SHAa1bdccf.Checked this morning:
infra/firestore/firestore.indexes.jsondeclares 7 indexes with zero duplicates, key-counted on(collectionGroup, ordered field tuple). The duplication this issue reports is gone.What is not confirmed: that the file now matches the live Firestore database. That needs cloud-console or
gcloudaccess this machine does not have. And there is still no automated deploy path for index or rule changes — that is #51, and it is the reason this class of drift recurs rather than staying fixed.Leaving this open pending a live-database confirmation. If #51 lands, this closes with it rather than by inspection.
Ref
7ef5704. Found by the 2026-08-25 unattended session while auditing tracker-vs-repo drift.(An earlier version of this comment was posted with its formatting mangled by a shell-quoting fault in the session tooling. This is the corrected text.)
Live audit 2026-09-07 ~19:35 — Archive (/calls) is down with a 503, likely a missing/absent composite index on live
c2-server.GET https://api.drb.cusano.net/calls/search?limit=50&link=any&transcript=any:server: uvicorn, browser surfaces it asTypeError: Failed to fetch(503 error responses skip CORSMiddleware so they carry no ACAO)search_calls(routers/calls.py:44) runs exactly one Firestore composite query:calls where(org_id ==) order_by(started_at DESCENDING), everything else is Python-side. The//drift-2026-08-23note infirestore.indexes.jsonclaims a livecalls(org_id ASC, started_at DESC)exists — the 503 suggests it does not, or the whole index set on live has drifted again.Need
docker compose ... logs c2-core --tail=200from the VM to confirm it isFAILED_PRECONDITION. If so, thefirebase deploy --only firestore:indexesfrom #51 fixes both this and /watch in one shot.Resolved by PR #124 + the gcloud index creates on 2026-09-08. The ASC-only
firestore.indexes.jsonwas the root of the drift: it declared ASC indexes for the frontend/backendorderBy(desc)queries and Firestore refused to reverse-scan them. File now declares the DESC forms matching live; the CI step keeps them in sync. The old//drift-2026-08-23note that told a deployer to deletecalls/incidents (org_id, started_at DESC)as 'duplicates' is removed — those are the working indexes.