Open-source Patch Reports for AI-generated code changes.
PatchPlane gives developers evidence before they trust an AI patch. It turns each AI-generated change into an inspectable trust report before the patch continues toward merge.
For every patch, PatchPlane should make it obvious:
- what changed,
- what ran,
- where it ran,
- what passed or failed,
- what evidence exists,
- who approved or rejected it.
PatchPlane treats every AI-generated patch as untrusted until it has been executed, evidenced, reviewed, and explicitly approved. It keeps normal GitHub and CI/CD workflows while adding a trust boundary before generated code reaches secrets, shared caches, trusted automation, or merge paths.
Core docs:
- SPEC.md: product thesis, architecture, and MVP success criteria
- ROADMAP.md: active and completed delivery work
- packages/cli/README.md: CLI onboarding, env templates, and diagnostics
- packages/plugins/README.md: infrastructure plugin and sandbox-backed Pi runtime architecture
- CONTRIBUTING.md: development and contribution guide
- docs/philosophy.md: product and developer-experience decision principles
- docs/critical-path.md: product path from intake through evidence, decision, publication, and release proof
- docs/telemetry-data-policy.md: Sentry allowlist, prohibited content, and sanitization requirements
- docs/m10-acceptance-runbook.md: repeatable human-gated trust-loop acceptance
- AGENTS.md: repository map, trust boundaries, and automation protocol
- REVIEW.md: risk-based review checklist for Patchplane changes
- SECURITY.md: security reporting and secret-handling policy
PatchPlane's OSS onboarding path is the CLI. It creates root patchplane.config.json, appends missing required keys to .env.local, and creates generated local state directories under .patchplane/{logs,cache,state}.
bun install
bun run patchplane init
bun run patchplane doctorFor scriptable or CI-safe setup, pass explicit flags instead of relying on prompts:
bun run patchplane init --profile app --yes
bun run patchplane init --profile githubWebhook --yes
bun run patchplane init --profile full --yesThen run the app and Convex backend in separate terminals:
bun run dev:backend
bun run dev:clientSecrets belong in .env.local or deployment secret stores, not in patchplane.config.json or plugin metadata.
Use the CLI instead of copying a large env file by hand:
bun run patchplane env template --surface app
bun run patchplane env template --surface githubWebhook
bun run patchplane env check --surface app
bun run patchplane env check --surface githubWebhookMinimal app profile:
VITE_CONVEX_URL=
WORKOS_CLIENT_ID=
WORKOS_API_KEY=
WORKOS_REDIRECT_URI=http://localhost:3000/api/auth/callback
WORKOS_COOKIE_PASSWORD=Minimal GitHub webhook profile:
VITE_CONVEX_URL=
PATCHPLANE_SYSTEM_INGESTION_SECRET=
GITHUB_APP_ID=
GITHUB_PRIVATE_KEY=
GITHUB_WEBHOOK_SECRET=
PATCHPLANE_GITHUB_ALLOWED_REPOSITORIES=owner/repo
PATCHPLANE_GITHUB_WORKSPACE_ID=
DAYTONA_API_KEY=Optional provider keys, such as OPENAI_API_KEY, are only needed for Pi modes.
The current alpha is being narrowed around one developer-first loop:
request → immutable attempt → agent execution → frozen candidate → independent verification → policy → human decision → canonical GitHub Patch Report
The current foundation includes two workflow-start paths:
WorkOS AuthKit session
→ TanStack Start server function
→ WorkOSAuthPlugin permission check
→ StorageService.createWorkflowFromPrompt
→ Convex workflowStarts:create with WorkOS JWT
→ promptRequests + workflowRuns
GitHub webhook
→ GitHubWebhookService signature verification
→ GitHub-specific normalization
→ generic WorkflowIntake + ExternalWorkflowRef
→ repository allowlist + repository access verification
→ StorageService.createWorkflowFromIntake
→ Convex workflowStarts:createFromExternalIntake
→ promptRequests + workflowRuns + externalWorkflowRefs
The authenticated dashboard lists connected GitHub repositories and their latest workspace-scoped trust status, with a direct link to the durable workflow investigation view.
Each V1 run is an immutable attempt. A rerun creates a child attempt pinned to the same source revision; it does not overwrite the parent. Evidence applies only to the candidate produced by that attempt, identified by its producing sandbox execution and sha256: candidate digest. Agent exit 0, diff capture, external review, independent verification, policy, human decision, and publication are separate states. Missing, blocked, stale, truncated, or candidate-mismatched required evidence cannot produce a trusted result. A human may still approve incomplete verification only with an explicit recorded override reason; the Patch Report continues to show the gap.
The canonical Patch Report V1 is assembled from durable Convex records and R2 artifact metadata for the exact attempt/candidate. GitHub issue comments and commit-bound check runs use stable canonical identities and update on replay; immutable attempts, publication rows, and provenance remain in PatchPlane.
GitHub, WorkOS, Convex, and Daytona SDK usage is server/plugin-side only. For the alpha daytona-pi path, Pi runs inside the Daytona sandbox rather than being bundled into the web/control-plane runtime. Core workflows depend on PatchPlane-owned Effect services and domain schemas.
The Pi runtime adapter is Effect-native at the PatchPlane boundary: packages/plugins/src/sandbox-runtime/pi/contract.ts defines the Effect RPC command contract, runtime-session.ts exposes a session facade, transport.ts translates typed commands to Pi JSONL, and jsonl.ts/ingestion.ts decode Daytona stdout streams into normalized runtime events. Raw Pi JSONL is retained as R2 evidence; transient token/tool deltas are omitted from normalized workflow truth, and client projections bound event counts and payload previews.
This repository is a Bun monorepo:
apps/client: TanStack Start app, WorkOS/AuthKit UI integration, Convex client integration, app routes, and app Effect runtime compositionapps/source-control: Cloudflare Worker for source-control provider webhooks, GitHub installation sync, Daytona/Pi orchestration, and repository publicationpackages/backend: Convex-backed control-plane backend and deployment functionspackages/domain: shared Effect schemas and PatchPlane-owned domain typespackages/core: Effect service contracts and workflow logic; no provider SDK importspackages/plugins: infrastructure plugins for WorkOS, Convex, GitHub, Daytona, experimental Pi runtime adapters, and plugin metadatapackages/cli: Effect-powered CLI for OSS onboarding, project config generation, plugin discovery, env templates/checks, and diagnostics
The hosted alpha GitHub webhook route is served by the dedicated source-control Worker:
POST /api/github/webhook
Required server environment for workflow creation from GitHub webhooks:
GITHUB_APP_ID
GITHUB_PRIVATE_KEY
GITHUB_WEBHOOK_SECRET
CONVEX_URL or VITE_CONVEX_URL
PATCHPLANE_SYSTEM_INGESTION_SECRET
PATCHPLANE_GITHUB_ALLOWED_REPOSITORIES=owner/repo,another/repo
PATCHPLANE_GITHUB_WORKSPACE_ID or PATCHPLANE_WORKOS_ORGANIZATION_ID
DAYTONA_API_KEY
The route verifies GitHub signatures against the raw request body, maps supported events into generic WorkflowIntake, verifies repository access through the GitHub App installation, pins the intake SHA, and persists generic external refs in Convex. Pi exiting successfully means only that sandbox agent execution completed. Verification requirements are persisted from trusted configuration before execution. Independent test evidence requires an explicit PATCHPLANE_EVIDENCE_TEST_REPORT_COMMAND; without one, PatchPlane reports verification as not configured/incomplete and never as clean or passed. Set PATCHPLANE_EVIDENCE_TEST_PLATFORM to linux, macos, or windows to declare the required platform. Non-Linux requirements remain explicit blocked evidence until a matching safe provider is configured.
To run the live Daytona/Pi RPC smoke locally, load .env.local and pass a public repository. The smoke starts Pi in a Daytona RPC session, validates get_state, prompt, steer, follow_up, abort, runtime events, session termination, and final Daytona sandbox deletion.
set -a
source .env.local
set +a
PATCHPLANE_SMOKE_REPOSITORY_URL=https://github.com/octocat/Hello-World \
PATCHPLANE_SMOKE_REPOSITORY_FULL_NAME=octocat/Hello-World \
PATCHPLANE_PI_PROVIDER=openai \
PATCHPLANE_PI_MODEL=gpt-4o-mini \
PATCHPLANE_SMOKE_TIMEOUT_SECONDS=180 \
bun run --cwd packages/plugins smoke:daytona-rpcExpected final summary fields include:
{
"getStateResponse": true,
"promptResponse": true,
"steerResponse": true,
"followUpResponse": true,
"abortResponse": true,
"terminated": true,
"sandboxDeleted": true
}Use tee if you want a raw smoke transcript:
bun run --cwd packages/plugins smoke:daytona-rpc | tee .patchplane/logs/daytona-rpc-smoke.jsonlUseful checks before committing:
bun run verify:fast
bun run verifyverify is the complete non-credentialed repository gate and runs on every
pull request. Credentialed smoke checks remain opt-in; see
docs/acceptance-tests.md for their scope.
A post-build client bundle guard should not find server-only secrets or SDKs:
rg "WORKOS_API_KEY|PATCHPLANE_SYSTEM_INGESTION_SECRET|GITHUB_PRIVATE_KEY|GITHUB_WEBHOOK_SECRET|octokit|workos-node|api.workos.com" apps/client/dist/clientEffect is used for the control-plane core:
packages/domainuseseffect/Schemafor shared modelspackages/coredefines Effect service contracts and workflowspackages/pluginsprovides Effect layers for real infrastructureapps/clientcomposes the app runtime; hosted source-control webhook/control-plane execution runs inapps/source-controlpackages/cliuseseffect/unstable/cli, EffectTerminalprompts,@effect/platform-node, and aManagedRuntimefor CLI services