{
 "name": "VOLO Ontology",
 "about": "The objects, links, actions and functions behind flyvolo.ai — how AI and automation change occupations, task by task. Modelled on Palantir's Ontology: semantic elements (object types, properties, links) and kinetic elements (actions, functions, permissions). Judgements are first-class objects; every change to them is an action with criteria and a log.",
 "license": "CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/",
 "attribution": "VOLO (flyvolo.ai) — please credit and link to https://flyvolo.ai/en/data",
 "refusals": [
  "No property, function or tool returns a probability of losing a job, a combined risk score, or a number of years.",
  "Capability, deployment and employment change are separate evidence stages and are never summed.",
  "AI agents on the public MCP can read; they cannot take any action. Suggestions about judgements become proposals decided by a named person."
 ],
 "objectTypes": [
  {
   "id": "Occupation",
   "description": "An occupation assessed on this site, task by task. The impact index is a labelled composite, never a probability, and is always shown with its confidence and date.",
   "primaryKey": "<slug>",
   "titleProperty": "name",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [
    "Dated"
   ],
   "properties": [
    {
     "id": "slug",
     "type": "id",
     "required": true,
     "description": "Canonical id; aliases resolve to it."
    },
    {
     "id": "name",
     "type": "multilingual",
     "required": true,
     "description": "Name in six languages."
    },
    {
     "id": "industry",
     "type": "multilingual",
     "required": true,
     "description": "Industry label."
    },
    {
     "id": "impactIndex",
     "type": "number",
     "required": true,
     "description": "0–100 composite of task exposure and adoption maturity. Not a probability of losing a job."
    },
    {
     "id": "confidence",
     "type": "enum",
     "values": [
      "high",
      "medium",
      "low"
     ],
     "required": true,
     "description": "Confidence in the index; never shown apart from it."
    },
    {
     "id": "assessedOn",
     "type": "date",
     "required": true,
     "description": "When the page was last assessed."
    },
    {
     "id": "scope",
     "type": "multilingual",
     "required": true,
     "description": "Where the assessment applies and what it does not cover."
    }
   ],
   "count": 90
  },
  {
   "id": "Task",
   "description": "A unit of work inside one occupation. The task, not the job, is the unit of every judgement.",
   "primaryKey": "<slug>/<taskId>",
   "titleProperty": "name",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "Task id, unique within its occupation."
    },
    {
     "id": "name",
     "type": "multilingual",
     "required": true,
     "description": "What practitioners would call it."
    },
    {
     "id": "what",
     "type": "multilingual",
     "required": true,
     "description": "What the task concretely involves."
    },
    {
     "id": "weight",
     "type": "enum",
     "values": [
      "core",
      "significant",
      "peripheral"
     ],
     "required": true,
     "description": "Share of the role; explains reach, never used as a probability."
    },
    {
     "id": "dimensions",
     "type": "list",
     "values": [
      "cognitive",
      "physical",
      "mobility",
      "process"
     ],
     "required": true,
     "description": "Which kinds of technology bear on it."
    },
    {
     "id": "noActivityReason",
     "type": "enum",
     "values": [
      "new-work",
      "not-in-profile",
      "no-onet"
     ],
     "required": false,
     "description": "Why no O*NET work activity is aligned: work O*NET does not describe yet (emerging tasks only), nothing in O*NET's list for this occupation, or no O*NET occupation at all."
    }
   ],
   "count": 470
  },
  {
   "id": "TaskJudgement",
   "description": "A decision about which way a task is moving, the layer of evidence it stands on, why, and what it does not establish. This is the object the rest of the ontology exists to support.",
   "primaryKey": "<slug>/<taskId>@<assessedOn>",
   "titleProperty": "direction",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [
    "Judged",
    "Dated"
   ],
   "properties": [
    {
     "id": "direction",
     "type": "enum",
     "values": [
      "automating",
      "augmenting",
      "human_led",
      "emerging"
     ],
     "required": true,
     "description": "Automating, augmented by tools, still led by people, or newly created by automation."
    },
    {
     "id": "basis",
     "type": "enum",
     "values": [
      "evidenced",
      "inferred",
      "uncertain"
     ],
     "required": true,
     "description": "Derived from verified evidence under the baseline-weight rule, never hand-set to evidenced."
    },
    {
     "id": "reasoning",
     "type": "multilingual",
     "required": true,
     "description": "The mechanism, not just the conclusion."
    },
    {
     "id": "limits",
     "type": "multilingual",
     "required": true,
     "description": "What this judgement does not establish."
    },
    {
     "id": "assessedOn",
     "type": "date",
     "required": true,
     "description": "Date of the assessment this judgement belongs to."
    }
   ],
   "count": 470
  },
  {
   "id": "Evidence",
   "description": "A dated event with a source, graded by stage. Capability, deployment and employment change are separate stages and are never summed.",
   "primaryKey": "<id>",
   "titleProperty": "title",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [
    "Sourced",
    "Dated"
   ],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "ev-YYYYMMDD-<occupation>-<n>."
    },
    {
     "id": "title",
     "type": "multilingual",
     "required": true,
     "description": "What happened, stated without verdict words unless attributed."
    },
    {
     "id": "occurredOn",
     "type": "date",
     "required": true,
     "description": "What the source establishes, from the document's own publication line."
    },
    {
     "id": "stage",
     "type": "enum",
     "values": [
      "rumor",
      "forecast",
      "capability",
      "worker_adoption",
      "pilot",
      "deployment",
      "labor_impact",
      "mandate",
      "rule_not_enacted",
      "constraint"
     ],
     "required": true,
     "description": "Where the event sits between capability and employment change."
    },
    {
     "id": "dimension",
     "type": "enum",
     "values": [
      "cognitive",
      "physical",
      "mobility",
      "process"
     ],
     "required": true,
     "description": "Kind of technology."
    },
    {
     "id": "sourceTier",
     "type": "enum",
     "values": [
      "primary",
      "secondary"
     ],
     "required": true,
     "description": "Primary: the party itself or the authority of record. Secondary needs a co-signature."
    },
    {
     "id": "status",
     "type": "enum",
     "values": [
      "candidate",
      "verified"
     ],
     "required": true,
     "description": "Only verified records reach pages and move judgements."
    },
    {
     "id": "verifiedBy",
     "type": "string",
     "required": false,
     "description": "Named verifier; required once verified."
    },
    {
     "id": "scope",
     "type": "multilingual",
     "required": true,
     "description": "Where it applies and what it does not show."
    }
   ],
   "count": 241
  },
  {
   "id": "Pathway",
   "description": "A route out of or within an occupation, with its real constraints and one thing to verify this week.",
   "primaryKey": "<slug>/<n>",
   "titleProperty": "title",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "kind",
     "type": "enum",
     "values": [
      "stay",
      "reshape",
      "adjacent",
      "cross"
     ],
     "required": true,
     "description": "Stay, reshape the role, move adjacent, or cross over."
    },
    {
     "id": "title",
     "type": "multilingual",
     "required": true,
     "description": "The route."
    },
    {
     "id": "constraints",
     "type": "multilingual",
     "required": true,
     "description": "Time, cost, income gap, entry barriers."
    },
    {
     "id": "verifyThisWeek",
     "type": "multilingual",
     "required": true,
     "description": "One concrete step that produces evidence."
    }
   ],
   "count": 267
  },
  {
   "id": "Degree",
   "description": "A field of study, with at least three paths and no score.",
   "primaryKey": "<slug>",
   "titleProperty": "name",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "slug",
     "type": "id",
     "required": true,
     "description": "Canonical id."
    },
    {
     "id": "name",
     "type": "multilingual",
     "required": true,
     "description": "Name in six languages."
    }
   ],
   "count": 18
  },
  {
   "id": "BusinessFunction",
   "description": "A department of a company; every occupation belongs to exactly one.",
   "primaryKey": "<id>",
   "titleProperty": "name",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "Function id."
    },
    {
     "id": "name",
     "type": "multilingual",
     "required": true,
     "description": "Name in six languages."
    }
   ],
   "count": 13
  },
  {
   "id": "Note",
   "description": "A long-form piece in which every section cites records or task judgements.",
   "primaryKey": "<slug>",
   "titleProperty": "title",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "slug",
     "type": "id",
     "required": true,
     "description": "Note id."
    },
    {
     "id": "title",
     "type": "multilingual",
     "required": true,
     "description": "Title."
    }
   ],
   "count": 6
  },
  {
   "id": "Capability",
   "description": "A half-year checkpoint of commercially available capability, anchored where possible to a primary source.",
   "primaryKey": "<id>",
   "titleProperty": "label",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [
    "Dated"
   ],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "Checkpoint id."
    },
    {
     "id": "at",
     "type": "date",
     "required": true,
     "description": "Date the checkpoint is drawn at."
    },
    {
     "id": "label",
     "type": "multilingual",
     "required": true,
     "description": "Axis label."
    }
   ],
   "count": 9
  },
  {
   "id": "ClassificationConcept",
   "description": "A code in a public classification (O*NET-SOC, SOC 2018, CIP 2020, ESCO, ISCO-08, SSOC 2024). Read-only reference data owned by its publisher; VOLO never edits it, only maps to it with a stated fit.",
   "primaryKey": "<scheme>:<code>",
   "titleProperty": "title",
   "owner": "publisher",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "scheme",
     "type": "enum",
     "values": [
      "onet-soc",
      "soc-2018",
      "cip-2020",
      "esco",
      "isco-08",
      "ssoc-2024"
     ],
     "required": true,
     "description": "Which classification."
    },
    {
     "id": "code",
     "type": "id",
     "required": true,
     "description": "The code as the publisher writes it."
    },
    {
     "id": "title",
     "type": "string",
     "required": true,
     "description": "The publisher's own title."
    }
   ],
   "count": 483
  },
  {
   "id": "WorkActivity",
   "description": "An O*NET work activity: detailed (DWA), intermediate (IWA) or generalized (GWA) — O*NET 31.0 has 2,087, 332 and 41. Read-only reference data owned by O*NET; VOLO only aligns its tasks to detailed activities with a stated fit. The graph holds the activities our tasks use and their parents.",
   "primaryKey": "<O*NET element id>",
   "titleProperty": "title",
   "owner": "onet",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "O*NET's element id, e.g. 4.A.4.a.8.c.5."
    },
    {
     "id": "level",
     "type": "enum",
     "values": [
      "detailed",
      "intermediate",
      "generalized"
     ],
     "required": true,
     "description": "DWA, IWA or GWA."
    },
    {
     "id": "title",
     "type": "string",
     "required": true,
     "description": "O*NET's own English sentence, verbatim."
    },
    {
     "id": "name",
     "type": "multilingual",
     "required": false,
     "description": "Six languages, for detailed and generalized activities. The translations are ours, not O*NET's."
    }
   ],
   "count": 525
  },
  {
   "id": "Regulation",
   "description": "A rule some verified record reads: a law, a regulation, a court rule, a regulator's guidance, a collective agreement, or a bill that did not pass. The text is its publisher's; how each record reads it (provision, verb, whom it binds) is ours.",
   "primaryKey": "<jurisdiction>/<short-id>",
   "titleProperty": "title",
   "owner": "publisher",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "<jurisdiction>/<short-id>."
    },
    {
     "id": "title",
     "type": "string",
     "required": true,
     "description": "The publisher's own name, in its own language; it must appear word for word in a record that reads it."
    },
    {
     "id": "kind",
     "type": "enum",
     "values": [
      "legislation",
      "regulation",
      "court-rule",
      "guidance",
      "collective-agreement",
      "bill"
     ],
     "required": true,
     "description": "What sort of instrument it is."
    },
    {
     "id": "adopted",
     "type": "enum",
     "values": [
      "yes",
      "no"
     ],
     "required": true,
     "description": "Whether it became a rule (a vetoed bill did not)."
    }
   ],
   "count": 41
  },
  {
   "id": "Jurisdiction",
   "description": "Where a rule applies: a country, a US state, a Canadian province, or the European Union.",
   "primaryKey": "<code>",
   "titleProperty": "name",
   "owner": "volo",
   "storedIn": "repository",
   "implements": [],
   "properties": [
    {
     "id": "code",
     "type": "id",
     "required": true,
     "description": "eu, us, us-ca, jp, sg…"
    },
    {
     "id": "name",
     "type": "multilingual",
     "required": true,
     "description": "Name in six languages."
    }
   ],
   "count": 12
  },
  {
   "id": "Proposal",
   "description": "A lead, never a judgement: a verified record whose task shares an O*NET detailed activity with a task in another occupation. Derived at build time; its status is a fact (accepted when that occupation has its own verified record citing the same source, rejected with a named reason, otherwise open). Not shown on pages.",
   "primaryKey": "<record id>→<slug>/<taskId>",
   "titleProperty": "id",
   "owner": "volo",
   "storedIn": "derived",
   "implements": [],
   "properties": [
    {
     "id": "id",
     "type": "id",
     "required": true,
     "description": "<record id>→<slug>/<taskId>."
    },
    {
     "id": "status",
     "type": "enum",
     "values": [
      "open",
      "accepted",
      "rejected"
     ],
     "required": true,
     "description": "Computed from the evidence and the rejections, never written by hand."
    }
   ],
   "count": 114
  },
  {
   "id": "Source",
   "description": "A document an evidence record cites, identified by its URL.",
   "primaryKey": "<url>",
   "titleProperty": "name",
   "owner": "publisher",
   "storedIn": "derived",
   "implements": [],
   "properties": [
    {
     "id": "url",
     "type": "url",
     "required": true,
     "description": "Where the document answers."
    },
    {
     "id": "name",
     "type": "string",
     "required": true,
     "description": "Publisher — document."
    }
   ],
   "count": 221
  },
  {
   "id": "Subscriber",
   "description": "A person who asked for the weekly digest (double opt-in).",
   "primaryKey": "<email>",
   "titleProperty": "email",
   "owner": "user",
   "storedIn": "agent database",
   "implements": [],
   "properties": [
    {
     "id": "email",
     "type": "id",
     "required": true,
     "description": "Stored only in the agent's database."
    }
   ]
  },
  {
   "id": "WaitlistEntry",
   "description": "A person who asked to be told when the first paid product opens. Only confirmed rows count.",
   "primaryKey": "<email>",
   "titleProperty": "email",
   "owner": "user",
   "storedIn": "agent database",
   "implements": [],
   "properties": [
    {
     "id": "email",
     "type": "id",
     "required": true,
     "description": "Stored only in the agent's database."
    }
   ]
  },
  {
   "id": "ProAccount",
   "description": "A paid personal MCP address: entitlement, keys stored as SHA-256 only, and the person's own profile (follows, marked tasks).",
   "primaryKey": "<email>",
   "titleProperty": "email",
   "owner": "user",
   "storedIn": "agent database",
   "implements": [],
   "properties": [
    {
     "id": "email",
     "type": "id",
     "required": true,
     "description": "Stored only in the agent's database."
    }
   ]
  }
 ],
 "linkTypes": [
  {
   "id": "hasTask",
   "from": "Occupation",
   "to": [
    "Task"
   ],
   "cardinality": "one-to-many",
   "source": "volo",
   "description": "An occupation is made of tasks; each task belongs to exactly one occupation.",
   "count": 470
  },
  {
   "id": "judgedAs",
   "from": "Task",
   "to": [
    "TaskJudgement"
   ],
   "cardinality": "one-to-one",
   "source": "volo",
   "description": "The current judgement of a task. Earlier judgements live in git history until the proposal log exists (P4).",
   "count": 470
  },
  {
   "id": "supports",
   "from": "Evidence",
   "to": [
    "Task"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "The tasks an evidence record bears on. A verified record can move their basis under the baseline-weight rule.",
   "count": 357
  },
  {
   "id": "cites",
   "from": "Evidence",
   "to": [
    "Source"
   ],
   "cardinality": "many-to-one",
   "source": "volo",
   "description": "The document behind a record.",
   "count": 241
  },
  {
   "id": "offersPathway",
   "from": "Occupation",
   "to": [
    "Pathway"
   ],
   "cardinality": "one-to-many",
   "source": "volo",
   "description": "Routes offered on an occupation page.",
   "count": 267
  },
  {
   "id": "inFunction",
   "from": "Occupation",
   "to": [
    "BusinessFunction"
   ],
   "cardinality": "many-to-one",
   "source": "volo",
   "description": "The department an occupation sits in.",
   "count": 90
  },
  {
   "id": "leadsTo",
   "from": "Degree",
   "to": [
    "Occupation"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "Occupations a degree's paths lead to on this site.",
   "count": 66
  },
  {
   "id": "classifiedAs",
   "from": "Occupation",
   "to": [
    "ClassificationConcept"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "Which public classification code an occupation corresponds to. The fit is itself a judgement.",
   "properties": [
    {
     "id": "fit",
     "type": "enum",
     "values": [
      "exact",
      "broader",
      "narrower",
      "closest"
     ],
     "required": true,
     "description": "exact / broader / narrower / closest — SKOS exactMatch / broadMatch / narrowMatch / closeMatch."
    }
   ],
   "count": 367
  },
  {
   "id": "degreeClassifiedAs",
   "from": "Degree",
   "to": [
    "ClassificationConcept"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "Which CIP 2020 code a degree corresponds to.",
   "properties": [
    {
     "id": "fit",
     "type": "enum",
     "values": [
      "exact",
      "broader",
      "narrower",
      "closest"
     ],
     "required": true,
     "description": "Same four fits."
    }
   ],
   "count": 23
  },
  {
   "id": "crosswalk",
   "from": "ClassificationConcept",
   "to": [
    "ClassificationConcept"
   ],
   "cardinality": "many-to-many",
   "source": "nces",
   "description": "NCES CIP 2020 → SOC 2018: which occupations a field of study officially leads to.",
   "count": 160
  },
  {
   "id": "refinesSoc",
   "from": "ClassificationConcept",
   "to": [
    "ClassificationConcept"
   ],
   "cardinality": "many-to-one",
   "source": "onet",
   "description": "An O*NET-SOC code is a SOC 2018 detailed code plus a suffix; this link joins the NCES crosswalk to the codes our occupations map to.",
   "count": 31
  },
  {
   "id": "escoWithinIsco",
   "from": "ClassificationConcept",
   "to": [
    "ClassificationConcept"
   ],
   "cardinality": "many-to-one",
   "source": "esco",
   "description": "An ESCO occupation sits inside one ISCO-08 unit group: its ESCO code is the ISCO code plus a suffix.",
   "count": 84
  },
  {
   "id": "ssocCorrespondsToIsco",
   "from": "ClassificationConcept",
   "to": [
    "ClassificationConcept"
   ],
   "cardinality": "many-to-many",
   "source": "singstat",
   "description": "The Singapore Department of Statistics' own correspondence between SSOC 2024 and ISCO-08.",
   "count": 84
  },
  {
   "id": "alignsTo",
   "from": "Task",
   "to": [
    "WorkActivity"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "Which O*NET detailed work activity a task corresponds to, chosen only from the activities O*NET lists for the occupation's own codes. The fit is our judgement; an alignment never changes a direction, a basis or an index.",
   "properties": [
    {
     "id": "fit",
     "type": "enum",
     "values": [
      "exact",
      "broader",
      "narrower",
      "closest"
     ],
     "required": true,
     "description": "exact / broader / narrower / closest, measured against the task."
    }
   ],
   "count": 397
  },
  {
   "id": "activityPartOf",
   "from": "WorkActivity",
   "to": [
    "WorkActivity"
   ],
   "cardinality": "many-to-one",
   "source": "onet",
   "description": "O*NET's hierarchy: a detailed activity sits in one intermediate activity, which sits in one generalized activity.",
   "count": 487
  },
  {
   "id": "sharesActivity",
   "from": "Task",
   "to": [
    "Task"
   ],
   "cardinality": "many-to-many",
   "source": "derived",
   "description": "Tasks in two different occupations aligned to the same detailed activity. Computed from alignsTo; a pointer between pages, not a measure of similarity.",
   "count": 154
  },
  {
   "id": "concerns",
   "from": "Evidence",
   "to": [
    "Regulation"
   ],
   "cardinality": "many-to-one",
   "source": "volo",
   "description": "The rule a record reads, or the rule being enforced in it.",
   "properties": [
    {
     "id": "role",
     "type": "enum",
     "values": [
      "text",
      "enforcement"
     ],
     "required": true,
     "description": "text = the record reads the rule; enforcement = the record is the rule being enforced."
    }
   ],
   "count": 55
  },
  {
   "id": "inJurisdiction",
   "from": "Regulation",
   "to": [
    "Jurisdiction"
   ],
   "cardinality": "many-to-one",
   "source": "volo",
   "description": "Where the rule applies.",
   "count": 41
  },
  {
   "id": "bearsOn",
   "from": "Regulation",
   "to": [
    "Task"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "How a record reads the rule for one of its tasks: the provision, the verb that matters, whom it binds, and whether it requires a person. A reading never changes a direction, a basis or an index.",
   "properties": [
    {
     "id": "provision",
     "type": "string",
     "required": false,
     "description": "As the text writes it."
    },
    {
     "id": "verb",
     "type": "enum",
     "values": [
      "must",
      "must-not",
      "may",
      "should",
      "defines",
      "funds"
     ],
     "required": true,
     "description": "must / must-not / may / should (best efforts, an expectation) / defines / funds."
    },
    {
     "id": "subject",
     "type": "enum",
     "values": [
      "person",
      "organisation",
      "authority"
     ],
     "required": true,
     "description": "Whom it binds."
    },
    {
     "id": "requiresHuman",
     "type": "enum",
     "values": [
      "yes",
      "no"
     ],
     "required": true,
     "description": "Whether the provision requires a person to do, decide or answer for the work."
    },
    {
     "id": "record",
     "type": "id",
     "required": true,
     "description": "The record this reading comes from."
    }
   ],
   "count": 87
  },
  {
   "id": "triggeredBy",
   "from": "Proposal",
   "to": [
    "Evidence"
   ],
   "cardinality": "many-to-one",
   "source": "derived",
   "description": "The verified record the proposal starts from.",
   "count": 114
  },
  {
   "id": "about",
   "from": "Proposal",
   "to": [
    "Task"
   ],
   "cardinality": "many-to-one",
   "source": "derived",
   "description": "The task in another occupation the record might also bear on.",
   "count": 114
  },
  {
   "id": "via",
   "from": "Proposal",
   "to": [
    "WorkActivity"
   ],
   "cardinality": "many-to-many",
   "source": "derived",
   "description": "The O*NET detailed activities the two tasks share.",
   "count": 116
  },
  {
   "id": "relatedTo",
   "from": "Occupation",
   "to": [
    "Occupation"
   ],
   "cardinality": "many-to-many",
   "source": "onet",
   "description": "O*NET's related occupations, where both have a page here.",
   "count": 217
  },
  {
   "id": "noteCites",
   "from": "Note",
   "to": [
    "Evidence",
    "Task"
   ],
   "cardinality": "many-to-many",
   "source": "volo",
   "description": "What each section of a long-form piece rests on.",
   "count": 90
  }
 ],
 "interfaces": [
  {
   "id": "Judged",
   "description": "Anything that states a judgement must say what layer it stands on, why, and what it does not establish.",
   "properties": [
    "basis",
    "reasoning",
    "limits"
   ]
  },
  {
   "id": "Sourced",
   "description": "Anything taken from a document names the document, its tier and the date the document itself establishes.",
   "properties": [
    "sourceTier",
    "occurredOn"
   ]
  },
  {
   "id": "Dated",
   "description": "Anything that can go stale carries the date it was true on.",
   "properties": []
  }
 ],
 "actors": [
  {
   "id": "ceo",
   "description": "The CEO: everything, plus money, entitlements, legal and licensing."
  },
  {
   "id": "named-verifier",
   "description": "A named person or a named Claude agent in an attended session: all evidence actions, mappings, judgement changes (with a memo)."
  },
  {
   "id": "evidence-loop",
   "description": "The unattended twice-daily run: may add content and nothing else (apps/web/scripts/harness.mjs)."
  },
  {
   "id": "public-agent",
   "description": "Any AI agent on the public MCP: read-only tools, no actions."
  },
  {
   "id": "pro-user",
   "description": "A paying person through their own MCP address or account page: only their own objects."
  },
  {
   "id": "visitor",
   "description": "Anyone on the site: subscribe and join the waitlist."
  }
 ],
 "actionTypes": [
  {
   "id": "addEvidence",
   "description": "Record a candidate evidence record for one occupation and the tasks it bears on.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "occupation",
    "task",
    "url",
    "occurred",
    "stage",
    "dimension",
    "source-tier",
    "source-name",
    "title-en",
    "title-zh",
    "scope-en",
    "scope-zh"
   ],
   "criteria": [
    "The source URL answers to the script (a 202 is a challenge page, not the document).",
    "Title is one sentence (≤200 characters in English, ≤100 in Chinese).",
    "Every record declares its source tier; a verbatim mirror is primary only with mirrorOf.",
    "Forecasts name who and by when; they never move a baseline.",
    "A vendor's material about its own product: at most one per occupation, never the only evidence, never moves a baseline.",
    "Scope says what the evidence is, never how many sources a page has."
   ],
   "actors": [
    "named-verifier",
    "evidence-loop"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "events.json (status candidate, addedOn) and git history"
  },
  {
   "id": "verifyEvidence",
   "description": "A named verifier confirms the source says what the record says; the record goes live and may move task bases.",
   "edits": [
    "Evidence",
    "TaskJudgement"
   ],
   "parameters": [
    "id",
    "by"
   ],
   "criteria": [
    "A named verifier is required.",
    "The source is probed again; a challenged source needs a recorded browser reading.",
    "Secondary sources need a co-signature; primary sources may not carry one.",
    "`no` never flips a task, `yes` flips on one record, `cautious` needs two independent records."
   ],
   "actors": [
    "named-verifier",
    "evidence-loop"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "verifiedBy / verifiedOn on the record, and git history"
  },
  {
   "id": "annotateEvidence",
   "description": "Say what a record means, what it does not show yet, and how a reader can verify it.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "id",
    "means-en",
    "means-zh",
    "not-yet-en",
    "not-yet-zh",
    "verify-en",
    "verify-zh",
    "changes-note-en",
    "changes-note-zh",
    "by"
   ],
   "criteria": [
    "Verdict words are allowed only when attributed."
   ],
   "actors": [
    "named-verifier",
    "evidence-loop"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "interpretation on the record"
  },
  {
   "id": "cosignEvidence",
   "description": "A second person co-signs a secondary-source record.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "id",
    "by"
   ],
   "criteria": [
    "Only secondary records take a co-signature, and not from the original verifier."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "cosign fields on the record"
  },
  {
   "id": "resourceEvidence",
   "description": "Replace a record's source with a better one (usually the primary original); the record must be verified again.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "id",
    "url",
    "source-name",
    "source-tier",
    "why",
    "by"
   ],
   "criteria": [
    "Say why the new source is better; the record returns to candidate."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "sourceHistory on the record"
  },
  {
   "id": "correctEvidence",
   "description": "Correct the wording that depends on a source, saying what the original actually says.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "id",
    "why",
    "title-en",
    "title-zh",
    "scope-en",
    "scope-zh",
    "by"
   ],
   "criteria": [
    "A reason is required; every changed field is logged with its old value."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "textHistory on the record"
  },
  {
   "id": "classifyEvidence",
   "description": "Declare that a record's source is a vendor's material about its own product, so the vendor-document rules apply.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "id",
    "vendor-doc-product",
    "vendor-doc-stake-en",
    "vendor-doc-stake-zh",
    "why",
    "by"
   ],
   "criteria": [
    "Stake declared in two languages; the vendor-document cap applies from then on."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "textHistory (vendorDoc) on the record"
  },
  {
   "id": "relinkEvidence",
   "description": "Change which tasks a record bears on; it returns to candidate, because that is what verification judges.",
   "edits": [
    "Evidence",
    "TaskJudgement"
   ],
   "parameters": [
    "id",
    "tasks",
    "why",
    "by"
   ],
   "criteria": [
    "Task ids must exist on the occupation; the record returns to candidate."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "textHistory on the record"
  },
  {
   "id": "reassignEvidence",
   "description": "Move a record to another occupation (id unchanged, it is a URL) together with the tasks it supports there.",
   "edits": [
    "Evidence",
    "TaskJudgement"
   ],
   "parameters": [
    "id",
    "to",
    "tasks",
    "why",
    "by"
   ],
   "criteria": [
    "The target occupation and tasks must exist; the move is logged."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "textHistory on the record"
  },
  {
   "id": "mergeTranslations",
   "description": "Write translations of new or changed text into the four derived languages and record the English they were made from.",
   "edits": [
    "Occupation",
    "Task",
    "TaskJudgement",
    "Evidence"
   ],
   "parameters": [
    "locale",
    "paths"
   ],
   "criteria": [
    "No cross-language fallback: every surface exists in every language, or the build fails."
   ],
   "actors": [
    "named-verifier",
    "evidence-loop"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "sources.json fingerprints and git history"
  },
  {
   "id": "regenerateArtefacts",
   "description": "Rebuild the picker, roster, sample cards and open data from the content.",
   "edits": [],
   "parameters": [],
   "criteria": [
    "Generated files match the content byte for byte, or the tests fail."
   ],
   "actors": [
    "named-verifier",
    "evidence-loop"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history"
  },
  {
   "id": "setTaskJudgement",
   "description": "Change a task's direction, reasoning or limits (the basis is derived, not set). Recorded in a memo.",
   "edits": [
    "TaskJudgement"
   ],
   "parameters": [
    "occupation",
    "task",
    "direction",
    "reasoning",
    "limits"
   ],
   "criteria": [
    "Limits are required and may not reassure; no platitudes; 'how long do I have' is never answered with a year.",
    "The impact index never changes automatically."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history and the wave's memo"
  },
  {
   "id": "addOccupation",
   "description": "Add an occupation with its tasks, paths, FAQs, trajectory, business function, map sector, classification mapping, illustrations and share images.",
   "edits": [
    "Occupation",
    "Task",
    "TaskJudgement",
    "Pathway"
   ],
   "parameters": [
    "slug"
   ],
   "criteria": [
    "At least four tasks and four FAQs, every task with limits, trajectory ending at the published index.",
    "Every classification code exists in the stated version."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history and the wave's memo"
  },
  {
   "id": "mapClassification",
   "description": "Map an occupation or degree to a public classification code with a stated fit.",
   "edits": [
    "ClassificationConcept"
   ],
   "parameters": [
    "subject",
    "scheme",
    "code",
    "fit"
   ],
   "criteria": [
    "The code must exist in the stated version; the fit is one of four, or no mapping with a reason."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history"
  },
  {
   "id": "alignTask",
   "description": "Align a task to O*NET detailed work activities with a stated fit, or record why none applies.",
   "edits": [
    "Task"
   ],
   "parameters": [
    "occupation",
    "task",
    "activity",
    "fit",
    "reason"
   ],
   "criteria": [
    "The activity must be in O*NET's list for the occupation's own codes; the fit is one of four.",
    "No activity only with a reason: new work (emerging tasks only), nothing in O*NET's list, or no O*NET occupation (only where the occupation has none)."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history and the wave's memo"
  },
  {
   "id": "readRule",
   "description": "Record how a verified record reads a rule — provision, verb, whom it binds, whether it requires a person — creating the rule if it is new.",
   "edits": [
    "Regulation",
    "Jurisdiction"
   ],
   "parameters": [
    "record",
    "rule",
    "provision",
    "verb",
    "subject",
    "requiresHuman",
    "tasks"
   ],
   "criteria": [
    "The rule's name appears word for word in a record that reads it; nothing is named from memory.",
    "A mandate is read only as must, must not or funds; a bill that did not pass only with rule_not_enacted, and the reverse."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history and the wave's memo"
  },
  {
   "id": "acceptProposal",
   "description": "Accept a lead by reading the source and, only if its own text speaks to that task, recording evidence for the other occupation through the normal entry point. The proposal's status then turns accepted by itself.",
   "edits": [
    "Evidence"
   ],
   "parameters": [
    "proposal",
    "record"
   ],
   "criteria": [
    "Accepted exactly when the target occupation has its own verified record citing the same source for that task; a proposal alone never records anything."
   ],
   "actors": [
    "named-verifier",
    "evidence-loop"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "events.json (the new record's addedOn / verifiedBy)"
  },
  {
   "id": "rejectProposal",
   "description": "Reject a lead with a named reason: why this source does not reach that task.",
   "edits": [
    "Proposal"
   ],
   "parameters": [
    "proposal",
    "by",
    "why"
   ],
   "criteria": [
    "Only proposals that exist now; who, when and a full-sentence reason; never both accepted and rejected."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [
    "repository"
   ],
   "log": "git history"
  },
  {
   "id": "release",
   "description": "Publish the site: build, canary, both gates, release, then accept by content.",
   "edits": [],
   "parameters": [],
   "criteria": [
    "sweep and audit:seo must both have passed on the canary for this source fingerprint."
   ],
   "actors": [
    "named-verifier"
   ],
   "writesTo": [],
   "log": "ops/memos/ acceptance entries"
  },
  {
   "id": "subscribe",
   "description": "Ask for the weekly digest; confirmed by an emailed link.",
   "edits": [
    "Subscriber"
   ],
   "parameters": [
    "email",
    "locale"
   ],
   "criteria": [
    "Double opt-in; only confirmed rows are sent to."
   ],
   "actors": [
    "visitor"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "row timestamps in the agent's database"
  },
  {
   "id": "joinWaitlist",
   "description": "Ask to be told when the first paid product opens.",
   "edits": [
    "WaitlistEntry"
   ],
   "parameters": [
    "email",
    "locale"
   ],
   "criteria": [
    "Only status = 'confirmed' rows count."
   ],
   "actors": [
    "visitor"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "row timestamps in the agent's database"
  },
  {
   "id": "grantPro",
   "description": "Open or extend a paid personal MCP address after payment; prints the install prompt.",
   "edits": [
    "ProAccount"
   ],
   "parameters": [
    "email"
   ],
   "criteria": [
    "Payment has been received; 30 days prepaid, no auto-renew; keys stored as SHA-256 only."
   ],
   "actors": [
    "ceo"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "pro_grants"
  },
  {
   "id": "rotateProKey",
   "description": "A paying person signs in by email link and generates a new key, which revokes the old one.",
   "edits": [
    "ProAccount"
   ],
   "parameters": [
    "email"
   ],
   "criteria": [
    "One-time 20-minute link; the response never reveals who has paid."
   ],
   "actors": [
    "pro-user"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "row timestamps in the agent's database"
  },
  {
   "id": "followOccupation",
   "description": "Follow an occupation from a personal MCP address.",
   "edits": [
    "ProAccount"
   ],
   "parameters": [
    "occupation"
   ],
   "criteria": [
    "A valid, unexpired personal key; only the caller's own profile changes."
   ],
   "actors": [
    "pro-user"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "pro_profiles.updated_at"
  },
  {
   "id": "unfollowOccupation",
   "description": "Stop following an occupation.",
   "edits": [
    "ProAccount"
   ],
   "parameters": [
    "occupation"
   ],
   "criteria": [
    "A valid, unexpired personal key; only the caller's own profile changes."
   ],
   "actors": [
    "pro-user"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "pro_profiles.updated_at"
  },
  {
   "id": "markMyTasks",
   "description": "Mark which tasks of an occupation are the caller's own work, so the weekly brief speaks to them.",
   "edits": [
    "ProAccount"
   ],
   "parameters": [
    "occupation",
    "tasks"
   ],
   "criteria": [
    "Task ids must exist; only the caller's own profile changes."
   ],
   "actors": [
    "pro-user"
   ],
   "writesTo": [
    "agent database"
   ],
   "log": "pro_profiles.updated_at"
  }
 ],
 "readTools": [
  {
   "server": "public",
   "tool": "resolve_occupation_or_major",
   "reads": [
    "Occupation",
    "Degree"
   ],
   "function": "resolveEntity"
  },
  {
   "server": "public",
   "tool": "search",
   "reads": [
    "Occupation",
    "Degree",
    "Note"
   ],
   "function": "searchEntities"
  },
  {
   "server": "public",
   "tool": "get_occupation",
   "reads": [
    "Occupation",
    "Task",
    "TaskJudgement"
   ],
   "function": "getOccupationView"
  },
  {
   "server": "public",
   "tool": "get_ontology",
   "reads": [
    "Occupation",
    "ClassificationConcept",
    "Degree",
    "Task",
    "WorkActivity",
    "Regulation"
   ],
   "function": "getOntologyView"
  },
  {
   "server": "public",
   "tool": "get_role_tasks",
   "reads": [
    "Task",
    "TaskJudgement"
   ],
   "function": "getRoleTasks"
  },
  {
   "server": "public",
   "tool": "find_evidence",
   "reads": [
    "Evidence"
   ],
   "function": "findEvidence"
  },
  {
   "server": "public",
   "tool": "get_change",
   "reads": [
    "Evidence"
   ],
   "function": "getEvidenceById"
  },
  {
   "server": "public",
   "tool": "find_affected",
   "reads": [
    "Evidence",
    "Task"
   ],
   "function": "findAffected"
  },
  {
   "server": "public",
   "tool": "get_change_history",
   "reads": [
    "Evidence"
   ],
   "function": "getChangeHistory"
  },
  {
   "server": "public",
   "tool": "find_transition_paths",
   "reads": [
    "Pathway",
    "Occupation"
   ],
   "function": "findTransitionPaths"
  },
  {
   "server": "public",
   "tool": "list_business_functions",
   "reads": [
    "BusinessFunction",
    "Occupation"
   ],
   "function": "listBusinessFunctions"
  },
  {
   "server": "public",
   "tool": "query_ontology",
   "reads": [
    "Occupation",
    "Task",
    "TaskJudgement",
    "Evidence",
    "Pathway",
    "Degree",
    "BusinessFunction",
    "Note",
    "Capability",
    "ClassificationConcept",
    "WorkActivity",
    "Regulation",
    "Jurisdiction",
    "Source"
   ],
   "function": "queryOntology"
  },
  {
   "server": "public",
   "tool": "get_major",
   "reads": [
    "Degree"
   ],
   "function": "getMajorView"
  },
  {
   "server": "public",
   "tool": "find_majors_for_occupation",
   "reads": [
    "Degree",
    "Occupation"
   ],
   "function": "findMajorsForOccupation"
  },
  {
   "server": "public",
   "tool": "find_notes",
   "reads": [
    "Note"
   ],
   "function": "findNotes"
  },
  {
   "server": "public",
   "tool": "get_note",
   "reads": [
    "Note"
   ],
   "function": "getNoteView"
  },
  {
   "server": "public",
   "tool": "find_notes_for_occupation",
   "reads": [
    "Note",
    "Occupation"
   ],
   "function": "notesForOccupation"
  },
  {
   "server": "public",
   "tool": "describe_coverage",
   "reads": [
    "Occupation",
    "Evidence"
   ],
   "function": "describeCoverage"
  },
  {
   "server": "pro",
   "tool": "my_profile",
   "reads": [
    "ProAccount"
   ]
  },
  {
   "server": "pro",
   "tool": "whats_new_for_me",
   "reads": [
    "ProAccount",
    "Evidence",
    "Occupation"
   ]
  }
 ],
 "functions": [
  {
   "id": "buildOntology",
   "description": "Assemble every content object and link into one read-only graph.",
   "returns": "OntologyGraph"
  },
  {
   "id": "evidencedTaskIds",
   "description": "Which tasks the verified records make evidenced, under the baseline-weight rule.",
   "returns": "set of task ids"
  },
  {
   "id": "weightOf",
   "description": "Whether a record can move a baseline: no, cautious or yes.",
   "returns": "baseline weight"
  },
  {
   "id": "attributionFor",
   "description": "Credit for a flip goes to the earliest baseline-moving verified record.",
   "returns": "attribution"
  },
  {
   "id": "vendorDocViolations",
   "description": "Records that break the vendor-document rules.",
   "returns": "list of violations"
  },
  {
   "id": "unattributedVerdict",
   "description": "Whether a text uses a verdict word without attribution.",
   "returns": "boolean"
  },
  {
   "id": "getTrajectory",
   "description": "The reconstructed index at each checkpoint; nothing past now.",
   "returns": "trajectory"
  },
  {
   "id": "buildQuadrant",
   "description": "Every occupation on one map: impact index across, augmenting minus automating up.",
   "returns": "map data"
  },
  {
   "id": "occupationOntology",
   "description": "The per-occupation reference view: classification codes, O*NET descriptors, degrees.",
   "returns": "view"
  },
  {
   "id": "queryOntology",
   "description": "Object query and one-step traversal for AI agents: the types, the objects of a type, one object with what it links to. Read-only; proposals and user objects never leave.",
   "returns": "view"
  },
  {
   "id": "ontologyTriples",
   "description": "The graph as RDF statements — vocabulary from the definition, instances from the graph, fits as W3C SKOS matches — published as JSON-LD and N-Triples.",
   "returns": "statements"
  },
  {
   "id": "occupationActivities",
   "description": "Each task of an occupation with the O*NET activities it is aligned to, or the reason there are none.",
   "returns": "list"
  },
  {
   "id": "occupationRegulations",
   "description": "The rules an occupation's verified records read, with each reading.",
   "returns": "list"
  },
  {
   "id": "recordsReading",
   "description": "Every verified record, in any occupation, that reads one rule.",
   "returns": "list"
  },
  {
   "id": "allProposals",
   "description": "Every cross-occupation lead: a transferable verified record × a shared O*NET activity × a task elsewhere, with its computed status.",
   "returns": "list"
  },
  {
   "id": "proposalsFor",
   "description": "The leads one verified record starts.",
   "returns": "list"
  },
  {
   "id": "proposalsAbout",
   "description": "The leads that land on one occupation.",
   "returns": "list"
  },
  {
   "id": "tasksSharingActivity",
   "description": "Tasks in other occupations aligned to the same detailed activity (derives sharesActivity).",
   "returns": "list"
  },
  {
   "id": "buildOpenData",
   "description": "The downloadable files, byte-identical for identical content.",
   "returns": "files"
  },
  {
   "id": "resolveEntity",
   "description": "Resolve a job or degree name; a wrong match is worse than none.",
   "returns": "entity or none"
  },
  {
   "id": "searchEntities",
   "description": "Search occupations, degrees and notes.",
   "returns": "list"
  },
  {
   "id": "getOccupationView",
   "description": "An occupation with its tasks and judgements.",
   "returns": "view"
  },
  {
   "id": "getRoleTasks",
   "description": "Task judgements of one occupation.",
   "returns": "list"
  },
  {
   "id": "findEvidence",
   "description": "Verified records for an occupation or task.",
   "returns": "list"
  },
  {
   "id": "getEvidenceById",
   "description": "One verified record.",
   "returns": "record"
  },
  {
   "id": "findAffected",
   "description": "Tasks a record bears on.",
   "returns": "list"
  },
  {
   "id": "getChangeHistory",
   "description": "An occupation's records in date order.",
   "returns": "list"
  },
  {
   "id": "findTransitionPaths",
   "description": "Routes from an occupation.",
   "returns": "list"
  },
  {
   "id": "listBusinessFunctions",
   "description": "Departments and their occupations.",
   "returns": "list"
  },
  {
   "id": "getMajorView",
   "description": "A degree with its paths.",
   "returns": "view"
  },
  {
   "id": "findMajorsForOccupation",
   "description": "Degrees leading to an occupation.",
   "returns": "list"
  },
  {
   "id": "describeCoverage",
   "description": "What the site covers and refuses to answer.",
   "returns": "description"
  },
  {
   "id": "findNotes",
   "description": "Long-form pieces matching a query.",
   "returns": "list"
  },
  {
   "id": "getNoteView",
   "description": "One long-form piece with its citations.",
   "returns": "view"
  },
  {
   "id": "notesForOccupation",
   "description": "Long-form pieces citing an occupation.",
   "returns": "list"
  },
  {
   "id": "getOntologyView",
   "description": "The reference view for agents.",
   "returns": "view"
  }
 ]
}
