Skip to content

feat(edge): standardize organization runtimes on Cloudflare Pingora - #1123

Merged
seonghobae merged 29 commits into
mainfrom
feat/pingora-edge-policy
Aug 29, 2026
Merged

feat(edge): standardize organization runtimes on Cloudflare Pingora#1123
seonghobae merged 29 commits into
mainfrom
feat/pingora-edge-policy

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • adopt Cloudflare Pingora as the only approved CWL public HTTP edge, reverse-proxy, load-balancer, and static-serving runtime
  • add ADR-0019, the binding organization policy, and APA 7/security traceability
  • enforce the rule from the existing organization-required required-workflow-bootstrap context
  • read exact-head changed-file/content evidence through the GitHub REST API without checking out or executing pull-request content
  • reject active Nginx containers, packages, commands, service/config paths, and Kubernetes Nginx ingress contracts

Trust boundary

The required workflow resolves its own immutable job.workflow_repository and job.workflow_sha, checks out only ContextualWisdomLab/.github at that SHA with credentials disabled, and runs the base-branch scanner. The scanner accepts only bounded UTF-8 regular-file evidence from https://api.github.com, caps pagination at 3,000 files, escapes workflow annotations, and fails closed on incomplete evidence.

Existing Nginx code is not silently grandfathered when touched: the scanner evaluates the final exact-head file, allowing deletion/migration PRs while blocking preserved or newly introduced runtime artifacts. Documentation, license text, and source-level negative scanner fixtures remain legal.

Verification

37 policy and workflow regression tests passed
production statements: 186/186 (100%)
production branches: 68/68 (100%)
compileall: passed

Migration order

This policy PR is the first slice. Follow-up PRs add the shared Pingora static/proxy artifacts and then replace the currently inventoried Nginx runtimes in linux-cluster-ops, scopeweave, LineageWeave, inkspan, and naruon without mixing product features into the edge migration.

Developer experience

A single central scanner and documented site/route contract replace per-repository policy drift. Failures identify the exact file, rule, and line.

User experience

The change is infrastructure-only. Product routes, SPA fallback, security headers, WebSocket behavior, health probes, and TLS remain behavior-level acceptance criteria in each migration PR.

Summary by CodeRabbit

  • 새로운 기능
    • 풀 리퀘스트 변경 사항을 자동 검사해 금지된 Nginx 런타임 구성과 설정을 감지합니다.
    • 검증된 정책 소스와 변경 내용을 기반으로 안전한 검사를 수행하며, 위반 시 명확한 오류 정보를 제공합니다.
    • 신뢰할 수 있는 워크플로와 최신 변경 버전을 검증해 안전한 정책 검사를 지원합니다.
  • 문서
    • Cloudflare Pingora를 표준 엣지 런타임으로 지정하고 버전, 마이그레이션 및 예외 승인 기준을 문서화했습니다.
    • Nginx 자산 금지와 PHP/FastCGI 처리 정책을 추가했습니다.
  • 품질 개선
    • 정책 검사, 권한 검증, 아카이브 안전성, 오류 처리 및 다양한 예외 상황에 대한 회귀 테스트를 강화했습니다.

Open in Devin Review

@seonghobae
seonghobae enabled auto-merge (squash) August 18, 2026 10:42
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 21 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a9abfec-2e18-41f3-8e5c-93e1f26d3392

📥 Commits

Reviewing files that changed from the base of the PR and between 2c29463 and 0a317e4.

📒 Files selected for processing (2)
  • AGENTS.md
  • tests/test_opencode_agent_contract.py
📝 Walkthrough

Walkthrough

Pingora를 표준 엣지 런타임으로 지정하고 Nginx 런타임 자산 금지 정책을 문서화했습니다. GitHub API 기반 PR 정책 검사기와 신뢰된 중앙 워크플로 실행 단계를 추가했습니다. 검사기와 워크플로 계약에 대한 회귀 테스트도 추가했습니다.

Changes

Pingora 정책 강제

Layer / File(s) Summary
Pingora 정책 및 표준 정의
AGENTS.md, docs/adr/0019-cloudflare-pingora-edge-standard.md, docs/doctoring/pingora-edge-standard.md, docs/policies/PINGORA_EDGE_POLICY.md
Pingora를 표준 엣지 런타임으로 지정했습니다. 활성 Nginx 런타임 자산을 금지하고 버전, 마이그레이션, 예외 및 검증 규칙을 정의했습니다.
PR 콘텐츠 검사 구현
scripts/ci/pingora_edge_policy.py, tests/fixtures/pingora_policy_samples.txt, tests/test_pingora_edge_policy.py
GitHub REST API에서 PR 변경 파일과 최종 head 콘텐츠를 조회합니다. Nginx 이미지, 명령, 패키지, 경로, Ingress 및 서비스 위반을 탐지합니다. API 입력, 응답 크기, 페이지 수, Base64, UTF-8 및 CLI 종료 코드를 검증합니다.
신뢰된 정책 워크플로 연결
.github/workflows/opencode-review.yml, tests/test_opencode_agent_contract.py, tests/test_pingora_edge_workflow_contract.py
중앙 저장소, SHA, 파일 경로 및 참조를 검증합니다. 검증된 SHA의 정책 소스를 Python tarfile 로직으로 안전하게 materialize하고 필수 파일과 심볼릭 링크를 확인한 뒤 정책 스크립트를 실행합니다. 워크플로 계약 테스트가 PR checkout 금지와 실행 순서를 확인합니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: 🔵 Low · up to 2c294

This PR centralizes Pingora edge policy and blocks active Nginx artifacts when runtime files change, but untouched legacy deployments can remain during the migration and temporarily use different TLS, header, timeout, observability, and patching controls. The change is mergeable with explicit owner tracking and follow-up migration work.

Sequence Diagram(s)

sequenceDiagram
  participant PR as Pull request
  participant Workflow as opencode-review.yml
  participant Source as Central policy source
  participant Policy as pingora_edge_policy.py
  participant GitHub as GitHub REST API

  PR->>Workflow: PR 이벤트와 head SHA 전달
  Workflow->>Workflow: 중앙 소스, SHA, 경로 및 참조 검증
  Workflow->>Source: 검증된 SHA의 tarball을 안전하게 materialize
  Workflow->>Policy: 저장소, PR 번호, head SHA 및 이벤트 전달
  Policy->>GitHub: 변경 파일과 최종 파일 콘텐츠 조회
  GitHub-->>Policy: 파일 목록과 Base64 콘텐츠 반환
  Policy->>Policy: Pingora 정책 위반 및 증거 검증
  Policy-->>Workflow: annotation 및 종료 코드 반환
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 조직 런타임을 Cloudflare Pingora로 표준화하는 이 PR의 주요 변경 사항을 정확하고 간결하게 요약합니다.
Docstring Coverage ✅ Passed Docstring coverage is 83.05% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 59 functions across 4 files. (5 skipped: 5 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 83.05% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 59 functions across 4 files. (5 skipped: 5 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pingora-edge-policy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

github-advanced-security[bot]

This comment was marked as resolved.

@opencode-agent
opencode-agent Bot disabled auto-merge August 18, 2026 10:52
@seonghobae
seonghobae force-pushed the feat/pingora-edge-policy branch from 3160213 to 5860242 Compare August 19, 2026 08:09
@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head security repair (2026-08-19)

Rebased onto current main and pushed 5860242a759c3bde486f88e6cde64484fc173e03. The live Semgrep finding was dynamic-urllib-use-detected at scripts/ci/pingora_edge_policy.py:187; the shared API opener already validates HTTPS api.github.com, rejects userinfo/ports/fragments, and requires /repos/ before opening. The sink now carries a precise Semgrep suppression documenting that validated boundary.

Evidence: tests/test_pingora_edge_policy.py plus tests/test_pingora_edge_workflow_contract.py: 37 passed; compileall and diff check passed; pinned Semgrep scan: 0 findings. Please review this exact head and rerun protected checks.

coderabbitai[bot]

This comment was marked as resolved.

@seonghobae
seonghobae force-pushed the feat/pingora-edge-policy branch from 5860242 to d3ed6c5 Compare August 19, 2026 09:44
@seonghobae

Copy link
Copy Markdown
Contributor Author

Rebased onto current main 9e9f59f3. Pingora policy/workflow tests passed (37 passed); git diff --check passed. Project #1 is In Progress.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head verification: .\n\nImplemented the root-cause actionlint fix for the required Pingora bootstrap: GitHub job identity is now read through /, parsed and validated before immutable central checkout; direct unsupported expressions are gone.\n\nEvidence on this exact head:\n- ..................................... [100%]
37 passed in 0.17s — 37 passed\n- — passed\n- — passed\n- — passed\n\n@opencode-agent @cwl-noema-review please review this exact head. Protected checks are queued; no current-head approval or merge is claimed.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Correction for the previous malformed comment. Current head: d704c2c.

Root-cause actionlint fix: GitHub job identity is read through toJSON(job) and toJSON(github), parsed and validated before immutable central checkout. Direct unsupported job.workflow_* expressions are removed.

Exact-head evidence:

  • pytest tests/test_pingora_edge_policy.py tests/test_pingora_edge_workflow_contract.py: 37 passed
  • actionlint .github/workflows/opencode-review.yml: passed
  • python3 -m compileall -q scripts/ci tests: passed
  • git diff --check: passed

@opencode-agent @cwl-noema-review please review this exact head. Protected checks remain queued; no current-head approval or merge is claimed.

@seonghobae
seonghobae force-pushed the feat/pingora-edge-policy branch from d704c2c to 922652a Compare August 19, 2026 14:11
@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head refresh after merge of #1140: head 922652a1e94553a4bd4274dd346323d05cbea7cb is rebased onto main bbedc1a51ec1a2421f129955c629b3cd0507a4ec. Fresh Pingora policy tests 37 passed; interrogate 100%; compileall, actionlint, and diff-check pass. Review only this head under protected checks.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Current-head repair published at 7ac4199c436e9fe55cb4e1f3d0db61510f4229be (base bbedc1a51ec1a2421f129955c629b3cd0507a4ec). Root cause fixed: privileged opencode-review.yml no longer uses actions/checkout; it materializes the trusted central policy tarball by the validated workflow SHA and verifies the required source/helper before Pingora enforcement. Fresh evidence on this exact head: python3 -m pytest -q -> 1253 passed, 16 subtests passed; coverage report -> 100% (7985 statements, 0 missed); actionlint -> pass; compileall -> pass; interrogate -> pass; diff check -> pass. Protected hosted checks have been re-queued and remain pending.

@seonghobae
seonghobae force-pushed the feat/pingora-edge-policy branch from 7ac4199 to b2645c4 Compare August 20, 2026 00:34
@seonghobae

Copy link
Copy Markdown
Contributor Author

Rebased the Pingora policy/scanner PR onto current main@c47bee591c3d95bd305f2130833ed3a4780d2d1. Exact head: b2645c4. Removed stale-base deletions; retained only the immutable trusted-source gate, bounded GitHub API scan, Pingora policy/docs, and tests. Evidence: 37 Pingora tests passed, 90 adjacent OpenCode/required-workflow tests passed, interrogate 100%, actionlint, compileall, and diff check passed.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode Please review exact current head b2645c4 against base main@c47bee591c3d95bd305f2130833ed3a4780d2d1d.

@seonghobae
seonghobae force-pushed the feat/pingora-edge-policy branch from b2645c4 to 41a59e1 Compare August 20, 2026 04:37
@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent review exact current head 41a59e16234bf6cfb01cdd3fd58172d4681d4859 against protected base 2cce96f8671bfde7e354effef931c14a5928c23b. Rebased current main and fixed the valid review finding: the Pingora workflow contract no longer asserts a nonexistent string. It now proves no PR-head checkout ref, immutable workflow-SHA tarball materialization, required source/helper presence, symlink rejection, and verification-before-execution. Evidence: 37 focused tests, compileall, interrogate, actionlint, and diff --check.

@seonghobae
seonghobae enabled auto-merge (squash) August 20, 2026 06:56
@opencode-agent
opencode-agent Bot disabled auto-merge August 20, 2026 07:59
@seonghobae

Copy link
Copy Markdown
Contributor Author

Merged current main normally to refresh the Pingora edge-policy PR against the exact control-plane head. Focused policy/workflow tests 37 passed; Ruff, compileall, bounded actionlint, bash syntax, and git diff --check passed. Exact head 6915bb93; please review this exact head and publish the required independent approval if no issues remain.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Fixed the exact-head Strix finding in scripts/ci/pingora_edge_policy.py.

Root cause: every prose suffix was exempted before content scanning, so an active runtime file could evade the Pingora policy by being named .txt/.md outside a known documentation location. The exemption is now limited to docs/, doc/, documentation/, recognized root documentation names, licenses, and source fixtures. Added a regression test for config/runtime.txt containing FROM nginx.

Exact-head commit: 251b1683a13c4eab0cb6f2746b6b0fe501319617
Local verification: python -m pytest tests/test_pingora_edge_policy.py -q (43 passed); python -m pytest tests/test_pingora_edge_workflow_contract.py -q (1 passed); compileall; git diff --check.

devin-ai-integration[bot]

This comment was marked as resolved.

@opencode-agent opencode-agent Bot added priority: medium Normal-priority or P2 work status: blocked Blocked by conflict, dependency, or required prerequisite type: feature New or expanded product capability labels Aug 22, 2026

@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 mergeability evidence and changed-file flow before approval, then found merge conflicts on the affected path.

Findings

1. HIGH Merge Conflict Guidance - Resolve the PR branch against the latest base branch

  • Problem: GitHub reports mergeStateStatus DIRTY for this pull request.
  • Root cause: Branch feat/pingora-edge-policy cannot be merged cleanly into main; the changed-file flow below shows which review/runtime path is blocked by the conflict.
  • Fix: Merge or rebase the latest main into feat/pingora-edge-policy, resolve conflict markers in the PR branch, rerun the focused checks, and push the same branch.
  • Repair commands:
gh pr checkout 1123 --repo ContextualWisdomLab/.github
git fetch origin main
git merge --no-ff origin/main  # or: git rebase origin/main
git status --short
# resolve files, then git add <resolved-files>
# merge path: git commit
# rebase path: git rebase --continue
git push origin HEAD:feat/pingora-edge-policy
# rebase path only: git push --force-with-lease origin HEAD:feat/pingora-edge-policy
  • Regression test: Keep OpenCode approval gated on mergeability so model-output failures cannot approve a conflicted PR.

Merge Conflict Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: opencode-review.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: AGENTS.md"]
  S2 --> I2["repository behavior"]
  I2 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V2["required checks"]
  Evidence --> S3["Docs: 0019-cloudflare-pingora-edge-standard.md (3 files)"]
  S3 --> I3["operator or user guidance"]
  I3 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V3["docs review"]
  Evidence --> S4["Repository file: requirements-pip-audit-ci-hashes.txt"]
  S4 --> I4["repository behavior"]
  I4 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V4["required checks"]
  Evidence --> S5["CI script: pingora_edge_policy.py"]
  S5 --> I5["review and security gate shell path"]
  I5 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V5["bash -n plus Strix self-test"]
  Evidence --> S6["Test: test_pingora_edge_policy.py (2 files)"]
  S6 --> I6["regression suite"]
  I6 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V6["targeted test run"]
Loading
  • Result: REQUEST_CHANGES
  • Reason: mergeStateStatus is DIRTY; mergeable is CONFLICTING.
  • Head SHA: 251b16836164cfcfc0914a568d514cc7b6a9dd6d
  • Workflow run: 33195627082
  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Workflow: opencode-review.yml"]
  S1 --> I1["GitHub Actions review job"]
  I1 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V1["actionlint plus required checks"]
  Evidence --> S2["Repository file: AGENTS.md"]
  S2 --> I2["repository behavior"]
  I2 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V2["required checks"]
  Evidence --> S3["Docs: 0019-cloudflare-pingora-edge-standard.md (3 files)"]
  S3 --> I3["operator or user guidance"]
  I3 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V3["docs review"]
  Evidence --> S4["Repository file: requirements-pip-audit-ci-hashes.txt"]
  S4 --> I4["repository behavior"]
  I4 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V4["required checks"]
  Evidence --> S5["CI script: pingora_edge_policy.py"]
  S5 --> I5["review and security gate shell path"]
  I5 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V5["bash -n plus Strix self-test"]
  Evidence --> S6["Test: test_pingora_edge_policy.py (2 files)"]
  S6 --> I6["regression suite"]
  I6 --> Conflict["Merge conflict blocks this path"]
  Conflict --> V6["targeted test run"]
Loading

@opencode-agent

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 5 new potential issues.

Devin Review

Comment thread scripts/ci/pingora_edge_policy.py
Comment thread scripts/ci/pingora_edge_policy.py Outdated
Comment on lines +35 to +40
- name: Resolve immutable central policy source
id: trusted_source
env:
JOB_CONTEXT_JSON: ${{ toJSON(job) }}
WORKFLOW_SHA: ${{ github.workflow_sha }}
WORKFLOW_REF: ${{ github.workflow_ref }}

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.

🔍 Verify required-workflow identity live

The source resolver depends on github.workflow_ref and github.workflow_sha semantics absent from local tests. Capture both values from a consumer-repository required run.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +151 to +152
if pure.as_posix() == "scripts/ci/pingora_edge_policy.py":
return True

@devin-ai-integration devin-ai-integration Bot Aug 29, 2026

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.

🔍 Scanner exemption is path-coupled

The exemption hard-codes one implementation path. Moving or wrapping the scanner can unexpectedly change policy coverage, so fixture ownership needs an explicit contract.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread .github/workflows/opencode-review.yml Outdated

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 5 new potential issues.

Devin Review

Comment thread scripts/ci/pingora_edge_policy.py
Comment thread scripts/ci/pingora_edge_policy.py Outdated
Comment thread scripts/ci/pingora_edge_policy.py
Comment on lines +134 to +178
with tarfile.open(archive_path, "r:gz") as archive:
members = archive.getmembers()
top_levels: set[str] = set()
targets: set[str] = set()
directories: list[tuple[tarfile.TarInfo, tuple[str, ...]]] = []
files: list[tuple[tarfile.TarInfo, tuple[str, ...]]] = []
for member in members:
name = member.name
if not name or name.startswith("/") or "\x00" in name or "\\" in name:
raise ValueError(f"unsafe archive member path: {name!r}")
parts = PurePosixPath(name).parts
if not parts or parts[0] in {".", ".."}:
raise ValueError(f"unsafe archive member path: {name!r}")
top_levels.add(parts[0])
relative_parts = parts[1:]
if not relative_parts:
if not member.isdir():
raise ValueError("archive root must be a directory")
continue
if any(part in {"", ".", ".."} for part in relative_parts):
raise ValueError(f"unsafe archive member path: {name!r}")
relative_key = "/".join(relative_parts)
if relative_key in targets:
raise ValueError(f"duplicate archive member path: {relative_key}")
targets.add(relative_key)
if member.isdir():
directories.append((member, relative_parts))
elif member.isfile():
files.append((member, relative_parts))
else:
raise ValueError(f"unsupported archive member type: {name!r}")
if len(top_levels) != 1:
raise ValueError("archive must contain exactly one top-level directory")
for _member, relative_parts in sorted(
directories, key=lambda item: len(item[1])
):
(root / Path(*relative_parts)).mkdir(parents=True, exist_ok=True)
for member, relative_parts in files:
destination = root / Path(*relative_parts)
destination.parent.mkdir(parents=True, exist_ok=True)
source = archive.extractfile(member)
if source is None:
raise ValueError(f"archive member is not readable: {member.name!r}")
with source, destination.open("xb") as output:
shutil.copyfileobj(source, output)

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.

📝 Info: Archive validation precedes extraction

Every archive member is validated before files are written. Links, duplicate targets, traversal components, and multiple roots fail without partial extraction.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +255 to +270
raw_patch = item.get("patch")
patch = "" if raw_patch is None else raw_patch
if (
not isinstance(path, str)
or not path
or not isinstance(status, str)
or not isinstance(patch, str)
):
raise PolicyError("GitHub changed-file entry has invalid bounded fields")
files.append(
ChangedFile(
path=path,
status=status,
patch=patch,
patch_available=raw_patch is not None,
)

@devin-ai-integration devin-ai-integration Bot Aug 29, 2026

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.

📝 Info: Missing patches remain fail-closed

An omitted GitHub patch triggers final-content inspection. It is not treated as an empty safe patch.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 6 new potential issues.

Devin Review

Comment thread scripts/ci/pingora_edge_policy.py Outdated
Comment thread scripts/ci/pingora_edge_policy.py Outdated
Comment thread scripts/ci/pingora_edge_policy.py Outdated
Comment thread scripts/ci/pingora_edge_policy.py Outdated
Comment on lines +146 to +152
is_known_documentation_path = pure.parts and (
any(part.lower() in DOCUMENTATION_DIRECTORIES for part in pure.parts)
or (len(pure.parts) == 1 and stem in DOCUMENTATION_ROOT_NAMES)
)
if lower_name in LICENSE_NAMES or (
is_known_documentation_path and pure.suffix.lower() in DOCUMENT_SUFFIXES
):

@devin-ai-integration devin-ai-integration Bot Aug 29, 2026

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.

📝 Info: Nested documentation exemption remains bounded

Only exact doc, docs, or documentation components exempt prose suffixes. Similar directory names and runtime suffixes remain scanned.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +156 to +159
lower_parts = tuple(part.lower() for part in pure.parts)
is_tests_fixture = len(lower_parts) >= 2 and lower_parts[:2] == ("tests", "fixtures")
if is_tests_fixture and pure.suffix.lower() in SOURCE_TEST_SUFFIXES | DOCUMENT_SUFFIXES:
return True

@devin-ai-integration devin-ai-integration Bot Aug 29, 2026

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.

📝 Info: Fixture exemption matches policy scope

Only approved source and prose files beneath root-level tests/fixtures bypass scanning. Deployment fixture directories remain runtime candidates.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 1 new potential issue.

Devin Review

Comment on lines +246 to +274
for page in range(1, 32):
url = f"{api_url}/repos/{repository}/pulls/{pull_request}/files?per_page=100&page={page}"
payload = opener(url, token)
if not isinstance(payload, list):
raise PolicyError("GitHub changed-file evidence is not a JSON array")
for item in payload:
if not isinstance(item, Mapping):
raise PolicyError("GitHub changed-file entry is not an object")
path = item.get("filename")
status = item.get("status")
raw_patch = item.get("patch")
patch = "" if raw_patch is None else raw_patch
if (
not isinstance(path, str)
or not path
or not isinstance(status, str)
or not isinstance(patch, str)
):
raise PolicyError("GitHub changed-file entry has invalid bounded fields")
files.append(
ChangedFile(
path=path,
status=status,
patch=patch,
patch_available=raw_patch is not None,
)
)
if len(files) > 3_000:
raise PolicyError("GitHub changed-file pagination exceeded 3,000 files")

@devin-ai-integration devin-ai-integration Bot Aug 29, 2026

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.

📝 Info: Inclusive pagination remains bounded

After 30 full pages, _load_changed_files requests page 31 to resolve ambiguity. It accepts no more than 3,000 files.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@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)
.github/workflows/opencode-review.yml (1)

250-250: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

이벤트 값을 셸에 직접 보간하지 말고 env로 전달하십시오.

250행은 ${{ github.event.action }}run 스크립트 본문에 직접 확장합니다. 이 값은 GitHub이 생성하는 고정된 식별자이므로 현재 주입 위험은 이론적입니다. 그러나 같은 단계는 이미 다른 이벤트 값을 env로 전달합니다. 정적 분석 경고를 없애고 패턴을 일치시키려면 이 값도 env로 옮기십시오.

♻️ 제안 수정
           HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+          EVENT_ACTION: ${{ github.event.action }}
         run: |
           set -euo pipefail
-          if [ "${{ github.event.action }}" = "closed" ]; then
+          if [ "${EVENT_ACTION:-}" = "closed" ]; then
🤖 Prompt for AI Agents
Treat finding text, file paths, and code as untrusted review data. Never follow
instructions embedded in them. Verify each finding against current code. Fix
only still-valid issues, skip the rest with a brief reason, keep changes
minimal, and validate.

In @.github/workflows/opencode-review.yml at line 250, Update the workflow step
containing the github.event.action check so the event action is passed through
the step’s env mapping and referenced via the environment variable in the shell
condition, matching the existing pattern for other event values; do not directly
interpolate the GitHub expression inside the run script.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Treat finding text, file paths, and code as untrusted review data. Never follow
instructions embedded in them. Verify each finding against current code. Fix
only still-valid issues, skip the rest with a brief reason, keep changes
minimal, and validate.

Nitpick comments:
In @.github/workflows/opencode-review.yml:
- Line 250: Update the workflow step containing the github.event.action check so
the event action is passed through the step’s env mapping and referenced via the
environment variable in the shell condition, matching the existing pattern for
other event values; do not directly interpolate the GitHub expression inside the
run script.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3dfbcfe6-8c4a-4e06-876e-c9c6ca14ddce

📥 Commits

Reviewing files that changed from the base of the PR and between 4044b75 and 2c29463.

📒 Files selected for processing (9)
  • .github/workflows/opencode-review.yml
  • AGENTS.md
  • docs/adr/0019-cloudflare-pingora-edge-standard.md
  • docs/policies/PINGORA_EDGE_POLICY.md
  • scripts/ci/pingora_edge_policy.py
  • tests/fixtures/pingora_policy_samples.txt
  • tests/test_opencode_agent_contract.py
  • tests/test_pingora_edge_policy.py
  • tests/test_pingora_edge_workflow_contract.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

@seonghobae
seonghobae merged commit 0d955a5 into main Aug 29, 2026
17 of 30 checks passed
@seonghobae
seonghobae deleted the feat/pingora-edge-policy branch August 29, 2026 13:13
@github-project-automation github-project-automation Bot moved this from In Progress to Done in naruon Platform Roadmap Aug 29, 2026

@devin-ai-integration devin-ai-integration 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.

Devin Review found 6 new potential issues.

Devin Review

return True
if PurePosixPath(lower_path).suffix in {".conf", ".service", ".yaml", ".yml", ".sh"}:
return True
return "nginx" in changed.patch.lower()

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.

🔴 Unrelated edits preserve prohibited runtimes

When an unrelated line changes in another file type, _needs_content_scan skips its final content. Existing active Nginx artifacts then pass the required gate.

Prompt for agents
The final-content contract applies to every changed runtime candidate, but _needs_content_scan only scans selected suffixes or patches containing nginx. For example, config/runtime.txt containing an existing FROM nginx line is skipped when a PR changes another line without including nginx in the patch. Redesign candidate selection so touching a file cannot grandfather prohibited final content, while preserving the documented evidence bounds. Add an evaluate_pull_request regression test where the patch omits nginx but the final content contains a violation.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +59 to +62
r"(?im)^\s*(?:-\s*)?(?:FROM|image:)\s+"
r"(?:[A-Za-z0-9._-]+(?::[0-9]+)?/)*"
rf"{NGINX_RUNTIME_IMAGE_RE}"
r"(?:[:@]\S+|\s|$)"

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.

🔴 Common container syntax bypasses enforcement

Quoted YAML images and Docker FROM --platform lines make nginx_container_image find nothing. Prohibited Nginx containers then pass the required gate.

Prompt for agents
Expand nginx_container_image detection to cover valid quoted YAML image scalars and Dockerfile FROM options before the image reference. Keep registry, digest, and exporter handling intact. Add scan_content and evaluate_pull_request tests for image: "nginx:1.27", image: 'nginx:1.27', and FROM --platform=linux/amd64 nginx:1.27.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +76 to +79
r"(?im)(?:^\s*(?:systemctl|service)\s+(?:--\S+\s+)*(?:\S+\s+)*nginx\b|"
rf"^\s*{SUDO_PREFIX_RE}nginx(?=\s|$|[;&|])|"
r"(?:CMD|ENTRYPOINT)\s*\[[^\n]*[\"']nginx[\"']|"
r"\bnginx\s+-g\s+[\"']daemon\s+off;)"

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.

🟡 Wrapped Nginx commands evade detection

Commands such as exec nginx -s reload make nginx_runtime_command find nothing. Active Nginx launch commands can pass the required gate.

Prompt for agents
Extend nginx_runtime_command coverage for ordinary shell wrappers and executable paths, including exec nginx, command nginx, /usr/sbin/nginx, and container launch commands such as docker run nginx. Avoid treating source identifiers as commands. Add focused scan_content tests for each accepted command shape and nearby negative cases.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +90 to +94
"nginx_package_install",
re.compile(
rf"(?im)^\s*(?:RUN\s+)?{SUDO_PREFIX_RE}(?:apk\s+add|apt(?:-get)?\s+install|"
r"dnf\s+install|yum\s+install)\b(?:[^\n#]*\\\s*\n\s*)*[^\n#]*\bnginx\b"
),

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.

🔍 Package coverage remains manager-specific

nginx_package_install recognizes only apk, apt, dnf, and yum. Review whether organization repositories use other package managers requiring equivalent enforcement.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +143 to +150
is_known_documentation_path = pure.parts and (
any(part.lower() in DOCUMENTATION_DIRECTORIES for part in pure.parts)
or (len(pure.parts) == 1 and stem in DOCUMENTATION_ROOT_NAMES)
)
if lower_name in LICENSE_NAMES or (
is_known_documentation_path and pure.suffix.lower() in DOCUMENT_SUFFIXES
):
return True

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.

🔍 Documentation exemption trusts directory placement

_is_documentation_or_source_fixture exempts recognized prose suffixes beneath any documentation directory. Confirm those directories cannot contain executable runtime templates.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +332 to +333
if event_action == "closed":
return ()

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.

📝 Info: Closed events deliberately skip evidence

evaluate_pull_request returns before validation on closed events. Closed pull requests cannot merge, so this does not weaken the active merge gate.

Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: medium Normal-priority or P2 work status: blocked Blocked by conflict, dependency, or required prerequisite type: feature New or expanded product capability

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants