Patchr
Patchr - the Work Execution Protocol for developers building automated software delivery workflows.
Patchr is an SDK and hosted API for turning engineering intent into executed work with contracts, evidence trails, human-safe handoffs, and portable proof outputs.
Use it when your app needs to configure environments, validate release readiness, coordinate deployment handoffs, monitor workflow state, repair broken processes, or run external work through auditable JSON results and streaming status messages.
Patchr workers are deterministic, policy-gated engines — not free-running LLM agents. Every run produces the same auditable result for the same inputs, mutating actions always pause for human approval, and live execution is delegated to systems you connect (CI pipelines, webhooks, SaaS APIs). An optional LLM triage layer (Gemini or a custom endpoint) can refine intent classification, and can be disabled.
The same protocol primitives power all of those workflows:
Huntdiscovers dependencies, services, sources, risks, and candidate work.Resolvevalidates requirements, contradictions, evidence, and next actions.Bridgeconnects repositories, CI/CD, cloud resources, SaaS tools, APIs, MCP, and A2A.Proxypauses automation for human judgment, protected operations, and proof capture.Paysettles outcome-based work with mandates, receipts, and proof-of-value.
Engineering intent routes to dedicated developer domains:
environmentmaps runtimes, dependencies, backing services, and required secrets from repository files.cicdevaluates release gates and produces deployment plans with rollback steps.kubernetestriages cluster snapshots and proposes approval-gated remediations.incidentcorrelates alerts into a triaged incident with safe next actions.migrationclassifies schema changes and gates risky database rollouts.securityscans provided files for exposed secrets and insecure configuration.deliverychains configure, validate, and deploy with human approval gates.
Status: shipped vs planned
| Capability | Status |
|---|---|
| Orchestrator, streaming, resume, proof packs | Shipped |
| Developer-intent routing (LLM planner, active by default; deterministic fallback) | Shipped — natural-language requests route to the owning developer domain; the planner refines ambiguous routes and is fail-closed. Kill switch: PICUX_LLM_PLANNER_ENABLED=false |
| Developer domains (environment, cicd, kubernetes, incident, migration, security, delivery) | Shipped — deterministic advisory plans; live execution via connectors after approval, or autonomously under a mandate (see below) |
| Autonomous execution | Shipped, opt-in — runAutonomous(payload) auto-approves the gates a mandate grants and runs setup commands through a guarded executor. Off by default; ungranted gates still pause for a human |
| Human-in-the-loop (approval gates, proxy missions, durable resume) | Shipped |
| Connector catalog | 25 connectors — 22 live (Gmail, Slack, Jira, Salesforce, Twilio, GitHub, GitLab, AWS/GCP/Azure CI, shipmentTracking, ...), 3 simulation-only (blockchainExplorer, chainAnalytics, bankRecall) |
| Per-connector network egress policies | Shipped — allowOutbound + allow/deny host lists, enforced at the action boundary and the wire; cloud-metadata denied by default |
| Physical logistics | Shipped — shipmentTracking connector (23-carrier catalog, auto-detect) + HMAC-verified carrier webhook ingestion with durable storage |
| MCP server (JSON-RPC 2.0, 219 tools; typed input schemas on the highest-traffic tools) | Shipped |
Change verification (verifyChange — one pass/review/block verdict over a change, per-gate checks, proof pack, optional GitHub commit status) |
Shipped — status posting is contract-mode by default, live with GITHUB_TOKEN + explicit opt-in |
Coding-agent surface (exportAgentBrief briefs as AGENTS.md/CLAUDE.md/Cursor rules; autonomy code mode drives a coding agent under a mandate) |
Shipped — see docs/developers/coding-agents.md |
Run history + console (orchestrator runs persisted with route, planner decision, and full trace; live console at /console) |
Shipped — listOrchestratorRuns / getOrchestratorRun / observabilityMetrics; counters wire up via PICUX_REDIS_URL |
Runtime governance (Decionis SDK_EXECUTION_GATE evaluated before every autonomous run) |
Shipped — shadow by default, PICUX_AUTONOMY_GOVERNANCE=enforce stops non-allow runs; CI infra-destroy gate enforces |
| A2A envelopes | Shipped (picux-a2a protocol; not interoperable with Google A2A) |
| SDKs | Python + Node (full surface), Go + Java + .NET (core + developer domains + activation); filesFromLocalRepo in all five |
| Pay: mandates, escrow state machine, receipts | Shipped (local ledger; HMAC-signed receipts when PICUX_RECEIPT_SIGNING_SECRET is set) |
Pay rail: stripeSpt |
Live test-mode — with STRIPE_SECRET_KEY + {"live": true} (or PICUX_STRIPE_LIVE=true), creates/captures real manual-capture PaymentIntents; otherwise contract-mode |
Pay rail: solanaPay |
Live signing — pure-Python Ed25519 signer for the picux_escrow Anchor program; opt-in via PICUX_SOLANA_SIGNER_SECRET + live flag |
Pay rail: baseUsdc |
Live signing — pure-Python secp256k1/keccak/EIP-155 signer + ERC-20 / PicuxEscrow.sol calls; opt-in via PICUX_BASE_SIGNER_SECRET + live flag |
Pay rails: x402, mpp, l402 |
Contract only (transaction intents; no live processor calls yet) |
Install
pip install patchr # Python SDK
npm install @patchr-core/sdk # Node.js SDK
npm install -g @patchr/cli # terminal (natural-language CLI over the Node SDK)
export PATCHR_API_BASE_URL="https://api.patchr.co"
export PATCHR_API_TOKEN="your_patchr_api_token"
# or interactively: patchr login
Prefer the terminal? patchr takes plain language and reuses the SDK 1:1 —
confident intents route straight to the mapped call (interpretation shown),
work requests fall back to the orchestrator, --explain previews the routing:
patchr "configure a python dev environment with postgres"
# ➜ interpreted as env-setup 100% (environment, configure, "dev environment")
patchr "deploy web to staging as canary"
patchr run "validate this repo for production readiness" --stream
See packages/cli for the full command set.
Developer Activation
New developers can create a profile directly from the SDK and start testing immediately. Patchr returns a starter API token, sends an activation link to the email address, and keeps unactivated starter tokens limited to 5 workflow requests.
createProfile(email, name, password)returns a starter token.activateToken(activationToken)activates the token after the email link is opened or the activation token is supplied in local/debug mode.runOrchestrator(payload)runs the workflow with the activated token.
from patchr.sdk import PatchrClient
patchr = PatchrClient()
profile = patchr.createProfile(
email="dev@example.com",
name="Dev Example",
password="use-a-real-password",
)
token = profile["token"]
print(profile["activation"]["message"])
# In production, click the emailed activation link. Local/debug responses may
# include activationToken for automated tests.
activation_token = profile.get("activation", {}).get("activationToken")
if activation_token:
patchr.activateToken(activation_token)
patchr = PatchrClient(token=token)
run = patchr.runOrchestrator({
"clientId": "activation_smoke_test",
"channel": "sdk",
"request": "Validate this repository for production readiness",
})
Quick Start
from patchr.sdk import PatchrClient
patchr = PatchrClient.fromEnv()
run = patchr.runOrchestrator({
"clientId": "release_readiness_demo",
"channel": "sdk",
"conversationId": "conv_release_001",
"request": "Validate this repository for production readiness and identify deployment blockers.",
"metadata": {
"repo": "https://github.com/acme/api",
"environment": "production"
},
})
print(run["status"])
print(run["route"])
Fast Sandbox Smoke Test
Before wiring code, open the hosted sandbox and click the Hunt example:
The starter request is:
Buy me iPhone7 less than 500 dollar
The sandbox explicitly sends allowNetwork: false unless you override it, so the starter run is deterministic. Outside the sandbox, omitting allowNetwork defaults to live Hunt discovery. If marketplace pages are slow, blocked, or return no eligible listing, Hunt completes the mission with status: "ready" and source-attempt evidence in results.hunt.sourceResponse / results.hunt.sourceAggregate. NEEDS_INPUT is reserved for result selection when Hunt has source-backed options, or for later workflow details such as checkout inputs. For deterministic SDK smoke tests, pass a known source URL explicitly:
run = patchr.runOrchestrator({
"clientId": "sandbox_smoke_test",
"channel": "sdk",
"conversationId": "conv_iphone7_smoke_001",
"request": "Buy me iPhone7 less than 500 dollar",
"urls": [
"data:text/html,<html><title>Used iPhone7 listing</title><body>Used iPhone7 listing available in stock. List 600 dollar, sale 189.99 dollar with receipt and fast shipping.</body></html>"
],
"targetLimit": 1,
"allowNetwork": False
})
print(run["status"]) # NEEDS_INPUT when the supplied result is ready to choose
Remove urls and omit allowNetwork when you want Patchr to search live marketplaces outside the sandbox.
Typical response shape:
{
"ok": true,
"status": "ready",
"route": ["resolve", "bridge"],
"results": {
"resolve": {
"claimDraft": {
"summary": "Damaged goods claim with attachment evidence"
}
},
"bridge": {
"contactPlan": {
"primary": { "type": "merchantSupport" }
}
}
}
}
Streaming Status
Use streaming when the workflow may take more than a few seconds. Patchr sends human-readable progress events during quiet periods and handoff events when work moves into a human-facing step.
for event in patchr.streamOrchestrator({
"clientId": "incident_repair_demo",
"channel": "sdk",
"conversationId": "conv_incident_repair_001",
"request": "Investigate why the production deployment failed and prepare the next safe action.",
"stream": True,
}):
if event.get("type") in {"progress", "handoff"}:
print(event["message"])
if event.get("type") == "final":
print(event["result"]["status"])
Example stream events:
{"type":"progress","status":"running","elapsedSec":10.0,"message":"I am still checking source-bound deployment evidence and connector state."}
{"type":"handoff","phase":"proxy","name":"mission.approval","status":"waiting","message":"Waiting for the release owner to approve the rollback plan."}
Common Scenarios
Engineering requests route to the owning developer domain. When required inputs are missing, the run returns NEEDS_INPUT with requestedKeys; re-run with those payload keys included.
Release readiness (routes to cicd):
patchr.runOrchestrator({
"clientId": "release_readiness_demo",
"channel": "sdk",
"conversationId": "conv_release_001",
"request": "Validate this repository for production readiness and identify deployment blockers.",
"service": "web",
"environment": "prod",
"version": "v2.0.0",
"strategy": "rolling",
"artifacts": {"build": "pass", "tests": "pass"},
})
Environment configuration (routes to environment; collect real repo context with filesFromLocalRepo):
from patchr.sdk import filesFromLocalRepo
patchr.runOrchestrator({
"clientId": "environment_setup_demo",
"channel": "sdk",
"conversationId": "conv_env_setup_001",
"request": "Find missing dependencies, required services, and setup blockers for this cloned repository.",
"files": filesFromLocalRepo("~/code/my-service"),
})
filesFromLocalRepo collects known manifests, lockfiles, Dockerfiles, compose files, and .env.example templates. It never collects secret-bearing files (.env, keys, credentials).
Incident repair (routes to incident; mutating responses stay approval-gated):
patchr.runOrchestrator({
"clientId": "incident_repair_demo",
"channel": "sdk",
"conversationId": "conv_incident_001",
"request": "Investigate why the production deployment failed and prepare the next safe action.",
"alerts": [{"source": "prometheus", "name": "HighErrorRate", "severity": "critical", "service": "web"}],
"signals": {"recentDeploys": [{"service": "web", "version": "v2.0.0"}]},
})
Delivery pipeline with a human approval gate (routes to delivery; resume with resumeDelivery(runId, approved=True)):
run = patchr.runOrchestrator({
"clientId": "delivery_demo",
"channel": "sdk",
"request": "Run the software delivery pipeline from clone to production",
"service": "web",
"environment": "prod",
"version": "v1.2.0",
"strategy": "rolling",
"artifacts": {"build": "pass", "tests": "pass"},
"files": filesFromLocalRepo("~/code/my-service"),
})
if run["status"] == "awaitingApproval":
patchr.resumeDelivery(run["results"]["delivery"]["runId"], approved=True)
Autonomous Execution
By default the developer engines are human-gated: a production deploy pauses at
awaitingApproval. runOrchestrator never acts on a protected operation without
a person. To let a run act on its own, pass an explicit autonomy mandate —
autonomy is off unless autonomy.enabled is true, and the deployment kill switch
PICUX_AUTONOMY_ENABLED=false overrides any request.
from patchr.sdk import filesFromLocalRepo
result = patchr.runAutonomous({
"mode": "delivery", # or "environment" (inferred when omitted)
"service": "web",
"environment": "prod",
"version": "v2.0.0",
"strategy": "rolling",
"artifacts": {"build": "pass", "tests": "pass"},
"files": filesFromLocalRepo("~/code/my-service"),
"autonomy": {
"enabled": True,
"allowedActions": ["delivery.deploy", "delivery.rollback"],
"allowCommands": ["npm ci", "npm run build", "docker compose up"],
"maxActions": 6, # action budget for the whole run
"dryRun": False, # False = really execute setup commands
"workdir": "/path/to/checkout",
"requireApproval": [], # actions that STILL need a human
},
})
print(result["status"]) # "delivered" — no human needed
print(result["autonomy"]["autonomousToCompletion"]) # True
print(result["autonomy"]["actions"]) # audit trail of every auto-decision
Guardrails: autonomy runs only under the mandate. Actions must be allow-listed
(and not in requireApproval); shell commands must match allowCommands and
clear a built-in denylist (rm -rf, sudo, git push, curl|sh, ...); the run
is bounded by maxActions. Anything outside the grant — or an exhausted budget —
leaves the run awaitingApproval for a human (fail-closed). Real command
execution requires dryRun: false and a workdir; the default dry run only
reports what it would run. Every decision is returned in autonomy.actions and
emitted as an autonomy.run event. See docs/developers/autonomy-guide.md.
Code mode extends the same mandate to coding agents: runAutonomous({"task": "fix the failing suite", ...}) drives a headless agent (default claude -p {task}) through the guarded executor under a code.fix grant, with an optional
verifyCommand after a successful fix — see docs/developers/coding-agents.md.
Developer Domains
Engineering requests route to the owning developer domain (via the always-on
planner). When a required input is missing the run returns NEEDS_INPUT with
requestedKeys; re-run with those keys. Each domain is reachable by natural
language through runOrchestrator, or directly:
patchr.configureEnvironment({"files": filesFromLocalRepo(".")}) # environment
patchr.planDeployment({"service": "web", "environment": "prod", # cicd
"version": "v2", "strategy": "rolling", "artifacts": {"build": "pass", "tests": "pass"}})
patchr.repairKubernetes({"pods": [...], "events": [...]}) # kubernetes
patchr.respondToIncident({"alerts": [...], "signals": {...}}) # incident
patchr.validateMigration({"migrations": [...], "backup": {...}}) # migration
patchr.validateSecurity({"files": filesFromLocalRepo(".")}) # security
patchr.runDelivery({"service": "web", "environment": "staging", ...}) # delivery pipeline
External workflow examples:
patchr.runOrchestrator({
"clientId": "support_ops_demo",
"channel": "sdk",
"conversationId": "conv_ticket_dispute_001",
"request": "Dispute ticket ZD-44291: airline charged me twice after cancellation and closed the refund case."
})
Useful Methods
# Activation & discovery
patchr.health()
patchr.createProfile(email, name, password)
patchr.activateToken(activation_token)
patchr.manifest()
patchr.protocolMap()
# Orchestration
patchr.runOrchestrator(payload)
patchr.streamOrchestrator(payload)
patchr.resumeOrchestrator(conversation_id, item_id, action, payload)
patchr.runAutonomous(payload) # autonomous execution under a mandate
# Developer domains (also reachable via natural language through runOrchestrator)
patchr.configureEnvironment(payload)
patchr.planDeployment(payload)
patchr.repairKubernetes(payload)
patchr.respondToIncident(payload)
patchr.validateMigration(payload)
patchr.validateSecurity(payload)
patchr.runDelivery(payload)
patchr.resumeDelivery(run_id, approved=True)
# Coding-agent surface
patchr.verifyChange(payload) # one verdict over a change: pass | review | block
patchr.exportAgentBrief(payload) # AGENTS.md / CLAUDE.md / Cursor rules from repo files
# Run history & observability
patchr.listOrchestratorRuns(filters) # summaries: route, status, planner decision
patchr.getOrchestratorRun(run_id) # one run with its full trace
patchr.observabilityMetrics() # domain counters (needs a Redis sink)
# Repository context
filesFromLocalRepo(path) # from patchr.sdk
# Logistics
patchr.trackShipment(tracking_number, carrier="")
patchr.ingestCarrierWebhook(payload, headers)
patchr.getShipmentStatus(tracking_number)
# Tools
patchr.mapTool(payload)
patchr.nlpTool(payload)
Runtime Notes
- Engineering requests route to the owning developer domain (environment, cicd, kubernetes, incident, migration, security, delivery) via the always-on planner; consumer/commerce requests still route through HUNT, RESOLVE, BRIDGE, PROXY, and PAY.
- Developer engines are deterministic and human-gated by default.
runAutonomousopts a run into autonomous execution under an explicit mandate; without it, protected operations always pause for approval. - Long-running workflows emit user-facing progress text so your client does not appear stuck.
- Handoff events include plain messages such as "Waiting for release owner approval", "Preparing case documents", and "Contacting the provider for availability".
- Set
PATCHR_API_TOKENfor hosted API calls. Local test transports can run in-process without network I/O.
Changelog
0.2.0 adds developer-intent routing with an always-on planner, opt-in autonomous execution (runAutonomous), filesFromLocalRepo in all five SDKs, live payment signing for Stripe test-mode / Solana / Base (opt-in), the shipmentTracking connector with carrier-webhook ingestion, per-connector network egress policies, and security hardening (PBKDF2 vault, signed receipts).
0.1.4 adds SDK developer activation: createProfile, emailed activation links, activateToken, and a 5-request limit for unactivated starter tokens.
0.1.3 adds a fast sandbox smoke test for Hunt, the Buy me iPhone7 less than 500 dollar starter example, and first-class vendorDueDiligence workflow support.
See CHANGELOG.md in the package source for full release notes.
More
- Hosted API reference: https://patchr.co/api-reference
- Control plane: https://patchr.co/control-plane
- Developer sandbox: https://patchr.co/sandbox
- Python package: https://pypi.org/project/patchr/
- Node package: https://www.npmjs.com/package/@patchr-core/sdk
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file patchr-0.1.5.tar.gz.
File metadata
- Download URL: patchr-0.1.5.tar.gz
- Upload date:
- Size: 596.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d1851dfa28e2f202a394a80e40eff5bde4e2ec76734d823d898e0d7d42b2e1a
|
|
| MD5 |
0ea8abffcf02613132da786a74f73a7e
|
|
| BLAKE2b-256 |
456c97f7a35896b5d713b73b39f637033084643d8e4840ba2a47f439ca1eb5ae
|
File details
Details for the file patchr-0.1.5-py3-none-any.whl.
File metadata
- Download URL: patchr-0.1.5-py3-none-any.whl
- Upload date:
- Size: 497.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be2b0d706b7893df8c092002192efeb22a76359f6d565c00fde023cf6082d209
|
|
| MD5 |
d92f5c072319bafacb0ce25a3e2a5552
|
|
| BLAKE2b-256 |
d49f52871ab71d33cf7190bbb48ff63cae12e2a7976fb3f222606d9e836d2d32
|