Repository navigation
feat(OMN-20738): a typed read node for the database work ledger - #3630
Merged
Merged
Conversation
added 2 commits
October 9, 2026 04:27
Adds node_work_ledger_query_effect with contract.yaml defining onex.cmd.omnimarket.work-ledger-query-requested.v1 and onex.evt.omnimarket.work-ledger-query-completed.v1. HandlerWorkLedgerQuery implements handle(request: ModelWorkLedgerQueryRequest) -> ModelWorkLedgerQueryResult; a read-only lazy Postgres reader reads omninode_internal.work_ledger_rows. Shared models reside in omnimarket.models.work_ledger_query. Queries cover rows by window, kind, lane, ticket, PR, row id or term, open claims, holds in force, a lane's inbox, newest row per lane, rulings and consents. The handler replays raw_row with the markdown ledger read verbs' own rules (query, holds, inbox, open-claims), so a reader's shadow comparison differs only where the two stores hold different rows. Every answer carries freshness (newest row_ts, newest projected_at, rows read) and the window's parity status from the daily parity receipts (exact, not-exact, unmeasured). A database error is returned in the error field with no answer sections and no freshness. Golden-chain test includes 21 recorded verb calls over a synthetic fixture ledger, plus parity, freshness, error and typed-dispatch cases; 29 tests.
The reader raises WorkLedgerReadError with its message already redacted and type-prefixed; the handler reports that message as is and type-prefixes only other exceptions. Found on the lab, where an unset DSN read "RuntimeError: RuntimeError: ...". A regression test covers it.
|
| 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_architecture_discovery_orchestrator/handlers/handler_architecture_discovery.py:109: execute = HandlerCodingAgentBus().execute\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).
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
|
|
||
| def read_rows( | ||
| self, *, since: datetime | None, until: datetime | ||
| ) -> tuple[ModelWorkLedgerRowRecord, ...]: ... |
| ) -> tuple[ModelWorkLedgerRowRecord, ...]: ... | ||
| def read_parity_receipts( | ||
| self, *, since: datetime, until: datetime | ||
| ) -> tuple[ModelWorkLedgerRowRecord, ...]: ... |
| ) -> tuple[ModelWorkLedgerRowRecord, ...]: ... | ||
| def freshness( | ||
| self, *, until: datetime | ||
| ) -> tuple[datetime | None, datetime | None]: ... |
jonahgabriel
enabled auto-merge (squash)
October 9, 2026 08:49
Adds contracts/OMN-20738.yaml, the DoD contract for ticket OMN-20738 (node_work_ledger_query_effect), with four acceptance criteria bound to selectors over tests/test_golden_chain_work_ledger_query.py (30 tests pass on h201). Fixes repo-evidence / dod-verify, which failed because the PR cited OMN-20738 but carried no contracts/OMN-20738.yaml.
Added node_work_ledger_query_effect to LANE_SCOPED_MAIN_OWNED_NODES to satisfy runtime profile contracts. Regenerated docs/evidence/OMN-15423-relation-inventory.json using scripts/generate_application_relation_inventory.py. This updates the inventory to reflect node_work_ledger_query_effect as a reader of omninode_internal.work_ledger_rows.
The four queries in work_ledger_query_reader.py previously interpolated the relation name into SQL using f-strings. This change replaces that with a quoted psycopg2 sql.Identifier to prevent SQL injection. The regex validation on the relation field remains in place. Verified against Postgres 16 that rows and receipts read back correctly and missing relations return a typed error.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ticket OMN-20738 adds a typed read node for the database work ledger.
The node is
node_work_ledger_query_effect.It uses
contract.yamlwith command topiconex.cmd.omnimarket.work-ledger-query-requested.v1and terminal topiconex.evt.omnimarket.work-ledger-query-completed.v1.HandlerWorkLedgerQueryhashandle(request: ModelWorkLedgerQueryRequest) -> ModelWorkLedgerQueryResult.A read-only lazy Postgres reader reads
omninode_internal.work_ledger_rows.The DSN env is
OMNINODE_INTERNAL_DB_URL, declared in the contract.Shared request and answer models are in
omnimarket.models.work_ledger_query.What it answers
Queries cover rows by window, kind, lane, ticket, PR, row id or term.
Every row in an answer carries its full text and its first line.
Queries cover open claims.
Queries cover holds in force with checked, released, expired and legacy counts.
Queries cover a lane's inbox (MSG without ACK, HOLD without RELEASE).
Queries cover newest row per lane.
Queries cover rulings and consents.
Every answer carries freshness (newest row_ts, newest projected_at, rows read).
Every answer carries the window's parity status (exact, not-exact or unmeasured) from the newest daily parity receipt (STATUS lane=work-ledger-parity) of each UTC day in the window.
A database error is returned in the error field.
A database error has no answer sections and no freshness.
A caller cannot read a failed read as no rows.
Why it replays raw rows
The node replays
raw_rowwith the markdown ledger read verbs' own rules.These rules are query, holds, inbox, open-claims.
The node does not read
work_ledger_state, whose fold rules differ.A reader's shadow comparison then differs only where the database and the file hold different rows.
The parity receipts measure these differences.
Rows stamped in the same second are ordered by (row_ts, projected_at, row_id), not file order.
The database holds every row the projection received; a markdown reader sees only the file it opened.
Tests
File is
tests/test_golden_chain_work_ledger_query.pywith 30 tests.21 cases are verb calls recorded over a synthetic fixture ledger
tests/fixtures/work_ledger_query.These are replayed through the handler.
Other tests cover parity, freshness, a database error, a reader error reported once, continuation lines, contract topics and real runtime typed dispatch.
Four hand mutations of the replay rules each failed 3 tests.
These are claim close comparison, hold expiry without a surface, inbox release check, inbox action flag.
The runtime sweep import check is clean over 497 entry points.
It reported the node when its import was broken on purpose.
Lab
Lab: host=h201 lane=omn20739-ba01 head=e9a842267333f95b5068c24f0614c18508fadbf7 command="the handler read-only against the dev lane omninode_internal.work_ledger_rows, then the markdown read verbs over an export of the same rows" observed=identical answers on 8 of 8 queries over 42672 rows
Evidence-Ticket: OMN-20738
Evidence-Source: OCC#13411