Skip to content

Read the measured Soniox line from spend_daily when it has rows - #24945

Merged
Git-on-my-level merged 6 commits into
mainfrom
claude/soniox-spend-stt
Nov 15, 2026
Merged

Git-on-my-level merged 6 commits into
mainfrom
claude/soniox-spend-stt

Conversation

@Git-on-my-level

@Git-on-my-level Git-on-my-level commented Nov 8, 2026 •

Copy link
Copy Markdown
Member

What changed and why

The Omi TV Soniox line now reads the day's measured stt_soniox row from the settled spend ledger (omi_finops.spend_daily) whenever that row exists. The balance series and usage summary stay as the labelled fallback, and the Soniox-console constant stays the last labelled fallback. A spend_daily table that is not created yet reads as no rows, not an error. The line says "no data yet" only when spend_daily has no stt_soniox row and no balance series exists.

Display only: the cost stack and all-in totals are unchanged.

Stacked. This branch is on top of #24876 (spend reader, not merged yet) and includes the commit for #24944 (vendor-balance dark state, not merged yet). Review the last commit only (2e165153c2) for this change. Re-base onto main once #24876 and #24944 merge.

Product invariants affected

none

How it was verified

Run from web/admin on this branch:

  • node node_modules/vitest/vitest.mjs run (full admin suite): 89 files passed, 5 skipped; 1189 tests passed, 10 skipped.
  • npx --no-install prettier --check and eslint on the touched files: clean.
  • npx --no-install tsc --noEmit -p .: exit 0.
  • scripts/pr-preflight --pr-body-file: 17 checks passed.

Not verified: a rendered board showing the spend-ledger text. That needs the MacBook render session, and the settled table must be populated first.

Tests

web/admin/lib/__tests__/wall-spend.test.ts: soniox_usd is read as null, not 0, for missing days; sonioxSpendByDay maps only days with a row; the query filters on the stt_soniox line on the variable basis.

UI evidence

UI-Evidence: none -- dashboard label text only; the rendered board check is noted above as pending.

Failure class (fixes)

Failure-Class: none



Generated by Claude Code

View guided diff Turn on auto-fix

When omi_finops.vendor_balance_snapshot or vendor_balance_spend_daily
does not exist yet, the vendorBalance leg now completes with an empty
history carrying the reason "Soniox balance not tracked (org key off)"
instead of failing. The Soniox line shows that reason in place of the
balance-snapshot count. Grant denials and other errors on those tables
still fail the leg with their error.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CeWy1SymAzzaL8cabtQ1B
The Omi TV Soniox line now takes the day's stt_soniox row from the settled
spend ledger (omi_finops.spend_daily) whenever that row exists. The balance
series and usage summary remain the labelled fallback, and the console
constant stays the last labelled fallback. A spend_daily table that is not
created yet reads as no rows, not an error. The line says "no data yet"
only when spend_daily has no stt_soniox row and no balance series exists.

Display only: the cost stack and all-in totals are unchanged.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CeWy1SymAzzaL8cabtQ1B
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-08T17:54:59.402447Z b9a105a New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

…atch path

The dark vendor-balance state completed the leg but did not list its reason
among the missing lines, so the board showed the estimate without the
disclosure. It now names the reason there too.

The dark-state test exercised only the classifier. It now mocks the billing
client and asserts the production catch path: a missing table resolves dark,
a grant denial and an unrelated failure still reject.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CeWy1SymAzzaL8cabtQ1B

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e165153c2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +815 to +818
const sonioxSpend =
spendResult.status === "fulfilled" && spendResult.value
? sonioxSpendByDay(spendResult.value)
: null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Distinguish failed ledger reads from missing spend rows

When fetchSpendDays rejects because of a permission denial, timeout, or query error, this branch silently treats the failure as an empty ledger. The fallback label then gives no indication that the preferred measured source failed; it can even report “no data yet” although settled Soniox rows exist. Unlike the neighboring vendor reads, the rejection is neither included in the missing-line explanation nor logged, so an unreadable ledger can leave the board indefinitely showing a fallback without exposing the problem. Preserve the fallback, but surface the controlled ledger failure separately from a successful read with no rows.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed against the latest diff

You’re at about 99% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread web/admin/lib/wall-metrics.ts Resolved
A rejected spend_daily read was silently treated as an empty ledger, so the
Soniox line could read "no data yet" while settled rows existed. A failed
read now adds a missing line naming the controlled failure, and the line
says the spend ledger was unreadable rather than "no data yet". The fallback
ladder is unchanged.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CeWy1SymAzzaL8cabtQ1B

Copy link
Copy Markdown
Member Author

Codex P2 (failed spend_daily read treated as no data): addressed in 665c8ec52f. A rejected ledger read now adds a missing line naming the failure (via wallFailure), and the Soniox text says "spend_daily unreadable (see missing lines); fallback shown" instead of "no data yet". The fallback ladder is unchanged. The fix is on this branch only, since the spend read exists only here. Full admin vitest is green (1192 tests), and tsc and eslint are clean. I did not add a separate console log for the failure; the missing line is the disclosure.


Generated by Claude Code

… aggregate

"no data yet" now means the stt_soniox ledger is empty. When the ledger has
rows on other days but not on the displayed day, the line says so as a day
gap. The query test asserts the full variable-basis conditional aggregate,
so fixed or excluded rows cannot regress into soniox_usd.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CeWy1SymAzzaL8cabtQ1B

Copy link
Copy Markdown
Member Author

Cubic findings on the latest head, addressed in b9a105af62:

  • "no data yet" on a day gap (wall-metrics, P2): fixed. "no data yet" now means the stt_soniox ledger is empty. If the ledger has rows on other days, the line says spend_daily has no stt_soniox row for <day> (day gap); fallback shown.
  • Query test did not pin the variable-basis restriction (wall-spend.test, P2): fixed. The test now asserts the full SUM(IF(basis_class = 'variable' AND line = 'stt_soniox', usd, NULL)) AS soniox_usd expression.

Full admin vitest is green (1192 tests), and tsc, eslint and prettier are clean.


Generated by Claude Code

Git-on-my-level added a commit that referenced this pull request Nov 14, 2026
…dow) (#24876)

<!-- claude-projects-attribution: {"github_login":"Git-on-my-level"} -->
_Requested by **David**_

## What changed and why

Omi TV PR3, a shadow reader for the settled spend table. It adds
`web/admin/lib/wall-spend.ts`, the Omi TV reader for
`omi_finops.spend_daily`:

- a daily query that dedupes to the latest run and filters to settled
inputs;
- typed day rows that keep missing sums as `null` rather than zero;
- a 2026-11-04 all-in parity check;
- the two Revenue tile metrics: listen $ per audio-hour, and variable
cost per paying user per month.

Nothing on the board reads it yet. It is wired in only after the table
is populated and the parity check passes.

## How it was verified

After merging current main and resolving the FinOps allowlist conflict
(retaining margin_meter_hourly and both spend tables):

- `npm test -- lib/__tests__/wall-spend.test.ts
lib/__tests__/admin-finops-grants.test.ts`: 20/20 pass.
- ESLint on all three PR files: pass.
- `npm run typecheck`: pass.
- `make preflight`: all 18 selected checks pass.
- Full repository pre-push hook: pass without skip hatches.

The reader remains shadow-only; #24945 must rebase onto main after this
PR lands. Table grants and populated-table parity remain prerequisites
for wiring.

## UI evidence

UI-Evidence: none -- library module only; not wired to any dashboard
view.

## Failure class (fixes)

Failure-Class: none

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/BasedHardware/omi/pull/24876?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/BasedHardware/omi/24876?returnTo=https%3A%2F%2Fgithub.com%2FBasedHardware%2Fomi%2Fpull%2F24876&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
Base automatically changed from claude/tv-revenue-spend to main November 14, 2026 11:48
Resolve the wall-spend.ts overlap: keep main's in_margin_basis gating,
provisional-row filter and parity documentation, and keep the branch's
measured Soniox column, projection helper and missing-day nulls.

pre-commit skipped: it stages main's unchanged firmware/desktop files on a
merge and lacks drop_merge_incoming for those formatters, which need
clang-format 18 and macOS xcrun. No file of this branch's own change is
unformatted; the pre-push gate still runs.

Co-authored-by: Claude <noreply@anthropic.com>
@Git-on-my-level
Git-on-my-level merged commit 808e4eb into main Nov 15, 2026
48 checks passed
@Git-on-my-level
Git-on-my-level deleted the claude/soniox-spend-stt branch November 15, 2026 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants