The Agent Spec Protocol (AP) — the complete spec for encoding agent routing, pipeline state, and content contracts in HTML documents using ap- custom elements. Read this before producing or validating any AP-compliant HTML document.
Instalação
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
The Agent Spec Protocol (AP) — the complete spec for encoding agent routing, pipeline state, and content contracts in HTML documents using ap- custom elements. Read this before producing or validating any AP-compliant HTML document.
Agent Spec Protocol v3.0
AP is a standard for HTML documents that are simultaneously human-readable pages and machine-navigable agent workspaces. It uses custom HTML elements (<ap-gate>, <ap-source>, <ap-gen>, etc.) to encode which agents own which sections, what pipeline state each section is in, and how agents read, write, and route through the document.
Why HTML
Most AI pipeline definitions live in YAML config files, JSON schemas, or markdown documents. All three have the same problem: they are invisible to humans without tooling, and they separate the pipeline definition from the content it produces. An Airflow DAG file and the data it processes are two completely separate things. A GitHub Actions workflow and the code it builds live in different files. You must hold both in your head simultaneously.
AP collapses those two things into one file. An AP document is the pipeline definition AND the content workspace. Open it in a browser: you see a readable document showing each stage, its current status, and whatever content agents have written. Open it with an XPath query: you see a machine-navigable graph of sections with precise routing and state. The same file, read two ways, serves two different audiences without compromise.
Why not JSON? JSON has no human-readable rendering and no native hierarchy that maps to document content. You cannot open a JSON pipeline config in a browser and read the actual output from each stage.
Why not YAML? Same problem — YAML is config, not content. Pipeline state and pipeline output are still in separate files.
Why not Markdown? Markdown is human-readable but machine-opaque. There is no standard way to attach pipeline metadata, agent assignments, or status to a markdown section. Agents parsing markdown must read and interpret prose to find their work — there is no precise address to navigate to.
HTML's specific advantages for AP:
Native hierarchy — the DOM tree is a real data structure agents can query with XPath, not freeform text
Custom elements — W3C standard extension point: define your own tags with full attribute freedom, no prefixing required
Human rendering — any browser renders an AP document as a readable page with zero tooling
Stable addressing — id attributes are W3C-standardized unique addresses; #competitive inside <ap-gate> is a precise, unambiguous pointer
Semantic vocabulary — HTML elements like <del>, <mark>, <progress>, <time>, <details> carry meaning that agents can read without custom attributes
Separation by design — element names declare type, attributes carry metadata, element content holds human/agent output
Design Philosophy
HTML is the medium — use it fully. AP does not invent structure that HTML already provides. The DOM tree is the pipeline graph: nesting expresses grouping, hierarchy expresses inheritance, element order expresses sequence.
Custom elements are the building block for pipeline stages. Pipeline attributes (agent, status, on-pass, on-fail, depends-on) belong only on custom elements — never on standard HTML elements. A parser finding pipeline stages looks for custom elements only. The hyphenated tag name is the signal. Reading layer attributes (kind, topic) are different: they may appear on any element, standard or custom, because they carry no workflow semantics and produce no parser scanning overhead for pipeline discovery.
The element name is the namespace.<ap-gate id="trends"> — the <ap-gate> wrapper makes trends unambiguous. There is no need to write id="ap-trends" or on-pass="ap-competitive". The surrounding element provides the context. Attributes on custom elements are owned by that element — no data- prefix is needed or wanted.
Hierarchy over repetition. Parent elements declare shared defaults. Child sections override only what is genuinely different. An attribute that appears on every section belongs on their parent.
Self-describing documents. An agent knows its own name. That is the only query it needs: //ap-gate[@agent='idea-trends'][@status='pending']. The document delivers the agent directly to its work — no scanning, no full-document reads.
Framework owns vocabulary. Users own values. AP defines the element names and valid enums. The values inside attributes — agent names, section IDs, output key names — belong to the implementor. Any domain can use AP without AP knowing anything about that domain.
AP operates at two independent layers:
Reading layer — topic and kind attributes on any HTML element. Makes existing content findable by agents without restructuring. No workflow implied.
Pipeline layer — custom elements with agent, status, on-pass, etc. Defines workflow stages where agents do work.
A page can use either layer independently or both together.
AP also separates three concerns that must never mix:
Design — visual classes owned by the design system (e.g., bp-*)
Protocol — agent routing, state, and contracts encoded as attributes on AP custom elements
Content — what agents and humans write inside AP elements
The Reading Layer
The reading layer solves one problem: an agent must find specific content in a document without reading the whole thing.
A documentation page with 40 sections costs 8,000 tokens if an agent reads it in full. With reading layer attributes, the agent issues one XPath query and reads only the sections it needs. Like a book with a precise index — you don't read every page to find the definition of a term.
Two attributes. Both may appear on any HTML element — standard or custom. Neither implies workflow state or pipeline processing.
kind — What type of content is this?
A spec-defined closed vocabulary. Every AP-aware tool understands these values consistently.
Value
Meaning
summary
A condensed version of larger content
overview
High-level introduction to a topic
reference
Detailed lookup material (API docs, specs, tables)
key-point
A single critical insight worth highlighting
definition
A term and its meaning
example
A concrete illustration of a concept
instruction
Step-by-step directions for doing something
topic — What subject does this cover?
A user-defined open vocabulary. AP defines the attribute name. The implementor defines the values. Any string is valid. Use kebab-case for multi-word topics.
<!-- a documentation page — no restructuring needed, just annotations --><sectionid="auth-intro"topic="authentication"kind="overview"><h2>Authentication</h2><p>Our API uses bearer tokens...</p></section><sectionid="auth-reference"topic="authentication"kind="reference"><h2>Authentication Reference</h2><table>...</table></section><pid="auth-tldr"topic="authentication"kind="summary">
Pass your API key as a Bearer token in the Authorization header.
</p><asideid="rate-limit-note"topic="rate-limiting"kind="key-point">
Requests are limited to 1,000 per minute per API key.
</aside>
An agent answering "how does authentication work?" needs exactly two queries:
//*[@topic='authentication'][@kind='summary'] ← get the one-line answer first
//*[@topic='authentication'][@kind='reference'] ← get the full details if needed
Neither query reads the rate limiting section, the pricing section, or anything else. The document delivers targeted content directly.
Reading Layer Rules
kind and topic may appear on any HTML element — standard or custom
kind takes only the enumerated values above — no custom values
topic is user-defined — any lowercase kebab-case string is valid
These attributes carry no workflow semantics — no agent assignment, no state, no routing
A document using only kind and topic is a valid AP reading-layer document even with no custom elements
Document Structure
Every AP document is a valid HTML5 file with three distinct zones:
Zone
Element
Owns
1
<html>
Design system attributes only
2
<head>
Document-level metadata in <meta> tags
3
<body>
Content and AP pipeline sections
Zone 1: The <html> Element
Only design system attributes live here. AP protocol does not touch <html>.
<htmldata-bp-theme="auto"lang="en">
Zone 2: Head Metadata
Document-level metadata lives in <head> as namespaced <meta> tags:
<meta name="[namespace]:[key]" content="[value]">
Namespace rules:
Lowercase letters and hyphens only: a-z and -
Must identify the plugin without requiring a lookup
Registered: every plugin using AP registers its namespace to prevent collisions
The index contract: An orchestrator reading a portfolio of AP documents reads only <head> metadata — never section content. Meta tags must be complete and current. Every agent that updates a section status must also update the relevant <meta> tags.
Zone 3: AP Custom Elements
Each pipeline stage is an AP custom element in <body>. The element name declares the stage type. Attributes declare the metadata. Content is what agents and humans write.
AP custom elements may be nested. A parent <ap-parallel> contains child elements that run concurrently. All other nesting is for attribute inheritance.
AP Custom Elements
Element Vocabulary
Element
Who runs it
Gate decision?
Notes
<ap-source>
human
no
Immutable origin. Never modified after creation.
<ap-gen>
AI agent
no
Produces content with no pass/fail outcome.
<ap-transform>
AI agent
no
Converts inputs to a different output form.
<ap-gate>
AI agent
yes
Automated pass/fail decision.
<ap-review by="ai">
AI agent
yes
AI reads upstream content and decides.
<ap-review by="human">
human
yes
Human reads and decides. Status set manually. Never completed by an agent.
Child element: marks unfilled content. Removed when agent writes.
Required Attributes
Every leaf AP element must have all three:
Attribute
Format
Example
id
kebab-case
id="competitive"
agent
agent name string
agent="idea-competitive"
status
enum
status="pending"
Recommended Attributes
Attribute
Type
Purpose
on-pass
section ID
Where control routes on pass
on-fail
section ID
Where control routes on failure
on-skip
section ID
Where control routes on skip
depends-on
space-separated IDs
Guards: all must be passed before this runs
context
space-separated IDs
Section IDs to inject as agent context
updated-at
ISO 8601 datetime
When agent last wrote to this section
version
positive integer
How many times this section has been written
Optional Attributes
Attribute
Type
Purpose
gate
enum
Whether this stage has a pass/fail gate decision
format
enum
Expected output shape
token-budget
positive integer
Max tokens the agent should write
outputs
space-separated keys
Named values this section produces
inputs
space-separated keys
Named values this section requires from upstream
route-to
section ID
Written by <ap-route> agents; orchestrator follows this
Attribute Inheritance
AP attributes cascade from parent to child elements, exactly like CSS properties cascade through the DOM. Declare shared defaults on the nearest common ancestor.
Cascading Attributes
Attribute
Cascades
gate
Yes
format
Yes
token-budget
Yes
on-fail
Yes — default escalation path for all children
Non-Cascading Attributes
Attribute
Does Not Cascade
agent
Each element has its own assigned agent
status
Each element holds its own live state
depends-on
Each element declares its own guards
context
Each element specifies its own read targets
outputs
Each element declares its own produced keys
inputs
Each element declares its own required keys
on-pass
Each element declares its own forward route
on-skip
Each element declares its own skip route
updated-at
Each element holds its own timestamp
version
Each element holds its own count
Inheritance Example
<!-- Parent sets shared defaults --><maingate="required"format="prose"><!-- Children only declare what is unique --><ap-gateid="trends"agent="idea-trends"status="pending"context="raw-idea"on-pass="competitive"on-fail="human-triage"
><ap-gateid="competitive"agent="idea-competitive"status="blocked"depends-on="trends"context="raw-idea trends"on-pass="icp"on-fail="human-triage"
></main>
Enumerated Vocabularies
Closed sets. No values outside these lists are valid.
status
Value
Meaning
pending
Not yet processed
running
Agent currently processing
passed
Gate cleared or section complete
failed
Gate not cleared
skipped
Intentionally bypassed
blocked
Waiting on a dependency that has not passed
gate
Value
Meaning
required
Must pass for downstream sections to become runnable
optional
Informational — pipeline continues regardless of outcome
none
Purely generative; no gate decision
format
Value
Meaning
prose
Narrative text paragraphs
json
Structured JSON data
list
Unordered or ordered list
table
Tabular data
html
Rich HTML fragment
mixed
Multiple formats within the section
HTML Semantic Elements as Agent-Readable State
AP custom elements handle pipeline-level concerns. For content-level state within a section, use native HTML semantic elements — they carry meaning that both browsers and agents understand without custom attributes.
HTML element
Human sees
Agent reads as
<del>
strikethrough
done / removed / no longer applies
<ins>
underline
newly added / just written
<mark>
highlight
flagged / needs attention
<progress value="3" max="7">
progress bar
3 of 7 steps complete
<details open>
expanded section
currently active
<details> (no open)
collapsed
not active / archived
<time datetime="...">
readable date
machine-parseable ISO timestamp
<strong>
bold
high importance
Example — an agent marking completed checklist items:
The orchestrator fans out all children simultaneously when <ap-parallel> becomes runnable. The container completes when all children have status="passed".
Routing
Each AP element declares where control goes when it finishes. The orchestrator never needs to scan for what comes next.
Attribute
Trigger
Meaning
on-pass
section passes
Activate this section ID next
on-fail
section fails
Activate this section ID next
on-skip
section is skipped
Activate this section ID next
depends-on
before running
Guard: all listed IDs must be passed first
depends-on is a guard — prevents a section from starting too early. on-* are routes — they tell the orchestrator where to go after. Two different jobs; two different attributes.
Dynamic Routing via <ap-route>
When routing logic is too complex for a static value, use <ap-route>. The agent reads context, decides the next target, writes route-toon its own element — never on any other element — then sets status="passed". The orchestrator follows route-to.
<ap-routeid="score-router"agent="scoring-router-agent"context="trends competitive"status="pending"route-to=""
><!-- agent writes route-to="icp" or route-to="human-triage" based on scores --></ap-route>
Output/Input Contracts
Key Naming Convention
Keys are namespaced with a colon: [section-id]:[key-name]. This prevents two sections from producing a key with the same name.
Every key in inputs must resolve unambiguously to exactly one upstream element's outputs. The CLI validates this graph.
What a Completed Section Looks Like
<!-- PENDING --><ap-gateid="trends"agent="idea-trends"status="pending"on-pass="competitive"><ap-placeholder>Trends analysis pending.</ap-placeholder></ap-gate><!-- COMPLETED --><ap-gateid="trends"agent="idea-trends"status="passed"updated-at="2026-05-12T14:30:00Z"version="1"on-pass="competitive"><h2>Trends Analysis</h2><p>Strong market signal across three growth vectors...</p><footer><timedatetime="2026-05-12T14:30:00Z">May 12, 2026 at 2:30 PM</time>
· idea-trends · 387 tokens
</footer></ap-gate>
updated-at is agent-writable and XPath-queryable. version tracks rewrites. <time datetime="..."> renders the timestamp for humans in the browser. <ap-placeholder> is removed when the agent writes real content — its presence alone signals pending state.
Agent Navigation
An agent knows its own name. One query delivers it directly to its work:
The CLI materializes inheritance before returning an element to an agent. When ap next --agent=idea-competitive runs, the CLI resolves all attributes inherited from parent elements and returns the section with its full resolved attribute set. Agents never walk the tree themselves — they receive a complete work order.
Common XPath Patterns
//ap-gate[@agent='idea-trends'][@status='pending'] ← agent finds its pending work
//ap-gate[@id='competitive'] ← read a specific section
//ap-gate[@status='failed'][@gate='required'] ← find blocking failures
//ap-review[@by='human'][@status='pending'] ← find work waiting on a human
//*[@status='pending'][not(ap-placeholder)] ← pending but already has content
//ap-gate[@version > 1] ← sections rewritten more than once
//li[not(del)] ← incomplete checklist items
Orchestrator Contract
The orchestrator reads only <head> meta tags and AP element attributes. It never reads section content.
Algorithm:
Read all AP elements — collect id, agent, status, depends-on, gate, on-pass, on-fail
Resolve inherited attributes for each element (cascade from parent)
Find the first element where:
status="pending"
All IDs in depends-on have status="passed" (or attribute is absent)
If inside <ap-parallel>, fan out all pending siblings simultaneously
Run the agent for that element
After agent completes:
Update status
Set updated-at to current ISO 8601 timestamp
Increment version
Follow on-pass, on-fail, or on-skip to activate the next element
Update relevant <meta> tags in <head>
Agent Write Contract
When an agent writes to its element:
Read context: fetch elements listed in context using XPath
Read its own element: fetch //ap-gate[@id='[own-id]'] to see current state
Respect token budget: do not exceed token-budget (if present)
Respect format: output matches format
Remove placeholder: replace <ap-placeholder> with real content
Set outcome: update status to passed or failed
Set timestamp: write updated-at with current ISO 8601 datetime
Increment version: add 1 to version (or set to 1 if absent)
Never touch other elements — write scope is exactly its own element
ID Rules
Format: kebab-case, lowercase, letters and hyphens: [a-z][a-z0-9-]*
Unique per document
Frozen once set — IDs are stable addresses. #competitive today finds the same element indefinitely. Never rename or reuse.
<!DOCTYPE html><htmllang="en"data-bp-theme="auto"><head><metacharset="UTF-8"><title>AI Memory Layer</title><metaname="idea:id"content="ai-memory-layer"><metaname="idea:status"content="in-progress"><metaname="idea:current-stage"content="trends"><metaname="idea:gates-passed"content=""><metaname="idea:created"content="2026-05-12T00:00:00Z"></head><body><maingate="required"format="prose"><ap-sourceid="raw-idea"agent="human"status="passed"outputs="raw-idea:text"><h2>Raw Idea</h2><p>The raw idea text goes here, exactly as captured.</p></ap-source><ap-gateid="trends"agent="idea-trends"status="pending"context="raw-idea"inputs="raw-idea:text"outputs="trends:score trends:recommendation"on-pass="competitive"on-fail="human-triage"
><ap-placeholder>Trends analysis pending.</ap-placeholder></ap-gate><ap-gateid="competitive"agent="idea-competitive"status="blocked"depends-on="trends"context="raw-idea trends"inputs="raw-idea:text trends:score trends:recommendation"outputs="competitive:score competitive:gaps"on-pass="phase-3"on-fail="human-triage"
><ap-placeholder>Blocked — waiting for trends to pass.</ap-placeholder></ap-gate><ap-parallelid="phase-3"depends-on="competitive"><ap-genid="icp"agent="icp-agent"status="blocked"context="raw-idea competitive"><ap-genid="mom-test"agent="mom-test-agent"status="blocked"context="raw-idea competitive"><ap-genid="mvp"agent="mvp-agent"status="blocked"context="raw-idea competitive"></ap-parallel><ap-reviewby="human"id="final-review"agent="human"status="blocked"depends-on="phase-3"
><ap-placeholder>Awaiting human review after all analysis completes.</ap-placeholder></ap-review></main></body></html>
Extending AP
AP is a protocol, not a fixed vocabulary. The <ap-*> elements are the reference implementation — the vocabulary AP ships with. Any team can define their own custom elements and remain fully within spec, as long as those elements honor the core attribute contract.
The Core Contract
Any custom element is AP-compliant if it:
Has a hyphenated tag name (W3C requirement for all custom elements)
Carries id, agent, and status on every pipeline stage element
Uses the enumerated values for status without modification
Uses on-pass, on-fail, on-skip, and depends-on for routing and guards when routing is needed
That is the entire contract. AP does not need to know your element names.
Domain Vocabulary Example
A legal team defines their own elements. An orchestrator that understands the core contract routes through this document without any changes:
The orchestrator reads agent, status, on-pass, on-fail, depends-on — the same six attributes it reads on <ap-gate>. It never needs to know what <legal-gate> means.
Rules for Domain Extensions
Tag names must contain a hyphen: legal-gate is valid; legalgate is not
Do not redefine the core attribute enum values — status="approved" instead of status="passed" breaks orchestrator compatibility
Do not add AP protocol semantics to standard HTML elements in the same document — pick one model per document
Document your element vocabulary the same way AP does: element name, who runs it, whether it produces a gate decision
What Implementors Get for Free
Because it is HTML, domain teams do not write a new parser. Every language has an HTML parser that handles custom elements:
Language
Library
JavaScript
Native DOM (querySelectorAll, XPath)
Python
BeautifulSoup, lxml
Ruby
Nokogiri
Go
golang.org/x/net/html
Rust
html5ever
An XPath query that works on <ap-gate> works identically on <legal-gate>:
//*[@status='pending'][not(ap-placeholder)] ← finds pending work in any vocabulary
Validation Checklist
Structure
Valid HTML5
<html> has no AP attributes
<head> contains at least one <meta name="[namespace]:[key]"> tag
Elements
Every AP pipeline stage uses a custom element with a hyphenated tag name
No AP protocol attributes (agent, status, on-pass, on-fail, depends-on, etc.) appear on standard HTML elements (<section>, <div>, <article>, etc.) — this is a violation, not a warning
Every leaf AP element has id, agent, status
All IDs match ^[a-z][a-z0-9-]*$ (kebab-case, no prefix required)
All IDs are unique within the document
status is one of the enumerated values
gate is one of the enumerated values (if present)
format is one of the enumerated values (if present)
An <ap-source> element never has status="running"
An <ap-review by="human"> element is never set to status="passed" by an agent
Routing and Dependencies
All IDs in depends-on reference existing element IDs in the document
All IDs in context reference existing element IDs in the document
All IDs in on-pass, on-fail, on-skip reference existing element IDs
No circular dependencies in depends-on chains
Contracts
Every key in inputs follows the [section-id]:[key-name] convention
Every key in inputs appears in a reachable upstream element's outputs
No two elements produce a key with the same fully-qualified name
Open Issues
OI-1: Formal Attribute Type Grammar
Each attribute needs a declared type for validators to be written against the spec without interpretation:
Type
Meaning
Example
string
Freeform text
agent name
enum
One value from a closed set
pending, gate
id
A single kebab-case section ID
trends
id-list
Space-separated section IDs
trends raw-idea
key-list
Space-separated namespaced contract keys
trends:score trends:recommendation
integer
Positive whole number
3
ISO-8601
Full datetime string
2026-05-12T00:00:00Z
Status: Not yet assigned to each attribute. Needed before v1.0 stability declaration.
OI-2: Multi-Domain Worked Examples
The spec uses one domain (idea validation) in all examples. Two additional worked examples are needed:
Suggested example A: Legal document review — intake, AI extraction, human-review gate, compliance gate, final approval
Suggested example B: Software CI pipeline — source commit, lint gate, test gate, build transform, deploy gate
These should live in /examples/ and use real agent names, routing decisions, and inputs/outputs contracts.
Status: Not yet written.
OI-3: Stability Promise
Every attribute needs a maturity level before open source publication:
Level
Meaning
stable
Will not change in a breaking way within a major version
experimental
May change; implementors should expect breakage
reserved
Defined but not yet implemented
Status: Maturity levels not yet assigned.
OI-4: Parallel Container Error Model
When some children of <ap-parallel> pass and some fail:
Does the container itself pass, fail, or take a new value like partial?
Does on-fail on the container fire if any child fails, or only if all children fail?
Can on-pass fire before all children complete?
Status: Semantics not yet defined. Blocking for pipelines using parallel execution with required gates.