Repository navigation
test(OMN-10400): prove orchestrated merge sweep and session baseline - #465
Conversation
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (40)
📝 WalkthroughWalkthroughAdds a CLI reporting system with typed Pydantic models and multiple renderers, a new operator script to run the orchestrated merge-sweep workflow (with live effects and git worktree handling), tri-state PR required-check evaluation, PR-polish command emission, deterministic session orchestration fixtures, and broad test coverage and contract metadata. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant Script as run_orchestrated_merge_sweep_workflow
participant GitHub
participant Compute as NodeMergeSweep
participant Triage as TriageOrchestrator
participant Reducer as MergeSweepStateReducer
participant Effect as EffectHandlers
participant Classify as SweepOutcomeClassify
Caller->>Script: invoke (--repos, --execute?)
Script->>GitHub: fetch branch protection & open PRs
Script->>Compute: compute merge-sweep (ModelMergeSweepRequest)
Compute-->>Script: ModelMergeSweepResult
Script->>Triage: triage (emit commands)
Triage-->>Script: command list (merge/ci/polish/etc)
Script->>Reducer: reduce commands -> state
Reducer-->>Script: ModelMergeSweepState
alt --execute
loop for each command
Script->>Effect: execute effect async (auto-merge/ci-rerun/polish)
Effect-->>Script: dispatch event
Script->>Classify: classify event -> outcome
Classify-->>Script: outcome enum
end
else dry-run
Script->>Script: log planned commands
end
Script->>Script: summarize counts & exit with code
Script-->>Caller: exit code (0/1)
sequenceDiagram
participant Triage as TriageOrchestrator
participant Request as ModelTriageRequest
participant TrackB as Track B PR
participant Polish as PRPolishHandler
participant Classify as SweepOutcomeClassify
Triage->>Request: inspect emit_pr_polish_commands & dry_run
alt emit_pr_polish_commands == true
Triage->>TrackB: evaluate required checks
alt checks failed (terminal)
Triage->>Polish: emit ModelPrPolishStartCommand (dry_run flag)
Polish-->>Triage: ModelPrPolishCompletedEvent (extra.final_phase)
Triage->>Classify: classify PR_POLISH_COMPLETED (final_phase)
Classify-->>Triage: SUCCESS/FAILED/DEGRADED
else checks not failed
Triage->>Triage: skip polish emission
end
else
Triage->>Triage: suppress polish emission
end
Triage->>Triage: deduplicate total_prs by (repo, pr_number)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 0/5 reviews remaining, refill in 3 minutes and 8 seconds. Comment |
|
| 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)
There was a problem hiding this comment.
Actionable comments posted: 10
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_merge_sweep_triage_orchestrator/handlers/handler_triage.py (1)
355-383:⚠️ Potential issue | 🟠 Major | ⚡ Quick winGate reruns and rebases on terminal failures, not any non-pass state.
These branches still use
not pr.required_checks_pass, so aB_POLISHpayload withrequired_checks_pending=Truecan fan out a live CI rerun/rebase. The compute side now distinguishes terminal failure from pending; this orchestrator needs the same predicate or the tri-state fix is easy to bypass with older or manually-constructed inputs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/omnimarket/nodes/node_merge_sweep_triage_orchestrator/handlers/handler_triage.py` around lines 355 - 383, The current branches for CI rerun/rebase use the brittle predicate "not pr.required_checks_pass" which treats pending checks as failures; update both conditional guards that now read "and not pr.required_checks_pass" (the MERGEABLE+BLOCKED rerun path that calls _resolve_failing_run_id and returns ModelCiRerunCommand, and the MERGEABLE+BEHIND rebase path) to explicitly require terminal failure instead of any non-pass state—i.e., replace the predicate with a tri-state-aware check such as "and pr.required_checks_failed" or "and (not pr.required_checks_pass and not pr.required_checks_pending)" depending on which property exists in the PR model so pending checks do not trigger reruns/rebases.src/omnimarket/nodes/node_merge_sweep_compute/handlers/handler_merge_sweep.py (1)
465-489:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse the reducer’s emitted merge order here.
triage_recordsis created fromtrack_abefore the orchestrator runs, and lines 479-483 rebuildorderedfrom that same tuple. As written,use_lifecycle_ordering=Truejust round-trips the original Track A order instead of applying the lifecycle/reducer ordering.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/omnimarket/nodes/node_merge_sweep_compute/handlers/handler_merge_sweep.py` around lines 465 - 489, The current code rebuilds ordered from triage_records (which mirrors track_a) so use_lifecycle_ordering does not apply the reducer/orchestrator merge ordering; change the construction to iterate the reducer-emitted merge sequence (the merge_prs passed by the orchestrator / recorded by _NoopMerge) instead of triage_records: keep the pr_lookup = {(c.pr.repo, c.pr.number): c for c in track_a} and the seen set, then for each entry in merge_prs (or whatever variable holds the reducer's MERGE intent order) form the same key and append pr_lookup[key] when present, then finally append any remaining track_a stragglers as before; ensure you reference the reducer/orchestrator merge_prs variable rather than triage_records so use_lifecycle_ordering actually applies the lifecycle order.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/reference/2026-04-28-market-skill-baseline.md`:
- Around line 3-5: Remove the regenerated, timestamped execution transcript and
any volatile capture state from the public baseline doc (e.g., strings like
`2026-04-30T16:49:31.241546+00:00`, `Baseline window: 2026-04-30`, and the `Repo
root: <omnimarket>` note); retain only stable, contract-level baseline facts and
descriptions. Move the detailed historical run output and any workspace/ticket
identifiers to a non-public/generated artifact or internal storage, and replace
the removed sections with a short note pointing to the internal artifact or
stating that transcripts are available privately.
In `@scripts/run_orchestrated_merge_sweep_workflow.py`:
- Around line 229-263: _prepare_polish_worktree currently always uses the global
REPO_ROOT and runs git operations there which breaks when repo != the local
checkout; change it to resolve the target checkout for the incoming repo (i.e.
call the existing repo→checkout resolver or add a new helper) and use that
checkout path in place of REPO_ROOT for the _pr_head call,
current_sha/_is_clean_worktree checks, _worktrees_for_branch lookup, and the git
_run fetch/worktree commands, or if you do not yet support multi-repo workspaces
add a hard guard at the top of _prepare_polish_worktree that raises if repo is
not the local repo name (e.g. not "omnimarket"); update references to REPO_ROOT
in this function to the resolved checkout Path so all branch/SHA checks and git
fetch/worktree operations act against the correct repository.
- Around line 371-406: The ModelPrPolishStartCommand branch currently prepares a
worktree and calls run_live_pr_polish even when execute is false; guard that
branch with the same execute short-circuit used below so planning/dry-run
doesn't perform git actions: before calling _prepare_polish_worktree, check the
execute flag (the same condition used by the existing "if not execute" block)
and if not executing just _log the planned command (use _log and _dump_model on
command) and return []; otherwise proceed to call _prepare_polish_worktree,
run_live_pr_polish, and always call _cleanup_polish_worktree in the finally
block as currently implemented.
In `@src/omnimarket/cli/reporting.py`:
- Around line 137-177: The report builder build_report_from_merge_sweep_result
currently hardcodes status = EnumMarketCliStatus.SUCCESS; change it to derive
the report status from result.status (e.g., map result.status == "error" to
EnumMarketCliStatus.FAILURE and result.status == "warning"/"partial" to an
appropriate enum value, otherwise SUCCESS) and use that mapped value when
constructing ModelMarketCliReport so the report status matches the actual
result.status.
In `@src/omnimarket/nodes/node_merge_sweep_compute/__main__.py`:
- Around line 101-112: The check-evaluation logic currently only treats
conclusion == "SUCCESS" as passing and misses legacy StatusContext success and
non-failing CheckRun conclusions; update the block that computes conclusion and
status (variables conclusion, status, and the surrounding loop that sets
failed/pending using failed_conclusions) so that it treats status == "SUCCESS"
as a passing check and treats conclusion in {"SUCCESS","NEUTRAL","SKIPPED"} as
passing as well (i.e., skip marking failed or pending when conclusion is one of
those), leaving failed_conclusions handling intact for explicit failure reasons.
In
`@src/omnimarket/nodes/node_merge_sweep_triage_orchestrator/handlers/handler_triage.py`:
- Around line 545-548: The code only treats checks with conclusion == "FAILURE"
as failures when extracting details_url/run_id, but
node_merge_sweep_compute.consumer._required_check_state() treats
ACTION_REQUIRED, CANCELLED, FAILED, STARTUP_FAILURE, STALE, and TIMED_OUT as
terminal failures too; update the condition in the resolver(s) (the blocks using
check.get("conclusion"), details_url, and _run_id_from_details_url, including
the other resolver at the other occurrence) to test membership in a failure set
(e.g.
{"FAILURE","ACTION_REQUIRED","CANCELLED","FAILED","STARTUP_FAILURE","STALE","TIMED_OUT"})
so run/job resolution and failing-job-name scanning run for all terminal failure
conclusions.
In
`@src/omnimarket/nodes/node_session_orchestrator/handlers/handler_session_orchestrator.py`:
- Around line 1434-1448: The handler currently mutates process-wide os.environ
keys ONEX_STATE_DIR and ONEX_PARENT_SESSION_ID around calling
NodeDispatchWorker().handle(command), causing non-reentrancy and races; instead,
change HandlerSessionOrchestrator to stop touching os.environ and pass the
context explicitly into NodeDispatchWorker (e.g., construct
NodeDispatchWorker(state_dir=state_dir, parent_session_id=session_id) or call
NodeDispatchWorker().handle(command, state_dir=state_dir,
parent_session_id=session_id)), and update the NodeDispatchWorker class
(constructor and/or handle method) to accept and use those parameters internally
wherever it currently reads os.environ for
ONEX_STATE_DIR/ONEX_PARENT_SESSION_ID. Ensure no global env mutation remains in
handler_session_orchestrator while preserving existing behavior by using the
passed-in values.
- Around line 1050-1055: The code currently treats an empty result from
self._load_linear_fixture when ONEX_SESSION_ORCHESTRATOR_LINEAR_FIXTURE is set
as success by returning [], which silences setup failures; change the behavior
in the handler where fixture_path =
os.environ.get("ONEX_SESSION_ORCHESTRATOR_LINEAR_FIXTURE", "") is read so that
if fixture_path is set but self._load_linear_fixture(fixture_path) returns an
empty or falsy tickets list, the handler fails fast (raise a clear exception or
return an error status) instead of returning []—update the block around
fixture_path/_load_linear_fixture in handler_session_orchestrator.py to log an
explicit error including fixture_path and either raise a ValueError or propagate
an error state so Phase 2 does not complete successfully when the configured
fixture yields zero tickets.
- Around line 1142-1162: The fixture loader _load_linear_fixture currently only
validates the top-level container and can return nodes that break _score_tickets
which expects GraphQL-style nested objects (e.g., labels["nodes"],
children["nodes"]); update _load_linear_fixture to validate each node's shape
before returning: ensure each node is a dict and that required nested fields
like "labels" and "children" exist and are dicts with a "nodes" list (or coerce
simple lists into {"nodes": [...]}) and otherwise raise SessionLinearFetchError
or skip the malformed node so that _score_tickets never receives invalid shapes;
reference the function names _load_linear_fixture and _score_tickets when making
the change.
In `@tests/unit/nodes/node_ticket_pipeline/test_main_cli_outputs.py`:
- Around line 23-35: The subprocess.run call in
tests/unit/nodes/node_ticket_pipeline/test_main_cli_outputs.py should include a
timeout to avoid CI hangs; add a timeout parameter (e.g. timeout=30) to the
subprocess.run invocation that runs omnimarket.nodes.node_ticket_pipeline and
wrap the call in a try/except that catches subprocess.TimeoutExpired then fail
the test explicitly (raise or assert False with a clear message) so a hung CLI
produces a deterministic test failure rather than stalling CI.
---
Outside diff comments:
In
`@src/omnimarket/nodes/node_merge_sweep_compute/handlers/handler_merge_sweep.py`:
- Around line 465-489: The current code rebuilds ordered from triage_records
(which mirrors track_a) so use_lifecycle_ordering does not apply the
reducer/orchestrator merge ordering; change the construction to iterate the
reducer-emitted merge sequence (the merge_prs passed by the orchestrator /
recorded by _NoopMerge) instead of triage_records: keep the pr_lookup =
{(c.pr.repo, c.pr.number): c for c in track_a} and the seen set, then for each
entry in merge_prs (or whatever variable holds the reducer's MERGE intent order)
form the same key and append pr_lookup[key] when present, then finally append
any remaining track_a stragglers as before; ensure you reference the
reducer/orchestrator merge_prs variable rather than triage_records so
use_lifecycle_ordering actually applies the lifecycle order.
In
`@src/omnimarket/nodes/node_merge_sweep_triage_orchestrator/handlers/handler_triage.py`:
- Around line 355-383: The current branches for CI rerun/rebase use the brittle
predicate "not pr.required_checks_pass" which treats pending checks as failures;
update both conditional guards that now read "and not pr.required_checks_pass"
(the MERGEABLE+BLOCKED rerun path that calls _resolve_failing_run_id and returns
ModelCiRerunCommand, and the MERGEABLE+BEHIND rebase path) to explicitly require
terminal failure instead of any non-pass state—i.e., replace the predicate with
a tri-state-aware check such as "and pr.required_checks_failed" or "and (not
pr.required_checks_pass and not pr.required_checks_pending)" depending on which
property exists in the PR model so pending checks do not trigger reruns/rebases.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 938077f1-91f4-46d1-a2ff-7e50c0cda443
📒 Files selected for processing (54)
contracts/OMN-10400.yamldocs/reference/2026-04-28-market-skill-baseline.jsondocs/reference/2026-04-28-market-skill-baseline.mdscripts/run_orchestrated_merge_sweep_workflow.pysrc/omnimarket/cli/__init__.pysrc/omnimarket/cli/args.pysrc/omnimarket/cli/output/__init__.pysrc/omnimarket/cli/output/handlers/__init__.pysrc/omnimarket/cli/output/handlers/handler_json.pysrc/omnimarket/cli/output/handlers/handler_markdown.pysrc/omnimarket/cli/output/handlers/handler_text.pysrc/omnimarket/cli/output/handlers/handler_yaml.pysrc/omnimarket/cli/output/protocol.pysrc/omnimarket/cli/output/registry.pysrc/omnimarket/cli/reporting.pysrc/omnimarket/market_skill_baseline.pysrc/omnimarket/models/cli_report.pysrc/omnimarket/nodes/node_merge_sweep_compute/__main__.pysrc/omnimarket/nodes/node_merge_sweep_compute/consumer.pysrc/omnimarket/nodes/node_merge_sweep_compute/handlers/handler_merge_sweep.pysrc/omnimarket/nodes/node_merge_sweep_triage_orchestrator/contract.yamlsrc/omnimarket/nodes/node_merge_sweep_triage_orchestrator/handlers/handler_triage.pysrc/omnimarket/nodes/node_merge_sweep_triage_orchestrator/models/model_triage_request.pysrc/omnimarket/nodes/node_session_orchestrator/handlers/handler_session_orchestrator.pysrc/omnimarket/nodes/node_session_orchestrator/tests/test_handler_session_orchestrator.pysrc/omnimarket/nodes/node_sweep_outcome_classify/handlers/handler_outcome_classify.pysrc/omnimarket/nodes/node_sweep_outcome_classify/models/model_sweep_outcome.pysrc/omnimarket/nodes/node_ticket_pipeline/__main__.pytests/test_codex_runtime_client.pytests/test_golden_chain_merge_sweep.pytests/test_golden_chain_merge_sweep_executor.pytests/test_golden_chain_ticket_pipeline.pytests/test_market_skill_smokes.pytests/test_no_cross_node_reach_in.pytests/test_orchestrated_merge_sweep_workflow.pytests/test_sweep_outcome_classify.pytests/test_triage_orchestrator.pytests/test_triage_phase2_emit_rules.pytests/unit/cli/__init__.pytests/unit/cli/_fixtures.pytests/unit/cli/output/__init__.pytests/unit/cli/output/handlers/__init__.pytests/unit/cli/output/handlers/test_handler_json.pytests/unit/cli/output/handlers/test_handler_markdown.pytests/unit/cli/output/handlers/test_handler_text.pytests/unit/cli/output/handlers/test_handler_yaml.pytests/unit/cli/output/test_registry.pytests/unit/cli/test_args.pytests/unit/cli/test_reporting.pytests/unit/models/test_cli_report.pytests/unit/nodes/node_merge_sweep_compute/__init__.pytests/unit/nodes/node_merge_sweep_compute/test_main_cli_outputs.pytests/unit/nodes/node_ticket_pipeline/__init__.pytests/unit/nodes/node_ticket_pipeline/test_main_cli_outputs.py
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/run_orchestrated_merge_sweep_workflow.py`:
- Around line 409-417: Polish evidence is being returned as a reducer outcome
which blocks later real remediation outcomes; stop emitting a reducible outcome
for polish by not returning the classified outcome from the polish handler.
Specifically, in run_orchestrated_merge_sweep_workflow.py replace the return of
_classify_outcome(_polish_completed_to_input(...)) (functions
_polish_completed_to_input and _classify_outcome) with an empty list (or
otherwise mark the result as non-reducer-only evidence) so
ModelPrPolishStartCommand/HandlerTriageOrchestrator polish events do not consume
the HandlerMergeSweepStateReducer dedup slot keyed by repo#pr_number.
- Around line 201-214: The function _worktrees_for_branch currently matches
branches by suffix (raw_branch.endswith(f"/{branch}")), which can incorrectly
match unrelated refs; update _worktrees_for_branch to compare the full ref
exactly (e.g., raw_branch == f"refs/heads/{branch}") so only worktrees whose
branch ref equals the exact ref are returned, and ensure any callers like
_prepare_polish_worktree use the corrected _worktrees_for_branch result.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7354c1d4-3183-46a4-b013-983ca3b36ed7
📒 Files selected for processing (4)
scripts/run_orchestrated_merge_sweep_workflow.pysrc/omnimarket/nodes/node_merge_sweep_compute/handlers/handler_merge_sweep.pytests/test_golden_chain_merge_sweep.pytests/test_orchestrated_merge_sweep_workflow.py
🚧 Files skipped from review as they are similar to previous changes (3)
- src/omnimarket/nodes/node_merge_sweep_compute/handlers/handler_merge_sweep.py
- tests/test_golden_chain_merge_sweep.py
- tests/test_orchestrated_merge_sweep_workflow.py
|
Added the next Codex skill shim: Scope:
Proof:
Commit: |
|
Added the next Codex skill shim: Scope:
Proof:
Commit: |
|
Added the next Codex skill shim: Scope:
Proof:
Commit: |
|
Added the final missing Codex skill shim in this pass: Scope:
Proof:
Commit: |
|
Corrected focus back to actual market-skill end-to-end proof. Ran the full market-owned skill baseline, not just Codex shim checks:
Result:
Committed refreshed durable evidence: Note: the current baseline runner is batch-style and prints after completion. If we want the exact operator experience of logs as each node runs inline, the next concrete improvement should be a streaming market-skill proof runner rather than more skill packaging. |
|
Added streaming market-skill proof output. New behavior:
Proof run: Result:
Additional checks:
Commit: |
|
Pushed hardening fixes in Local verification after the merge:
All previously open CodeRabbit review threads are resolved. |
Ticket
OMN-10400
Summary
Live proof
uv run python scripts/run_orchestrated_merge_sweep_workflow.py --repos OmniNode-ai/omnimarket --executeci_rerun=1,armed=2,failed=0,terminal_emitted=True.Runtime adapter coverage now in baseline
aislop_sweep: adapter dispatch scans a controlled repo and returns real findings.pr_lifecycle_orchestrator/merge-sweep: adapter dispatch runs the real PR lifecycle FSM with deterministic sub-handlers and writesmerge-sweep/<run_id>/result.json.pr_polish: adapter dispatch runs the pure polish FSM todone.local_review: adapter dispatch runs the pure review FSM todone.coderabbit_triage: adapter dispatch runs real CodeRabbit classification over deterministic GraphQL review-thread shapes.session_bootstrap: adapter dispatch runs the real handler, writes contract snapshot and cron IDs.session_orchestrator: adapter dispatch runs the real handler, scores fixture Linear tickets, compiles dispatch specs, and writes durable session artifacts.ticket_pipeline: adapter dispatch runs PRE_FLIGHT plus compile-only IMPLEMENT and honestly stops at unwired LOCAL_REVIEW.Verification
PatternBBrokerClienttoCodexRuntimeRequestAdapter, removed the misleading public broker type names, and updated source plus packaged Codex skill shims to describe the handler/adapter path.uv run ruff format --check src/omnimarket/adapters/codex/runtime_client.py tests/test_codex_runtime_client.py tests/test_codex_plugin_shims.py scripts/generate_adapters.py src/omnimarket/adapters/codex/topics.py-> passeduv run ruff check src/omnimarket/adapters/codex/runtime_client.py tests/test_codex_runtime_client.py tests/test_codex_plugin_shims.py scripts/generate_adapters.py src/omnimarket/adapters/codex/topics.py-> passeduv run pytest tests/test_codex_runtime_client.py tests/test_install_codex_skills.py tests/test_codex_plugin_shims.py -q-> 37 passeduv run pytest tests/test_codex_runtime_client.py tests/test_golden_chain_ticket_pipeline.py tests/test_market_skill_smokes.py -q-> 52 passeduv run pytest tests/test_codex_runtime_client.py tests/test_golden_chain_coderabbit_triage.py tests/test_market_skill_smokes.py -q-> 61 passeduv run pytest tests/test_codex_runtime_client.py tests/unit/nodes/node_pr_lifecycle_orchestrator/test_main_cli.py tests/test_golden_chain_pr_lifecycle_orchestrator.py tests/test_market_skill_smokes.py -q-> 61 passeduv run pytest tests/test_codex_runtime_client.py src/omnimarket/nodes/node_session_orchestrator/tests/test_handler_session_orchestrator.py tests/test_market_skill_smokes.py -q-> 60 passeduv run mypy --strict src/omnimarket/nodes/node_merge_sweep_triage_orchestrator/handlers/handler_triage.py src/omnimarket/nodes/node_session_orchestrator/handlers/handler_session_orchestrator.py src/omnimarket/market_skill_baseline.pyuv run python scripts/run_market_skill_baseline.py --strict --json-out docs/reference/2026-04-28-market-skill-baseline.json --markdown-out docs/reference/2026-04-28-market-skill-baseline.md-> 8 working / 0 degraded / 0 failinguv run ruff check tests/test_codex_runtime_client.py src/omnimarket/market_skill_baseline.py && uv run ruff format --check tests/test_codex_runtime_client.py src/omnimarket/market_skill_baseline.pySummary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests