SPECIFICATION / IDENTITY
Open Agent Profile
A profile is a file describing a named agent: role, model, tool surface, permissions, and what previous sessions learned. A harness reads it to start a session and writes an updated revision when the session ends. No process is resident. The file is the agent.
Project
What it is
The Open Agent Profile is an open specification for persisting a named AI agent as a file rather than as a running process. A profile describes an agent: role and instructions, model or capability tier, tool surface, permissions, attached context, and what previous sessions learned.
A harness reads the file to start a fresh session on demand and writes an updated revision when that session ends. Nothing needs to stay resident. It is Apache licensed, at version 1.0 with maintenance releases, and ships schemas, a conformance suite, and support libraries in several languages.
The problem I wrote it for
You define a useful agent. A reviewer that knows your conventions, a researcher that cites the way you want, a data agent that has learned your table layout. Then the session ends.
That definition either dies with the session or lives in a format only one harness reads. Neither outcome carries what the agent actually learned: the conventions it picked up, the preferences you corrected it on, the investigation it was halfway through.
The obvious fix is to keep a process alive, and it is the wrong one. It is expensive. It dies with the machine. It cannot be diffed or reviewed. Two people cannot share it. Every property you want from a durable agent, a running process fails to provide.
Persisting the agent as data solves all four, and it introduces a set of safety problems that occupied most of the actual design work.
What a profile contains
Three top-level parts, and the separation between them is where the design lives.
Metadata. Name, description, and a revision number. The revision is what makes a profile something with a history rather than a current state.
Spec. The contract. Role instructions and constraints, model provider and identifier plus a portable capability tier as a fallback, the tool policy with an allowlist or denylist, and lifecycle settings including how writeback is handled. A human authors and approves this.
State. What previous sessions learned. A summary, discrete facts with confidence and provenance, and open threads with their status. Sessions write this.
The model field captures a portability problem neatly and is worth calling out. It carries both a specific provider and identifier, which is what you want on a machine that has that provider configured, and a portable tier, which is what a different harness uses when the named model is unavailable. Naming a specific model is precise and unportable. Naming only a tier is portable and imprecise. Carrying both lets each consumer take what it can use, which is a pattern I have since applied elsewhere.
The three rules
A file describing what an agent may do is a security question, not a convenience. These three rules are the reason the specification is more than a file format, and each closes a hole the others leave open.
A profile narrows. It never widens.
A harness grants the intersection of what the profile asks for and what its own policy allows. There is no field, flag, or trust label that reverses this. Moving a profile to a new machine can never grant capability the harness would not otherwise give.
Without this, a portable agent file is an escalation mechanism: acquire a profile from somewhere, run it, and receive whatever it claims. With it, a profile is safe to accept from anyone, because the worst case is an agent with fewer capabilities than you already permit.
An agent cannot rewrite its own contract.
Sessions emit a state delta, and delta operations may only touch the state section. A change to tools, permissions, model, or instructions goes into a proposals block with a written rationale and waits for a human.
This holds under every writeback setting, including fully automatic. That detail is deliberate: a boundary that configuration can relax is not a boundary, it is a default.
Learned state is untrusted content.
Text an agent wrote about itself is injected as information, never as authority. A state entry saying the shell may now be used without asking changes nothing.
This rule closes the failure I find most alarming. Without it, one successful prompt injection becomes permanent. An attacker persuades the agent once, the agent writes the instruction into its own state, and every future session starts already compromised. Treating state as content keeps a one-time injection one-time.
Narrowing stops a file from granting power. State-only writeback stops a session from granting itself power. Untrusted state stops persuasion from becoming policy. Any two without the third leaves a path.
Proposals instead of refusals
This is the mechanism I am happiest with, because it turns a refusal into a conversation.
When a session concludes it needs a capability it does not have, the naive options are both bad. Granting it means an agent expanding its own authority. Silently dropping the request means the agent keeps failing at the same thing and nobody finds out why.
A proposal is the third option. The specific change being requested is recorded with a written rationale explaining what the agent could not do without it. A human reads that and decides.
The rationale is what makes it work. A request to add shell access, with an explanation that the agent could not verify a flaky test claim without running the suite, is a reviewable engineering decision. A bare request to add shell access is not. The mechanism produces exactly the artifact a reviewer needs, at the moment the need is fresh.
It also addresses the usual failure of least privilege. Narrow permissions block legitimate work, friction accumulates, and someone eventually widens the grant to stop the complaints. A structured request with a documented reason turns that pressure into a decision with evidence, which is the only version of least privilege I have seen survive contact with real work.
Conformance levels and honest gaps
Three levels, so implementations can be honest about partial support.
- Level 1, Read. Discover, validate, and instantiate an agent from a profile.
- Level 2, Read and Write. Level 1 plus state injection, delta generation, and persistence.
- Level 3, Full. Level 2 plus composition, MCP, skills, external memory, and delegation.
The accompanying requirement matters as much as the levels: an implementation must publish what it does not implement. Partial support is fine. Partial support that looks complete is not, because someone will review a profile, run it elsewhere, and get a different agent than the one they read.
I put that requirement in the specification rather than leaving it as advice, because I had already built the version that silently degraded and watched it manufacture confidence. It is the same principle as the projection reporting a broker needs, arrived at from the specification side.
Implementations and encodings
A specification is only as real as its second implementation, so tooling is part of the evaluation rather than a footnote.
The repository ships a reference validator and applicator, plus support libraries for Python, TypeScript, Go, Rust, and Java, each covering validation, canonical digests, inheritance, policy narrowing, prompt rendering, and delta application. A shared conformance corpus is used across languages, including negative fixtures that a correct implementation must reject.
Cross-language testing against a shared corpus is the part worth insisting on. It is the difference between five libraries that each interpret the specification plausibly and five libraries that demonstrably agree. Negative fixtures matter for the same reason: a specification is defined as much by what it rejects, and an implementation that accepts an invalid profile produces an agent nobody reviewed.
Canonical digests deserve their own note. Because a profile can be written in more than one encoding with fields in any order, comparing two profiles textually is unreliable. A canonical digest gives a stable identifier for the content regardless of formatting, which is what lets you say the profile running in production is exactly the one that was approved.
For harnesses without native support, the repository ships two Agent Skills that let a harness load a profile, assemble the prompt in the specified order, report what it dropped, and turn a session into a reviewable delta. That is not as good as native support, and it means the format is usable today rather than after someone else's roadmap.
The lifecycle in practice
The mechanism that turns a static file into something that accumulates is worth walking through, because the interesting decisions are in the details rather than the concept.
A harness loads a profile and starts a session. The session runs. At the end it produces a delta: a structured description of what changed. Facts learned, threads opened or closed, the summary updated. Applying that delta produces a new revision.
Writeback settings control how much human involvement that requires, ranging from proposing everything for approval through applying state updates automatically. What does not change across settings is which parts a delta may touch. Automatic writeback means state updates apply without review. It never means the contract can change without review.
State entries carry more than text, and that structure is what keeps them maintainable. Facts have confidence, a source, and can be pinned. A fact whose source was one uncertain observation can be treated differently from one confirmed repeatedly. Pinned facts survive summarization, which is how you keep the three things that actually matter from being compacted away along with everything else.
Open threads are the part people underestimate. An agent halfway through an investigation, with a thread marked blocked and a reason, resumes usefully next session. Without that, the next session starts by rediscovering that the investigation exists, which is most of the cost of having stopped.
The practical advice from running this for a while: review state periodically rather than continuously. Continuous review defeats the purpose, since the point is that sessions accumulate learning without needing you. A monthly skim catches stale facts, conclusions drawn from one ambiguous case, and threads that were closed in reality but not in the profile.
How it relates to the other contracts
The division that I think is the clearest statement of this whole layer:
- Skills are what an agent knows how to do.
- MCP is what it can reach.
- Harness configuration is what it is allowed to do.
- A profile is who it is, and what it has learned.
None of these substitutes for another. An agent needs all four, and before profiles the fourth was either absent or trapped inside a product. Identity and accumulated learning were the parts with no portable home, which is precisely why I wrote it.
Adopting it
The useful starting point is not converting everything. It is writing one profile for the agent with the most capability, because that exercise reveals the most.
- Pick the agent with the broadest permissions. Writing down what it may do reliably surfaces at least one grant nobody would defend.
- Express the contract, not the current behavior. What it should be permitted, rather than what it happens to be able to reach.
- Validate it. The tooling checks the schema and produces a stable digest, which is what makes a profile citable in a review.
- Turn on state with proposal-based writeback. Let sessions accumulate learning while capability changes wait for review.
- Read the proposals. They are the most direct feedback available about where your permission model is wrong.
- Keep profiles in version control. History, review, and rollback come free.
Limits and honest caveats
- Check your harness's conformance level. Level 1 support means state does not persist, which changes what the profile is for.
- State needs curation. Facts go stale. Confidence and provenance fields exist to support pruning, and someone has to do it.
- State is data an agent wrote. Review it when a profile moves between environments, particularly one that has been running unattended.
- Narrowing means a profile can quietly do less elsewhere. That is the safe direction and it can still surprise you. A projection report is how you find out.
- Do not put secrets in a profile. It is a file meant to be shared, versioned, and copied. Credentials belong in a vault the harness references.
- It is young. A small number of known implementations, all of which I can name. That is a real limitation, and the alternative is not a mature portable format but no portable format at all.
What it is not
A profile is not an enforcement mechanism. It expresses a contract; the harness enforces it. A harness that ignores a declared denylist makes the profile a description rather than a control, which is exactly why conformance statements matter.
A profile is not a memory system. State captures what a session learned about the agent's own work. Putting large amounts of domain knowledge into profile state is using the wrong container, and there are better ones.
A profile is not a skill. It says who the agent is, not how to perform a procedure. Conflating them produces profiles that grow into unmaintainable instruction documents, which I have done and do not recommend.
Where to learn more
Primary sources first. Repositories and specifications move faster than any summary, so treat the links below as the authority and this page as orientation.
- Open Agent Profile on GitHub ↗Specification, schemas, conformance suite, examples, and support libraries in five languages.
- The normative specification ↗The authoritative document, including the security model and conformance requirements.
- Agentic Graph Specification ↗The companion specification describing the shape of a piece of work.
- Agent Skills ↗The capability format, covering what an agent knows how to do.