---
title: "Carry the Receipts"
description: "Define a typed work order, append observable evidence with eve tools, and configure a durable root session that can resume without losing the factory's decision trail."
canonical_url: "https://vercel.com/academy/creating-a-software-factory/carry-the-receipts"
md_url: "https://vercel.com/academy/creating-a-software-factory/carry-the-receipts.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-08-29T01:48:00.510Z"
content_type: "lesson"
course: "creating-a-software-factory"
course_title: "Creating a Software Factory"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Carry the Receipts

# Carry the receipts

Picture a run that pauses Friday afternoon and resumes after Monday's deploy. If its request, commands, and decisions lived only in the old process, the reviewer gets a confident answer with no usable history.

```ts title="agent/lib/work-order.ts"
export const evidenceSchema = z.object({
  details: z.string().optional(),
  kind: z.enum(["observation", "command", "test", "decision", "diff"]),
  recordedAt: z.iso.datetime(),
  summary: z.string().min(1),
});
```

A work order gives every station the same request, current status, route, and evidence. eve keeps that object attached to a durable session across model calls, sandboxes, redeploys, and approval pauses.

## Carry Evidence Across Every Pause

Create a durable work-order contract with tools that initialize work and append observable evidence.

## Hands-on Exercise 1.2

Create `agent/lib/work-order.ts`. Define these accepted values first:

```ts title="agent/lib/work-order.ts"
import { z } from "zod";

export const workTypeSchema = z.enum([
  "documentation",
  "bug",
  "public-api",
  "unknown",
]);
export const riskSchema = z.enum(["low", "medium", "high"]);
export const laneSchema = z.enum([
  "documentation",
  "bug",
  "public-api",
  "manual",
]);
```

Add `evidenceSchema` from the opening, then define `workOrderSchema`. Its source is always present. Classification and route are optional because intake has not made those decisions yet.

```ts title="agent/lib/work-order.ts"
export const workOrderSchema = z.object({
  classification: z.object({
    actionable: z.boolean(),
    confidence: z.number().min(0).max(1),
    questions: z.array(z.string()),
    rationale: z.string(),
    risk: riskSchema,
    type: workTypeSchema,
  }).optional(),
  evidence: z.array(evidenceSchema).default([]),
  id: z.string().min(1),
  route: z.object({
    approvalRequired: z.boolean(),
    lane: laneSchema,
    reason: z.string(),
  }).optional(),
  source: z.object({
    body: z.string(),
    number: z.number().int().positive(),
    title: z.string().min(1),
    url: z.url(),
  }),
  status: z.enum([
    "received", "needs-clarification", "routed", "investigating",
    "awaiting-approval", "building", "verifying",
    "ready-for-draft-pr", "stopped",
  ]),
});
```

Infer `Evidence` and `WorkOrder` types from the schemas. Add an `addEvidence` function that creates the timestamp and parses the updated object. Create the timestamp inside `addEvidence` rather than accepting it from tool input.

Create `agent/tools/create_work_order.ts` and `agent/tools/record_evidence.ts`. Each file becomes an eve tool, so their filenames become the tool names.

```ts title="agent/tools/create_work_order.ts"
import { defineTool } from "eve/tools";
import { z } from "zod";
import { workOrderSchema } from "../lib/work-order.js";

export default defineTool({
  description: "Create the typed work order for one GitHub issue.",
  execute(input) {
    return workOrderSchema.parse({
      evidence: [],
      id: `issue-${input.number}`,
      source: input,
      status: "received",
    });
  },
  inputSchema: z.object({
    body: z.string(),
    number: z.number().int().positive(),
    title: z.string().min(1),
    url: z.url(),
  }),
});
```

`record_evidence` accepts the current work order and one evidence record without `recordedAt`. It returns the entire updated work order.

Finally, configure enough session time and output budget for investigation, verification, and approval pauses. In `agent/agent.ts`, keep `maxOutputTokensPerSession: 80_000` and add `sessionTimeoutMs`:

```ts title="agent/agent.ts"
limits: {
  maxOutputTokensPerSession: 80_000,
  sessionTimeoutMs: 7 * 24 * 60 * 60 * 1_000,
},
```

The output-token limit is a ceiling for the whole durable session, including subagents and revision loops. It prevents an accidental unbounded run; it is not a target and does not reserve or spend 80,000 tokens by itself.

Disable eve's general delegation tool at `agent/tools/agent.ts`:

```ts title="agent/tools/agent.ts"
import { disableTool } from "eve/tools";

export default disableTool();
```

Set the session timeout to seven days. General delegation stays off until we add named specialists with narrow jobs.

## Try It

Create `agent/lib/work-order.test.ts` with one new work order and one appended observation. Then run:

```bash
pnpm test agent/lib/work-order.test.ts
pnpm typecheck
pnpm exec eve info
```

The test should report two passing checks. eve should discover two authored tools and zero subagents:

```text
Compile       ready
Diagnostics   0 errors, 0 warnings
Tools         2 tools
Subagents     0 subagents
```

\*\*Note: Inspect the trust boundary\*\*

Try to create a work order with `status: "looks-good-to-me"`. Zod should reject any state outside the defined workflow.

\*\*Warning: record\_evidence requires a timestamp\*\*

Use `evidenceSchema.omit({ recordedAt: true })` in the tool input. `addEvidence` creates the timestamp during execution.

\*\*Warning: eve exposes a general agent tool\*\*

The override must live at `agent/tools/agent.ts` and export `disableTool()` as its default value.

## Commit

```bash
git add agent
git commit -m "feat(factory): preserve durable evidence"
```

## Done-When

- [ ] Every work order carries its source, status, route, and evidence
- [ ] New work orders begin with an empty evidence list
- [ ] Evidence timestamps are created by the factory
- [ ] Root sessions have a seven-day lifetime
- [ ] `eve info` reports two tools and zero diagnostics

The work order can now outlive the process that created it. Only trusted GitHub events should be allowed to create one.

## Solution

The exercise contains the complete schemas, tool shape, and session limits. Compare `agent/lib/work-order.ts`, `agent/tools/record_evidence.ts`, and `agent/agent.ts` with the `solution` branch if a focused test fails.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
