Skip to main content
    All shows

    Tuesday, November 3 · 27 min

    Build It So It Holds

    0:00-:--
    Speed

    Transcript

    Koko: Here is the one thing that separates a prompt from a system: a prompt is a request. A system is a contract. And until you can read that contract out loud and have it answer eight specific questions, you do not have a system — you have a very confident wish.

    Chris: That distinction does real work. I've sat in delivery reviews where the whole design lives in a single system message and nobody has asked what the completion condition is, let alone written one down.

    Koko: Right. So let's build this from the inside out, because the layers matter. Innermost: the model itself. Around it, the instruction contract — what most people call the system prompt, but it's more than wording. Outside that, the context assembled for each individual call — the documents, the history, the data pulled in at runtime. And holding all three: the harness. Tools, schemas, loop bounds, hooks, state management, error handling. That's the fourth layer, and it's where a system is actually made.

    Chris: So prompt engineering is the second layer, context engineering is the third, and harness engineering is the fourth. Those are three different disciplines sitting inside what people usually just call 'the AI.'

    Koko: Exactly. And conflating them is how you end up tuning the wording of a sentence when the real problem is that the harness has no retry logic. Now — the instruction contract. Eight fields. Role and scope, the outcome and its target, the evidence it may use, the prohibitions quoted verbatim from the policy, the thresholds it must honor, the tools it may call, the output contract, and the completion condition. Miss any one of those and you have a request, not a contract.

    Chris: Let's make that concrete. Walk me through the invoice-matching case.

    Koko: Good. Procurement team, invoice-matching assistant. Role field: names the organization and the specific queue — not 'an assistant' but this queue, this team. Outcome field: matched invoices released within the agreed number of days, at a stated exception rate — the actual number from the case. Prohibition: the policy sentence itself, copied in, not summarized. 'No release above the approval threshold without a named approver.' Not 'check for approvals' — the actual sentence.

    Chris: Because paraphrasing it is changing it. The model follows the version you wrote, not the version in the policy document.

    Koko: That's the mechanism, yes. Then: thresholds from the case, the tools it may call, the output contract — a schema — and the completion condition, which says what done looks like so the loop has somewhere to stop. Now here's what I want you to notice. Read those eight fields out loud for any real client and seven of them are the client's. The outcome, the prohibitions, the thresholds, the evidence sources — those come from the business. One field is the engineer's: the output contract, the schema. That ratio tells you where the design work actually lives.

    Chris: The schema is the one field that's structurally the same across organizations. Everything else is specific.

    Koko: Exactly. Which brings me to the analogy that makes this stick. Think about the difference between telling a contractor 'make the kitchen nice' versus handing them an actual brief. The brief names the room, the budget, what may not be touched, what done looks like, and who signs it off. 'Make the kitchen nice' is a wish. The brief is a contract. The instruction contract is the brief.

    Chris: And the contractor can't be blamed for a wrong result if all they had was the wish.

    Koko: Correct. So the instinct to carry into the room: when you're reviewing a design, ask someone to read the eight fields out loud. Not describe them — read them. If any field is missing or if a prohibition is paraphrased rather than quoted, stop there. That's the gap.

    Chris: The version of this I keep seeing in architecture reviews is teams treating the schema as the whole of validation. The schema passes, so the output is good.

    Koko: That's a real failure mode. A response can match the schema perfectly — every field present, every type correct — and be wrong in every value. Shape is not meaning. So validation is layered: shape first, then meaning, then consequence. And every deterministic check runs before any judgment-based one, because a deterministic check is essentially free and it fails closed. Let the schema catch the missing field. Then do the work of checking whether the numbers are right.

    Chris: Fails closed. That's the key property — a failed deterministic check stops the action. A failed judgment call might not.

    Koko: Which is exactly why you run the cheap certain ones first. The second failure mode is the paraphrased prohibition — and this one is subtle because the contract looks complete. All eight fields are there. But the prohibition field says 'ensure approvals are in place for large releases' instead of copying the actual policy sentence. That is now nobody's policy. The model follows what you wrote. If what you wrote is softer than the policy, the system is operating outside the policy and no one has flagged it.

    Chris: Quote it, don't summarize it.

    Koko: Quote it. Every time.

    Koko: Here is the mental model that changes how you debug. Context is not a bucket you fill. It is a supply chain with six distinct components: the instructions, retrieved knowledge, user and session state, tool results, examples and procedures, and the working memory of the run.

    Chris: And each one has its own answer to the same set of questions — where it came from, how it was selected, how fresh it is, what permissions gate it.

    Koko: Exactly. Plus what provenance travels with it, and how it gets compacted when the window fills. Six components, six questions each. That is the supply chain.

    Chris: The provenance piece is the one I see teams skip. They retrieve a chunk, use it, but nothing about where it came from or when it was written actually follows it into the response.

    Koko: Right, and that matters because the answer the model gives is only as trustworthy as the weakest link in the chain that fed it. So here is the worked example. Picture a policy assistant answering leave questions across multiple jurisdictions.

    Chris: Already a hard problem before you write a single prompt.

    Koko: Three supply-chain questions hit you immediately. First, the retrieval boundary — does the system allow employee-relations case notes to reach this assistant, or is that a permissions wall? Second, freshness — is last quarter's leave policy still being cited as if it is current? Third, compaction — in a long session, does the window quietly discard the one jurisdictional constraint that the user stated at the very start?

    Chris: That compaction one is brutal. You gave the constraint, the model acknowledged it, and forty turns later it is gone.

    Koko: And no prompt rewrite fixes it. You need a compaction rule that preserves anchors. Which brings us to the deletion test — the cleanest diagnostic tool in the kit. Remove one component, re-run your evaluation set. If nothing moved, that component was never context. It was just weight.

    Chris: I love that as a discipline. It forces you to justify every piece of what you are putting in the window.

    Koko: The analogy I use: think of a restaurant. The menu is the prompt. But what actually reaches the plate depends on the suppliers, the cold chain, who is allowed in the walk-in refrigerator, and what gets thrown out at close. You can rewrite the menu every night. If the lettuce supplier stopped delivering fresh stock three weeks ago, the salad is still bad.

    Chris: So the instinct is — before you touch a single word of the prompt, locate which layer of the supply chain produced the bad output.

    Koko: That is exactly the takeaway. Most persistent failures are supply-chain failures wearing a prompt costume. The fix is a boundary change, a refresh policy, or a compaction rule — not a sentence rewrite. When output quality disappoints, locate the fault on a layer first.

    Chris: You mentioned permissions gating a component. How does that interact with configuration? Because in practice there are multiple places where behavior can be set — the platform, the org, the workflow, the session, the individual request.

    Koko: That ordering is not arbitrary. The platform sets a floor. The organization's policy sits on top of that. Then the workflow. Then the session. And only then the individual request. Each layer can narrow what the layer below it permitted. No layer can widen what the layer above it closed.

    Chris: So if the org policy says this assistant cannot surface compensation data, a session-level instruction that says 'actually, do show it' cannot override that.

    Koko: Cannot and must not. The session instruction is simply out of scope for that decision. The hierarchy exists precisely so that a request at the bottom of the stack cannot undo a governance decision made at the top.

    Chris: The version of this I keep seeing on teams is people treating all configuration as equal — so they try to patch a platform-level constraint by writing harder in the system prompt, and then they are confused when it does not work.

    Koko: That is the misconception: that more forceful downstream instruction can compensate for a constraint set upstream. It cannot. The constraint is not a suggestion competing for attention — it is a floor. The fix, if the constraint is genuinely wrong, is to raise it with whoever owns that layer. Not to outwrite it.

    Chris: Which also means you need to know where in the stack a behavior is actually being set before you decide who needs to change it.

    Koko: Exactly. And that connects back to the failure-shape discipline. The failure playbook has eight shapes, and exactly one of them is answered by a retry — the transient one. The other seven are budget, permission, safety, a schema break, a stale read, a wrong tool, and a run that finished without actually producing the outcome.

    Chris: And retrying a permission failure just gives you a second permission failure and a log that looks like the system is persistently broken.

    Koko: Worse — it can look like the system is trying to force something past a constraint, which is a governance red flag. Name the shape first, then choose the verb. Permission failure means you go back up the stack and have a conversation about access, not about retry intervals.

    Chris: So the instinct coming out of this whole module is: before you rewrite anything, name the layer and name the shape.

    Koko: That is it. Layer first, shape second, fix third. In that order, every time.

    Koko: So the harness has six layers, and the model sits inside exactly one of them. Everything else — tools, retrieval, identity, policy — lives outside the model and around it. And that framing changes how you think about tools, because a tool is not a function call. A tool is a product. It has a name, a purpose, an input schema, an output schema, declared permissions, a cost, defined error behavior, and a consequence class — meaning you know upfront whether a call is reversible or not.

    Chris: The consequence class is the one I see teams skip. They define the schema and move on. But whether an action can be undone is a design input, not something you figure out after the incident.

    Koko: Exactly. And consequence class is directly connected to the least-privilege argument — which is not a security nicety here. It is a reliability feature. A tool that can only do one thing cannot be talked into doing another. The failure space is smaller because the permission space is smaller.

    Chris: So scope restriction buys you a smaller blast radius before you even think about what the model might do.

    Koko: Right. And here is the worked example that makes this concrete. Say you have a deductions queue — customers dispute a charge, someone has to write off the deduction. You could give the agent one narrow tool: it takes an identifier and an amount, and it has a hard ceiling baked into the code. Anything above that ceiling gets refused before the model is ever consulted. Now compare that to the tempting alternative: one tool that can update anything in the ledger. Same agent, same prompt. Which one does the controls team sign off on?

    Chris: They answer immediately. The narrow one. Because the wide one means the approval conversation is about whether they trust the prompt, and nobody in controls trusts a prompt as a control.

    Koko: Nobody should. The analogy I use is a valet key. It starts the car, it opens the driver's door. It does not open the glove box or the trunk. And that property holds regardless of whether the valet is honest or not. You did not design it to rely on character. Same principle: the authority chain runs from the named human, through the workflow, to the identity the tool sees. Never from the model.

    Chris: So the model is never the authorizing party. It makes a request; the deterministic layer decides whether that request is in scope.

    Koko: That is the takeaway to carry into the room. Security, authorization, approval, policy — all of it lives in deterministic code outside the model. The gap between what a model could do and what the design permits is closed by identity and code. Never by wording. Decision rights, which we mapped in part one, are the columns in your design. The tool contract is where those columns become real.

    Chris: Let me press on retrieval for a second, because I see it treated as infrastructure — you bolt on a vector store and call it done. What does designed retrieval actually look like?

    Koko: It means you chunk documents along their own structure, not by arbitrary character count. You search by meaning and by exact terms simultaneously — account codes, for instance, need exact match, not semantic approximation. You rerank the candidates. And critically, you filter by the caller's permissions when passages are fetched, not after the answer is written. A passage a user is not allowed to see should never enter the context in the first place.

    Chris: Because if it enters the context, it can leave in the answer.

    Koko: That is exactly the reason. Whatever is in the window can appear in the output. So post-answer filtering is not a control; it is a hope. You also date every passage, and you measure the retriever independently — so when something goes wrong you can tell whether the passage was missing or whether it was there and misread. Those are different problems with different fixes.

    Chris: And retrieved text is evidence, not instruction. That framing matters for how you write the system prompt around it.

    Koko: It matters for everything downstream. Now, the same enforcement logic applies at the tool gateway. One gateway, every call: checks identity, checks scope, checks amount. It issues short-lived credentials so no secret ever has to enter the context window. And if the agent is driving a screen — browser automation, RPA-style — that is your widest blast radius. Isolated session, allowlisted sites, and a person confirming before anything is submitted or paid.

    Chris: The version of this I keep seeing on teams is the agent that drives a UI gets treated as lower risk because it looks like a human doing clicks. But it can move faster than any human and it has no fatigue-based hesitation.

    Koko: Which is exactly why it needs the most friction before a write, not the least. Okay — and here is the failure mode, because it is a plausible one. The wide tool with the careful prompt. The tool can update anything in the ledger, but the prompt says to be careful, to only touch deductions, to check before acting. That sounds like a reasonable middle ground.

    Koko: It is not. Every word after 'anything' is a request. A request to a model, not a constraint on a system. There is no ceiling in code. There is no named approver in a contract. The first of eight critical control gates at this stage is that no write path exists without a contract that names its ceiling and its approver. A prompt does not satisfy that gate. A well-worded prompt really does not satisfy that gate.

    Chris: So when you are in the design review and someone says 'we handled it in the prompt,' that is the signal to go back to the tool contract and ask where the ceiling is written down.

    Koko: That is the instinct. Prompt as policy is not policy. The valet key does not work because the valet was told to behave.

    Koko: Two protocols, two jobs. One connects a model to tools — think: the model reaches for a function, gets a result back, keeps going. The other connects agents to agents — one agent hands control to another. They are not interchangeable, and the moment you treat a tool like a colleague you have jumped a rung you haven't earned yet.

    Chris: The way I frame it to teams: a tool has no memory, no plan, no authority — it just executes. An agent has a loop. That loop is the difference.

    Koko: Exactly right. And that loop has five steps: observe, decide, act, check, continue. Every iteration, in that order. What makes it trustworthy is that there is exactly one enforcement point — the hook. The hook runs before and after every action. It is deterministic, it can block, and it is where you generate the evidence that proves what happened.

    Chris: So the hook is doing two things at once — it's the guardrail and the audit trail.

    Koko: That's the right way to hold it. The model reasons; the hook enforces. Those are separate jobs and they stay separate. Now, patterns. They map onto a ladder. A single model call sits at the bottom. Above it, a fixed workflow — steps in code, maybe one model call in the middle. Above that, a bounded loop — the model decides what to gather next, but there is a ceiling on iterations and a hook on every write. And only at the top do you get the manager mode and handoff mode. The manager keeps the plan and delegates. A handoff passes a six-part packet and releases control.

    Chris: The six-part packet matters a lot in practice. What's in it?

    Koko: Goal, context, constraints, the work done so far, the decision authority being transferred, and the return address — where to send the result. Every field has to survive the boundary. If one field drops, the receiving agent inherits an incomplete picture.

    Chris: Let me give you the concrete case. Same problem — a deductions review. Built as a fixed workflow: three steps in code, one model call in the middle to assess the evidence. Cheap to build, easy to test, ships in weeks. I've done this version. It works for eighty percent of what you'd reach for a loop to do.

    Koko: And the bounded loop version? The model decides which evidence to gather next, iteration ceiling, hook on every write. That version is right only if the fixed workflow measurably fails the evaluation. And that is the collapse question — the one every multi-agent design has to answer before it adds a rung: what would this lose if it were one agent? If you cannot answer that concretely, you haven't earned the step up.

    Chris: The version of this I keep seeing on teams is they answer that question with 'it feels more flexible' and then they're managing three agent identities, three context boundaries, and three places a handoff can lose a field.

    Koko: Which brings me to the analogy — a kitchen brigade. The head chef keeps the plan and calls the passes. A handoff is a plate leaving one station for the next, with everything the next cook needs already on it. And nobody adds a station because it looks impressive. You add a station because the current one is the bottleneck.

    Chris: Start one rung lower than feels natural. Climb on evidence.

    Koko: That's the takeaway, word for word. Every added agent is another identity, another context boundary, another place a packet can lose a field. The pressure in the room is always toward the fancier pattern. The instinct to carry in is: what rung have I actually earned?

    Chris: The failure mode I see follow right behind that pressure is the unbounded loop. No ceiling on iterations. It runs, it narrates progress the whole time, and it looks productive — right up until the budget is gone.

    Koko: And the only reason it didn't act on iteration forty is the hook at the edge. That's what kept it from doing something consequential on stale or contradictory state. Remove the hook, or forget to set the ceiling, and you have no enforcement point at all. The second failure is quieter: the handoff that passes a summary instead of the packet. The receiving agent gets the conclusion and none of the constraints. It proceeds confidently on an incomplete picture, and nothing in the loop catches it because from the loop's perspective, the handoff completed successfully.

    Chris: A summary feels like enough until the next agent needs to know why a constraint exists, and that's exactly the field that didn't make it across.

    Koko: Right. The packet isn't overhead — it's the contract. Skip a field and you've just made an undocumented assumption at a boundary where assumptions are the most expensive thing you can leave lying around.

    Koko: Alright, last one. And I want to do this one right, because it is the thing that ties every earlier decision to a real-world consequence. We have been building toward a run — an actual execution of an agentic workflow — and a run has explicit states. Not vibes. States.

    Chris: And two of them are terminal. That is the part I think people underweight when they are first designing these.

    Koko: Exactly right. So let's name all of them. A run is created. It runs. It waits — for a human, for a tool, for a clock. It resumes. And then it either completes with the outcome, or it stops without it. Those last two are your terminal states: completed with outcome, stopped without.

    Chris: And waiting is not a failure. That is the one I keep having to say out loud on teams — a run that is parked waiting for a named approval is behaving correctly.

    Koko: It is behaving perfectly. And when it resumes — after the approval comes in, after the platform restarts underneath it — it resumes from where it stopped, not from the beginning. That is the whole point of durable execution. The state is persisted. The run remembers where it was.

    Chris: So let's walk the actual pipeline, because this is where it clicks for me. Procurement invoice, end to end. Five stages.

    Koko: Let's do it. Stage one: intake. Reads the document into the schema. Structured, typed, ready for the next stage to reason about. Stage two: matching. Compares the invoice against the purchase order and the goods receipt. Stage three: assessment. Decides whether the invoice clears the defined thresholds — amount, terms, tolerances.

    Chris: And if it does not clear — or if it is above the ceiling — stage four is approval. Routes to the named approver and waits. That is the wait state, right there.

    Koko: Correctly parked. And stage five — only stage five — is the consequential action. The one write. The release. And after the write succeeds, you notify. Not before.

    Chris: Notification is the last thing in the sequence. Every stage before it has a contract, the write has a ceiling, and the whole run can be resumed at any stage.

    Koko: Here is the analogy that makes this stick for me. Think about certified mail. A letter is not lost just because the recipient was out when the carrier arrived. It is held. It gets signed for when the person shows up. And there is a record of every hand it passed through. A durable run is the same — held, not lost. Resumed, not restarted.

    Chris: That record-of-every-hand piece is doing a lot of work. Auditability is built into the structure, not bolted on afterward.

    Koko: Which brings me to the takeaway I want you to carry out of this module — and honestly out of this whole half of the course. Design the two terminal states before you design the happy path. Before you think about what success looks like, define what stopped without the outcome looks like. What does the system report? What state is it in? Who knows?

    Chris: Because a system that cannot say stopped without the outcome will report every failure as a success in a different shape. It just looks like a completed run that somehow produced nothing.

    Koko: And now the failure mode, and this is the one I want to close on because it is so plausible. Notification before the action. The version of this I keep seeing deployed is: the message goes out saying the invoice was released, and then the write happens. And when the write fails — because writes can fail — every downstream reader now believes something the ledger does not contain.

    Chris: The notification is the promise, and you made the promise before you kept it.

    Koko: That is the exact shape of the error. Notify after the write confirms. Never before.

    Chris: Alright. So let's say what this part of the course leaves you with. You have an instruction contract — how to write a prompt that holds up. A context map — what to include, what to trim. A tool contract for every write. A pattern chosen one rung below instinct. And now a run lifecycle with exactly two ways to end.

    Koko: And Part Three is where a listener proves any of it is true — that is where testing, evaluation and trust enter. But before you go there, everything that supports this lesson — the method, the prioritization gates and the scoring model, the workflow moves, the sorting lab — all of it is on the course page at KokoAI Academy, at koko knows dot A I. Take a breath, revisit the pipeline, and bring one of your own cases to it. You have the structure now — use it.