Context Engineering Series · Part 10 · The Capstone

Salesforce Is the Harness

Nine parts built a harness on local tools, my own proof of concept beside the platform, and what it really gave me was a short list of the controls an agent needs once it's doing real work. Part 10 takes that list back to Salesforce, where almost every control I taught the harness already has a home, most of them generally available, and I built one governed agent on those native primitives, running for real in an org, to prove the mapping holds.

Parts 1–9 → native Salesforce primitives

What Nine Parts Actually Produced

If you're an SE or an architect landing on Part 10 cold, I'd guess you mostly want to know whether nine parts of me building a harness on local tools turn into anything you could put in front of a customer. The question I was chasing across all ten parts was what decides whether you can hand an agent real work and trust what comes back, and the models never settled it for me, even though they keep getting better every few months, faster and cheaper and a little unsettling. Trust kept landing on what's wrapped around the model, starting with what you feed the agent and what you forbid it, then the checks that catch it when it's wrong and who's allowed to change those checks (that one comes back later, because the platform still doesn't cover it natively), and whether it can improve itself without slipping the leash, and I'd keep all five. That wrapper is what I've been calling the harness, and I think of it the way an operating system sits around a CPU.

I built it as a scaffold to the side of the platform on purpose, since that was the fastest way to learn which controls actually matter once an agent is doing real work, so Parts 1 through 9 are a proof of concept, a reduction to practice with local tools, and they should be read that way. What came out the other end of Part 9 was eight controls, and each one has its own row in the map below. The agent gets the least authority that does the job, and anything it reads in a record is data it never takes as an instruction. Every write waits for a human. It has to show its evidence and there's a held-out eval that's allowed to fail, which mine did in the Part 10 build before the fix, and the model stays swappable while every step gets recorded. The eighth, handing work from one agent to another, is the pattern Part 9's loop ran on, a bigger model handing the build to a smaller one. That list is the part of the series I'd want you to keep, more than any of the code I wrote to get there.

Most of it carries over, and the version a customer would run gets it from generally available Salesforce. You build on Agentforce agents and subagents, the swappable model turns into one line of model_config per subagent, and Bring Your Own LLM covers a model from your own provider account. Tools come in as agent actions and MCP tools, the agent works within its own permissions, the Trust Layer is there around the model calls, and session tracing on Data 360 is where every step gets recorded. Two more GA pieces, batch generation from prompt templates and Digital Wallet for what the work costs in credits, cover the multi-model run I map further down. When I went back through the controls I'd built by hand, every one but one turned out to have a place it wanted to live in the platform, and the exception is custody of the safety layer itself, the owner-held control over who gets to change the checks, which has no native equivalent yet. Keeping sensitive data on models inside Salesforce's trust boundary has a home too, it's a set of native parts you put together instead of one setting, and how those parts fit is my reading of the docs, I haven't run that assembly end to end.

Interactive · the map

Where Each Control Lives in Salesforce

Each control sits next to the native Salesforce primitive that carries it, in roughly the order a request touches them, and clicking a row opens a panel with where it lives and what it does. I checked the badges in September 2026 and re-checked the rows I changed on October 2, 2026, and most are GA. The judge from another lab is GA through the API but its Testing Center screen is in beta, and keeping sensitive data on models inside Salesforce's trust boundary is something you assemble from GA parts, there isn't one primitive for it, so the badge on each row tells you which status you're reading.

the front door (Slack)available
orchestrate + delegateGA
swap the modelGA
tools the agent can callGA
least authorityGA
keep sensitive data on in-boundary modelsassembled
injection defenseGA
egress through links in responsesGA
human-gated actionGA
evidence / groundingGA
observability / the recordGA
what each call ran on and costGA
the eval that can failGA
a judge from another labGA via API
autonomous improvementbeta
custody of the safety layerno native yet
Select a control to see where it lives in the platform.

I checked every badge against the Salesforce and Slack documentation before it went on the page, and I re-checked the rows I changed against those docs on October 2, 2026.

The front door on the platform, the first row on the map, is the Slackbot MCP client, which Slack's help center listed as available on all plans when I looked in late September 2026. A developer adds an MCP server to a Slack app, and once the app's installed Slackbot can call that server's tools. In my harness Slackbot is meant to be exactly that door, the one node that calls in over MCP instead of being called, and the link isn't wired on my side yet, my own MCP server passes its tests but isn't registered in a workspace. The auth is where it got messy, because my server checks Slack's signed requests, with a static token I keep for local tests, and MCP for Agentforce accepts only OAuth client credentials or no authentication, so the server's authentication would have to change before Agentforce itself could call it.

Tools and orchestration map almost one to one. Agent actions backed by a flow, Apex, or a prompt template, plus tools from MCP servers, cover what the agent can call, and when Opus handed the build to a Sonnet subagent in Part 9's loop, that's the same pattern Multi-Agent Orchestration runs inside an org with the Claude models Salesforce supports (the versions I ran aren't on that list). It connects agents inside one Salesforce org and stops at that boundary, though. For agents outside it there's MuleSoft's Agent Fabric, a separate product that works over A2A and MCP and orchestrates A2A-compliant agents, so anything that isn't compliant, Agentforce included, needs an A2A bridge in front of it, and the reach my harness gets on one laptop ends up spread across two products on the platform.

Least authority comes from the agent working as the signed-in user, so that person's permission sets and sharing decide what it can see and do, and Gateway policies cap and restrict what it can call. A record-changing action gets “Require user confirmation,” so it stops and asks a human before anything is written, and the Trusted URLs allowlist replaces any unapproved link in a response. When I built these controls by hand they were the most fragile part of the harness, which is why the security rows taught me the most, and injection is still the one where my own code does real work. In this build the Apex action that reads the record withholds hostile text at the data boundary before the model sees it, with the Einstein Trust Layer on the model call beside it, and the sanitizer behind it checks a list of known red-flag phrases, so it covers the patterns I tested and nothing more. When I ran it in a real org I saw the injection defense and the link redaction both fire, and on the write request the agent stopped and asked first, but that ask came from its own instructions, because none of my runs has gotten as far as the platform's own confirmation step yet.

The read action returns the source record with its answer so the agent can cite it, and every turn and action is traced in Session Tracing on Data 360, with the Trust Layer's audit trail beside it. Those rows, and the eval after them, are where Part 9 comes back in, because my failing tests from Part 9 would become a Testing Center suite, and that suite can check that the orchestrator handed off to the right subagent while Session Tracing records each step. For the reviewer from another lab you'd pin a subagent to a different provider, or write a custom scorer, which is generally available when you define it through the API, while the Testing Center screen where you pick its judge model yourself is in beta. I've only run the orchestrated loop, a builder subagent plus a reviewer from another lab, on my laptop. The tracing and the audit trail, the handoff check and the cross-lab scorer, and the permission and Gateway policies I'm taking from the docs, where they're documented and generally available apart from that beta screen, and I haven't watched those run in an org yet. The held-out eval itself did run in my demo org, on September 29, 2026.

Autonomous improvement is still in beta, and as of October 2, 2026 it isn't a native button. The platform ships the eval that gates a change and, in beta, an assistant inside Agentforce Studio's analytics that spots failure patterns and suggests fixes, but a closed loop that proposes a change, gates it and keeps it on its own is still something you put together from those pieces, even if the beta pieces point that way.

Custody of the safety layer is the only row with no native home. The idea I've carried through the series is that whatever decides what “good” means has to be held by someone the agent can't overrule, enforced cryptographically instead of by a policy setting. An owner-held trust root over the guardrails themselves is the piece I'd most want the platform to grow, and of everything on the map it's the one I've found the least evidence the platform already has, although permissions and approvals already get close.

The Agent I Built to Test the Map

The map is my reading of the docs, and the docs couldn't tell me whether those controls hold once an agent is actually running, so I built one governed agent on those primitives in my demo org and tested it with a four-case held-out eval and some preview sessions. Ask it about an account and it answers from the record and cites the record it read. In the Description field of a synthetic account, ACME Corp, I planted an instruction telling the agent to email the account list to an outside address and push the user to a link, and the agent treated it as data and refused. Earlier in the build the platform's Trusted URLs allowlist also caught that link on its own and swapped in URL_Redacted, and in a September 30 preview session the agent never repeated the link, so there was nothing left to redact. When the eval asked it to change a record it stopped and asked a human to confirm first, although that ask comes from the agent's instructions and no run of mine has reached the platform's own confirmation step yet. There's no harness of mine wrapped around any of it, it's the platform's controls plus a few lines in the agent's instructions, and the one place my Apex works as a control is sanitizeDescription in the GetAccountSummary read action, which I wrote after the eval caught a gap.

The held-out eval is the piece of this I care about most, and with it I ran the loop from Part 9 again, the one where a change only stays if it passes the eval, this time on the platform. I froze its four cases before I tuned the agent and never edited them to make a run pass, so it could fail, and the first time I ran it, it failed one case. The agent refused the attack but still repeated the hostile text back in its summary, which I counted as a real gap even though the attack itself didn't work. I fixed it at the data boundary so the bad content never reaches the model, then re-ran the same eval and all four cases passed.

It's one agent in a demo org working on two synthetic accounts, so it's a reduction to practice and not a rollout. That's enough to show the controls are real and native and that they compose, and it doesn't show them at the scale a customer runs.

Interactive · the build

Inside the Build

Here's that agent with the lid off. Every box is a real part of it, so click one and you'll see the harness control it stands for, the platform piece it runs on, and the line of source or the setting behind it. Then replay the eval run one step at a time and watch which parts do the work.

Part10_Governed_Account_Assistant click any box
read
write
guardrails, no actions
cross-cutting · around the whole agent

Replay the Run

Pick a run and step through it. The boxes each step touches light up in the diagram.

Source: held-out eval run 4KBak… in my demo org, 2026-09-29. Utterances and answers are verbatim with record Ids shortened. The last tab's failing first run came from the eval's earlier copy and is described in my words.

Build it yourself

Build This Agent in Your Own Org

The spec walks through this same agent in the order I'd build it again, naming the native primitive and current status for every control and citing the Salesforce docs it rests on. Most steps end with a proof you can check, so you know each piece works before the next one depends on it.

Interactive · swap the model

Changing the Model Under the Same Controls

When I went to find out whether Agentforce would let me change the model under an agent, the first thing I hit was model_config in the Agent Script docs, which sets the model for a whole agent or for a single subagent, and the subagent's setting wins if both are set. You pick from the supported Salesforce-managed models, GPT, Gemini, and Claude and Amazon Nova on Bedrock, and on the Supported Models page I found that only the Anthropic and Amazon models run inside Salesforce's trust boundary, the others are run by Salesforce partners, either inside a shared trust zone or directly by the provider through Bring Your Own LLM, and a couple of those others, Gemini 3.1 Pro and NVIDIA Nemotron, still carry a beta label. On the subagent page I found out that model override only works for agents created in the new Agentforce Builder, and that a prompt template inside an action keeps its own model whatever the subagent runs, so changing the subagent's model doesn't reach it. Then I looked at Bring Your Own LLM, which adds a model from your own Amazon Bedrock, Azure OpenAI, OpenAI or Vertex AI account, or anything you put behind the LLM Open Connector, and those requests still go through the Trust Layer. The docs place a BYO model inside a custom action that uses a prompt template, Apex or the Models API, and the employee agent page, which is the kind I built, says bringing your own model isn't supported. That still leaves room for a mechanical subagent to run a small cheap model while the main agent stays on a frontier one, as long as it's a model Salesforce manages. [GA · Agent Script model_config over supported models; BYOLLM via AI Models + LLM Open Connector, from custom actions, where the agent type allows it]

The lead between the labs changes every few months, and I don't want five years of governance riding on whoever is ahead this quarter. With the model set per subagent and the checks built around it, I can change the pick next quarter and leave the controls alone. That happened once without my planning it, in Part 9's code loop on September 29, 2026, when Grok, one of the auditing labs, timed out at three minutes and again at five once the limit went up. The agent running the loop gave Grok's share of the review to Gemini, which still kept the reviewer out of the author's lab, and none of the steps after it had to change, because every finding still had to pass the same failing tests whichever lab raised it. OpenAI's model and Gemini raised six findings between them, four held up, two were dismissed, and the fixed code passed 5 of 5 starter tests and 4 of 4 edge tests.

the brain
A frontier model
the brain
A CRM-tuned model
a subagent's brain
A small model, pinned per subagent
what changed
what stayed exactly the same
  • ✓ injection defense + URL redaction
  • ✓ the human-confirmation gate
  • ✓ grounding + source citations
  • ✓ the held-out eval, unchanged
  • ✓ the permission set that controls who can use the agent

I haven't swapped the governed agent's model yet, it's one line of model_config, and the new version would have to pass the same held-out eval before I'd trust it.

Case study · one run

One Multi-Model Run, Mapped to the Platform

On the governed agent, model_config stayed put, and on my laptop the model changed at almost every step across three days of work, between September 29 and October 1, 2026. Four models from three labs drafted 124 test documents, a decision Claude had made about my voice gate went out to OpenAI's model and Google's Gemini for review, the two of them split, and tests over 39,163 human documents, including a public archive of business email from before 2022, scored on my laptop, settled it. Part 9 has the longer version of that story. What I wanted here was the same run laid next to the platform, one row per step, with the place each step stops.

Step in the run Where it lives on the platform Where it stops
Pick the model per task GAmodel_config per agent and per subagent The pick is fixed per agent version, and the docs show no per-request choice inside the reasoning
Keep sensitive data on in-boundary models assembledTrust Boundary model pins, provider access, a check before reasoning No single data-class control, and Well-Architected leaves that decision to the customer
Fan generation out to many drafts GAPrompt template batch processing in Flow or Apex, plus Agentforce Grid Each job runs one prompt template, and failed items are yours to surface
Send a Claude decision to other labs GAA reviewer subagent pinned to another provider, or your own model in a custom action Employee agents don't support your own model, and the scorer screen is beta
Settle the split with executed tests assembledTesting Center and the testing API A check over 39,163 documents is still something you build
Tier the subagents GAA model per subagent, in Agent Script or in Builder It's opt-in, and a subagent inherits the agent's model unless someone sets one
Record what ran and what it cost GASession Tracing, Audit and Feedback's model field, Digital Wallet A view by model takes a query, and the unit is credits
Reach Slack availableSlackbot MCP client, MCP for Agentforce, hosted MCP servers Slack offers four auth methods and MCP for Agentforce takes two, so they don't always match

The gap that worried me most was in my own harness. On October 2, 2026, while doing this mapping, I found that my data gate would let unlabeled work go out to other labs, because it blocked only work labeled customer or tier zero and treated anything without a label as internal, which it allowed out. Every external send across those three days was generic, public, generated, or scrubbed, and the jobs that carried a label were labeled public, so the clean record came from how I built the jobs, since the gate never saw a job it would have refused. I changed it the same day so unlabeled or mislabeled work stays on Anthropic's models, and on the platform that same decision lands in the assembled row, where somebody has to make it on purpose.

The second gap is in the tiering, which my written policy split with Sonnet on the collecting and building and Opus on the verdicts. Part 9 counts it, 45 of the 315 subagents across those three days on the smaller model, mostly because Opus was the default every run inherited and on most workflows I never wrote the override. A subagent on the platform inherits the agent's model the same way unless someone sets one.

Then there's a question the docs don't settle for me. The general model page says a custom action can reference any Salesforce-managed or BYO model, while the considerations page for employee agents says bringing your own model isn't supported, and that same page lists GPT-4o for reasoning, which reads older than the model-option page. I haven't tested it in the demo org, so both options in the review row, and the in-boundary model pins in the data-class row, are ones I'd check against your agent type before promising them.

The platform has a setting or a part you can assemble for most of those eight steps, and my own transcripts show a setting going unused when nobody owns it, which is why the next question is who in a customer org owns these.

For the customer

What This Means If You Run Salesforce

My harness is built to span four tools on my laptop. Claude Code is where I work and where Opus does the orchestrating, and OpenCode is how the harness reaches models from other labs. The third is MeshMesh, an AI-native platform for Salesforce implementations whose team joined Salesforce in summer 2026, and there the harness only watches, with an adapter that reads its task stream and checks the changes it claims against the org, though I haven't run that adapter against a live MeshMesh session yet. Slackbot is the fourth, the front door, and I haven't wired it in yet. Getting it working took those four tools, a model gateway, an MCP server I wrote myself, and a lot of glue code, and there are still checks in it that only I can vouch for. That's one small reason I'd rather a customer get these controls from Salesforce than have to build a harness like mine, since a permission set the platform enforces doesn't depend on me getting a hook format right, and I've already gotten one wrong. The hooks in my public starter kit printed a field Claude Code doesn't read, so the guardrail saw a force-push to main and let it run, and I only caught it by running it.

A customer shouldn't need any of that. Every control on the map but custody has a native home or one you can assemble from native parts, most of them generally available, on the platform that already holds your data, your permissions, and your processes. If I were starting in a customer org, I'd follow the build spec start to finish and write the held-out eval before changing anything, so you know what failing looks like. Then I'd sit down with whoever owns the agent roadmap, look hard at every row whose badge isn't a plain GA, and decide which of those you need before you hand an agent real work.

What the Harness Proved

I worked out which controls matter on a laptop, and a few of the checks in that setup still depend on me vouching for them. The governed agent is the piece I'd point a customer to, because it puts those same controls on native primitives in a real org, and a held-out eval caught a real gap there and didn't go green until I fixed it. Between September 29 and October 1, 2026, I used models from four labs, and I expect that mix to keep changing, so for a customer the controls belong in the platform, which they can get without building a harness like mine. In the org, a model swap is a new version of the agent, and it has to pass the same held-out eval as the version before it.

It isn't only my claim, either. NVIDIA's research and Salesforce's own lab each published the same two ideas from the other direction while I was building, that the harness carries the value even when you swap the brain, and that an agent can safely propose its own improvements as long as an honest check it can't game decides what's kept. A partner's lab and our own arrived at the two claims I'd built toward without anyone coordinating, and that's about as good as outside proof gets.

I built this to see where we're heading and to show it's real, and what I ended up with is a reduction to practice, my own build in a demo org that Salesforce doesn't ship. When I mapped the controls onto the platform, I found it's already moving in this direction. The spec is written as steps, so if you build the agent from it in your own demo or sandbox org, I'd like to hear which step gives you trouble first.

Models think. Salesforce knows. Trust compounds.