Metadata-Version: 2.4
Name: terkel
Version: 0.1.0
Summary: Interviews the person who does the work, scores each step for automation, and says which steps to leave alone.
Author: terkel contributors
License: Apache-2.0
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.110
Requires-Dist: jinja2>=3.1
Requires-Dist: networkx>=3
Requires-Dist: pyyaml>=6
Requires-Dist: typer>=0.12
Requires-Dist: uvicorn>=0.29
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.40; extra == 'anthropic'
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: openai
Requires-Dist: openai>=1.30; extra == 'openai'
Description-Content-Type: text/markdown

# terkel

Point a tool for scoring business processes at a process and it will find things to automate, because that is what it was built to do. The more useful answer is usually the opposite, the parts you should leave alone and why. terkel (said *TUR-kuhl*) is built to give that answer. It is named after Studs Terkel, who spent his career recording ordinary people describing their jobs; it interviews the person who actually does the work, maps how the process really runs, and scores each step. When a step should not be automated, it says so plainly and names the constraint that stopped it.

That matters because the documented process and the real one are never the same. The exceptions and the workarounds are where the effort goes, and they are exactly what a map drawn from a flowchart misses. A tool built only to find opportunities will cheerfully recommend automating a step whose mistakes, in real life, no one ever catches.

## It will tell you no

When a step should not be handed to a machine, terkel caps the verdict and names why, instead of letting a high score wave it through:

- errors that are **never caught** → leave alone; you cannot safely automate work whose mistakes no one notices.
- work that is **mostly judgement** → augment at most; a person keeps the decision.
- costly mistakes that **reach the customer** → augment, with a person in the loop.
- a build that **would not pay back** within your ceiling → leave alone.

Each of these is a hard limit that overrides the score, and each appears in the report as the binding constraint on that step, in plain words.

## What it produces

For a process, terkel reports two things and keeps them apart:

- **Hours released per year**, the capacity that would be freed if the promising steps were automated, and the full-time equivalent that represents.
- **Technology cost**, the build effort as a range of days, the annual cost of running it, and the payback period.

It does not recommend redundancies or headcount reductions, and none of its output is framed that way. Released hours are capacity, not a cash saving; the two are reported separately and never blended.

## Run the example with no API key

Everything except the interview runs on files, offline, with no API key and no network.

Clone the repository, enter it, and install:

```bash
git clone https://github.com/danielross-ai/terkel.git
cd terkel
pip install -e .
```

Once terkel is published to PyPI, `pip install terkel` will be the route and you can skip the clone.

Then start with the process that mostly should not be automated:

```bash
terkel score examples/supplier-onboarding.yaml
```

One step comes back **leave alone** because its errors are never caught, and the risk rating is capped at **augment** because it is mostly judgement. Each has its reason on the line beneath. Add a day rate and a heavy, low-volume build that will not pay back is demoted as well (terkel has no default day rate on purpose, since it will not assert what engineering costs):

```bash
terkel score examples/supplier-onboarding.yaml -c examples/day-rate.yaml
```

Then the invoice process, where more of the work is worth doing:

```bash
terkel score examples/invoice-processing.yaml     # verdicts and reasons in the terminal
terkel report examples/invoice-processing.yaml    # writes a self-contained HTML report
```

The report is a single HTML file that opens in any browser and prints to PDF.

## The interview

The interview is the only part that needs a model. It runs as a conversation in the browser, in plain language, for someone with no technical background:

```bash
export TERKEL_PROVIDER=anthropic      # or: openai
export ANTHROPIC_API_KEY=...          # or: OPENAI_API_KEY
terkel interview --output my-process.yaml
```

It asks about the steps, the volumes and timings, what goes wrong and who catches it; it chases the exceptions rather than accepting the tidy version; and it writes the workflow file when it judges the picture complete. You then run `terkel score` or `terkel report` on that file, offline.

## Why a model

Only the interview uses one, and the split is deliberate.

The interview needs a model because a process is described in conversation, not filled into a form. Someone says "I check the invoice against the PO", and the useful detail is in what they leave out: the supplier who still emails PDFs, the threshold above which it goes to a manager, the month-end batch that breaks the usual order. A fixed questionnaire cannot ask the follow-up that surfaces those, because the follow-up depends on the answer before it. A model can hear a tidy account and press on the exceptions until the real shape appears.

The scoring, the economics and the gates use no model at all. A verdict has to be reproducible, so the same workflow file must produce the same answer today and next quarter, and it has to be arguable, so when you disagree you can point at a weight, a threshold or a factor and change it. A number regenerated by a model each run is neither: you cannot diff it, and you cannot argue with it, you can only rerun it and hope. So those parts are arithmetic over a config file, and every factor carries the inputs it came from.

## What it deliberately does not do

- It interviews **one person about one process**. It does not reconcile several accounts of the same work, or compare processes against each other.
- Its scoring weights are **judgement, not measurement**. They encode a point of view about what makes work automatable. They live in a config file so you can disagree with them and change them.
- The verdict is **not just the weighted score**. A weighted average cannot express a veto, so the hard gates above override it. Their thresholds, how much judgement is too much and which payback is too slow, are themselves judgement, and they too live in the config.
- It separates **how often errors happen from how bad they are**. Error frequency counts towards automating a step; error consequence (the cost of a mistake) is kept out of the score and instead feeds the gates. The two used to be one number that both rewarded and penalised errors. This split is a deliberate choice, not a measurement.
- Error frequency scores the **error rate, not errors per year**. Annual volume already drives repetition, and counting it again here let one input push the composite twice. The rate at which the signal saturates, currently one item in five, is another judgement in the config.
- Its build estimates are **ranges, on purpose**. Each range lists the drivers behind it, so you can argue with one assumption rather than dismiss the figure. A single number would imply a precision that is not there.
- It maps steps to capability patterns, such as extraction and classification, **never to a named product or vendor**.
- It does not implement anything it recommends.

## What I would change

Where the design was wrong first, and what is still unproven:

- **The verdict started as a weighted mean**, and a mean cannot express a veto. A step whose errors nobody ever catches scored high on every other factor and came out as automate, which is exactly the recommendation that should never be made. The hard gates were added over the top to say no regardless of the score. Given the time again I would design the vetoes first and the score second, rather than bolting one onto the other.
- **Error exposure was originally one number.** It both rewarded errors (more mistakes, more worth fixing) and penalised them (mistakes are dangerous), so the same input pushed in both directions and the number meant nothing. It had to be split into frequency, which stays in the mean, and consequence, which leaves the mean and feeds the gates.
- **Annual volume influenced the score through more than one factor.** It drove repetition and, through errors per year, error frequency as well, so a high-volume step was rewarded twice for the same fact. Error frequency now scores the error rate itself.
- **The weights and the gate thresholds are still judgement, not measurement.** How much judgement is too much, which payback is too slow, where the error rate saturates: these are a point of view, held in a config file so you can disagree with them.
- **Nothing here has been validated against real implementation outcomes.** No step it called automate has been tracked through a build to see whether the estimate held or the automation stuck. Until that happens the verdicts are a structured argument, not evidence.

## Commands

| Command | What it does |
| --- | --- |
| `terkel interview` | Start the browser interview (needs a model) |
| `terkel score FILE` | Score a workflow and print the verdicts to the terminal |
| `terkel report FILE` | Write the HTML report |
| `terkel init` | Write a starter config file |

## Configuration

Scoring weights, the gate thresholds and the economic assumptions live in a config file you can override. One value has no default on purpose: the **day rate** for build effort. Build cost, payback and the payback gate stay dormant until you set it.

```bash
terkel init                                             # writes terkel.config.yaml
# edit the file, set day_rate, then:
terkel score examples/supplier-onboarding.yaml -c terkel.config.yaml
```

## Requirements

Python 3.11 or later. The interview additionally needs the `anthropic` or `openai` package and the matching API key.

## Licence

Apache 2.0. See [LICENSE](LICENSE).
