Skip to content

feat(operations): restack runner-assignment audit on current main - #252

Closed
seonghobae wants to merge 9 commits into
mainfrom
feat/actions-runner-assignment-audit-current-main-v4
Closed

feat(operations): restack runner-assignment audit on current main#252
seonghobae wants to merge 9 commits into
mainfrom
feat/actions-runner-assignment-audit-current-main-v4

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Purpose

Create a fresh direct protected-main successor for stale runner-assignment Drafts without rebasing, force-pushing, or transferring predecessor evidence. Protected main advanced through #250; this successor is built directly on that protected lineage and is now fully revalidated at its current exact head.

Exact source identity

  • protected base: 82d884d0415a83423d56fba9bac5262c3470a646;
  • source predecessor feat(operations): restack runner-assignment audit on live main #251 exact head: aeb567797ee9fd18c7e86fc03c36b91dd5e89223;
  • initial current-main restack: 93f3a585d9b584b1e901c02f03059db7ba4736c5;
  • current exact head: edf9f7e4c92f29b66a19913574006cf294d4a8b9;
  • ancestry: exactly 3 commits ahead / 0 behind protected base; merge base is exactly protected base;
  • current-main delta: exactly 10 files, 1,147 additions, 0 deletions.

The two post-restack commits are retained evidence of a test-discovered documentation defect and its correction. The first changelog correction attempt changed unrelated protected wording; an immediate exact-base comparison detected that no-op-quality failure. The current head restores all protected changelog text exactly and adds only the intended one-line runner-assignment contract. History was not rewritten.

Restack integrity

The eight runner-assignment source/test/operator blobs are preserved exactly from #251:

  • docs/doctoring/actions-runner-assignment-audit.md3920cc778152b366263e94f324c6e74a2b8becb8;
  • scripts/actions-runner-assignment-audit.mjse09422a7a5effe883af6515b0255134dfe2effb3;
  • scripts/lib/actions-runner-assignment-audit.mjsf7dba42424cd2c6c93ba95459e7a12eecf4135c4;
  • scripts/lib/actions-runner-assignment-source.mjs0cad167a30e933d56f97d47e111be40ec280d2d3;
  • test/actions-runner-assignment-audit.test.ts45ca88e2a9467afd6d132d0386a9bc0038a23b0f;
  • test/actions-runner-assignment-cli.test.ts93e24358f70efd7844340c24d85d4f52e774e366;
  • test/actions-runner-assignment-docs.test.ts83076fbf1f05234b1e5710348f48f6e5317b27ca;
  • test/actions-runner-assignment-source.test.tse35adf11d2ff167f44014d1c8f9a9388249b8bc9.

Protected-main package.json was independently refetched at base 82d884d0415a83423d56fba9bac5262c3470a646. The successor changes that file only by adding operations:runner-assignment; current package-manager/install-script metadata and #250 KPI provenance controls are preserved. The final CHANGELOG.md diff is one additive line only.

Evidence boundary

The operator is read-only and exact-source-head/workflow-run-ID bound. Paginated filter=all job evidence separates runner assignment from workflow/test conclusions and dependency/environment waiting. A fresh unassigned queue remains non-passing; bounded-grace expiry fails closed; an assigned runner followed by workflow failure proves assignment only, never workflow success.

The gh subprocess receives bounded PATH, explicit read-only GH_TOKEN, pinned GH_HOST=github.com, and NO_COLOR=1; ambient write/model/App/proxy/home authority is not intentionally propagated. Reports carry no required-check, formal-review, merge, release, deployment, production, KPI, licensing, IP, or acquisition authority.

Fresh exact-head validation

For unchanged exact head edf9f7e4c92f29b66a19913574006cf294d4a8b9 on protected base 82d884d0415a83423d56fba9bac5262c3470a646:

  • application ci run 31659834342: terminal success;
  • reviewer-ci run 31659834314: terminal success;
  • protected-base-eligible central Security Scan run 31659834299: terminal success;
  • central OSV evidence checked out exact base 82d884d0415a83423d56fba9bac5262c3470a646, then exact head edf9f7e4c92f29b66a19913574006cf294d4a8b9; both scans produced 0 findings and the reporter found no issues;
  • dependency-review, Trivy filesystem scan, and Scorecard jobs were terminal success;
  • application CI checked out the exact current head and live base, used Node 24.19.0 / npm 11.17.0, installed with 0 vulnerabilities, and passed release:verify with 120 test files / 1,028 tests;
  • configured source/scripts coverage is 100% statements, branches, functions, and lines; npm audit --audit-level=high reports 0 vulnerabilities;
  • formal GitHub reviews: 0; inline review threads: 0; GitHub reports the content graph mergeable.

The non-strict KPI step still reports SKIP because no production log is present. The acquisition manifest continues to report missing final-gate production KPI/provenance, independent security-validation, immutable release-publication, production deployment/attestation/verification and environment-governance, revenue/customer, and legal/transfer evidence. None of those absences is promoted to PASS by this PR.

Governance and merge boundary

Live enforceable Noema governance was refetched against the current head/base. Active organization ruleset 18794436 applies central .github/workflows/security-scan.yml from .github main to the default branch, has no bypass actors, and does not currently impose an independent-approval rule. Central .github main is 6eb06cdd08c79a06f7b390069d4ffa49e2eb7dba; its Security Scan remains protected-base triggered and hard-gates OSV PR-introduced vulnerabilities, supported dependency review, and fixable MEDIUM/HIGH/CRITICAL Trivy findings, with Scorecard posture evidence.

No predecessor CI, reviewer, scanner, model, operational, or production evidence transfers from #251/#240/#94. Marking this PR ready may itself trigger new evidence; any new pending, queued, skipped, absent, neutral, failed, cancelled, stale, predecessor-head, status-only, model-only, or rate-limited result is non-passing until terminally resolved. Immediately before merge, refetch exact head/base, ancestry, reviews/threads, actual checks and checkout SHAs, live ruleset, and central Security Scan authority again and require zero valid unresolved findings.

#240 and #94 remain historical predecessors until this current protected-main successor is actually integrated; only then may they be closed as proven superseded work.

Related: #27, #30, #77, #79, #88, #91, #94, #240, #251

Summary by CodeRabbit

  • 새 기능

    • GitHub Actions 워크플로의 러너 할당 상태를 읽기 전용으로 점검하는 감사 명령을 추가했습니다.
    • 모든 작업 페이지를 확인해 PASS, PENDING, FAIL 상태로 명확히 분류합니다.
    • 일정 시간 이상 러너가 할당되지 않으면 실패로 처리하며, 러너 할당 이후의 워크플로 실패도 성공으로 간주하지 않습니다.
    • 결과를 구조화된 보고서로 저장하고, 인증 정보가 보고서에 노출되지 않도록 보호합니다.
  • 문서

    • 감사 절차, 판정 기준, 대기 상태 구분 및 보고서 요구사항을 문서화했습니다.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 63be1878-0a45-439f-b03a-b43e423b25df

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

읽기 전용 GitHub Actions runner-assignment 감사 CLI를 추가했다. 정확한 source head와 workflow run을 검증하고 모든 job 페이지를 수집한다. runner 할당 상태를 PASS, PENDING, FAIL로 분류하고 제한된 JSON 보고서를 원자적으로 기록한다.

Changes

Runner assignment 감사

Layer / File(s) Summary
페이지네이션 증거 수집
scripts/lib/actions-runner-assignment-source.mjs, test/actions-runner-assignment-source.test.ts
선택된 run ID를 검증하고 모든 job 페이지를 평탄화한다. 평가에 필요한 필드만 투영한 증거를 생성한다.
Runner 할당 상태 평가
scripts/lib/actions-runner-assignment-audit.mjs, test/actions-runner-assignment-audit.test.ts
source head, workflow 상태, job 상태, queue grace, 환경 보호 및 needs 대기를 기준으로 PASS, PENDING, FAIL을 반환한다. runner 할당 후 workflow 실패는 성공으로 처리하지 않는다.
CLI 실행 및 보고서 통합
scripts/actions-runner-assignment-audit.mjs, package.json, test/actions-runner-assignment-cli.test.ts
제한된 gh 환경과 읽기 전용 API 어댑터를 구성한다. 보고서를 원자적으로 기록하고 상태별 종료 코드를 반환한다.
운영 계약 및 검증
docs/doctoring/actions-runner-assignment-audit.md, CHANGELOG.md, test/actions-runner-assignment-docs.test.ts
입력, API 범위, 보안 경계, RCA 기준, acceptance 조건 및 operations:runner-assignment 명령을 문서화한다.

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

Mergeability Score: 🔵 Low · up to edf9f

This PR adds a read-only runner-assignment audit and CLI entry point. The current implementation may retain more jobs than documented, can hide the original file-write error during cleanup, and may conflict with the repository’s secret-handling policy unless an exception is confirmed. CI and security checks pass, so the PR is mergeable with explicit owner awareness of these bounded risks.

Possibly related issues

  • ContextualWisdomLab/noema issue 30 — bounded stall 분류, 페이지네이션 증거 수집, exact-head 검증 및 자격 증명 격리 목표를 직접 구현한다.

Possibly related PRs

  • ContextualWisdomLab/noema#71 — workflow source/head provenance와 runner 증거를 권한 증거와 분리하는 구현이 연결된다.
  • ContextualWisdomLab/noema#230 — 읽기 전용 Actions 감사, 페이지네이션, 제한된 gh 환경 및 fail-closed 검증 패턴이 연결된다.

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant RunnerAssignmentCLI
  participant GitHubActionsAPI
  participant EvidenceEvaluator
  participant ReportFile

  Operator->>RunnerAssignmentCLI: operations:runner-assignment 실행
  RunnerAssignmentCLI->>GitHubActionsAPI: workflow run 및 전체 jobs 조회
  GitHubActionsAPI-->>RunnerAssignmentCLI: paginated run/job 증거 반환
  RunnerAssignmentCLI->>EvidenceEvaluator: source head와 runner assignment 평가
  EvidenceEvaluator-->>RunnerAssignmentCLI: PASS, PENDING 또는 FAIL
  RunnerAssignmentCLI->>ReportFile: JSON 보고서 원자적 기록
  RunnerAssignmentCLI-->>Operator: 상태 출력 및 종료 코드 반환
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 현재 main을 기준으로 runner-assignment 감사 기능을 재구성하는 변경을 간결하게 설명하며 변경 내용과 일치합니다.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/actions-runner-assignment-audit-current-main-v4

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.

@seonghobae
seonghobae marked this pull request as ready for review August 13, 2026 02:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
scripts/actions-runner-assignment-audit.mjs (1)

146-158: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

parseQueueGrace가 평가기 상한을 반영하지 않는다.

scripts/lib/actions-runner-assignment-audit.mjs는 30분 초과 grace를 runner_evidence_invalid FAIL로 거부한다. 여기서는 상한이 없으므로, 잘못된 환경변수 값이 입력 오류가 아니라 감사 실패 보고서로 나타난다. 운영자 진단이 어려워진다. CLI에서 동일한 상한을 적용하십시오.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/actions-runner-assignment-audit.mjs` around lines 146 - 158, Update
parseQueueGrace to enforce the same 30-minute maximum used by the evaluator,
rejecting values above that limit as invalid environment configuration before
audit processing. Preserve the existing positive-integer and safe-integer
validation, and reuse the shared upper-bound symbol if one is available.
test/actions-runner-assignment-source.test.ts (1)

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

Add regression coverage for the two input and API boundary contracts introduced by this audit: reject oversized run-id text and missing read adapters, and verify that ghApi rejects absolute paths, traversal segments, control characters, and overlong paths without invoking gh. These tests should remain local and use Vitest.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/actions-runner-assignment-source.test.ts` around lines 16 - 28, Add
regression cases in the existing tests for parseSelectedRunIds covering input
exceeding MAX_RUN_ID_TEXT_BYTES and asserting rejection, plus the
adapter-missing path for the relevant assignment-source API and its expected
failure. Keep the tests in Vitest style alongside the existing boundary cases
and use the established symbols and error messages.

Apply the same fix in `@test/actions-runner-assignment-cli.test.ts` around lines
11 - 23: Covers the CLI API-path validation cases listed in the original
comment.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/actions-runner-assignment-audit.mjs`:
- Around line 173-184: Update the cleanup logic in the finally block around
descriptor and temporaryPath handling so unlinkSync failures other than ENOENT
do not throw and replace an exception from the preceding try body. Preserve
descriptor closure and missing-file tolerance, while swallowing cleanup errors
to ensure the original openSync or writeFileSync failure propagates.

In `@scripts/lib/actions-runner-assignment-source.mjs`:
- Around line 59-69: scripts/lib/actions-runner-assignment-source.mjs:59-69의 수집
루프에서 모든 run의 job을 합산한 누적 개수가 총량 상한 2,000건을 넘지 않도록 MAX_SELECTED_JOBS 검사를 전역 누적
기준으로 적용하십시오. scripts/lib/actions-runner-assignment-source.mjs의 jobs 수집 동작은 유지하되
상한 초과 시 기존 오류 흐름을 사용하십시오.
docs/doctoring/actions-runner-assignment-audit.md:20-20은 총량 상한을 적용한 뒤 별도 변경이 필요
없습니다.

---

Nitpick comments:
In `@scripts/actions-runner-assignment-audit.mjs`:
- Around line 146-158: Update parseQueueGrace to enforce the same 30-minute
maximum used by the evaluator, rejecting values above that limit as invalid
environment configuration before audit processing. Preserve the existing
positive-integer and safe-integer validation, and reuse the shared upper-bound
symbol if one is available.

In `@test/actions-runner-assignment-source.test.ts`:
- Around line 16-28: Add regression cases in the existing tests for
parseSelectedRunIds covering input exceeding MAX_RUN_ID_TEXT_BYTES and asserting
rejection, plus the adapter-missing path for the relevant assignment-source API
and its expected failure. Keep the tests in Vitest style alongside the existing
boundary cases and use the established symbols and error messages.

Apply the same fix in `@test/actions-runner-assignment-cli.test.ts` around lines
11 - 23: Covers the CLI API-path validation cases listed in the original
comment.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 12129f2d-8abb-461e-820a-60ee59b5eb20

📥 Commits

Reviewing files that changed from the base of the PR and between 82d884d and edf9f7e.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • docs/doctoring/actions-runner-assignment-audit.md
  • package.json
  • scripts/actions-runner-assignment-audit.mjs
  • scripts/lib/actions-runner-assignment-audit.mjs
  • scripts/lib/actions-runner-assignment-source.mjs
  • test/actions-runner-assignment-audit.test.ts
  • test/actions-runner-assignment-cli.test.ts
  • test/actions-runner-assignment-docs.test.ts
  • test/actions-runner-assignment-source.test.ts

Comment thread scripts/actions-runner-assignment-audit.mjs
Comment thread scripts/lib/actions-runner-assignment-source.mjs
@seonghobae
seonghobae marked this pull request as draft August 13, 2026 03:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant