Skip to content

fix(service): accept standalone Windows wrappers in ownership probe (carry #6238) - #6258

Merged
lidge-jun merged 8 commits into
devfrom
codex/rt6-l4-windows-wrapper-carry
Sep 29, 2026
Merged

lidge-jun merged 8 commits into
devfrom
codex/rt6-l4-windows-wrapper-carry

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

Carries #6238 by @lcBreathe onto current dev so it can land in 2.73.0. Fixes #6237: the Windows standalone 2.71.0 service wrapper ("%OCX_BUN%" start) was rejected by the ownership probe, so ocx sync refused an OpenCodex-owned service.

The original change accepts the standalone launch form. Three rounds of independent security review then hardened the new acceptance path so that only a wrapper matching the standalone generator can claim ownership:

  • the wrapper must contain the generator's quoted OCX_BUN assignment and markers, no OCX_CLI in any quoting form, and the generator's control-flow lines in order (inserted goto, exit, call or labels are rejected);
  • the wrapper's executable must match the path recorded in the scheduler install state;
  • the registered task must have exactly one Exec action, running the generator's wscript.exe command with the exact launcher arguments.

Source-install wrappers keep their existing behavior. Documented residual (structure/ops/service-and-sidecars.md): install state records a path rather than a file identity, so a junction retargeted by someone with write access to the install location cannot be told apart.

The contributor's commits are preserved unchanged; the maintainer commits sit on top.

Co-authored-by: lcBreathe 165003424+lcBreathe@users.noreply.github.com

Verification

  • bun test tests/codex-integration/codex-service-manager-probe.test.ts tests/codex-integration/codex-service-manager-probe-hardening.test.ts tests/service/standalone-service.test.ts: 108 pass, 0 fail.
  • bun x tsc --noEmit, bun run structure:check, bun run privacy:scan: pass.
  • The same commits on fix(service): accept standalone Windows wrappers in ownership probe #6238 (head 0401a98) passed exact-head Cross-platform CI (31 success, 6 skipped).
  • Independent security review of the final head: no findings. Full bun run test is left to this PR's CI because several release lanes share one machine.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • Bug Fixes
    • Improved Windows service ownership checks to verify generated wrappers and scheduled-task actions before recognizing a service as managed.
    • When install-state evidence is missing, inconsistent, or does not match, the probe reports ownership as unknown and does not authorize unattended native changes.
    • Windows service inspection can now use explicitly provided state-evidence paths.

@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 29, 2026 19:31
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T19:34:30.797004Z 3488c24 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Sep 29, 2026
@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 0a05f969-8ff8-4f1f-baaf-d27eea158b8a

📥 Commits

Reviewing files that changed from the base of the PR and between 48470c3 and 3488c24.

📒 Files selected for processing (5)
  • src/service-manager-probe.ts
  • src/service/windows-taskxml.ts
  • structure/ops/service-and-sidecars.md
  • tests/codex-integration/codex-service-manager-probe-hardening.test.ts
  • tests/codex-integration/codex-service-manager-probe.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The Windows ownership probe now validates generated source and standalone wrappers, registered Task Scheduler actions, and scheduler state evidence. The tests cover accepted and rejected wrapper and task forms. The documentation describes these checks and notes that executable identity is established only by lexical path.

Changes

Windows service ownership

Layer / File(s) Summary
Registered Task Scheduler action validation
src/service/windows-taskxml.ts, src/service-manager-probe.ts
The task XML validator requires exactly one unprefixed Actions element with one matching Exec action and no extra action content or Data elements. The probe returns unknown when the registered action does not match the generated launcher.
Generated wrapper and standalone state validation
src/service-manager-probe.ts
The probe checks wrapper assignments and launch structure against generated source or standalone forms. Standalone wrappers also require an absolute .exe matching valid version-2 scheduler state evidence with cliPath: null. ProbeDeps accepts explicit statePaths; otherwise the probe derives paths from the effective configuration directory.
Integration coverage and documented checks
tests/codex-integration/codex-service-manager-probe*.test.ts, structure/ops/service-and-sidecars.md
Tests cover production-generated wrappers, task actions, state evidence, and malformed or foreign variants. Documentation describes the ownership requirements and states that lexical path evidence does not prove install-time file identity.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related PRs

  • lidge-jun/opencodex#1154: Introduced the Windows ownership probe that traverses Task Scheduler and WinSW definitions and validates generated wrappers.

Merge Risk: ⚪ Minimal · up to 3488c

The change makes the Windows ownership probe stricter and accepts the standalone wrapper form. No unresolved merge-blocking issue was found in the supplied evidence.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 3488c

The new checks reject malformed wrappers, mismatched task actions, and contradictory install state. A remaining limitation is that the recorded executable path does not prove which file occupies that path. Its security impact depends on who can modify the installation location.

Retained concerns

  • Medium · security · inferred: New standalone ownership eligibility relies on a recorded executable path, not the identity of the installed file. If a separate actor can replace that file or retarget its junction without controlling the other ownership evidence, the probe can still report ownership and admit native writes. Whether that actor has a meaningful distinct privilege is unproven.
Security review details

Security Blast Radius

  • inferred — The affected authorization outcome is unattended writing to native Codex catalog and configuration files on Windows installations; the supplied evidence does not establish cross-user or elevated execution from this change.

Security Findings and Attack Paths

  • inferred — Replacing the executable behind a still-matching recorded path is a conditional false-provenance path for newly accepted standalone ownership. The available evidence does not establish the required attacker write access or a privilege gain beyond executable replacement itself.

Trust Boundaries and Controls

  • observed — A wrapper-only or registered-task-action-only change cannot satisfy the full standalone gate: generated wrapper structure, matching scheduler state, and the registered action are checked, while malformed or contradictory evidence returns unknown.

Resilience and Maintainability Implications

  • observed — Automatic catalog-drift healing checks for owned service homes and checks again immediately before client writes, limiting reliance on an earlier ownership verdict.

Hardening Proposals

  • proposed — Confirm installation-directory and state-file permissions for supported Windows deployments before treating lexical executable-path agreement as provenance across distinct local users; if that boundary is required, bind acceptance to a protected file identity or equivalent install-time evidence.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 4 files. (1 skipped: … 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 The title clearly and concisely describes the main change: accepting standalone Windows wrappers in the service ownership probe.
Linked Issues check ✅ Passed The PR addresses the coding requirements in [#6237]. src/service/windows-taskxml.ts preserves the two production wrapper forms: standalone "%OCX_BUN%" start --port ... and source `"%OCX_BUN%" "%OC…
Out of Scope Changes check ✅ Passed The changes stay within the linked issue scope. The ProbeDeps.statePaths seam supports deterministic service-state validation. windowsTaskActionMatches supports the required rejection of inconsist…
Full details: Docstring Coverage

Explanation

Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 4 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3488c24389

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +993 to +995
|| valid.length === 0 || evidence.some(e => e.kind === "invalid" || e.kind === "unreadable")
|| valid.some(e => e.state.version !== 2 || e.state.backend !== "scheduler" || e.state.cliPath !== null
|| !e.state.bunPath || normalizeWindowsPath(e.state.bunPath) !== normalizeWindowsPath(executable))) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Select authoritative state before matching the executable

When a custom OPENCODEX_HOME has a lower-revision compatibility mirror whose refresh previously failed, src/service-manager-probe.ts checks every valid record and rejects the standalone wrapper if that stale mirror retains the prior bunPath, cliPath, or backend. This is a supported state: swapServiceInstallState commits the final authority first and explicitly allows mirror publication to fail, while selectAuthoritativeServiceState treats lower-revision disagreement as repairable. The resulting unknown ownership blocks unattended operations even though the authoritative record and generated wrapper agree; select the authoritative state first and bind the executable to that record, while preserving failure for same/newer unordered conflicts.

Useful? React with 👍 / 👎.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 74 / 80

Windows 단독 설치(standalone) 서비스 래퍼가 소유권 검사에서 거절되던 버그를 고치는 PR이에요. 예전 검사는 "%OCX_BUN%" "%OCX_CLI%" start 형태만 생성된 래퍼로 봤어요. 2.71.0 단독 설치는 "%OCX_BUN%" start라서 ocx sync가 우리 서비스를 남의 것으로 봤어요. 이 PR은 그 단독 실행 줄을 받아요. 대신 새 길을 그냥 열지 않아요. 생성기가 만든 따옴표 부여, 마커, 제어 흐름 순서, 설치 상태의 exe 경로, 등록된 작업의 Exec 한 줄까지 맞아야 소유로 봐요. 소스 설치 래퍼는 예전보다 조금 더 빡세졌고, 기본 동작은 그대로예요. base는 dev예요. #6237을 고치고, #6238을 현재 dev 위로 옮긴 자리예요.

라인 - #6238 은 아직 열린 draft예요. 이 PR이 그 내용을 보안 보강까지 얹어서 옮긴 본선이에요. 같이 두면 같은 수정이 두 갈래로 남아요.
src/service-manager-probe.ts wrapperLaunchShape - 소스 갈래는 실행 줄·OCX_CLI·OCX_BUN 정도만 봐요. 단독 갈래만 생성기 제어 흐름과 설치 상태 묶기를 해요. 의도로 적혀 있어요. 다만 소스 쪽이 더 헐겁다는 점은 남아 있어요.
structure/ops/service-and-sidecars.md - 설치 상태는 경로만 기억해요. 같은 경로를 가리키는 정션이 바뀌면 이 검사로는 구분 못 해요. 문서에 이미 적혀 있어요. 코드 구멍이라기보다 남는 한계예요.

메인테이너의 판단이 필요한 지점

#6238 draft를 이 PR 기준으로 닫을지 정해 주세요. 소스 래퍼에도 단독과 같은 제어 흐름·상태 묶기를 앞으로 올릴지는 제품 판단이에요. 지금 문서의 정션 한계를 이 릴리스에서 더 막을지, 그대로 둘지도 정해 주세요. 생성기 제어 흐름을 지금 HEAD 기준으로 딱 맞춰서, 예전에 깔린 2.71.0 래퍼가 생성기 이후 문구와 조금만 달라도 계속 unknown이 됩니다. 그 경우 service repair로 래퍼를 다시 쓰는 전제가 맞는지 확인해 주세요.

너의 추천

이 PR을 본선으로 두고 #6238은 닫으세요. 단독 쪽 엄격한 검사는 풀지 마세요. 정션 한계는 문서대로 남겨도 됩니다. CI 핵심 검사가 초록이면 합쳐도 됩니다. 미리보기 배포 이야기는 이 PR과 무관하니 건너뛰세요.

이 댓글은 grok-bot이 작성했습니다

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants