@flashyos/aao
v0.4.2
Published
The AAO manifest and charter format, naming standard and conformance suite — what makes an organization an Agentic Autonomous Organization on the DeAI Operating System.
Maintainers
Readme
@flashyos/aao
██
██
██████
██
██
██Seven questions decide whether an organization of AI agents deserves the name. This package asks them as executable code.
The AAO manifest format and conformance suite — what makes an organization an Agentic Autonomous Organization rather than a product with agents in it. The spec layer of the DeAI Operating System.
Why this exists
Several teams are building organizations on FlashyOS independently: StartupOS, PersonalOS, FinancialOS, and more. Each could reimplement identity, permissions, approvals and audit — and each would do it slightly differently, so nothing would compose and every one would need rewriting to combine.
An OS is a manifest and a handful of domain agents. It is never a fork of another OS. This package is that manifest format, plus the contract that decides whether a repo qualifies.
The canon this implements
This package is the executable half of documents that live elsewhere — read them together, and when they seem to disagree, the canon wins:
- What an AAO actually is — the operator definition at flashyos.com/concepts/ai-autonomous-organization, the institutional definition at gda.group.
- The naming standard — flashyos.com/standard: roles are standing responsibilities, branches are assignments, and every rule the validator below enforces is stated there in prose first.
- The spec page — flashyos.com/aao, the format itself, presented for humans.
- A charter in production — FlashyOS's own
flashyos.roles.json:
ten declared roles (
standard,directory,settlement-record,trust,onboarding,network-effects,developer-experience,release,intelligence,coordination), two families deliberately empty because inventing a role to fill a family is the roster inflation this standard exists to stop. The templates in this package follow the same discipline.
The manifest
{
"aao": "0.1",
"name": "StartupOS",
"slug": "startup-os",
"description": "A five-agent company, governed from the first command.",
"accountableTo": "[email protected]", // question five: a real, reachable human
"roles": [
{
"name": "operations", // a standing responsibility, never a person
"purpose": "Runs the books, the calendar and the vendors.",
"capabilities": ["schedule", "bookkeeping", "procure"],
"humanApprovalAtOrAbove": "LOW" // this role can spend money
}
],
"network": { "offers": ["research"], "wants": ["legal-review"] }
}Two conventions carry most of the value:
- Capabilities name actions, not departments.
deployandreview, neverengineering. A capability that names an org unit can never be enforced. - Approval thresholds go where a mistake would actually hurt, not everywhere. Uniform gates are how governance becomes theatre people route around. A read-only research role needs none; anything touching money needs one at every level.
Conformance
Seven checks, derived from the seven questions any organization has to answer about an agent holding credentials.
npx @flashyos/agent conform # exits 1 on failure — run it in CIFour are static and run from the manifest alone with no network. Three are live: whether an agent's authorizing human was recorded, whether revoking one actually stops it, and whether the org produces a real audit trail. Those cannot be declared — an org that merely claims its agents are revocable has said nothing — so they are reported as deferred rather than quietly dropped.
The list is deliberately short and deliberately hard to grow. It runs in independent builders' CI, and every check added is a constraint on people who don't work for you. A suite held together by a short contract survives; one held together by a long contract gets forked.
Naming: roles, not codenames
One test governs every name on the network. A person who has never met your organization opens the public directory, reads the role list, and knows what each one does — before clicking anything, and without a glossary.
nova · hermes · aura · sage · atlas five names, five questions
activation · retention · conversion · inbound four names, no questionsThat is the same reason a bank has a Treasurer rather than an Apollo. A role outlives whoever holds it and its name states its charter, so nobody has to be told. The market test settles it: a construction company cannot name its roles Hermes. If this is a standard other organizations adopt, it has to work for a builder in Toronto and a bank in Singapore — and function names do.
Three things people conflate
| | What it is | Lifetime | Example |
| --- | --- | --- | --- |
| Role | A standing responsibility | Years — exists when no work is in flight | retention |
| Agent | The session holding the role now | A session | a token, a heartbeat |
| Assignment | The work in flight | Days | branch retention/win-back-emails |
Naming all three with one string is why a public roster ends up reading like a git log. A role persists; an assignment does not.
The rules
import { validateRoleName, validateBranchName } from '@flashyos/aao';
validateRoleName('retention'); // []
validateRoleName('claude-agent'); // [{ rule: 'vendor', ... }]
validateRoleName('hermes'); // [{ rule: 'codename', ... }]
validateRoleName('main'); // [{ rule: 'git', ... }]A role name is lowercase, hyphen-separated, 3–24 characters, at most three
words. Rejected: model vendors (claude, gpt, copilot), git names (main),
placeholders (agent, bot, worker), trailing machine ids (-bxq1t0), and a
denylist of known codenames.
That last rule is a heuristic and is documented as one — no validator can tell
atlas from audit. A reviewer remains the real control for a codename nobody
has seen before.
Every failure names the rule broken and shows a conforming example, because an error that does not teach the rule gets worked around.
Branches are assignments
<role>/<workstream>, plus four reserved namespaces: team/, feature/,
project/ and incident/<YYYY-MM-DD>-<slug>.
Roles never get a branch of their own. Git stores refs as files, so a branch
retention and a branch retention/inbox cannot coexist — in either order.
That constraint is telling you the model is right: a role lives in the charter,
and branches are only ever the work in flight beneath it.
Families
Ten, closed, deliberately generic: growth, revenue, product,
engineering, operations, data, finance, risk, governance, support.
A taxonomy each organization extends cannot sort across organizations, which is
the whole point of having one. The family is a separate field, not part of the
name — encoding it would give every role a growth- prefix and buy nothing.
The charter
The manifest answers who are my agents. That is a register, and it is what every competing agent ecosystem publishes. A charter adds the three things an organization needs that a register does not carry:
| Field | Answers |
| --- | --- |
| repositories[] | What this organization owns, and what each repository holds |
| roles[].worksIn | Which repositories a role may push to — its jurisdiction |
| escalation | Which role decides when the charter does not answer |
{
"aao": "0.1",
"name": "FinancialOS",
"slug": "financial-os",
"accountableTo": "[email protected]",
"repositories": [
{ "name": "financial-os", "url": "github.com/example/financial-os",
"holds": ["ledger", "payments", "reporting"], "default": true },
{ "name": "financial-os-compliance", "url": "github.com/example/financial-os-compliance",
"holds": ["policies", "filings", "evidence"] }
],
"roles": [
{ "name": "settlement",
"family": "finance",
"purpose": "Moves value when an obligation completes, exactly once.",
"measure": "Unreconciled entries at end of day",
"capabilities": ["post", "reverse", "report"],
"humanApprovalAtOrAbove": "LOW",
"worksIn": ["financial-os"],
"renamedFrom": ["treasury-bot"] }
],
"escalation": "coordination"
}Charter fields are additive. A manifest with none of them stays valid, so an organization adopts this incrementally rather than in a migration.
How an agent knows where to push
Deterministically, from the charter — no model call, no other agent involved. Routing that needs judgement is a bottleneck wearing a job title.
import { resolveRepository, branchPrefix } from '@flashyos/aao';
resolveRepository(charter, 'settlement');
// { repository: { name: 'financial-os', ... }, reason: 'the only repository this role works in' }
resolveRepository(charter, 'compliance', 'filings');
// { repository: { name: 'financial-os-compliance', ... }, reason: 'holds "filings"' }
branchPrefix('settlement'); // 'settlement/'When a role works in several repositories and none matches, it returns null
with a reason naming the escalation role. It never guesses — work landing
somewhere plausible that nobody notices is the worst available outcome.
Succession
Renaming a role would otherwise orphan every event attributed to the old name.
Institutions rename offices and the record follows, so renamedFrom carries the
prior names, newest first, and the network re-points the history.
Completeness
A charter is complete when every repository has an owning role — not when all ten families are filled. Ten families across sixteen organizations is a hundred and sixty roles, most of them empty, which looks like coverage and is not. A role exists because work exists.
Templates
import { PERSONAL_OS, AMBASSADOR_OS, FINANCIAL_OS } from '@flashyos/aao';Three reference charters — one person's life, relationships at scale, money movement. They exist to prove the format generalises: fifteen roles across three unrelated domains, and a reader needs no glossary for any of them.
Copy the closest one and change every field. They are starting points, not defaults to ship.
Scaffolding a conforming charter
The templates are fixed examples with placeholder identities. When you want a charter for your org — filled in and passing L2 from the first line — scaffold one:
import { scaffoldCharter, validateCharter, runStaticConformance } from '@flashyos/aao';
const charter = scaffoldCharter({ name: 'Acme Robotics', slug: 'acme-robotics', accountable: '[email protected]' });
validateCharter(charter); // []
runStaticConformance(charter).filter((r) => r.status !== 'pass'); // [] — every static check passesIt returns a complete charter — three honest roles, one of them gated, one
repository, an escalation that names a real role — that validateCharter accepts
and every static conformance check passes. That is the definition of L2, so a
stranger reaches the second rung of the ladder in one call rather than by
hand-authoring governance they have not thought about yet. It is a floor: edit it
to describe your real organisation, then run npx @flashyos/conformance
<your-domain> --level 2 to confirm it still conforms. scaffold.test.ts runs
the checker against the output, so the scaffold can never drift into emitting
something that does not pass.
Starting an OS
npx @flashyos/agent init --template startup --org acme-os --name "Acme OS" --email [email protected]Writes acme-os.aao.json, one agent file per role, and prints the conformance
report. Nothing is overwritten if you run it again.
Adding an OS to the suite means adding a manifest to src/templates/ — not
forking the runtime. If a new OS needs a change to the format, that's a signal
the format is wrong, and it gets fixed once for everyone rather than worked
around eight times.
Staffing a role with any harness
The manifest names roles; it never names software. The agent holding a role is a session, and whatever runs that session — Claude Code, hermes-agent, a bespoke loop over a raw model API — is the harness. The spec is deliberately harness-agnostic: anything that can hold credentials, respect an approval threshold and push to a branch can staff a role.
Worked example, staffing a role with Nous Research's hermes-agent:
- Give the session the role's charter entry — its
purpose,capabilitiesandworksIn— as standing context. Most harnesses read anAGENTS.md-style doctrine file; this repo ships its own. - Name everything by the role. The session works as
retention, pushes toretention/<workstream>, and appears in the public directory asretention. Note that the validator rejectshermesas a role name — on purpose. Hermes names the software; a role names the responsibility. The same string can be a fine harness name and a failing role name, and that line is the entire naming standard. - Enforce the threshold at the harness boundary.
humanApprovalAtOrAboveis a property of the role, so whichever harness staffs it must gate those actions on its human channel — hermes has one built in; a CI-driven harness uses required reviews. - Run
npx @flashyos/agent conformin the org's CI. Conformance checks the organization, not the harness, so a mixed fleet — one role on Claude Code, one on hermes, one hand-rolled — passes or fails as one org.
An organization that swaps a role's harness changes nothing in its manifest. That is the point: roles outlive the software that staffs them, the way offices outlive office-holders.
Compatible with skills standards
Skills standards such as agentskills.io describe what an agent can do; the AAO manifest governs what it is authorized to do, and which human answers for it. Capability and authority are different axes, so an agent carries both without conflict — its skills travel with the harness, its role and thresholds live in the charter. Neither standard has to lose for the other to win.
⚡ The Strike
This README commits to a secret, the way conformance commits to its answers:
sha256: bb5372b0b56678d6bc85b2b052ab1c4c1c97c794e1e0d60879d84119d31eb45aThe preimage is a single line a careful reader of this package can reconstruct
exactly. Recover it, verify the hash yourself, and open an issue titled
⚡ STRIKE with the preimage — the first verified striker per release is
sealed into the repo's STRIKERS.md.
And one more thing, in the Nintendo sense: the conformance suite knows an eighth question. It is only ever asked of someone whose manifest has already answered the first seven. No flag enables it. Nothing disables it.
License
Apache-2.0. The spec is open; the network that enforces it live is a product. Fork the rules, run your own conformance, verify anyone's manifest.
