An initial prototype often puts the prompt, file access, retries, and final answer in one function. It is convenient until the model proposes a different path or a log contains an instruction to start a job. You need to know exactly which component may authorize an effect. In our design, a chooser proposes one action, the controller checks it, and a tool returns bounded evidence. A future model can replace the chooser without acquiring the controller's authority.
The chooser receives the goal, evidence, unknowns, and tool catalog. It may request searchlogs, readspec, getrunhistory, or stop. The controller validates the proposal, enforces step and evidence budgets, checks the deadline, detects repeated requests, and records events. The tool layer accepts specific typed arguments and maps exact identifiers to approved records. The handover layer presents evidence and unknowns without turning a stop request into a claim that a root cause has been proven.
A catalog is documentation for choosing, not an authorization mechanism. Even if a model is asked to produce JSON, its output must pass ordinary validation. Conversely, a Python Protocol describes what a chooser should implement but provides no runtime isolation. The starter's copy of state prevents accidental mutation through the supplied view. It is not a sandbox for executing malicious Python plugins; only trusted application code should implement the adapter and tools.
On its first turn, the scripted baseline requests searchlogs for reset_smoke in the approved R42 record. The controller checks the action shape, then the tool checks path, query, and limit. The result receives reference E1. Next, the baseline requests the reset_release specification section and the history. Three successful results become E1, E2, and E3. On turn four it requests stop. These choices follow a fixed sequence written by the author; no model has inferred a next step or diagnosed a bug.
Now imagine an optional model proposes readspec for lab/protected/design.txt after reading a suspicious log line. The same controller and tool boundary rejects that request. The authority does not depend on whether the proposal came from a script, a model, or a tired engineer's copied example. That stable boundary is why the architecture is useful before any provider is connected. It also makes model replacement an evaluation decision rather than a permission redesign.
Assign each responsibility to one component: rejecting a boolean limit, deciding whether history is useful, stopping after eight choices, and displaying E2's specification line. Then draw an equivalent assistant for comparing two STA reports. Keep the tool surface limited to evidence lookup; do not add an EDA command runner merely because the domain changed. Describe which component would reject an attempt to request a different scenario.
The tool validator rejects limit=True. A model chooser could propose another history read; the controller still checks budget and repetition. The scripted baseline makes no adaptive usefulness judgment.
This decomposition does not guarantee correct interpretations. It makes effects and records inspectable. The lab uses Python 3.12 standard-library interfaces; see Python 3.12 typing.Protocol for the structural interface mechanism. A real transport must additionally handle data approval, request limits, timeout enforcement, and provider-specific response parsing before it can satisfy the same chooser contract.