# The job build loop
Source: https://docs.minicor.com/agents/job-build-loop
The canonical way an agent works on a job: samples define done, then build until they pass.
This is the loop every agent should run when building or fixing a job. It is the same loop the platform's own builder follows. There are two ways to get the steps written: hand the work to the builder with `teach_job`, or author the step graph yourself with `register_job` and `update_job`. Either way, this loop is how the work is verified.
## The loop
Before touching the job, make sure it has samples that encode what correct means. Use `teach_job` with a real input and a plain-language intent, or `add_test_case` with an input and checks. Group related samples into scenarios. A job with no samples has no definition of correct, and nothing you build against it can be verified.
Create or update the job's step graph with `register_job` or `update_job` with `variant: "draft"`. Steps call whole automations or run code blocks. Data flows through `ctx`: each step can save its output under a key, and later steps reference it.
`run_tests` with `variant: "draft"` runs every sample. Green means go live. Red means step 4. Never declare a job working without a green run of its samples.
`resolve_job_state` tells you where the job stands and what to do next. `get_test_report` shows which scenarios failed, and `inspect_job_execution` drills a failing sample down to the failing step and its run underneath.
If the problem is in the job's wiring (step order, data passing, checks), update the draft and re-run just the failing slice: `run_job` from a step, seeded with the failed execution so earlier steps' values resolve without re-running them. If the problem is inside an automation step, fix the step's code, then return to step 3. Fixes are proven by samples, not by eyeballing a single run.
When the draft's samples are green, `publish_job` takes it live. Traffic at the trigger URL switches immediately.
## Rules that keep the loop honest
* **Samples define done.** If the user describes new behavior, teach it as a sample before building it.
* **Never edit live directly.** All work happens on the draft; live changes only through going live.
* **Pass `variant: "draft"` explicitly.** `update_job`, `run_job`, and `run_tests` default to the live variant. Teach and build work always targets the draft.
* **Reproduce with the seed.** When re-running a failing slice, seed from the failed execution so you are debugging the real state, not a fresh one.
* **Stops are cooperative.** There is no pause. Stopping a run lets the current operation finish; plan around that for long automations.
* **When lost, ask the platform.** `resolve_job_state` returns the concrete next calls for exactly this loop.
> The mistake agents make is skipping step 1: building first and never defining done. Run the steps in order; every later step leans on the samples to say what correct is.
# The Minicor MCP
Source: https://docs.minicor.com/agents/mcp
Connect any coding agent to Minicor. Everything the dashboard does, your agent can do through MCP.
Minicor exposes a Model Context Protocol server. Point Cursor, Claude Code, or any MCP-capable agent at it and the agent can teach jobs, run samples, inspect failures, drive desktops, and take jobs live, the same surface the dashboard and the co-pilot use.
## Hosted server (recommended)
The easiest way to connect: no install, no local process. The server runs at
```text theme={null}
https://mcp.minicor.com/mcp
```
Add a URL entry to `~/.cursor/mcp.json`; Cursor prompts for the sign-in on first use:
```json theme={null}
{
"mcpServers": {
"minicor": {
"url": "https://mcp.minicor.com/mcp"
}
}
}
```
```bash theme={null}
claude mcp add --transport http minicor https://mcp.minicor.com/mcp
```
Then run `/mcp` inside Claude Code to trigger the sign-in.
Go to **Settings > Connectors > Add custom connector**, paste `https://mcp.minicor.com/mcp`, and save. OAuth is auto-discovered; no client ID or secret.
Authentication is an OAuth flow: your client opens the Minicor sign-in page, you enter your email, password, and region (US or Canada), and the connection acts as your account. No API keys, no local tokens. Access tokens expire within an hour and refresh automatically for up to 30 days; after that you sign in again.
The hosted tool set matches the local server except for the tools that read and write your local disk (workspace clones, sessions, sync). If you need those, install locally.
## Local install
Add the server to `~/.cursor/mcp.json`:
```json theme={null}
{
"mcpServers": {
"minicor": {
"command": "npx",
"args": ["-y", "@minicor/mcp-server"]
}
}
}
```
```bash theme={null}
claude mcp add minicor -- npx -y @minicor/mcp-server
```
Then authenticate:
```bash theme={null}
npx -y -p @minicor/mcp-server minicor-mcp-setup
```
This opens a browser to sign in with your Minicor account. Tokens are stored at `~/.minicor/tokens.json` and refresh automatically. On a headless machine or over SSH, add `--cli` to sign in from the terminal.
## What the surface covers
| Area | What an agent can do |
| -------------- | ---------------------------------------------------------------------------------------------- |
| Jobs | Teach with samples, group scenarios, run samples, read run reports, inspect failures, go live. |
| Automations | Create and edit the steps underneath a job, run them against a desktop. |
| Executions | List runs, read step outputs, fetch replays and screenshots, diagnose failures. |
| Desktops | Connect, screenshot, inspect UI elements, execute scripts, control runs. |
| Configurations | Create and update key-value configurations, including two-factor channels and secrets. |
| Workspace | Issues for shared context, skills for reusable automation patterns, agents on watch. |
## Where to go next
* [The job build loop](/agents/job-build-loop) is the canonical way an agent should work on a job. Read it first. The zero-to-live path is short: connect, pick a workspace, make sure a desktop is attached, teach samples, run them until green, go live.
* [Sessions](/agents/sessions) covers long-running work and handoffs between agents.
* [Tools](/agents/tools) is the one-page overview of the tool families.
> These docs are written to be read by agents as much as by people. If you are an agent connected to the MCP: samples define done. Start every job task by making sure the job has samples that encode what correct means.
# Sessions
Source: https://docs.minicor.com/agents/sessions
Long-running work and handoffs: how agents keep state across machines, restarts, and each other.
Building an automation often outlasts one context window, one machine, or one agent. Sessions make the work resumable.
## Working in a cloned workspace
An agent can clone a workspace to a local folder: the jobs, the automations, the accumulated skills, and the open issues, in files it can read and diff. The clone includes a generated `AGENTS.md` with the workspace's rules and the phase loop for the work.
Inside a clone, the contract is:
1. **Call `session_start` first.** It returns the workspace rules, the current state of the work, and whatever a previous session left behind, so the agent resumes rather than restarts.
2. **Checkpoint as you go.** `session_checkpoint` persists progress at meaningful points.
3. **Call `session_end` before finishing.** It writes the final state so the next agent, on any machine, picks up where this one stopped.
If an agent disconnects mid-session, the platform checkpoints automatically with an interrupted status. Nothing is lost to a crash or a closed IDE.
## Handoffs
Session state syncs to the workspace itself, not just the local folder. That is what makes multi-agent work practical: an agent on another machine, a scheduled run overnight, or a person in the dashboard all see the same record of what was done, what broke, and what was decided.
Two conventions carry the context:
* **Issues** hold durable notes: quirks of the target system, decisions made, problems encountered. Read them before starting; write them when you learn something the next agent needs.
* **Skills** hold reusable automation patterns learned from previous builds, per workspace. Load the relevant ones before writing automation code, and save new ones when you solve something general.
> Treat `session_start` and `session_end` as non-negotiable bookends. The cost is two calls; the payoff is that no agent ever starts from zero on work another agent already did.
# Tools
Source: https://docs.minicor.com/agents/tools
The MCP tool families in one page.
The Minicor MCP groups its tools by what they operate on. This page is the map; each tool's own description carries its full schema.
## Jobs
The endpoint, its samples, and its lifecycle.
* `teach_job`, `add_test_case`, `update_test_case`: teach with real inputs, manage samples and their checks, group scenarios.
* `register_job`, `update_job`, `get_job`, `delete_job`: the job's step graph, edited with `variant: "draft"`.
* `run_job`, `run_tests`, `get_test_report`: run the job or all of its samples, read the results per scenario.
* `list_job_executions`, `get_job_execution`, `inspect_job_execution`: run history and failure drill-down.
* `resolve_job_state`: where the job stands and the concrete next calls.
* `publish_job`, `get_build_status`, `answer_build_question`, `cancel_build`: go live, follow the builder, answer its questions.
## Automations and executions
The steps underneath a job and their runs.
* Create, read, and edit the automation steps; run an automation whole or from a specific step.
* List executions, read each step's input and output, and diagnose failures with automation-aware analysis.
* Fetch replays: full recordings, single frames, zoomed regions, and clips around the moment of failure.
* Analyze a replay with computer vision: `analyze_recording` maps a run into UI events with timestamps, change regions, click positions, and a step-to-video timeline. Clicks and keystrokes come from the desktop's recorded input telemetry when it is present, and are inferred from the video otherwise. `annotate_recording` renders any moment with the analysis drawn on the frame: event boxes, click markers, the cursor trail.
An agent debugging a failure does not have to watch the video: it asks for the analysis, jumps to the event that matters, and reads the annotated frame.
## Desktops
* `vm_connect`, `vm_status`, `vm_screenshot`, `vm_screenshot_region`: attach to a desktop and see it.
* `vm_execute_script`, `vm_inspect_ui`, `vm_read_clipboard`, `vm_execution_control`: act on it, inspect the UI element tree, control a running script.
* Deployment helpers install and start the Minicor Desktop Service on a new machine.
## Configurations and two-factor
* Configurations: create them, read and update the properties resolved into runs.
* Two-factor: provision virtual phone numbers and email addresses, register TOTP secrets (including from a QR code), generate current codes, and resolve challenges mid-run.
## Workspace
* Workspaces: list, inspect, create.
* Issues: durable context shared between agents and people.
* Skills: reusable automation patterns, loaded before building and saved after learning something general.
* Agents: create and manage on-demand, scheduled, or monitoring agents.
* Sessions and sync: clone a workspace locally, `session_start` / `session_checkpoint` / `session_end`, push and pull changes. See [Sessions](/agents/sessions).
> When in doubt, start with `resolve_job_state` for job work and `get_workspace_context` for everything else. Both return the situation and the next calls, which beats guessing from tool names.
# Authentication
Source: https://docs.minicor.com/api/authentication
One API key in the x-api-key header, for live calls, teaching, and the reserved paths.
All requests to a trigger URL authenticate with an API key in the `x-api-key` header:
```bash theme={null}
curl -X POST "https:///create-invoice" \
-H "x-api-key: $MINICOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "customerName": "Bobs Tires" }'
```
The same key covers live calls, teaching calls, and the reserved introspection paths (`/_jobs`, `/_executions/:id`, `/_builds/:id`). The OpenAPI document at `/swagger.json` is the one path that does not require it.
## Getting the key
The key lives with the trigger URL. Open a job and click **Call this job**: the dialog shows the trigger URL and the API key together, ready to copy. Every job behind the same trigger host shares the key.
Keys you create under **Settings** are workspace API keys for the Minicor platform itself (the dashboard, the MCP, and platform APIs). They are not the trigger key.
## Handling the key
* Pass the key from a secret store or environment variable at request time. Never commit one.
* If the key is exposed, contact the Minicor team to replace it.
A missing or invalid key returns `401` with no further detail.
# Calling jobs
Source: https://docs.minicor.com/api/calling-jobs
The full HTTP contract for a job's trigger URL.
Every live job is an HTTP endpoint at its trigger URL, shown on the job page. All requests carry your API key in the `x-api-key` header.
## Request
```bash theme={null}
curl -X POST "https:///create-invoice" \
-H "x-api-key: $MINICOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "customerName": "Bobs Tires", "amount": 1250.00 }'
```
Jobs can be registered on any HTTP method. The job's input is the merge of query parameters and the JSON body; if a key appears in both, the body wins. Request metadata (method, path, path parameters, headers) is available to the job under `_http`, so a job can read a path parameter or a header when it was taught to.
## Synchronous response
By default the connection holds until the run finishes. The body is the job's output as structured JSON.
| Status | Meaning |
| ------ | ---------------------------------------------------------------- |
| `200` | The run succeeded. |
| `207` | The run partially succeeded. The body reports per-step outcomes. |
| `401` | Missing or invalid `x-api-key`. |
| `404` | No job matches the method and path. |
| `502` | The run failed. The body carries the error. |
## Asynchronous execution
Add `?async=1` to the URL, or send the header `x-job-async: true`. The call returns `202` immediately:
```json theme={null}
{
"jobExecutionId": "8f2c41d6-93b4-4a1e-9d0e-5b7a2c6f13aa",
"status": "queued",
"resultPath": "/m/acme/_executions/8f2c41d6-93b4-4a1e-9d0e-5b7a2c6f13aa"
}
```
`resultPath` is relative to the host; appended to it, it resolves to the `/_executions/:id` path under your trigger URL. Poll it with the same API key:
```bash theme={null}
curl "https:///_executions/8f2c41d6-93b4-4a1e-9d0e-5b7a2c6f13aa" \
-H "x-api-key: $MINICOR_API_KEY"
```
The response reports the execution's status (`running`, then a terminal state) and, once done, the job's output, the same body a synchronous call would have returned.
## Status webhooks
Polling tells you where a run stands when you ask. Webhooks tell you the moment it changes. Add a `callback_url` query parameter when you execute an automation and Minicor POSTs a JSON event to that URL as the run progresses:
| Event | When it fires |
| --------------------- | --------------------------------- |
| `execution_started` | The run has started. |
| `step_started` | A step has begun. |
| `step_completed` | A step finished successfully. |
| `step_failed` | A step failed. |
| `execution_completed` | The run reached a terminal state. |
Step events carry the step's name, its position in the run (`executionOrder` of `totalSteps`), its status, and its result. The completion event carries the final status, the result, and a link to the replay.
```json theme={null}
{
"eventType": "step_completed",
"executionId": 48291,
"timestamp": "2026-07-24T17:31:04Z",
"step": {
"flowName": "Create invoice in billing system",
"executionOrder": 3,
"totalSteps": 5,
"status": "SUCCESS"
}
}
```
Deliveries are fire-and-forget: a failed delivery is retried once and never blocks or slows the run. The callback URL must be publicly reachable over HTTP or HTTPS.
Webhooks fire per automation execution. For a job called at its trigger URL, follow progress by polling the execution's result path, which moves from `queued` to `running` to a terminal status with `done: true`.
## Reserved paths
A few paths on your trigger host are reserved for introspection:
| Path | Returns |
| --------------------------- | ------------------------------------------------------------------------------ |
| `GET /swagger.json` | An OpenAPI document describing the jobs on this trigger host. No key required. |
| `GET /_jobs` | The list of jobs and their endpoints. |
| `GET /_executions/:id` | The status and result of one execution. |
| `GET /_builds/:id` | The status of a build, including any open question. |
| `POST /_builds/:id/answers` | Answer a builder question. |
Everything except the OpenAPI document requires the API key.
## Teaching over the same endpoint
A call whose body includes the `minicor.teach` envelope is a teaching call, not a live run. See [The teach envelope](/api/teach).
# The teach envelope
Source: https://docs.minicor.com/api/teach
Add minicor.teach to any call and it becomes a lesson instead of a live run.
Teaching happens over the same endpoint as live traffic. A call whose body contains the `minicor` envelope with `teach: true` is a teaching call: it creates or updates a sample, and it never touches live traffic.
## Shape
```json theme={null}
{
"customerName": "Bobs Tires",
"amount": 1250.00,
"dueDate": "2026-08-15",
"minicor": {
"teach": true,
"prompt": "Create an invoice in the billing system for this customer. If the customer already has an open invoice for the same amount, refuse and say why.",
"scenario": "Rejects duplicate invoice",
"artifacts": [
{ "type": "url", "url": "https://example.com/sops/invoicing.pdf" },
{ "type": "text", "text": "The billing system rejects due dates in the past." }
]
}
}
```
Everything outside `minicor` is the sample input, exactly as your product would send it on a live call.
## Fields
| Field | Required | What it does |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `teach` | Yes | Marks the call as a teaching call. |
| `prompt` | Yes | What the job should do with this input, in plain language. On later samples, use it to describe the expected outcome for this specific case. |
| `scenario` | No | Names the scenario this sample belongs to. Without it, the platform buckets the sample automatically. Manual grouping always wins. |
| `expect` | No | The expected outcome for this sample: fields the response should contain, or `{ "refusal": "why" }` when the correct behavior is to refuse. |
| `artifacts` | No | Context for the builder: SOP documents, transcripts, walkthrough videos, or plain notes. Each entry carries a `type` and a matching `url` or `text` field, plus an optional `description`. |
## What a teach call does
1. The first teach call to an unknown method and path **creates the job** in the Learning state and starts the builder.
2. Every teach call **records a sample**: the input, the intent, and the checks derived from it.
3. The **builder runs** until this sample and every existing sample pass.
4. If the job is already Live, the work happens on a new version and production traffic is untouched until you go live again.
The response acknowledges the lesson and points at the build, which you can follow on the job page or poll at `GET /_builds/:id`.
> Send the payload your product actually produces, not a cleaned-up version. The sample is the contract for live calls, and the job is only as honest as its inputs.
# How it runs
Source: https://docs.minicor.com/how-it-runs
What happens between your API call and the desktop.
You call a job's trigger URL. Minicor runs the automation on a desktop. You get structured JSON back. That is the whole contract, and this page fills in just enough of the middle to reason about it.
## The path of a request
```mermaid theme={null}
flowchart LR
You[Your product] -->|"POST trigger URL"| Engine[Jobs engine]
Engine -->|runs the job steps| Platform[Minicor platform]
Platform -->|drives the application| Desktop[Minicor Desktop Service on a Windows desktop]
Desktop -->|results and recording| Platform
Platform --> Engine
Engine -->|structured JSON| You
```
1. Your product calls the trigger URL with an API key and a JSON body.
2. The jobs engine, the service behind your trigger URLs, matches the request to your job and runs its steps in order. Most steps execute an automation on a desktop; some transform data between steps.
3. On the desktop, the Minicor Desktop Service drives the target application the way a person would, while recording the screen.
4. The result flows back as structured JSON. By default the call is synchronous; for long-running work you can ask for an execution ID and poll instead. See [Calling your job](/running/calling-your-job).
## What makes it reliable
The determinism of an API, the power of AI. The automation steps are deterministic code, built and tested against your real samples until every scenario passes. The intelligence is spent at teach time, not on every request. When something new does break in production, you teach the job the new case and the fix becomes a permanent scenario. See [Self-healing](/teaching/self-healing).
## The same platform, three ways in
* **The dashboard**, where you teach jobs, watch the builder, and go live.
* **The co-pilot**, a chat rail inside the dashboard that operates the platform for you. See [Co-pilot](/teaching/co-pilot).
* **The Minicor MCP**, the same tool surface exposed to your own coding agents. See [Connect an agent](/agents/mcp).
> Everything you can do in the dashboard, an agent can do through the MCP. The [For agents](/agents/mcp) section exists so agents can operate the platform end to end.
# What is Minicor?
Source: https://docs.minicor.com/index
The interface between AI and legacy desktop applications: call them like any API.
Minicor is SOC 2 Type II certified and HIPAA compliant. Automations and their data can run entirely [on your own cloud](/operations/network-boundary).
Minicor is the interface between AI and legacy desktop applications: call them like any API. Minicor agentically builds self-healing automations on any no-API system, EHR, ERP, DMS, TMS, SCM, CMS, then hands you an API endpoint to call. No integration to build, nothing to maintain.
The unit of automation is a **job**. A job is an endpoint that represents an automation. You teach it by sending real sample API calls. The builder works on the automation until every sample passes. Then you go live and call the same endpoint from your product, like any other API.
## How you work with Minicor
1. **Connect a desktop.** Jobs run on a Windows machine with the [Minicor Desktop Service](/running/desktop-service) installed. Use a cloud desktop provisioned through Minicor or a machine in your own environment.
2. **Teach a job with real examples.** Send sample API inputs to the job's endpoint. The platform buckets your samples into **scenarios**, one for each behavior the job needs to handle.
3. **Watch the builder work.** The builder constructs and refines the automation until every sample passes. It asks you questions when it needs answers.
4. **Go live.** The job earns a [stability score](/teaching/stability) as samples pass and live traffic succeeds. When you go live, the same URL serves production traffic.
> The samples you teach are the definition of correct. The more scenarios a job has, the more reliable it gets. That is also how [self-healing](/teaching/self-healing) works on Minicor.
## What runs underneath
Each job is a sequence of automation steps that execute on a desktop through the Minicor Desktop Service. Steps drive the target application the way a person would: navigating screens, filling fields, reading results. Every run is recorded, so you can watch a [replay](/running/executions-and-replays) of exactly what happened on the desktop.
## What the platform gives you
| | |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Stay in control** | [Verification](/operations/verification) checks the screen before critical actions, human review steps gate the writes you choose, and agent actions require your approval. |
| **End-to-end observability** | Audit logs and a video [replay](/running/executions-and-replays) of every step, for every run. |
| **Plugs into your stack** | [Status webhooks](/api/calling-jobs#status-webhooks) and telemetry push events to your systems in real time. |
| **Authentication that holds** | [2FA / OTP](/running/two-factor) handled inside the run, credentials vaulted in [configurations](/running/configurations), and authenticated sessions reused across runs. |
| **Scale** | Run many jobs at once. Runs serialize per [desktop](/running/desktops) and scale out across desktops. |
| **Deploy anywhere** | [Desktops, virtual machines, browsers, and Citrix](/running/desktops#where-automations-run). Host on our cloud, or [entirely on yours](/operations/network-boundary). |
## Where to start
Teach your first job in a few minutes.
What happens between your API call and the desktop.
How teaching works and how scenarios are formed.
Point your coding agent at the Minicor MCP.
# Exceptions and telemetry
Source: https://docs.minicor.com/operations/exceptions-and-telemetry
How failures are categorized, where they surface, and how they reach your systems.
Automations against legacy systems fail for reasons that have nothing in common: a UI change, bad input, the target system being down. Operating at scale means categorizing failures so each kind routes to the right fix, instead of being triaged by hand every time.
## The four categories
| Category | What happened | Resolution |
| ------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| Automation failure | The job did not do what it should: a missed click, a wrong field, an element that moved. | Watch the replay, teach the failing case, go live with the fix. |
| Bad input | The caller sent data the target system rejects: a missing field, an invalid format, a date rule violation. | Route back to the caller. This is an upstream fix. |
| System instability | The target system is down, hanging, or in maintenance. A person could not complete the task either. | Retry later. Excluded from the job's stability signal. |
| External dependency | A prerequisite owned by someone else is missing: a document not uploaded, an approval not given. | Hold and notify whoever owns the prerequisite. |
Tracking bad input over time is worth the effort on its own. A validation error that fires many times a day is a signal to add validation upstream in your product; one that fires monthly is not worth the engineering.
## Where failures surface
**Callbacks.** The primary machine channel. When a run fails, your failure endpoint receives structured error information, including the category, so your system can update statuses, open tickets, or trigger its own flows automatically.
**Slack.** Executions post to a dedicated telemetry channel: job name, status, and a link to the replay. Failures are flagged with what likely went wrong. Most production triage happens directly from this channel, without opening the dashboard.
**Your observability stack.** Failures can flow into your existing tooling through an OpenTelemetry pipeline or a notification endpoint you define. Execution artifacts and logs can be written to a storage bucket you choose, including one inside [your own boundary](/operations/network-boundary).
Callbacks, Slack channels, and export destinations are wired up with your Minicor team when you move to production.
> The failure loop is teach-shaped on purpose. An automation failure becomes a sample, the sample becomes a scenario, and the same failure does not come back. See [Self-healing](/teaching/self-healing).
# Human in the loop
Source: https://docs.minicor.com/operations/human-in-the-loop
Patterns for putting a person exactly where one belongs: on the write that matters, and nowhere else.
Most of a job should run without anyone watching. The point of human-in-the-loop is precision: a person on the one action that deserves judgment, automation on everything else. These are the patterns, from lightest to heaviest, and how to build each one.
## Verify, gate, write
The default. Before a critical action, a [verification step](/operations/verification) checks the screen against a plain-language expectation and a gate stops the run if it fails. No person involved unless something is wrong, and when something is wrong, nothing gets written.
**Build it:** ask for it when you teach. "Verify we are on the right screen before submitting, and stop if we are not." The builder puts the verification and the gate in place.
## Refuse instead of guessing
When the input itself is the problem, the right behavior is a refusal the caller can act on, not a best guess. A job taught with refusal scenarios rejects bad input instantly and returns why.
**Build it:** teach a sample with `expect: { "refusal": "why" }` in the [teach envelope](/api/teach). Duplicate records, missing fields, and unknown entities each become a scenario that refuses cleanly.
## A person approves the write
For high-stakes writes, regulatory requirements, or judgment calls, a [human review step](/operations/verification#human-review) pauses the run and notifies your Slack channel with the context and the state of the desktop. Approved runs continue; rejected runs stop safely.
**Build it:** ask for it when you teach: "before saving, send this for review and wait for approval."
## Your own review queue
When approvals belong in your product rather than ours, run the loop yourself: call the job [asynchronously](/running/calling-your-job#asynchronous-for-long-work), follow progress with [status webhooks](/api/calling-jobs#status-webhooks) or polling, and surface the run to your reviewer with whatever context your product has. Their decision becomes the next API call.
**Build it:** split the work into two jobs, one that reads and prepares, one that writes, and put your approval between them.
## Take the desktop yourself
Sometimes the loop is literal: a one-time dialog, a manual sign-in, a state only a person can untangle. Every desktop has a [live view](/running/desktops#watching-and-intervening) and you can take control from the browser mid-run.
## Approving what agents do
The [co-pilot](/teaching/co-pilot) and any agent on the [MCP](/agents/mcp) propose actions with consequences, teaching a job, going live, running a script, as approval cards. You approve or decline each one.
> Start with verify-gate-write everywhere, add refusals for bad input, and reserve human approval for the writes where being wrong is expensive. A loop with a person in the wrong place is just a slow automation.
# Monitoring and reporting
Source: https://docs.minicor.com/operations/monitoring-and-reporting
What operating live jobs looks like: agents watching traffic, and reports you can hand to your own customers.
Going live is the start of the operating loop, not the end of the project. Live jobs are watched continuously, and the platform is built so most of that watching is not done by a person.
## The operating loop
1. Executions post to [telemetry](/operations/exceptions-and-telemetry) with their status and replay link.
2. Failures are categorized, so bad input routes to the caller and automation failures route to a fix.
3. Fixes arrive by teaching: the failing case becomes a sample, the builder makes it pass, you go live. The [stability score](/teaching/stability) reflects the job's live record the whole time.
## Agents on watch
You can set an agent to watch a live automation. It watches runs, investigates failures by reading the run and the replay, and can trigger teach mode with the failing case, so the fix is often waiting for your review before you have read the alert. Agents run on demand, on a schedule, or as monitors, and their runs are recorded and reviewable like any other execution.
The dashboard aggregates the same signal for people: stability at a glance, readiness across the workspace, and which jobs need attention.
## Reporting
Minicor produces periodic usage and error reports per job: total runs, retries, failures with their categories, and trends over time. The reports are written to be handed downstream. When one of your own customers is the source of malformed input, the report documents it concretely, which turns a recurring support argument into a data point.
> Use replays to see what happened, categories to decide whose fix it is, and reports when you need a paper trail.
# Deploy on your cloud
Source: https://docs.minicor.com/operations/network-boundary
Deploy the jobs engine inside your own cloud, so sensitive data never leaves your project.
For customers handling regulated data, Minicor deploys the jobs engine and the stack around it inside your cloud project: the jobs engine, the platform API, the dashboard, the automation desktop, and the storage for replays and execution data. Sensitive data, PHI included, stays inside your boundary. We run this in production today for healthcare customers.
## What lives where
Inside your cloud project:
* The jobs engine serving your trigger URLs.
* The platform API and dashboard.
* The Windows desktop running the Minicor Desktop Service and the target application.
* Your storage buckets and database, holding replays, screenshots, and run payloads.
What crosses to Minicor cloud is coordination, not content:
| Crosses the boundary | What it contains |
| -------------------------------------------- | ------------------------------------------------------------------------- |
| Job and automation definitions, run metadata | What the steps are and how runs went. No payload data. |
| Coordination state | Locks and run bookkeeping, so one run drives a desktop at a time. |
| The command bus | Instructions to the desktop and their results in transit. |
| Verification screenshots | Sent for a pass or fail verdict under BAA, passed through and not stored. |
Traffic in and out rides your edge (your CDN, WAF, and load balancers), and services inside the project talk to each other without leaving it. We provide a complete allowlist of every endpoint the deployment talks to, in both directions, so your network team can pin the boundary down and audit it.
## How a run flows
```mermaid theme={null}
sequenceDiagram
autonumber
participant P as Your product
participant E as Jobs engine (your cloud)
participant A as Platform API (your cloud)
participant D as Desktop (your cloud)
participant S as Your storage (your cloud)
participant M as Minicor cloud
P->>E: POST trigger URL (x-api-key)
E->>A: run the job's steps
A->>M: read definitions, write run metadata
A->>D: execute automation steps
D->>S: replay and screenshots
D->>A: step results
A->>M: screenshot verdict (pass-through, not stored)
A->>E: job result
E->>P: structured JSON back
```
The payloads, the replays, and everything the automation read off the screen stay in your project. Minicor cloud sees that a run happened and how it went, not what was in it.
## What this takes
A deployment like this is set up together with your infrastructure team: a cloud project you own, a Windows VM for the desktop, and the network rules from the allowlist. Deployments update through your own CI/CD, so you control what ships and when. Talk to us at [connect@minicor.com](mailto:connect@minicor.com) to scope one.
# Verification
Source: https://docs.minicor.com/operations/verification
Screenshot checks, gates, and human review keep an automation from writing to the wrong place.
Legacy UIs are unpredictable. A pop-up, a session timeout, or an unexpected navigation state can leave an automation on the wrong screen, and writing data into the wrong record is the one failure that is hard to unwind. Verification steps exist so that never happens silently.
## Screenshot verification
Before a critical action, the automation captures a screenshot of the desktop and checks it against a plain-language expectation: "Is this the order entry form for customer 12345?" The check runs against the actual pixels on screen, so it catches exactly the failures that break blind automations: the wrong patient chart, the stale session, the dialog covering the form.
A verified lookup in a legacy dealership system: the automation opens the customer record, and a verification step confirms it is the right customer before anything downstream reads or writes.
## Gates
A gate reads the verification result and decides what happens next.
| Result | Action |
| ------ | ----------------------------------------------------------------------------- |
| Pass | The run continues to the next step. |
| Fail | The run stops safely before the write, resets state, and reports the failure. |
The pair is the standard safety pattern: verify, then gate, then write. Ask for it when you teach ("verify we are on the right screen before submitting, and stop if we are not") and the builder puts both steps in place.
## Human review
Some writes deserve a person. A human review step pauses the run and sends a notification to your Slack channel with the context and the current state of the desktop. A reviewer approves or rejects; approved runs continue, rejected runs stop safely.
Use human review for high-stakes writes, regulatory requirements, or judgment calls, and screenshot verification for everything routine. They compose: an automated check on every screen, a person on the one that matters.
> Verification failures are not errors, they are saves. Each one is a bad write that did not happen, and each is worth teaching back as a scenario so the run handles that state on its own next time.
# Quickstart
Source: https://docs.minicor.com/quickstart
Teach your first job: connect a desktop, send one real example, watch the builder work, and go live.
A job is an endpoint that represents an automation. This guide takes you from an empty workspace to a live job you can call from your product.
## Prerequisites
* A Minicor workspace. Sign in at [app.minicor.com](https://app.minicor.com), the Minicor dashboard.
* The target application you want to automate, running on a desktop you can connect.
Jobs run on a Windows machine with the [Minicor Desktop Service](/running/desktop-service) installed. You can use a cloud desktop provisioned through Minicor or a machine in your own environment. Once the desktop is connected, it appears in your workspace with a live preview.
See [Desktops](/running/desktops) for the details.
Describe what the job should do and give it one real input. The first call to a new endpoint with a teach envelope creates the job and starts the builder.
Your trigger URL and its API key are on the Jobs page; the empty state hands you a ready-to-run curl. See [Authentication](/api/authentication) for where keys live.
```bash theme={null}
curl -X POST "https:///create-invoice" \
-H "x-api-key: $MINICOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerName": "Bobs Tires",
"amount": 1250.00,
"dueDate": "2026-08-15",
"minicor": {
"teach": true,
"prompt": "Create an invoice in the billing system for this customer."
}
}'
```
You can do the same thing without curl: click **Create a job** in the dashboard and fill in the description and example input, or ask the [co-pilot](/teaching/co-pilot) to teach it for you.
The job appears in your workspace in the **Learning** state. A job is always either **Learning** (the builder and your samples are shaping it) or **Live** (real traffic runs through it). The builder explores the target application on your desktop, constructs the automation steps, and runs your sample until it passes. You can watch its progress on the job page, including a live view of the desktop. If it needs information it cannot discover on its own, it asks you a question.
See [The builder](/teaching/the-builder).
Send more real inputs the same way, with the teach envelope. Samples that exercise different behavior are bucketed into separate [scenarios](/teaching/samples-and-scenarios): the happy path, the duplicate customer, the missing field. Each scenario makes the job more reliable, and the job's [stability score](/teaching/stability) reflects that.
When your samples pass and the stability score looks right, click **Promote to live**. See [Going live](/teaching/going-live).
Same URL, no teach envelope. The job runs the automation on your desktop and returns structured JSON.
```bash theme={null}
curl -X POST "https:///create-invoice" \
-H "x-api-key: $MINICOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerName": "Bobs Tires",
"amount": 1250.00,
"dueDate": "2026-08-15"
}'
```
See [Calling your job](/running/calling-your-job) for sync and async patterns.
> Every run is recorded. If anything looks off, open the execution and watch the [replay](/running/executions-and-replays) of what happened on the desktop.
# Calling your job
Source: https://docs.minicor.com/running/calling-your-job
One HTTP call to the trigger URL. JSON in, structured JSON out, sync or async.
Every job has a trigger URL, shown at the top of its job page next to its API key. Calling it is ordinary HTTP: the key in the `x-api-key` header, JSON in the body, structured JSON back.
```bash theme={null}
curl -X POST "https:///create-invoice" \
-H "x-api-key: $MINICOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerName": "Bobs Tires",
"amount": 1250.00,
"dueDate": "2026-08-15"
}'
```
## Synchronous by default
By default the call holds until the job finishes and returns the job's output as the response body. The status code tells you how the run went:
| Status | Meaning |
| ------ | ------------------------------------------------------------------------------------- |
| 200 | The job succeeded. |
| 207 | The job partially succeeded; some steps completed, some did not. The body says which. |
| 502 | The job failed. The body carries the error. |
Synchronous calls fit jobs that finish in seconds to a couple of minutes. Desktop automations are slower than a database query; set your client timeout accordingly.
## Asynchronous for long work
For long-running jobs, ask for an execution instead of holding the connection. Add `?async=1` to the URL (or send the `x-job-async: true` header) and the call returns `202` immediately:
```json theme={null}
{
"jobExecutionId": "8f2c41d6-93b4-4a1e-9d0e-5b7a2c6f13aa",
"status": "queued",
"resultPath": "/m/acme/_executions/8f2c41d6-93b4-4a1e-9d0e-5b7a2c6f13aa"
}
```
Poll the result path on the same host with the same API key until the execution reports done, then read the output from the response.
The poll is also how you follow a run in progress: the status moves from `queued` to `running` to a terminal state, with `done: true` and the output once it finishes. If you would rather be told than ask, [status webhooks](/api/calling-jobs#status-webhooks) push events to your endpoint as the run progresses.
## Inputs
Query parameters and the JSON body merge into a single input object for the job. What you send is what you taught: the samples you used in teaching are the contract for what a live call should look like.
The full request and response contract, including reserved paths and the per-job OpenAPI document, is in the [API reference](/api/calling-jobs).
# Configurations
Source: https://docs.minicor.com/running/configurations
Key-value settings resolved into a job at run time. Credentials live here, not in the automation.
A configuration is a set of key-value pairs attached to a job and resolved at run time: the automation reads a key and gets the current value. Credentials for the target system are the most common use, which keeps them out of the automation itself and out of its history.
## Using configurations
Create a configuration in the dashboard under **Configurations**, add your properties, and attach it to the job. The job page shows which configuration a job uses. Change a value and the next run picks it up; nothing needs to be rebuilt or retaught.
Configurations also select the environment. A job pointed at a staging configuration runs against your staging system; swap the configuration and the same job runs against production.
For login challenges that need a code, see [2FA / OTP](/running/two-factor).
> Change a value in one place and every run after picks it up. Credentials never live in the automation itself.
# The Minicor Desktop Service
Source: https://docs.minicor.com/running/desktop-service
The service that connects a Windows machine to the platform and executes every automation step.
The Minicor Desktop Service (MDS) is what turns a Windows machine into a [desktop](/running/desktops) the platform can use. It executes automation steps, captures screenshots and replays, records input telemetry for the run analysis, and manages browser sessions for web applications. Every click and keystroke a job makes goes through it.
Cloud desktops provisioned through Minicor come with the service already installed. For a machine you control, install it yourself.
## Install
Windows 10 or later. Open an elevated PowerShell window and paste:
```powershell theme={null}
$installPath = "$env:TEMP\install.ps1"
irm https://minicor.com/installs/desktop-service/ps1 -OutFile $installPath
powershell -ExecutionPolicy Bypass -File $installPath
```
To register the machine in one shot, set your VM API key from the dashboard first:
```powershell theme={null}
$env:MDS_VM_API_KEY="your-key"
irm https://minicor.com/installs/desktop-service/ps1 -OutFile C:\temp\install.ps1
powershell -ExecutionPolicy Bypass -File C:\temp\install.ps1
```
Prefer a guided setup? Download the installer from [minicor.com/installs/desktop-service](https://minicor.com/installs/desktop-service) and enter the VM API key when prompted.
## After the install
The service registers with the platform automatically. The machine appears in your workspace with a live screen view, and jobs can run against it immediately. If it does not show up, check the dashboard's desktops page for its connection state.
Where you install it is up to you: a Minicor cloud VM, your own cloud project or VPC, or on premises next to the system being automated. See [Desktops](/running/desktops#where-automations-run) for the deployment options and [Deploy on your cloud](/operations/network-boundary) for keeping everything inside your boundary.
# Desktops
Source: https://docs.minicor.com/running/desktops
Deploy on desktops, virtual machines, browsers, and Citrix. Jobs run wherever the target application lives.
A desktop is a Windows machine that runs the application you are automating. Every job executes against a desktop, and everything the automation does happens there: the clicks, the keystrokes, the screen reads, the recording.
Each desktop runs the [Minicor Desktop Service](/running/desktop-service), the service that connects the machine to the platform, executes automation steps, and captures replays. Minicor provisions cloud desktops with it preinstalled, or you install it on a machine you control. Once the service is running, the desktop appears in your workspace with a live preview, ready for jobs.
## Where automations run
Automations drive the target application through its interface, the pixels and controls on screen, so they run anywhere that interface appears.
### Virtual machines
Minicor provisions a Windows VM with the Desktop Service installed, the fastest way to start. Or install the Desktop Service on a machine you control: your cloud project, your VPC, or on premises next to the system being automated. That is the usual choice when the target system is locked down or the data cannot leave your boundary. See [Deploy on your cloud](/operations/network-boundary).
### Browsers
Web applications run in a managed browser session on the desktop. The automation handles single-page apps, dynamic content, popups, and authentication flows, and a single job can mix browser and desktop steps: read from a web portal, write into a desktop application, in one run.
### Citrix and remote desktops
Applications served through Citrix, RDP, or another virtual desktop environment automate the same way local ones do: the automation works the visual stream, so no Citrix-specific connectors are needed. Session disconnects, reconnects, and latency are handled as part of the run.
Wherever it runs, the target application signs in with your existing account for that system. No separate integration user is required.
## Watching and intervening
The dashboard shows a live view of each connected desktop. The same view appears on the job page while the builder works and while runs execute, so you always see what the automation sees.
When you need to act on the desktop yourself (dismiss a one-time dialog, complete a manual sign-in), you can take control from the browser. For extended work on the machine, connect over RDP as usual.
## Scaling out
One desktop is enough to build and go live. When volume grows, add more desktops and Minicor distributes work across them. Jobs that must not overlap on the same application serialize automatically, so two runs never fight over one screen.
# Executions and replays
Source: https://docs.minicor.com/running/executions-and-replays
Every run of a job is an execution, and every execution is recorded.
Every time a job runs, Minicor creates an execution: the input, the outcome of each step, the response, and a replay of the desktop while the automation ran. The job page lists them all, filterable by **All**, **Samples**, and **Live**.
## Sample runs and live runs
Sample runs come from teaching: the builder running samples during a build, or you clicking **Run this sample** or **Run all samples** on the job. Live runs come from real traffic at the trigger URL. They are the same machinery; the filter exists so a burst of sample runs does not bury your production history.
Running all samples produces a **run report**: every scenario, every sample, pass or fail, in one place. It is the fastest way to answer "does this job still work?" after anything changes.
## Replays
The replay is the recording of the desktop during the run. Automation failures are usually visual: a dialog that appeared, a field that did not populate, a click that landed on the wrong row. Watching the replay is almost always the fastest way to see what actually happened, faster than reading logs.
A replay of a live run: the job opens the customer list in a legacy dealership system, fills the new customer form from the request payload, and saves. The record count in the corner ticks up when the write lands.
When a run fails:
1. Open the execution from the job page.
2. Check which step failed and what its output was.
3. Watch the replay around that step.
4. Teach the job the failing case as a new sample, or [drill down](/teaching/drilling-down) and fix the step yourself.
## Reading a replay
Here is a live run that pulls a report out of a dealership management system and returns the rows as JSON. The whole run takes seven seconds. We ran the recording through the platform's video analysis, the same tool agents use through the [MCP](/agents/tools), and drew its layers onto the video: the banner names the step that was executing at that moment, the green boxes are the screen regions the analysis detected changing, and the orange ring is the click it inferred from the cursor's path.
The run has three steps. Watch it once, then walk through the key moments. The frames carry the same layers as the video, drawn at the instant each event fired:
This is the shape of most debugging on Minicor: the response tells you what came back, the step list tells you where time went, and the replay shows you the screen at the moment anything surprising happened.
> Replays double as your audit trail. For every write into a system of record, there is a replay of it being made.
# 2FA / OTP
Source: https://docs.minicor.com/running/two-factor
Virtual phones, emails, and authenticator secrets, so a login challenge never needs a person on call.
Many legacy systems challenge sign-ins with a code. Minicor handles this inside the run, without a person on call:
| Capability | What it does |
| ----------------------- | ------------------------------------------------------------------------------------ |
| Virtual phone numbers | Receive SMS codes for logins that require text verification. |
| Virtual email addresses | Receive email verification codes. |
| Authenticator secrets | Store TOTP secrets and generate current codes on demand. |
| QR registration | Register an authenticator directly from the QR code the target application displays. |
Provision a phone number, email address, or secret once for the workspace under **2FA / OTP** in the dashboard. When a run hits a challenge, the automation requests the current code from the platform and enters it, the same way it fills any other field.
> Secrets are provisioned once and referenced by ID. The values never appear in the automation, the samples, or the replays.
# Co-pilot
Source: https://docs.minicor.com/teaching/co-pilot
A chat rail inside the dashboard that teaches jobs, adds scenarios, and answers questions about your workspace.
The co-pilot is a chat rail on the right side of the dashboard. Open it with the **Co-pilot** button in the top bar or with **Cmd+J**. It knows what page you are on, so on a job page you can just ask about that job.
## What you can do with it
* **Teach a job.** Describe what the job should do and paste one real example input. The co-pilot creates the job and starts the builder.
* **Add samples and scenarios.** Tell it the edge case in plain language and it turns that into a sample with the right checks.
* **Diagnose failures.** Ask why a scenario is failing and it reads the run, looks at what happened on the desktop, and tells you what it found.
* **Check readiness.** Ask what is blocking go-live and it walks the stability breakdown for you.
* **Operate the workspace.** Ask about executions, desktops, configurations, or anything else you would otherwise click through to find.
## Approvals
Anything with consequences comes back to you as an approval card before it happens: teaching the job with a new sample, updating the job, going live, running a script on a desktop. The co-pilot proposes, you approve.
> "Promote /create-invoice to live?" Real traffic will run this version. **Approve** / **Not yet**
## The same tools your agents get
The co-pilot is not a separate system. It operates the platform through the Minicor MCP, the same tool surface you can point your own coding agent at. If you would rather work from your IDE or wire Minicor into your own agent stack, see [Connect an agent](/agents/mcp).
# Drilling down
Source: https://docs.minicor.com/teaching/drilling-down
When you want to see exactly where a job failed and edit the automation yourself, open the Build view.
Most fixes go through teaching: send the failing case as a sample and let the builder handle it. But sometimes you want your hands on the automation itself. You saw the replay, you know exactly which step misbehaved, and you would rather edit it than describe it.
The **Build** view is the tool for that. Treat it as the advanced path; for day-to-day work, teaching is faster and keeps the scenarios as the source of truth.
## From a failing sample to the step
1. On the job page, select the failing sample. The job's steps light up according to what happened in its latest run, so you can see exactly where it went wrong.
2. Click **Fix in Build**. This drops you into the Build view scoped to the failing step's automation.
3. The left side shows the automation's steps. The right side shows the desktop and the output of each run, with the evidence from the failing job run already loaded.
## Working in the Build view
* Edit a step's code directly, then run just that step, a range of steps, or the whole automation against a live desktop.
* Seed the run with the input from the failing job run, so you are reproducing the real failure rather than a synthetic one.
* Watch the desktop live as steps execute, the same view the builder uses.
When the step behaves, save your changes and re-run the job's samples from the job page to confirm every scenario still passes.
> Whatever you change by hand, prove it with the samples afterward. A manual fix that passes the scenarios is a fix; one that skips them is a guess.
# Going live
Source: https://docs.minicor.com/teaching/going-live
A job is Learning or Live. Go live switches the trigger URL to the taught version immediately.
A job is in one of two states: **Learning** or **Live**. Learning means the builder and your samples are shaping it. Live means real traffic runs through it.
## Go live
When your scenarios pass and the [stability score](/teaching/stability) looks right, click **Promote to live** on the job page. Live traffic at the trigger URL switches to the taught version immediately. There is no separate release step and nothing to configure.
If the job's stability is low, the dialog says so: the tier, the score, and a suggestion to add scenarios and get every sample passing first. It is a warning, not a gate. You decide.
## Calling a live job
The same URL you taught against serves production. The only difference is the payload: no teach envelope.
```bash theme={null}
curl -X POST "https:///create-invoice" \
-H "x-api-key: $MINICOR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerName": "Bobs Tires",
"amount": 1250.00,
"dueDate": "2026-08-15"
}'
```
See [Calling your job](/running/calling-your-job) for the full request contract.
## Teaching a job that is already live
Live jobs keep learning. Send a new sample with the teach envelope and the builder works on a new version while production traffic continues on the current one, untouched. As soon as a live job has taught changes waiting, it shows **Live · new lesson ready**. Review the new version, run the samples, then click **Promote to live** again to switch traffic over.
> Production is never where you teach. Everything you teach runs against the job's working version; live traffic only changes when you say so.
# Samples and scenarios
Source: https://docs.minicor.com/teaching/samples-and-scenarios
Teaching a job means sending it real sample API calls. The platform buckets them into scenarios, one for each behavior the job needs to handle.
You do not configure a job. You teach it, and teaching means sending real examples.
## Samples
A sample is one real API input, sent to the job's endpoint with a teach envelope:
```json theme={null}
{
"customerName": "Bobs Tires",
"amount": 1250.00,
"minicor": {
"teach": true,
"prompt": "Create an invoice in the billing system for this customer."
}
}
```
Each sample becomes part of the job's definition of correct. The builder is not done until every sample passes. You can send samples from curl, create them in the dashboard, ask the [co-pilot](/teaching/co-pilot), or use the [MCP](/agents/mcp) from your own agent.
A sample carries three things:
| Part | What it is |
| ------ | ------------------------------------------------------------- |
| Input | The real JSON payload, exactly as your product would send it. |
| Intent | What should happen, in plain language. |
| Checks | What the response must look like for the sample to pass. |
Checks come in two forms. **Expression checks** assert on the response directly, like a status code or a field value. **Judged checks** describe the expected outcome in plain language and the platform grades the response against it. Judged checks are useful when the exact shape of a correct response varies.
## Scenarios
As samples run, the platform groups them into **scenarios**. Samples that exercise the same path through the job land in the same scenario, and the scenario gets named for the behavior it covers: "Creates a standard invoice", "Rejects duplicate customer", "Handles missing due date".
The grouping is based on what actually happened during the run, not on how similar the inputs look. Two inputs that read very differently but drive the job down the same path belong to the same scenario. An input that triggers a new path creates a new scenario.
You can also group samples yourself. Name a scenario when you teach, or add samples to a scenario from the job page. Samples in a scenario you created yourself are never regrouped automatically.
## Why scenarios matter
Scenarios are the job's coverage map. The job page shows how many scenarios are passing at a glance, and the [stability score](/teaching/stability) counts your samples toward readiness. When you wonder whether a job is ready for production, the question is concrete: which behaviors have scenarios, and are they all green?
> Teaching is defining what correct means up front, except the definition is real API calls from your product. Edge cases you teach today are failures you never see in production.
## Adding edge cases
The fastest way to harden a job is to teach the inputs you are worried about:
* The record that already exists.
* The field that is sometimes missing.
* The value the target system rejects.
* The request that should be refused entirely.
Send each one as a sample with the expected outcome, and the builder works until the job handles them all. This is the core of [self-healing on Minicor](/teaching/self-healing): enough scenarios, and the job stops breaking.
# Self-healing
Source: https://docs.minicor.com/teaching/self-healing
Self-healing on Minicor is accumulation: every sample you teach makes the job better, until it stops breaking.
People usually ask about self-healing expecting runtime magic: an agent that improvises its way past whatever the screen throws at it, on every request. Minicor can heal jobs automatically, and does. But the healing runs through teaching, not through improvising in production, and that difference is the reason jobs hold up.
## Healing by accumulation
Every sample you teach becomes a scenario the job must keep passing. The job that has seen the duplicate customer, the expired session, the missing field, and the vendor's quirky validation dialog does not break on them, because handling those cases is part of what the builder verified.
So the automation gets more reliable the longer it runs. Not because it improvises better, but because coverage only grows: more scenarios, fewer surprise failures.
## When something new happens
New failure modes still appear: a vendor ships a UI change, a system behaves differently at month-end. When that happens:
1. The failure surfaces in [telemetry](/operations/exceptions-and-telemetry) with a replay of exactly what happened on the desktop.
2. You, the co-pilot, or an agent in teach mode sends the failing input back to the job as a new sample.
3. The builder updates the automation until the new sample passes, alongside every existing scenario.
4. You review and go live. The failure is now a scenario, and it never surprises you again.
This loop can run without you. An agent on watch catches the failure and triggers teach mode with the failing case, so the fix is often ready before you have looked at the alert. See [Monitoring and reporting](/operations/monitoring-and-reporting).
> After you teach the failing case, that failure mode is covered. You should not see the same break twice.
## What we recommend
Let agents catch failures and teach the fixes automatically, and keep the go-live as your review point for jobs that write into systems of record. You get the speed of hands-off healing with a human decision on what reaches production.
The reason healing goes through teaching rather than runtime improvisation: deterministic steps are fast, auditable, and repeatable, which is what you want when writing into a system of record. Minicor spends the intelligence at teach time, where a wrong guess costs a failed sample instead of a bad write against production data. What runs in production is code that your scenarios have already proven.
# Stability
Source: https://docs.minicor.com/teaching/stability
Every job has a stability score from 0 to 100 that tells you how proven it is.
Every job carries a stability score from 0 to 100 and a readiness tier. Together they answer one question: how proven is this job right now?
The score appears next to the job's name on the job page. Click it for the full breakdown.
## How the score is computed
The score is the sum of three components.
| Component | Up to | What it measures |
| ------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Coverage | 30 points | How many samples the job has. Full marks at 5 enabled samples. |
| Sample runs | 35 points | The pass rate of the most recent sample run. No runs yet means 0. |
| Live traffic | 35 points | The success rate of the last 50 live calls. Discounted until there are at least 10, so a small streak does not read as proven. |
A job with 5 samples, a fully green latest run, and 50 successful live calls scores 100. A freshly taught job with one passing sample sits much lower, which is the honest answer.
## Readiness tiers
The tier is the plain-language version of the score.
| Tier | What it means |
| ----------- | ---------------------------------------------------------------------------------------------- |
| Unproven | The job has never had a passing build, or has no samples. There is no evidence yet. |
| Stabilizing | The job has been built and has samples, but has not cleared the bar below. |
| Ready | Score of 70 or higher, the latest sample run is fully green, and there are at least 3 samples. |
| Proven | Ready, plus at least 20 successful live calls. The job has held up under real traffic. |
## What stability does and does not do
Stability informs, it never blocks. You can take an unproven job live; the **Promote to live** dialog will tell you the score and suggest adding scenarios first, and then it will do what you asked.
The score moves for exactly the reasons you would want it to:
* Teaching more samples raises coverage.
* A green run of all samples raises the sample component; a red one lowers it.
* Successful live traffic accumulates toward proven; failures pull the live component down.
> If you want a higher score, do not chase the number. Teach the edge cases you are worried about and run the samples. The score follows the evidence.
# The builder
Source: https://docs.minicor.com/teaching/the-builder
The builder constructs the automation and refines it until every sample passes.
When you teach a job, the builder takes over. It connects to your desktop, explores the target application, constructs the automation steps, and runs your samples against them. It keeps working until every sample passes.
## Watching it work
The job page shows builder activity as it happens: what the builder is doing, which samples it is running, and how each one turned out. A live view of the desktop sits alongside, so you can watch the automation drive the application in real time.
A build run moves through a small set of states:
| State | Meaning |
| ----------------- | -------------------------------------------------------- |
| Queued | The build is waiting to start. |
| Building | The builder is working on the draft. |
| Needs your answer | The builder has a question for you. |
| Passed | Every sample passes. |
| Failed | The builder could not make the samples pass and stopped. |
| Stopped | You stopped the build. |
## Answering questions
Some things the builder cannot discover on its own: which environment to use, what a company-specific field means, how to resolve an ambiguous instruction. When it hits one of these, the build pauses in **Needs your answer** and the question appears on the job page. Answer it and the build continues. Attaching context when you teach (an SOP document, a call transcript, plain notes) reduces how often this happens.
A **Failed** build is not a dead end either. Answer any open question, add context or another sample that clarifies the behavior, and teach again.
## Stopping and re-teaching
You can stop a build at any time from the job page. Stopping is cooperative: the current operation finishes, then the build halts.
Teaching is never one-shot. Send a new sample to a **Learning** job and the builder folds it in. Teach a job that is already **Live** and the builder works on a new version without touching production traffic. See [Going live](/teaching/going-live).
> The builder edits the job's automation, not your live traffic. Nothing you teach affects production until you click **Promote to live**.