Skip to content

feat(api): wire Probot I2 enforcement into epicon-api (C-368 PR5 deploy)#17

Merged
kaizencycle merged 2 commits into
mainfrom
cursor/guard-app-epicon-api-wire-0e02
Jul 10, 2026
Merged

feat(api): wire Probot I2 enforcement into epicon-api (C-368 PR5 deploy)#17
kaizencycle merged 2 commits into
mainfrom
cursor/guard-app-epicon-api-wire-0e02

Conversation

@kaizencycle

@kaizencycle kaizencycle commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Mobius PR — Cycle

  • Cycle: C-368
  • Type: Feature
  • Primary Area(s): apps / infra
  • Pulse Attached:

1. Summary

Completes PR5 deployment wiring: epicon-api now starts Probot I2 enforcement when APP_ID and PRIVATE_KEY are set on Render. Without those credentials it falls back to transport-only mode (current production behavior). Render blueprint builds from repo root so workspace packages (guard-app, guard-core) resolve.


2. Details

  • Motivation: PR feat(core): Guard App Phase 1 scaffold with shared guard-core (C-368 PR5) #14 merged scaffold but live epicon-api only verified webhooks — no Check Runs or I2 enforcement.
  • Solution:
    • server.mjs branches on APP_ID + PRIVATE_KEYcreateGuardApp() with /api/github/webhook
    • Manifest /health reports enforcement_mode: probot-i2 | transport-only
    • render.yaml rootDir ., env vars for App credentials
  • Breaking Changes: no — transport-only remains default without credentials

3. EPICON Intent

epicon_id: EPICON_C-368_CORE_guard-app-phase1_v2
ledger_id: kaizencycle
scope: core
mode: normal
issued_at: 2026-07-10T00:00:00Z
expires_at: 2026-10-08T00:00:00Z
justification:
  VALUES INVOKED: integrity, transparency, accountability, safety
  REASONING: PR5 scaffold merged but epicon-api ran transport-only. This wires Probot I2 enforcement when APP_ID and PRIVATE_KEY are set, falling back to signature-verify-only mode otherwise.
  ANCHORS:
    - Mobius-Substrate/docs/epicon/EPICON-02.md (IPDP v1.0.0, I2 immutability)
    - epicon/apps/guard-app/README.md (Phase 1 deploy target)
    - epicon/packages/guard-core/src/immutability.mjs (I2 enforcement logic)
  BOUNDARIES: Deploy wiring only. No ledger attestation, dashboard, or CII changes. GitHub Action remains the primary gate; App augments.
  COUNTERFACTUAL: If Probot credentials are absent, the service remains transport-only without breaking webhook signature verification.
counterfactuals:
  - If Probot webhook latency exceeds 30s on cold starts, move to a paid Render instance
  - If workspace root build fails on Render, verify npm workspaces install in render.yaml
  - If App permissions are rejected by org policy, run report-only until resolved

4. Operator next step

On Render epicon-api service, set:

  • APP_ID — GitHub App ID
  • PRIVATE_KEY — PEM private key
  • GITHUB_WEBHOOK_SECRET — webhook secret (already required)
  • WEBHOOK_PATH=/api/github/webhook

Redeploy → /health should show "enforcement_mode":"probot-i2".

Manual acceptance: edit a test PR intent without version bump → Check Run fails with I2 VIOLATION.

Open in Web Open in Cursor 

When APP_ID and PRIVATE_KEY are configured, epicon-api starts the Guard App
(Probot) with manifest/health routes on the same port. Falls back to
transport-only mode when credentials are absent. Render blueprint now builds
from repo root so workspace packages resolve.

Co-authored-by: michaeljjudan <michaeljjudan@gmail.com>
@kaizencycle
kaizencycle marked this pull request as ready for review July 10, 2026 22:04
@cursor

cursor Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@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: 0559c76dcf

ℹ️ 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 thread packages/github-app/src/server.mjs Outdated
if (probotConfigured) {
const { createGuardApp } = await import('../../../apps/guard-app/src/index.js');
const probot = createGuardApp({ webhookPath: WEBHOOK_PATH });
const app = probot.server;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Start Probot with a real Server before adding routes

In the configured Render path (APP_ID + PRIVATE_KEY set), createGuardApp() returns a Probot instance, but Probot 13.4.7 (the version pinned in package-lock.json) does not expose a server property on that class; the Express app is created through the Server API or createNodeMiddleware. That leaves app undefined here, so the next app.get(...) throws before the service can listen, making the new probot-i2 mode fail to boot as soon as the credentials are configured.

Useful? React with 👍 / 👎.

Probot 13.4.x does not expose probot.server on the Probot class.
Wire epicon-api through Server + guardAppFn load pattern so probot-i2
mode boots when APP_ID and PRIVATE_KEY are configured.

Co-authored-by: michaeljjudan <michaeljjudan@gmail.com>
@kaizencycle
kaizencycle merged commit 5ba73e6 into main Jul 10, 2026
1 check passed
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.

2 participants