ONAS: one map of the company your apps live in
NAS describes one app. ONAS describes the company the apps live in: the things it runs on (entities), which system is the source of truth for each, how each is keyed in every system, how sensitive it is, and the words people use for it. Deliberately small, and every part of it is read by something.
Who reads it
- The hub. Every organisation's MCP address exposes
nibor_company(the whole map, with the tools that touch each entity) andnibor_resolve("förfallna fakturor för Älvsjö" answers with the invoice entity, its source of truth, its keys per system, and the facility's cost centre in Fortnox), so an AI client picks the right system and the right key instead of guessing. - Studio. When an organisation has a map, every generation gets it as context: an app built for a company whose customers live in Fortnox gets a field keyed by the Fortnox customer number, declared with
externalRef, not an invented text field. - You. Export it as JSON from nibor.io/connect and take it to the next vendor; it is yours.
Where it comes from
Nothing in the map is invented; every node carries provenance. Three sources, in order of precedence:
- Curated rows in the organisation's Connect app (Entities and Vocabulary under Company map) win for the same entity.
- Your Nibor apps contribute every model as an entity keyed by its primary field, and every field with
externalRefas a key in that other system. - Registered external systems appear as systems; their entities and keys are curated, never scraped.
The shape (excerpt)
{
"$onas": "1.0-min",
"organization": { "name": "Xtra Storage", "slug": "xtrastorage" },
"systems": [ { "id": "nibor:xtrastorage", "kind": "nibor-app" }, { "id": "fortnox", "kind": "openapi" } ],
"entities": [
{ "id": "customer", "name": "Customer", "labels": { "sv": "Kund" },
"sourceOfTruth": "fortnox", "classification": "personal",
"keys": [ { "system": "fortnox", "field": "CustomerNumber" },
{ "system": "nibor:xtrastorage", "field": "customers.fortnoxCustomerNumber" } ],
"provenance": { "kind": "curated", "ref": "entities/…" } }
],
"vocabulary": [
{ "term": "Älvsjö", "locale": "sv", "entity": "facility",
"instance": { "nibor:xtrastorage": "4b38…", "fortnox": "12" },
"provenance": { "kind": "curated", "ref": "vocabulary/…" } }
]
}
In a NAS document
A field that carries another system's key for a company entity says so:
{ "name": "fortnoxCustomerNumber", "type": "string",
"externalRef": { "system": "fortnox", "entity": "customer", "field": "CustomerNumber" } }
The compiler records it as a comment on the column; the map reads it back as a key.
Lint
An export always carries its lint: duplicate ids, a source of truth or key naming a system that is not in the map, vocabulary naming an unknown entity, a key example that looks like a real personal value, an entity that mentions personal data without being classified so, and entities that are known but keyed nowhere. Errors block an import; nothing is dropped silently.
Not yet
Field-level paths and cross-system relations, an analysis pass that proposes the map from samples, a review queue, and classification-aware grants on the hub. The format grows as those consumers arrive; the version says 1.0-min on purpose.