Skip to content

feat(agent): add Noema general Pydantic-AI agent on the provider layer - #970

Merged
seonghobae merged 8 commits into
developfrom
feat/noema-general-agent
Jul 13, 2026
Merged

feat(agent): add Noema general Pydantic-AI agent on the provider layer#970
seonghobae merged 8 commits into
developfrom
feat/noema-general-agent

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Summary

Adds a general-purpose Pydantic-AI (MIT) agent — noema, a complementary second reviewer/assistant — that reasons over the naruon workspace on the tenant's own LLM provider. It reuses the confirmed seams rather than introducing a parallel stack.

  • Provider layer, not os.getenv. run_noema_agent resolves creds/model/base-url through resolve_runtime_llm_provider (Fernet-encrypted LLMProvider records → tenant config). The OpenAI client is built with build_llm_provider_http_client, so the base-URL allowlist / SSRF-pinned transport and local-provider (Ollama) support are preserved.
  • Tools plug into existing seams (backend/services/noema_agent.py):
    • owner-scoped mail read/search and content-graph queries (Email / ContentNodeRecord / KnowledgeGraphEdgeRecord),
    • task actions — list + status update on TicketTask, audit-logged via AuditLog,
    • writeback dispatched to the self-hosted runner (write_caldav / write_webdav handled by SelfHostedConnector), preserving the opt-in-writeback + audit-logged contract: no runner contact unless writeback_enabled, and every dispatch writes an audit row.
  • Registration point wired. registered_agents.json + task_agent_mapping.json (previously empty scaffolding) now register the agent, loaded defensively by backend/services/agent_registry.py.
  • Degrades gracefully. Returns a structured no-op notice (never raises) when the provider/creds or the pydantic-ai runtime are absent.
  • Dependency hygiene. Pydantic-AI is an optional lazy import (mirroring the existing websockets pattern) via backend/requirements-agent.txt, kept out of the hash-pinned runtime set so the deterministic --require-hashes CI install is unchanged. Permissive (MIT) deps only.

Tests

Fast mocked tests (test_noema_agent.py, test_agent_registry.py): tool wiring, config-from-DB resolution, the opt-in/audit writeback contract, and graceful degradation. A TestModel-based end-to-end run executes when pydantic-ai is installed (skipped otherwise). New tests: 18 passed, 1 skipped. No new ruff findings; app-ci forbidden-word grep (timeout|fatal|warn|denied) stays clean.

Untouched (by design)

OpenCode review pipeline (opencode-review.yml) and the TS Cloudflare Worker OIDC broker (noema/src/index.ts) are unchanged.

Note

Two pre-existing failures in test_release_governance.py (dependency-review.yml absent; scorecard/trivy lack pull_request after #926) fail identically on the clean develop tree and are unrelated to this change. They were intentionally left alone — "fixing" them would revert the deliberate central-Security-Scan / CodeQL-only CI policy.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P

seonghobae and others added 2 commits July 8, 2026 12:13
Add a general-purpose agent (services/noema_agent.py) built on Pydantic-AI
(MIT, optional dependency) that runs on the tenant's configured LLM provider
resolved via resolve_runtime_llm_provider (Fernet-encrypted provider records /
tenant config), never os.getenv. Base-URL allowlist and local-provider support
are preserved by reusing build_llm_provider_http_client for the OpenAI client.

Tools plug into the existing seams: owner-scoped mail read/search and
content-graph queries, task list/status actions (audit-logged), and writeback
dispatched to the self-hosted runner (write_caldav / write_webdav handled by
SelfHostedConnector) preserving the opt-in-writeback + audit-logged contract.

Register the agent at the intended registration point (registered_agents.json /
task_agent_mapping.json) with a defensive loader (services/agent_registry.py).

Degrade gracefully to a structured no-op notice when the provider/creds or the
pydantic-ai runtime are unavailable. Fast mocked tests cover tool wiring,
config-from-DB resolution, the opt-in/audit writeback contract, and graceful
degradation; a TestModel-based end-to-end test runs when pydantic-ai is present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
…orks

The Noema agent was dead on arrival against a real pydantic-ai install:

* services/noema_agent.py imported OpenAIModel from pydantic_ai.models.openai,
  but pydantic-ai 2.x renamed it to OpenAIChatModel. With the unbounded
  >=0.0.49 pin resolving to 2.6.0, a real install raised ImportError, so
  build_noema_agent() always returned None — silently hidden by the graceful
  degradation path. Rename the import/usage to OpenAIChatModel.

* Once the import worked, a second latent bug surfaced: the tool functions
  annotated ctx with a closure-local alias (run_context[NoemaAgentDeps]) that
  pydantic-ai's get_type_hints could not resolve (NameError). Hoist RunContext
  to a module-level symbol (guarded import, falls back to Any when pydantic-ai
  is absent) and annotate the tools with RunContext[NoemaAgentDeps].

* Pin backend/requirements-agent.txt to >=2.0,<3.0 to match the 2.x API and
  keep the next major break opt-in. Still out of the hash-pinned set.

* app-ci.yml now installs requirements-agent.txt so
  test_agent_runs_tools_with_test_model actually EXECUTES instead of skipping;
  the test asserts build_noema_agent returns a real Agent and every declared
  tool is exercised end to end via TestModel.

Config still resolves from the Fernet DB provider layer (not os.getenv), the
SSRF-pinned http client / base-URL allowlist and Ollama local-provider support
are untouched, and graceful degradation still holds when the dep is absent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
@seonghobae

Copy link
Copy Markdown
Contributor Author

Fix: Noema agent build path was dead on arrival against a real pydantic-ai install

Confirmed the review finding by installing pydantic-ai-slim[openai] (resolves to 2.6.0) into a fresh venv and exercising the real build path.

Root cause (two latent bugs, the second masked by the first)

  1. OpenAIModel was removed in pydantic-ai 2.x → renamed to OpenAIChatModel. services/noema_agent.py imported the old name, so on a real install _load_pydantic_ai() raised ImportError, build_noema_agent() returned None, and the agent was silently disabled by the graceful-degradation path. The unbounded >=0.0.49 pin resolved straight to 2.x, guaranteeing the break.
  2. Once the import worked, the tool functions annotated ctx: run_context[NoemaAgentDeps] using a closure-local alias. With from __future__ import annotations, pydantic-ai resolves those strings via get_type_hints against each function's module globals — where run_context doesn't exist — raising NameError: name 'run_context' is not defined at @agent.tool registration.

Changes

  • services/noema_agent.py: import/use OpenAIChatModel; hoist RunContext to a module-level symbol (guarded import, falls back to Any when pydantic-ai is absent) and annotate the six tools with RunContext[NoemaAgentDeps]. OpenAIProvider(openai_client=...) construction is unchanged and still valid in 2.x.
  • backend/requirements-agent.txt: pydantic-ai-slim[openai]>=2.0,<3.0 (was unbounded >=0.0.49). Still kept out of the hash-pinned requirements-hashes.txt.
  • .github/workflows/app-ci.yml: new step installs requirements-agent.txt so the real build-path test executes in CI instead of being importorskip-ped.
  • tests/test_noema_agent.py: test_agent_runs_tools_with_test_model now asserts build_noema_agent returns a real pydantic_ai.Agent and that every declared tool is exercised end-to-end via TestModel.

Verification (local venv, real pydantic-ai 2.6.0 installed)

  • build_noema_agent() returns a real Agent (not None); TestModel tool run passes; all 6 tools fire.
  • Config still resolves from the Fernet DB provider layer (not os.getenv); SSRF-pinned http client / base-URL allowlist and Ollama local-provider support untouched.
  • Graceful degradation still holds when the dep is truly absent (module imports, RunContextAny, _load_pydantic_ai()None).
  • tests/test_noema_agent.py: 16 passed. Full backend suite: 1156 passed, 22 skipped, only the 2 pre-existing test_release_governance failures remain (unrelated; fixed by fix: align release-governance tests with central Security Scan migration (#926) #968). Ruff clean.

Not merging — leaving for review.

Comment thread .github/workflows/app-ci.yml Fixed
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 964bf8d1b5f8c2e64854a5ea008bfb834f221fbf:

  • Branch is BEHIND the base branch; update the branch and re-run checks.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head e61f4bc23dddb93a56217af0a2c91327ba6fc388.

  • Head SHA: e61f4bc23dddb93a56217af0a2c91327ba6fc388

  • Workflow run: 28915315237

  • Workflow attempt: 1

Coverage evidence

Coverage Evidence

  • Head SHA: e61f4bc23dddb93a56217af0a2c91327ba6fc388
  • Required test evidence: supported repository test suites must pass.
  • Required docstring evidence: repository-owned docstring gates must pass when configured; otherwise docstring coverage is advisory.

Python project dependencies (backend/requirements.txt)

Defaulting to user installation because normal site-packages is not writeable
Collecting fastapi==0.138.2 (from -r requirements.txt (line 1))
  Downloading fastapi-0.138.2-py3-none-any.whl.metadata (26 kB)
Collecting starlette==1.3.1 (from -r requirements.txt (line 2))
  Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)
Collecting uvicorn==0.49.0 (from -r requirements.txt (line 3))
  Downloading uvicorn-0.49.0-py3-none-any.whl.metadata (6.7 kB)
Requirement already satisfied: pytest==9.1.1 in /home/runner/.local/lib/python3.12/site-packages (from -r requirements.txt (line 4)) (9.1.1)
Collecting httpx==0.28.1 (from -r requirements.txt (line 5))
  Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)
Collecting pydantic-settings==2.14.2 (from -r requirements.txt (line 6))
  Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)
Collecting aiosmtplib==5.1.2 (from -r requirements.txt (line 7))
  Downloading aiosmtplib-5.1.2-py3-none-any.whl.metadata (3.6 kB)
Collecting aioimaplib==2.0.1 (from -r requirements.txt (line 8))
  Downloading aioimaplib-2.0.1-py3-none-any.whl.metadata (9.5 kB)
Collecting sqlalchemy==2.0.51 (from -r requirements.txt (line 9))
  Downloading sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (9.5 kB)
Collecting alembic==1.18.5 (from -r requirements.txt (line 10))
  Downloading alembic-1.18.5-py3-none-any.whl.metadata (7.2 kB)
Collecting greenlet==3.5.3 (from -r requirements.txt (line 11))
  Downloading greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.metadata (3.8 kB)
Collecting asyncpg==0.31.0 (from -r requirements.txt (line 12))
  Downloading asyncpg-0.31.0-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (4.4 kB)
Collecting pgvector==0.4.2 (from -r requirements.txt (line 13))
  Downloading pgvector-0.4.2-py3-none-any.whl.metadata (19 kB)
Collecting pytest-asyncio==1.4.0 (from -r requirements.txt (line 14))
  Downloading pytest_asyncio-1.4.0-py3-none-any.whl.metadata (4.1 kB)
Collecting openai==2.44.0 (from -r requirements.txt (line 15))
  Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)
Collecting langchain-text-splitters==1.1.2 (from -r requirements.txt (line 16))
  Downloading langchain_text_splitters-1.1.2-py3-none-any.whl.metadata (3.3 kB)
Collecting tiktoken==0.13.0 (from -r requirements.txt (line 17))
  Downloading tiktoken-0.13.0-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (6.7 kB)
Collecting google-api-python-client==2.198.0 (from -r requirements.txt (line 18))
  Downloading google_api_python_client-2.198.0-py3-none-any.whl.metadata (7.0 kB)
Collecting google-auth-httplib2==0.4.0 (from -r requirements.txt (line 19))
  Downloading google_auth_httplib2-0.4.0-py3-none-any.whl.metadata (3.0 kB)
Collecting google-auth-oauthlib==1.4.0 (from -r requirements.txt (line 20))
  Downloading google_auth_oauthlib-1.4.0-py3-none-any.whl.metadata (2.6 kB)
Collecting email-validator==2.3.0 (from -r requirements.txt (line 21))
  Downloading email_validator-2.3.0-py3-none-any.whl.metadata (26 kB)
Collecting cryptography==49.0.0 (from -r requirements.txt (line 22))
  Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)
Collecting python-multipart==0.0.32 (from -r requirements.txt (line 23))
  Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)
Collecting prometheus-fastapi-instrumentator==8.0.2 (from -r requirements.txt (line 24))
  Downloading prometheus_fastapi_instrumentator-8.0.2-py3-none-any.whl.metadata (13 kB)
Collecting opentelemetry-api==1.43.0 (from -r requirements.txt (line 25))
  Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)
Collecting opentelemetry-sdk==1.43.0 (from -r requirements.txt (line 26))
  Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)
Collecting opentelemetry-instrumentation-fastapi==0.64b0 (from -r requirements.txt (line 27))
  Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)
Collecting opentelemetry-exporter-otlp==1.43.0 (from -r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp-1.43.0-py3-none-any.whl.metadata (2.4 kB)
Collecting protobuf==7.35.1 (from -r requirements.txt (line 29))
  Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)
Collecting setuptools==82.0.1 (from -r requirements.txt (line 30))
  Downloading setuptools-82.0.1-py3-none-any.whl.metadata (6.5 kB)
Collecting wheel==0.47.0 (from -r requirements.txt (line 31))
  Downloading wheel-0.47.0-py3-none-any.whl.metadata (2.3 kB)
Collecting websockets==16.0 (from -r requirements.txt (line 32))
  Downloading websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.8 kB)
Collecting PyJWT==2.13.0 (from -r requirements.txt (line 33))
  Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)
Collecting icalendar==7.2.0 (from -r requirements.txt (line 34))
  Downloading icalendar-7.2.0-py3-none-any.whl.metadata (6.9 kB)
Collecting ruff==0.15.20 (from -r requirements.txt (line 35))
  Downloading ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (26 kB)
Collecting defusedxml==0.7.1 (from -r requirements.txt (line 36))
  Downloading defusedxml-0.7.1-py2.py3-none-any.whl.metadata (32 kB)
Collecting pydantic>=2.9.0 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 109.4/109.4 kB 23.8 MB/s eta 0:00:00
Requirement already satisfied: typing-extensions>=4.8.0 in /usr/lib/python3/dist-packages (from fastapi==0.138.2->-r requirements.txt (line 1)) (4.10.0)
Collecting typing-inspection>=0.4.2 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)
Collecting annotated-doc>=0.0.2 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading annotated_doc-0.0.4-py3-none-any.whl.metadata (6.6 kB)
Collecting anyio<5,>=3.6.2 (from starlette==1.3.1->-r requirements.txt (line 2))
  Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)
Requirement already satisfied: click>=7.0 in /usr/lib/python3/dist-packages (from uvicorn==0.49.0->-r requirements.txt (line 3)) (8.1.6)
Collecting h11>=0.8 (from uvicorn==0.49.0->-r requirements.txt (line 3))
  Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)
Requirement already satisfied: iniconfig>=1.0.1 in /home/runner/.local/lib/python3.12/site-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (2.3.0)
Requirement already satisfied: packaging>=22 in /usr/lib/python3/dist-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (24.0)
Requirement already satisfied: pluggy<2,>=1.5 in /home/runner/.local/lib/python3.12/site-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (1.6.0)
Requirement already satisfied: pygments>=2.7.2 in /usr/lib/python3/dist-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (2.17.2)
Requirement already satisfied: certifi in /usr/lib/python3/dist-packages (from httpx==0.28.1->-r requirements.txt (line 5)) (2023.11.17)
Collecting httpcore==1.* (from httpx==0.28.1->-r requirements.txt (line 5))
  Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)
Requirement already satisfied: idna in /usr/lib/python3/dist-packages (from httpx==0.28.1->-r requirements.txt (line 5)) (3.6)
Collecting python-dotenv>=0.21.0 (from pydantic-settings==2.14.2->-r requirements.txt (line 6))
  Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)
Collecting Mako (from alembic==1.18.5->-r requirements.txt (line 10))
  Downloading mako-1.3.12-py3-none-any.whl.metadata (2.9 kB)
Collecting typing-extensions>=4.8.0 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
Collecting numpy (from pgvector==0.4.2->-r requirements.txt (line 13))
  Downloading numpy-2.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (6.6 kB)
Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai==2.44.0->-r requirements.txt (line 15)) (1.9.0)
Collecting jiter<1,>=0.10.0 (from openai==2.44.0->-r requirements.txt (line 15))
  Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)
Collecting sniffio (from openai==2.44.0->-r requirements.txt (line 15))
  Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)
Collecting tqdm>4 (from openai==2.44.0->-r requirements.txt (line 15))
  Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 57.4/57.4 kB 16.5 MB/s eta 0:00:00
Collecting langchain-core<2.0.0,>=1.2.31 (from langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading langchain_core-1.4.8-py3-none-any.whl.metadata (4.7 kB)
Collecting regex (from tiktoken==0.13.0->-r requirements.txt (line 17))
  Downloading regex-2026.6.28-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (40 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.5/40.5 kB 9.9 MB/s eta 0:00:00
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from tiktoken==0.13.0->-r requirements.txt (line 17)) (2.31.0)
Requirement already satisfied: httplib2<1.0.0,>=0.19.0 in /usr/lib/python3/dist-packages (from google-api-python-client==2.198.0->-r requirements.txt (line 18)) (0.20.4)
Collecting google-auth!=2.24.0,!=2.25.0,<3.0.0,>=1.32.0 (from google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading google_auth-2.55.2-py3-none-any.whl.metadata (5.2 kB)
Collecting google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5 (from google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading google_api_core-2.31.0-py3-none-any.whl.metadata (3.2 kB)
Collecting uritemplate<5,>=3.0.1 (from google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading uritemplate-4.2.0-py3-none-any.whl.metadata (2.6 kB)
Collecting requests-oauthlib>=0.7.0 (from google-auth-oauthlib==1.4.0->-r requirements.txt (line 20))
  Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)
Collecting dnspython>=2.0.0 (from email-validator==2.3.0->-r requirements.txt (line 21))
  Downloading dnspython-2.8.0-py3-none-any.whl.metadata (5.7 kB)
Collecting cffi>=2.0.0 (from cryptography==49.0.0->-r requirements.txt (line 22))
  Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)
Collecting prometheus-client<1.0.0,>=0.8.0 (from prometheus-fastapi-instrumentator==8.0.2->-r requirements.txt (line 24))
  Downloading prometheus_client-0.25.0-py3-none-any.whl.metadata (2.1 kB)
Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-sdk==1.43.0->-r requirements.txt (line 26))
  Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)
Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)
Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)
Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)
Collecting opentelemetry-exporter-otlp-proto-grpc==1.43.0 (from opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp_proto_grpc-1.43.0-py3-none-any.whl.metadata (2.6 kB)
Collecting opentelemetry-exporter-otlp-proto-http==1.43.0 (from opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)
Requirement already satisfied: python-dateutil in /usr/lib/python3/dist-packages (from icalendar==7.2.0->-r requirements.txt (line 34)) (2.8.2)
Collecting tzdata>=2025.3 (from icalendar==7.2.0->-r requirements.txt (line 34))
  Downloading tzdata-2026.2-py2.py3-none-any.whl.metadata (1.4 kB)
Collecting googleapis-common-protos~=1.57 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)
Collecting grpcio<2.0.0,>=1.63.2 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading grpcio-1.81.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (3.7 kB)
Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)
Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)
Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)
Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)
Collecting pycparser (from cffi>=2.0.0->cryptography==49.0.0->-r requirements.txt (line 22))
  Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)
Collecting proto-plus<2.0.0,>=1.24.0 (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading proto_plus-1.28.0-py3-none-any.whl.metadata (2.2 kB)
Collecting requests (from tiktoken==0.13.0->-r requirements.txt (line 17))
  Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/lib/python3/dist-packages (from google-auth!=2.24.0,!=2.25.0,<3.0.0,>=1.32.0->google-api-python-client==2.198.0->-r requirements.txt (line 18)) (0.2.8)
Requirement already satisfied: pyparsing!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3,<4,>=2.4.2 in /usr/lib/python3/dist-packages (from httplib2<1.0.0,>=0.19.0->google-api-python-client==2.198.0->-r requirements.txt (line 18)) (3.1.1)
Collecting jsonpatch<2.0.0,>=1.33.0 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading jsonpatch-1.33-py2.py3-none-any.whl.metadata (3.0 kB)
Collecting langchain-protocol>=0.0.17 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading langchain_protocol-0.0.18-py3-none-any.whl.metadata (2.4 kB)
Collecting langsmith<1.0.0,>=0.3.45 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading langsmith-0.9.8-py3-none-any.whl.metadata (22 kB)
Requirement already satisfied: pyyaml<7.0.0,>=5.3.0 in /usr/lib/python3/dist-packages (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16)) (6.0.1)
Collecting tenacity!=8.4.0,<10.0.0,>=8.1.0 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading tenacity-9.1.4-py3-none-any.whl.metadata (1.2 kB)
Collecting uuid-utils<1.0,>=0.12.0 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading uuid_utils-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.4 kB)
Collecting annotated-types>=0.6.0 (from pydantic>=2.9.0->fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)
Collecting pydantic-core==2.46.4 (from pydantic>=2.9.0->fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)
Collecting charset_normalizer<4,>=2 (from requests->tiktoken==0.13.0->-r requirements.txt (line 17))
  Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.7/41.7 kB 12.3 MB/s eta 0:00:00
Requirement already satisfied: urllib3<3,>=1.26 in /usr/lib/python3/dist-packages (from requests->tiktoken==0.13.0->-r requirements.txt (line 17)) (2.0.7)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/lib/python3/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib==1.4.0->-r requirements.txt (line 20)) (3.2.2)
Requirement already satisfied: MarkupSafe>=0.9.2 in /usr/lib/python3/dist-packages (from Mako->alembic==1.18.5->-r requirements.txt (line 10)) (2.1.5)
Requirement already satisfied: jsonpointer>=1.9 in /usr/lib/python3/dist-packages (from jsonpatch<2.0.0,>=1.33.0->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16)) (2.0)
Collecting orjson>=3.9.14 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading orjson-3.11.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.0/42.0 kB 10.7 MB/s eta 0:00:00
Collecting requests-toolbelt>=1.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl.metadata (14 kB)
Collecting xxhash>=3.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading xxhash-3.8.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (15 kB)
Collecting zstandard>=0.23.0 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (3.3 kB)
Downloading fastapi-0.138.2-py3-none-any.whl (129 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 129.3/129.3 kB 37.0 MB/s eta 0:00:00
Downloading starlette-1.3.1-py3-none-any.whl (73 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 73.6/73.6 kB 23.2 MB/s eta 0:00:00
Downloading uvicorn-0.49.0-py3-none-any.whl (71 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 71.4/71.4 kB 11.0 MB/s eta 0:00:00
Downloading httpx-0.28.1-py3-none-any.whl (73 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 73.5/73.5 kB 23.3 MB/s eta 0:00:00
Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.7/61.7 kB 17.0 MB/s eta 0:00:00
Downloading aiosmtplib-5.1.2-py3-none-any.whl (28 kB)
Downloading aioimaplib-2.0.1-py3-none-any.whl (34 kB)
Downloading sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (3.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.4/3.4 MB 152.5 MB/s eta 0:00:00
Downloading alembic-1.18.5-py3-none-any.whl (264 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 264.7/264.7 kB 62.2 MB/s eta 0:00:00
Downloading greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (614 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 614.2/614.2 kB 97.0 MB/s eta 0:00:00
Downloading asyncpg-0.31.0-cp312-cp312-manylinux_2_28_x86_64.whl (3.5 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.5/3.5 MB 169.0 MB/s eta 0:00:00
Downloading pgvector-0.4.2-py3-none-any.whl (27 kB)
Downloading pytest_asyncio-1.4.0-py3-none-any.whl (16 kB)
Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 145.4 MB/s eta 0:00:00
  • Result: PASS

Python coverage with missing-line report (backend)

============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.1.1, pluggy-1.6.0
rootdir: /home/runner/work/naruon/naruon/pr-head/backend
configfile: pytest.ini

## Changed-File Evidence Map

```mermaid
flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: app-ci.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: app-ci.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Backend (6 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (6 files)"]
  R2 --> V2["backend tests"]
  Evidence --> S3["Changed file (2 files)"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Changed file (2 files)"]
  R3 --> V3["required checks"]

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: e61f4bc23dddb93a56217af0a2c91327ba6fc388
  • Workflow run: 28915315237
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode cannot approve yet because required coverage evidence did not pass.

Review outcome

1. HIGH .github/workflows/opencode-review.yml:1 - Coverage evidence did not prove required test/docstring evidence

  • Problem: The required coverage-evidence job result was failure, so OpenCode cannot establish approval sufficiency for this head.

  • Root cause: Automated approval is only valid when the same-head coverage-evidence job proves supported repository test suites passed and configured docstring gates passed or were advisory, or reports not applicable because no supported source files or package manifests exist. Missing, failed, skipped, unavailable, or unsupported-tooling test evidence is a blocker.

  • Fix: Install or configure the repository test/docstring evidence tooling when source files or package manifests exist, rerun the current-head coverage-evidence job, and approve only after it reports success with required evidence or explicit no-source not-applicable evidence.

  • Regression test: Keep the approval branch checking needs.coverage-evidence.result == success before posting APPROVE, and publish REQUEST_CHANGES when coverage-evidence blocker states such as cancelled, skipped, failed, unsupported-tooling, or below-100 evidence are present.

  • Result: REQUEST_CHANGES

  • Reason: coverage-evidence result was failure, so required test/docstring evidence was not proven for current head e61f4bc23dddb93a56217af0a2c91327ba6fc388.

  • Head SHA: e61f4bc23dddb93a56217af0a2c91327ba6fc388

  • Workflow run: 28915315237

  • Workflow attempt: 1

Coverage evidence

Coverage Evidence

  • Head SHA: e61f4bc23dddb93a56217af0a2c91327ba6fc388
  • Required test evidence: supported repository test suites must pass.
  • Required docstring evidence: repository-owned docstring gates must pass when configured; otherwise docstring coverage is advisory.

Python project dependencies (backend/requirements.txt)

Defaulting to user installation because normal site-packages is not writeable
Collecting fastapi==0.138.2 (from -r requirements.txt (line 1))
  Downloading fastapi-0.138.2-py3-none-any.whl.metadata (26 kB)
Collecting starlette==1.3.1 (from -r requirements.txt (line 2))
  Downloading starlette-1.3.1-py3-none-any.whl.metadata (6.4 kB)
Collecting uvicorn==0.49.0 (from -r requirements.txt (line 3))
  Downloading uvicorn-0.49.0-py3-none-any.whl.metadata (6.7 kB)
Requirement already satisfied: pytest==9.1.1 in /home/runner/.local/lib/python3.12/site-packages (from -r requirements.txt (line 4)) (9.1.1)
Collecting httpx==0.28.1 (from -r requirements.txt (line 5))
  Downloading httpx-0.28.1-py3-none-any.whl.metadata (7.1 kB)
Collecting pydantic-settings==2.14.2 (from -r requirements.txt (line 6))
  Downloading pydantic_settings-2.14.2-py3-none-any.whl.metadata (3.4 kB)
Collecting aiosmtplib==5.1.2 (from -r requirements.txt (line 7))
  Downloading aiosmtplib-5.1.2-py3-none-any.whl.metadata (3.6 kB)
Collecting aioimaplib==2.0.1 (from -r requirements.txt (line 8))
  Downloading aioimaplib-2.0.1-py3-none-any.whl.metadata (9.5 kB)
Collecting sqlalchemy==2.0.51 (from -r requirements.txt (line 9))
  Downloading sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (9.5 kB)
Collecting alembic==1.18.5 (from -r requirements.txt (line 10))
  Downloading alembic-1.18.5-py3-none-any.whl.metadata (7.2 kB)
Collecting greenlet==3.5.3 (from -r requirements.txt (line 11))
  Downloading greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.metadata (3.8 kB)
Collecting asyncpg==0.31.0 (from -r requirements.txt (line 12))
  Downloading asyncpg-0.31.0-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (4.4 kB)
Collecting pgvector==0.4.2 (from -r requirements.txt (line 13))
  Downloading pgvector-0.4.2-py3-none-any.whl.metadata (19 kB)
Collecting pytest-asyncio==1.4.0 (from -r requirements.txt (line 14))
  Downloading pytest_asyncio-1.4.0-py3-none-any.whl.metadata (4.1 kB)
Collecting openai==2.44.0 (from -r requirements.txt (line 15))
  Downloading openai-2.44.0-py3-none-any.whl.metadata (34 kB)
Collecting langchain-text-splitters==1.1.2 (from -r requirements.txt (line 16))
  Downloading langchain_text_splitters-1.1.2-py3-none-any.whl.metadata (3.3 kB)
Collecting tiktoken==0.13.0 (from -r requirements.txt (line 17))
  Downloading tiktoken-0.13.0-cp312-cp312-manylinux_2_28_x86_64.whl.metadata (6.7 kB)
Collecting google-api-python-client==2.198.0 (from -r requirements.txt (line 18))
  Downloading google_api_python_client-2.198.0-py3-none-any.whl.metadata (7.0 kB)
Collecting google-auth-httplib2==0.4.0 (from -r requirements.txt (line 19))
  Downloading google_auth_httplib2-0.4.0-py3-none-any.whl.metadata (3.0 kB)
Collecting google-auth-oauthlib==1.4.0 (from -r requirements.txt (line 20))
  Downloading google_auth_oauthlib-1.4.0-py3-none-any.whl.metadata (2.6 kB)
Collecting email-validator==2.3.0 (from -r requirements.txt (line 21))
  Downloading email_validator-2.3.0-py3-none-any.whl.metadata (26 kB)
Collecting cryptography==49.0.0 (from -r requirements.txt (line 22))
  Downloading cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl.metadata (4.3 kB)
Collecting python-multipart==0.0.32 (from -r requirements.txt (line 23))
  Downloading python_multipart-0.0.32-py3-none-any.whl.metadata (2.1 kB)
Collecting prometheus-fastapi-instrumentator==8.0.2 (from -r requirements.txt (line 24))
  Downloading prometheus_fastapi_instrumentator-8.0.2-py3-none-any.whl.metadata (13 kB)
Collecting opentelemetry-api==1.43.0 (from -r requirements.txt (line 25))
  Downloading opentelemetry_api-1.43.0-py3-none-any.whl.metadata (1.4 kB)
Collecting opentelemetry-sdk==1.43.0 (from -r requirements.txt (line 26))
  Downloading opentelemetry_sdk-1.43.0-py3-none-any.whl.metadata (1.7 kB)
Collecting opentelemetry-instrumentation-fastapi==0.64b0 (from -r requirements.txt (line 27))
  Downloading opentelemetry_instrumentation_fastapi-0.64b0-py3-none-any.whl.metadata (2.2 kB)
Collecting opentelemetry-exporter-otlp==1.43.0 (from -r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp-1.43.0-py3-none-any.whl.metadata (2.4 kB)
Collecting protobuf==7.35.1 (from -r requirements.txt (line 29))
  Downloading protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl.metadata (595 bytes)
Collecting setuptools==82.0.1 (from -r requirements.txt (line 30))
  Downloading setuptools-82.0.1-py3-none-any.whl.metadata (6.5 kB)
Collecting wheel==0.47.0 (from -r requirements.txt (line 31))
  Downloading wheel-0.47.0-py3-none-any.whl.metadata (2.3 kB)
Collecting websockets==16.0 (from -r requirements.txt (line 32))
  Downloading websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (6.8 kB)
Collecting PyJWT==2.13.0 (from -r requirements.txt (line 33))
  Downloading pyjwt-2.13.0-py3-none-any.whl.metadata (3.4 kB)
Collecting icalendar==7.2.0 (from -r requirements.txt (line 34))
  Downloading icalendar-7.2.0-py3-none-any.whl.metadata (6.9 kB)
Collecting ruff==0.15.20 (from -r requirements.txt (line 35))
  Downloading ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (26 kB)
Collecting defusedxml==0.7.1 (from -r requirements.txt (line 36))
  Downloading defusedxml-0.7.1-py2.py3-none-any.whl.metadata (32 kB)
Collecting pydantic>=2.9.0 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading pydantic-2.13.4-py3-none-any.whl.metadata (109 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 109.4/109.4 kB 23.8 MB/s eta 0:00:00
Requirement already satisfied: typing-extensions>=4.8.0 in /usr/lib/python3/dist-packages (from fastapi==0.138.2->-r requirements.txt (line 1)) (4.10.0)
Collecting typing-inspection>=0.4.2 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading typing_inspection-0.4.2-py3-none-any.whl.metadata (2.6 kB)
Collecting annotated-doc>=0.0.2 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading annotated_doc-0.0.4-py3-none-any.whl.metadata (6.6 kB)
Collecting anyio<5,>=3.6.2 (from starlette==1.3.1->-r requirements.txt (line 2))
  Downloading anyio-4.14.1-py3-none-any.whl.metadata (4.6 kB)
Requirement already satisfied: click>=7.0 in /usr/lib/python3/dist-packages (from uvicorn==0.49.0->-r requirements.txt (line 3)) (8.1.6)
Collecting h11>=0.8 (from uvicorn==0.49.0->-r requirements.txt (line 3))
  Downloading h11-0.16.0-py3-none-any.whl.metadata (8.3 kB)
Requirement already satisfied: iniconfig>=1.0.1 in /home/runner/.local/lib/python3.12/site-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (2.3.0)
Requirement already satisfied: packaging>=22 in /usr/lib/python3/dist-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (24.0)
Requirement already satisfied: pluggy<2,>=1.5 in /home/runner/.local/lib/python3.12/site-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (1.6.0)
Requirement already satisfied: pygments>=2.7.2 in /usr/lib/python3/dist-packages (from pytest==9.1.1->-r requirements.txt (line 4)) (2.17.2)
Requirement already satisfied: certifi in /usr/lib/python3/dist-packages (from httpx==0.28.1->-r requirements.txt (line 5)) (2023.11.17)
Collecting httpcore==1.* (from httpx==0.28.1->-r requirements.txt (line 5))
  Downloading httpcore-1.0.9-py3-none-any.whl.metadata (21 kB)
Requirement already satisfied: idna in /usr/lib/python3/dist-packages (from httpx==0.28.1->-r requirements.txt (line 5)) (3.6)
Collecting python-dotenv>=0.21.0 (from pydantic-settings==2.14.2->-r requirements.txt (line 6))
  Downloading python_dotenv-1.2.2-py3-none-any.whl.metadata (27 kB)
Collecting Mako (from alembic==1.18.5->-r requirements.txt (line 10))
  Downloading mako-1.3.12-py3-none-any.whl.metadata (2.9 kB)
Collecting typing-extensions>=4.8.0 (from fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
Collecting numpy (from pgvector==0.4.2->-r requirements.txt (line 13))
  Downloading numpy-2.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.metadata (6.6 kB)
Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from openai==2.44.0->-r requirements.txt (line 15)) (1.9.0)
Collecting jiter<1,>=0.10.0 (from openai==2.44.0->-r requirements.txt (line 15))
  Downloading jiter-0.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (5.2 kB)
Collecting sniffio (from openai==2.44.0->-r requirements.txt (line 15))
  Downloading sniffio-1.3.1-py3-none-any.whl.metadata (3.9 kB)
Collecting tqdm>4 (from openai==2.44.0->-r requirements.txt (line 15))
  Downloading tqdm-4.68.4-py3-none-any.whl.metadata (57 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 57.4/57.4 kB 16.5 MB/s eta 0:00:00
Collecting langchain-core<2.0.0,>=1.2.31 (from langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading langchain_core-1.4.8-py3-none-any.whl.metadata (4.7 kB)
Collecting regex (from tiktoken==0.13.0->-r requirements.txt (line 17))
  Downloading regex-2026.6.28-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (40 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.5/40.5 kB 9.9 MB/s eta 0:00:00
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from tiktoken==0.13.0->-r requirements.txt (line 17)) (2.31.0)
Requirement already satisfied: httplib2<1.0.0,>=0.19.0 in /usr/lib/python3/dist-packages (from google-api-python-client==2.198.0->-r requirements.txt (line 18)) (0.20.4)
Collecting google-auth!=2.24.0,!=2.25.0,<3.0.0,>=1.32.0 (from google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading google_auth-2.55.2-py3-none-any.whl.metadata (5.2 kB)
Collecting google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5 (from google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading google_api_core-2.31.0-py3-none-any.whl.metadata (3.2 kB)
Collecting uritemplate<5,>=3.0.1 (from google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading uritemplate-4.2.0-py3-none-any.whl.metadata (2.6 kB)
Collecting requests-oauthlib>=0.7.0 (from google-auth-oauthlib==1.4.0->-r requirements.txt (line 20))
  Downloading requests_oauthlib-2.0.0-py2.py3-none-any.whl.metadata (11 kB)
Collecting dnspython>=2.0.0 (from email-validator==2.3.0->-r requirements.txt (line 21))
  Downloading dnspython-2.8.0-py3-none-any.whl.metadata (5.7 kB)
Collecting cffi>=2.0.0 (from cryptography==49.0.0->-r requirements.txt (line 22))
  Downloading cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.5 kB)
Collecting prometheus-client<1.0.0,>=0.8.0 (from prometheus-fastapi-instrumentator==8.0.2->-r requirements.txt (line 24))
  Downloading prometheus_client-0.25.0-py3-none-any.whl.metadata (2.1 kB)
Collecting opentelemetry-semantic-conventions==0.64b0 (from opentelemetry-sdk==1.43.0->-r requirements.txt (line 26))
  Downloading opentelemetry_semantic_conventions-0.64b0-py3-none-any.whl.metadata (2.4 kB)
Collecting opentelemetry-instrumentation-asgi==0.64b0 (from opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading opentelemetry_instrumentation_asgi-0.64b0-py3-none-any.whl.metadata (2.0 kB)
Collecting opentelemetry-instrumentation==0.64b0 (from opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading opentelemetry_instrumentation-0.64b0-py3-none-any.whl.metadata (7.2 kB)
Collecting opentelemetry-util-http==0.64b0 (from opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading opentelemetry_util_http-0.64b0-py3-none-any.whl.metadata (2.6 kB)
Collecting opentelemetry-exporter-otlp-proto-grpc==1.43.0 (from opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp_proto_grpc-1.43.0-py3-none-any.whl.metadata (2.6 kB)
Collecting opentelemetry-exporter-otlp-proto-http==1.43.0 (from opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp_proto_http-1.43.0-py3-none-any.whl.metadata (2.4 kB)
Requirement already satisfied: python-dateutil in /usr/lib/python3/dist-packages (from icalendar==7.2.0->-r requirements.txt (line 34)) (2.8.2)
Collecting tzdata>=2025.3 (from icalendar==7.2.0->-r requirements.txt (line 34))
  Downloading tzdata-2026.2-py2.py3-none-any.whl.metadata (1.4 kB)
Collecting googleapis-common-protos~=1.57 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading googleapis_common_protos-1.75.0-py3-none-any.whl.metadata (8.6 kB)
Collecting grpcio<2.0.0,>=1.63.2 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading grpcio-1.81.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (3.7 kB)
Collecting opentelemetry-exporter-otlp-proto-common==1.43.0 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_exporter_otlp_proto_common-1.43.0-py3-none-any.whl.metadata (1.8 kB)
Collecting opentelemetry-proto==1.43.0 (from opentelemetry-exporter-otlp-proto-grpc==1.43.0->opentelemetry-exporter-otlp==1.43.0->-r requirements.txt (line 28))
  Downloading opentelemetry_proto-1.43.0-py3-none-any.whl.metadata (2.3 kB)
Collecting wrapt<3.0.0,>=1.0.0 (from opentelemetry-instrumentation==0.64b0->opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (7.4 kB)
Collecting asgiref~=3.0 (from opentelemetry-instrumentation-asgi==0.64b0->opentelemetry-instrumentation-fastapi==0.64b0->-r requirements.txt (line 27))
  Downloading asgiref-3.11.1-py3-none-any.whl.metadata (9.3 kB)
Collecting pycparser (from cffi>=2.0.0->cryptography==49.0.0->-r requirements.txt (line 22))
  Downloading pycparser-3.0-py3-none-any.whl.metadata (8.2 kB)
Collecting proto-plus<2.0.0,>=1.24.0 (from google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0,>=1.31.5->google-api-python-client==2.198.0->-r requirements.txt (line 18))
  Downloading proto_plus-1.28.0-py3-none-any.whl.metadata (2.2 kB)
Collecting requests (from tiktoken==0.13.0->-r requirements.txt (line 17))
  Downloading requests-2.34.2-py3-none-any.whl.metadata (4.8 kB)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/lib/python3/dist-packages (from google-auth!=2.24.0,!=2.25.0,<3.0.0,>=1.32.0->google-api-python-client==2.198.0->-r requirements.txt (line 18)) (0.2.8)
Requirement already satisfied: pyparsing!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3,<4,>=2.4.2 in /usr/lib/python3/dist-packages (from httplib2<1.0.0,>=0.19.0->google-api-python-client==2.198.0->-r requirements.txt (line 18)) (3.1.1)
Collecting jsonpatch<2.0.0,>=1.33.0 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading jsonpatch-1.33-py2.py3-none-any.whl.metadata (3.0 kB)
Collecting langchain-protocol>=0.0.17 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading langchain_protocol-0.0.18-py3-none-any.whl.metadata (2.4 kB)
Collecting langsmith<1.0.0,>=0.3.45 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading langsmith-0.9.8-py3-none-any.whl.metadata (22 kB)
Requirement already satisfied: pyyaml<7.0.0,>=5.3.0 in /usr/lib/python3/dist-packages (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16)) (6.0.1)
Collecting tenacity!=8.4.0,<10.0.0,>=8.1.0 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading tenacity-9.1.4-py3-none-any.whl.metadata (1.2 kB)
Collecting uuid-utils<1.0,>=0.12.0 (from langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading uuid_utils-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.4 kB)
Collecting annotated-types>=0.6.0 (from pydantic>=2.9.0->fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading annotated_types-0.7.0-py3-none-any.whl.metadata (15 kB)
Collecting pydantic-core==2.46.4 (from pydantic>=2.9.0->fastapi==0.138.2->-r requirements.txt (line 1))
  Downloading pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (6.6 kB)
Collecting charset_normalizer<4,>=2 (from requests->tiktoken==0.13.0->-r requirements.txt (line 17))
  Downloading charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.7/41.7 kB 12.3 MB/s eta 0:00:00
Requirement already satisfied: urllib3<3,>=1.26 in /usr/lib/python3/dist-packages (from requests->tiktoken==0.13.0->-r requirements.txt (line 17)) (2.0.7)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/lib/python3/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib==1.4.0->-r requirements.txt (line 20)) (3.2.2)
Requirement already satisfied: MarkupSafe>=0.9.2 in /usr/lib/python3/dist-packages (from Mako->alembic==1.18.5->-r requirements.txt (line 10)) (2.1.5)
Requirement already satisfied: jsonpointer>=1.9 in /usr/lib/python3/dist-packages (from jsonpatch<2.0.0,>=1.33.0->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16)) (2.0)
Collecting orjson>=3.9.14 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading orjson-3.11.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (41 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.0/42.0 kB 10.7 MB/s eta 0:00:00
Collecting requests-toolbelt>=1.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading requests_toolbelt-1.0.0-py2.py3-none-any.whl.metadata (14 kB)
Collecting xxhash>=3.0.0 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading xxhash-3.8.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (15 kB)
Collecting zstandard>=0.23.0 (from langsmith<1.0.0,>=0.3.45->langchain-core<2.0.0,>=1.2.31->langchain-text-splitters==1.1.2->-r requirements.txt (line 16))
  Downloading zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (3.3 kB)
Downloading fastapi-0.138.2-py3-none-any.whl (129 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 129.3/129.3 kB 37.0 MB/s eta 0:00:00
Downloading starlette-1.3.1-py3-none-any.whl (73 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 73.6/73.6 kB 23.2 MB/s eta 0:00:00
Downloading uvicorn-0.49.0-py3-none-any.whl (71 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 71.4/71.4 kB 11.0 MB/s eta 0:00:00
Downloading httpx-0.28.1-py3-none-any.whl (73 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 73.5/73.5 kB 23.3 MB/s eta 0:00:00
Downloading pydantic_settings-2.14.2-py3-none-any.whl (61 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.7/61.7 kB 17.0 MB/s eta 0:00:00
Downloading aiosmtplib-5.1.2-py3-none-any.whl (28 kB)
Downloading aioimaplib-2.0.1-py3-none-any.whl (34 kB)
Downloading sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (3.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.4/3.4 MB 152.5 MB/s eta 0:00:00
Downloading alembic-1.18.5-py3-none-any.whl (264 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 264.7/264.7 kB 62.2 MB/s eta 0:00:00
Downloading greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (614 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 614.2/614.2 kB 97.0 MB/s eta 0:00:00
Downloading asyncpg-0.31.0-cp312-cp312-manylinux_2_28_x86_64.whl (3.5 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.5/3.5 MB 169.0 MB/s eta 0:00:00
Downloading pgvector-0.4.2-py3-none-any.whl (27 kB)
Downloading pytest_asyncio-1.4.0-py3-none-any.whl (16 kB)
Downloading openai-2.44.0-py3-none-any.whl (1.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4/1.4 MB 145.4 MB/s eta 0:00:00
  • Result: PASS

Python coverage with missing-line report (backend)

============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.1.1, pluggy-1.6.0
rootdir: /home/runner/work/naruon/naruon/pr-head/backend
configfile: pytest.ini

## Changed-File Evidence Map

```mermaid
flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: app-ci.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> R1["Review risk: Workflow: app-ci.yml"]
  R1 --> V1["actionlint plus required checks"]
  Evidence --> S2["Backend (6 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (6 files)"]
  R2 --> V2["backend tests"]
  Evidence --> S3["Changed file (2 files)"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Changed file (2 files)"]
  R3 --> V3["required checks"]

@seonghobae
seonghobae enabled auto-merge July 12, 2026 06:31
@opencode-agent
opencode-agent Bot disabled auto-merge July 12, 2026 06:40

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode model providers were unavailable for this same-head run, but deterministic current-head evidence is clean: coverage evidence passed, peer GitHub Checks are complete, medium-or-higher code-scanning alerts are clear, mergeability is clean, and reviewer threads are resolved or outdated.

Findings

No blocking findings.

Evidence

  • Result: APPROVE
  • Reason: current-head model-unavailable evidence fallback; coverage, docstring, peer GitHub Checks, code-scanning alerts, mergeability, and review threads were clear for current head.
  • Scope: unsupported
  • Changed files: 0
  • Model-pool outcome: exhausted
  • Head SHA: 2e4ce28f2da191d871215cbbc23bb5f1c4e9c81e
  • Workflow run: 29210232001
  • Workflow attempt: 1

This fallback does not suppress failed checks, medium-or-higher code-scanning alerts, merge conflicts, unresolved reviewer threads, or failed coverage evidence; any of those conditions still publish REQUEST_CHANGES or leave the approval state unchanged.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode model providers were unavailable for this same-head run, but deterministic current-head evidence is clean: coverage evidence passed, peer GitHub Checks are complete, medium-or-higher code-scanning alerts are clear, mergeability is clean, and reviewer threads are resolved or outdated.

Findings

No blocking findings.

Evidence

  • Result: APPROVE
  • Reason: current-head model-unavailable evidence fallback; coverage, docstring, peer GitHub Checks, code-scanning alerts, mergeability, and review threads were clear for current head.
  • Scope: unsupported
  • Changed files: 0
  • Model-pool outcome: exhausted
  • Head SHA: c91248b80934433d81f9311cbfa08f5c63d39d08
  • Workflow run: 29213384906
  • Workflow attempt: 1

This fallback does not suppress failed checks, medium-or-higher code-scanning alerts, merge conflicts, unresolved reviewer threads, or failed coverage evidence; any of those conditions still publish REQUEST_CHANGES or leave the approval state unchanged.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode model providers were unavailable for this same-head run, but deterministic current-head evidence is clean: coverage evidence passed, peer GitHub Checks are complete, medium-or-higher code-scanning alerts are clear, mergeability is clean, and reviewer threads are resolved or outdated.

Findings

No blocking findings.

Evidence

  • Result: APPROVE
  • Reason: current-head model-unavailable evidence fallback; coverage, docstring, peer GitHub Checks, code-scanning alerts, mergeability, and review threads were clear for current head.
  • Scope: unsupported
  • Changed files: 0
  • Model-pool outcome: exhausted
  • Head SHA: 964bf8d1b5f8c2e64854a5ea008bfb834f221fbf
  • Workflow run: 29214696014
  • Workflow attempt: 1

This fallback does not suppress failed checks, medium-or-higher code-scanning alerts, merge conflicts, unresolved reviewer threads, or failed coverage evidence; any of those conditions still publish REQUEST_CHANGES or leave the approval state unchanged.

@seonghobae
seonghobae enabled auto-merge July 13, 2026 01:37

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode model providers were unavailable for this same-head run, but deterministic current-head evidence is clean: coverage evidence passed, peer GitHub Checks are complete, medium-or-higher code-scanning alerts are clear, mergeability is clean, and reviewer threads are resolved or outdated.

Findings

No blocking findings.

Evidence

  • Result: APPROVE
  • Reason: current-head model-unavailable evidence fallback; coverage, docstring, peer GitHub Checks, code-scanning alerts, mergeability, and review threads were clear for current head.
  • Scope: unsupported
  • Changed files: 0
  • Model-pool outcome: exhausted
  • Head SHA: 4658c1023d6c561ce9a90cb13f377043923f20fb
  • Workflow run: 29217733776
  • Workflow attempt: 1

This fallback does not suppress failed checks, medium-or-higher code-scanning alerts, merge conflicts, unresolved reviewer threads, or failed coverage evidence; any of those conditions still publish REQUEST_CHANGES or leave the approval state unchanged.

@seonghobae
seonghobae merged commit ae0db99 into develop Jul 13, 2026
35 checks passed
@seonghobae
seonghobae deleted the feat/noema-general-agent branch July 13, 2026 02:00
@github-project-automation github-project-automation Bot moved this from Todo to Done in naruon Platform Roadmap Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants