Skip to content

feat(pdf-dom): recognize PDF DOM via NewsDOM sidecar into the content graph - #965

Merged
seonghobae merged 39 commits into
developfrom
feat/pdf-dom-recognition
Jul 13, 2026
Merged

feat(pdf-dom): recognize PDF DOM via NewsDOM sidecar into the content graph#965
seonghobae merged 39 commits into
developfrom
feat/pdf-dom-recognition

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Summary

Integrates the NewsDOM PDF recognition sidecar so naruon recognizes PDF DOM structure and lands the structured DOM into the content graph. PDFs were previously unsupported_binary; they are now recognized (pages → articles → body_blocks) into document → section → paragraph ContentNode/ContentSegment trees plus flat text for embeddings.

Targets the generalized NewsDOM /parse contract (multipart file + language/mode form fields + optional bearer) being landed in the sibling newsdom-api branch feat/generalize-pdf-dom. Extra form fields / auth header are ignored by the current sidecar, so this is forward-compatible.

What's included

  1. services/newsdom_client.py — SSRF-safe, address-pinned async httpx client (mirrors services/llm_provider_urls.py). POSTs the PDF to {base_url}/parse, validates the host against a new ALLOWED_NEWSDOM_HOSTS allowlist, resolves + pins IPs, rejects private/loopback/IP-literal/userinfo/DNS-rebind. ALLOW_LOCAL_NEWSDOM_PROVIDERS unlocks the docker container hostname for dev.
  2. NewsdomProvider model + migration 0010_newsdom_providersbase_url plaintext, api_token as EncryptedString (Fernet), resolved from the DB per organization. No os.getenv for service config/secrets in consumer code.
  3. Attachment pathapplication/pdf maps to a new deferred pdf descriptor with status pdf_dom_recognition_pending; heavy OCR/MinerU never runs inline during import. The worker maps the recognized tree into Attachment.parse_content + the content graph.
  4. Data-documents pathPOST /documents/{id}/pdf-dom-recognition-intent (mirrors the HWP conversion intent) + a binary PDF upload variant POST /documents/pdf-dom-recognition; executed by the worker calling newsdom_client.
  5. Submodule + sidecarvendor/newsdom-api pinned git submodule (ContextualWisdomLab/newsdom-api @ develop 4a68893) and a newsdom docker-compose service (build from submodule, healthcheck on /health). Backend allowlists newsdom and depends on it.
  6. Tests — fast mocked unit tests: pdf descriptor pending behavior, DOM→content-graph mapping, config-resolved-from-DB (asserts no env read), recognition worker with a mocked client, and SSRF allowlist rejection.

Graceful degradation

Without the sidecar (or with no active NewsdomProvider), resolve_newsdom_runtime_config returns None, PDFs stay in the clear pdf_dom_recognition_pending state, and imports never fail.

Test status

Full backend suite: 1159 passed, 22 skipped, 2 failed. The 2 failures are pre-existing test_release_governance.py checks about missing .github/workflows/* files, unrelated to this change (no governance files were touched). The 28 new tests all pass.

Human action required

  • Configure the sidecar: insert an active NewsdomProvider row (per organization) with base_url + api_token (token is Fernet-encrypted at rest) and add its host to ALLOWED_NEWSDOM_HOSTS. Nothing is read from the environment at request time.
  • Submodule pin: git submodule update --init --recursive. Re-pin vendor/newsdom-api once the sibling feat/generalize-pdf-dom /parse generalization lands on newsdom-api develop.

🤖 Generated with Claude Code

… graph

Integrate the NewsDOM PDF recognition sidecar so naruon can turn scanned/native
PDFs into a structured DOM and land it in the content graph.

- newsdom_client.py: SSRF-safe, address-pinned async httpx client that POSTs
  multipart PDF bytes to {base_url}/parse with language/mode form fields and an
  optional bearer token. Validates against a new ALLOWED_NEWSDOM_HOSTS allowlist
  (mirrors ALLOWED_LLM_BASE_URL_HOSTS) with an ALLOW_LOCAL_NEWSDOM_PROVIDERS
  escape hatch for the docker sidecar.
- NewsdomProvider model + migration 0010: base_url in plaintext, api_token as
  EncryptedString (Fernet), read from the DB per-org — never os.getenv at
  runtime, mirroring LLMProvider.
- Attachment path: application/pdf now maps to a deferred 'pdf' descriptor
  (parse_status pdf_dom_recognition_pending) instead of unsupported_binary, so
  heavy OCR/MinerU never runs inline during import. The worker maps the returned
  pages->articles->body_blocks tree into Attachment.parse_content (embeddings)
  and a document->section->paragraph ContentNode/ContentSegment graph.
- Data-documents path: pdf-dom-recognition intent endpoint (status
  pdf_dom_recognition_pending) mirroring the HWP conversion intent, plus a binary
  PDF upload variant; executed by the worker calling newsdom_client.
- Submodule + sidecar: vendor/newsdom-api pinned submodule and a 'newsdom'
  docker-compose service (healthcheck on /health). naruon degrades gracefully
  without the sidecar (PDFs stay pending).
- Tests: fast mocked unit tests for the pdf descriptor, the DOM->content-graph
  mapping, config-resolved-from-DB, the recognition worker with a mocked client,
  and SSRF allowlist rejection.

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

리뷰 참고 — 사람 조치 및 후속 항목 (검증 결과)

사람 조치:

  1. 조직별 newsdom_providers 행 삽입: base_url + api_token(Fernet 암호화), is_active=true, 그리고 호스트를 ALLOWED_NEWSDOM_HOSTS에 추가. (런타임은 DB에서 읽음 — os.getenv 아님.)
  2. git submodule update --init --recursive; 그리고 sibling newsdom-api PR Fix accounts mailbox owner auth boundary #300(language/mode + bearer 일반화)이 develop에 머지되면 vendor/newsdom-api 핀을 재고정.

후속(비차단):

  1. [중요] 워커 dispatch 확인newsdom_worker.recognize_attachment_pdf/recognize_document_pdf는 추가됐으나, pdf_dom_recognition_pending 행을 실제로 집어 실행하는 스케줄러/큐 배선이 이 diff엔 없습니다(기존 HWP식 pending 워커 프레임워크에 의존 가정). 그 프레임워크가 새 pending 상태를 dispatch하는지 확인하거나, 아니면 dispatch 배선을 추가해야 PDF가 영원히 pending에 머물지 않습니다.
  2. 업로드 PDF(최대 50MB)를 Document.document_content(text)에 base64 저장(~66MB/doc) — 오브젝트 스토리지 고려.
  3. 기존 문서를 pending으로 전환 시 decode_pending_pdf_document_bytes가 base64 PDF를 기대 — 콘텐츠가 base64 PDF가 아니면 decode 실패, 가드 필요.
  4. newsdom /health는 프로세스 liveness만 — MinerU 미번들 시 /parse는 503 가능(문서화된 readiness 주의, 버그 아님).

Comment thread backend/tests/test_newsdom_client.py Fixed
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for c8f93bac87ad44eb06a5d52d1921ea1cfa0289d4:

  • 1 unresolved current review thread(s) remain.

Comment thread backend/tests/test_newsdom_client.py Fixed
seonghobae and others added 2 commits July 8, 2026 22:45
The coverage-evidence CI gate runs `docker compose config` + `docker compose
build` whenever docker-compose.yml changes. The newsdom service builds from
context ./vendor/newsdom-api, a submodule that is not checked out in that job,
so the build failed with:

  target newsdom: failed to solve: failed to read dockerfile:
  open Dockerfile: no such file or directory

newsdom is an optional PDF->DOM sidecar; the backend already degrades
gracefully when it is absent. Put it behind a 'newsdom' compose profile so the
default build/config path skips it, and make the backend's depends_on
required: false so config/build does not fail when the profile is inactive
(dropped from the dependency graph) while still waiting for the sidecar when
the profile is enabled. Bring it up intentionally with:
  git submodule update --init vendor/newsdom-api
  docker compose --profile newsdom up

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTAMs4bpSZS77Xe3RQjv9P
Remove the unused module-level `from services import newsdom_client`
import (ruff F401) and replace the `startswith` prefix check with an
exact-equality assertion on the normalized URL. The prefix check
triggered CodeQL py/incomplete-url-substring-sanitization since it would
also accept hosts like newsdom.example.com.evil.com; the deterministic
normalizer output lets the test assert the full value instead.
@seonghobae
seonghobae enabled auto-merge July 12, 2026 06:32
@seonghobae

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts on this branch.

auto-merge was automatically disabled July 12, 2026 06:33

Head branch was pushed to by a user without write access

…dar descriptors and ALLOWED_NEWSDOM_HOSTS + ALLOWED_SCOPEWEAVE_HOSTS

Copilot AI commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts on this branch.

Merge conflicts resolved. Three files had conflicts:

  • backend/core/config.py — kept both ALLOWED_NEWSDOM_HOSTS/ALLOW_LOCAL_NEWSDOM_PROVIDERS (from this branch) and ALLOWED_SCOPEWEAVE_HOSTS (from develop).
  • backend/services/attachment_parser.py — kept the pdf descriptor (from this branch) alongside the new json, csv, xml, and calendar descriptors (from develop).
  • backend/tests/test_attachment_parser.py — merged both sets into the manifest keys assertion.

All 30 affected tests pass (commit fix(merge): resolve develop conflicts).

@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 2559283c7ab1c5865691db37d62293865988d67a.

  • Head SHA: 2559283c7ab1c5865691db37d62293865988d67a

  • Workflow run: 29205347662

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (3 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (3 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Backend (15 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (15 files)"]
  R2 --> V2["backend tests"]
Loading

@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: f99a0e967f954de8431de6b7bae320d94baa9143
  • Workflow run: 29220153338
  • 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 f99a0e967f954de8431de6b7bae320d94baa9143.

  • Head SHA: f99a0e967f954de8431de6b7bae320d94baa9143

  • Workflow run: 29220153338

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (3 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (3 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Backend (15 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (15 files)"]
  R2 --> V2["backend tests"]
Loading

@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 4e257f5fc6cf9983be2521af1542235631f2eb99.

  • Head SHA: 4e257f5fc6cf9983be2521af1542235631f2eb99

  • Workflow run: 29213382582

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (3 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (3 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Backend (15 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (15 files)"]
  R2 --> V2["backend tests"]
Loading

@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 8986e738afd9441d023c73134aeb85a119e03432.

  • Head SHA: 8986e738afd9441d023c73134aeb85a119e03432

  • Workflow run: 29215344235

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (3 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (3 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Backend (15 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (15 files)"]
  R2 --> V2["backend tests"]
Loading

@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 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 f99a0e967f954de8431de6b7bae320d94baa9143.

  • Head SHA: f99a0e967f954de8431de6b7bae320d94baa9143

  • Workflow run: 29220153338

  • Workflow attempt: 1

Coverage evidence

Coverage evidence job did not run or did not publish coverage evidence.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (3 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (3 files)"]
  R1 --> V1["required checks"]
  Evidence --> S2["Backend (15 files)"]
  S2 --> I2["API and service runtime"]
  I2 --> R2["Review risk: Backend (15 files)"]
  R2 --> V2["backend tests"]
Loading

@seonghobae
seonghobae dismissed opencode-agent[bot]’s stale review July 13, 2026 10:56

Dismissed as stale old-head OpenCode evidence: review commit c3c7f83 is superseded by current head 43fb307. Current-head security/application checks and all review threads are evaluated separately.

Comment thread backend/tests/test_newsdom_worker.py Fixed
@seonghobae

Copy link
Copy Markdown
Contributor Author

리뷰 후속 항목을 current-head 기준으로 재검증했습니다.

  1. pdf_dom_recognition_pendingmain.py lifespan에서 시작되는 NewsdomRecognitionWorker가 실제 소비합니다. provider 미설정 조직의 앞 batch가 뒤의 정상 조직을 영구 starvation시키지 않도록 attachment/document별 keyset cursor와 tail wrap을 추가했고, pending·구성 거부·payload 오류 사유를 로그에 남깁니다.
  2. worker 단위 line/branch coverage는 모두 100%이며 lifecycle, advisory lease, replica skip, rollback isolation, malformed payload, tail wrap을 보존 테스트로 고정했습니다.
  3. document decoder는 strict base64, decoded 20 MiB limit, %PDF- magic을 sidecar 호출 전에 검증합니다.
  4. base64 DB row를 외부 object storage로 전환하는 작업은 임시 local filesystem 구현 없이 tenant scope, encryption, lifecycle, backfill, 장애 주입까지 포함해 #1076에 등록했습니다.
  5. NewsDOM /health는 liveness이고 MinerU 부재 시 /parse 503은 readiness/processing failure라는 기존 계약을 유지합니다.
  6. 최신 develop 병합으로 생긴 Alembic 병렬 head는 순수 graph merge revision 0017_merge_newsdom_carddav_heads와 단일-head 회귀 테스트로 해소했습니다.

로컬 검증: backend 1535 passed, 33 skipped, Ruff 통과, 변경 production docstring coverage 100%, services/newsdom_worker.py line/branch coverage 100%.

@seonghobae
seonghobae enabled auto-merge July 13, 2026 11:34
Comment thread frontend/screenshot.cjs Fixed
@opencode-agent
opencode-agent Bot disabled auto-merge July 13, 2026 13:38

@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 reviewed the current-head bounded evidence and found no blocking issues.

Findings

No blocking findings.

Summary

Approval sufficiency: bounded evidence supplied affirmative approval evidence for changed files, coverage/docstring posture, risk surfaces, and current-head verification; approval is not based merely on the absence of known blockers.
Verification posture: CodeGraph evidence was initialized and bounded current-head evidence reviewed for changed-file evidence including backend/alembic/versions/0010_newsdom_providers.py, backend/alembic/versions/0015_merge_newsdom_email_heads.py, backend/alembic/versions/0016_document_org_scope.py, backend/alembic/versions/0017_merge_newsdom_carddav_heads.py, backend/api/data.py, and 26 more.
Linter/static: workflow/static review evidence is bounded by the current-head GitHub Checks gate and changed-file evidence.
TDD/regression: coverage execution evidence and focused changed hunks were reviewed from bounded-review-evidence.md.
Coverage: coverage execution evidence reports supported repository test suites passed.
Docstring coverage: coverage execution evidence reports configured repository docstring gates passed or docstring coverage was advisory.
DAG: CodeGraph/source-backed behavior map connects backend/alembic/versions/0010_newsdom_providers.py to the affected review, runtime, or workflow path and required checks.
PoC/execution: coverage-evidence job executed on the current head and reported PASS.
DDD/domain: workflow and repository-governance invariants were reviewed against changed files in bounded evidence.
CDD/context: CodeGraph evidence, changed-file history, and focused hunks were reviewed from bounded-review-evidence.md.
Similar issues: changed-file history evidence was reviewed for comparable local precedents.
Claim/concept check: bounded evidence, repository source, current-head workflow evidence, and, where numeric, scientific, statistical, or literature-backed claims are affected, original-paper/formula evidence and parameter-recovery expectations were used for claims.
Standards search: standards and external-source checks are delegated to configured OpenCode web_search/Context7/DeepWiki sources when applicable; no evidence-backed standards blocker is present in bounded evidence.
Compatibility/convention: changed workflow/script conventions, object naming, and reserved-word safety for schema/API/config/code surfaces were checked in bounded evidence.
Breaking-change/backcompat: deployment evidence and changed-file history were checked for backward-compatibility risk.
Performance: changed surfaces were checked for performance risk in bounded evidence.
Developer experience: changed automation, review, test, setup, and maintenance surfaces were checked for helpful or obstructive DX impact in bounded evidence.
User experience: connected user, operator, API, CLI, documentation, review-comment, status-check, rendering, and workflow-reader behavior was checked for contradictions against code, docs, and tests in bounded evidence.
Visual/DOM: deterministic repair does not infer browser runtime execution; source-backed DOM/UI evidence and trusted workflow receipts were reviewed when present, and non-web surfaces used API/CLI/log/docs/workflow evidence instead.
Accessibility/i18n: accessibility, localization, and human-readable text surfaces were checked where UI, CLI, API message, docs, logs, or review text changed.
Supply-chain/license: dependency, package, model, container, and external-tool changes were checked in bounded evidence.
Packaging: package, build, test, lint, and security contracts were checked in bounded evidence.
Security/privacy: workflow-token, review-gate, and repository-automation security/privacy boundaries were checked in bounded evidence.

Adversarial validation

{"status":"passed","probes":[{"path":"backend/services/newsdom_worker.py","line":367,"hypothesis":"Worker may fail to handle concurrent sweeps","attack_or_counterexample":"Simulated concurrent sweeps","evidence":"Worker uses advisory locks to prevent concurrent sweeps","outcome":"falsified"},{"path":"backend/services/newsdom_pdf_recognition.py","line":63,"hypothesis":"Missing provider config may cause errors","attack_or_counterexample":"Null provider input","evidence":"Function gracefully returns None for missing/inactive providers","outcome":"falsified"}],"residual_risk":"Low risk of edge cases in provider configuration handling"}
  • Result: APPROVE
  • Reason: PR integrates PDF DOM recognition with comprehensive tests and coverage
  • Head SHA: 9fcd5d17e38a7bc7cff8bcfd2479de195a1f36c8
  • Workflow run: 29255409437
  • Workflow attempt: 1

@seonghobae
seonghobae merged commit 14b6e40 into develop Jul 13, 2026
41 checks passed
@seonghobae
seonghobae deleted the feat/pdf-dom-recognition branch July 13, 2026 14:04
@github-project-automation github-project-automation Bot moved this from In Progress 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.

3 participants