Skip to content

feat(OMN-19978): usage-by-model-day projection gives tokens and cost per model per UTC day - #3073

Merged
jonahgabriel merged 13 commits into
devfrom
jonah/omn-19978-usage-by-model-day
Sep 30, 2026
Merged

jonahgabriel merged 13 commits into
devfrom
jonah/omn-19978-usage-by-model-day

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

What

New node node_projection_usage_by_model_day (OMN-19978, plan task T3.6): tokens in, tokens out, cost and call count per (tenant, UTC day, model id), from onex.evt.omniintelligence.llm-call-completed.v1. Bus-backed exposure onex.snapshot.projection.usage-by-model-day.v1 (cursor projection_cursor, key columns tenant_id, usage_day, model_id).

  • Pure definition-B fold HandlerProjectionUsageByModelDay: UTC day derived from the event timestamp, never the clock; a missing timestamp is refused (poison to DLQ). Missing tenant falls to the house tenant.
  • Store-neutral apply_usage_call(delta, db) over upsert/query only: ledger row keyed on call id, then RECOUNT of the key (never increment), so a replay writes nothing. Runs on the real SQLite adapter (DDL added beside the others in sqlite_database.py).
  • Effect writer UsageByModelDayProjectionWriter (in-process dispatch, only the writer is routed): one transaction, advisory lock on the key, insert-if-new, recount, snapshot delta.
  • Tenant domain, not internal: both tables carry tenant_id, so they live in public with row-level security (0001), like node_projection_cost_summary.

Reuse

node_projection_cost_summary does NOT carry this grain (its key is a 24h/7d/30d window enum with no model or day), so it is not reusable here. Reused: the node_projection_topic_activity bus-backed contract and writer shape, SqliteDatabaseAdapter, HOUSE_TENANT_SLUG, cost_summary's RLS migration shape.

Evidence (dod_evidence)

  • AC1: uv run pytest tests/test_omn19978_usage_by_model_day.py -- ten calls, two days, two models give four rows; token, cost and call-count sums equal the call rows'; replay changes nothing (19 passed with the writer tests).
  • Lab readback (real Postgres, dev-lane database on the .201 lab host, throwaway schema): tests/test_omn19978_usage_by_model_day_real_postgres.py ran the writer's own insert and recount statements for the same ten calls: 1 passed; four rows, sums equal, replay left rows and cursors unchanged.
  • Ratchets moved with the node: relation inventory (+2 tables), exposure and cursor counts, node and entry-point counts, golden chain.

Not proven here (stated plainly)

  • AC2 (the rendered Usage page equals the sum of the day's call rows) is NOT proven: no runtime deploy, snapshot-topic read or page render was done in this lane. It needs the deployed writer plus the page reader; follow-up on the ticket.
  • The SQLite exposure read side is the mode 1 reader (T2.3), not this PR. The SQLite tables carry no projection_cursor.
  • omnibase_infra vendoring of the new migrations (vendor-parity gate) is a companion step if the gate demands it.
  • Depends on OMN-19968 (writer store parity) only in spirit: this node has its own store-neutral path and does not touch its files except sqlite_database.py DDL (adjacent hunk, may need a trivial rebase).

Delegation

Codex drafted the node from the RED test; the lab (onex delegate --task-type code_review, Qwen3.8-27B, whole files) reviewed it: three findings, all discarded with reasons (single-process local path, sequential by design; the Postgres path holds the advisory lock; a primary key column is already NOT NULL).

Evidence-Ticket: OMN-19978
Evidence-Source: OCC#11871

…tokens out and cost per model per UTC day

Onex-Lane: mvp-omn-19978-0035
Onex-Session: b78fc6159e6e4a648f308f40a1486942
@github-actions

Copy link
Copy Markdown

⚠️ Architectural Review — WARNINGS

Errors: 0
Warnings: 1

What this checks

Rule Description
ARCH-TOPIC-001 No hardcoded Kafka topic strings in handler code
ARCH-DI-001 No event_bus=None bypass
ARCH-DI-002 No direct Handler instantiation outside workflow_runner/adapters
ARCH-DI-003 No reinvented DI containers
ARCH-TOPIC-002 contract.yaml topics follow `onex.{cmd

ARCH-DI-002: Direct Handler instantiation (warning)\n\n\nsrc/omnimarket/nodes/node_projection_usage_by_model_day/handlers/handler_usage_by_model_day_writer.py:86: self._derive = HandlerProjectionUsageByModelDay()\n\n\nHandler classes should be wired only in workflow_runner.py or adapter modules. Direct instantiation elsewhere bypasses the contract system.\n\n

Static architectural lint — no model inference (OMN-14176).

onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…9432, OMN-19454, OMN-19513, OMN-19566, OMN-19790, OMN-19792, OMN-19813, OMN-19937, OMN-19966, OMN-19968, OMN-19995, OMN-19999, OMN-20010, OMN-20038): author OCC companion for OmniNode-ai/omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head c78564ea41d5134c6611891d854cfae0d9d8e69f.
onexbot-occ-writer Bot added a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…nimarket#3073

The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited.

Ticket: OMN-16859 (AC3b)
Onex-Workflow: OCC Receipt Runner
Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36513952606
@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 29, 2026 02:45
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

✅ Hostile Reviewer — PASSED

Blocking findings (critical/error): 0
Total findings: 18
Models succeeded: qwen3-review,gpt-oss-review


Gate semantics

Verdict Meaning Blocks merge?
passed >=2 models succeeded, no critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded Fewer than 2 models succeeded (infra unavailable/timeout) Yes (OMN-15110)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)

Comment thread tests/test_omn19978_usage_by_model_day_real_postgres.py
…ble and joins the pinned in-process writer set

Onex-Lane: mvp-omn-19978-0035
Onex-Session: b78fc6159e6e4a648f308f40a1486942
…entry-point counts become 441 and 431, relation inventory regenerated

Onex-Lane: mvp-omn-19978-0035
Onex-Session: b78fc6159e6e4a648f308f40a1486942
…counts 444 and 433, census 81, 90 and 5, inventory regenerated

Onex-Lane: mvp-omn-19978-0035
Onex-Session: b78fc6159e6e4a648f308f40a1486942
jonahgabriel and others added 2 commits September 29, 2026 11:32
…d counts 445 and 434, census 82, 92 and 4, inventory regenerated

Onex-Lane: mvp-omn-19978-0035
Onex-Session: 9f94733ba0e749e5b49d90ba2398ba6e
…sage tables converge a drifted shape and the role DDL names its provisioning seam

The role DO block had no insufficient_privilege handler and the guarded CREATE TABLE IF NOT EXISTS left columns nullable on a drifted table. The reconciliation now ends in a NOT NULL convergence that refuses to invent values, plus the CHECK and primary-key constraints a fresh apply creates. Verified on a throwaway postgres:16-alpine on the lab: fresh and drifted schemas identical, a second apply is a no-op, NULL rows are refused, and a non-CREATEROLE identity gets the named remediation. Pinned counts re-derived from the measured report: 445, 434, census 82, 92, 4.
@onexbot-occ-writer

Copy link
Copy Markdown
Contributor

OCC autobind rebound this PR's evidence-source stamp line to OCC#11779.

The receipt gate's own eligibility validator, run against the change-control tree the gate pins for OCC#11779, returned eligible for head 179e4a36d25796e29b77c149b1ce70139ab1756a. The body now carries exactly one stamp line. Displaced: OCC#11772.

Reported by occ_companion_emitter (OMN-18853).

…by_model_day migration and merge dev; pinned counts 446 and 434

Onex-Lane: qfix-takeover-1715
Onex-Session: 5815e546f13d4e72a59526fc95d30a7a
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head fff6c231c3ae20ca517c8081abbb777e66a64ee8.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head fff6c231c3ae20ca517c8081abbb777e66a64ee8.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head fff6c231c3ae20ca517c8081abbb777e66a64ee8.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head fff6c231c3ae20ca517c8081abbb777e66a64ee8.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head fff6c231c3ae20ca517c8081abbb777e66a64ee8.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 29, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head fff6c231c3ae20ca517c8081abbb777e66a64ee8.
@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 30, 2026 00:34
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head b4494bdc9a21d0caa18157bb7aa6d50ba1cd3558.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head b4494bdc9a21d0caa18157bb7aa6d50ba1cd3558.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head b4494bdc9a21d0caa18157bb7aa6d50ba1cd3558.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head b4494bdc9a21d0caa18157bb7aa6d50ba1cd3558.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head b4494bdc9a21d0caa18157bb7aa6d50ba1cd3558.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head b4494bdc9a21d0caa18157bb7aa6d50ba1cd3558.
…tatically and the board probe cursor keeps its owner declaration

The application SQL gate rejects any DO block that contains dynamic SQL, so the two NOT NULL
convergence loops become static ALTER COLUMN SET NOT NULL statements, and the merge of dev had
split the board_probe_results cursor sequence entry from its owner_declaration and writers,
which failed manifest validation.

Onex-Lane: qfix-takeover-1715
Onex-Session: 0b78e1ee32804fbebb702790c3102c3e
onexbot-occ-writer Bot added a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…nimarket#3073

The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited.

Ticket: OMN-16859 (AC3b)
Onex-Workflow: OCC Receipt Runner
Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36656765154
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…mniNode-ai/omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 4916db65ed37ce9cdd9467c102c667fa34544616.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…mniNode-ai/omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 4916db65ed37ce9cdd9467c102c667fa34544616.
…, keep both writer declarations, recount the relation inventory (84 created, bound 2)
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head e8e6ad3b31c97912e3dbbd985b3e971b44569aa4.
onexbot-occ-writer Bot added a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…nimarket#3073

The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited.

Ticket: OMN-16859 (AC3b)
Onex-Workflow: OCC Receipt Runner
Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36665567122
…_day tables together (85 created, 94 declared, 1 unreconciled)
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…anion for OmniNode-ai/omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 8c25ea340d95e4264c1409877feda21141a1f1c7.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…anion for OmniNode-ai/omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 8c25ea340d95e4264c1409877feda21141a1f1c7.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 30, 2026
…anion for OmniNode-ai/omnimarket#3073

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 8c25ea340d95e4264c1409877feda21141a1f1c7.
@jonahgabriel
jonahgabriel merged commit 02acdb3 into dev Sep 30, 2026
253 of 265 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-19978-usage-by-model-day branch September 30, 2026 09:33
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.

3 participants