Skip to main content

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:

  • Hunt discovers dependencies, services, sources, risks, and candidate work.
  • Resolve validates requirements, contradictions, evidence, and next actions.
  • Bridge connects repositories, CI/CD, cloud resources, SaaS tools, APIs, MCP, and A2A.
  • Proxy pauses automation for human judgment, protected operations, and proof capture.
  • Pay settles outcome-based work with mandates, receipts, and proof-of-value.

Engineering intent routes to dedicated developer domains:

  • environment maps runtimes, dependencies, backing services, and required secrets from repository files.
  • cicd evaluates release gates and produces deployment plans with rollback steps.
  • kubernetes triages cluster snapshots and proposes approval-gated remediations.
  • incident correlates alerts into a triaged incident with safe next actions.
  • migration classifies schema changes and gates risky database rollouts.
  • security scans provided files for exposed secrets and insecure configuration.
  • delivery chains 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.

  1. createProfile(email, name, password) returns a starter token.
  2. activateToken(activationToken) activates the token after the email link is opened or the activation token is supplied in local/debug mode.
  3. 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:

https://patchr.co/sandbox

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. runAutonomous opts 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_TOKEN for 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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

patchr-0.1.5.tar.gz (596.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

patchr-0.1.5-py3-none-any.whl (497.7 kB view details)

Uploaded Python 3

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

Hashes for patchr-0.1.5.tar.gz
Algorithm Hash digest
SHA256 7d1851dfa28e2f202a394a80e40eff5bde4e2ec76734d823d898e0d7d42b2e1a
MD5 0ea8abffcf02613132da786a74f73a7e
BLAKE2b-256 456c97f7a35896b5d713b73b39f637033084643d8e4840ba2a47f439ca1eb5ae

See more details on using hashes here.

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

Hashes for patchr-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 be2b0d706b7893df8c092002192efeb22a76359f6d565c00fde023cf6082d209
MD5 d92f5c072319bafacb0ce25a3e2a5552
BLAKE2b-256 d49f52871ab71d33cf7190bbb48ff63cae12e2a7976fb3f222606d9e836d2d32

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 files

0.1.4

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page