Skip to content

feat(OMN-7972): HandlerReportPoster — final PR review summary comment - #121

Merged
jonahgabriel merged 3 commits into
mainfrom
jonah/omn-7972-report-poster
Apr 9, 2026
Merged

jonahgabriel merged 3 commits into
mainfrom
jonah/omn-7972-report-poster

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Apr 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Implements HandlerReportPoster satisfying ProtocolReportPoster from handler_fsm.py
  • Aggregates findings by severity (CRITICAL/MAJOR/MINOR/NIT) into a markdown table and thread resolution counts (PASS/FAIL/pending) into a second table
  • Posts the formatted summary via injected ProtocolGitHubBridge — handler stays unit-testable without network access
  • Dry-run mode logs the body at INFO level and skips the GitHub API call
  • Exports HandlerReportPoster, ProtocolGitHubBridge, and build_summary_comment from handlers/__init__.py
  • Fixes pre-existing no-hardcoded-topics hook failures on claude_code.yaml (generated event registry), lint_no_hardcoded_topics.py (the detector itself), and structured_logger.py by adding per-file excludes to .pre-commit-config.yaml

Test plan

  • Import HandlerReportPoster from omnimarket.nodes.node_pr_review_bot.handlers
  • Instantiate with a mock ProtocolGitHubBridge and verify post_summary calls post_pr_comment with expected markdown body
  • Verify dry-run skips post_pr_comment
  • Verify build_summary_comment renders verdict badge, findings table, and thread table correctly
  • pre-commit run --all-files passes (all hooks green)

Summary by CodeRabbit

  • New Features

    • Added ability to build and post comprehensive PR review summaries, including categorized findings, thread-status summaries, and verdict-specific messaging; new report-poster and GitHub-bridge components are exposed for use.
  • Chores

    • Updated pre-commit hook configuration to exclude specific paths from hardcoded-topic checks.

@coderabbitai

coderabbitai Bot commented Apr 9, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@jonahgabriel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 41 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 4 minutes and 41 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e60e40b9-037c-47b9-96eb-1bce6e98b239

📥 Commits

Reviewing files that changed from the base of the PR and between 9edf3a6 and 0fff774.

📒 Files selected for processing (4)
  • .pre-commit-config.yaml
  • src/omnimarket/nodes/node_pr_review_bot/contract.yaml
  • src/omnimarket/nodes/node_pr_review_bot/handlers/__init__.py
  • src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py
📝 Walkthrough

Walkthrough

Added a new handler module that builds and posts PR review summary comments (with dry-run support) via a GitHub bridge protocol, updated package exports to expose the poster and helpers, and excluded three files from a pre-commit hook.

Changes

Cohort / File(s) Summary
Pre-commit Configuration
\.pre-commit-config.yaml
Added an exclude pattern to the no-hardcoded-topics hook to skip three specific paths (src/omnimarket/nodes/node_emit_daemon/registries/claude_code.yaml, scripts/lint_no_hardcoded_topics.py, src/omnimarket/logging/structured_logger.py).
Handler Module Implementation
src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py
New module: defines ProtocolGitHubBridge, formatting helpers _build_findings_table and _build_thread_summary, build_summary_comment to assemble verdict+metadata+tables, and HandlerReportPoster which posts or logs comments (supports dry-run).
Package Exports
src/omnimarket/nodes/node_pr_review_bot/handlers/__init__.py
Extended __all__ to export HandlerReportPoster, ProtocolGitHubBridge, and build_summary_comment from the handlers package.

Sequence Diagram

sequenceDiagram
    actor Caller
    participant HandlerReportPoster
    participant build_summary_comment
    participant ProtocolGitHubBridge

    Caller->>HandlerReportPoster: post_summary(pr_number, repo, verdict, dry_run)
    activate HandlerReportPoster

    HandlerReportPoster->>build_summary_comment: build_summary_comment(verdict, findings, thread_states)
    activate build_summary_comment
    build_summary_comment->>build_summary_comment: _build_findings_table(findings)
    build_summary_comment->>build_summary_comment: _build_thread_summary(thread_states)
    build_summary_comment-->>HandlerReportPoster: comment_body
    deactivate build_summary_comment

    alt dry_run = true
        HandlerReportPoster->>HandlerReportPoster: log would-be comment
    else dry_run = false
        HandlerReportPoster->>ProtocolGitHubBridge: post_pr_comment(repo, pr_number, body)
        activate ProtocolGitHubBridge
        ProtocolGitHubBridge-->>HandlerReportPoster: success/ack
        deactivate ProtocolGitHubBridge
        HandlerReportPoster->>HandlerReportPoster: log completion
    end

    deactivate HandlerReportPoster
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped in with a bonnet of code,
Spun verdicts and tables down the road.
Findings queue up in tidy rows,
A comment blooms where the GitHub wind blows. 🌿

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main feature addition: implementing HandlerReportPoster for generating final PR review summary comments, with clear task tracking (OMN-7972).
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-7972-report-poster

Comment @coderabbitai help to get the list of available commands and usage tips.

Base automatically changed from jonah/omn-7966-pr-review-bot-fsm to jonah/omn-7964-pr-review-bot-scaffold April 9, 2026 07:56
@jonahgabriel
jonahgabriel changed the base branch from jonah/omn-7964-pr-review-bot-scaffold to main April 9, 2026 08:03
@jonahgabriel
jonahgabriel force-pushed the jonah/omn-7972-report-poster branch from fea58ba to 11db0b1 Compare April 9, 2026 08:03
@jonahgabriel
jonahgabriel enabled auto-merge April 9, 2026 08:04
@jonahgabriel
jonahgabriel added this pull request to the merge queue Apr 9, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Apr 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/omnimarket/nodes/node_pr_review_bot/models/models.py (1)

50-63: Consider adding validation that end_line >= start_line.

The DiffHunk model validates that both line numbers are >= 1, but doesn't enforce end_line >= start_line. An invalid hunk with end_line < start_line would pass validation.

♻️ Add model validator
+from pydantic import model_validator
+
 class DiffHunk(BaseModel):
     """A single contiguous segment of a unified diff for one file."""

     model_config = ConfigDict(frozen=True, extra="forbid")

     file_path: str = Field(..., description="Repo-relative file path.")
     start_line: int = Field(
         ..., ge=1, description="First line of the hunk (1-indexed)."
     )
     end_line: int = Field(..., ge=1, description="Last line of the hunk (inclusive).")
     content: str = Field(..., description="Raw unified diff content for this hunk.")
     is_new_file: bool = Field(default=False)
     is_deleted_file: bool = Field(default=False)
+
+    `@model_validator`(mode="after")
+    def _check_line_range(self) -> "DiffHunk":
+        if self.end_line < self.start_line:
+            raise ValueError("end_line must be >= start_line")
+        return self
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/omnimarket/nodes/node_pr_review_bot/models/models.py` around lines 50 -
63, Add a model-level validator to DiffHunk that ensures end_line >= start_line:
implement a pydantic v2 model validator (e.g., `@model_validator`) on the DiffHunk
class which checks the start_line and end_line fields and raises a clear
ValueError if end_line < start_line, so invalid hunks are rejected during
validation; keep the existing model_config and field types untouched and update
the validation error message to reference DiffHunk/start_line/end_line for
clarity.
src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py (1)

73-88: Consider using Counter[EnumFindingSeverity] for type precision.

The counter is typed as Counter[str] but keys are EnumFindingSeverity values. Since StrEnum inherits from str, this works at runtime, but Counter[EnumFindingSeverity] would be more precise for static analysis.

♻️ Optional type refinement
-    counts: Counter[str] = Counter()
+    counts: Counter[EnumFindingSeverity] = Counter()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py`
around lines 73 - 88, The Counter in _build_findings_table is declared as
Counter[str] but its keys are EnumFindingSeverity instances; update the type to
Counter[EnumFindingSeverity] (or Counter[ReviewFinding.severity.__class__] if
that helps type checkers) and adjust any imports/annotations so the function
signature and local variable use Counter[EnumFindingSeverity] (refer to
_build_findings_table, ReviewFinding, and _SEVERITY_ORDER) to provide precise
static typing without changing runtime behavior.
src/omnimarket/nodes/node_pr_review_bot/handlers/handler_fsm.py (1)

336-340: Consider capturing now once to ensure timing consistency.

datetime.now(tz=UTC) is called twice in quick succession. While unlikely to cause issues, capturing it once ensures duration_ms and completed_at are computed from the same instant.

♻️ Suggested refactor
     def make_verdict(self, state: ModelPrReviewBotState) -> ReviewVerdict:
         """Derive the final ReviewVerdict from completed FSM state."""
         threads = state.thread_states
         threads_posted = sum(1 for t in threads if t.status != EnumThreadStatus.PENDING)
         threads_pass = sum(
             1 for t in threads if t.status == EnumThreadStatus.VERIFIED_PASS
         )
         threads_fail = sum(
             1 for t in threads if t.status == EnumThreadStatus.VERIFIED_FAIL
         )
         threads_pending = sum(
             1
             for t in threads
             if t.status in (EnumThreadStatus.PENDING, EnumThreadStatus.POSTED)
         )

         if threads_fail > 0:
             verdict = EnumPrVerdict.BLOCKING_ISSUE
         elif state.findings:
             verdict = EnumPrVerdict.RISKS_NOTED
         else:
             verdict = EnumPrVerdict.CLEAN

+        now = datetime.now(tz=UTC)
         return ReviewVerdict(
             correlation_id=state.correlation_id,
             pr_number=state.pr_number,
             repo=state.repo,
             verdict=verdict,
             total_findings=len(state.findings),
             threads_posted=threads_posted,
             threads_verified_pass=threads_pass,
             threads_verified_fail=threads_fail,
             threads_pending=threads_pending,
             judge_model_used="",  # set by caller from ReviewRequest
             duration_ms=int(
-                (datetime.now(tz=UTC) - state.started_at).total_seconds() * 1000
+                (now - state.started_at).total_seconds() * 1000
             ),
-            completed_at=datetime.now(tz=UTC),
+            completed_at=now,
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_fsm.py` around lines
336 - 340, The two calls to datetime.now(tz=UTC) in the block that sets
duration_ms and completed_at (inside the handler function in handler_fsm.py
where state.started_at is used) should be unified: capture a single timestamp
(e.g., now = datetime.now(tz=UTC)) and use that same now to compute duration_ms
= int((now - state.started_at).total_seconds() * 1000) and set completed_at=now
so both values are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/omnimarket/nodes/node_pr_review_bot/contract.yaml`:
- Around line 28-32: The contract's fsm_transition operation currently points
HandlerPrReviewBot to module
"omnimarket.nodes.node_pr_review_bot.handlers.handler_pr_review_bot" which does
not exist; update the module value for the operation named "fsm_transition"
(handler name "HandlerPrReviewBot") to
"omnimarket.nodes.node_pr_review_bot.handlers.handler_fsm" so the FSM handler
resolves to the existing handler_fsm implementation.
- Around line 73-81: The contract references non-existent model files; update
input_model and output_model to the actual model classes by replacing name
"ModelPrReviewBotStartCommand" with "ReviewRequest" and name
"ModelPrReviewBotCompletedEvent" with "ReviewVerdict", and change both module
paths to "omnimarket.nodes.node_pr_review_bot.models.models" so the contract
points to the real ReviewRequest (input) and ReviewVerdict (output) classes.

---

Nitpick comments:
In `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_fsm.py`:
- Around line 336-340: The two calls to datetime.now(tz=UTC) in the block that
sets duration_ms and completed_at (inside the handler function in handler_fsm.py
where state.started_at is used) should be unified: capture a single timestamp
(e.g., now = datetime.now(tz=UTC)) and use that same now to compute duration_ms
= int((now - state.started_at).total_seconds() * 1000) and set completed_at=now
so both values are consistent.

In `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py`:
- Around line 73-88: The Counter in _build_findings_table is declared as
Counter[str] but its keys are EnumFindingSeverity instances; update the type to
Counter[EnumFindingSeverity] (or Counter[ReviewFinding.severity.__class__] if
that helps type checkers) and adjust any imports/annotations so the function
signature and local variable use Counter[EnumFindingSeverity] (refer to
_build_findings_table, ReviewFinding, and _SEVERITY_ORDER) to provide precise
static typing without changing runtime behavior.

In `@src/omnimarket/nodes/node_pr_review_bot/models/models.py`:
- Around line 50-63: Add a model-level validator to DiffHunk that ensures
end_line >= start_line: implement a pydantic v2 model validator (e.g.,
`@model_validator`) on the DiffHunk class which checks the start_line and end_line
fields and raises a clear ValueError if end_line < start_line, so invalid hunks
are rejected during validation; keep the existing model_config and field types
untouched and update the validation error message to reference
DiffHunk/start_line/end_line for clarity.
🪄 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: a3f716cc-9b0b-4e77-bbf1-a1f8492b02e0

📥 Commits

Reviewing files that changed from the base of the PR and between e8ad755 and 11db0b1.

📒 Files selected for processing (12)
  • .pre-commit-config.yaml
  • src/omnimarket/nodes/node_build_loop_orchestrator/README.md
  • src/omnimarket/nodes/node_pr_review_bot/__init__.py
  • src/omnimarket/nodes/node_pr_review_bot/contract.yaml
  • src/omnimarket/nodes/node_pr_review_bot/handlers/__init__.py
  • src/omnimarket/nodes/node_pr_review_bot/handlers/handler_fsm.py
  • src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py
  • src/omnimarket/nodes/node_pr_review_bot/metadata.yaml
  • src/omnimarket/nodes/node_pr_review_bot/models/__init__.py
  • src/omnimarket/nodes/node_pr_review_bot/models/models.py
  • src/omnimarket/nodes/node_pr_review_bot/node.py
  • src/omnimarket/nodes/node_ticket_pipeline/README.md

Comment thread src/omnimarket/nodes/node_pr_review_bot/contract.yaml
Comment thread src/omnimarket/nodes/node_pr_review_bot/contract.yaml
@jonahgabriel
jonahgabriel force-pushed the jonah/omn-7972-report-poster branch from 11db0b1 to 33e5cf3 Compare April 9, 2026 10:00
@jonahgabriel
jonahgabriel enabled auto-merge April 9, 2026 10:01
@jonahgabriel jonahgabriel changed the title feat(omn-7972): HandlerReportPoster — final PR review summary comment feat(OMN-7972): HandlerReportPoster — final PR review summary comment Apr 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py`:
- Around line 187-209: The constructor for HandlerReportPoster currently
defaults findings and thread_states to empty tuples which allows posting
misleading summaries; change the API to require these values (remove the default
values in __init__) or add a precondition check at the start of post_summary
that compares verdict aggregates (e.g., ReviewVerdict.total_findings and any
thread counts on verdict) against self._findings and self._thread_states and
raise an exception or abort when they are inconsistent; implement the check in
post_summary (before calling build_summary_comment) referencing self._findings,
self._thread_states, and the incoming verdict to fail fast and prevent posting
an incorrect summary.
- Around line 123-166: The build_summary_comment function omits the
model-authored narrative stored on ReviewVerdict (verdict.summary); update
build_summary_comment to include verdict.summary (e.g., insert a Summary section
or append the text after meta) when verdict.summary is non-empty so the rendered
PR comment shows the human-readable review summary along with the existing
header/meta/verdict_detail/findings and thread sections; reference
build_summary_comment and the ReviewVerdict object (verdict.summary) and ensure
you skip or omit the Summary section if verdict.summary is falsy.
🪄 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: 457b13f9-e34b-4c41-82d6-be0fd7e0bdc1

📥 Commits

Reviewing files that changed from the base of the PR and between 11db0b1 and 33e5cf3.

📒 Files selected for processing (3)
  • .pre-commit-config.yaml
  • src/omnimarket/nodes/node_pr_review_bot/handlers/__init__.py
  • src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py
✅ Files skipped from review due to trivial changes (2)
  • .pre-commit-config.yaml
  • src/omnimarket/nodes/node_pr_review_bot/handlers/init.py

@jonahgabriel
jonahgabriel force-pushed the jonah/omn-7972-report-poster branch from 33e5cf3 to 9edf3a6 Compare April 9, 2026 11:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py (1)

73-77: Consider using Counter[EnumFindingSeverity] for type precision.

The counter keys are EnumFindingSeverity values, not plain strings. While this works at runtime (StrEnum is a str subtype), the type hint could be more precise for mypy strict mode.

♻️ Proposed fix
 def _build_findings_table(findings: tuple[ReviewFinding, ...]) -> str:
     """Return a markdown table summarising finding counts by severity."""
-    counts: Counter[str] = Counter()
+    counts: Counter[EnumFindingSeverity] = Counter()
     for f in findings:
         counts[f.severity] += 1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py`
around lines 73 - 77, The Counter used in _build_findings_table currently types
keys as str but the keys are EnumFindingSeverity values from
ReviewFinding.severity; change the type of counts to
Counter[EnumFindingSeverity] (or Counter[ReviewFinding.severity's enum type]) so
static checkers like mypy treat keys precisely rather than as plain
strings—update the annotation for counts and any related type imports/usages to
reference EnumFindingSeverity and keep the runtime logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py`:
- Around line 73-77: The Counter used in _build_findings_table currently types
keys as str but the keys are EnumFindingSeverity values from
ReviewFinding.severity; change the type of counts to
Counter[EnumFindingSeverity] (or Counter[ReviewFinding.severity's enum type]) so
static checkers like mypy treat keys precisely rather than as plain
strings—update the annotation for counts and any related type imports/usages to
reference EnumFindingSeverity and keep the runtime logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 08670cf9-0b8b-475e-a49c-c03039709426

📥 Commits

Reviewing files that changed from the base of the PR and between 33e5cf3 and 9edf3a6.

📒 Files selected for processing (3)
  • .pre-commit-config.yaml
  • src/omnimarket/nodes/node_pr_review_bot/handlers/__init__.py
  • src/omnimarket/nodes/node_pr_review_bot/handlers/handler_report_poster.py
✅ Files skipped from review due to trivial changes (1)
  • .pre-commit-config.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/omnimarket/nodes/node_pr_review_bot/handlers/init.py

…ry comments

Implements ProtocolReportPoster from handler_fsm.py. Aggregates findings by
severity and thread resolution status into a markdown table + verdict badge,
then posts via ProtocolGitHubBridge. Dry-run mode logs instead of posting.

Also fixes pre-existing no-hardcoded-topics hook failures on generated registry
files (claude_code.yaml), the lint script itself, and structured_logger.py by
adding per-file exclusions to .pre-commit-config.yaml.
- contract.yaml: fix fsm_transition handler module (handler_pr_review_bot -> handler_fsm)
- contract.yaml: fix input/output model references (ReviewRequest/ReviewVerdict in models.models)
- handler_report_poster: include verdict.summary in rendered PR comment when non-empty
- handler_report_poster: make findings/thread_states required; add precondition guard in post_summary
@jonahgabriel
jonahgabriel force-pushed the jonah/omn-7972-report-poster branch from 75ca9a9 to e837594 Compare April 9, 2026 16:18
@jonahgabriel
jonahgabriel added this pull request to the merge queue Apr 9, 2026
Merged via the queue into main with commit f090f1e Apr 9, 2026
13 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-7972-report-poster branch April 9, 2026 16:28
jonahgabriel added a commit that referenced this pull request Aug 31, 2026
omnimarket carried the largest alert backlog in the org (74 of the 141 open
org-wide). 71 are closed here; the remaining 3 are deferred with a stated
reason rather than forced.

## Where the alerts actually live (70 of 74 are NOT in the shipped package)

Only 4 alerts are in the root `uv.lock`. The other 70 are in
`experiments/adk_eval/track_a_adk/uv.lock` — a standalone, generated ADK
subproject with its own pyproject, venv and build backend, which this repo's
own pyproject.toml (lines 762-768) documents as "not importable from the
omnimarket package root". Nothing in .pre-commit-config.yaml or
.github/workflows references that subtree, so its lock is scanned by
Dependabot but validated by nothing.

## Root uv.lock (2 alerts closed, 3 deferred)

- h2 4.3.0 -> 4.4.1 (+ hpack 4.1.0 -> 4.2.0) — CVE-2026-71554, alert #119

DEFERRED, not forced — transformers (#120 medium, #121 high, #122 high):
the fix requires transformers 5.x, and resolving it is not a version bump.
`uv lock --upgrade-package 'transformers>=5.5.0'` DOWNGRADES optimum
2.1.0 -> 1.17.1, REMOVES optimum-onnx entirely, and pulls 14 new packages
(datasets, evaluate, pandas, pyarrow, sentencepiece, typer, xxhash, ...).
transformers is transitive via adaptive-classifier / optimum / optimum-onnx
and has no direct import in src/. That is a dependency-stack migration, not
a security patch, so it is tracked as its own line on OMN-17184 instead of
being smuggled into this PR.

## experiments/adk_eval/track_a_adk (70 alerts closed)

Full `uv lock --upgrade` of the isolated subproject, closing every alert in
it, including 8 criticals/highs in litellm and the aiohttp, starlette, nltk,
sqlparse, cryptography, mcp, pyjwt, python-multipart, urllib3, joserfc,
authlib, httplib2, Mako, idna and pydantic-settings chains.

One constraint change was required: pytest was capped at `<9.0.0` and
pytest-asyncio at `<1.0.0`, which made alert #4 (CVE-2025-71176, needs
pytest >= 9.0.3) unreachable. Both caps were lifted together
(pytest >=9.0.3,<10; pytest-asyncio >=1.3.0,<2) because pytest-asyncio 0.x
itself pins pytest <9 — lifting only the pytest cap fails to resolve.

Verification: `uv lock --check` clean on both lockfiles. The subproject
`uv sync --all-extras` resolves and installs. Its suite runs 2 failed /
12 passed — the 2 failures are `tests/integration/test_server_e2e.py`
(::test_chat_stream asserts 404, ::test_collect_feedback connection error)
and are PRE-EXISTING: the identical 2-failed/12-passed result reproduces on
unmodified origin/dev in a separate baseline worktree. They need a live
server that is not running locally; neither is dependency-related.

Ticket: OMN-17184
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant