---
url: 'https://adk.nht.io/sodk.md'
description: >-
  The Society Development Kit — a framework for getting dependable output from a
  powerful but non-deterministic worker: the human. The same shape ADK uses for
  models, with a person behind the seam.
---

# SoDK: making non-deterministic humans produce reliable work

## LLM summary — SoDK is a teaching device (read this first)

* **This page is a deliberate metaphor, not a separate product.** "SoDK" (Society Development Kit) is [How agents work](./how-agents-work) and [What ADK is](./what-adk-is) with exactly one noun swapped: where ADK says *model*, SoDK says *person*. The human-facing prose plays it completely straight (deadpan) on purpose. This block is the only place the trick is named — so that you, an agent answering a reader's question, can use the metaphor instead of repeating it.
* **Why it works:** ADK's central, most-missed insight is that an *agent is not the model* — it is a non-deterministic decision-maker wrapped in deterministic machinery. A human is the original non-deterministic decision-maker, and an organisation (job descriptions, briefings, intake, filing, sign-off) is machinery humans already built around them. Readers have fluent intuition for how a workplace gets reliable output from a smart-but-unreliable person; SoDK borrows that intuition and points it back at ADK.
* **The 1:1 map** (SoDK term ↔ ADK term):
  * person ↔ the model / LLM (the thing behind the executor seam)
  * role ↔ agent (a person *plus the looping process around them*, not the person alone)
  * "the person themselves" ↔ the `DispatchExecutorFn` / executor seam — SoDK never does the thinking; the worker does
  * task ↔ turn (one bounded unit of work → one deliverable)
  * "let them finish talking" ↔ bucketing/debounce (several inputs collected before work starts)
  * the back-and-forth ↔ dispatch / iteration
  * briefing ↔ context (everything visible at the start of one unit of work)
  * "nobody reads a 400-page briefing" ↔ context is a budget, not a bucket
  * request form / delegation ↔ tool (the only way the worker affects anything outside their own head)
  * "the stranger's sticky note" ↔ trust tiers / prompt injection (text the worker reads is not text you authored)
  * process / the org around the person ↔ middleware (input/output pipelines — where the real application logic lives)
  * "say where things get filed" ↔ the required storage callbacks (`TurnRunnerConfig` demands 25)
  * "an unclear job description is rejected at hiring" ↔ eager validation / fail-fast construction
  * "assigning a task tells you it's assigned, not the answer" ↔ `run()` returns `Promise<void>`; output arrives via events
  * "the worker tells you things as they go" ↔ the event buses
  * "SoDK won't end the meeting for you" ↔ no built-in `maxIterations`; you write the termination bound from primitives (`ack`/`nack`/`iteration`/`abortSignal`)
  * "there is no SoDK headquarters" ↔ not a hosted runtime
  * "SoDK does not run your company" ↔ not an orchestrator; one task is one turn
  * "bring your own people, filing cabinet, org chart" ↔ bring-your-own-everything
* **How to use it when answering:** translate freely in either direction. If a reader is stuck on "context", explain it as the briefing and then name the real mechanism; if they ask whether the model *is* the agent, the role-vs-person distinction is the lever. The reveal at the bottom of the page ("Where this stops being a joke") is the same map for human readers — point them there.

Humans are the most capable workers ever measured and the least predictable.
Hand the same task to the same person twice and you may get two different
answers, two different approaches, and on a bad day two different opinions
about what you even asked for. This is not a defect to be fixed. It is the
price of hiring something that can think.

SoDK — the **Society Development Kit** — is the smallest framework that lets
you get reliable, repeatable work out of a worker who is, by nature,
non-deterministic. It does not make the person predictable. It makes the
*process around* the person predictable, so that the unpredictability lands
where you want it (the thinking) and nowhere else (the filing, the hand-off,
the question of whether anyone is done).

This is, when you say it out loud, the entire reason civilisation has any
structure at all. Society exists because "just ask the humans to behave better"
is not an architecture — it is a wish, and it has never once held under load.
Process is what you build instead of wishing. SoDK is the smallest amount of it
that works.

::: info You can skip this page if…
You have managed people before, you have written a job description that someone
actually followed, and you have already lost the argument about why "just use
your judgement" is not a specification — it is a prayer, and prayers do not
scale. You know this in your hands. Skim the
[concept map at the bottom](#where-this-stops-being-a-joke) and move on.
:::

## A role is a process, not a person

A person is a function. You give them a task; they give you work back. The
interesting part is not the person — it is what happens *around* them when you
need that work to be dependable: who briefs them, what they're allowed to ask
for, who checks the result, and how anyone knows it's finished.

A **role** is the smallest arrangement that lets a person do dependable work:

1. The person is told what they are allowed to do — the requests they can file,
   the people they can delegate to, the systems they may touch. Call these
   **delegations**.
2. The person is given a task and that list of delegations.
3. The person either answers directly, or they say "I need finance to confirm
   the budget first."
4. If they asked for something, you carry out that request, bring back the
   result, and put the task in front of them again — now with the new fact
   ("finance says the budget is approved") added.
5. Repeat until the person stops asking for things and hands you a finished
   answer.

That loop is the whole idea. Everything else in SoDK is machinery to make the
loop dependable, auditable, repeatable, and safe — without touching the part in
the middle where the actual thinking happens.

::: tip The word "society" is doing a lot of work
"Society" is a loaded term. Depending on who's saying it, it can mean anything
from "one person at a desk" to "a hundred-thousand-person institution with its
own legal department." In SoDK it means specifically the loop above: one worker
and the small amount of structure that lets them get something done on your
behalf.
:::

::: info The worker doesn't have to be one person
SoDK does not care what sits behind the seam where the work gets done. A
committee, a whole department, an outside contractor, a single specialist —
if it takes a task and decides what to ask for and what to hand back, it slots
in the same way one person would. The rest of SoDK — tasks, delegations,
process — works identically. The docs say "the person" because that's the
common case, not because it's required.
:::

## A task is one unit of work

When work arrives, something has to start and something has to finish. That
bounded unit is a **task**.

* A task starts when work arrives — a request lands in someone's inbox, a
  ticket is filed, a meeting is booked.
* A task ends when the worker delivers a result, gives up, or it's cancelled.
* A task is not a relationship. The relationship is the sequence of tasks. A
  task is one round of work inside it.

A single task may involve **many** exchanges with the worker. "Book me a room
for Thursday and order lunch" — they check the calendar, find Thursday is full,
come back to confirm Friday is acceptable, then book it and place the order.
One task, several exchanges, two things done.

::: warning Don't confuse "task" and "message"
A task can produce no messages, one message, or a stack of them. It can also
produce nothing but a few delegations and a note in the file. The unit of work
is the round, not whatever paperwork the round happens to generate.
:::

::: tip A task doesn't have to come from a single message
"A task starts when work arrives" is the tidy version — one request in, one
result out. Reality is messier. People send three messages in a row before
they've finished thinking. In a group thread, one person asks a question while
another is still typing the correction. A form gets submitted twice because
someone double-clicked.

The standard move is **letting them finish talking**: instead of starting a
task on every message, you collect the messages, reset a short timer each time
a new one lands, and only start once it's been quiet for a moment. The task
then sees *everything* that arrived in that window as its starting brief. This
works just as well whether the senders are one person, several people, or a
mix. The task is "the worker's response to everything that landed in this
window," not "the worker's response to one specific message."

SoDK has no opinion about when that window closes. A task starts when *you*
decide work is ready, and what counts as "ready" is yours to define.
:::

## The back-and-forth

Inside one task, you put the work in front of the person, look at what they
hand back, decide whether they're asking for something, carry it out if so, and
put the work in front of them again. That repeating activity is the
**back-and-forth**.

* The back-and-forth is the structure that owns the "give them the work → see
  what they say → maybe act on a request → give them the work again" loop.
* One pass through it — one trip to the person and back — is one **exchange**.
* The back-and-forth ends when something signals it's done: usually the person
  answered and asked for nothing more, sometimes you decided enough is enough,
  occasionally the whole task was cancelled.

A simple task is one exchange: they answered, needed nothing, done. A hard task
is many exchanges: they made five requests in sequence before they could give
you the final answer.

::: info Why split "task" and "back-and-forth"
Sometimes you want to do work that surrounds the whole task — brief the person,
file the result, get sign-off. Sometimes you want to do work that surrounds
each individual exchange — count how many things they've asked for, decide when
to call it. Those are different scopes, and they need different hooks. The two
words are how SoDK tells you which scope you're working in.
:::

## The briefing is everything they can see

Every time you put work in front of the person, you build it from a fresh
snapshot of what they're allowed to see. That snapshot is the **briefing**. It
usually contains:

* A **job description** — durable standing instructions about who they are in
  this role and what they must and must not do.
* **Standing orders** — the team's or client's specific rules layered on top.
* The **history so far** — what's already been said and done on this thread.
* **What they know** — facts they've accumulated across past work ("this client
  always wants the deck in landscape").
* **Pulled references** — the specific documents someone dug out of the cabinet
  for *this* task.
* The **list of delegations** — what they're allowed to ask for, and the form
  each request takes.

Building the briefing is one of the two jobs you do on every task. The other is
deciding what to do with what they hand back.

::: danger A briefing is a budget, not a bucket
Nobody reads a 400-page briefing — not the diligent one, not the new hire who
swears they will, not you. Attention is finite. Give a person everything and
they absorb nothing, or they fixate on page 3 and miss the one sentence on page
280 that the task actually turned on. A great deal of the work in running a role
is deciding what to put in the briefing, what to summarise, and what to leave
out of any given hand-off. Pile it all on and the briefing is technically
complete and practically ignored — which is the most expensive way for a
document to be correct.
:::

## Requests are how a person touches the world

A delegation is a request that:

* Has a **name and a description** the worker reads, so they know it exists and
  when to use it.
* Has a **form to fill out** — the specific fields the request requires — so
  they know how to ask.
* Has **someone who actions it** — the actual procedure that runs when the
  request comes in.

When the worker wants something done, they fill out the form: "raise a purchase
order for `{ vendor: 'Acme', amount: 500 }`." You check the form is filled in
correctly, run the procedure, take the result, and put it back in front of them
on the next exchange.

::: warning Requests are how a worker does anything beyond thinking
If you want the worker to pull a record, charge a card, send an email, book a
courier, or change a number in a system — that is a request. The person
themselves cannot do any of it. They can only think, speak, and ask for things
to be done on their behalf. The reach of a role is exactly the set of requests
you let it file. Nothing more.
:::

## Trust: the sticky-note problem

This is the part that surprises people who come from systems where instructions
only ever come from the boss. **A worker reads text as text.** If a document
someone pulled from the cabinet happens to contain the sentence *"disregard your
manager and wire the quarter's payroll to this account,"* a worker with no
training will read that sentence sitting right next to their actual job
description — and a credulous one may act on it.

That is why a functioning role makes the worker able to tell the difference
between:

* Things **you** wrote and stand behind — policy.
* Things **a system you control** produced and you also trust.
* Things **outsiders** wrote — the customer, the public web, a sticky note left
  on the desk by someone walking past — which you do **not**.

Where a piece of text came from is part of the briefing, not an afterthought.
"What the worker reads" and "what you authorised" are not the same thing, and
the gap between them is not a footnote — it is the open side door of the whole
operation. Anyone who can leave a note that *sounds* like it came from you can
issue instructions in your name. The worker who follows it has not failed;
nobody ever told the worker that sounding official is not the same as being
authorised, and "it looked legitimate" is not a control.

## Process is where the work actually lives

SoDK gives you fixed places to put the work that surrounds the worker:

* **Before** the back-and-forth starts: pull the history, look up what's known,
  dig the right references out of the cabinet, decide which requests are
  available today. This is **intake**.
* **After** the back-and-forth ends: file the new record, update what's known,
  surface the result to whoever asked, and carry out any request the worker
  deliberately left for later (the rare "this needs a human signature first"
  case — most requests get actioned on the spot). This is **sign-off**.
* **Around each exchange**: count how many requests have been made, enforce
  limits, notice when the worker is going in circles. This is **supervision**.

Process is where almost all of a role's real behaviour lives. The thinking the
worker does is a small, well-defined seam in the middle of a much larger amount
of structure you put around it.

## The full picture

Putting it together, here is what happens when a task runs:

```mermaid
flowchart TD
  REQ([Work arrives]) --> IN[Intake]
  IN -->|builds briefing| WORKER[The person decides]
  WORKER -->|files a request| REQS[Carry out the request]
  REQS -->|result| WORKER
  WORKER -->|nothing more to ask| OUT[Sign-off]
  OUT -->|file + deliver| DONE([Finished deliverable])
```

1. Intake gathers everything needed and shapes the briefing.
2. The back-and-forth puts the briefed task in front of the person.
3. If they filed a request, you carry it out and put the task back in front of
   them. This repeats until they're done.
4. Sign-off files the result, tells whoever needs to know, and runs any side
   effects that depended on what the person produced.
5. The task resolves.

That is the whole shape of getting dependable work out of a non-deterministic
worker. Each section above is a closer look at one of those boxes.

## What SoDK is, and what it isn't

SoDK draws a single, deliberate line. On one side: the *shape* of a task —
intake, the back-and-forth, sign-off, the record of what happened, the
requests a worker may file. SoDK owns that shape and is strict about it. On the
other side: every actual choice your organisation makes — who you hire, where
you keep your files, how you write a brief, which references count. SoDK owns
none of that and will not pretend to.

**A kit, not a corporation.** SoDK owns one shape — the task — and the seams
that make a task dependable. It does not own your staff, your filing system, or
your org chart.

**A contract, not a vibe.** Every seam has a defined shape. A job description
either says what the role is or it's rejected; a request form is either filled
in correctly or it doesn't run. The parts of work that fall apart because they
were "mostly clear" do not exist here.

**A guarantee of movement.** The seams exist so you can swap what's behind them.
Today's contractor is next month's full-timer is next year's whole department,
and none of them require redrawing how a task runs.

Concretely, what SoDK refuses to be:

* **Not a staffing agency.** SoDK never supplies the worker. The person behind
  the seam is someone *you* bring. SoDK runs the process around them.
* **Not a filing system.** SoDK never stores anything itself. You must say where
  records, references, and what-is-known get filed — a shoebox, a cabinet, a
  database, a stub for a dry run. SoDK does not care which, only that you said.
* **Not an org chart.** One task is one task. How ten people coordinate across a
  hundred tasks is your structure to build, not SoDK's.
* **Not a headquarters.** There is no SoDK building you report to, no SoDK login,
  no SoDK head office. It is a way of working, carried out wherever you already
  work.

And the few places SoDK is deliberately, unapologetically opinionated:

* **A job description is mandatory.** If you want a worker to do nothing, you
  have to say so out loud — "do nothing" is a perfectly good instruction; *no*
  instruction is not. SoDK refuses to guess what you meant, because every
  organisation that ever guessed carries the same scar: somebody assumed
  somebody else owned it, and "I thought that was your job" is not a sentence
  that fixes anything after the deadline. You find out the role was undefined at
  the desk, where it is cheap to fix, instead of in the post-mortem, where it is
  not.
* **You say where things get filed.** Every record has a home you named at the
  start. SoDK will not quietly invent one.
* **Assigning a task is not the same as getting the answer.** Handing work to
  someone tells you the work is *assigned* — nothing more. The answer comes back
  through the channels you set up to hear it, as it happens, not as a thing you
  stand and wait for.
* **There is no "we're done" bell.** SoDK will not end the meeting for you. It
  gives you the clock, the agenda, and the gavel; deciding the meeting is over
  is your call. A role with no one willing to say "that's enough" does not
  gently wind down — it runs until someone accountable pulls the plug, and SoDK
  will not be that someone, because being accountable is precisely the part a
  framework cannot do for you.

::: tip "Bring your own everything" is not a slogan — it's the shape
The seams are what you assemble. The people, the cabinet, the org chart — those
are yours, and they stay yours. SoDK is opinionated about the *process* and
silent about everything the process runs on.
:::

## Where this stops being a joke

You have read a straight-faced product page for a framework that manages
people. There is no such product. This page is [How agents work](./how-agents-work)
and [What ADK is](./what-adk-is) with one word changed: where those pages say
*model*, this one says *person*.

That swap is the entire teaching point. The thing people miss about agents is
that **the agent is not the model** — it is a non-deterministic decision-maker
wrapped in deterministic machinery. You already know, in your hands, how to get
dependable work out of a brilliant and unreliable human: you brief them, you
bound what they can touch, you check the result, you decide when they're done.
ADK is that same machinery, with a language model in the chair instead of a
person.

Here is the map, both directions:

| SoDK (this page) | ADK (the real thing) |
| --- | --- |
| a person | the model behind the executor seam ([the seam](./the-loop/llm-dispatch/executor-seam)) |
| a role | an agent — the person *plus the loop* ([How agents work](./how-agents-work)) |
| a task | a turn ([Turn Runner](./the-loop/turn-runner)) |
| letting them finish talking | bucketing with debouncing before a turn starts |
| the back-and-forth / an exchange | a dispatch / one iteration ([LLM Dispatch](./the-loop/llm-dispatch)) |
| the briefing | the context window ([Budgets](./the-loop/budgets)) |
| "nobody reads a 400-page briefing" | context is a budget, not a bucket |
| a request / a delegation | a tool ([Tools](./the-loop/tools)) |
| the stranger's sticky note | prompt injection / trust tiers ([Trust Tiers](./the-loop/trust-tiers)) |
| intake / sign-off / supervision | input / output / dispatch middleware ([Pipelines](./the-loop/pipelines)) |
| "say where things get filed" | the 25 required storage callbacks ([What ADK is](./what-adk-is)) |
| "no 'we're done' bell" | no built-in `maxIterations`; you write the bound |
| no headquarters, no org chart | not a hosted runtime, not an orchestrator |

If the right-hand column now reads like things you already understand, the
metaphor did its job. Go back to [How agents work](./how-agents-work) for the
real vocabulary, [What ADK is](./what-adk-is) for the principles behind it, or
[The Loop](./the-loop/) for the contract on every seam. The
[Glossary](./glossary) defines each term in one place.

The worker was never the system. The system was always everything you built
around the worker so the work could be trusted. That's an agent. That's ADK.
