Skip to main content
An AI agent can read a netlist, but a netlist alone doesn’t tell it what the box is for or what each wire means. Knowing uart1 is a UART is not the same as knowing it’s the DUT’s debug CLI. DUT context is the narrative you author once so agents reason about your bench at the level of systems, not loose wires. DUT context lives in /etc/lager/bench.json and is surfaced to agents through the MCP resources lager://dut/overview.md and lager://dut/context, and the discover_dut() and cite_schematic() tools.

The two things to author

1. Per-net purpose

Each net carries a single-sentence purpose plus optional notes. Two more fields serve the test author. dut_connection says where the net lands on the DUT: a connector, pin or test point. test_hints holds one-line advice, one entry per hint. Set purpose, notes and tags in the Net Manager TUI:
Select a net, choose Edit Details, and fill in:
  • Purpose — “DUT debug CLI over UART; primary command/response channel.”
  • Notes (optional) — gotchas, jumper positions, scope probe points.
  • Tags (optional) — short keywords the planning tools match on, e.g. flash, boot-critical.
purpose and notes are prose for the agent to read. tags are keywords that the planning tools score against, and a tag matching a test goal is the strongest relevance signal. You can also set these without the TUI:
--dut-connection and --test-hint are the only way to set those two fields from the CLI; the TUI edits purpose, notes and tags.
/etc/lager/bench.json can hold a net_overrides entry for a net. If that entry sets purpose, notes, tags, dut_connection or test_hints, agents see the override value, not the value saved on the net. The TUI and lager nets describe give no warning about this. discover_bench(net_name) and the bench manifest carry metadata_sources. It names the file each field came from, bench.json or saved_net, so you can see when an override shadows a saved value. Remove the field from the override before you set it on the net.

2. DUT-wide context

The DUT context describes the board as a whole: its purpose, MCU, key peripherals, subsystems, and references to documents. Author it with the lager dut command group.
A fully authored DUT context looks like this in bench.json:
Subsystems group related nets (Power tree, Flash subsystem, Debug, …) so the agent reasons about functional blocks. The agent can ask for one net and learn which subsystem it belongs to and which schematic sheet covers it.

Attaching schematics and datasheets

The Lager Box is not a document store. It records pointers to your documents; the agent fetches and analyzes them with its own (vision-capable) tools. This keeps the box lean and lets the agent use the best tool for reading a PDF or board image. Attach a pointer without hand-editing JSON:
A document reference (DocRef) has: You must supply at least one of --url, --repo-path, --external-id or --external-url. When the MCP server loads bench.json, it skips a reference that has none of them and logs a warning.

URL vs. repo-path: which to use

For Google Docs, prefer an export URL over the editor URL — the /edit URL returns the JS app, not the content:
For a document that needs authentication, you have three options:
  • Share it with “anyone with the link.”
  • Give your agent a Google Drive connector or MCP server that holds the credentials.
  • Export it into your repo and use --repo-path.

Documents that are not in your project

The agent looks for a repo_path in your project root first. If the file is not there, it looks under ~/.lager_dut_docs/ at the same relative path. For example, the agent looks for docs/sch.pdf at ~/.lager_dut_docs/docs/sch.pdf. Keep that directory outside your project. lager python uploads the project directory, follows symbolic links, and refuses an upload larger than 20 MB after compression. A folder of PDFs in the project, or linked into it, can make every run fail.

How the agent uses it

Once authored, the context drives the whole agent loop:
  1. The agent reads lager://dut/overview.md and learns: “power-regression rig, STM32H7, flash + power-tree subsystems, schematic at docs/sch.pdf.”
  2. plan_firmware_test("flash driver", "exercise QSPI") returns a plan already scoped to the flash subsystem, with a pointer to schematic page 3.
  3. cite_schematic("flash_cs") returns just the refs for that net:
    The agent opens docs/sch.pdf at page 3 with its own file tools — no scanning the whole PDF.

Applying changes

The MCP server watches /etc/lager/bench.json, /etc/lager/saved_nets.json, and /etc/lager/box_id and auto-reloads when any of them changes on disk. So after lager dut edit, lager dut add-doc, or lager nets describe, agents see the new context on their next discover_dut(), discover_bench(), or lager://dut/overview.md request — no manual step required. You can also force a reload immediately, to confirm that a change took effect. A connected agent can call the box_manage tool with action="reload", or you can restart the box service.