Audiences, jobs-to-be-done and information requirements
This page is for anyone deciding what a page is for — its author, its reviewer, or whoever is designing the navigation it will sit in. It names the readers this product writes for, the job each of them arrives to finish, and the information a page must supply for that job to complete.
It exists because a surface can be accurate, well-owned and correctly bounded and still fail: the reader who needed it could not tell it was theirs, or reached it and found the one fact their decision turned on was somewhere else. Ownership answers who decides this fact. This page answers the different question of who needs it, to finish what.
It is an input to an information architecture, not a taxonomy for its own sake. Every audience below has at least one job, every job ends in a named decision or action, and every information requirement is traced to a surface that satisfies it today or recorded as a gap. The gaps are the operative output — they are the page-shapes that do not exist yet.
What governs this page
This page is downstream of five merged artifacts. It adds no claim to any of them and restates none of their definitions.
| Source | What it supplies | Where |
|---|---|---|
| Page standards | The audience enum this page’s audiences are, the four disclosure levels, and the metadata contract every page named below must satisfy | page-standards.md |
| Content-layer ownership | The L0–L6 layer model, each layer’s primary audience, and the rule that a derivative may narrow but never widen | content-ownership.md |
| ADR 0034 — one product truth | The T1–T7 authority hierarchy, hand-off 7’s three-axis ruling, and the reviewer classes that sign off a boundary | ADR 0034 |
| Product promise & message hierarchy | The one approved promise, the default-posture table, and the Provisional list | product-promise.md |
| Risk scenarios | The flagship story and three supporting threats, with the Tier 1 / Tier 2 publication gate | risk-scenarios.md |
Ticket references are plain text, not links: the tracker is not publicly readable, so a link would only reach a login wall — and a link checker scores that wall as reachable, which makes the reference look verified when it is not.
What this page does not decide
- Which pages exist, and where they sit. AAASM-5594 designs the product-site and Docs Hub sitemaps from this model. This page supplies the requirements and the gaps; it does not draw the tree.
- Any product claim. Where an audience’s requirement names a product fact, the
fact is cited to
product-promise.md,risk-scenarios.mdor a manifest row. Nothing here is a new capability statement, which is why this page carriesdescribes_capability: false. - Page metadata rules.
page-standards.mdowns the block, the field reference and the fifteen cross-field rules. This page consumes itsaudiencekey; it does not extend it. - Ownership of any content type. That is
content-ownership.md’s canonical-source table.
The reader axis, and why this page coins nothing
This is the part most likely to go wrong, so it is stated before the model rather than left implicit in it.
A reader vocabulary already exists, and this page does not own it.
page-standards.md’s audience key takes one of six values —
evaluator, developer, operator, security-engineer, contributor, auditor —
and those six are the audiences below. Not analogues of them, not a refinement of them:
the same six words, used for the same subject. Publishing a second reader vocabulary
beside that key would create exactly the two-vocabularies defect this programme exists
to eliminate, and it would do it on the one key an information architecture routes by.
The six are also already in
content-ownership.md’s
layer table, in its Primary audience column, which reads in full: anyone assessing
the company at L0; evaluators, buyers, technical leaders at L1; teams, security
engineers, operators at L2; application developers, operators, contributors, security
researchers at L3; developers who want to see it run at L4; a visitor who landed on
the repo at L5; contributors, auditors at L6. That column is the prose form of the
same axis, and this page reconciles to it rather than beside it — its security
researchers are security-engineer, and its buyers and technical leaders are
evaluator.
Three of its entries are not reader classes, and none of the three maps to an audience
value on its own:
- L0’s anyone assessing the company is an arrival, and it is outside what this product writes for entirely — the company site’s reader, not this product’s.
- L5’s a visitor who landed on the repo is also an arrival, but not out of scope:
they become a
contributor, adeveloperor anevaluatoras soon as they have a job, which is what a README’s “where its documentation is” line exists to decide. - L2’s teams is a collective, not a role — a team is some mixture of
operator,security-engineeranddeveloper, which is why the L2 cell names the first two alongside teams rather than instead of it. It routes to whichever member holds the job in hand, and no page targets it directly:audienceis a list precisely so a page can name the two or three values a team comprises.
None of the three is a seventh audience.
The axis this sits on, and the one rule that binds it
ADR 0034 hand-off 7 fixes three vocabularies, each ranging over a different subject — an action takes an ADR 0033 §6 claim term, a documentation area takes a maturity label, a product in the portfolio takes a lifecycle value — and rules that no axis may be applied to another’s subject.
The reader axis sits outside all three. Hand-off 7 counts “three vocabularies in
total”, and that count is ADR 0034’s to keep — this page is not adding a fourth row to
someone else’s table, it is observing that the audience enum is a vocabulary hand-off
7 does not range over, and asking what follows. Its subject is a person
arriving at a page, which is not an action, not a documentation area and not a
portfolio product. Its vocabulary is the audience enum, its owner is
page-standards.md, and hand-off 7’s rule applies to it in both
directions:
- No term from another axis is written about a reader here. No audience below
carries an availability value, a §6 claim term, a maturity label or a lifecycle
value. A reader is not
Unmeasuredand an audience is not🧪 Release candidate. - No term is coined on the claim axis. Forbidden design 12’s coining clause is scoped to the claim axis alone; this page adds nothing to any axis, so the question does not arise. Every product fact cited below is quoted or linked from a page that already owns it.
The one thing this page does add is the job and the information requirement, and neither is a vocabulary. A job is a sentence about a reader’s intent; a requirement is a sentence about what a page must contain. Neither ranges over an action, an area, a product or a reader class, so neither collides with anything.
Crosswalk: seven role labels, six audience values
The parent scope names seven roles. They map onto six audience values, and the
collapse is deliberate rather than a rounding error.
| Role as named in the parent scope | audience value | Note |
|---|---|---|
| Executive / Evaluator | evaluator | Job EV1 |
| PM / Engineering Leader | evaluator | Job EV3 — the same value, a different job |
| Security / Risk | security-engineer | Includes L3’s security researchers |
| QA / Assurance | auditor | L6’s audience in the layer table |
| Platform / SRE | operator | |
| Application / AI Developer | developer | |
| Maintainer / Contributor | contributor |
Two roles share evaluator, and the metadata key cannot tell them apart. An
executive deciding whether to trial at all and an engineering leader deciding what to
sequence want different pages, and audience: [evaluator] routes both to the same
place. The distinction is real and it is carried by user_job, not by a seventh
enum value — a page states which of the two it serves in the one field
page-standards.md gives it — the one field that can express it,
though that page reserves user_job for stating a page’s job generally, not for
separating two audiences that share a value. Coining a seventh
value would be an edit to someone else’s enum, made from a page that does not own it,
to express something the existing schema already expresses.
That is a recorded limitation rather than a silent one: an automated router keyed on
audience alone cannot separate EV1 from EV3. If a sitemap needs to, it reads
user_job. Whether the enum should gain a value at schema_version: 2 is
page-standards.md’s decision, and this page hands it the
evidence rather than pre-empting it.
How to read an audience entry
Each of the six carries the same seven fields, and each field exists because a sitemap needs it.
| Field | What it answers | Why an IA needs it |
|---|---|---|
| Who | Which real roles this value covers | Stops two readers being served one page by accident |
| Arrives knowing | The context the reader already has | Fixes the disclosure level an entry page opens at |
| Must be able to do | The capability the reader leaves with | The test a candidate page is judged against |
| Jobs | Each job, and the decision or action it ends in | The unit a page is designed around |
| Never hidden | What must be reachable from their route, without exception | The content a navigation redesign may not bury |
| Belongs elsewhere | Content this reader is not the audience for | The anti-persona, stated as content rather than as a person |
| Entry · next · escalation | The three-step route | The spine of the sitemap branch |
Belongs elsewhere is an anti-persona in its operative form. Naming a person nobody is writing for is unfalsifiable; naming the content that must not be on a reader’s entry page is checkable against a candidate sitemap in a single pass. Where a role is genuinely out of scope for the whole product, it is recorded once at the end rather than repeated six times.
On the identifiers
Job ids are two letters and a digit (EV1, SE1, AU1, OP1, DV1, CO1); gaps are
GAP-n. Neither shape is arbitrary. The capability manifest’s rows are a single letter
and a digit, and the letter is its domain — S sdk, H host_action, N network,
M mcp, L devtool_launch, C credentials, I identity, G degraded_mode, P
platform, eighty rows in nine series. This page cites some of them by id, so a job
called S1 and a manifest row called S1 would collide on exactly the identifier a
checking reader follows. risk-scenarios.md lettered its scenarios
F and T1–T3 for the same reason. Where a single-letter id appears below, it is the
manifest’s and is named as such.
The letter is the domain, not the owning component, and G is where that distinction
bites. Every G row is domain: degraded_mode — the series is about what happens when
a control cannot run, not about the gateway. Only three of the eleven are owned by
aa-gateway — G8, G9, G10; the other eight belong to aa-runtime (five),
aa-proxy (two) and the SDK (one). This matters for reading the citations below rather
than as a point of order: G9 is this page’s
recurring failure-posture exemplar precisely because it is a degraded-mode row, and a
reader who took G for “gateway” would look for degradation somewhere else and not find
it.
evaluator
Who. Someone deciding whether this product should be adopted, and at what altitude they need the answer. Two roles: an executive or evaluator deciding whether to trial at all, and a PM or engineering leader deciding what to sequence and what to tell a stakeholder is not yet available.
Arrives knowing. The category, and a concrete worry — an agent did something, or plausibly could. Sometimes a competitor. Does not know the product’s mechanisms, its routing model, or its platform position, and should not need to.
Must be able to do. Reach an accurate account of what the product decides, on which paths, what is on by default and what it leaves uncovered, without opening an ADR; and separate what ships today from what is decided but not built.
Jobs.
| Job | Stated as a job | Ends in |
|---|---|---|
EV1 | Decide whether this product is worth a trial | A trial started, or a recorded reason not to |
EV2 | Decide whether one stated capability meets one stated requirement | Met · met with a named limit · not met |
EV3 | Decide what to sequence, and what to tell a stakeholder is not available yet | A plan whose gaps are named rather than assumed |
Never hidden. The boundary clause, on the same screen as any headline that needs it
(product-promise.md). The default posture — a capability that
exists but is off is a different product from one that is on. The area’s maturity
label. The channel and platform position. That an approval hold has no shipped
operator surface today, which
product-promise.md carries as Provisional.
Belongs elsewhere. Protocol semantics, policy field validation rules, ADR rationale,
per-language API surfaces. An entry page that opens with an architecture diagram has
moved L3 content onto an L1 route; per
content-ownership.md,
that is content at the wrong layer, not a more thorough page.
Entry · next · escalation. Entry: the product website (T6/L1), or this hub’s index —
which carries two evaluator jobs in its Find what you need table but never names the
role, gap GAP-1. Next: product-promise.md level 3 and
source-of-truth.md. Escalation: ADR 0033 §5.3 for the platform
matrix and §6 for the vocabulary, in the core docs.
security-engineer
Who. Security and risk reviewers, and the security researchers
content-ownership.md
names as an L3 audience. One value, because they read the same pages for the same
reason: to find the edge of the boundary.
Arrives knowing. Threat modelling, and that vendor descriptions overstate. Arrives sceptical, which is the correct posture and should be rewarded rather than managed.
Must be able to do. Determine the trust boundary and its enumerated bypasses; find the failure posture of each control, including the ones that fail open; establish what an absent or degraded control reports; and file a vulnerability report at the right address.
Jobs.
| Job | Stated as a job | Ends in |
|---|---|---|
SE1 | Decide whether this boundary is acceptable for a named class of agent traffic | An approval or a refusal for one deployment |
SE2 | Determine what a quiet result means | An uninspected action read as Unmeasured rather than as clean |
SE3 | Report a vulnerability | A report filed against the owning repository’s SECURITY.md |
Never hidden. The bypass catalogue. The failure posture of every control cited,
including the silent fail-open on the budget store that
risk-scenarios.md records as row G9. That the audit chain is
tamper-evident rather than signed, and that emission is best-effort. The platform
matrix, in both directions. Understating it is a defect too — ADR 0034 grades it below
broadening “because it is less dangerous, not because it is acceptable”, and records
that understatements in this programme were introduced while correcting
overstatements, with at least one reaching main. A security reader is the audience
an understated boundary misleads most.
Belongs elsewhere. Install ergonomics, SDK API surface, positioning. A security reader does not need a getting-started path on their entry page and will read one as evasion.
Entry · next · escalation. Entry: this hub’s security-model.md
— which carries a superseded model today, recorded as gap GAP-5 below. Next: the
core threat model and ADR 0033. Escalation: the capability manifest rows and the
verification reports in the core repository.
auditor
Who. QA and assurance readers: anyone whose job is to check a published statement against something, rather than to build or to buy.
Arrives knowing. How to evaluate evidence. Does not know the codebase and should not have to read it to establish what backs a sentence.
Must be able to do. Take any published claim and reach the evidence it rests on, or establish that there is none and record that; and interpret a verification result for what it establishes rather than for what it suggests.
Jobs.
| Job | Stated as a job | Ends in |
|---|---|---|
AU1 | Find the evidence behind one published claim | A cited row, or a recorded gap |
AU2 | Verify an audit record | A result read as integrity of the entries present, not completeness of the log |
AU3 | Decide whether a demonstration may be published as evidence | Tier 1 published, or Tier 2 withheld |
Never hidden. Which statements are Provisional, and why. The Tier 1 / Tier 2
publication gate in risk-scenarios.md. That a passing chain
verification does not establish the log is whole. That absence of a finding is a fact
about the observer.
Belongs elsewhere. Positioning and conversion copy. An auditor arriving at a marketing page has been misrouted, and no amount of accuracy in that page fixes it.
Entry · next · escalation. Entry: none on this hub today — the index does not
mention this reader (gap GAP-1), and an entry alone would not be enough, because the
evidence it would route to is not published either (gap GAP-4). Next: the
determinations in risk-scenarios.md, which is the closest thing
to a claim-to-evidence route currently published. Escalation:
capability-manifest.yaml
and the verification reports — both L6, and
content-ownership.md
states that nothing in L6 is a reader-facing page, which is the shape of the gap.
operator
Who. Platform engineers and SREs: the people who put the product in front of an agent and keep it there.
Arrives knowing. How to run a service. Does not know that routing is a thing they do per agent and per launch, which is the single most consequential thing this audience learns.
Must be able to do. Route an agent on one host; install the right artifact for their platform from a channel that carries it; observe what the stack recorded; and work out why a control did not fire.
Jobs.
| Job | Stated as a job | Ends in |
|---|---|---|
OP1 | Route an agent through the product on one host | A governed launch |
OP2 | Decide what to install, on which platform, from which channel | An install performed |
OP3 | Work out why a control did not fire | A corrected configuration, or an accepted bound |
OP4 | Stand up a limited-function self-hosted stack for evaluation | A running stack |
Never hidden. That routing is per agent and per launch, so an agent nobody routed
is outside everything. The per-channel and per-platform position — the manifest’s
released_channels and released_platforms are per row, and
risk-scenarios.md records that the proxy reaches macOS through
crates.io only. Which controls are off until configured. The failure postures, so a
silent fail-open is not discovered during an incident.
Belongs elsewhere. Production orchestration commitments. Helm, Terraform and
Kubernetes are a research question under current project policy, not committed work,
and open-core-boundary.md is where the self-host scope is
stated. A page that reads as a production deployment guide has made a commitment the
product has not.
Entry · next · escalation. Entry: this hub’s Getting Started section — whose
two pages are both 🗺️ Planned, gap GAP-2. Next:
docker-containers.md and
self-host-observability.md, which describe shipping
behaviour but are filed under Operations rather than on the entry route.
Escalation: the core quick-start and CLI reference.
developer
Who. Application and AI developers integrating the product into an agent they are building.
Arrives knowing. Their framework and their language. Wants working code, and will judge the product on how quickly they get some.
Must be able to do. Add a policy checkpoint in their language; choose an SDK mode knowing what each one does; and find a runnable integration for the framework they are actually using.
Jobs.
| Job | Stated as a job | Ends in |
|---|---|---|
DV1 | Add a policy checkpoint to an agent in my language | Code that runs and reaches a decision |
DV2 | Choose an SDK mode | An explicit choice between the advisory default and the check-capable mode |
DV3 | Find a runnable integration for my framework | An example running locally |
Never hidden. That the SDK is advisory, and that a policy refusal blocks a wrapped
tool only in the check-capable mode — product-promise.md’s
default-posture table carries both. That an unadapted framework, or a call that does
not go through the framework’s dispatch, is outside the wrapper: the manifest’s S11
and S10 carry exactly those two, and S12 the raw HTTP, subprocess and filesystem
class — all three language: [python, node, go], which is what makes them the right
citation for an audience that spans three languages. A quick-start that omits them has
widened the claim by dropping a precondition. Per-language rows say more but say it
narrowly: S1’s known_bypasses list the same items plus not calling
init_assembly(), and S1 is Python — Go’s S8 has a different list.
Belongs elsewhere. The threat model, the deployment matrix, positioning. A developer needs the boundary, but as a precondition on their own code rather than as a security chapter.
Entry · next · escalation. Entry: README.md’s SDKs & components
table, or documentation.md — both branch by language, and neither
is in the sidebar (gap GAP-7). Next: the SDK documentation mounted at /python-sdk/,
/node-sdk/ and /go-sdk/ by the aggregation pipeline, which is where the first
checkpoint lives. Escalation: the core API reference and the runnable examples at L4.
contributor
Who. Maintainers and contributors, in any repository in the org, including the coding agents working under the org’s rules.
Arrives knowing. The repository they are in. Does not know the cross-repository truth hierarchy, and will otherwise fix a defect in the place they noticed it.
Must be able to do. Classify a fact and find its canonical owner; choose a sanctioned reuse pattern; write a page that satisfies the metadata contract; and route a correction to the source before the derivative.
Jobs.
| Job | Stated as a job | Ends in |
|---|---|---|
CO1 | Decide where a fact belongs before writing it | A layer and a canonical owner named in the ticket |
CO2 | Write a page that conforms | A page carrying a valid metadata block |
CO3 | Route a correction | A pull request against the canonical source first |
CO4 | Decide whether a change is a material truth change | The right reviewer class requested |
Never hidden. That depth is not a defect — no rule in this programme may be cited to thin a component’s documentation. That understating is a defect too — graded below broadening by ADR 0034, but a defect, and a contributor trimming for brevity is the commonest way one gets introduced. That an ownership dispute is a decision, not an edit, and stops rather than resolves inside a content pull request.
Belongs elsewhere. Positioning copy and conversion paths. A contributor reading those is reading the wrong layer for their job.
Entry · next · escalation. Entry: page-standards.md. Next:
content-ownership.md
and
claim-vocabulary.md.
Escalation:
ADR 0034
for precedence, waivers and the reviewer classes.
Roles this product does not write for
Recorded once rather than repeated as six anti-personas, because each is out of scope for every surface rather than for one route.
| Not an audience | Why | Where such a reader goes |
|---|---|---|
| Someone evaluating the company rather than the product | L0’s job, and L0 must not carry a per-capability status or a platform claim | horonomy.dev |
| A reader looking for agent-building guidance | This product governs an agent; it does not help write one. A page that teaches agent construction has widened the product’s subject | Framework documentation |
| A procurement or compliance reader wanting an SLA, a region or a certification | Planned, not available; asserting any of it is a managed-service claim bounded by the checklist | saas-claim-publication-checklist.md and source-of-truth.md |
A reader of the private cloud or agent-assembly-enterprise internals | Outside the public content boundary; paraphrasing does not make it publishable | The public ticket |
Information requirements
One row per (audience, job, requirement). What a page must supply is the contract: if a candidate page does not carry it, the job does not complete on that page. Where it is satisfied today is this model applied once to the surfaces that exist, which is what makes it a review instrument rather than a wish list.
Status values: ✅ satisfied — a published page carries it on that audience’s route; ◐ partial — a published page carries it, but not on that route, or not in full; ✗ gap — nothing published carries it.
Requirements for evaluator
| ID | Job | What a page must supply | Where it is satisfied today | Status |
|---|---|---|---|---|
IR-EV1-a | EV1 | The one approved promise, with its boundary clause on the same screen | product-promise.md | ◐ partial (GAP-1, GAP-8) — filed under About, and no evaluator route reaches it |
IR-EV1-b | EV1 | One concrete story of a decision the product made, with its determination | risk-scenarios.md | ✅ satisfied |
IR-EV1-c | EV1 | What is on by default, as a table rather than as prose | product-promise.md level 3 | ◐ partial (GAP-1, GAP-8) — one satisfier, and it is not on the route |
IR-EV2-a | EV2 | Per capability: whether it ships, on which channel and which platform | manifest released_channels / released_platforms (L6) | ✗ gap GAP-3, GAP-4 |
IR-EV2-b | EV2 | Per capability: whether anything reaches it by default | manifest default_state (L6); product-promise.md for the headline set | ◐ partial |
IR-EV2-c | EV2 | The stated limit that changes what may be relied on | product-promise.md, risk-scenarios.md known-boundary blocks | ✅ satisfied |
IR-EV3-a | EV3 | The maturity of each documented area | source-of-truth.md | ✅ satisfied |
IR-EV3-b | EV3 | What is decided but not built, with its ticket and no capability claim | scattered Planned statements; no roadmap surface | ✗ gap GAP-6 |
IR-EV3-c | EV3 | The open-source / managed split, so a plan can be split along it | open-core-boundary.md | ✅ satisfied |
Requirements for security-engineer
| ID | Job | What a page must supply | Where it is satisfied today | Status |
|---|---|---|---|---|
IR-SE1-a | SE1 | The trust boundary, in the current architecture rather than a superseded one | core ADR 0033 and the core security section | ◐ partial — the hub entry page is superseded (GAP-5) |
IR-SE1-b | SE1 | The enumerated bypasses, published rather than implied | risk-scenarios.md; manifest known_bypasses | ◐ partial (GAP-4) — complete only at L6 |
IR-SE1-c | SE1 | The failure posture per control, including the fail-open ones | manifest failure_posture; G9 in risk-scenarios.md | ◐ partial — one worked instance published, the rest at L6 (GAP-4) |
IR-SE1-d | SE1 | The platform matrix, stated in both directions | core ADR 0033 §5.3; restated on the hub by product-promise.md — which carries the macOS row in both directions explicitly — and by README.md’s layer 2/3 notes | ◐ partial — restated in prose on two pages, but as neither a matrix nor anything on the security-engineer route (GAP-1) |
IR-SE2-a | SE2 | That an uninspected action is reported as Unmeasured, never as clean | product-promise.md, risk-scenarios.md | ✅ satisfied |
IR-SE2-b | SE2 | What a passing chain verification does and does not establish | product-promise.md | ✅ satisfied |
IR-SE3-a | SE3 | The vulnerability reporting address for the repository in question | each repo’s SECURITY.md, falling back to the org default | ◐ partial (GAP-1) — no hub route names it; a sweep for SECURITY.md, security@ and report a vulnerability returns zero on every hub page, against a control (security) that hits on 14 of the 23 |
Requirements for auditor
| ID | Job | What a page must supply | Where it is satisfied today | Status |
|---|---|---|---|---|
IR-AU1-a | AU1 | A published route from a claim to the row or record that backs it | nothing published; the manifest is L6 | ✗ gap GAP-4 |
IR-AU1-b | AU1 | Which claims are Provisional, and the ticket that would close each | product-promise.md | ✅ satisfied |
IR-AU2-a | AU2 | What the verification command establishes, and its two negative results | product-promise.md | ✅ satisfied |
IR-AU3-a | AU3 | The Tier 1 / Tier 2 gate, and which tickets lift it | risk-scenarios.md | ✅ satisfied |
IR-AU3-b | AU3 | For a managed-service claim, the register that bounds it | saas-claim-publication-checklist.md | ◐ partial — interim, and managed-service only |
Requirements for operator
| ID | Job | What a page must supply | Where it is satisfied today | Status |
|---|---|---|---|---|
IR-OP1-a | OP1 | That routing is performed per agent and per launch | product-promise.md level 2 step 1 | ◐ partial (GAP-1) — not on the operator route |
IR-OP1-b | OP1 | The launch preconditions in full, none dropped | core quick-start; risk-scenarios.md governed-path fields | ◐ partial |
IR-OP2-a | OP2 | Which artifact reaches which platform, from which channel | manifest (L6); compatibility.md carries versions only | ✗ gap GAP-3 |
IR-OP2-b | OP2 | An install route that does not begin with an unavailable page | docker-containers.md | ✗ gap GAP-2 on the entry route |
IR-OP3-a | OP3 | Which controls are off until configured | product-promise.md level 3 | ◐ partial (GAP-8) |
IR-OP3-b | OP3 | The failure postures, including the ones that produce no decision-path signal | risk-scenarios.md for G9; manifest for the rest | ◐ partial (GAP-4) |
IR-OP4-a | OP4 | The scope of a limited-function self-host, and what it excludes | open-core-boundary.md, docker-containers.md | ✅ satisfied |
IR-OP4-b | OP4 | What the stack records, and how to read it | self-host-observability.md | ◐ partial (GAP-2) — filed off the entry route |
Requirements for developer
| ID | Job | What a page must supply | Where it is satisfied today | Status |
|---|---|---|---|---|
IR-DV1-a | DV1 | A language-specific first checkpoint, reachable from this hub | the SDK docs, mounted and listed — README.md’s SDKs & components table and documentation.md both branch by language | ◐ partial (GAP-1, GAP-7) — reachable in two hops from two index pages, absent from the sidebar, and no checkpoint on the hub itself. A sweep for init_assembly, WrapTools and the three install commands finds none on any hub page, against a control that hits |
IR-DV1-b | DV1 | The initialisation preconditions the wrapper depends on | SDK docs; manifest S1 preconditions (AA_AGENT_ID set) | ◐ partial |
IR-DV2-a | DV2 | That the SDK is advisory, and what the check-capable mode changes | product-promise.md level 3 | ◐ partial (GAP-1, GAP-8) — not on a developer route |
IR-DV2-b | DV2 | What sits outside the wrapper, stated as preconditions on their code | manifest S1 known_bypasses, and rows S10–S12 (L6) | ✗ gap GAP-4 |
IR-DV3-a | DV3 | A runnable integration per framework, and a way to choose between them | the examples repository (L4), routed from README.md’s Runnable examples section, its Find what you need table and its next-step call to action, and again from documentation.md | ◐ partial — well routed; the missing half is the chooser, since those routes name the framework dimensions but offer no way to pick between them |
Requirements for contributor
| ID | Job | What a page must supply | Where it is satisfied today | Status |
|---|---|---|---|---|
IR-CO1-a | CO1 | The canonical owner per content type | content-ownership.md | ✅ satisfied |
IR-CO1-b | CO1 | The four sanctioned reuse patterns, and when each applies | same | ✅ satisfied |
IR-CO2-a | CO2 | The metadata contract and a copyable template per page type | page-standards.md | ✅ satisfied |
IR-CO2-b | CO2 | Which audience and job a page is being written for | this page | ✅ satisfied |
IR-CO3-a | CO3 | Where a correction goes first, as an ordered procedure | content-ownership.md | ✅ satisfied |
IR-CO4-a | CO4 | The reviewer classes, and what counts as a material truth change | ADR 0034 Decision 9 | ✅ satisfied |
The gaps
This is the list AAASM-5594 turns into pages. Each row names the requirements it blocks and the page-shape it implies; none of them is a request to move an existing page without a job to justify it.
Two of these gaps are bounded by something that already exists, and the bound is the point. A gap that overstates an absence sends 5594 to build a page the hub already has — which is worse than missing the gap, because the duplicate then competes with the original for the same reader. Where a route exists and is merely thin, the row says so and narrows the ask to the residue.
The relation below is invertible, and that is a property worth relying on. Every
requirement id in a Requirements it blocks cell names that gap back in its own
Status cell, and no status cell names a gap that does not claim it — 24 pairs, checked
mechanically in both directions. So “is every gap closed by this sitemap?” is a set
comparison over the two tables, not a reading of them. It is deliberately not a
separate machine-readable block: page-standards.md and AAASM-5601
own structured page data, a second block format invented here would be exactly the
coin-a-vocabulary-someone-else-owns defect this page argues against, and 5601’s validator
would not know to check it. Two Markdown tables that parse cleanly give 5594 the same
guarantee without the new format.
| # | Gap | Requirements it blocks | Page-shape implied |
|---|---|---|---|
GAP-1 | No surface routes all six audiences; the index covers two and sends two away. README.md’s “Who this documentation is for” names teams, security engineers, and operators — the same three roles as content-ownership.md’s L2 cell, though not word for word — so it covers operator and security-engineer. Its next sentence routes “a developer who wants to contribute or integrate at the code level” off-site to the core docs, which under this page’s own crosswalk addresses both developer and contributor — addressed, but deliberately not entered here. That leaves evaluator and auditor unmentioned, and no per-audience route beyond that one paragraph. The index does carry two evaluator jobs in its Find what you need table — Compare AI Agent Assembly to other tools (EV1) and Know what is open source vs. paid (EV3) — but job-addressed rows are not a role route, which is the distinction this gap is about. The product website publishes four pages and a blog and routes by none of them | IR-EV1-a, IR-EV1-c, IR-SE1-d, IR-SE3-a, IR-OP1-a, IR-DV1-a, IR-DV2-a | A per-audience entry for the six, on both L1 and L2 — extending the index’s existing role paragraph, not replacing it |
GAP-2 | The hub’s Getting Started section contains only 🗺️ Planned pages. Both entries are labelled Coming soon, and source-of-truth.md marks the Operations area 🗺️ Planned with a managed-service page as its Where to read cell — while two pages describing shipping behaviour sit under Operations and are not named by that row | IR-OP2-b, IR-OP4-b | An operator entry that starts from what ships |
GAP-3 | No per-platform install position is published on this hub, and the channel picture is partial. compatibility.md pairs versions across the four repos, names npm and PyPI, and does name GitHub Releases (“core cuts GitHub Releases”, plus a /releases link) — so the absence is not total. But it names no Homebrew, crates.io, install-script or GHCR position, and carries no platform at any point: a whitespace-normalised sweep for linux, macos, windows, x86_64 and aarch64 returns zero hits, against a positive control that hits on the same normalised text. The per-row facts live in the manifest’s released_channels and released_platforms | IR-EV2-a, IR-OP2-a | A channel-and-platform matrix at L2, generated from the manifest and keyed on its channel vocabulary rather than a hand-written list — see the GHCR hand-off below |
GAP-4 | The evidence layer has no reader-facing surface. capability-manifest.yaml exists with a schema, a validator and a CI gate, and verification-reports/** holds the records — but content-ownership.md states nothing in L6 is a reader-facing page, and ADR 0034’s T3 approved-claims registry does not exist yet | IR-AU1-a, IR-DV2-b, and the L6-only half of IR-EV2-a, IR-SE1-b, IR-SE1-c, IR-OP3-b | A generated claim-to-evidence surface at L2 |
GAP-5 | The hub’s security entry page carries a superseded model. product-promise.md records that where this hub still carries the older framing, ADR 0033 wins, and names the migration tickets — but a reader arriving at that page first never sees the note | IR-SE1-a | A security entry rewritten against ADR 0033, not a note added to the old one |
GAP-6 | No roadmap surface exists. No file named for one is present in this repository, the product website or the core repository, checked with a positive control in the same sweep; ADR 0034 hand-off 4 assigns the owner, so the owner currently owns an empty surface | IR-EV3-b | A bounded forward-looking page at L1, in the admissible forms only |
GAP-7 | The language route exists; what is missing is a first checkpoint and a sidebar entry. Two hub pages branch by language — README.md’s SDKs & components table links /python-sdk/, /node-sdk/ and /go-sdk/, and documentation.md is a router that does the same — so a developer entry that branches by language already exists twice and must not be built again. The residue is narrower: the mounts are reachable only from those two pages’ bodies and appear nowhere in the sidebar, and no hub page carries a language-specific first checkpoint | IR-DV1-a | A sidebar route to the mounts; the checkpoint itself belongs in the SDK docs at L3, not here — see the note below |
GAP-8 | The default-posture table has exactly one satisfier, and it is filed under About. Defaults are stated at level 3, whose bound page-standards.md sets as “Must state defaults and non-coverage” — and level 3 is a must for four of the five page types (product, guide, reference, architecture), not for product alone. No hub page on an evaluator or operator route carries level 3 today | IR-EV1-a, IR-EV1-c, IR-OP3-a, IR-DV2-a | A level-3 surface on those routes. product carrying levels 1–3 is one admissible shape, not the required one |
Why GAP-7’s missing checkpoint is not a page this hub should write
IR-DV1-a asks for a language-specific first checkpoint reachable from this hub, and
the temptation is to close it by writing one here. That would be the wrong fix twice
over. content-ownership.md puts per-language API surfaces at L3 and forbids L2 a
reference of its own for anything a component owns; and this repository’s own project
instructions at
.claude/CLAUDE.md
say the hub orients readers toward component docs and does not re-author their install
steps or API surface, “which would only drift”. A checkpoint written here would
be a derivative reproducing its source at the same depth — the defect
page-standards.md names when it forbids a summary that replaces
its source.
So the closable half of GAP-7 is the route, not the content: the SDK mounts belong
in the sidebar. The checkpoint itself is the SDK docs’ to carry, and if it is thin there,
that is an L3 ticket against the SDK in question rather than anything 5594 can draw.
Four hand-offs, not gaps
Recorded here because they were found while deriving the gaps and would otherwise be lost, but none is this page’s to fix and none blocks a requirement.
-
GHCR is a published channel that the manifest’s
released_channelsvocabulary does not contain.docker-containers.mdstates that five multi-arch images are published toghcr.io/ai-agent-assembly; the manifest’sreleased_channelsvalues across all eighty rows arecrates_io,github_release,homebrew,install_script,pypi,npmandgo_modules— eight distinct values counting the sentinelnot_applicable, which is not a channel and must not become a column — with no Docker or GHCR value.GAP-3’s page-shape is a matrix generated from the manifest, so a matrix built faithfully from that vocabulary would ship without a GHCR column while the hub separately documents the images. Whether GHCR belongs in the manifest is the manifest’s owner’s call, not this page’s, and is now tracked as AAASM-5680 — but 5594 needs to know before it generates anything. -
glossary.mdalso carries the superseded model.product-promise.mdnames two pages still carrying the older framing —security-model.mdandglossary.md.GAP-5is scoped to the security entry page because that is the one on asecurity-engineerroute, but a sitemap treatingGAP-5as the complete list of superseded surfaces will miss the glossary, which is owned separately by AAASM-5658. -
page-standards.md’s note that the capability manifest has not started is now stale.capability-manifest.yamlis present in the core repository under AAASM-5531 with a schema, a semantic validator and a CI gate. That affects the reserved status ofcapability_idsand theplatforms[]hand-off, both of which that page marks as pending AAASM-5531. It ispage-standards.md’s edit to make, at whatever schema version it decides. -
The
evaluatorvalue cannot separateEV1fromEV3. Recorded above; the evidence is handed topage-standards.mdrather than resolved by coining a value here.
Using this model
To evaluate an existing page
Answer four questions in order. The first two are the ones that catch a misplaced page.
- Which audience value, and which job? Name one of the six and one job id. A page
that serves no job on this list either has an unnamed audience — in which case name
it — or does not need to exist. This is the same question
page-standards.md’saudienceanduser_jobkeys ask, so a conforming page has already answered it. - Does it carry every requirement for that job? Walk the rows for that job id. A missing requirement is either a defect in the page or a link the page must add.
- Does it carry anything from belongs elsewhere? Content for another audience on this reader’s route is the commonest cause of a page that is accurate and still unusable.
- Is anything from never hidden absent? That list has no exceptions, and its items are the ones a redesign removes first because they are the least attractive.
To evaluate a proposed navigation
- Every audience has an entry. Six values, six routes. A value with no entry means a reader with no way in.
- Every route reaches its escalation in three steps. Entry, next, escalation. A fourth step is a route nobody finishes.
- No route opens on a
🗺️ Plannedpage. GapGAP-2is what that looks like when it happens. - Every gap above is either closed by a page in the proposal, or is carried forward as a named open item. A sitemap that silently drops one has not resolved it.
- No route requires a reader to reach L6 to finish their job. Where it does today,
that is gap
GAP-4and the fix is a surface, not a deep link.
How this page meets its acceptance criteria
| Criterion | How it is met |
|---|---|
| Every audience has an explicit job-to-be-done and information contract | Six audience sections, each with a Jobs table whose every row ends in a decision or an action, and an information requirements block keyed by job id. Twenty jobs, forty requirements, each with a named satisfier or a gap, and the gap relation invertible in both directions |
| The model distinguishes non-developer technical readers from application developers and maintainers | security-engineer, operator and auditor are the non-developer technical readers and each carries its own jobs, its own never hidden list and its own belongs elsewhere boundary; developer and contributor are separate values with separate routes. The crosswalk states which of the parent scope’s seven roles lands on which value, including the two that share evaluator and the reason they are separated by user_job rather than by a coined enum value |
| The model is usable to evaluate current pages and proposed navigation | Using this model gives both checklists, and the Where it is satisfied today column is that evaluation already applied once to every published surface — which is what produced the gaps. Every absence asserted there was re-derived with a whitespace-normalised, block-markup-stripped probe carrying a positive control, because a phrase that wraps a line or crosses a table cell is invisible to a per-line search and reads as a gap that is not there |
| Website, Docs Hub, SaaS docs and project docs owners approve the boundaries | Not something a page can assert about itself. The boundaries are stated in the owning classes’ own terms — L1/T6 for positioning and the roadmap, L2/T5 for routing and maturity, L3/T4 for architecture and semantics, and the SaaS claim publication checklist for managed-service claims — so approval is the pull request’s, under ADR 0034 Decision 9, from truth-owner-website, truth-owner-docs-hub and truth-owner-core |
What this page hands off
| To | What |
|---|---|
| AAASM-5594 | The eight gaps and the forty information requirements, as the input to the product-site and Docs Hub sitemaps, related by 24 pairs that invert. The two navigation checklists are intended to be sufficient to review a proposed tree without further decisions from this page. Read GAP-1 and GAP-7 before drawing anything: both are bounded by routes that already exist on README.md, and the ask is the residue, not a new entry page |
| AAASM-5585 · AAASM-5587 | The evaluator entry and its requirements, including the default-posture table gap GAP-8 — whose constraint is a level-3 surface on the route, not a page of any particular page_type |
| AAASM-5596 · AAASM-5608 · AAASM-5611 | The per-audience never hidden lists, which bound what a rewritten page may drop. GAP-5 covers security-model.md; glossary.md carries the same superseded framing under AAASM-5658 and is not in that gap |
page-standards.md | Two records: that the evaluator value cannot separate EV1 from EV3, and that its AAASM-5531 pending note is now stale |
| AAASM-5680 | That GHCR is a published channel absent from the released_channels vocabulary, which a generated channel matrix would inherit as a missing column. Also that not_applicable is a sentinel in that vocabulary, not a channel, so a generator keying columns on distinct values must exclude it |
Last reviewed: 2026-08-07 — AI Agent Assembly Team
Last updated: 2026-08-07 by AI Agent Assembly Team