config.yaml. The Agent Card owns public identity, and pyproject.toml owns dependencies.
Fix folder validation errors
Managed feature folders are configuration, not general storage. Harnest checks the files it finds there so that a misplaced file or unfinished declaration does not silently disappear from your agent. Messages for misplaced files and missing declarations name the problem file, then explain What Harnest expects and How to fix it. Keep an active feature in its required format. For a note, backup, or unused example in a discovery folder, add_ to the filename or move it outside that folder.
An underscore prefix leaves an unused entry out of automatic feature discovery; it does not repair or activate its code. Follow each generated example’s destination and declaration instructions when enabling it. Put reusable Python helpers in
lib/. The importable lib/ and models/ namespaces are different from feature discovery: underscore-prefixed Python modules can still be imported. Links to files or folders are still subject to Harnest’s symlink restrictions.
See generated examples and Sandboxing for feature setup.
config.yaml
config.yaml selects the entrypoint, framework, authoring mode, Python runtime, environment, secret references, and permissions. harnest init never generates spec.resources or spec.scaling; existing blocks are silently ignored:
adk or langgraph. Managed mode is the portable default; advanced mode accepts a native framework target. See ADK and LangGraph. Unknown fields and invalid deployment values fail before authored Python loads.
interfaces.cli: true explicitly enables harnest run and the compiled
launcher’s run command. Omit it for a server-only artifact.
Configure workload CPU and memory under resources, and instance counts under replicas, in harnest-deployment.yaml. Existing spec.resources and spec.scaling blocks have no effect. Harnest silently ignores their contents, including empty, null, or invalid values, and leaves the source file unchanged. The standalone development server does not provision infrastructure, inject secret declarations, scale replicas, or enforce network permissions.
Configure a model
Choose the model and endpoint, supply local or deployment credentials, and configure eval model reuse.
Retired resource and scaling fields
You can remove these ignored blocks fromspec when cleaning up an existing project. Configure any limits you need explicitly:
The old timeout and concurrency hints did not override standalone server settings. Review the behavior you want instead of copying every old value. Omit HTTP settings that match the defaults. These ignored blocks do not block
harnest upgrade and do not supply defaults to Studio deployment discovery.
Server settings in config.yaml
The optional root server: section controls the standalone bind, remote-bind consent, request timeout, concurrency, request-size limit, and playground. Omit the section to use all defaults, or specify only what you want to change:
config.yaml
live for HTTP/SSE only. Exact ${NAME} values are resolved and type-checked at startup. Authentication, persistence, TLS, secrets, and scaling do not belong in this section. Set explicit HTTP limits with server.http.requestTimeoutSeconds and server.http.maxConcurrentRequests; omit settings that match the defaults. See Server configuration for defaults and legacy server.yaml migration.
agent-card.yaml
The Agent Card supplies public discovery metadata and declared capabilities. Compilation validates and copies it into the artifact. The server exposes the card at /.well-known/agent-card.json and includes its identity and route links in GET /agent. Declare an A2A interface here when you want to serve the agent through A2A.
pyproject.toml and harnest-runtime.lock
Declare only agent-owned provider, tool, and ordinary Python dependencies in pyproject.toml. Do not declare Harnest, ADK, LangGraph, LangChain adapters, or other Harnest-owned framework packages. Each Harnest release supplies and checks a compatible framework version.
Synchronize the project environment and commit the resulting lock:
runtime profile resolves the embedded release wheel, selected
framework, project and Harnest Extension dependencies, optional task runtime,
and every transitive dependency into harnest-runtime.lock. Every distribution
is hash verified. It does not install evaluation packages. ADK or LangGraph MCP
adapters join the solve only when an active mcp/*.py exists in the agent tree.
Development tools use independent profiles and locks:
harnest-development.lock. The eval profile
adds pytest plus Google ADK’s evaluation dependencies and writes
harnest-eval.lock. harnest serve, harnest run, and ordinary harnest test
share development; harnest test --evals selects eval. Commit each lock used by CI. Development/eval locks are not
copied into deployable artifacts and do not change the deployable source digest.
The generated lock replaces machine-local wheel paths with a release marker, so
it can be reviewed and committed without recording a developer’s filesystem.
The environment lives under AGENT_DIR/.harnest/environments/ and should not
be activated. An explicit sync creates or updates AGENT_DIR/.venv as an
IDE-detectable link to the current environment. Harnest preserves an existing
.venv that it does not own and prints the exact managed interpreter instead.
compile selects the lean production runtime; run, serve, and ordinary
test select development; test --evals selects eval.
Each command synchronizes its internal environment automatically without
changing the IDE link and leases the selected
environment for its complete lifetime. After a replacement is published,
Harnest removes older unleased fingerprints asynchronously; overlapping tests,
compiles, and servers retain their environment until they finish. CI can
require a current committed lock without resolving or changing it:
harnest.lock
harnest.lock records the project schema and the exact framework distribution installed by harnest env sync. A new scaffold starts with the schema only; synchronization adds the resolved version:
harnest.lock
framework entry and run environment sync again, then review and commit the new pin. Changing the selected framework in config.yaml followed by normal sync records the new framework; frozen sync rejects that change. Project schema migrations use harnest upgrade and preserve the framework pin.
Harnest’s CI exercises both framework adapters and the shared evaluation engine against pinned, minimum-supported, and latest-compatible dependencies on Python 3.11 and 3.12, on pull requests and daily. harnest.lock records the selected framework; harnest-runtime.lock remains the lean deployment resolution, while development and eval tooling stays in its own locks.