Profiles, the Primitive Most Frameworks Miss
A profile is not a config file. It is the assembly that makes one harness work across domains.

The question I dodged
Two weeks ago you ran strategic-council and got a memo with the dissent still attached. Now the question I dodged. Why did that particular assembly produce that particular argument?
In Issue 3 I showed you the machine running. Install, point strategic-council at the auto-deploy decision, read the memo. What I did not do was open the box and show you why the argument came out shaped the way it did, with the reliability specialist's dissent preserved instead of averaged away. That was deliberate. It is the payoff of this whole Foundations arc, and it has one name.
The profile. Not the agents inside it, not the Arbiter that wrote the memo. The assembly. This issue is me paying that back.
Anatomy of a profile
A profile is a small YAML file. schema: aos/profile/v1, an id, a list of agents, some settings. If you stop reading at the file, you will conclude it is config, and you will build the wrong thing. Here is the strategic-council profile you already ran, trimmed to the parts that matter.
# core/profiles/strategic-council/profile.yaml
schema: aos/profile/v1
id: strategic-council
assembly:
orchestrator: arbiter
perspectives:
- agent: catalyst
required: true
- agent: sentinel
required: true
- agent: architect
required: true
- agent: provocateur
required: true
structural_advantage: speaks-last
- agent: navigator
required: false
# … advocate, pathfinder, strategist, operator, steward, auditor (required: false)
delegation:
default: broadcast
opening_rounds: 1
bias_limit: 5
tension_pairs:
- [catalyst, sentinel] # velocity vs blast radius
- [architect, pathfinder]
- [strategist, operator]
# … [advocate, navigator], [catalyst, pathfinder]
input:
format: brief
required_sections:
- heading: "## Situation"
- heading: "## Stakes"
- heading: "## Constraints"
- heading: "## Key Question"
output:
format: memo
path_template: "output/memos/{{date}}-{{brief_slug}}-{{session_id}}/memo.md"
sections: [ranked_recommendations, agent_stances, dissent_and_tensions,
tradeoffs_and_risks, next_actions, deliberation_summary]
constraints:
time: { min_minutes: 2, max_minutes: 10 }
budget: { min: 1.00, max: 10.00, currency: USD }
rounds: { min: 2, max: 8 }Twelve agents, counting the Arbiter. Now look at what a config file cannot fake.
Evidence standards. What counts as proof. These do not live in the profile. They live on the agents, in the `agent.yaml` files you met in Issue 2. Catalyst declares an evidence_standard that is convinced_by revenue data and willingness-to-pay signals. Sentinel's bar is change-failure rate, time-to-recovery, and the blast radius of a bad ship: durability and trust over velocity. The platform-engineering domain pack then hands the whole room a shared vocabulary for the auto-deploy question, deployment_frequency and lead_time_for_changes on the velocity side, change_failure_rate and MTTR on the reliability side. What the profile does is decide which of those standards get a seat. A config file can list the agents. It cannot hold the bar each one brings.
Interface contracts. How one agent's output becomes the next one's input. The input block is the input contract: strategic-council will not run until it gets Situation, Stakes, Constraints, Key Question. The output block is the exit contract: a memo at a fixed path with fixed sections. And in between, the Provocateur carries structural_advantage: speaks-last, which means its input is everyone else's output. That is the contract in one line. The assumption-breaker cannot fire early, so consensus has to survive being formed before it gets stress-tested.
Bias and temperament, promoted to a design lever. In Issues 2 and 3 these were descriptors, a way to tell the agents apart. Here they are the control surface. Catalyst's core_bias: speed-and-monetization is a required seat in strategic-council on purpose, because a strategy call that never hears the velocity argument is not a strategy call. You tune a profile by choosing which biases sit at the table, not by editing prompts.
Same decision, different profile
Keep the auto-deploy question exactly as it was. Should our deployment agent be allowed to merge and ship to production on its own, and for which change-classes? Now point security-review at it instead.
# core/profiles/security-review/profile.yaml
schema: aos/profile/v1
id: security-review
assembly:
orchestrator: arbiter # same machinery
perspectives:
- agent: architect
required: true
- agent: sentinel
required: true
- agent: provocateur
required: true
structural_advantage: speaks-last
- agent: steward # catalyst out, steward in
required: true
# … operator, navigator (required: false)
delegation:
default: broadcast
opening_rounds: 1
bias_limit: 5
tension_pairs:
- [architect, provocateur]
- [sentinel, operator]
input:
format: brief
required_sections:
- heading: "## System Description"
- heading: "## Known Threats"
- heading: "## Compliance Requirements"
- heading: "## Key Question"
output:
format: report
path_template: "output/reports/{{date}}-{{brief_slug}}-{{session_id}}/report.md"
sections: [vulnerability_assessment, risk_matrix, remediation_priorities,
compliance_gaps, immediate_actions]
constraints:
time: { min_minutes: 2, max_minutes: 8 }
budget: { min: 1.00, max: 8.00, currency: USD }
rounds: { min: 2, max: 6 }Watch what moved. Catalyst is gone. The monetization bias has no seat here, because "will customers pay for autonomous deploys in 90 days" is the wrong question to ask a threat model. Steward is required instead, and it weighs regulatory exposure, not revenue. The input contract changed shape: the profile now demands System Description, Known Threats, Compliance Requirements. You cannot even feed security-review the strategic-council brief. It will reject it. And the exit contract is a report with a risk_matrix and compliance_gaps, not a memo with ranked recommendations.
Same decision, same Arbiter, seven agents instead of twelve, and the answer that comes back is held to a different standard of proof.
The side-by-side
| | **strategic-council** | **security-review** |
|---|---|---|
| orchestrator | `arbiter` | `arbiter` (same machinery) |
| required agents | catalyst, sentinel, architect, provocateur | architect, sentinel, provocateur, **steward** |
| the swap | Catalyst (monetization) required | Catalyst **out**, Steward (compliance) **in** |
| agent count | 12 | 7 |
| evidence standard | revenue, willingness-to-pay, DORA (deploy freq, lead time, change_failure_rate, MTTR) | threat model, blast radius, regulatory exposure |
| input contract | Situation / Stakes / Constraints / Key Question | System Description / Known Threats / Compliance / Key Question |
| output contract | `memo` → ranked_recommendations + documented dissent | `report` → vulnerability_assessment + risk_matrix |One row survives the swap: orchestrator. Every other row moved. Different agents, a different bar for proof, different contracts at both ends. A memo comes out of one, a risk matrix out of the other. That is the difference between a config file and a profile, sitting in one table. You can read both, whole, in the public repo.
Why frameworks miss it
I have circled this since Issue 1. A config file can hold a list of agents. It can hold model names and temperatures and a system prompt with seven roles in it. What it cannot hold is what counts as proof in the room, and it cannot hold how one agent's output becomes the next one's input. Both are structure, and structure has no slot in a key-value file.
So the frameworks that treat a profile as config keep shipping the list and dropping the structure, and then they wonder why nothing reuses. Every new domain starts from a blank prompt again. A profile is not a config file. It is a config file the way a contract is a PDF. The format is the least interesting thing about it.
This is also where the reuse claim from Issue 1 stops being a claim. I told you the harness makes Councils composable across domains. You just watched one harness argue a strategy call and a security review off the same decision. You reused the profile. Not one line of harness code changed. Author one for your field (the docs walk through it) and the machinery comes for free.
Foundations closes
Two threads have run under this arc since the manifesto. One said the thing that breaks agent systems is the space between the models. The other said the profile only looks like config. In this issue they meet on the same noun.
A profile is the space between the models, written down and handed to the next team. It is also an assembly with evidence standards and an interface contract, and that is exactly the part the cottage industry leaves out. It is the primitive most frameworks miss.
Next issue we climb inside one and take the deliberation apart: Tension Pairs, and why the Provocateur's speaks-last seat forces synthesis instead of averaging.