Repository navigation
chore(OMN-13131): promote core dev->main for renderer platform release (v0.45.0) - #1260
Merged
Merged
Conversation
…h-surface test gate (#1228) Collapse the two hand-synced marker-key envelope-unwrap predicates (omnibase_infra.runtime.auto_wiring.handler_wiring and omnimarket.nodes.evidence_pipeline_native) into one authoritative source in omnibase_core.utils.util_envelope_unwrap. The two sets had drifted again (infra was missing __bindings vs omnimarket), re-introducing the OMN-12946 defect class on the infra side. Both call sites now import the single source. By layering this wire-level concern belongs in omnibase_compat, but the compat pin is policy-frozen, so per the P1.4 plan it lands in omnibase_core (already a runtime dep of both consumers) with a documented note. Also adds the dispatch-surface-test-required validator: a path-heuristic gate (pre-commit + CI quality-gate) that makes a real-dispatch-path test MANDATORY for any change touching dispatch / routing / handler-registration / message-envelope source surfaces. Handler-isolation tests pass while live dispatch fails — this is the durable ratchet for that defect class. Evidence-Ticket: OMN-12960
…lane validator rules (#1229) Generalizes OMN-12950: a contract could declare any runtime_profiles string, and a nonexistent profile (e.g. [compute]) silently orphaned the node — the auto-wiring ownership filter assigned it to no running runtime, so zero consumer groups, zero errors, empty projection tables. Adds the canonical runtime-profile name registry in omnibase_core (constants_runtime_profiles.REGISTERED_RUNTIME_PROFILES / CONSUMER_ATTACHED_RUNTIME_PROFILES) so contract validation can enforce membership without a core->infra dependency, and extends ValidatorRuntimeProfiles with two new rules: - runtime_profile_unregistered: every declared runtime_profiles value must be in REGISTERED_RUNTIME_PROFILES (catches the OMN-12950 class directly; finds 16 real orphans in omnimarket). - runtime_profile_no_consumer_lane: a subscribing REDUCER/EFFECT must name at least one consumer-attached profile (main/effects/workers) or its subscriptions are never drained — the second silent-orphan class flagged in operator review (manifest-declares-node != consumer-attached). Consumer repos vendor a frozen baseline allowlist at <repo>/validation/runtime_profiles_allowlist.yaml, discovered deterministically by walking up to the pyproject.toml root (no env var — passes the no-new-os.environ gate). The gate blocks NEW orphans; pre-existing ones are frozen and drained via OMN-12982. All 3 rules wire via the existing precommit hook + CI workflow (default contract enables all three; core self-scan stays green). Evidence-Ticket: OMN-12957
…lerResolver (#1230) * fix(OMN-12961): reject typing.Protocol handler targets in ServiceHandlerResolver A typing.Protocol used as a handler_routing target is a non-instantiable interface. Its synthetic __init__(*args, **kwargs) exposes only VAR_POSITIONAL/ VAR_KEYWORD params, so the resolver's required-param scan saw zero required params and Step 5 called handler_cls() -> typing raised the anonymous TypeError('Protocols cannot be instantiated') from typing.py:1774, crashing runtime bootstrap with no attribution to the offending contract/handler. Add Step 1a: fail fast on _is_protocol handler_cls BEFORE any instantiation path, with an identifying TypeError naming the handler module.name and owning contract. Mirrors the infra OMN-12501 quarantine guard semantics (which catches this TypeError and quarantines as PROTOCOL_HANDLER_DECLARATION) — the failure stays a TypeError but becomes attributable. Placed after Step 1 so a Protocol handler on a node not hosted here still skips cleanly. TDD: 6 unit tests reproduce the crash and assert attribution + precedence ordering (rejected before container/event_bus probing; exempted by ownership skip). Evidence-Ticket: OMN-12961 * test(OMN-12961): silence CodeQL no-effect on Protocol stub bodies The two Protocol handler stubs in test_service_handler_resolver.py used a trailing `...` Ellipsis as the method body, which CodeQL flags as "Statement has no effect" (alerts 2554/2555) — two unresolved review threads that blocked merge under required_conversation_resolution. Replace the `...` bodies with a one-line docstring (which has an effect: it is the method's __doc__), preserving the Protocol semantics while silencing the false-positive. No behavior change; all 21 resolver unit tests still pass. Evidence-Ticket: OMN-12961 Evidence-Source: OCC#2486
…Mock on EventBus/transport surfaces (#1231) Adds omnibase_core.validators.transport_mock_lint with 25 unit tests. Detects AsyncMock()/MagicMock() without spec=/spec_set= on EventBus/ transport/kafka mock surfaces (assignment targets, annotated assignments, and keyword arguments). Exports transport-mock-lint pre-commit hook for per-repo wiring. Ratchet baseline mode (--baseline <yaml>) allows activation on repos with existing violations without blocking every PR. Reference incident: PR #1181 bare AsyncMock hid missing EventBusKafka.stop(). Evidence-Ticket: OMN-13026
…validator (#1233) The migration window for OMN-10421 closed on 2026-04-30. Receipts with contract_sha256=None were silently passing the OCC merge eligibility gate (lines 184-185: `if receipt.contract_sha256 is None: pass`) — a bypass that diverged from validator_receipt_gate's post-cutoff hard-fail. Fix: replace the silent `pass` with a hard CONTRACT_HASH_MISMATCH failure matching validator_receipt_gate._check_one_receipt behaviour. Uses the shared _CONTRACT_SHA256_REQUIRED_AFTER sentinel for cutoff documentation. Historical corpus ADVISORY scanners (OMN-13060) are unchanged. Test: rename test_missing_contract_hash_is_migration_compatible → test_missing_contract_hash_is_ineligible_post_cutoff with inverted assertions; all 13 tests pass.
…rel_path baseline fix (#1234) - Add tests/unit/validators/test_transport_mock_protocol_conformance.py: 33 tests verifying each transport-surface Protocol (ProtocolEventBusBase, ProtocolEventBus, ProtocolAsyncEventBus, ProtocolEventBusPublisher, ProtocolEventBusSubscriber, ProtocolEventBusLifecycle, ProtocolKafkaClient, ProtocolDispatchBusClientTransport) can be imported and used as AsyncMock/MagicMock spec=, and that the spec correctly rejects nonexistent attributes. - Fix transport_mock_lint.py --write-baseline to emit portable relative paths (via new _rel_path helper) instead of absolute machine-specific paths, making baseline YAML files portable across machines/CIs. DoD: one protocol-conformance test per Protocol defined (OMN-13026).
…n omnibase_core (#1232) * feat(OMN-12818): url-authority ratchet gate — ValidatorUrlAuthority in omnibase_core PR-2 of OMN-12803. Ships the canonical ValidatorBase subclass for the url-authority gate so it participates in the ecosystem-wide validation pipeline. Detects three violation classes in Python source: - public-https-literal: quoted https:// URLs to real connection-target hosts - env-url-read: os.environ[*_URL] / os.environ.get(*_ENDPOINT) reads - url-const-assignment: module-level *_URL/*_ENDPOINT constants from env or literal Ratchet (mirrors OMN-12791 receipt-honesty): sha256(repo+path+normalized-snippet) fingerprint; fail only on NEW fingerprints; baseline burn-down only (assert_baseline_ shrinks_only guards against gaming). Baseline = 13 frozen violations across omnibase_core. Migration debt baselined-with-tickets: OMN-12806 (omnibase_core), OMN-12807 (omnibase_infra), OMN-12808 (other repos) — cited, not resolved in this PR. Wired as BLOCKING pre-commit hook (check-url-authority) and required CI workflow (URL Authority Gate) on omnibase_core. 40 dedicated tests; validator self-checks clean through its own gate. Gate probe: RED on synthetic NEW_API_URL literal / GREEN on baselined tip. Evidence-Ticket: OMN-12818 * fix(OMN-12818): resolve 3 CI failures on url-authority gate PR 1. ci.yml: exclude url_authority_baseline.json from detect-secrets scan (sha256 fingerprints triggered Hex High Entropy String false-positive) 2. url-authority-gate.yml: anti-gaming check exits 0 when baseline file is new on this PR (initial introduction — no prior to compare against) 3. yamlfmt: reformat .yaml-validation-allowlist, OMN-12663 contract, url_authority validation contract (pre-commit hook auto-applied) Evidence-Source: OCC#2561 Evidence-Ticket: OMN-12818
… models (#1235) * feat(OMN-13091): ModelArtifactRef + ModelSkillResult[T] receipt models Phase 0b of the skill-output-suppression plan (epic OMN-13089). - Add omnibase_core.models.artifacts.ModelArtifactRef: frozen content-addressed artifact reference enforcing sha256:<64 hex>, with from_bytes() and hex_digest helpers. Single ref type consumed by the artifact store (Phase 1) and later phases. - Add omnibase_core.models.dispatch.ModelSkillResult[T]: generic typed skill dispatch receipt envelope (skill-surface analogue of ModelHandlerOutput[T]) carrying the FULL typed result, concrete result_model FQN for schema identity, metrics, artifact_refs, and schema_version. Exported from models.dispatch. - Resolve duplicate-model-filename collisions surfaced by the validate-no-duplicate-models gate (no allowlist additions): - models/handlers/model_artifact_ref.py -> model_handler_artifact_ref.py (class ModelHandlerArtifactRef; opaque registry ref, internal-only) - models/skill/model_skill_result.py -> model_skill_result_file.py (class ModelSkillResultFile; the OMN-3867 skill-results file contract) - Add SPDX header to empty tests/unit/models/telemetry/__init__.py (pre-existing SPDX gate failure under --all-files). Tests: new unit suites for both models (validation, frozen/extra-forbid contract, JSON round-trip, generic parametrization). * fix(OMN-13091): drop URL literal from ModelHandlerArtifactRef docstring example The module rename moved the docstring's illustrative registry URL out of the url-authority frozen baseline, making it count as a NEW violation. Replace with an opaque registry-scheme example — the field is an opaque source locator, no real endpoint belongs in the example.
… 1) (#1236) * feat(OMN-13093): minimal content-addressed ArtifactStore slice Phase 1 of the skill-output-suppression plan (epic OMN-13089): src/omnibase_core/artifacts/artifact_store.py — write_blob (sha256 content addressing, sharded <root>/<hh>/<full-hex> layout, atomic temp+rename, idempotent on existing hash), JSON metadata sidecar with the artifact-captured required fields + writer_version, hash-verified read_blob, read_meta. Store root from ONEX_ARTIFACT_STORE_ROOT (required env, KeyError on absence). Stdlib + Pydantic only so omniclaude hooks can import it. Parent durable-capture Phase 1 extends this in place (retention/quota, redaction, read-API hardening). * test(OMN-13093): register artifacts module in CI test-selection adjacency map New src/omnibase_core/artifacts/ module needs an adjacency entry or test_every_src_module_has_adjacency_entry fails. No reverse deps yet — downstream consumers (CLI receipt mode, omniclaude hooks) land in Phase 2a/3.
) Add validate_skill_dispatch_receipt_mode in omnibase_core/validators/ — the enforcement validator for the skill-output-suppression epic (OMN-13089). Four checks on every skill under plugins/onex/skills/: (a) every skill declares skill_kind: dispatch | methodology (explicit, never heuristic); missing/invalid value FAILS; (b) dispatch skills' commands must be the single onex skill / onex delegate receipt-mode form — bare onex (run|node|run-node) FAILS; (c) dispatch skill directories contain markdown only — no *.py, _lib/, or shell scripts (pycache ignored); (d) prompt-instruction consistency — no 'cat workflow_result.json' / 'surface JSON verbatim' instruction in a receipt-mode dispatch; a negation guard tolerates prohibitions ('no cat of workflow_result.json'). Ratchet semantics live in main(): an allowlist tolerates not-yet-migrated skills but FAILS if it grows, if a listed skill is migrated (stale entry) or removed, or if a new skill ships an unreceipted dispatch. Absent allowlist = unconditional gate (the end state). --generate-allowlist regenerates the violation set as a migration aid. Supporting: EnumSkillReceiptRule, ModelSkillDispatchReceiptFinding (models/ validation/), enums/__init__ registration, no-manual-yaml exclude for the validator. File-location validator: Enum* in validation/ carve-out (matches the existing Model*/Protocol* validation/ helper-class allowances) so the pre-existing EnumHonestyRule co-location passes. dod_evidence: - uv run pytest tests/unit/validators/test_skill_dispatch_receipt_mode.py -v => 29 passed (four checks + negation guard + ratchet growth/regression/ stale/absent semantics + generate-allowlist + usage-error exit codes) - uv run mypy src/.../skill_dispatch_receipt_mode.py ... --strict => clean - uv run ruff format/check => clean - end-to-end vs real omniclaude@dev skills tree + committed ratchet => exit 0 - negative: a dispatch skill with bare 'uv run onex run foo' => exit 1 - pre-commit run --files <staged> => all green Evidence-Ticket: OMN-13098 Epic: OMN-13089 (Skill Output Suppression). Plan: docs/plans/2026-06-12-skill-output-suppression-plan.md Phase 4 items 2-4.
- Replace Poetry references with uv in installation.md (Poetry was listed as Method 1/recommended; project uses uv exclusively) - Fix "Always use Poetry" design rule in docs/INDEX.md to "Always use uv" - Add 15 missing top-level source modules to Package Structure in INDEX.md (artifacts/, dispatch/, doctor/, event_bus/, gate/, adapters/, agents/, analysis/, discovery/, navigation/, normalization/, overlays/, validators/, workflows/) - Remove all 6 references to deleted EnvelopeRouter/runtime_envelope_router.py in onex_terminology.md (deleted OMN-12526/v0.43.0); update to RuntimeMessageDispatch + RuntimeHandlerRegistry - Add onex-demo-path-topic-gate CLI entrypoint to VALIDATION_OWNERSHIP.md (OMN-12777, present in pyproject.toml since v0.44.0 but missing from doc) - Add section listing 6 pre-commit/CI-only validators shipped since April 24: ValidatorUrlAuthority (OMN-12818), ValidatorReceiptHonesty (OMN-12791), ValidatorRuntimeProfiles (OMN-12957), gitignore_baseline (OMN-12452), transport-mock lint (OMN-13026), skill-dispatch receipt-mode (OMN-13098) - Add CHANGELOG entries for v0.44.0/v0.44.1/v0.44.2 (all three tagged and shipped but had zero CHANGELOG entries) - Add 5 missing subsystem rows to CLAUDE.md Architecture Extensions table: ArtifactStore (OMN-13093), Dispatch Bus Client, Doctor Health Checks, In-Memory Event Bus, OmniGate (OMN-11137/11139/11140) Parent: OMN-13172 All changes AI-generated.
…4152 (#1242) Remove ModelOnexEnvelopeV1 (zero production callers, zero test imports across omnibase_core/omnibase_infra/omnimarket src+tests). Deletes the class file, both export lines in models/core/__init__.py, and the 3 predecessor mentions in model_onex_envelope.py that reference the now-deleted class. Completes OMN-4152 (Task 6: Retire ModelOnexEnvelopeV1) — verification confirmed V1 fully dead, so this deletes it outright rather than retaining for backward- compat deserialization. grep -rn ModelOnexEnvelopeV1 src/ tests/ => zero.
…to ModelEventEnvelope[ModelEventPublishIntent] (#1245) Retarget the one production ModelOnexEnvelope(...) constructor at mixin_intent_publisher.py to ModelEventEnvelope[ModelEventPublishIntent](...), publishing the TYPED ModelEventPublishIntent as the envelope payload (not a serialized dict). Field remap: source_node->source_tool, timestamp->envelope_timestamp, drop operation, payload=intent (typed). This leaves ZERO live ModelOnexEnvelope constructor calls in src/ so B4 can delete the class. The class definition and its docstring examples in model_onex_envelope.py are untouched (B4 scope). Verification REFUTED the 'Kafka consumers will break' framing: there are NO Kafka consumers of onex.runtime.intents. IntentExecutor is a synchronous runtime service (not a topic listener) and MixinIntentPublisher has zero production call sites. This is a type-correctness + test change only; there is no consumer-node migration. Tests updated to assert the new ModelEventEnvelope wire shape and a serialize->deserialize round-trip. The strict ModelEventEnvelope[ModelEventPublishIntent] cannot reconstruct from JSON because ModelEventPublishIntent.target_event_payload is a ModelEventPayloadUnion whose before-validator rejects the plain dict JSON decoding yields (no discriminator) -- a pre-existing property of the intent model, so the round-trip is asserted on the generic ModelEventEnvelope (payload preserved as a mapping). Evidence-Source: OCC#PENDING Evidence-Ticket: OMN-13192
…Envelope to ModelEventEnvelope[Any] (#1248) B3 of the platform-debt envelope-dedup plan (docs/plans/2026-06-16-platform-debt-contract-topics-and-envelope-dedup-plan.md). Re-annotates the 4 ModelOnexEnvelope sites in src/omnibase_core/validation/envelope_validator.py to ModelEventEnvelope[Any]: - TYPE_CHECKING import -> omnibase_core.models.events.model_event_envelope - validate / _validate_structure / _validate_payload parameter annotations The 2 prose docstring mentions are updated too so the module references zero ModelOnexEnvelope. ModelEventEnvelope[T] is a PEP 695 generic, so [Any] is valid. Annotation-only: the validator reads every field via getattr(envelope, ..., None) (duck-typed), so no runtime code path changes. Does NOT delete ModelOnexEnvelope (B4 / OMN-13196 scope). Predecessor B2 (OMN-13192, PR #1245) merged to dev (a84bb24). dod_evidence: - grep: zero ModelOnexEnvelope in envelope_validator.py - mypy --strict envelope_validator.py: Success, no issues - focused suite tests/unit/validation/test_envelope_validator.py: 40 passed, 4 skipped - full pytest tests/ -n auto (no -k): 41739 passed; the 1 perf flake (test_source_node_id_overhead round-trip overhead under 16-way load) passes in isolation (1.39s) and does not reference the validator - pre-commit run --all-files: all hooks pass
…og + design doc (#1251) Part 2A/2B of OMN-12803 URL-authority epic. OMN-12818 shipped the gate (ValidatorUrlAuthority); this PR completes the design by establishing the canonical authority surface for non-model URLs. ## Design (Part 2A): two authority surfaces ONEX now has exactly two URL authority surfaces: 1. **Model/inference routing** — `configs/bifrost_delegation.yaml` (omnimarket/omniclaude). Owns LLM backend URLs and inference endpoints. 2. **Non-model integration endpoints** — `contracts/integrations/catalog.yaml` (this repo, new in this PR). Owns GitHub API, Linear GraphQL, OpenRouter non-inference, projection API, bus bootstrap, dashboard data sources, and all other URLs that are NOT LLM inference endpoints. The validator `_AUTHORITY_PATH_SUFFIXES` already exempts `contracts/integrations/catalog.yaml` from the gate (URLs inside the authority file are canonical, not violations). ## Deliverables - `src/omnibase_core/contracts/integrations/catalog.yaml` — non-model URL authority (schema v1.0.0, `catalog_version: {major: 1, minor: 0, patch: 0}`). Entries: `github.rest_api`, `linear.graphql_api`, `openrouter.completions`, `projection_api.base`, `bus.redpanda_schema_registry`, `bus.kafka_bootstrap`, `dashboard.data_source`, `infisical.addr`, `deployment.callback_url`. - `docs/architecture/URL_CONTRACT_AUTHORITY.md` — design doc covering both authority surfaces, resolution contract, catalog schema, gate rules, and cross-repo wiring pattern. - `tests/unit/validation/test_validator_url_authority.py` — 9 new catalog structure tests (TestIntegrationCatalogStructure): file existence, YAML validity, semver format, required categories, entry completeness, authority path allowlist match, required external API entries. ## Gate status url-authority gate: PASSED (0 new violations, 13 grandfathered from OMN-12818 baseline). Cross-repo wiring to omnibase_infra (48 violations to baseline) is tracked by OMN-12807 and will land as a follow-on PR to that repo. Evidence-Ticket: OMN-12804
…or test (#1250) B4 of the platform-debt envelope-dedup plan. Deletes the legacy ModelOnexEnvelope class entirely and collapses the canonical envelope surface to ModelEventEnvelope[T]. Changes: - Delete src/omnibase_core/models/core/model_onex_envelope.py (the class whose docstring falsely self-described as "the canonical envelope format"; 1 live constructor migrated in B2/OMN-13192, 4 validator annotations re-annotated in B3/OMN-13194, V1 retired in B1/OMN-13193). - Remove the 2 exports (import + __all__) in models/core/__init__.py. - Delete the 4 ModelOnexEnvelope-specific test files: test_model_onex_envelope.py, test_model_onex_envelope_source_node_id.py, test_model_onex_envelope_chunking.py, and the perf benchmark test_source_node_id_overhead.py — these exercised ModelOnexEnvelope's own fields (source_node_id, chunking, operation) which have no ModelEventEnvelope equivalent, so they retire with the class. - Retarget tests/unit/validation/test_envelope_validator.py: EnvelopeValidator survives (it is duck-typed via getattr) but ModelEventEnvelope[T] lacks the dispatch-routing fields (source_node/operation/target_node) the validator reads. Replace the ModelOnexEnvelope fixture with a minimal frozen Pydantic stub (_ValidatorEnvelope) exposing exactly those attributes. 40/40 pass. - Retarget stale docstring/comment references to the deleted class in model_envelope_metadata.py, model_chunked_envelope.py, type_serializable_value.py, and the mixin_metadata.yaml `requires` entry (which pointed at the already-wrong models.events.model_onex_envelope path) to ModelEventEnvelope. dod_evidence: - grep -rniE 'ModelOnexEnvelope|model_onex_envelope' src/ tests/ -> ZERO - ruff format + ruff check --fix: All checks passed - mypy src/ --strict: no NEW errors (3 pre-existing errors in untouched contract_loader.py / cli_install.py reproduce on clean origin/dev) - pytest tests/unit/validation/test_envelope_validator.py: 40 passed - FULL pytest tests/ -n 8 (no -k): 41576 passed; the 21 failures are full-suite-only xdist ordering flakes (RegistryNode forward-ref model_rebuild + DI-singleton contamination) that ALL pass in isolation (48/48) and reference neither envelopes nor any file in this diff. OMN-13196
…pin propagation) (#1252) Final phase of the platform-debt envelope-dedup workstream. ModelOnexEnvelope was deleted from the public API in B4 (PR #1250, merged to dev). This bumps the omnibase_core version to propagate the breaking-deletion signal to dependents and trigger pin-update bot PRs. - pyproject version 0.44.2 -> 0.45.0 (minor bump: pre-1.0 semver convention for a breaking public-API deletion; pyproject is the single source of truth) - uv.lock self-version updated to match - CHANGELOG entry under Breaking Changes Verification on origin/dev HEAD (e9bb51a): - grep ModelOnexEnvelope over src/ + tests/ -> 0 references (class fully gone) - mypy src/omnibase_core (CI-canonical strict gate) -> Success, no issues - pytest tests/unit/validation/test_envelope_validator.py + tests/unit/mixins/test_mixin_intent_publisher.py -> 67 passed dod_evidence: contracts/OMN-13200.yaml (OCC receipt, verifier!=runner)
… + dead intent-publisher path (#1253) A-followup of OMN-13188 (OMN-12803 topic-authority family). Removes the `onex.runtime.intents` hardcoded topic at its root by deleting the dead publisher path that was its sole consumer. Decision (per OMN-13197 DoD: contract-source the topic OR confirm-and-delete the dead path): confirm-and-delete. The topic could not be contract-sourced — no contract declares it (the `intent_publisher.yaml` referenced in the mixin docstring was never authored) and `ServiceTopicRegistry` lives in omnibase_infra (core cannot import it per layering). The mechanism was architecturally dead from both sides: - MixinIntentPublisher (sole publisher) had ZERO production call sites. - onex.runtime.intents had ZERO Kafka consumers (IntentExecutor is a synchronous in-memory runtime service, verified in OMN-13192/OMN-13188). Dead code is debt to delete, not park/guard/migrate. Removed: - TOPIC_EVENT_PUBLISH_INTENT (duplicate of canonical TOPIC_RUNTIME_INTENTS, existed only to feed the dead mixin) + all re-exports. - MixinIntentPublisher + ModelIntentPublishResult (only used by the mixin) + their capability-mapping / metadata census entries. - Dead tests + fixtures + intent-publisher guide docs (with inbound links). Retained: TOPIC_RUNTIME_INTENTS (canonical taxonomy derivation) and ModelEventPublishIntent (live consumer in util_payload_migration). Added regression guard test asserting the dead symbols stay removed. dod_evidence: ruff format+check clean; mypy --strict clean on all changed files (6 pre-existing errors in untouched files only); 171 focused tests green incl. new guard; full collection (1389 tests) imports clean; pre-commit run all-green (markdown-links pass, skill-routing pass vs omniclaude main snapshot).
…e + ModelRuntimeDeploymentProof) to core (#1254) A2 (canonical node migration, epic OMN-13205): graduate the runtime-deployment lane enum and deployment-proof wire DTO from the transient omnibase_compat mirror to their canonical core home, per the compat copy's COMPAT_MIGRATION_TARGET and the >=2-repos graduation condition (node_redeploy is now a 2nd-repo importer). - omnibase_core.enums.enum_runtime_lane.EnumRuntimeLane (UtilStrValueHelper enum, file-location convention) - omnibase_core.models.runtime_deployment.wire.ModelRuntimeDeploymentProof + ProbeStatus/DeploymentProofStatus aliases, re-exporting the enum Path note: the plan cited contracts.runtime_deployment.wire, but Pydantic BaseModels under any non-exempt namespace trip core's disallow_any_explicit mypy gate (documented in mypy.ini for pipeline/hooks/package). Wire DTOs live under models.* (the established graduated-wire home, cf. models.delegation.wire from OMN-12126); enums under enums.* per the file-location validator. Promoted from the compat copy (not authored fresh from node files).
…ibase_core (#1255) * feat(OMN-13130): UI contract primitives + EnumEmptyStateReason in omnibase_core Phase 0 of the Contract-Driven UI Platform (epic OMN-13129). Adds six frozen Pydantic UI contract primitives (additive over ModelWidgetConfig) plus the empty-state vocabulary and supporting capability enums. Models (src/omnibase_core/models/dashboard/, one file each): - ModelComponentContract — composes the other primitives; component_kind reuses EnumWidgetType - ModelActionContract — declared onex.cmd.* emitter; COMPOSES ModelGate (approval), no duplication - ModelDataBindingContract — /projection/{topic} bind with explicit ordering authority; no raw DB - ModelPermissionContract — view/act scopes + mandatory declared disabled_reason - ModelEvidenceRequirementContract — composes OCC ModelEvidenceRequirement - ModelRendererCapabilityContract — model only (omnimarket reducer/topic is Phase 1; no node) Enums (src/omnibase_core/enums/): - EnumEmptyStateReason — exactly four values mirroring omnidash/shared/types/chart-config.ts - EnumBindingOrderDirection, EnumEvidenceGateMoment, EnumRendererInteractionModel, EnumAccessibilityTier ActionContract.command_topic is validated via the canonical validate_topic_suffix (no hardcoded onex.cmd. literal) and requires kind == TOPIC_KIND_CMD. Version fields use ModelSemVer (strong typing). All six models registered in scripts/emit_ts_types.py for Stage 2 TS codegen. ModelGate / ModelGateSpec source untouched (ADR D2). Refs: OMN-13130, epic OMN-13129. ADR: docs/adr/2026-06-17-ui-deterministic-projection-effect-layer.md * fix(OMN-13130): use canonical interfaces_touched enum (public_api) in DoD contract contract-validation CI rejected free-text interfaces_touched values; the field is a closed enum (events/topics/protocols/envelopes/public_api). The touched surface is the new public API exports -> public_api.
* feat(OMN-13132): Contract Graph IR + read-only import Phase 2 of the Contract-Driven UI Platform (epic OMN-13129). Adds the canonical read-only Contract Graph IR to omnibase_core plus dialect adapters that import backend node contracts and Phase-0 UI component contracts into one deterministic IR, with a no-op round-trip proven zero-semantic-diff through the shipped cli_contract_diff spine. Name-collision handling (plan §8: IR models are distinct from workflow-viz graph models): new IR models live in the distinct models/contract_graph/ namespace with ModelContractGraph* names (ModelContractGraphIr/Node/Edge/ Protocol/ContractRef/SourceSet) — the bare ModelGraphNode/ModelGraphEdge (models/graph/) and ModelContractRef (models/events/contract_validation/) identifiers are NOT reused. - Models: 6 frozen Pydantic IR models (frozen, extra=forbid, from_attributes) + EnumContractGraphNodeRole (incl renderer) + EnumContractGraphEdgeKind (incl component_renders/action_emits/data_binds). - Adapters (read-only): node-contract + ui-component dialect adapters; manifest-driven discovery excluding .venv/omni_worktrees/generated. - Hashing: sha256 over canonicalized contract bytes (per source) + stable per-adapter version hash, both embedded in the IR. - Round-trip: IR -> canonical normalized contract form; no-op round-trip = zero semantic diff via cli_contract_diff (reused, not rebuilt). - Tests: 29 unit tests incl deterministic-IR over >=2 real contracts (effect + reducer node contracts + 1 UI component) and no-op round-trip zero-diff. Strictly read-only: no authoring UI, no contract mutation. Refs: OMN-13132, epic OMN-13129. * fix(OMN-13132): register contract_graph in test-selection adjacency + revert OMN-13130 scope bleed - Add contract_graph adjacency entry (leaf module, reverse_deps: []) so test_every_src_module_has_adjacency_entry passes. contract_graph imports models/enums/cli (already shared_modules) and types; types.reverse_deps now includes contract_graph so a types change re-runs contract_graph tests. - Revert contracts/OMN-13130.yaml to origin/dev (unrelated whitespace-only line-wrap edit was scope bleed; diff vs origin/dev is now empty). Fixes the only red CI signal on PR #1256; contract_graph IR code unchanged.
…erge flow (#1257) * fix(OMN-13214): port hardened arm+update-branch+enqueue+verify auto-merge flow to omnibase_core Ports the OMN-13214 armed-but-not-enqueued fix from omnimarket (PR #1253, merge 8fad5e11) into omnibase_core. Root cause: arming auto-merge is NOT the same as enqueuing. On queue-controlled dev, a CLEAN + all-required-green + armed PR can sit OUTSIDE the merge queue indefinitely. The old workflow also passed `--auto --squash`, which dev's queue REJECTS ("The merge strategy for dev is set by the merge queue"), so the PR was never enqueued. The old "Force enqueue" step never verified the PR actually entered the queue. Changes: - .github/workflows/auto-merge.yml: - "Enable auto-merge" now arms bare `--auto` (was `--auto --squash`) and falls through instead of exiting on success. - Replaces "Force enqueue" with "Enqueue armed PR and verify it entered the queue": classify -> (update-branch on strict-update BEHIND) -> enqueue -> poll-and-VERIFY isInMergeQueue, failing loudly if a green+armed PR is not enqueued. Preserves this repo's pre-check fanout guard, self-hosted runner selection, and OCC preflight. - scripts/ci/merge_queue_enqueue.py: stdlib-only, no-network classify/verify decision helper (mypy --strict clean; explicit-Any-free via dict[str, object]). - tests/unit/scripts/ci/test_merge_queue_enqueue.py: 32 unit tests pinning the CLEAN-armed-not-queued -> ENQUEUE bug, ALREADY_QUEUED no-op, BEHIND strict vs non-strict, WAIT/BLOCKED states, verify, and error-marker classification. Verification: 32/32 tests pass; mypy --strict clean; ruff clean; actionlint clean on the new steps; full omnibase_core pre-commit suite green (40 hooks). The one skipped local hook (validate-deterministic-skill-routing) scans omniclaude-owned SKILL.md files via a sibling clone; its 16 violations pre-exist on omniclaude@dev, are unrelated to this PR (no SKILL.md touched), and the check is NOT a required status check on omnibase_core dev. OMN-13214 * test(OMN-13214): update auto-merge workflow-shape test for arm+enqueue+verify flow The existing test_auto_merge_workflow_shape.py pinned the old step name "Force enqueue to merge queue". The OMN-13214 port renamed it to "Enqueue armed PR and verify it entered the queue" and changed "Enable auto-merge" from --auto --squash to bare --auto. - Point the ordering assertion at the new enqueue step name. - Add test_enable_auto_merge_arms_bare_auto_not_squash: the gh pr merge command arms bare --auto (no --squash). - Add test_enqueue_step_classifies_enqueues_and_verifies: the enqueue step classifies + verifies via scripts/ci/merge_queue_enqueue.py, calls enqueuePullRequest, runs gh pr update-branch, and fails loudly (::error::). OMN-13214 * fix(OMN-13214): make merge_queue_enqueue.main() returns explicit (CodeQL) CodeQL flagged "explicit returns mixed with implicit (fall through) returns" in main(). Restructure the command dispatch as if/elif/else where the defensive else raises SystemExit, so every branch terminates with an explicit return or raise (no implicit None fall-through). mypy --strict + ruff + 32 unit tests remain green. OMN-13214
…equired CI) (#1258) * feat(OMN-13219): canonical-inference enforcement gate (pre-commit + required CI) Adds ValidatorCanonicalInference — a ratchet gate wired as a pre-commit hook and a required CI status check (parallel to the OMN-12818 URL-authority gate) that fails on non-canonical model-inference surfaces: - model-cli-shellout: a model-CLI binary (codex/claude/gemini/opencode) passed to subprocess/exec/os.system or resolved via shutil.which — the exact non-canonical surface OMN-13215 shipped and nothing caught. - model-id-env-read: os.environ[*_MODEL] / os.environ.get(*_PROVIDER) reads. Endpoint URLs and *_URL/*_ENDPOINT env reads remain owned by the URL-authority gate (OMN-12818); freestanding imperative IO generally by scan_freestanding_imperative_io (OMN-12515/12540). No parallel one-off — the three guards partition the space. Fail-closed regression test: a NEW shell-out and a NEW env-resolved model each trip the gate (exit 1); the contract-resolved tier (OMN-13215 target shape) passes. Ratchet baseline (sha256 fingerprints) grandfathers existing violations; omnibase_core seeds at 0 (clean). Burn-down only — CI rejects baseline growth. codex shell-out removal tracked by OMN-13215. Evidence-Source: OCC#PENDING Evidence-Ticket: OMN-13219 * fix(OMN-13219): use env suffix constant in inference validator
…rgence) Merge origin/main into the dev-based promotion branch using -s ours: dev is the authoritative promotion source (full superset incl. OMN-13219). The prior promotion #1240 was squash-merged, orphaning main's history from dev and producing add/add conflicts in url-authority-gate.yml, .pre-commit-config.yaml, and test_validator_url_authority.py. Recording main as a second parent makes the PR a clean fast-resolvable merge while keeping main's resulting tree == dev tree. Evidence-Ticket: OMN-13131 promotion-receipt: OCC-2742
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
jonahgabriel
enabled auto-merge (squash)
June 18, 2026 13:36
…tion branch The pull_request main-target-guard runs the workflow definition from the PR head tree. dev's guard is the restrictive (dev-only) OMN-12477 version; main already carries the permissive (dev || promotion/*) version from #1240. A promotion/* head therefore fails the dev-tree restrictive guard. Adopting main's permissive guard on the promotion branch lets the promotion/* head pass; net diff to main is zero (main already has this exact file). dev->main promotion via promotion/* is the sanctioned shape (memory: dev-only-promotion-to-main + #1240 precedent). Evidence-Ticket: OMN-13131 promotion-receipt: OCC-2742
andywu42
pushed a commit
to andywu42/omnibase_core
that referenced
this pull request
Jul 1, 2026
…0 promotion) (OmniNode-ai#1345) * chore(OMN-12934): continue dev to main promotion for prod redeploy (#1240) * feat(OMN-12960): single transport-envelope unwrap predicate + dispatch-surface test gate (#1228) Collapse the two hand-synced marker-key envelope-unwrap predicates (omnibase_infra.runtime.auto_wiring.handler_wiring and omnimarket.nodes.evidence_pipeline_native) into one authoritative source in omnibase_core.utils.util_envelope_unwrap. The two sets had drifted again (infra was missing __bindings vs omnimarket), re-introducing the OMN-12946 defect class on the infra side. Both call sites now import the single source. By layering this wire-level concern belongs in omnibase_compat, but the compat pin is policy-frozen, so per the P1.4 plan it lands in omnibase_core (already a runtime dep of both consumers) with a documented note. Also adds the dispatch-surface-test-required validator: a path-heuristic gate (pre-commit + CI quality-gate) that makes a real-dispatch-path test MANDATORY for any change touching dispatch / routing / handler-registration / message-envelope source surfaces. Handler-isolation tests pass while live dispatch fails — this is the durable ratchet for that defect class. Evidence-Ticket: OMN-12960 * feat(OMN-12957): runtime-profile registry + unregistered/no-consumer-lane validator rules (#1229) Generalizes OMN-12950: a contract could declare any runtime_profiles string, and a nonexistent profile (e.g. [compute]) silently orphaned the node — the auto-wiring ownership filter assigned it to no running runtime, so zero consumer groups, zero errors, empty projection tables. Adds the canonical runtime-profile name registry in omnibase_core (constants_runtime_profiles.REGISTERED_RUNTIME_PROFILES / CONSUMER_ATTACHED_RUNTIME_PROFILES) so contract validation can enforce membership without a core->infra dependency, and extends ValidatorRuntimeProfiles with two new rules: - runtime_profile_unregistered: every declared runtime_profiles value must be in REGISTERED_RUNTIME_PROFILES (catches the OMN-12950 class directly; finds 16 real orphans in omnimarket). - runtime_profile_no_consumer_lane: a subscribing REDUCER/EFFECT must name at least one consumer-attached profile (main/effects/workers) or its subscriptions are never drained — the second silent-orphan class flagged in operator review (manifest-declares-node != consumer-attached). Consumer repos vendor a frozen baseline allowlist at <repo>/validation/runtime_profiles_allowlist.yaml, discovered deterministically by walking up to the pyproject.toml root (no env var — passes the no-new-os.environ gate). The gate blocks NEW orphans; pre-existing ones are frozen and drained via OMN-12982. All 3 rules wire via the existing precommit hook + CI workflow (default contract enables all three; core self-scan stays green). Evidence-Ticket: OMN-12957 * fix(OMN-12961): reject typing.Protocol handler targets in ServiceHandlerResolver (#1230) * fix(OMN-12961): reject typing.Protocol handler targets in ServiceHandlerResolver A typing.Protocol used as a handler_routing target is a non-instantiable interface. Its synthetic __init__(*args, **kwargs) exposes only VAR_POSITIONAL/ VAR_KEYWORD params, so the resolver's required-param scan saw zero required params and Step 5 called handler_cls() -> typing raised the anonymous TypeError('Protocols cannot be instantiated') from typing.py:1774, crashing runtime bootstrap with no attribution to the offending contract/handler. Add Step 1a: fail fast on _is_protocol handler_cls BEFORE any instantiation path, with an identifying TypeError naming the handler module.name and owning contract. Mirrors the infra OMN-12501 quarantine guard semantics (which catches this TypeError and quarantines as PROTOCOL_HANDLER_DECLARATION) — the failure stays a TypeError but becomes attributable. Placed after Step 1 so a Protocol handler on a node not hosted here still skips cleanly. TDD: 6 unit tests reproduce the crash and assert attribution + precedence ordering (rejected before container/event_bus probing; exempted by ownership skip). Evidence-Ticket: OMN-12961 * test(OMN-12961): silence CodeQL no-effect on Protocol stub bodies The two Protocol handler stubs in test_service_handler_resolver.py used a trailing `...` Ellipsis as the method body, which CodeQL flags as "Statement has no effect" (alerts 2554/2555) — two unresolved review threads that blocked merge under required_conversation_resolution. Replace the `...` bodies with a one-line docstring (which has an effect: it is the method's __doc__), preserving the Protocol semantics while silencing the false-positive. No behavior change; all 21 resolver unit tests still pass. Evidence-Ticket: OMN-12961 Evidence-Source: OCC#2486 * feat(OMN-13026): transport-mock lint validator — bare AsyncMock/MagicMock on EventBus/transport surfaces (#1231) Adds omnibase_core.validators.transport_mock_lint with 25 unit tests. Detects AsyncMock()/MagicMock() without spec=/spec_set= on EventBus/ transport/kafka mock surfaces (assignment targets, annotated assignments, and keyword arguments). Exports transport-mock-lint pre-commit hook for per-repo wiring. Ratchet baseline mode (--baseline <yaml>) allows activation on repos with existing violations without blocking every PR. Reference incident: PR #1181 bare AsyncMock hid missing EventBusKafka.stop(). Evidence-Ticket: OMN-13026 * fix(OMN-13061): hard-fail on contract_sha256=None in OCC eligibility validator (#1233) The migration window for OMN-10421 closed on 2026-04-30. Receipts with contract_sha256=None were silently passing the OCC merge eligibility gate (lines 184-185: `if receipt.contract_sha256 is None: pass`) — a bypass that diverged from validator_receipt_gate's post-cutoff hard-fail. Fix: replace the silent `pass` with a hard CONTRACT_HASH_MISMATCH failure matching validator_receipt_gate._check_one_receipt behaviour. Uses the shared _CONTRACT_SHA256_REQUIRED_AFTER sentinel for cutoff documentation. Historical corpus ADVISORY scanners (OMN-13060) are unchanged. Test: rename test_missing_contract_hash_is_migration_compatible → test_missing_contract_hash_is_ineligible_post_cutoff with inverted assertions; all 13 tests pass. * feat(OMN-13026): protocol-conformance tests per Protocol + portable _rel_path baseline fix (#1234) - Add tests/unit/validators/test_transport_mock_protocol_conformance.py: 33 tests verifying each transport-surface Protocol (ProtocolEventBusBase, ProtocolEventBus, ProtocolAsyncEventBus, ProtocolEventBusPublisher, ProtocolEventBusSubscriber, ProtocolEventBusLifecycle, ProtocolKafkaClient, ProtocolDispatchBusClientTransport) can be imported and used as AsyncMock/MagicMock spec=, and that the spec correctly rejects nonexistent attributes. - Fix transport_mock_lint.py --write-baseline to emit portable relative paths (via new _rel_path helper) instead of absolute machine-specific paths, making baseline YAML files portable across machines/CIs. DoD: one protocol-conformance test per Protocol defined (OMN-13026). * feat(OMN-12818): url-authority ratchet gate — ValidatorUrlAuthority in omnibase_core (#1232) * feat(OMN-12818): url-authority ratchet gate — ValidatorUrlAuthority in omnibase_core PR-2 of OMN-12803. Ships the canonical ValidatorBase subclass for the url-authority gate so it participates in the ecosystem-wide validation pipeline. Detects three violation classes in Python source: - public-https-literal: quoted https:// URLs to real connection-target hosts - env-url-read: os.environ[*_URL] / os.environ.get(*_ENDPOINT) reads - url-const-assignment: module-level *_URL/*_ENDPOINT constants from env or literal Ratchet (mirrors OMN-12791 receipt-honesty): sha256(repo+path+normalized-snippet) fingerprint; fail only on NEW fingerprints; baseline burn-down only (assert_baseline_ shrinks_only guards against gaming). Baseline = 13 frozen violations across omnibase_core. Migration debt baselined-with-tickets: OMN-12806 (omnibase_core), OMN-12807 (omnibase_infra), OMN-12808 (other repos) — cited, not resolved in this PR. Wired as BLOCKING pre-commit hook (check-url-authority) and required CI workflow (URL Authority Gate) on omnibase_core. 40 dedicated tests; validator self-checks clean through its own gate. Gate probe: RED on synthetic NEW_API_URL literal / GREEN on baselined tip. Evidence-Ticket: OMN-12818 * fix(OMN-12818): resolve 3 CI failures on url-authority gate PR 1. ci.yml: exclude url_authority_baseline.json from detect-secrets scan (sha256 fingerprints triggered Hex High Entropy String false-positive) 2. url-authority-gate.yml: anti-gaming check exits 0 when baseline file is new on this PR (initial introduction — no prior to compare against) 3. yamlfmt: reformat .yaml-validation-allowlist, OMN-12663 contract, url_authority validation contract (pre-commit hook auto-applied) Evidence-Source: OCC#2561 Evidence-Ticket: OMN-12818 * feat(OMN-13091): ModelArtifactRef + ModelSkillResult[T] typed receipt models (#1235) * feat(OMN-13091): ModelArtifactRef + ModelSkillResult[T] receipt models Phase 0b of the skill-output-suppression plan (epic OMN-13089). - Add omnibase_core.models.artifacts.ModelArtifactRef: frozen content-addressed artifact reference enforcing sha256:<64 hex>, with from_bytes() and hex_digest helpers. Single ref type consumed by the artifact store (Phase 1) and later phases. - Add omnibase_core.models.dispatch.ModelSkillResult[T]: generic typed skill dispatch receipt envelope (skill-surface analogue of ModelHandlerOutput[T]) carrying the FULL typed result, concrete result_model FQN for schema identity, metrics, artifact_refs, and schema_version. Exported from models.dispatch. - Resolve duplicate-model-filename collisions surfaced by the validate-no-duplicate-models gate (no allowlist additions): - models/handlers/model_artifact_ref.py -> model_handler_artifact_ref.py (class ModelHandlerArtifactRef; opaque registry ref, internal-only) - models/skill/model_skill_result.py -> model_skill_result_file.py (class ModelSkillResultFile; the OMN-3867 skill-results file contract) - Add SPDX header to empty tests/unit/models/telemetry/__init__.py (pre-existing SPDX gate failure under --all-files). Tests: new unit suites for both models (validation, frozen/extra-forbid contract, JSON round-trip, generic parametrization). * fix(OMN-13091): drop URL literal from ModelHandlerArtifactRef docstring example The module rename moved the docstring's illustrative registry URL out of the url-authority frozen baseline, making it count as a NEW violation. Replace with an opaque registry-scheme example — the field is an opaque source locator, no real endpoint belongs in the example. * feat(OMN-13093): minimal content-addressed ArtifactStore slice (Phase 1) (#1236) * feat(OMN-13093): minimal content-addressed ArtifactStore slice Phase 1 of the skill-output-suppression plan (epic OMN-13089): src/omnibase_core/artifacts/artifact_store.py — write_blob (sha256 content addressing, sharded <root>/<hh>/<full-hex> layout, atomic temp+rename, idempotent on existing hash), JSON metadata sidecar with the artifact-captured required fields + writer_version, hash-verified read_blob, read_meta. Store root from ONEX_ARTIFACT_STORE_ROOT (required env, KeyError on absence). Stdlib + Pydantic only so omniclaude hooks can import it. Parent durable-capture Phase 1 extends this in place (retention/quota, redaction, read-API hardening). * test(OMN-13093): register artifacts module in CI test-selection adjacency map New src/omnibase_core/artifacts/ module needs an adjacency entry or test_every_src_module_has_adjacency_entry fails. No reverse deps yet — downstream consumers (CLI receipt mode, omniclaude hooks) land in Phase 2a/3. * feat(OMN-13098): skill-dispatch receipt-mode validator (Phase 4b) (#1237) Add validate_skill_dispatch_receipt_mode in omnibase_core/validators/ — the enforcement validator for the skill-output-suppression epic (OMN-13089). Four checks on every skill under plugins/onex/skills/: (a) every skill declares skill_kind: dispatch | methodology (explicit, never heuristic); missing/invalid value FAILS; (b) dispatch skills' commands must be the single onex skill / onex delegate receipt-mode form — bare onex (run|node|run-node) FAILS; (c) dispatch skill directories contain markdown only — no *.py, _lib/, or shell scripts (pycache ignored); (d) prompt-instruction consistency — no 'cat workflow_result.json' / 'surface JSON verbatim' instruction in a receipt-mode dispatch; a negation guard tolerates prohibitions ('no cat of workflow_result.json'). Ratchet semantics live in main(): an allowlist tolerates not-yet-migrated skills but FAILS if it grows, if a listed skill is migrated (stale entry) or removed, or if a new skill ships an unreceipted dispatch. Absent allowlist = unconditional gate (the end state). --generate-allowlist regenerates the violation set as a migration aid. Supporting: EnumSkillReceiptRule, ModelSkillDispatchReceiptFinding (models/ validation/), enums/__init__ registration, no-manual-yaml exclude for the validator. File-location validator: Enum* in validation/ carve-out (matches the existing Model*/Protocol* validation/ helper-class allowances) so the pre-existing EnumHonestyRule co-location passes. dod_evidence: - uv run pytest tests/unit/validators/test_skill_dispatch_receipt_mode.py -v => 29 passed (four checks + negation guard + ratchet growth/regression/ stale/absent semantics + generate-allowlist + usage-error exit codes) - uv run mypy src/.../skill_dispatch_receipt_mode.py ... --strict => clean - uv run ruff format/check => clean - end-to-end vs real omniclaude@dev skills tree + committed ratchet => exit 0 - negative: a dispatch skill with bare 'uv run onex run foo' => exit 1 - pre-commit run --files <staged> => all green Evidence-Ticket: OMN-13098 Epic: OMN-13089 (Skill Output Suppression). Plan: docs/plans/2026-06-12-skill-output-suppression-plan.md Phase 4 items 2-4. * ci(OMN-12934): allow ticketed promotion branches to target main * chore(OMN-13131): promote core dev->main for renderer platform release (v0.45.0) (#1260) * feat(OMN-12960): single transport-envelope unwrap predicate + dispatch-surface test gate (#1228) Collapse the two hand-synced marker-key envelope-unwrap predicates (omnibase_infra.runtime.auto_wiring.handler_wiring and omnimarket.nodes.evidence_pipeline_native) into one authoritative source in omnibase_core.utils.util_envelope_unwrap. The two sets had drifted again (infra was missing __bindings vs omnimarket), re-introducing the OMN-12946 defect class on the infra side. Both call sites now import the single source. By layering this wire-level concern belongs in omnibase_compat, but the compat pin is policy-frozen, so per the P1.4 plan it lands in omnibase_core (already a runtime dep of both consumers) with a documented note. Also adds the dispatch-surface-test-required validator: a path-heuristic gate (pre-commit + CI quality-gate) that makes a real-dispatch-path test MANDATORY for any change touching dispatch / routing / handler-registration / message-envelope source surfaces. Handler-isolation tests pass while live dispatch fails — this is the durable ratchet for that defect class. Evidence-Ticket: OMN-12960 * feat(OMN-12957): runtime-profile registry + unregistered/no-consumer-lane validator rules (#1229) Generalizes OMN-12950: a contract could declare any runtime_profiles string, and a nonexistent profile (e.g. [compute]) silently orphaned the node — the auto-wiring ownership filter assigned it to no running runtime, so zero consumer groups, zero errors, empty projection tables. Adds the canonical runtime-profile name registry in omnibase_core (constants_runtime_profiles.REGISTERED_RUNTIME_PROFILES / CONSUMER_ATTACHED_RUNTIME_PROFILES) so contract validation can enforce membership without a core->infra dependency, and extends ValidatorRuntimeProfiles with two new rules: - runtime_profile_unregistered: every declared runtime_profiles value must be in REGISTERED_RUNTIME_PROFILES (catches the OMN-12950 class directly; finds 16 real orphans in omnimarket). - runtime_profile_no_consumer_lane: a subscribing REDUCER/EFFECT must name at least one consumer-attached profile (main/effects/workers) or its subscriptions are never drained — the second silent-orphan class flagged in operator review (manifest-declares-node != consumer-attached). Consumer repos vendor a frozen baseline allowlist at <repo>/validation/runtime_profiles_allowlist.yaml, discovered deterministically by walking up to the pyproject.toml root (no env var — passes the no-new-os.environ gate). The gate blocks NEW orphans; pre-existing ones are frozen and drained via OMN-12982. All 3 rules wire via the existing precommit hook + CI workflow (default contract enables all three; core self-scan stays green). Evidence-Ticket: OMN-12957 * fix(OMN-12961): reject typing.Protocol handler targets in ServiceHandlerResolver (#1230) * fix(OMN-12961): reject typing.Protocol handler targets in ServiceHandlerResolver A typing.Protocol used as a handler_routing target is a non-instantiable interface. Its synthetic __init__(*args, **kwargs) exposes only VAR_POSITIONAL/ VAR_KEYWORD params, so the resolver's required-param scan saw zero required params and Step 5 called handler_cls() -> typing raised the anonymous TypeError('Protocols cannot be instantiated') from typing.py:1774, crashing runtime bootstrap with no attribution to the offending contract/handler. Add Step 1a: fail fast on _is_protocol handler_cls BEFORE any instantiation path, with an identifying TypeError naming the handler module.name and owning contract. Mirrors the infra OMN-12501 quarantine guard semantics (which catches this TypeError and quarantines as PROTOCOL_HANDLER_DECLARATION) — the failure stays a TypeError but becomes attributable. Placed after Step 1 so a Protocol handler on a node not hosted here still skips cleanly. TDD: 6 unit tests reproduce the crash and assert attribution + precedence ordering (rejected before container/event_bus probing; exempted by ownership skip). Evidence-Ticket: OMN-12961 * test(OMN-12961): silence CodeQL no-effect on Protocol stub bodies The two Protocol handler stubs in test_service_handler_resolver.py used a trailing `...` Ellipsis as the method body, which CodeQL flags as "Statement has no effect" (alerts 2554/2555) — two unresolved review threads that blocked merge under required_conversation_resolution. Replace the `...` bodies with a one-line docstring (which has an effect: it is the method's __doc__), preserving the Protocol semantics while silencing the false-positive. No behavior change; all 21 resolver unit tests still pass. Evidence-Ticket: OMN-12961 Evidence-Source: OCC#2486 * feat(OMN-13026): transport-mock lint validator — bare AsyncMock/MagicMock on EventBus/transport surfaces (#1231) Adds omnibase_core.validators.transport_mock_lint with 25 unit tests. Detects AsyncMock()/MagicMock() without spec=/spec_set= on EventBus/ transport/kafka mock surfaces (assignment targets, annotated assignments, and keyword arguments). Exports transport-mock-lint pre-commit hook for per-repo wiring. Ratchet baseline mode (--baseline <yaml>) allows activation on repos with existing violations without blocking every PR. Reference incident: PR #1181 bare AsyncMock hid missing EventBusKafka.stop(). Evidence-Ticket: OMN-13026 * fix(OMN-13061): hard-fail on contract_sha256=None in OCC eligibility validator (#1233) The migration window for OMN-10421 closed on 2026-04-30. Receipts with contract_sha256=None were silently passing the OCC merge eligibility gate (lines 184-185: `if receipt.contract_sha256 is None: pass`) — a bypass that diverged from validator_receipt_gate's post-cutoff hard-fail. Fix: replace the silent `pass` with a hard CONTRACT_HASH_MISMATCH failure matching validator_receipt_gate._check_one_receipt behaviour. Uses the shared _CONTRACT_SHA256_REQUIRED_AFTER sentinel for cutoff documentation. Historical corpus ADVISORY scanners (OMN-13060) are unchanged. Test: rename test_missing_contract_hash_is_migration_compatible → test_missing_contract_hash_is_ineligible_post_cutoff with inverted assertions; all 13 tests pass. * feat(OMN-13026): protocol-conformance tests per Protocol + portable _rel_path baseline fix (#1234) - Add tests/unit/validators/test_transport_mock_protocol_conformance.py: 33 tests verifying each transport-surface Protocol (ProtocolEventBusBase, ProtocolEventBus, ProtocolAsyncEventBus, ProtocolEventBusPublisher, ProtocolEventBusSubscriber, ProtocolEventBusLifecycle, ProtocolKafkaClient, ProtocolDispatchBusClientTransport) can be imported and used as AsyncMock/MagicMock spec=, and that the spec correctly rejects nonexistent attributes. - Fix transport_mock_lint.py --write-baseline to emit portable relative paths (via new _rel_path helper) instead of absolute machine-specific paths, making baseline YAML files portable across machines/CIs. DoD: one protocol-conformance test per Protocol defined (OMN-13026). * feat(OMN-12818): url-authority ratchet gate — ValidatorUrlAuthority in omnibase_core (#1232) * feat(OMN-12818): url-authority ratchet gate — ValidatorUrlAuthority in omnibase_core PR-2 of OMN-12803. Ships the canonical ValidatorBase subclass for the url-authority gate so it participates in the ecosystem-wide validation pipeline. Detects three violation classes in Python source: - public-https-literal: quoted https:// URLs to real connection-target hosts - env-url-read: os.environ[*_URL] / os.environ.get(*_ENDPOINT) reads - url-const-assignment: module-level *_URL/*_ENDPOINT constants from env or literal Ratchet (mirrors OMN-12791 receipt-honesty): sha256(repo+path+normalized-snippet) fingerprint; fail only on NEW fingerprints; baseline burn-down only (assert_baseline_ shrinks_only guards against gaming). Baseline = 13 frozen violations across omnibase_core. Migration debt baselined-with-tickets: OMN-12806 (omnibase_core), OMN-12807 (omnibase_infra), OMN-12808 (other repos) — cited, not resolved in this PR. Wired as BLOCKING pre-commit hook (check-url-authority) and required CI workflow (URL Authority Gate) on omnibase_core. 40 dedicated tests; validator self-checks clean through its own gate. Gate probe: RED on synthetic NEW_API_URL literal / GREEN on baselined tip. Evidence-Ticket: OMN-12818 * fix(OMN-12818): resolve 3 CI failures on url-authority gate PR 1. ci.yml: exclude url_authority_baseline.json from detect-secrets scan (sha256 fingerprints triggered Hex High Entropy String false-positive) 2. url-authority-gate.yml: anti-gaming check exits 0 when baseline file is new on this PR (initial introduction — no prior to compare against) 3. yamlfmt: reformat .yaml-validation-allowlist, OMN-12663 contract, url_authority validation contract (pre-commit hook auto-applied) Evidence-Source: OCC#2561 Evidence-Ticket: OMN-12818 * feat(OMN-13091): ModelArtifactRef + ModelSkillResult[T] typed receipt models (#1235) * feat(OMN-13091): ModelArtifactRef + ModelSkillResult[T] receipt models Phase 0b of the skill-output-suppression plan (epic OMN-13089). - Add omnibase_core.models.artifacts.ModelArtifactRef: frozen content-addressed artifact reference enforcing sha256:<64 hex>, with from_bytes() and hex_digest helpers. Single ref type consumed by the artifact store (Phase 1) and later phases. - Add omnibase_core.models.dispatch.ModelSkillResult[T]: generic typed skill dispatch receipt envelope (skill-surface analogue of ModelHandlerOutput[T]) carrying the FULL typed result, concrete result_model FQN for schema identity, metrics, artifact_refs, and schema_version. Exported from models.dispatch. - Resolve duplicate-model-filename collisions surfaced by the validate-no-duplicate-models gate (no allowlist additions): - models/handlers/model_artifact_ref.py -> model_handler_artifact_ref.py (class ModelHandlerArtifactRef; opaque registry ref, internal-only) - models/skill/model_skill_result.py -> model_skill_result_file.py (class ModelSkillResultFile; the OMN-3867 skill-results file contract) - Add SPDX header to empty tests/unit/models/telemetry/__init__.py (pre-existing SPDX gate failure under --all-files). Tests: new unit suites for both models (validation, frozen/extra-forbid contract, JSON round-trip, generic parametrization). * fix(OMN-13091): drop URL literal from ModelHandlerArtifactRef docstring example The module rename moved the docstring's illustrative registry URL out of the url-authority frozen baseline, making it count as a NEW violation. Replace with an opaque registry-scheme example — the field is an opaque source locator, no real endpoint belongs in the example. * feat(OMN-13093): minimal content-addressed ArtifactStore slice (Phase 1) (#1236) * feat(OMN-13093): minimal content-addressed ArtifactStore slice Phase 1 of the skill-output-suppression plan (epic OMN-13089): src/omnibase_core/artifacts/artifact_store.py — write_blob (sha256 content addressing, sharded <root>/<hh>/<full-hex> layout, atomic temp+rename, idempotent on existing hash), JSON metadata sidecar with the artifact-captured required fields + writer_version, hash-verified read_blob, read_meta. Store root from ONEX_ARTIFACT_STORE_ROOT (required env, KeyError on absence). Stdlib + Pydantic only so omniclaude hooks can import it. Parent durable-capture Phase 1 extends this in place (retention/quota, redaction, read-API hardening). * test(OMN-13093): register artifacts module in CI test-selection adjacency map New src/omnibase_core/artifacts/ module needs an adjacency entry or test_every_src_module_has_adjacency_entry fails. No reverse deps yet — downstream consumers (CLI receipt mode, omniclaude hooks) land in Phase 2a/3. * feat(OMN-13098): skill-dispatch receipt-mode validator (Phase 4b) (#1237) Add validate_skill_dispatch_receipt_mode in omnibase_core/validators/ — the enforcement validator for the skill-output-suppression epic (OMN-13089). Four checks on every skill under plugins/onex/skills/: (a) every skill declares skill_kind: dispatch | methodology (explicit, never heuristic); missing/invalid value FAILS; (b) dispatch skills' commands must be the single onex skill / onex delegate receipt-mode form — bare onex (run|node|run-node) FAILS; (c) dispatch skill directories contain markdown only — no *.py, _lib/, or shell scripts (pycache ignored); (d) prompt-instruction consistency — no 'cat workflow_result.json' / 'surface JSON verbatim' instruction in a receipt-mode dispatch; a negation guard tolerates prohibitions ('no cat of workflow_result.json'). Ratchet semantics live in main(): an allowlist tolerates not-yet-migrated skills but FAILS if it grows, if a listed skill is migrated (stale entry) or removed, or if a new skill ships an unreceipted dispatch. Absent allowlist = unconditional gate (the end state). --generate-allowlist regenerates the violation set as a migration aid. Supporting: EnumSkillReceiptRule, ModelSkillDispatchReceiptFinding (models/ validation/), enums/__init__ registration, no-manual-yaml exclude for the validator. File-location validator: Enum* in validation/ carve-out (matches the existing Model*/Protocol* validation/ helper-class allowances) so the pre-existing EnumHonestyRule co-location passes. dod_evidence: - uv run pytest tests/unit/validators/test_skill_dispatch_receipt_mode.py -v => 29 passed (four checks + negation guard + ratchet growth/regression/ stale/absent semantics + generate-allowlist + usage-error exit codes) - uv run mypy src/.../skill_dispatch_receipt_mode.py ... --strict => clean - uv run ruff format/check => clean - end-to-end vs real omniclaude@dev skills tree + committed ratchet => exit 0 - negative: a dispatch skill with bare 'uv run onex run foo' => exit 1 - pre-commit run --files <staged> => all green Evidence-Ticket: OMN-13098 Epic: OMN-13089 (Skill Output Suppression). Plan: docs/plans/2026-06-12-skill-output-suppression-plan.md Phase 4 items 2-4. * docs(OMN-13182): refresh omnibase_core documentation (#1241) - Replace Poetry references with uv in installation.md (Poetry was listed as Method 1/recommended; project uses uv exclusively) - Fix "Always use Poetry" design rule in docs/INDEX.md to "Always use uv" - Add 15 missing top-level source modules to Package Structure in INDEX.md (artifacts/, dispatch/, doctor/, event_bus/, gate/, adapters/, agents/, analysis/, discovery/, navigation/, normalization/, overlays/, validators/, workflows/) - Remove all 6 references to deleted EnvelopeRouter/runtime_envelope_router.py in onex_terminology.md (deleted OMN-12526/v0.43.0); update to RuntimeMessageDispatch + RuntimeHandlerRegistry - Add onex-demo-path-topic-gate CLI entrypoint to VALIDATION_OWNERSHIP.md (OMN-12777, present in pyproject.toml since v0.44.0 but missing from doc) - Add section listing 6 pre-commit/CI-only validators shipped since April 24: ValidatorUrlAuthority (OMN-12818), ValidatorReceiptHonesty (OMN-12791), ValidatorRuntimeProfiles (OMN-12957), gitignore_baseline (OMN-12452), transport-mock lint (OMN-13026), skill-dispatch receipt-mode (OMN-13098) - Add CHANGELOG entries for v0.44.0/v0.44.1/v0.44.2 (all three tagged and shipped but had zero CHANGELOG entries) - Add 5 missing subsystem rows to CLAUDE.md Architecture Extensions table: ArtifactStore (OMN-13093), Dispatch Bus Client, Doctor Health Checks, In-Memory Event Bus, OmniGate (OMN-11137/11139/11140) Parent: OMN-13172 All changes AI-generated. * refactor(OMN-13189): delete dead ModelOnexEnvelopeV1 — completes OMN-4152 (#1242) Remove ModelOnexEnvelopeV1 (zero production callers, zero test imports across omnibase_core/omnibase_infra/omnimarket src+tests). Deletes the class file, both export lines in models/core/__init__.py, and the 3 predecessor mentions in model_onex_envelope.py that reference the now-deleted class. Completes OMN-4152 (Task 6: Retire ModelOnexEnvelopeV1) — verification confirmed V1 fully dead, so this deletes it outright rather than retaining for backward- compat deserialization. grep -rn ModelOnexEnvelopeV1 src/ tests/ => zero. * refactor(OMN-13192): migrate sole live ModelOnexEnvelope constructor to ModelEventEnvelope[ModelEventPublishIntent] (#1245) Retarget the one production ModelOnexEnvelope(...) constructor at mixin_intent_publisher.py to ModelEventEnvelope[ModelEventPublishIntent](...), publishing the TYPED ModelEventPublishIntent as the envelope payload (not a serialized dict). Field remap: source_node->source_tool, timestamp->envelope_timestamp, drop operation, payload=intent (typed). This leaves ZERO live ModelOnexEnvelope constructor calls in src/ so B4 can delete the class. The class definition and its docstring examples in model_onex_envelope.py are untouched (B4 scope). Verification REFUTED the 'Kafka consumers will break' framing: there are NO Kafka consumers of onex.runtime.intents. IntentExecutor is a synchronous runtime service (not a topic listener) and MixinIntentPublisher has zero production call sites. This is a type-correctness + test change only; there is no consumer-node migration. Tests updated to assert the new ModelEventEnvelope wire shape and a serialize->deserialize round-trip. The strict ModelEventEnvelope[ModelEventPublishIntent] cannot reconstruct from JSON because ModelEventPublishIntent.target_event_payload is a ModelEventPayloadUnion whose before-validator rejects the plain dict JSON decoding yields (no discriminator) -- a pre-existing property of the intent model, so the round-trip is asserted on the generic ModelEventEnvelope (payload preserved as a mapping). Evidence-Source: OCC#PENDING Evidence-Ticket: OMN-13192 * chore(OMN-13187): refresh core dependency pins (#1246) * refactor(OMN-13194): re-annotate envelope_validator.py from ModelOnexEnvelope to ModelEventEnvelope[Any] (#1248) B3 of the platform-debt envelope-dedup plan (docs/plans/2026-06-16-platform-debt-contract-topics-and-envelope-dedup-plan.md). Re-annotates the 4 ModelOnexEnvelope sites in src/omnibase_core/validation/envelope_validator.py to ModelEventEnvelope[Any]: - TYPE_CHECKING import -> omnibase_core.models.events.model_event_envelope - validate / _validate_structure / _validate_payload parameter annotations The 2 prose docstring mentions are updated too so the module references zero ModelOnexEnvelope. ModelEventEnvelope[T] is a PEP 695 generic, so [Any] is valid. Annotation-only: the validator reads every field via getattr(envelope, ..., None) (duck-typed), so no runtime code path changes. Does NOT delete ModelOnexEnvelope (B4 / OMN-13196 scope). Predecessor B2 (OMN-13192, PR #1245) merged to dev (a84bb24). dod_evidence: - grep: zero ModelOnexEnvelope in envelope_validator.py - mypy --strict envelope_validator.py: Success, no issues - focused suite tests/unit/validation/test_envelope_validator.py: 40 passed, 4 skipped - full pytest tests/ -n auto (no -k): 41739 passed; the 1 perf flake (test_source_node_id_overhead round-trip overhead under 16-way load) passes in isolation (1.39s) and does not reference the validator - pre-commit run --all-files: all hooks pass * chore(OMN-13195): bump validate-boundaries action pin (#1249) * feat(OMN-12804): non-model URL contract authority — integration catalog + design doc (#1251) Part 2A/2B of OMN-12803 URL-authority epic. OMN-12818 shipped the gate (ValidatorUrlAuthority); this PR completes the design by establishing the canonical authority surface for non-model URLs. ## Design (Part 2A): two authority surfaces ONEX now has exactly two URL authority surfaces: 1. **Model/inference routing** — `configs/bifrost_delegation.yaml` (omnimarket/omniclaude). Owns LLM backend URLs and inference endpoints. 2. **Non-model integration endpoints** — `contracts/integrations/catalog.yaml` (this repo, new in this PR). Owns GitHub API, Linear GraphQL, OpenRouter non-inference, projection API, bus bootstrap, dashboard data sources, and all other URLs that are NOT LLM inference endpoints. The validator `_AUTHORITY_PATH_SUFFIXES` already exempts `contracts/integrations/catalog.yaml` from the gate (URLs inside the authority file are canonical, not violations). ## Deliverables - `src/omnibase_core/contracts/integrations/catalog.yaml` — non-model URL authority (schema v1.0.0, `catalog_version: {major: 1, minor: 0, patch: 0}`). Entries: `github.rest_api`, `linear.graphql_api`, `openrouter.completions`, `projection_api.base`, `bus.redpanda_schema_registry`, `bus.kafka_bootstrap`, `dashboard.data_source`, `infisical.addr`, `deployment.callback_url`. - `docs/architecture/URL_CONTRACT_AUTHORITY.md` — design doc covering both authority surfaces, resolution contract, catalog schema, gate rules, and cross-repo wiring pattern. - `tests/unit/validation/test_validator_url_authority.py` — 9 new catalog structure tests (TestIntegrationCatalogStructure): file existence, YAML validity, semver format, required categories, entry completeness, authority path allowlist match, required external API entries. ## Gate status url-authority gate: PASSED (0 new violations, 13 grandfathered from OMN-12818 baseline). Cross-repo wiring to omnibase_infra (48 violations to baseline) is tracked by OMN-12807 and will land as a follow-on PR to that repo. Evidence-Ticket: OMN-12804 * refactor(OMN-13196): delete ModelOnexEnvelope (B4) + retarget validator test (#1250) B4 of the platform-debt envelope-dedup plan. Deletes the legacy ModelOnexEnvelope class entirely and collapses the canonical envelope surface to ModelEventEnvelope[T]. Changes: - Delete src/omnibase_core/models/core/model_onex_envelope.py (the class whose docstring falsely self-described as "the canonical envelope format"; 1 live constructor migrated in B2/OMN-13192, 4 validator annotations re-annotated in B3/OMN-13194, V1 retired in B1/OMN-13193). - Remove the 2 exports (import + __all__) in models/core/__init__.py. - Delete the 4 ModelOnexEnvelope-specific test files: test_model_onex_envelope.py, test_model_onex_envelope_source_node_id.py, test_model_onex_envelope_chunking.py, and the perf benchmark test_source_node_id_overhead.py — these exercised ModelOnexEnvelope's own fields (source_node_id, chunking, operation) which have no ModelEventEnvelope equivalent, so they retire with the class. - Retarget tests/unit/validation/test_envelope_validator.py: EnvelopeValidator survives (it is duck-typed via getattr) but ModelEventEnvelope[T] lacks the dispatch-routing fields (source_node/operation/target_node) the validator reads. Replace the ModelOnexEnvelope fixture with a minimal frozen Pydantic stub (_ValidatorEnvelope) exposing exactly those attributes. 40/40 pass. - Retarget stale docstring/comment references to the deleted class in model_envelope_metadata.py, model_chunked_envelope.py, type_serializable_value.py, and the mixin_metadata.yaml `requires` entry (which pointed at the already-wrong models.events.model_onex_envelope path) to ModelEventEnvelope. dod_evidence: - grep -rniE 'ModelOnexEnvelope|model_onex_envelope' src/ tests/ -> ZERO - ruff format + ruff check --fix: All checks passed - mypy src/ --strict: no NEW errors (3 pre-existing errors in untouched contract_loader.py / cli_install.py reproduce on clean origin/dev) - pytest tests/unit/validation/test_envelope_validator.py: 40 passed - FULL pytest tests/ -n 8 (no -k): 41576 passed; the 21 failures are full-suite-only xdist ordering flakes (RegistryNode forward-ref model_rebuild + DI-singleton contamination) that ALL pass in isolation (48/48) and reference neither envelopes nor any file in this diff. OMN-13196 * chore(OMN-13200): bump omnibase_core to v0.45.0 (B6 — envelope-dedup pin propagation) (#1252) Final phase of the platform-debt envelope-dedup workstream. ModelOnexEnvelope was deleted from the public API in B4 (PR #1250, merged to dev). This bumps the omnibase_core version to propagate the breaking-deletion signal to dependents and trigger pin-update bot PRs. - pyproject version 0.44.2 -> 0.45.0 (minor bump: pre-1.0 semver convention for a breaking public-API deletion; pyproject is the single source of truth) - uv.lock self-version updated to match - CHANGELOG entry under Breaking Changes Verification on origin/dev HEAD (e9bb51aac): - grep ModelOnexEnvelope over src/ + tests/ -> 0 references (class fully gone) - mypy src/omnibase_core (CI-canonical strict gate) -> Success, no issues - pytest tests/unit/validation/test_envelope_validator.py + tests/unit/mixins/test_mixin_intent_publisher.py -> 67 passed dod_evidence: contracts/OMN-13200.yaml (OCC receipt, verifier!=runner) * refactor(OMN-13197): remove dead onex.runtime.intents hardcoded topic + dead intent-publisher path (#1253) A-followup of OMN-13188 (OMN-12803 topic-authority family). Removes the `onex.runtime.intents` hardcoded topic at its root by deleting the dead publisher path that was its sole consumer. Decision (per OMN-13197 DoD: contract-source the topic OR confirm-and-delete the dead path): confirm-and-delete. The topic could not be contract-sourced — no contract declares it (the `intent_publisher.yaml` referenced in the mixin docstring was never authored) and `ServiceTopicRegistry` lives in omnibase_infra (core cannot import it per layering). The mechanism was architecturally dead from both sides: - MixinIntentPublisher (sole publisher) had ZERO production call sites. - onex.runtime.intents had ZERO Kafka consumers (IntentExecutor is a synchronous in-memory runtime service, verified in OMN-13192/OMN-13188). Dead code is debt to delete, not park/guard/migrate. Removed: - TOPIC_EVENT_PUBLISH_INTENT (duplicate of canonical TOPIC_RUNTIME_INTENTS, existed only to feed the dead mixin) + all re-exports. - MixinIntentPublisher + ModelIntentPublishResult (only used by the mixin) + their capability-mapping / metadata census entries. - Dead tests + fixtures + intent-publisher guide docs (with inbound links). Retained: TOPIC_RUNTIME_INTENTS (canonical taxonomy derivation) and ModelEventPublishIntent (live consumer in util_payload_migration). Added regression guard test asserting the dead symbols stay removed. dod_evidence: ruff format+check clean; mypy --strict clean on all changed files (6 pre-existing errors in untouched files only); 171 focused tests green incl. new guard; full collection (1389 tests) imports clean; pre-commit run all-green (markdown-links pass, skill-routing pass vs omniclaude main snapshot). * feat(OMN-13209): promote runtime-deployment wire DTOs (EnumRuntimeLane + ModelRuntimeDeploymentProof) to core (#1254) A2 (canonical node migration, epic OMN-13205): graduate the runtime-deployment lane enum and deployment-proof wire DTO from the transient omnibase_compat mirror to their canonical core home, per the compat copy's COMPAT_MIGRATION_TARGET and the >=2-repos graduation condition (node_redeploy is now a 2nd-repo importer). - omnibase_core.enums.enum_runtime_lane.EnumRuntimeLane (UtilStrValueHelper enum, file-location convention) - omnibase_core.models.runtime_deployment.wire.ModelRuntimeDeploymentProof + ProbeStatus/DeploymentProofStatus aliases, re-exporting the enum Path note: the plan cited contracts.runtime_deployment.wire, but Pydantic BaseModels under any non-exempt namespace trip core's disallow_any_explicit mypy gate (documented in mypy.ini for pipeline/hooks/package). Wire DTOs live under models.* (the established graduated-wire home, cf. models.delegation.wire from OMN-12126); enums under enums.* per the file-location validator. Promoted from the compat copy (not authored fresh from node files). * feat(OMN-13130): UI contract primitives + EnumEmptyStateReason in omnibase_core (#1255) * feat(OMN-13130): UI contract primitives + EnumEmptyStateReason in omnibase_core Phase 0 of the Contract-Driven UI Platform (epic OMN-13129). Adds six frozen Pydantic UI contract primitives (additive over ModelWidgetConfig) plus the empty-state vocabulary and supporting capability enums. Models (src/omnibase_core/models/dashboard/, one file each): - ModelComponentContract — composes the other primitives; component_kind reuses EnumWidgetType - ModelActionContract — declared onex.cmd.* emitter; COMPOSES ModelGate (approval), no duplication - ModelDataBindingContract — /projection/{topic} bind with explicit ordering authority; no raw DB - ModelPermissionContract — view/act scopes + mandatory declared disabled_reason - ModelEvidenceRequirementContract — composes OCC ModelEvidenceRequirement - ModelRendererCapabilityContract — model only (omnimarket reducer/topic is Phase 1; no node) Enums (src/omnibase_core/enums/): - EnumEmptyStateReason — exactly four values mirroring omnidash/shared/types/chart-config.ts - EnumBindingOrderDirection, EnumEvidenceGateMoment, EnumRendererInteractionModel, EnumAccessibilityTier ActionContract.command_topic is validated via the canonical validate_topic_suffix (no hardcoded onex.cmd. literal) and requires kind == TOPIC_KIND_CMD. Version fields use ModelSemVer (strong typing). All six models registered in scripts/emit_ts_types.py for Stage 2 TS codegen. ModelGate / ModelGateSpec source untouched (ADR D2). Refs: OMN-13130, epic OMN-13129. ADR: docs/adr/2026-06-17-ui-deterministic-projection-effect-layer.md * fix(OMN-13130): use canonical interfaces_touched enum (public_api) in DoD contract contract-validation CI rejected free-text interfaces_touched values; the field is a closed enum (events/topics/protocols/envelopes/public_api). The touched surface is the new public API exports -> public_api. * feat(OMN-13132): Contract Graph IR + read-only import (#1256) * feat(OMN-13132): Contract Graph IR + read-only import Phase 2 of the Contract-Driven UI Platform (epic OMN-13129). Adds the canonical read-only Contract Graph IR to omnibase_core plus dialect adapters that import backend node contracts and Phase-0 UI component contracts into one deterministic IR, with a no-op round-trip proven zero-semantic-diff through the shipped cli_contract_diff spine. Name-collision handling (plan §8: IR models are distinct from workflow-viz graph models): new IR models live in the distinct models/contract_graph/ namespace with ModelContractGraph* names (ModelContractGraphIr/Node/Edge/ Protocol/ContractRef/SourceSet) — the bare ModelGraphNode/ModelGraphEdge (models/graph/) and ModelContractRef (models/events/contract_validation/) identifiers are NOT reused. - Models: 6 frozen Pydantic IR models (frozen, extra=forbid, from_attributes) + EnumContractGraphNodeRole (incl renderer) + EnumContractGraphEdgeKind (incl component_renders/action_emits/data_binds). - Adapters (read-only): node-contract + ui-component dialect adapters; manifest-driven discovery excluding .venv/omni_worktrees/generated. - Hashing: sha256 over canonicalized contract bytes (per source) + stable per-adapter version hash, both embedded in the IR. - Round-trip: IR -> canonical normalized contract form; no-op round-trip = zero semantic diff via cli_contract_diff (reused, not rebuilt). - Tests: 29 unit tests incl deterministic-IR over >=2 real contracts (effect + reducer node contracts + 1 UI component) and no-op round-trip zero-diff. Strictly read-only: no authoring UI, no contract mutation. Refs: OMN-13132, epic OMN-13129. * fix(OMN-13132): register contract_graph in test-selection adjacency + revert OMN-13130 scope bleed - Add contract_graph adjacency entry (leaf module, reverse_deps: []) so test_every_src_module_has_adjacency_entry passes. contract_graph imports models/enums/cli (already shared_modules) and types; types.reverse_deps now includes contract_graph so a types change re-runs contract_graph tests. - Revert contracts/OMN-13130.yaml to origin/dev (unrelated whitespace-only line-wrap edit was scope bleed; diff vs origin/dev is now empty). Fixes the only red CI signal on PR #1256; contract_graph IR code unchanged. * fix(OMN-13214): port hardened arm+update-branch+enqueue+verify auto-merge flow (#1257) * fix(OMN-13214): port hardened arm+update-branch+enqueue+verify auto-merge flow to omnibase_core Ports the OMN-13214 armed-but-not-enqueued fix from omnimarket (PR #1253, merge 8fad5e11) into omnibase_core. Root cause: arming auto-merge is NOT the same as enqueuing. On queue-controlled dev, a CLEAN + all-required-green + armed PR can sit OUTSIDE the merge queue indefinitely. The old workflow also passed `--auto --squash`, which dev's queue REJECTS ("The merge strategy for dev is set by the merge queue"), so the PR was never enqueued. The old "Force enqueue" step never verified the PR actually entered the queue. Changes: - .github/workflows/auto-merge.yml: - "Enable auto-merge" now arms bare `--auto` (was `--auto --squash`) and falls through instead of exiting on success. - Replaces "Force enqueue" with "Enqueue armed PR and verify it entered the queue": classify -> (update-branch on strict-update BEHIND) -> enqueue -> poll-and-VERIFY isInMergeQueue, failing loudly if a green+armed PR is not enqueued. Preserves this repo's pre-check fanout guard, self-hosted runner selection, and OCC preflight. - scripts/ci/merge_queue_enqueue.py: stdlib-only, no-network classify/verify decision helper (mypy --strict clean; explicit-Any-free via dict[str, object]). - tests/unit/scripts/ci/test_merge_queue_enqueue.py: 32 unit tests pinning the CLEAN-armed-not-queued -> ENQUEUE bug, ALREADY_QUEUED no-op, BEHIND strict vs non-strict, WAIT/BLOCKED states, verify, and error-marker classification. Verification: 32/32 tests pass; mypy --strict clean; ruff clean; actionlint clean on the new steps; full omnibase_core pre-commit suite green (40 hooks). The one skipped local hook (validate-deterministic-skill-routing) scans omniclaude-owned SKILL.md files via a sibling clone; its 16 violations pre-exist on omniclaude@dev, are unrelated to this PR (no SKILL.md touched), and the check is NOT a required status check on omnibase_core dev. OMN-13214 * test(OMN-13214): update auto-merge workflow-shape test for arm+enqueue+verify flow The existing test_auto_merge_workflow_shape.py pinned the old step name "Force enqueue to merge queue". The OMN-13214 port renamed it to "Enqueue armed PR and verify it entered the queue" and changed "Enable auto-merge" from --auto --squash to bare --auto. - Point the ordering assertion at the new enqueue step name. - Add test_enable_auto_merge_arms_bare_auto_not_squash: the gh pr merge command arms bare --auto (no --squash). - Add test_enqueue_step_classifies_enqueues_and_verifies: the enqueue step classifies + verifies via scripts/ci/merge_queue_enqueue.py, calls enqueuePullRequest, runs gh pr update-branch, and fails loudly (::error::). OMN-13214 * fix(OMN-13214): make merge_queue_enqueue.main() returns explicit (CodeQL) CodeQL flagged "explicit returns mixed with implicit (fall through) returns" in main(). Restructure the command dispatch as if/elif/else where the defensive else raises SystemExit, so every branch terminates with an explicit return or raise (no implicit None fall-through). mypy --strict + ruff + 32 unit tests remain green. OMN-13214 * feat(OMN-13219): canonical-inference enforcement gate (pre-commit + required CI) (#1258) * feat(OMN-13219): canonical-inference enforcement gate (pre-commit + required CI) Adds ValidatorCanonicalInference — a ratchet gate wired as a pre-commit hook and a required CI status check (parallel to the OMN-12818 URL-authority gate) that fails on non-canonical model-inference surfaces: - model-cli-shellout: a model-CLI binary (codex/claude/gemini/opencode) passed to subprocess/exec/os.system or resolved via shutil.which — the exact non-canonical surface OMN-13215 shipped and nothing caught. - model-id-env-read: os.environ[*_MODEL] / os.environ.get(*_PROVIDER) reads. Endpoint URLs and *_URL/*_ENDPOINT env reads remain owned by the URL-authority gate (OMN-12818); freestanding imperative IO generally by scan_freestanding_imperative_io (OMN-12515/12540). No parallel one-off — the three guards partition the space. Fail-closed regression test: a NEW shell-out and a NEW env-resolved model each trip the gate (exit 1); the contract-resolved tier (OMN-13215 target shape) passes. Ratchet baseline (sha256 fingerprints) grandfathers existing violations; omnibase_core seeds at 0 (clean). Burn-down only — CI rejects baseline growth. codex shell-out removal tracked by OMN-13215. Evidence-Source: OCC#PENDING Evidence-Ticket: OMN-13219 * fix(OMN-13219): use env suffix constant in inference validator * ci(OMN-13131): adopt main's permissive main-target-guard on the promotion branch The pull_request main-target-guard runs the workflow definition from the PR head tree. dev's guard is the restrictive (dev-only) OMN-12477 version; main already carries the permissive (dev || promotion/*) version from #1240. A promotion/* head therefore fails the dev-tree restrictive guard. Adopting main's permissive guard on the promotion branch lets the promotion/* head pass; net diff to main is zero (main already has this exact file). dev->main promotion via promotion/* is the sanctioned shape (memory: dev-only-promotion-to-main + #1240 precedent). Evidence-Ticket: OMN-13131 promotion-receipt: OCC-2742 * ci(OMN-13332): pin occ-preflight to Evidence-Source OCC SHA (#1344) * ci(OMN-13332): pin occ-preflight evidence source * ci(OMN-13332): refresh occ-preflight promotion checks --------- Co-authored-by: jonahgabriel <jonah.neugass@gmail.com> --------- Co-authored-by: jonahgabriel <jonah.neugass@gmail.com>
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.
OMN-13131 — promote omnibase_core dev -> main for renderer platform release (v0.45.0)
Promotes the current omnibase_core dev lane to main so the contract-driven UI / renderer platform (OMN-13129 Phase-1) can build from released core models. origin/dev is ahead of origin/main by 25 commits; this PR brings main to dev HEAD c281fbb and unblocks the v0.45.0 release + OMN-13221 (omnibase_spi renderer/capability protocols) which pins the released core.
promotion-receipt: OCC-2743
Evidence-Ticket: OMN-13131
Evidence-Source: a56001acc43897f875dafaf09c116c3cfea39cc4
Scope
Evidence
Release (tag v0.45.0 -> PyPI publish + GitHub Release) follows on merge to main.