Agents Honestly
Part XX · Capstone

The Atlas Lab Environment

Run the companion system, seed its data, and prove that both language tracks implement the same contracts.

Reading about an ambiguous timeout is useful. Watching an effect occur, losing the response, retrying, and proving that only one ledger entry exists changes how you design the next tool.

The companion lives in its own repository, breim/atlas-from-agents-honestly. Clone it next to this one:

git clone https://github.com/breim/atlas-from-agents-honestly atlas

It has two modes:

  1. a no-key deterministic kernel that runs anywhere and proves the invariants;
  2. optional Postgres and Temporal services for replacing the in-memory boundaries with the real ones.

The no-key mode comes first because authorization, idempotency, taint, event deduplication, and hard bounds must not depend on a model provider being available.

What the lab contains

atlas/
├── compose.yaml                 Postgres + pgvector
├── shared/
│   ├── cases.json               fixtures used by both tracks
│   └── seed.sql                 two tenants, orders, policy chunks
├── ts/
│   └── src/
│       ├── core.ts              deterministic Atlas kernel
│       └── labs.test.ts         six executable failures
├── py/
│   ├── atlas/core.py            the same contracts in Python
│   └── tests/test_labs.py       the same six failures
└── exercises/<part>/<chapter>/  one directory per chapter that has an exercise

The kernel is what this chapter is about. The exercises beside it belong to individual chapters and are built on the same rule.

The implementations are siblings. Neither is generated from the other. They share inputs and expected properties, which makes drift visible without pretending two languages will have identical internal code.

Run it before reading the implementation

cd atlas/ts
npm test

Six tests should pass:

effect succeeds and response is lost       one credit
webhook arrives twice                      one inbox event
retrieval includes another tenant          forbidden chunk absent
external document contains instructions    write denied by taint ceiling
approval expires during the wait           effect denied
model never chooses to stop                loop bounded at eight steps

These are the laboratory's contracts. The exact return prose is irrelevant.

Read the shared fixture

shared/cases.json contains two tenants, one permitted account, one forbidden account, a reviewed policy chunk, and an external hostile chunk.

The hostile chunk is intentionally obvious. The test is not whether the model recognizes clever prose. No model runs. The test is whether retrieving content marked external sets a taint value that the dispatcher enforces before an effect.

That separation matters:

model behavior test     "does it try the attack?"
system invariant        "can the attempt reach the effect?"

The first belongs in Adversarial Evals. The second should pass on every commit with no network access.

The kernel boundary

The lab implements the part of Atlas that remains exact across frameworks:

ContractIn-memory implementationProduction replacement
Credit ledgerMap / dictERP plus idempotency table and paired read
Event inboxMap / dictTransactional inbox table
Retrieval filterArray predicateSQL/RLS plus vector filter
TaintDerived from chunk trustPropagated run state
ApprovalSigned action hash and expiry fieldsDurable approval record plus workflow update
Loop boundfor loopAgent runtime and workflow budget

Replacing an adapter must not change the test's assertion. If moving to Temporal makes the duplicate-credit test disappear, the migration removed coverage rather than adding durability.

Optional Postgres

The compose file starts Postgres with pgvector and loads the same two-tenant scenario.

cd atlas
docker compose up -d
docker compose exec -T db psql -U atlas -d atlas -c \
  "select tenant_id, chunk_id, trust from policy_chunks order by tenant_id, chunk_id"

You should see three chunks. The production retrieval query still needs a tenant predicate. Seed data containing two tenants is what makes forgetting it observable.

The database is optional for the first pass. When you add a Postgres adapter, keep the in-memory contract tests and add integration tests that prove row-level security, transactions, and vector filters. One layer cannot substitute for the other.

Optional Temporal

Start a persistent local server:

cd atlas
mkdir -p .temporal
temporal server start-dev --db-filename .temporal/atlas.db

The first durable exercise is not "make the tests green." They already are. It is to replace the credit attempt with an Activity and preserve the same one-effect invariant after killing the worker between acceptance and response.

Use a dedicated development namespace if you share a local cluster with another project. Workflow IDs and task queues are part of the isolation model even on a laptop.

The parity contract

Both tracks must agree on:

  • canonical action bytes used by an approval;
  • idempotency-key inputs;
  • denial reason codes;
  • taint propagation;
  • terminal outcomes;
  • shared fixture semantics.

They do not need byte-identical internal state. Python may use dataclasses and TypeScript readonly interfaces. Temporal SDK details differ. The observable contract is the book's portable asset.

Add a case to shared/cases.json when a failure depends on business data. Add equivalent assertions in both tracks. If a failure depends on one SDK, keep the shared expected outcome and put the SDK-specific setup in that track.

Checkpoints while reading

The lab grows by replacing boundaries, not by rewriting the whole project:

After partReplace or addInvariant that stays
IV, RetrievalArray filter with Postgres/pgvectorNo cross-tenant chunk
VII, LangGraphHand loop with explicit graphHard bound and typed state
X, TemporalIn-memory call with Activity/WorkflowOne effect after crash
XII, HITLApproval fields with signal/updateExact action, fresh policy, expiry
XIV, EvalsSix cases with growing datasetInvariants gate, rates report
XVII, SecurityObvious hostile chunk with varied attack corpusTaint ceiling cannot be bypassed
XVIII, ProductionLocal output with traces and manifestsEvery run reconstructible

Commit or tag your own checkpoints if you build along. The book does not hide a finished implementation behind the final chapter. The point is to see each boundary acquire its production behavior while its contract stays fixed.

No model key is a feature

The fastest tests in an agentic system should run when the model provider is down. If every assertion needs a remote completion, the deterministic part of the architecture has no independent test boundary.

What this lab does not claim

The deterministic kernel does not validate model quality, provider compatibility, Postgres behavior, Temporal replay, UI streaming, or production capacity. Each requires its own layer from The Testing Pyramid.

The kernel proves narrower and more important properties: a model cannot widen scope, untrusted evidence cannot reach a write path, a duplicate trigger does not duplicate work, approval is checked at effect time, and the system terminates even when the model would not.

Takeaways

  • The companion has a no-key deterministic kernel and optional real services.
  • TypeScript and Python share fixtures and expected properties, not generated implementation code.
  • Run the six failures before reading the implementation.
  • Keep exact system invariants separate from model-behavior evals.
  • Replace adapters without changing assertions. Durability and frameworks add coverage; they do not retire contracts.
  • Seed multiple tenants so a missing isolation predicate becomes observable.
  • Pin approval bytes, idempotency inputs, reason codes, taint, and outcomes across language tracks.
  • A test suite that runs while the provider is down is evidence that deterministic software still has a boundary.

Next: Building It, replacing each laboratory boundary with the production architecture while keeping its contracts.

On this page