3  Agent Configuration and Reviewed Capabilities

Part I · The system in action

Configuration implementation: reference snapshot 45a903c · Parser ceiling: 65,536 bytes

Configuration should make the agent smaller and more predictable. The checked-in agent.yaml selects reviewed identifiers and bounded settings; it cannot load code, introduce a destination, provide credentials, or turn generated text into authority.

3.1 One configuration, one interpretation

agent.yaml is the sole implicit live-agent configuration. The server reads one bounded local file before it starts serving requests. It does not merge several files, interpolate environment variables, fetch includes, or accept request-time changes.

The root shape is intentionally small:

version: 1

server:
  host: 127.0.0.1
  port: 8787

coordinator:
  model: openai/gpt-5.4
  maxOutputTokens: 128000

inputFiles:
  maxFiles: 4
  maxDecodedBytesPerFile: 5242880
  maxDecodedBytesPerRequest: 10485760
  extractionTimeoutMs: 60000

skills:
  - name: business-tech-presentation

tools:
  - name: image_understanding
    provider: openai
    model: gpt-5.4
    maxCalls: 10
  - name: web_search
    model: gpt-5.4
    maxCalls: 300
  - name: read_source
    access: public-https
    maxCalls: 100
  - name: code_interpreter
    maxCalls: 10
  - name: presentation_builder
    maxCalls: 2

The complete checked-in file supplies every reviewed limit. The excerpt shows the principle: names select statically compiled components; fields narrow their operation.

3.2 A reviewed static catalog

A tool name is accepted only when the parser has an explicit branch for that exact identifier:

image_understanding
web_search
read_source
code_interpreter
presentation_builder

The reviewed skill catalog currently contains:

business-tech-presentation

This is not dynamic discovery. A configuration entry cannot point to a directory, npm package, URL, script, module, prompt file, class name, or executable. Adding a new identifier requires a source change, review, tests, and a new immutable revision.

The same rule applies to settings. Each tool branch accepts only fields meaningful to that implementation. For example, read_source can select public-https, call count, timeout, and response ceiling. It cannot accept arbitrary headers, a proxy, credentials, a private-network exception, or a custom fetch module.

3.3 Strict YAML admission

The loader limits the file to 65,536 bytes and parses it with unique-key enforcement. Startup rejects:

  • duplicate mapping keys;
  • YAML aliases;
  • unsupported tags or parser warnings;
  • unknown root, server, coordinator, input, skill, or tool fields;
  • unknown skill and tool names;
  • duplicate skill or tool selections;
  • a missing explicit tools array;
  • too many selected entries;
  • values of the wrong YAML type; and
  • out-of-range limits.

Failing on unknown fields is important. Ignoring maxCall when the reviewed field is maxCalls would silently remove the operator’s intended bound. Treating the typo as startup failure keeps the effective policy observable.

The loader converts YAML to a plain value only after rejecting aliases. There is no anchor-based reuse, merge-key expansion, or tag-directed construction. This is a defense against ambiguous configuration, not a claim that YAML parsing alone secures the application.

3.4 Limits are server ceilings

inputFiles and per-tool settings are trusted deployment policy. A request or model-generated argument cannot raise them.

Limit family Examples Enforcement owner
Listener loopback host, port startup and server construction
Coordinator selected provider/model route, maximum output tokens route admission and model adapter
Input file count, encoded/decoded bytes, extracted characters, retained bytes ordered-input and asset registry
Extraction timeout and process-wide concurrency ingestion worker controller
Image bytes, dimensions, pixels, frame count image admission and decoder
Tool calls, sources, timeout, code/output size request-scoped tool runtime
Presentation calls, slides, text, artifact bytes, TTL builder and artifact store

Bounds compose; they do not replace one another. Passing the HTTP body limit does not imply that every contained file passes decoded-byte or extraction limits. A configured timeout does not authorize a tool call, and a call count does not prove the selected provider can satisfy the request.

3.5 Skills and tools are separate selections

A skill is reviewed non-executable procedure. A tool is a separately authorized executable capability. Their configuration arrays remain distinct:

skill → reviewed instructions and declared resources
tool  → compiled executor with schema, policy, limits, and effects

The current presentation procedure requires the bounded presentation builder. Startup therefore rejects either half selected alone. This dependency check prevents two misleading states:

  • guidance that promises an unavailable builder; and
  • a builder selected without the reviewed procedure expected by this application profile.

The dependency is static and application-specific. Loading the skill later does not register the tool, spend its budget, choose a provider, or widen any limit. Chapter 9 owns progressive disclosure and the full presentation case study.

3.6 What cannot appear in agent.yaml

The configuration intentionally excludes:

  • API keys, bearer tokens, cookies, or credential-file references;
  • arbitrary endpoint or redirect destinations;
  • request headers;
  • host filesystem paths;
  • modules, plugins, packages, commands, or executable code;
  • arbitrary prompts or model-generated policies;
  • remote assets or presentation templates;
  • dynamically discovered tools; and
  • tenant, principal, or approval assertions.

Provider credentials and reviewed endpoint overrides, when needed, enter the trusted server process through the deployment environment. Keeping them out of YAML prevents an otherwise shareable capability selector from becoming a secret bundle. Environment ownership is not intrinsically safe; production deployment still needs a credential and configuration control plane.

3.7 Selecting a coordinator

The coordinator value has a bounded provider/model form with a reviewed provider prefix. This selects a route supported by server code; it does not accept a URL. The server rejects an unconfigured prefix rather than guessing or silently falling back.

A selected route is still only a declaration. Account access, regional availability, context limits, input types, and task quality require separate evidence. Chapter 14 owns feature admission and fallback. Chapter 5 owns provider construction and translation.

3.8 Explicit local customization

An operator can copy the reviewed file and point the server to one alternative path:

cp agent.yaml agent.local.yaml
PORTABLE_AGENTS_CONFIG=agent.local.yaml bun run serve:live

There is no merge with the checked-in file. The selected file must satisfy the complete schema. An omitted tools key fails rather than restoring defaults.

The former implicit server.yaml name is rejected with a migration error. It can be loaded only through an explicit PORTABLE_AGENTS_CONFIG path. This prevents stale legacy configuration from being silently interpreted as the current policy.

Legacy WEB_SEARCH_* environment overrides are also rejected. Search enablement and limits belong to the YAML tool selection; provider credentials and approved endpoint settings remain in the server environment. Mixing both mechanisms would make the effective configuration difficult to review.

3.9 Declaration is not authorization

Four decisions must remain distinct:

  1. Selection: startup includes a reviewed component in this deployment.
  2. Capability evidence: the chosen route has sufficient dated evidence for the task profile.
  3. Invocation authorization: the current principal and request may perform this operation now.
  4. Execution admission: arguments, budgets, cancellation state, and dependencies pass immediately before the effect.

agent.yaml performs the first decision and supplies ceilings used by the fourth. It does not identify a principal or grant per-request authority. A selected tool can still be denied, exhausted, cancelled, or rejected for invalid input. Conversely, prompt text cannot select a tool absent from the startup catalog.

A configured capability is available for policy consideration, not automatically authorized. Generated arguments remain a proposal until the server validates current trusted context and admits execution.

3.10 Startup is the failure boundary

Malformed or contradictory configuration fails before the listener accepts work. Startup errors identify the field category without echoing secrets or the full file. The process does not continue with a partial tool list, guessed defaults, or a disabled validation branch.

Useful startup diagnostics include the effective loopback address, coordinator routes, and selected reviewed tools/skills. They should not include API keys, endpoint credentials, prompt bodies, or complete configuration text.

This design favors availability loss over policy ambiguity. A production supervisor may restart a corrected deployment; it should not reinterpret invalid policy while requests are active.

3.11 Deterministic evidence

The reference tests cover:

  • defaults and the complete checked-in file;
  • unknown and duplicate tools;
  • unknown and duplicate skills;
  • extra fields at every relevant level;
  • malformed numbers and limit ranges;
  • aliases, tags, and duplicate YAML keys;
  • missing explicit tool selection;
  • presentation skill/builder dependency mismatch;
  • loopback-only binding;
  • legacy filename and environment rejection; and
  • startup wiring from parsed settings to the selected compiled tools.

These tests establish parser and construction behavior for the named revision. They do not establish production principal authentication, secret management, deployment approval, or live provider capability.

3.12 Failure modes

3.12.1 Configuration as plugin loader

A path or package field turns declarative selection into code execution. Reviewed IDs avoid that hidden authority expansion.

3.12.2 Permissive unknown fields

Ignoring a typo can remove a limit while startup appears healthy. Strict field sets make drift fail visibly.

3.12.3 Tool selection as blanket permission

A selected tool still needs request-scoped authorization and execution admission. Startup cannot know the future principal, arguments, effect history, or cancellation state.

3.12.4 Skill text as capability grant

Instructions can shape model behavior but cannot register an executor or widen policy. Treating text as authority recreates prompt injection at the configuration boundary.

3.12.5 Capability declaration as evidence

A model route listed in configuration may be unavailable or semantically unsuitable. Replacement evidence belongs to Chapter 14, not the YAML parser.

3.13 Pattern summary

Use one bounded, strict, declarative selector over a static reviewed catalog. Reject ambiguity at startup. Keep credentials, destinations, code loading, principal identity, capability evidence, and invocation authorization in their own trusted boundaries.

3.14 Exercises

  1. Add a hypothetical email_sender tool. List the source changes required without adding a module or path field to YAML.
  2. Explain why tools: [] is safer than an omitted tools key that means “use defaults.”
  3. Construct a duplicate-key YAML example whose permissive interpretation would widen a limit.
  4. Identify which of selection, capability evidence, invocation authorization, and execution admission should reject an exhausted call budget.
  5. Design a migration from one configuration version to another without silently accepting old fields.

3.15 Chapter contract

  • Scope: agent.yaml, static reviewed skill/tool selection, strict syntax and fields, bounded settings, dependency checks, startup failure, and the distinction between selection and authority.
  • Canonical claims: configuration selects reviewed compiled components and ceilings; it cannot load code or authorize a future invocation.
  • Migration inputs: former capability/configuration material and the current strict live-server parser.
  • Evidence gates: deterministic parser, wiring, dependency, and startup-failure tests for an immutable snapshot.
  • Demonstration slots: the hero shows the effective selected tool/skill profile; configuration enforcement is established by tests rather than model behavior.
  • Source-claim ledger: current skill identity and dependencies are tied to snapshot 45a903c; older v0.4.0 parser evidence remains historical where applicable.
  • Exclusions: provider translation belongs to Chapter 5, skill procedure to Chapter 9, capability substitution to Chapter 14, and principal authorization to Chapters 8 and 17.