feat(actions): inventory orphaned workflow identities - #1026
Conversation
|
Warning Review limit reached
Next review available in: 2 minutes 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. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthrough읽기 전용 GitHub Actions 워크플로 인벤토리 스크립트를 추가했습니다. 기본 브랜치 SHA와 워크플로 레지스트리를 비교하고 상태를 분류합니다. 불완전한 입력과 API 응답은 실패 처리합니다. 결과는 JSON 원장으로 출력하며 관련 테스트와 운영 문서를 추가했습니다. Changes워크플로 수명주기 인벤토리
Estimated code review effort: 4 (Complex) | ~60 minutes Merge Risk: 🔵 Low · up to The PR adds a read-only workflow-identity inventory without changing registry state. It is mergeable with owner follow-up for bounded risks: audit records may overstate inspection coverage, rollback instructions omit some related files, and usage documentation should accurately describe fixture-based input. Sequence Diagram(s)sequenceDiagram
participant Operator
participant inventory_orphaned_workflows
participant GitHub_Actions_API
participant Repository_Tree
Operator->>inventory_orphaned_workflows: JSON payload와 CLI 옵션 전달
inventory_orphaned_workflows->>GitHub_Actions_API: 워크플로 페이지 조회
GitHub_Actions_API-->>inventory_orphaned_workflows: 워크플로 상태, 경로, 페이지네이션 반환
inventory_orphaned_workflows->>Repository_Tree: 기본 브랜치 SHA의 파일 트리 조회
Repository_Tree-->>inventory_orphaned_workflows: 저장소 YAML 경로 반환
inventory_orphaned_workflows-->>Operator: 분류된 JSON ledger와 종료 코드 반환
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Exact current-head evidence for |
f7a4572 to
cbb0784
Compare
|
Fresh Inkspan consumer audit exposes a current exact-head routing contract gap in this existing #945 owner PR; no Inkspan-local scanner workaround is correct. Exact source owner: #1026 That proposition now conflicts with the live #945 authority itself: #945 already records Inkspan as a confirmed fleet reproduction ( Falsifiable RCA: owner routing is encoded as a stale three-repository constant rather than being complete for the current centrally accepted fleet-owner registry. This is central source ownership; Inkspan must not duplicate or patch the shared classifier. Test-first acceptance for this PR: add a RED fixture containing repository Current exact-head workflow evidence is not acceptance-clean independently of this source defect: OSV |
f4f0f81 to
7121132
Compare
|
Rebased orphaned workflow lifecycle inventory onto current main@c47bee59. Exact head: 7121132. The read-only scanner binds every classification to an unchanged exact default-branch SHA, paginates with count/ID checks, rejects traversal/encoded paths and COPILOT_GITHUB_TOKEN, distinguishes active/disabled/dynamic/unresolved identities, and preserves owner issue evidence. Evidence: 18 tests passed, interrogate 100%, compileall and diff check passed. |
|
@opencode-agent review exact current head 7121132 against base c47bee5; inspect the orphaned identity classification, ledger schema, and read-only contract. |
Add a read-only classifier that binds advertised GitHub Actions identities to the exact protected default-branch SHA, fail-closes on pagination or visibility defects, and refuses registry mutation. Addresses #945.
7121132 to
bbd7fa9
Compare
|
@opencode-agent review exact current head bbd7fa9 against protected base 2cce96f. Rebased the read-only orphaned workflow inventory onto current main; verified 18 focused tests, compileall, interrogate, and diff --check. Confirm exact default-branch SHA binding, bounded pagination, traversal/encoded-path/COPILOT token rejection, identity classification, and ledger evidence on this head. |
|
Current-head validation for exact commit |
|
Exact-head local verification for |
|
Exact-head evidence for 271ad3a: corrected the ARCHITECTURE.md section order identified by Devin. The hourly product-caller note now remains under the hourly NVIDIA NIM repair gate. Local verification passed: 18 inventory tests; 264 statements / 132 branches at 100% for the production inventory module; interrogate, compileall, and git diff --check. Hosted checks must be regenerated for this SHA; no approval or merge is claimed. |
|
Additional exact-head evidence for 271ad3a: complete central suite passed 1,301 tests plus 16 subtests; aggregate production statement/branch coverage is 100% (8,328 statements / 3,260 branches). The repository-wide interrogate run is 99.9% solely because the pre-existing GitHubClient.init docstring is owned by #1189; the changed inventory module remains 100%. I did not duplicate that separate PR scope. No approval or merge is claimed. |
|
Warning Review limit reachedNext included review available in 43 minutes. View limit detailsLimit 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. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (13)
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. Comment |
There was a problem hiding this comment.
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
DIRTYfor this pull request. - Root cause: Branch
feat/orphaned-workflow-lifecycle-inventorycannot be merged cleanly intomain; the changed-file flow below shows which review/runtime path is blocked by the conflict. - Fix: Merge or rebase the latest
mainintofeat/orphaned-workflow-lifecycle-inventory, resolve conflict markers in the PR branch, rerun the focused checks, and push the same branch. - Repair commands:
gh pr checkout 1026 --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/orphaned-workflow-lifecycle-inventory
# rebase path only: git push --force-with-lease origin HEAD:feat/orphaned-workflow-lifecycle-inventory- 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["Changed file (3 files)"]
S1 --> I1["repository behavior"]
I1 --> Conflict["Merge conflict blocks this path"]
Conflict --> V1["required checks"]
Evidence --> S2["Docs: orphaned-workflow-lifecycle.md"]
S2 --> I2["operator or user guidance"]
I2 --> Conflict["Merge conflict blocks this path"]
Conflict --> V2["docs review"]
Evidence --> S3["CI script (3 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> Conflict["Merge conflict blocks this path"]
Conflict --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test: test_inventory_orphaned_workflows.py"]
S4 --> I4["regression suite"]
I4 --> Conflict["Merge conflict blocks this path"]
Conflict --> V4["targeted test run"]
- Result: REQUEST_CHANGES
- Reason: mergeStateStatus is
DIRTY; mergeable isCONFLICTING. - Head SHA:
1be76989887ab772e3ce0d2e0c7f22d3ca98dd94 - Workflow run: 32768394298
- Workflow attempt: 1
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 --> Conflict["Merge conflict blocks this path"]
Conflict --> V1["required checks"]
Evidence --> S2["Docs: orphaned-workflow-lifecycle.md"]
S2 --> I2["operator or user guidance"]
I2 --> Conflict["Merge conflict blocks this path"]
Conflict --> V2["docs review"]
Evidence --> S3["CI script (3 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> Conflict["Merge conflict blocks this path"]
Conflict --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test: test_inventory_orphaned_workflows.py"]
S4 --> I4["regression suite"]
I4 --> Conflict["Merge conflict blocks this path"]
Conflict --> V4["targeted test run"]
OpenCode Review Overview
Pull request overviewOpenCode reviewed the current-head mergeability evidence and changed-file flow before approval, then found merge conflicts on the affected path. Findings1. HIGH Merge Conflict Guidance - Resolve the PR branch against the latest base branch
gh pr checkout 1026 --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/orphaned-workflow-lifecycle-inventory
# rebase path only: git push --force-with-lease origin HEAD:feat/orphaned-workflow-lifecycle-inventory
Merge Conflict Evidence Mapflowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Changed file (3 files)"]
S1 --> I1["repository behavior"]
I1 --> Conflict["Merge conflict blocks this path"]
Conflict --> V1["required checks"]
Evidence --> S2["Docs: orphaned-workflow-lifecycle.md"]
S2 --> I2["operator or user guidance"]
I2 --> Conflict["Merge conflict blocks this path"]
Conflict --> V2["docs review"]
Evidence --> S3["CI script (3 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> Conflict["Merge conflict blocks this path"]
Conflict --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test: test_inventory_orphaned_workflows.py"]
S4 --> I4["regression suite"]
I4 --> Conflict["Merge conflict blocks this path"]
Conflict --> V4["targeted test run"]
Changed-File Evidence Mapflowchart LR
PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
Evidence --> S1["Changed file (3 files)"]
S1 --> I1["repository behavior"]
I1 --> Conflict["Merge conflict blocks this path"]
Conflict --> V1["required checks"]
Evidence --> S2["Docs: orphaned-workflow-lifecycle.md"]
S2 --> I2["operator or user guidance"]
I2 --> Conflict["Merge conflict blocks this path"]
Conflict --> V2["docs review"]
Evidence --> S3["CI script (3 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> Conflict["Merge conflict blocks this path"]
Conflict --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test: test_inventory_orphaned_workflows.py"]
S4 --> I4["regression suite"]
I4 --> Conflict["Merge conflict blocks this path"]
Conflict --> V4["targeted test run"]
Merge Conflict Guidance
gh pr checkout 1026 --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/orphaned-workflow-lifecycle-inventory
# rebase path only: git push --force-with-lease origin HEAD:feat/orphaned-workflow-lifecycle-inventory |
There was a problem hiding this comment.
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
DIRTYfor this pull request. - Root cause: Branch
feat/orphaned-workflow-lifecycle-inventorycannot be merged cleanly intomain; the changed-file flow below shows which review/runtime path is blocked by the conflict. - Fix: Merge or rebase the latest
mainintofeat/orphaned-workflow-lifecycle-inventory, resolve conflict markers in the PR branch, rerun the focused checks, and push the same branch. - Repair commands:
gh pr checkout 1026 --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/orphaned-workflow-lifecycle-inventory
# rebase path only: git push --force-with-lease origin HEAD:feat/orphaned-workflow-lifecycle-inventory- 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["Changed file (3 files)"]
S1 --> I1["repository behavior"]
I1 --> Conflict["Merge conflict blocks this path"]
Conflict --> V1["required checks"]
Evidence --> S2["Docs: orphaned-workflow-lifecycle.md"]
S2 --> I2["operator or user guidance"]
I2 --> Conflict["Merge conflict blocks this path"]
Conflict --> V2["docs review"]
Evidence --> S3["CI script (3 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> Conflict["Merge conflict blocks this path"]
Conflict --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test: test_inventory_orphaned_workflows.py"]
S4 --> I4["regression suite"]
I4 --> Conflict["Merge conflict blocks this path"]
Conflict --> V4["targeted test run"]
- Result: REQUEST_CHANGES
- Reason: mergeStateStatus is
DIRTY; mergeable isCONFLICTING. - Head SHA:
1be76989887ab772e3ce0d2e0c7f22d3ca98dd94 - Workflow run: 32777281829
- Workflow attempt: 1
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 --> Conflict["Merge conflict blocks this path"]
Conflict --> V1["required checks"]
Evidence --> S2["Docs: orphaned-workflow-lifecycle.md"]
S2 --> I2["operator or user guidance"]
I2 --> Conflict["Merge conflict blocks this path"]
Conflict --> V2["docs review"]
Evidence --> S3["CI script (3 files)"]
S3 --> I3["review and security gate shell path"]
I3 --> Conflict["Merge conflict blocks this path"]
Conflict --> V3["bash -n plus Strix self-test"]
Evidence --> S4["Test: test_inventory_orphaned_workflows.py"]
S4 --> I4["regression suite"]
I4 --> Conflict["Merge conflict blocks this path"]
Conflict --> V4["targeted test run"]
# Conflicts: # CHANGELOG.md # scripts/ci/organization_commercial_readiness_loop.py
|
Fresh current-main convergence pass: keep this lane non-merge-ready until the latest live-inventory review findings are repaired on the existing owner branch. Required fixes: (1) |
| visible_names = {item.get("full_name") for item in repositories} | ||
| if ( | ||
| len(visible_names) != len(repositories) | ||
| or len(repositories) != public_repos + private_repos | ||
| ): |
There was a problem hiding this comment.
🟡 Repository renames bypass completeness proof
collect_live_organization validates only unique-name counts after page-number pagination. A concurrent rename can omit one repository while preserving the accepted total.
Prompt for agents
The repository completeness check in collect_live_organization cannot establish a stable inventory from one page-number traversal plus a total count. A repository rename during sorted pagination can produce a same-sized unique list that omits another repository. Add a stability proof, such as repeating the complete paginated repository listing and requiring the canonical repository identity set to match before scanning, then revalidating it before emission. Retain the organization-wide total check and add a regression fixture that shifts an item across a page boundary without changing the total.
Was this helpful? React with 👍 or 👎 to provide feedback.
| created = client.request( | ||
| f"/repos/ContextualWisdomLab/{repository}/issues", | ||
| method="POST", | ||
| payload={ | ||
| "title": "Disable orphaned workflow registry identity", | ||
| "body": body, | ||
| }, |
There was a problem hiding this comment.
🟡 Repeated publication duplicates owner issues
publish_owner_issue always creates an issue without a static route. Reprocessing the same ledger creates another identical owner issue.
Prompt for agents
Make publish_owner_issue idempotent for repositories absent from KNOWN_OWNER_ISSUES. Before creating an issue, locate an existing lifecycle issue using a stable marker or durable ledger mapping and comment on or return that issue instead. Ensure repeated publication of the same ledger digest does not create duplicate issues, and add a regression test covering two calls for one unknown repository.
Was this helpful? React with 👍 or 👎 to provide feedback.
| try: | ||
| text = write_ledger(ledger, Path(args.output) if args.output else None) | ||
| except (FileNotFoundError, OSError) as exc: | ||
| print(f"ERROR: unable to write ledger: {exc}", file=sys.stderr) | ||
| return 2 |
| ledger_sha = record.get("default_branch_sha") | ||
| if not isinstance(repository, str) or not isinstance(workflow_id, int): | ||
| raise InventoryError("operator record identity is malformed") | ||
| assert_default_branch_bound(ledger_sha, confirmed_head_sha) |
There was a problem hiding this comment.
| if not isinstance(repository, str) or not isinstance(workflow_id, int): | ||
| raise InventoryError("operator record identity is malformed") |
There was a problem hiding this comment.
| if ( | ||
| record.get("classification") != "orphan_active" | ||
| or HEX_SHA256.fullmatch(ledger_sha256) is None | ||
| ): | ||
| raise InventoryError( | ||
| "issue publication requires an orphan_active and ledger digest" | ||
| ) |
There was a problem hiding this comment.
|
This is now a high-leverage #1531 queue-lifecycle owner, but the branch predates #1546 and currently mixes its inventory feature with scheduler coverage files that are canonically owned by #1567 ( |
…rchestrator#1026 Found #1026 already merged, delivering both the priority audit-staleness fix and the noted secondary color-coded-feedback improvement for model_groups' save/delete handlers. Diffed the still-open duplicate #1011 against #1026 before closing it: same fix, different implementation (CSS classes vs inline style), functionally identical outcome, now genuinely CONFLICTING against main. Closed #1011 with evidence per repair-not-close policy (full-delta successor case). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # scripts/ci/test_strix_quick_gate.sh
…entory) One conflicted file: scripts/ci/test_strix_quick_gate.sh, one conflict block. Block classification (line by line): - 'scopes workflow_run concurrency to the completed review PR' -> DROPPED. main removed the workflow_run trigger from pr-review-merge-scheduler.yml entirely (merge-base and branch both had it 14x; main has 0x) and inverted the contract to assert_file_not_contains 'workflow_run:' and assert_file_not_contains 'github.event.workflow_run'. Keeping the branch's assertion would have put two mutually contradictory assertions in one gate. - 'isolates ... hourly organization sweep' vs 'isolates repository-local recovery from PR runs' -> took main's wording; same assertion string, main's current message. - 'keeps manual queue scans isolated per repository dispatch target' -> KEPT. This one line is this PR's entire contribution to the file (branch diff vs merge-base: 1 file changed, 1 insertion). main has no equivalent assertion. Loss check: the resolved file differs from main's version by exactly that one line and nothing else (diff /tmp/theirs.sh -> 1568a1569, single '>' line). Evidence: - uvx ruff check --select F821 scripts/ci tests: All checks passed - full suite, branch head 2cbd370 (unmerged): 2825 passed, 0 failed - full suite, this merge: 2946 passed, 0 failed (failure-name diff empty on both sides with non-zero denominators) - PR's own oracle, tests/test_inventory_orphaned_workflows.py + tests/test_workflow_lifecycle_inventory_workflow.py: 47 passed - isolated run of the resolved gate function assert_pr_review_merge_scheduler_uses_github_actions_bot_token: 0 failures - negative control 1: deleting the repo-dispatch scoping line from the workflow makes the KEPT assertion fail (1 failure, named) -> it has real detection power, it is not decorative - negative control 2: re-adding the DROPPED workflow_run assertion makes it fail against current main (1 failure, named) -> dropping it was required, not a convenience - coverage report: TOTAL 100%; interrogate: PASSED (minimum 100.0%) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
main 병합 완료 — 충돌 1건 해결 (
|
| 줄 | 판정 | 근거 |
|---|---|---|
scopes workflow_run concurrency to the completed review PR |
폐기 | main이 pr-review-merge-scheduler.yml에서 workflow_run 트리거를 통째로 제거했습니다(merge-base·이 브랜치 14회 → main 0회). 그리고 계약을 assert_file_not_contains 'workflow_run:' / assert_file_not_contains 'github.event.workflow_run'로 뒤집었습니다. 이 단언을 남겼다면 한 게이트 안에 서로 모순되는 단언 두 개가 공존합니다. |
isolates the hourly organization sweep… → isolates repository-local recovery from PR runs |
main 문구 채택 | 단언 문자열은 동일, 메시지만 현행판 |
keeps manual queue scans isolated per repository dispatch target |
보존 | merge-base 대비 이 브랜치의 해당 파일 diff는 1 file changed, 1 insertion — 이 한 줄이 기여 전부입니다. main에는 대응 단언이 없습니다. |
손실 없음의 산술적 확인: 해결본을 main 판본과 직접 diff하면 1568a1569 한 줄뿐입니다. 즉 main의 현행 내용을 전부 취하고 이 PR의 기여 한 줄만 더한 상태입니다.
검증
uvx ruff check --select F821 scripts/ci tests— All checks passed- 전체 스위트, 병합 전 브랜치 헤드
2cbd3708: 2825 passed / 0 failed - 전체 스위트, 이 병합: 2946 passed / 0 failed (양쪽 실패 집합 공집합, 분모 2825·2946로 실재하는 측정)
- 이 PR 고유 오라클
tests/test_inventory_orphaned_workflows.py+tests/test_workflow_lifecycle_inventory_workflow.py: 47 passed - 해결한 게이트 함수
assert_pr_review_merge_scheduler_uses_github_actions_bot_token격리 실행: 0 failures - 네거티브 컨트롤 ① 워크플로에서
repo-dispatch스코프 줄을 지우면 → 보존한 단언이 이름을 찍고 실패(1건). 장식이 아니라 실제 탐지력이 있습니다. - 네거티브 컨트롤 ② 폐기한
workflow_run단언을 되살리면 → 현행 main에서 이름을 찍고 실패(1건). 폐기는 편의가 아니라 필수였습니다. coverage reportTOTAL 100%,interrogatePASSED (minimum 100.0%)
브랜치 히스토리는 fast-forward이며 force push는 없습니다.
🤖 Generated with Claude Code
Buyer-visible gap
GitHub persists Actions registry identities after the YAML leaves the protected default branch. Buyers and reviewers cannot treat "the file is gone" as "no writer remains enabled." That is a control-plane visibility gap (#945; ContextualWisdomLab/appguardrail#929; ContextualWisdomLab/clearfolio#423; ContextualWisdomLab/disksage#191).
What this PR adds
scripts/ci/inventory_orphaned_workflows.pypresent_active,present_disabled,orphan_active,orphan_disabled,dynamic_owned,unresolvedCOPILOT_GITHUB_TOKENThis is the executable contract increment. It does not disable workflows or claim a live org sweep is complete.
Verification
Local 2x
coverage run -m pytest tests && coverage report --fail-under=100andinterrogateboth passed at 100%.Merge
Arm squash auto-merge. Do not self-approve. Two-approval + last-pusher 405 is a ruleset, not a coding stop.
Summary by CodeRabbit
새 기능
문서
품질 개선