Repository navigation
feat(OMN-14893): route OCC machine path through onexbot-occ-writer App auth - #1869
Conversation
…p auth Adds an opt-in GitHub App installation-token auth mode for the two OCC companion producers (OccCompanionEmitter, HandlerOccCompanionEffect), replacing the shared operator PAT with a short-lived, machine-attributable credential minted via the SAME idiom already proven in CI (actions/create-github-app-token, pr-arch-review.yml / call-occ-attestation-observe.yml). - New omnimarket.github_app_auth module: JWT sign (RS256) + installation resolve + token exchange, mirroring actions/create-github-app-token. - OMNI_OCC_GITHUB_AUTH_MODE env var selects pat (default, unchanged) or app. app mode resolves ONEXBOT_OCC_APP_ID / ONEXBOT_OCC_PRIVATE_KEY (contract-declared, required only in this mode) and NEVER reads GITHUB_TOKEN at all -- the fallback that reproduced this defect is mechanically absent from that code path, not just avoided by an if. - assert_is_app_installation_token guards every mint: a resolved credential that is not ghs_-prefixed (i.e. any human-PAT shape) raises immediately -- the invisible-misconfiguration gap this ticket exists to close. - OccCompanionEmitter now applies the occ:machine-minted provenance label on both create and sync (it never did -- the root cause of the OCC#4661 gap; HandlerOccCompanionEffect already applied it). - Extended ONEXBOT_OCC_APP_ID / ONEXBOT_OCC_PRIVATE_KEY org-secret visibility to include omnimarket (was onex_change_control-only, which would have fail-closed call-occ-attestation-observe.yml the moment its dry_run kill switch clears). BLOCKED: full app-mode cutover needs ONEXBOT_OCC_APP_ID / ONEXBOT_OCC_PRIVATE_KEY provisioned into the .201 runtime secret store -- not yet available to this session. pat mode remains the default and is byte-for-byte unchanged. Closes OMN-14893 dod_evidence: unit tests (103 passed: test_github_app_auth.py 16, test_occ_companion_emitter.py + friction suite, node_occ_companion_effect suite incl. new auth-mode tests), ruff format+check clean, mypy --strict clean on all 3 changed source files, full pre-commit clean (incl. topic-naming-lint with OMNIBASE_INFRA_PATH set).
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 11 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (9)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…imarket#1869 (#4665) * evidence(OMN-14893): author OCC companion for OmniNode-ai/omnimarket#1869 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 695708884f19a33e60b179fe9c8f47d18172d2d5. * evidence(OMN-14893): self-bind OCC#4665 + rebind contract_sha256 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai>
|
| Rule | Description |
|---|---|
| ARCH-TOPIC-001 | No hardcoded Kafka topic strings in handler code |
| ARCH-DI-001 | No event_bus=None bypass |
| ARCH-DI-002 | No direct Handler instantiation outside workflow_runner/adapters |
| ARCH-DI-003 | No reinvented DI containers |
| ARCH-TOPIC-002 | contract.yaml topics follow `onex.{cmd |
ARCH-DI-002: Direct Handler instantiation (warning)\n\n\nsrc/omnimarket/nodes/node_occ_companion_effect/handlers/handler_occ_companion_effect.py:155: self._state_handler = state_handler or HandlerOccStateEffect()\n\n\nHandler classes should be wired only in workflow_runner.py or adapter modules. Direct instantiation elsewhere bypasses the contract system.\n\n
Static architectural lint — no model inference (OMN-14176).
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics (pilot phase)
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
Summary
OMN-14893: get the canonical OCC companion producers (
OccCompanionEmitter,HandlerOccCompanionEffect) genuine, scoped write access toonex_change_controlinstead of the shared operator PAT (GITHUB_TOKEN) currently doing every machine-minted commit/PR/PATCH under a human's identity.omnimarket.github_app_authmodule: JWT sign (RS256) + installation resolve + token exchange, mirroring the SAME idiom already proven in CI (actions/create-github-app-token@v1, as used bypr-arch-review.yml/call-occ-attestation-observe.yml) -- no new pattern invented.OMNI_OCC_GITHUB_AUTH_MODEenv var (both producers) selectspat(default, byte-for-byte unchanged) orapp. Inappmode,resolve_app_installation_token_from_contractresolvesONEXBOT_OCC_APP_ID/ONEXBOT_OCC_PRIVATE_KEY(contract-declared,required: falseat the contract level sincepatmode doesn't need them, but the app-mode code path itself has no PAT-reading branch at all -- fallback is mechanically absent, not just avoided by anif). A declared-but-unresolvable credential raises immediately, naming the exact missing secret ref.assert_is_app_installation_tokenidentity guard (feat: 6 critical Kafka→DB projection nodes [OMN-7610] #4): every minted/resolved token in app mode must carry theghs_prefix GitHub always mints installation tokens with; any other shape (ghp_/gho_/github_pat_/anything else) raisesGitHubAppIdentityErrorimmediately. This is the mechanical check for "the OCC companion path cannot authenticate as a human PAT" -- a misconfiguration here was previously invisible (companion still mints, just mis-attributed).OccCompanionEmitternow applies theocc:machine-mintedlabel on both PR create and PR sync. It never did -- this is the actual root cause of the OCC#4661 gap (HandlerOccCompanionEffect, the other live producer, already applied it). Best-effort, matches the existing contract (label failure never aborts the mint).ONEXBOT_OCC_APP_ID/ONEXBOT_OCC_PRIVATE_KEYorg-secret visibility to includeomnimarket(wasonex_change_control-only -- verified viagh api orgs/OmniNode-ai/actions/secrets/<name>/repositories).call-occ-attestation-observe.ymlreferences these secrets today; without this the workflow would fail-closed the instant itsdry_runkill switch (OMN-14955) clears, since GitHub Actions secrets are invisible to a workflow run in a repo not on the visibility list.Blocked
Full cutover to
appmode is blocked on provisioningONEXBOT_OCC_APP_ID/ONEXBOT_OCC_PRIVATE_KEYinto the.201runtime secret store (~/.omnibase/.envor the Infisical prefetch path) -- not available to this session (live-verified:.201~/.omnibase/.envcarriesGITHUB_TOKENx1, zeroONEXBOT*names).patmode remains the default; nothing in this PR changes runtime behavior until the credential is provisioned and the mode is flipped.Also out of scope (per the OMN-14893 investigation and OMN-14955's own scope): broadening
onexbot-occ-writer's installation to cover the product repos for theEvidence-SourcePATCH leg. Today the App is write-scoped toonex_change_controlonly;appmode as implemented here covers the OCC-repo clone/push/PR-open/label calls, not the product-PR PATCH (which still needsGITHUB_TOKEN-equivalent scope on the product repo). Flagged for a follow-up, not silently degraded.Test plan
uv run pytest tests/unit/test_github_app_auth.py tests/unit/nodes/node_pr_lifecycle_fix_effect/test_occ_companion_emitter.py tests/unit/nodes/node_pr_lifecycle_fix_effect/test_occ_companion_emitter_friction_omn_14741.py tests/unit/nodes/node_occ_companion_effect/ -q-- 103 passeduv run ruff format+uv run ruff checkclean on all changed filesuv run mypy --strictclean on all 3 changed source filespre-commit runclean on the diff (incl.topic-naming-lintwithOMNIBASE_INFRA_PATHset,OCC emitter golden gate,GitHub-token env-read gate,Validate no silent env fallbacks,One OCC producer per contract)gh apiCloses OMN-14893
dod_evidence: see Test plan above; commit message carries the same evidence block.
Evidence-Ticket: OMN-14893
Evidence-Source: OCC#4670
Evidence-Commit: 8e799e865a29df08ca2b11c50dfe7fc8df6ab351