Repository navigation
feat(OMN-19513): declare claude_hook_events and claude_agent_spans ownership ahead of their vendoring - #2958
Merged
jonahgabriel merged 3 commits intoSep 26, 2026
Conversation
…nership ahead of their vendoring Step 1 of the three-PR order scripts/application-relation-ownership.yaml documents, as omnimarket#2937 did for session_content. omnibase_infra#4169 vendors the node_projection_claude_hook_events migrations and its Application Database Domain Enforcement gate resolves ownership from this file at omnimarket dev tip, so the declaration has to land first; omnimarket#2956 then lands the node and its migration. No SQL, no exemption. The relation inventory is regenerated: source_declared_tables 81 to 83, source_created_tables unchanged at 72.
✅ Architectural Review — PASSEDErrors: 0 What this checks
No architectural violations found. Static architectural lint — no model inference (OMN-14176). |
Contributor
|
OCC autobind did not mint a companion for this PR: no changed-file candidate could be proven RED against the merge base, and emitting a PR-existence probe instead would be non-falsifiable evidence (OMN-15247). Hand-authored evidence is required. |
jonahgabriel
enabled auto-merge (squash)
September 26, 2026 15:06
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
… their tables The first version of this declaration named claude_hook_events and claude_agent_spans only. The OMN-15361 SQL ownership gate treats a sequence named by a GRANT as a target in its own right (the OMN-18999 correction recorded beside prod_promotion_gate_decisions_projection_cursor_seq), and the vendored 0001 grants USAGE on both BIGSERIAL cursor sequences by literal name. Measured by running omnibase_infra scripts/ci/check_application_database_sql.py over omnibase_infra#4169 with this manifest as the omnimarket input: - at 304b049 (tables only): FAIL, two findings, one per sequence; - with these two database_objects entries: PASS. Test first: tests/test_omn19513_claude_hook_events_ownership_declared.py failed on both sequence cases before the entries and passes after. The generated relation inventory is unchanged (--check clean before and after --write).
jonahgabriel
added a commit
that referenced
this pull request
Sep 26, 2026
… sequences Two changes carried here so this node package stays byte-equal to what omnibase_infra#4169 vendors and to what omnimarket#2958 declares: - 0001 now asserts the omninode_runtime USAGE grant on schema omninode_internal with has_schema_privilege, answering the Hostile Reviewer MAJOR finding on omnibase_infra#4169 that it was the one issued privilege left unasserted. The grant set itself is unchanged: it is already exactly the writer scope. The file is byte-identical to the vendored copy on omnibase_infra#4169 (cmp). - scripts/application-relation-ownership.yaml gains the two database_objects sequence entries, identical to omnimarket#2958, because the OMN-15361 SQL gate refused both sequences by name with only the tables declared. The ownership test from #2958 is carried too, so the hunks are identical and merge cleanly in either order. Lab (.201 dev lane, omnibase-infra-postgres, database omnidash_analytics): both files applied inside BEGIN ... ROLLBACK with ON_ERROR_STOP=1, clean; with the schema USAGE revoked inside a rolled-back transaction the new assertion raised division by zero. Post-state unchanged (USAGE true, 21 event rows, 4 span rows).
Resolves the relation-inventory conflict with OMN-19716 (topic_activity): the inventory is regenerated from the merged tree (84 declared, 73 created, 21 sequences) and the census assertion counts both declarations. Onex-Lane: all-hooks-contract-83 Onex-Session: 6950f7ce306645a3b424fc90448d07c0
jonahgabriel
added a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 26, 2026
…market#2958 (#11491) * evidence(OMN-19513): hand-authored OCC companion for OmniNode-ai/omnimarket#2958 occ-preflight/eligibility declined omnimarket#2958 terminally with skip:NO_RED_DERIVABLE_CHECK: the diff is a db_io.db_tables ownership declaration in scripts/application-relation-ownership.yaml plus its regenerated evidence json and a test-count assertion. Per OMN-15247 the remedy is hand-authored evidence. Appends two dod_evidence entries to contracts/OMN-19513.yaml plus their receipts: a content-bound probe (role: claude_hook_events present at the PR head 304b049a57, absent at the merge base 6c13a5fcb5, positive control on a pre-existing role) and the product diff scope (3 files, 0 SQL). No acceptance criterion of OMN-19513 is bound: #2958 is step 1 of the forced order declare -> vendor (omnibase_infra#4169) -> create (omnimarket#2956). Purely additive. Local: check_contract_change_rebinds_receipts --staged, check_receipt_hardening --staged (positive control: a tampered entry hash is refused), check_contract_substance_floor, check_contract_dod_authoring and pre-commit over the touched files all pass. OMN-19513 * evidence(OMN-18921): mint the owed OCC self-bind for PR #11491 * evidence(OMN-19513): drop the self-bind minted before the dev merge so the mint re-binds it to the merged contract hash Onex-Lane: all-hooks-contract-83 Onex-Session: 58fb36e9cf4f473f85a53ae4d1016c46 * evidence(OMN-18921): mint the owed OCC self-bind for PR #11491 --------- Co-authored-by: onexbot-occ-writer[bot] <onexbot-occ-writer[bot]@users.noreply.github.com>
jonahgabriel
deleted the
jonah/omn-19513-declare-claude-hook-events-ownership
branch
September 26, 2026 23:50
jonahgabriel
added a commit
that referenced
this pull request
Sep 28, 2026
…ode hook, with subagent lineage (#2956) * feat(OMN-19513): node_projection_claude_hook_events -- every Claude Code hook, with subagent lineage The consumer half of the all-hooks capture contract (omniclaude#2370). One subscribe topic, onex.evt.omniclaude.hook-event.v1, carries all 33 Claude Code hook types with lineage on every event. This node projects it into omninode_internal.claude_hook_events (one row per event, session_id as a real column, agent_id NULL for the main thread) and folds subagent lineage into omninode_internal.claude_agent_spans (parent_agent_id plus parent_resolution: main_thread, resolved, workflow or unknown). Rule 7a pair: HandlerProjectionClaudeHookEvents is the pure definition-B fold; ClaudeHookEventsProjectionWriter is the in-process writer that reads the spawning PreToolUse, calls the fold and persists. Idempotent by construction: event rows insert ON CONFLICT (event_id) DO NOTHING, the span tool_call_count is recounted from the event table rather than incremented, and a known parent replaces unknown but never the reverse. A child written before its spawning call is repaired when the call arrives. Only the writer is a routed entry. The contract's event has a top-level payload mapping and an event_id, which the runtime's typed arm reads as a transport envelope and unwraps through (OMN-16050); a routed fold would receive the per-hook payload without its lineage and dead-letter every event. The wire model refuses a payload key the capture contract does not declare for the metadata topic, so content that reaches this topic by a producer regression is dead-lettered, not stored. It drops, by name, the five top-level stamps the emit seam adds (measured on a live lab record). Tests reproduce the contract's expected_projection rows for the nested subagent, workflow-agent and orphan-agent scenarios through the writer's runtime entry, pin the hook list, payload keys and projection columns to the contract, and prove the SQL against real Postgres (skips without a DB). * fix(OMN-19513): the hook wire model drops the journal appender's stamps by name The wire model for onex.evt.omniclaude.hook-event.v1 forbids extra top-level keys and drops transport stamps by name. It previously dropped only five stamps: correlation_id, causation_id, entity_id, session_id, and redaction_state. The real appender (omniclaude hook_emit_append.py) also merges lane, lane_source, lane_ticket, workspace_path, and turn_id into every record. Because these five keys were not in the drop set, a fixture event journaled through the real appender was rejected with extra_forbidden, so every real hook event would have been dead-lettered. The fix adds the five appender keys to the named stamp set so they are dropped instead of rejected. The event's lineage.turn_id remains authoritative over the appender's top-level turn_id. The seam test now carries the appender stamps with a different top-level turn_id and asserts the stored turn_id is the lineage one. A new test proves an unnamed top-level key such as prompt is still refused. * feat(OMN-19513): declare claude_hook_events and claude_agent_spans ownership ahead of their vendoring Step 1 of the three-PR order scripts/application-relation-ownership.yaml documents, as omnimarket#2937 did for session_content. omnibase_infra#4169 vendors the node_projection_claude_hook_events migrations and its Application Database Domain Enforcement gate resolves ownership from this file at omnimarket dev tip, so the declaration has to land first; omnimarket#2956 then lands the node and its migration. No SQL, no exemption. The relation inventory is regenerated: source_declared_tables 81 to 83, source_created_tables unchanged at 72. * fix(OMN-19513): the hook wire model drops the drainer's hook_fired_at stamp by name The omniclaude emit drainer stamps hook_fired_at on every published record, so every real drained hook event failed validation and was dead-lettered. This adds hook_fired_at to TRANSPORT_STAMP_KEYS, so the wire model drops it by name while still refusing unknown top-level keys. Tests carry the new key and assert it is accepted while an unknown key is still rejected. Onex-Lane: all-hooks-contract-83 Onex-Session: 9a8f8ac2b564447cbcbd3142788e28a1 * test(OMN-19513): pin the new writer, node and relations in the repo rosters CI on the first push failed three roster tests this node moves. ClaudeHookEventsProjectionWriter joins the pinned exact set of in-process-dispatch writers as the eighth, on the same reviewed terms (its pure fold does not declare the capability). The relation inventory is regenerated after merging the omnimarket#2958 ownership declaration: source_created_tables 72 to 74 and the arithmetic unreconciled bound 14 to 12, declared unchanged here. The dogfood inventory counts node_dirs 425 to 426 and entry_points 416 to 417. * fix(OMN-19513): assert the schema USAGE grant and declare both cursor sequences Two changes carried here so this node package stays byte-equal to what omnibase_infra#4169 vendors and to what omnimarket#2958 declares: - 0001 now asserts the omninode_runtime USAGE grant on schema omninode_internal with has_schema_privilege, answering the Hostile Reviewer MAJOR finding on omnibase_infra#4169 that it was the one issued privilege left unasserted. The grant set itself is unchanged: it is already exactly the writer scope. The file is byte-identical to the vendored copy on omnibase_infra#4169 (cmp). - scripts/application-relation-ownership.yaml gains the two database_objects sequence entries, identical to omnimarket#2958, because the OMN-15361 SQL gate refused both sequences by name with only the tables declared. The ownership test from #2958 is carried too, so the hunks are identical and merge cleanly in either order. Lab (.201 dev lane, omnibase-infra-postgres, database omnidash_analytics): both files applied inside BEGIN ... ROLLBACK with ON_ERROR_STOP=1, clean; with the schema USAGE revoked inside a rolled-back transaction the new assertion raised division by zero. Post-state unchanged (USAGE true, 21 event rows, 4 span rows).
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-19513 (operator ruling on the rolling ledger, lane all-hooks-capture-83-ruling: "we need all hooks captured").
This PR declares omnimarket as the catalog owner of two new relations in
scripts/application-relation-ownership.yaml:omninode_internal.claude_hook_eventsandomninode_internal.claude_agent_spans. Both relations are configured withdatabase_refset toapplication,accessset toread_write, androlesset toclaude_hook_eventsandclaude_agent_spans. The migration path issrc/omnimarket/nodes/node_projection_claude_hook_events/migrations/0000_create_claude_hook_events.sql. This change mirrors the node contract inomnimarket#2956. The PR carries no SQL. It is step 1 of the three-PR order documented in the file, similar to howomnimarket#2937handledsession_content. No exemption is added. The relation inventory evidence file underdocs/evidence/was regenerated usingscripts/generate_application_relation_inventory.py, updatingsource_declared_tablesfrom 81 to 83, whilesource_created_tablesremains 72.Proof
Unit tests in
tests/unit/scripts/test_application_relation_inventory.pyshow 12 passed. The generator--checkpasses. Ruff is clean. Per Rule 24, there are no runtime behaviour changes, so nothing is exercised on the lab. The tables named in the PR already exist on the .201 dev lane from theomnimarket#2956lab pass.Merge order
omnibase_infra#4169(vendors the two migrations)omnimarket#2956(the node and its migrations)The
omnibase_infraApplication Database Domain Enforcement gate resolves ownership from this file atomnimarketdev tip and requires exactly one declaration. Theomnimarketnode-migration-vendor-parity gate refuses a node migration untilomnibase_infradev carries the vendored copy.Hand-authored change-control companion: onex_change_control#11491 (the autobind declined this head terminally with skip:NO_RED_DERIVABLE_CHECK, so evidence is hand-authored under the hand-authored evidence procedure, mirroring the sibling #2937's companion). It must merge before this PR's change-control checks turn green.
Evidence-Ticket: OMN-19513
Evidence-Source: OCC#11491