Platform quickstart (control plane + runners)
This is the operational “how to use it” guide for the headless PatentChecker platform: programs, watchlists, runners, drift, webhooks, triage, and retention.
Choose your path
This page is for operators turning PatentChecker into a continuous monitoring service. If you are still validating the product, do not start here.
- 1Start with the public runtime and demo artifacts if you are evaluating the workflow for the first time.
- 2Use self-hosting when you only need local watchlist runs and offline verification inside your own environment.
- 3Stay on this page when you need control plane, runners, scheduling, webhook handling, triage, and retention.
- 4Keep the verification guide nearby for artifact and release checks while you operationalize the platform.
Use the shortest public path before you commit to control plane and runner operations.
Jump straight into the operational markdown if you are already past evaluation and local runtime setup.
Use the standalone runtime or signed container path if you need local execution without the full control plane.
Switch here when you need artifact-level or release-level proof checks instead of deployment mechanics.
Use the demo hub when the question is modality-specific: viral vectors, LNP delivery, regular mRNA sequences, or offline proof bundles.
Mental model
- Control plane (SaaS): Programs, watchlists, runs, drift events, receipts, retention, webhooks.
- Runner (hosted or customer VPC): Executes the job, produces deterministic artifacts, uploads by digest, finalizes the run.
- Scheduler + outbox: Creates runs on schedule and delivers signed webhooks.
- Triage API: Humans review drift, assign, disposition, and download/export evidence.
Request flow (high level)
program (active corpus snapshot)
-> watchlist (schedule + query ref + retention policy)
-> run (immutable record, pinned corpus snapshot)
watchlist (schedule + query ref + retention policy)
-> run (immutable record)
-> job (leased to a runner)
-> runner executes + uploads artifacts (deduped by sha256)
-> run finalized (idempotent)
-> drift event created (new vs old run)
-> webhook delivered (signed, at-least-once)
-> human triage (assign + dispositions)
-> retention pins evidence until drift is closed, then purges with a receiptWhere the code lives (local dev)
~/patentchecker: the trust anchor (artifact contracts + verifier + drift diff engine)~/patentchecker-platform: the control plane + workers + reference runner~/patentchecker-adapters: search adapters (BLAST/DIAMOND/etc), depending on your deployment
~/patentchecker-platform.0) Run the stack locally
cd ~/patentchecker-platform
docker compose -f docker-compose.dev.yml up --build- control plane API (Fastify)
- Postgres
- MinIO (S3-compatible object storage)
- scheduler worker
- outbox worker (webhooks)
- retention worker
CONTROL_PLANE_API_KEY from the compose file (often devkey).1) Create a program (unit of value)
export BASE_URL="http://localhost:3000"
export TOKEN="devkey"
curl -sS -X POST "$BASE_URL/v1/programs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: prog-kras-001" \
-d '{"name":"KRAS-G12D Program","description":"Primary oncology program"}'program_id.2) Register + activate a corpus snapshot (what was checked)
run-now request).source_type=customer):curl -sS -X POST "$BASE_URL/v1/programs/<program_id>/corpus-snapshots" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: cs-kras-001" \
-d '{
"corpus_snapshot_digest":"sha256:<64>",
"source_type":"customer",
"manifest":{
"jurisdictions":["US"],
"sequence_types":["protein"],
"made_public_until":"2025-01-01"
}
}'curl -sS -X POST "$BASE_URL/v1/programs/<program_id>/corpus-snapshots/activate" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: cs-kras-activate-001" \
-d '{"corpus_snapshot_digest":"sha256:<64>","reason":"baseline"}'3) Create a watchlist (what to monitor)
- runner target (hosted vs VPC runner group)
- schedule (interval for now)
- retention policy (what evidence is kept / purged)
- query input reference (where your sequence payload lives)
curl -sS -X POST "$BASE_URL/v1/programs/<program_id>/watchlists" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: wl-kras-protein-001" \
-d '{
"name":"KRAS protein watch",
"enabled":true,
"runner_target":{"kind":"hosted"},
"schedule":{"kind":"interval","interval_seconds":86400},
"retention_policy":{"retention_enabled":true,"keep_last_n":10,"keep_days":90,"legal_hold":false},
"query_input_ref":{"kind":"customer_bucket_pointer","uri":"s3://customer-bucket/watchlists/kras.json"}
}'watchlist_id.4) Trigger a run (run-now) or wait for the scheduler
curl -sS -X POST "$BASE_URL/v1/watchlists/<watchlist_id>/runs" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: run-now-001" \
-d '{}'- a
runrow (system-of-record) - a
jobrow (leaseable unit for a runner)
Option A: Reference runner (dev)
cd ~/patentchecker-platform
npm ci
npm run run:reference-runner- pulls a job lease
- heartbeats until completion
- produces a deterministic run directory + bundle
- uploads artifacts by sha256 (dedupe-safe)
- finalizes the run (idempotent)
Option B: Hosted runner (prod)
Option C: Customer VPC runner (prod upsell)
6) Inspect runs and download evidence
curl -sS "$BASE_URL/v1/runs?watchlist_id=<watchlist_id>&limit=50" \
-H "Authorization: Bearer $TOKEN"curl -sS "$BASE_URL/v1/runs/<run_id>/bundle" \
-H "Authorization: Bearer $TOKEN"curl -sS "$BASE_URL/v1/runs/<run_id>/bundle/manifest" \
-H "Authorization: Bearer $TOKEN"curl -sS "$BASE_URL/v1/runs/<run_id>/view-index" \
-H "Authorization: Bearer $TOKEN"7) Drift is created automatically (what humans review)
curl -sS "$BASE_URL/v1/programs/<program_id>/drift-events?state=new&limit=50" \
-H "Authorization: Bearer $TOKEN"curl -sS "$BASE_URL/v1/drift-events/<drift_event_id>" \
-H "Authorization: Bearer $TOKEN"curl -sS "$BASE_URL/v1/drift-events/<drift_event_id>/bundle" \
-H "Authorization: Bearer $TOKEN"curl -sS "$BASE_URL/v1/drift-events/<drift_event_id>/explain" \
-H "Authorization: Bearer $TOKEN"8) Webhooks (how teams “feel” the system without UI)
curl -sS -X POST "$BASE_URL/v1/webhook-endpoints" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: wh-001" \
-d '{"url":"https://example.com/webhooks/patentchecker"}'event_id.9) Triage primitives (assignment + dispositions)
curl -sS -X POST "$BASE_URL/v1/drift-events/<drift_event_id>/assign" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: assign-001" \
-d '{"assigned_to_user_id":"user_demo"}'curl -sS -X POST "$BASE_URL/v1/drift-events/<drift_event_id>/dispositions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: disp-001" \
-d '{"label":"relevant","reason_code":"triage","comment":"Overlaps our KRAS program; counsel review"}'new: no dispositionsopen: latest disposition is non-terminal (e.g.needs_review,escalate)closed: latest disposition is terminal (e.g.relevant,not_relevant)
10) Retention (evidence purge with receipts)
- Evidence for runs referenced by any non-closed drift event is pinned (both new + old sides).
- When evidence is purged, the run/drift history remains, and the system writes a retention deletion receipt artifact.
- Evidence never “silently disappears”.
- HTTP
410 Gone - error code
EVIDENCE_PURGED details.retention_deletion_receipt_artifact_idpoints to the receipt artifact
curl -sS "$BASE_URL/v1/runs/<run_id>/retention-deletion-receipt/view" \
-H "Authorization: Bearer $TOKEN"11) Enzyme-platform workflow (mRNA / IVT disclosures)
- start from a
WO...publication or a signed sequence-listing evidence pack - normalize disclosed sequences against a pinned T7 RNAP reference
- attach section-level patent-text provenance for abstract, claims, and description
- rank candidate polymerase disclosures before full comparison review
/docs/patentchecker-enzyme-platform
What to do next as a user (dogfood)
- Stand up one real protein watchlist.
- Wire webhooks to Slack.
- Review drift weekly and disposition everything.
- Track: alerts/week, time-to-triage, false positives.