Skip to content

feat(OMN-14893): route OCC machine path through onexbot-occ-writer App auth - #1869

Merged
jonahgabriel merged 1 commit into
devfrom
jonah/omn-14893-occ-app-auth-wiring
Jul 24, 2026
Merged

jonahgabriel merged 1 commit into
devfrom
jonah/omn-14893-occ-app-auth-wiring

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

OMN-14893: get the canonical OCC companion producers (OccCompanionEmitter, HandlerOccCompanionEffect) genuine, scoped write access to onex_change_control instead of the shared operator PAT (GITHUB_TOKEN) currently doing every machine-minted commit/PR/PATCH under a human's identity.

  • New omnimarket.github_app_auth module: JWT sign (RS256) + installation resolve + token exchange, mirroring the SAME idiom already proven in CI (actions/create-github-app-token@v1, as used by pr-arch-review.yml / call-occ-attestation-observe.yml) -- no new pattern invented.
  • OMNI_OCC_GITHUB_AUTH_MODE env var (both producers) selects pat (default, byte-for-byte unchanged) or app. In app mode, resolve_app_installation_token_from_contract resolves ONEXBOT_OCC_APP_ID / ONEXBOT_OCC_PRIVATE_KEY (contract-declared, required: false at the contract level since pat mode 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 an if). A declared-but-unresolvable credential raises immediately, naming the exact missing secret ref.
  • assert_is_app_installation_token identity guard (feat: 6 critical Kafka→DB projection nodes [OMN-7610] #4): every minted/resolved token in app mode must carry the ghs_ prefix GitHub always mints installation tokens with; any other shape (ghp_/gho_/github_pat_/anything else) raises GitHubAppIdentityError immediately. 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).
  • Provenance marker fix (feat: 6 standalone projection nodes for critical data paths #3): OccCompanionEmitter now applies the occ:machine-minted label 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).
  • Live infra fix: extended ONEXBOT_OCC_APP_ID / ONEXBOT_OCC_PRIVATE_KEY org-secret visibility to include omnimarket (was onex_change_control-only -- verified via gh api orgs/OmniNode-ai/actions/secrets/<name>/repositories). call-occ-attestation-observe.yml references these secrets today; without this the workflow would fail-closed the instant its dry_run kill 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 app mode is blocked on provisioning ONEXBOT_OCC_APP_ID / ONEXBOT_OCC_PRIVATE_KEY into the .201 runtime secret store (~/.omnibase/.env or the Infisical prefetch path) -- not available to this session (live-verified: .201 ~/.omnibase/.env carries GITHUB_TOKEN x1, zero ONEXBOT* names). pat mode 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 the Evidence-Source PATCH leg. Today the App is write-scoped to onex_change_control only; app mode as implemented here covers the OCC-repo clone/push/PR-open/label calls, not the product-PR PATCH (which still needs GITHUB_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 passed
  • uv run ruff format + uv run ruff check clean on all changed files
  • uv run mypy --strict clean on all 3 changed source files
  • Full pre-commit run clean on the diff (incl. topic-naming-lint with OMNIBASE_INFRA_PATH set, OCC emitter golden gate, GitHub-token env-read gate, Validate no silent env fallbacks, One OCC producer per contract)
  • Live-verified org-secret visibility extension via gh api

Closes 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

…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).
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 11 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d84a9523-dd85-43b2-b665-6f18ea688bd4

📥 Commits

Reviewing files that changed from the base of the PR and between a2c9e3c and 6957088.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • pyproject.toml
  • src/omnimarket/github_app_auth.py
  • src/omnimarket/nodes/node_occ_companion_effect/contract.yaml
  • src/omnimarket/nodes/node_occ_companion_effect/handlers/handler_occ_companion_effect.py
  • src/omnimarket/nodes/node_pr_lifecycle_fix_effect/contract.yaml
  • src/omnimarket/nodes/node_pr_lifecycle_fix_effect/handlers/occ_companion_emitter.py
  • tests/unit/nodes/node_occ_companion_effect/test_handler_occ_companion_effect_github_auth_mode.py
  • tests/unit/nodes/node_pr_lifecycle_fix_effect/test_occ_companion_emitter.py
  • tests/unit/test_github_app_auth.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonah/omn-14893-occ-app-auth-wiring

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

jonahgabriel added a commit to OmniNode-ai/onex_change_control that referenced this pull request Jul 24, 2026
…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>
@github-actions

Copy link
Copy Markdown

⚠️ Architectural Review — WARNINGS

Errors: 0
Warnings: 1

What this checks

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).

@github-actions

github-actions Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

✅ Hostile Reviewer — PASSED

Blocking findings (critical/error): 0
Total findings: 0
Models succeeded: qwen3-review,qwen3-review-b


Gate semantics (pilot phase)

Verdict Meaning Blocks merge?
passed No critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded All models unavailable (infra) No (pilot)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)

@jonahgabriel
jonahgabriel merged commit 463d147 into dev Jul 24, 2026
225 of 239 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-14893-occ-app-auth-wiring branch July 24, 2026 02:23
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