Repository navigation
backmerge(OMN-12245): delegation projection counts hotfix - #934
Conversation
| if not value: | ||
| _logger.warning( | ||
| "api_key_ref=%s declared but env var is unset; proceeding without api_key", | ||
| ref, |
| for subtask in wave_subtasks: | ||
| if any(dep in failed_ids for dep in subtask.depends_on): | ||
| all_dispatches.append( | ||
| ModelSwarmDispatch( |
| total_deadline = time.monotonic() + config.total_run_timeout_seconds | ||
| all_dispatches: list[ModelSwarmDispatch] = [] | ||
| failed_ids: set[str] = set() | ||
| wall_start = time.monotonic() |
| } | ||
| ) | ||
|
|
||
| _VALID_FORMATS = frozenset({"markdown", "json"}) |
| # Request / Response models | ||
| # --------------------------------------------------------------------------- | ||
|
|
||
| _VALID_MODES = frozenset( |
| "number": str(parsed["number"]), | ||
| "repo": str(parsed.get("repo", "")), | ||
| } | ||
| except json.JSONDecodeError: |
|
|
||
| # Keep _DEFAULT_FLOWS as a backwards-compatible alias (same objects — stubs | ||
| # carry safe zero-value defaults so pure-compute tests keep passing). | ||
| _DEFAULT_FLOWS = _DEFAULT_FLOW_STUBS |
| from omnimarket.cli.commands import ( # noqa: E402 | ||
| trace as _trace_commands, # noqa: F401 # registers trace group via @market.group decorator | ||
| ) |
| from omnimarket.cli.commands import ( # noqa: E402 | ||
| trace as _trace_commands, # noqa: F401 # registers trace group via @market.group decorator | ||
| ) |
| import click | ||
| import httpx | ||
|
|
||
| from omnimarket.cli.market import market |
|
Warning Review limit reached
More reviews will be available in 20 minutes and 49 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe PR adds branch-target enforcement, expands delegation and swarm orchestration behavior, introduces trace and persistence tooling, adds many new node contracts and stub packages, implements correctness and sweep features, migrates swarm fanout to an orchestrator, and refreshes packaging, evidence, and dep-health baseline artifacts. ChangesOmniMarket runtime and node expansion
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/omnimarket/nodes/node_ci_watch/handlers/handler_ci_watch.py (1)
143-158:⚠️ Potential issue | 🟠 Major | ⚡ Quick winTransport errors are currently reported as
PASSED.
_fetch_ci_status()returns([], "...error...")whengh pr checksfails or its output is unreadable, and this branch treats any emptyfailed_checkslist as green. That turns GitHub auth failures, CLI errors, and transient outages into a falsePASSEDresult and skips the auto-fix path entirely.Return an explicit error outcome from
_fetch_ci_status()(or raise) and map it toEnumCiTerminalStatus.ERROR/TIMEOUThere.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_ci_watch/handlers/handler_ci_watch.py` around lines 143 - 158, The code treats an empty failed_checks list as a PASSED result even when _fetch_ci_status returned an error summary; change the handler in handler_ci_watch.py to detect an error/timeout outcome from _fetch_ci_status (e.g., have _fetch_ci_status return an explicit error flag or raise a dedicated exception) and map that to a non-PASSED terminal status instead of PASSED: when _fetch_ci_status indicates a transport/CLI error or timeout, return ModelCiWatchResult with terminal_status set to EnumCiTerminalStatus.ERROR or EnumCiTerminalStatus.TIMEOUT (and include the failure_summary), and only return PASSED when there is no error flag/exception and failed_checks is empty. Ensure you update caller logic around the _fetch_ci_status call to catch the raised error or check the returned error flag and populate started_at/completed_at similarly to the success and failure branches.src/omnimarket/nodes/node_swarm_dispatch_orchestrator/handlers/handler_swarm_dispatch.py (1)
132-153:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFail fast when async routing is used without a state store.
With
state_store=None,handle_async()publishes the first command but_persist_state()is a no-op, so every laterroute_event()for that run deterministically fails withMissingRunStateError. That turns a wiring mistake into a delayed runtime wedge.Suggested guard
async def handle_async(self, request: ModelSwarmDispatchRequest) -> None: + if self._state_store is None: + raise RuntimeError( + "HandlerSwarmDispatchOrchestrator.handle_async requires a state_store" + ) """Handle the initial swarm-dispatch command. @@ async def route_event( self, topic: str, payload: dict[str, Any], ) -> ModelOrchestratorState: + if self._state_store is None: + raise RuntimeError( + "HandlerSwarmDispatchOrchestrator.route_event requires a state_store" + ) """Route a response event to the correct FSM transition.Also applies to: 520-548
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_dispatch_orchestrator/handlers/handler_swarm_dispatch.py` around lines 132 - 153, The constructor currently allows creating the handler with state_store=None which lets handle_async publish a first command while _persist_state is a no-op and later route_event calls raise MissingRunStateError; add a fail-fast guard in the handler constructor (the method that sets self._state_store and loads topics) that detects when async routing is expected (e.g., contract indicates subscribe_topics or publish topics used by handle_async like "swarm-decompose", "swarm-select-endpoints", "swarm-fanout", or presence of subscribe topics) and if so raise a clear exception (ValueError or custom) when state_store is None; reference the constructor that sets self._state_store and the methods handle_async, _persist_state, and route_event so reviewers can locate and fix the logic (also apply the same guard in the other constructor/initialization block noted around lines 520-548).
🟡 Minor comments (12)
src/omnimarket/nodes/node_contract_sweep/handlers/handler_contract_sweep.py-122-128 (1)
122-128:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign path filter with the stated “src-only authoritative” rule.
The new guard skips
.venv/site-packages, but it still allows any path containing"nodes"outsidesrc. Please enforcesrc/omnimarket/nodesexplicitly to avoid stale/non-source contract scans.As per coding guidelines, “Keep node logic inside
src/omnimarket/nodes/node_*directories.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_contract_sweep/handlers/handler_contract_sweep.py` around lines 122 - 128, The path filter currently only excludes ".venv" and "site-packages" but still allows contracts outside the authoritative source tree; update the logic around contract_path/contract_parts so it only accepts paths rooted under src/omnimarket/nodes and specifically under node_... directories (e.g., require the first three path components to be "src","omnimarket","nodes" and the next component to start with "node_"), while still keeping the existing checks for ".venv" and "site-packages"; adjust the conditional that now checks contract_parts to first check for those excluded segments and then require the src/omnimarket/nodes/node_* prefix before proceeding.src/omnimarket/models/swarm/model_swarm_subtask_result.py-18-18 (1)
18-18:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winConstrain
latency_msto non-negative values.Negative latency is currently accepted, which can skew telemetry and reporting. Add a lower bound at model validation.
💡 Suggested fix
-from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field @@ - latency_ms: int = 0 + latency_ms: int = Field(default=0, ge=0)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/models/swarm/model_swarm_subtask_result.py` at line 18, The field latency_ms on the SwarmSubtaskResult model currently allows negative values; update its type/validation to enforce a non-negative integer (>= 0) by using Pydantic validators or a constrained type/Field (e.g., conint(ge=0) or Field(..., ge=0)) on the latency_ms declaration and/or add a `@validator` for latency_ms in the SwarmSubtaskResult class to raise a ValidationError for negative inputs so telemetry/reporting cannot receive negative latencies.src/omnimarket/nodes/node_delegation_orchestrator/models/model_delegation_escalation_attempt.py-23-32 (1)
23-32:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd numeric bounds to match the field contracts.
Line 23 documents
quality_scoreas0.0-1.0, and Line 30 represents latency in milliseconds, but neither field enforces bounds. Invalid values can slip into persisted evidence records.Proposed fix
- quality_score: float = Field( - ..., description="Quality gate score for this attempt (0.0-1.0)." - ) + quality_score: float = Field( + ..., ge=0.0, le=1.0, description="Quality gate score for this attempt (0.0-1.0)." + ) @@ - latency_ms: int = Field( - ..., description="End-to-end latency for this attempt in milliseconds." - ) + latency_ms: int = Field( + ..., ge=0, description="End-to-end latency for this attempt in milliseconds." + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_delegation_orchestrator/models/model_delegation_escalation_attempt.py` around lines 23 - 32, The Pydantic model fields quality_score and latency_ms lack validation bounds; update the Field(...) declarations for quality_score (in model_delegation_escalation_attempt.py) to enforce 0.0 <= quality_score <= 1.0 (e.g., use ge=0.0, le=1.0) and for latency_ms to enforce non-negative integer values (e.g., ge=0); keep the current descriptions and default for failure_reasons unchanged.src/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_fanout_result.py-16-23 (1)
16-23:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winGuard telemetry fields against negative values.
wall_latency_ms,sum_subtask_latency_ms,completed_count, andfailed_countcan currently accept negative values, which can corrupt downstream metrics/projections.Proposed fix
-from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field @@ - wall_latency_ms: int - sum_subtask_latency_ms: int + wall_latency_ms: int = Field(ge=0) + sum_subtask_latency_ms: int = Field(ge=0) @@ - completed_count: int = 0 - failed_count: int = 0 + completed_count: int = Field(default=0, ge=0) + failed_count: int = Field(default=0, ge=0)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_fanout_result.py` around lines 16 - 23, The model currently allows negative metrics; add a validation step in the dataclass (e.g., implement __post_init__ on ModelSwarmFanoutResult) that checks wall_latency_ms, sum_subtask_latency_ms, completed_count, and failed_count are >= 0 and raises a ValueError with a clear message if any are negative; also ensure any deserialization/path that constructs ModelSwarmFanoutResult (factory methods or from_dict-like helpers) uses the same validation to prevent invalid instances from being created.src/omnimarket/nodes/node_delegation_orchestrator/plugin.py-440-445 (1)
440-445:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSanitize exception text before warning log emission.
Line 442 logs
_excdirectly; prefersanitize_error_message(_exc)to avoid leaking internal exception content.Suggested fix
except Exception as _exc: logger.warning( "Failed to register DirectBridgeDelegationDispatchPort: %s " "(correlation_id=%s)", - _exc, + sanitize_error_message(_exc), correlation_id, )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_delegation_orchestrator/plugin.py` around lines 440 - 445, The catch block logging for DirectBridgeDelegationDispatchPort currently emits the raw exception `_exc`; replace that with a sanitized string by calling `sanitize_error_message(_exc)` in the `logger.warning` call to avoid leaking internal details, and ensure `sanitize_error_message` is imported or available in the module where `plugin.py` defines the registration logic (the try/except around `DirectBridgeDelegationDispatchPort` registration).src/omnimarket/adapters/codex/runtime_client.py-624-636 (1)
624-636:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRuntime evidence should reflect the actual subscribed terminal topic.
When delegate-skill routing is selected, terminal subscription uses delegate-specific topics, but downstream evidence still reports
request.response_topic. This makes debugging/telemetry misleading for this path.💡 Suggested patch
@@ - if is_delegate_skill: + if is_delegate_skill: terminal_topic = _DELEGATE_SKILL_COMPLETED_TOPIC extra_topics = ( _DELEGATE_SKILL_FAILED_TOPIC, *additional_response_topics, ) @@ - route = ModelDispatchBusRoute( + selected_terminal_topic = terminal_topic + route = ModelDispatchBusRoute( contract_path=Path("codex-runtime-request-adapter"), command_topic=self._command_topic, terminal_topic=terminal_topic, ) @@ evidence = _deployed_runtime_evidence( command_topic=self._command_topic, - response_topic=request.response_topic, + response_topic=selected_terminal_topic, runtime_selection=request.runtime_selection, )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/adapters/codex/runtime_client.py` around lines 624 - 636, The runtime evidence currently always reports request.response_topic even when delegate-skill routing is used; detect the delegate path (the is_delegate_skill check that uses _DELEGATE_SKILL_COMMAND_TOPIC and _DELEGATE_SKILL_COMMAND_NAMES) and ensure downstream telemetry/evidence uses the actual terminal_topic (set to _DELEGATE_SKILL_COMPLETED_TOPIC for delegates) instead of request.response_topic; update any code that emits/runtime_evidence or similar to reference the terminal_topic variable (and, if applicable, include extra_topics from the extra_topics tuple) so reported subscriptions match the real subscribed topic.src/omnimarket/nodes/node_swarm_subtask_state_reducer/handlers/handler_swarm_subtask_state.py-177-185 (1)
177-185:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix attempt counter overwrite for first-seen escalation events.
Line 183 overwrites the earlier escalation increment logic. If
existing is Noneand the event isDELEGATION_ESCALATION_TRIGGERED,attempt_countbecomes0instead of1.Suggested fix
if existing is None: attempt_count = ( - 1 if event.event_type == EnumDelegationEventType.DELEGATION_EXECUTE else 0 + 1 + if event.event_type + in { + EnumDelegationEventType.DELEGATION_EXECUTE, + EnumDelegationEventType.DELEGATION_ESCALATION_TRIGGERED, + } + else 0 )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_subtask_state_reducer/handlers/handler_swarm_subtask_state.py` around lines 177 - 185, The current logic overwrites the escalation increment by resetting attempt_count when existing is None; update the initialization so first-seen escalation events keep their increment. Specifically, in the block that sets attempt_count when existing is None (around the variables attempt_count, existing, and event.event_type), set attempt_count = 1 if event.event_type is EnumDelegationEventType.DELEGATION_EXECUTE OR EnumDelegationEventType.DELEGATION_ESCALATION_TRIGGERED, otherwise 0 (or alternatively apply the escalation increment before the existing-is-None assignment and only set a default of 0 when no increment occurred). Ensure you reference and update the code paths that use attempt_count, existing, and event.event_type so first-seen DELEGATION_ESCALATION_TRIGGERED yields attempt_count == 1.src/omnimarket/nodes/node_swarm_dispatch_orchestrator/models/model_orchestrator_state.py-68-70 (1)
68-70:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winGuard invalid
max_subtasksand negative wall-latency values.Line 68 and Line 102 accept any integer;
max_subtasks <= 0ordispatch_wall_latency_ms < 0can propagate invalid orchestration state.Proposed fix
def with_max_subtasks(self, max_subtasks: int) -> ModelOrchestratorState: + if max_subtasks < 1: + raise ValueError("max_subtasks must be >= 1") return self.model_copy(update={"max_subtasks": max_subtasks}) @@ def with_dispatches( self, dispatches: tuple[ModelSubtaskDispatch, ...], dispatch_wall_latency_ms: int = 0, ) -> ModelOrchestratorState: + if dispatch_wall_latency_ms < 0: + raise ValueError("dispatch_wall_latency_ms must be >= 0") return self.model_copy( update={ "fsm_state": EnumSwarmOrchestratorState.DISPATCHING, "dispatches": dispatches, "dispatch_wall_latency_ms": dispatch_wall_latency_ms, } )Also applies to: 100-103, 108-108
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_dispatch_orchestrator/models/model_orchestrator_state.py` around lines 68 - 70, Validate inputs before calling model_copy: in with_max_subtasks ensure max_subtasks is an int > 0 and raise ValueError if not, and in the setter that updates dispatch_wall_latency_ms (the method that updates the dispatch wall latency) ensure dispatch_wall_latency_ms is an int >= 0 and raise ValueError if negative; keep using self.model_copy(update={...}) to return the updated ModelOrchestratorState after validation so invalid values cannot propagate into the orchestration state.src/omnimarket/nodes/node_refill_sprint_orchestrator/models/model_refill_sprint.py-176-176 (1)
176-176:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMake
ModelRefillSprintResultimmutable to match the module’s frozen-value-object contract.
ModelRefillSprintResultsetsmodel_config = ConfigDict(extra="forbid")withoutfrozen=True, while the module docstring and other models in this file useConfigDict(frozen=True, extra="forbid").Proposed fix
- model_config = ConfigDict(extra="forbid") + model_config = ConfigDict(frozen=True, extra="forbid")🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_refill_sprint_orchestrator/models/model_refill_sprint.py` at line 176, ModelRefillSprintResult currently sets model_config = ConfigDict(extra="forbid") but must be immutable to follow the module's frozen-value-object contract; update the class's model_config to include frozen=True (i.e., ConfigDict(frozen=True, extra="forbid")) so the Pydantic model is immutable, matching other models in the file and the module docstring.src/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/model_fleet_discovery_request.py-26-26 (1)
26-26:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winValidate
min_healthy_endpointsto reject negatives.At Line 26, negative values are accepted, which can break threshold semantics and let invalid requests through.
Suggested fix
-from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field @@ - min_healthy_endpoints: int = 8 + min_healthy_endpoints: int = Field(default=8, ge=0)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/model_fleet_discovery_request.py` at line 26, The field min_healthy_endpoints in model_fleet_discovery_request.py currently allows negative values; add validation on the model (e.g., a Pydantic validator or field constraint) to ensure min_healthy_endpoints is an int >= 0 and raise a validation error for negatives so invalid requests are rejected; locate the model class in model_fleet_discovery_request.py (the class that defines the min_healthy_endpoints field) and implement the non-negative check referencing the min_healthy_endpoints symbol.src/omnimarket/nodes/node_data_flow_sweep/collector.py-143-151 (1)
143-151:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix newest-message age parsing to avoid silent
Noneand missed TOPIC_STALEIn
src/omnimarket/nodes/node_data_flow_sweep/collector.py,_probe_newest_message_age’s regex captures only up to seconds (no.fffand no trailingZ/offset). As a result,datetime.fromisoformat(...)produces a naivets, and(now - ts)subtracts naive from timezone-awarenow(datetime.UTC), raisingTypeErrorwhich is caught and returned asNone. This bypasses the handler’snewest_message_age_seconds is not Nonecheck forTOPIC_STALE.💡 Proposed fix
- m = re.match(r"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})", out.strip()) + m = re.match( + r"(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)", + out.strip(), + ) @@ - ts = datetime.datetime.fromisoformat(m.group(1).replace("Z", "+00:00")) + ts = datetime.datetime.fromisoformat(m.group(1).replace("Z", "+00:00")) + if ts.tzinfo is None: + ts = ts.replace(tzinfo=datetime.UTC)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_data_flow_sweep/collector.py` around lines 143 - 151, The regex in _probe_newest_message_age only captures up to whole seconds so datetime.fromisoformat sometimes returns a naive timestamp which causes a TypeError when subtracting from timezone-aware datetime.now(tz=datetime.UTC) and the exception is swallowed returning None; update the regex in _probe_newest_message_age to capture optional fractional seconds and an optional timezone designator (Z or ±HH:MM) so m.group(1) contains a full ISO timestamp, then build a timezone-aware ts (use datetime.fromisoformat after normalizing 'Z' to '+00:00' or explicitly set tzinfo=datetime.UTC when no offset is present) and let that non-None value be returned instead of silently returning None. Ensure you still return None only when the regex truly fails and do not rely on catching TypeError from naive/aware arithmetic.src/omnimarket/nodes/node_swarm_dispatch_orchestrator/handlers/handler_swarm_dispatch.py-312-315 (1)
312-315:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winForward the aggregate event's latency into
transition_aggregating().
route_event()currently callstransition_aggregating(state, payload)with the defaulttotal_latency_ms=0, so the completed payload always reportstotal_latency_msas zero on this path.Suggested fix
elif routing_key == "aggregating": # aggregation-completed advances through AGGREGATING → COMPLETED in one shot - state, _ = self.transition_aggregating(state, payload) + total_latency_ms = int(payload.get("total_latency_ms", 0)) + state, _ = self.transition_aggregating( + state, + payload, + total_latency_ms=total_latency_ms, + ) state, publishes = self.transition_completed(state)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_dispatch_orchestrator/handlers/handler_swarm_dispatch.py` around lines 312 - 315, The call site in route_event that handles routing_key == "aggregating" must forward the aggregate event's latency into transition_aggregating instead of using the implicit zero; update the call where you currently do state, _ = self.transition_aggregating(state, payload) to compute the latency from the incoming payload (e.g. extract payload["total_latency_ms"] or payload.get("total_latency_ms", 0) / or combine individual latency fields as your payload schema requires) and pass it as the total_latency_ms argument to transition_aggregating(state, payload, total_latency_ms), then continue to call transition_completed(state) as before so the completed payload carries the correct total_latency_ms.
🧹 Nitpick comments (3)
src/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/model_fleet_discovery_result.py (1)
37-42: ⚡ Quick winEnforce aggregate-count invariants against
endpoints.
healthy_count,unhealthy_count,local_count, andopenrouter_countcan drift fromendpointswith no guard. Add an after-validation invariant that verifies these counters from endpointstatus/providerso projection counts fail fast when inconsistent.Proposed patch
-from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, model_validator @@ class ModelFleetDiscoveryResult(BaseModel): @@ correlation_id: str = "" + + `@model_validator`(mode="after") + def _validate_aggregate_counts(self) -> "ModelFleetDiscoveryResult": + healthy = sum(1 for endpoint in self.endpoints if endpoint.status == EnumDiscoveryEndpointStatus.healthy) + unhealthy = sum(1 for endpoint in self.endpoints if endpoint.status == EnumDiscoveryEndpointStatus.unhealthy) + local = sum(1 for endpoint in self.endpoints if endpoint.provider == "local") + openrouter = sum(1 for endpoint in self.endpoints if endpoint.provider == "openrouter") + + if self.healthy_count != healthy or self.unhealthy_count != unhealthy: + raise ValueError("status counts do not match endpoints") + if self.local_count != local or self.openrouter_count != openrouter: + raise ValueError("provider counts do not match endpoints") + return self🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/model_fleet_discovery_result.py` around lines 37 - 42, The aggregate count fields on ModelFleetDiscoveryResult can become inconsistent with the endpoints tuple; add an after-validation check (e.g., a pydantic `@root_validator`(pre=False) or equivalent post-init invariant in the ModelFleetDiscoveryResult class) that computes counts by iterating over endpoints and their status/provider (count healthy vs unhealthy from endpoint.status and local vs openrouter from endpoint.provider), then compare those computed values against healthy_count, unhealthy_count, local_count, and openrouter_count and raise a ValidationError/ValueError with a clear message if any mismatch is found so projection construction fails fast; update any logic that sets meets_threshold if it should be derived from the recomputed counts.src/omnimarket/nodes/node_demo_fanout_orchestrator/models/model_fanout_request.py (1)
29-31: ⚡ Quick winGuard against empty endpoint configuration at model boundary.
endpoint_urlaccepts empty strings today, which defers failure to runtime dispatch. Add a non-empty constraint here so bad configs fail fast.Suggested fix
- endpoint_url: str = Field(description="OpenAI-compatible endpoint base URL") + endpoint_url: str = Field( + min_length=1, + description="OpenAI-compatible endpoint base URL", + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_demo_fanout_orchestrator/models/model_fanout_request.py` around lines 29 - 31, The endpoint_url Field in model_fanout_request.py currently allows empty strings, so add a non-empty constraint on the Pydantic field to fail-fast: update endpoint_url: str = Field(...) to include min_length=1 (e.g., Field(..., min_length=1, description="OpenAI-compatible endpoint base URL")) or replace with constr(min_length=1) as the type (e.g., endpoint_url: constr(min_length=1) = Field(description=...)); this enforces a non-empty endpoint at model validation time for the model_fanout_request schema.src/omnimarket/nodes/node_create_followup_tickets_effect/models/model_create_followup_tickets_state.py (1)
129-132: ⚡ Quick winConstrain
statusto explicit allowed values.
statusis currently a plainstr, so invalid values can slip through silently. Encoding the allowed states in the type makes the wire contract safer.Suggested fix
+from typing import Literal ... class ModelCreateFollowupTicketsResult(BaseModel): ... - status: str = Field( + status: Literal["created", "dry_run", "error", "partial"] = Field( default="created", description="Overall status: created | dry_run | error | partial.", )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/omnimarket/nodes/node_create_followup_tickets_effect/models/model_create_followup_tickets_state.py` around lines 129 - 132, The status Field on the CreateFollowupTicketsState model is an unconstrained str; change it to an explicit allowed set (e.g., use typing.Literal["created","dry_run","error","partial"] or define a small Enum like FollowupStatus and use that as the type) and update the Field default to one of those members; adjust imports (from typing import Literal or from enum import Enum) and the model's status declaration so Pydantic enforces only the allowed states.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7fb0b748-ba86-4d88-9141-c8fd92da1824
📒 Files selected for processing (300)
.github/workflows/main-target-guard.yml.onex_state/dep_health_baseline.json.pre-commit-config.yamldocs/evidence/dep-health-sweep/proof-of-life-001/baseline_diff.jsondocs/evidence/dep-health-sweep/proof-of-life-001/findings.jsondocs/evidence/dep-health-sweep/proof-of-life-001/import_graph.jsondocs/evidence/dep-health-sweep/proof-of-life-001/projection_rows.jsondocs/evidence/dep-health-sweep/proof-of-life-001/proof_summary.mddocs/evidence/dep-health-sweep/proof-of-life-001/run_manifest.jsondocs/evidence/dep-health-sweep/proof-of-life-001/topology_graph.jsondocs/work-tracking/contracts/OMN-12245.yamlpyproject.tomlscripts/validation/unimported_handler_baseline.txtsrc/dep_health_allowlist.yamlsrc/omnimarket/adapters/codex/runtime_client.pysrc/omnimarket/adapters/codex/topics.pysrc/omnimarket/adapters/llm/adapter_llm_caller_delegation.pysrc/omnimarket/adapters/llm/bifrost/model_bifrost_delegation_config.pysrc/omnimarket/cli/commands/__init__.pysrc/omnimarket/cli/commands/trace.pysrc/omnimarket/cli/market.pysrc/omnimarket/configs/bifrost_delegation.yamlsrc/omnimarket/configs/routing_tiers.yamlsrc/omnimarket/events/delegation.pysrc/omnimarket/events/demo_pipeline.pysrc/omnimarket/inference/bridge_config_loader.pysrc/omnimarket/inference/registry_context_windows.pysrc/omnimarket/models/delegation/wire/__init__.pysrc/omnimarket/models/delegation/wire/model_bifrost_delegation_config.pysrc/omnimarket/models/swarm/__init__.pysrc/omnimarket/models/swarm/enum_execution_status.pysrc/omnimarket/models/swarm/model_swarm_subtask_assignment.pysrc/omnimarket/models/swarm/model_swarm_subtask_result.pysrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/__init__.pysrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/contract.yamlsrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/handlers/handler_adversarial_pipeline_orchestrator.pysrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_adversarial_pipeline_orchestrator/models/model_adversarial_pipeline_request.pysrc/omnimarket/nodes/node_architecture_graph_populate_effect/contract.yamlsrc/omnimarket/nodes/node_architecture_graph_query_effect/contract.yamlsrc/omnimarket/nodes/node_budget_policy_compute/models/model_budget_limits.pysrc/omnimarket/nodes/node_build_dispatch_effect/contract.yamlsrc/omnimarket/nodes/node_build_dispatch_effect/handlers/handler_build_dispatch.pysrc/omnimarket/nodes/node_build_loop_orchestrator/__main__.pysrc/omnimarket/nodes/node_build_loop_orchestrator/contract.yamlsrc/omnimarket/nodes/node_build_loop_orchestrator/handlers/adapter_delegation_router.pysrc/omnimarket/nodes/node_build_loop_orchestrator/handlers/adapter_llm_dispatch.pysrc/omnimarket/nodes/node_ci_watch/__init__.pysrc/omnimarket/nodes/node_ci_watch/contract.yamlsrc/omnimarket/nodes/node_ci_watch/handlers/handler_ci_watch.pysrc/omnimarket/nodes/node_context_experiment_compute/__init__.pysrc/omnimarket/nodes/node_context_experiment_compute/contract.yamlsrc/omnimarket/nodes/node_context_experiment_compute/metadata.yamlsrc/omnimarket/nodes/node_context_experiment_compute/models/__init__.pysrc/omnimarket/nodes/node_context_experiment_compute/models/model_context_chunk_extended.pysrc/omnimarket/nodes/node_context_experiment_compute/models/model_context_pack_extended.pysrc/omnimarket/nodes/node_context_experiment_compute/models/model_context_pack_validity_scope.pysrc/omnimarket/nodes/node_context_experiment_compute/models/util_context_chunk_id.pysrc/omnimarket/nodes/node_context_experiment_compute/tests/__init__.pysrc/omnimarket/nodes/node_contract_sweep/handlers/handler_contract_sweep.pysrc/omnimarket/nodes/node_create_followup_tickets_effect/__init__.pysrc/omnimarket/nodes/node_create_followup_tickets_effect/contract.yamlsrc/omnimarket/nodes/node_create_followup_tickets_effect/handlers/__init__.pysrc/omnimarket/nodes/node_create_followup_tickets_effect/handlers/handler_create_followup_tickets_effect.pysrc/omnimarket/nodes/node_create_followup_tickets_effect/metadata.yamlsrc/omnimarket/nodes/node_create_followup_tickets_effect/models/__init__.pysrc/omnimarket/nodes/node_create_followup_tickets_effect/models/model_create_followup_tickets_state.pysrc/omnimarket/nodes/node_dashboard_sweep/contract.yamlsrc/omnimarket/nodes/node_dashboard_sweep/handlers/handler_dashboard_sweep.pysrc/omnimarket/nodes/node_data_flow_sweep/__main__.pysrc/omnimarket/nodes/node_data_flow_sweep/collector.pysrc/omnimarket/nodes/node_data_flow_sweep/contract.yamlsrc/omnimarket/nodes/node_decompose_epic_orchestrator/__init__.pysrc/omnimarket/nodes/node_decompose_epic_orchestrator/contract.yamlsrc/omnimarket/nodes/node_decompose_epic_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_decompose_epic_orchestrator/handlers/handler_decompose_epic.pysrc/omnimarket/nodes/node_decompose_epic_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_decompose_epic_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_decompose_epic_orchestrator/models/model_decompose_epic_request.pysrc/omnimarket/nodes/node_delegate_skill_orchestrator/contract.yamlsrc/omnimarket/nodes/node_delegate_skill_orchestrator/ports/port_direct_bridge_dispatch.pysrc/omnimarket/nodes/node_delegate_skill_orchestrator/ports/port_runtime_delegation_dispatch.pysrc/omnimarket/nodes/node_delegation_orchestrator/contract.yamlsrc/omnimarket/nodes/node_delegation_orchestrator/delegation_intent_bridge.pysrc/omnimarket/nodes/node_delegation_orchestrator/enums.pysrc/omnimarket/nodes/node_delegation_orchestrator/handlers/handler_compliance_loop.pysrc/omnimarket/nodes/node_delegation_orchestrator/handlers/handler_delegation_workflow.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_baseline_intent.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_compliance_loop_result.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_delegation_escalation_attempt.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_delegation_event.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_delegation_request.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_delegation_result.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_inference_intent.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_inference_response_data.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_quality_gate_intent.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_routing_intent.pysrc/omnimarket/nodes/node_delegation_orchestrator/models/model_task_delegated_event.pysrc/omnimarket/nodes/node_delegation_orchestrator/plugin.pysrc/omnimarket/nodes/node_delegation_orchestrator/wiring.pysrc/omnimarket/nodes/node_delegation_quality_gate_reducer/handlers/handler_quality_gate.pysrc/omnimarket/nodes/node_delegation_quality_gate_reducer/models/model_quality_contract.pysrc/omnimarket/nodes/node_delegation_quality_gate_reducer/models/model_quality_gate_input.pysrc/omnimarket/nodes/node_delegation_quality_gate_reducer/models/model_quality_gate_result.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/__init__.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/contract.yamlsrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/handlers/__init__.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/handlers/handler_delegation_routing_feedback.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/metadata.yamlsrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/models/__init__.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/models/model_delegation_feedback_event.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/models/model_routing_feedback.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/tests/__init__.pysrc/omnimarket/nodes/node_delegation_routing_feedback_reducer/tests/test_handler_delegation_routing_feedback.pysrc/omnimarket/nodes/node_delegation_routing_reducer/handlers/handler_delegation_routing.pysrc/omnimarket/nodes/node_delegation_routing_reducer/models/model_delegation_config.pysrc/omnimarket/nodes/node_delegation_routing_reducer/models/model_routing_decision.pysrc/omnimarket/nodes/node_delegation_routing_reducer/models/model_routing_tier.pysrc/omnimarket/nodes/node_delegation_routing_reducer/models/model_tier_model.pysrc/omnimarket/nodes/node_demo_cost_compute/__init__.pysrc/omnimarket/nodes/node_demo_cost_compute/contract.yamlsrc/omnimarket/nodes/node_demo_cost_compute/handlers/__init__.pysrc/omnimarket/nodes/node_demo_cost_compute/handlers/handler_cost_compute.pysrc/omnimarket/nodes/node_demo_cost_compute/metadata.yamlsrc/omnimarket/nodes/node_demo_cost_compute/models/__init__.pysrc/omnimarket/nodes/node_demo_cost_compute/models/model_cost_request.pysrc/omnimarket/nodes/node_demo_cost_compute/tests/__init__.pysrc/omnimarket/nodes/node_demo_cost_compute/tests/test_golden_chain.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/__init__.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/contract.yamlsrc/omnimarket/nodes/node_demo_fanout_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/handlers/handler_fanout.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_demo_fanout_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/models/model_fanout_request.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/tests/__init__.pysrc/omnimarket/nodes/node_demo_fanout_orchestrator/tests/test_golden_chain.pysrc/omnimarket/nodes/node_demo_renderer_effect/__init__.pysrc/omnimarket/nodes/node_demo_renderer_effect/contract.yamlsrc/omnimarket/nodes/node_demo_renderer_effect/handlers/__init__.pysrc/omnimarket/nodes/node_demo_renderer_effect/handlers/handler_renderer.pysrc/omnimarket/nodes/node_demo_renderer_effect/metadata.yamlsrc/omnimarket/nodes/node_demo_renderer_effect/models/__init__.pysrc/omnimarket/nodes/node_demo_renderer_effect/models/model_render_request.pysrc/omnimarket/nodes/node_demo_renderer_effect/tests/__init__.pysrc/omnimarket/nodes/node_demo_renderer_effect/tests/test_golden_chain.pysrc/omnimarket/nodes/node_design_to_plan/contract.yamlsrc/omnimarket/nodes/node_dispatch_request_handler/__init__.pysrc/omnimarket/nodes/node_dispatch_request_handler/contract.yamlsrc/omnimarket/nodes/node_dispatch_request_handler/handlers/__init__.pysrc/omnimarket/nodes/node_dispatch_request_handler/handlers/handler_dispatch_request.pysrc/omnimarket/nodes/node_dispatch_request_handler/metadata.yamlsrc/omnimarket/nodes/node_dispatch_request_handler/models/__init__.pysrc/omnimarket/nodes/node_dispatch_request_handler/models/model_dispatch_request.pysrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/__init__.pysrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/contract.yamlsrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/handlers/handler_watchdog.pysrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_dispatch_watchdog_orchestrator/models/model_watchdog.pysrc/omnimarket/nodes/node_dod_sweep_orchestrator/handlers/handler_dod_sweep_orchestrator.pysrc/omnimarket/nodes/node_dod_sweep_orchestrator/models/model_dod_sweep_orchestrator_request.pysrc/omnimarket/nodes/node_dod_sweep_orchestrator/models/model_dod_sweep_orchestrator_result.pysrc/omnimarket/nodes/node_epic_team_orchestrator/__init__.pysrc/omnimarket/nodes/node_epic_team_orchestrator/contract.yamlsrc/omnimarket/nodes/node_epic_team_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_epic_team_orchestrator/handlers/handler_epic_team_orchestrator.pysrc/omnimarket/nodes/node_epic_team_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_epic_team_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_epic_team_orchestrator/models/model_epic_team_request.pysrc/omnimarket/nodes/node_epic_team_orchestrator/models/model_epic_team_result.pysrc/omnimarket/nodes/node_friction_triage_orchestrator/__init__.pysrc/omnimarket/nodes/node_friction_triage_orchestrator/contract.yamlsrc/omnimarket/nodes/node_friction_triage_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_friction_triage_orchestrator/handlers/handler_friction_triage_orchestrator.pysrc/omnimarket/nodes/node_friction_triage_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_friction_triage_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_friction_triage_orchestrator/models/model_friction_triage_request.pysrc/omnimarket/nodes/node_handler_correctness_gate/__init__.pysrc/omnimarket/nodes/node_handler_correctness_gate/contract.yamlsrc/omnimarket/nodes/node_handler_correctness_gate/contracts/example_eval_set.yamlsrc/omnimarket/nodes/node_handler_correctness_gate/handlers/__init__.pysrc/omnimarket/nodes/node_handler_correctness_gate/handlers/handler_correctness_gate.pysrc/omnimarket/nodes/node_handler_correctness_gate/metadata.yamlsrc/omnimarket/nodes/node_handler_correctness_gate/models/__init__.pysrc/omnimarket/nodes/node_handler_correctness_gate/models/enums.pysrc/omnimarket/nodes/node_handler_correctness_gate/models/model_correctness_check_request.pysrc/omnimarket/nodes/node_handler_correctness_gate/models/model_correctness_check_result.pysrc/omnimarket/nodes/node_handler_correctness_gate/models/model_eval_entry.pysrc/omnimarket/nodes/node_handler_correctness_gate/models/model_eval_failure.pysrc/omnimarket/nodes/node_handler_correctness_gate/models/model_eval_set.pysrc/omnimarket/nodes/node_handler_correctness_gate/tests/__init__.pysrc/omnimarket/nodes/node_handler_correctness_gate/tests/test_handler_correctness_gate.pysrc/omnimarket/nodes/node_handoff_effect/handlers/handler_handoff_effect.pysrc/omnimarket/nodes/node_integration_sweep_orchestrator/contract.yamlsrc/omnimarket/nodes/node_integration_sweep_orchestrator/handlers/handler_integration_sweep_orchestrator.pysrc/omnimarket/nodes/node_integration_sweep_orchestrator/handlers/surface_probes.pysrc/omnimarket/nodes/node_integration_sweep_orchestrator/models/model_integration_sweep_orchestrator_request.pysrc/omnimarket/nodes/node_integration_sweep_orchestrator/models/model_integration_sweep_orchestrator_result.pysrc/omnimarket/nodes/node_knowledge_context_assembler_orchestrator/contract.yamlsrc/omnimarket/nodes/node_knowledge_context_assembler_orchestrator/handlers/handler_knowledge_context_assembler_orchestrator.pysrc/omnimarket/nodes/node_log_persistence_effect/__init__.pysrc/omnimarket/nodes/node_log_persistence_effect/contract.yamlsrc/omnimarket/nodes/node_log_persistence_effect/handlers/__init__.pysrc/omnimarket/nodes/node_log_persistence_effect/handlers/handler_log_persistence_effect.pysrc/omnimarket/nodes/node_log_persistence_effect/metadata.yamlsrc/omnimarket/nodes/node_multi_agent_orchestrator/__init__.pysrc/omnimarket/nodes/node_multi_agent_orchestrator/contract.yamlsrc/omnimarket/nodes/node_multi_agent_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_multi_agent_orchestrator/handlers/handler_multi_agent.pysrc/omnimarket/nodes/node_multi_agent_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_multi_agent_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_multi_agent_orchestrator/models/model_multi_agent.pysrc/omnimarket/nodes/node_overnight/__main__.pysrc/omnimarket/nodes/node_pr_lifecycle_fix_effect/contract.yamlsrc/omnimarket/nodes/node_pr_lifecycle_fix_effect/handlers/adapter_occ_contract.pysrc/omnimarket/nodes/node_pr_lifecycle_fix_effect/handlers/adapter_pr_polish_dispatch.pysrc/omnimarket/nodes/node_pr_lifecycle_fix_effect/handlers/handler_pr_lifecycle_fix.pysrc/omnimarket/nodes/node_pr_lifecycle_fix_effect/models/model_fix_command.pysrc/omnimarket/nodes/node_pr_lifecycle_orchestrator/handlers/handler_pr_lifecycle_orchestrator.pysrc/omnimarket/nodes/node_projection_delegation/handlers/handler_projection_delegation.pysrc/omnimarket/nodes/node_projection_registration/contract.yamlsrc/omnimarket/nodes/node_projection_swarm/contract.yamlsrc/omnimarket/nodes/node_redeploy/__main__.pysrc/omnimarket/nodes/node_refill_sprint_orchestrator/__init__.pysrc/omnimarket/nodes/node_refill_sprint_orchestrator/contract.yamlsrc/omnimarket/nodes/node_refill_sprint_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_refill_sprint_orchestrator/handlers/handler_refill_sprint.pysrc/omnimarket/nodes/node_refill_sprint_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_refill_sprint_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_refill_sprint_orchestrator/models/model_refill_sprint.pysrc/omnimarket/nodes/node_session_orchestrator/__main__.pysrc/omnimarket/nodes/node_swarm_aggregator_compute/contract.yamlsrc/omnimarket/nodes/node_swarm_aggregator_compute/handlers/handler_swarm_aggregator.pysrc/omnimarket/nodes/node_swarm_aggregator_compute/models/model_swarm_aggregate_request.pysrc/omnimarket/nodes/node_swarm_aggregator_compute/models/model_swarm_aggregate_result.pysrc/omnimarket/nodes/node_swarm_decomposer_compute/contract.yamlsrc/omnimarket/nodes/node_swarm_decomposer_compute/handlers/handler_swarm_decomposer.pysrc/omnimarket/nodes/node_swarm_decomposer_compute/models/model_swarm_decompose_request.pysrc/omnimarket/nodes/node_swarm_decomposer_compute/models/model_swarm_decompose_result.pysrc/omnimarket/nodes/node_swarm_dispatch_orchestrator/handlers/handler_swarm_dispatch.pysrc/omnimarket/nodes/node_swarm_dispatch_orchestrator/models/model_orchestrator_state.pysrc/omnimarket/nodes/node_swarm_dispatch_orchestrator/models/model_swarm_dispatch_request.pysrc/omnimarket/nodes/node_swarm_dispatch_orchestrator/tests/test_fsm_routing_integration.pysrc/omnimarket/nodes/node_swarm_dispatch_orchestrator/tests/test_handler_swarm_dispatch.pysrc/omnimarket/nodes/node_swarm_dispatch_orchestrator/tests/test_models.pysrc/omnimarket/nodes/node_swarm_endpoint_health_effect/contract.yamlsrc/omnimarket/nodes/node_swarm_endpoint_health_effect/handlers/handler_swarm_endpoint_health.pysrc/omnimarket/nodes/node_swarm_endpoint_health_effect/models/model_swarm_health_check_request.pysrc/omnimarket/nodes/node_swarm_endpoint_health_effect/models/model_swarm_health_check_result.pysrc/omnimarket/nodes/node_swarm_fanout_effect/contract.yamlsrc/omnimarket/nodes/node_swarm_fanout_effect/handlers/handler_swarm_fanout.pysrc/omnimarket/nodes/node_swarm_fanout_effect/metadata.yamlsrc/omnimarket/nodes/node_swarm_fanout_effect/models/model_swarm_fanout_request.pysrc/omnimarket/nodes/node_swarm_fanout_effect/models/model_swarm_fanout_result.pysrc/omnimarket/nodes/node_swarm_fanout_effect/tests/test_handler_swarm_fanout.pysrc/omnimarket/nodes/node_swarm_fanout_effect/tests/test_models.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/__init__.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/contract.yamlsrc/omnimarket/nodes/node_swarm_fanout_orchestrator/handlers/__init__.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/handlers/handler_swarm_fanout.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/metadata.yamlsrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/__init__.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/enums.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_subtask.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_config.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_dispatch.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_endpoint.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_fanout_request.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_fanout_result.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_subtask_assignment.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/models/model_swarm_subtask_result.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/tests/__init__.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/tests/test_handler_swarm_fanout.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/tests/test_handler_swarm_fanout_queue.pysrc/omnimarket/nodes/node_swarm_fanout_orchestrator/tests/test_models.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/__init__.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/contract.yamlsrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/handlers/__init__.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/handlers/handler_swarm_fleet_discovery.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/metadata.yamlsrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/__init__.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/model_fleet_discovery_request.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/models/model_fleet_discovery_result.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/tests/__init__.pysrc/omnimarket/nodes/node_swarm_fleet_discovery_effect/tests/test_handler_swarm_fleet_discovery.pysrc/omnimarket/nodes/node_swarm_registry_compute/contract.yamlsrc/omnimarket/nodes/node_swarm_registry_compute/contracts/endpoint_registry.yamlsrc/omnimarket/nodes/node_swarm_registry_compute/handlers/handler_swarm_registry.pysrc/omnimarket/nodes/node_swarm_registry_compute/models/model_swarm_endpoint_selection_request.pysrc/omnimarket/nodes/node_swarm_registry_compute/models/model_swarm_endpoint_selection_result.pysrc/omnimarket/nodes/node_swarm_subtask_state_reducer/__init__.pysrc/omnimarket/nodes/node_swarm_subtask_state_reducer/contract.yamlsrc/omnimarket/nodes/node_swarm_subtask_state_reducer/handlers/__init__.pysrc/omnimarket/nodes/node_swarm_subtask_state_reducer/handlers/handler_swarm_subtask_state.pysrc/omnimarket/nodes/node_swarm_subtask_state_reducer/metadata.yaml
💤 Files with no reviewable changes (8)
- src/omnimarket/nodes/node_swarm_fanout_effect/handlers/handler_swarm_fanout.py
- src/omnimarket/nodes/node_swarm_fanout_effect/contract.yaml
- src/omnimarket/nodes/node_projection_registration/contract.yaml
- src/omnimarket/nodes/node_swarm_fanout_effect/metadata.yaml
- src/omnimarket/nodes/node_swarm_fanout_effect/models/model_swarm_fanout_result.py
- src/omnimarket/nodes/node_swarm_fanout_effect/models/model_swarm_fanout_request.py
- src/omnimarket/nodes/node_swarm_fanout_effect/tests/test_models.py
- src/omnimarket/nodes/node_swarm_fanout_effect/tests/test_handler_swarm_fanout.py
3169559 to
b6632bd
Compare
✅ Architectural Review — PASSEDErrors: 0 What this checks
No architectural violations found. Powered by node_pr_review_bot |
✅ PR Review Bot — CLEANFindings: 0
Verdict semantics
Powered by node_pr_review_bot — FSM pipeline with multi-model review fan-out |
|
| Verdict | Meaning | Blocks merge? |
|---|---|---|
passed |
No critical/error findings | No |
blocked |
CRITICAL or ERROR findings found | Yes |
degraded |
All models unavailable (infra) | No (pilot) |
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)
41bcada to
8fa014d
Compare
Summary
Verification
Evidence-Ticket: OMN-12245
Evidence-Source: OCC#1790
Guard-Source: OCC#1791
hotfix-evidence: OCC-1790
backmerge-for: #933