# 13.2 The workbench (/building-ai-workers/programming-fundamentals/the-workbench)

---
type: Document
title: "13.2 The workbench"
description: "What the tests, the type checker and the linter each check, why they run in strict mode, and what the commands the agent asks to run do."
status: stable
order: 313.02
ksor:
  owner: team:panaversity
  audience: [ public ]
  approval:
    by: process:panaversity
    at: 2026-11-09T19:52:57Z
chapter: "13"
part: III
expert_status: builder-only
concepts: [ "13.2" ]
last_verified: 2026-10-30
generated:
  at: 2026-11-09T19:52:57Z
  by: process:panaversity
trust_tier: unverified
build_id: sha256:46fd53c5d7ab1c14f6347908d45c9fdaecda4d914439923ee878bdcecd57803e
dirty: true
ksor_version: 0.0.60
---

**In everyday life.** A carpenter's bench holds more than a saw. A square checks the angles, and a level checks that a shelf is not tilted. They catch mistakes before the piece leaves the shop.

**What you will learn.** What each checking tool does, why they run in their strictest setting, and what the agent's commands do.

**Why it matters.** The tools catch small slips in seconds, before you read any code. Only your reading catches a wrong rule.

A coding workbench is the same: tools around the code check it before you read it. A **command** runs a file or a tool in a terminal, the window where commands are typed. You never type one. The agent asks before it runs each one, and you decide. A value's **type** is the kind of value it is, such as text or a number. A **type label**, such as `: number` after a name, says what kind that name holds.

### What reads the code before I do?

Four tools.

- **The runner** runs a file, like pressing Print.
- **Tests** are small programs that run your code on inputs whose answers you already know, and compare. They are like an answer key.
- **The type checker** reads the code before it runs, and checks that each value is used as the kind its label says. It is like a proofreader: it does not check whether the deal in the contract is a good one. In its default mode, Pyright accepts code with no labels at all. So both type checkers in this book run in **strict mode**, which reports a missing label as an error.
- **The linter** reads the code for style problems and common small slips, such as an unused import, a line that brings in other code. It is like a spell checker: it flags slips, not wrong ideas. The practice files in this chapter have none. Lab 13 sets one up for Python.

Tests, the type checker and the linter are reading machines. The type checker and the linter read every line, and the tests run only the lines they use. They tell you where to look first. A valid line with the wrong rule can pass all three.

### What will the agent ask me to approve?

Commands. The first word of a command names the tool.

| First word | What it is | What you will see |
| --- | --- | --- |
| `node` | Runs one TypeScript file | `node src/list-vendors.ts` |
| `npm` | Comes with Node.js. Runs a task this project has given a name, such as its tests | `npm test`, `npm run typecheck` |
| `uv` | Does the same jobs for Python | `uv run python 13_2.py`, `uv run pyright` |
| `npx`, `uvx` | Runs a tool, and fetches it first if the project does not have it | `uvx pyright 13_2.py` |

Use the check from [12.3](../agentic-coding/permissions-and-plan.md#what-do-i-check-before-i-say-yes) before you say yes. If you do not understand a command, ask the agent "What does this command do?" In this book's examples, a line that starts with `$` is a command the agent ran.

### Why does Node run a type mistake?

Node runs Brightline's TypeScript files directly, but does not check them. It removes the type labels and runs the rest. So a type mistake can run, and print nonsense, until a type checker reads the file. Python also ignores type labels when it runs. Pyright, a type checker, reads them.

**At work.** Before Ana opens the agent's changed vendor script, she asks the agent to run the tests and the checkers. The type check fails on one line: an amount from the file was labeled as a number, but it was still text. The tests had passed, because no test used that line.

**Predict.** Here `: string` and `str` label text, and `: number` and `int` label a number. Will this run? Will the type checker accept it?

```ts tab="TypeScript" tab-group="language"
const fromFile: string = "482500";
const cents: number = fromFile;
console.log(cents + 61875);
```

```python tab="Python" tab-group="language"
from_file: str = "482500"
cents: int = from_file
print(cents + 61875)
```

```text tab="TypeScript" tab-group="language"
$ node src/workbench.ts
48250061875
$ npm run typecheck
src/workbench.ts(2,7): error TS2322: Type 'string' is not assignable to type 'number'.
```

```text tab="Python" tab-group="language"
$ uv run python brightline_ap/workbench.py
Traceback (most recent call last):
  ...
TypeError: can only concatenate str (not "int") to str
$ uv run pyright
workbench.py:2:14 - error: Type "Literal['482500']" is not assignable to declared type "int"
```

`+` adds numbers, but it joins text. So Node joined "482500" and 61875, and printed a wrong number. Python stopped at line 3 with a `TypeError`, because it will not join text and a number. Both type checkers stopped at line 2, before anything ran. Their messages mean that text cannot go into a name labeled as a number.

### What will I see when the agent uses git?

You ask in plain words, as in [Chapter 12](../agentic-coding/the-workspace.md), and the agent runs the command. This chapter's lab uses these.

| What the agent is doing | The command you will see |
| --- | --- |
| Showing which files changed and which are new | `git status` |
| Showing the lines that changed, with `-` before the old line and `+` before the new one | `git diff` |
| Listing the **commits**, the save points, newest first | `git log --oneline` |
| Making a commit with a message | `git add`, then `git commit -m "..."` |
| Starting a **branch**, a separate line of work | `git switch -c name` |
| Giving one commit a lasting name, a **tag** | `git tag ch13` |

### Try it

The file in `13-2` is the program above.

**Run.** Send: "Please run the file in 13-2, then the type checker, and show me what each prints. Before the checker, tell me in plain words what each part of its command does. Change nothing."

**Investigate.** Read the checker's message. It names the file, the line and the problem. Ask about any part you can't read.

**Modify.** Send: "Please change the label on cents so it says text, not a number. Don't run anything yet." Will the type checker accept it now? Will the answer be right? Then ask the agent to run the file and the checker.

**Make.** Send: "Please convert the amount to a number before it is added. Run it, and check it."

**What you should see.** After your change, TypeScript's checker is satisfied and the number is still wrong. Python still stops, and Pyright reports the `+`. After the last step, both print `544375`.

**The operating rule:** have the agent run the tests, the type checker in strict mode and any linter the project has on every change, and read what they print before you read the code.

![Figure 13.2. One change through the workbench: the agent's change passes the type check, the linter and the tests, then your review with git status and git diff, then git commit. A failed check or a failed review sends the change back to the agent, and the checks run again.](img/workbench-checks.png)

*Figure 13.2. One change through the workbench. The reading machines go first because they are fast and never get tired. Your read of the diff comes before the commit, never after.*

**Next.** [13.3](values-types-variables.md) shows the kinds of value, and how to make a variable.
