Demo build. Every business shown is fictional, data is synthetic and partner integrations are simulated.What is real here

Add your industry

A new industry is a pack, built with the pack kit in days, with no service change.

AGORA never needs a code change to support a new industry. Industry behaviour (taxonomy, attributes, offering kinds, conversion types, surfaces, missions, intake fields, prohibited claims and display strings) is configuration in a versioned pack. The general business pack works for every business; an industry pack refines it.

The pack kit

  1. Scaffold a pack from the general pack, then check it as you go with the CLI: agora validate pack <dir>.
  2. Describe the industry: the taxonomy, the attributes that matter, which offering kinds and conversion types apply, the surfaces required or conditional on the graph, and the display strings for industry nouns.
  3. Generate fixtures for a fictional business and the projections you expect.
  4. Run conformance: pack CI runs every module against the new pack and the industry fixture matrix.
  5. Publish the pack version. A regulated pack needs a counsel sign-off record for its exact version first.

Packs are semantically versioned. Attribute renames ship as migrations, and tenants upgrade their pins explicitly. See Packs for the packs published in this build.


Authoring a vertical pack (for analysts)

A new industry is a pack, not a code change (hand-over G9, R10). This guide takes an analyst from nothing to a pack that passes pack CI in a few days. Everything you write lives under packs/<id>/; you never edit a service.

1. Decide whether you need a pack at all

Start from the generic pack (packs/generic/, "General business"). It already supports every offering kind (product, service, plan, programme, listing, membership, event, consultation, other), inquiry / booking / checkout by handoff, free typed attributes per merchant and graph-parameterised missions and panels. Six "no pack" businesses (car wash, tutoring centre, freight broker, wedding photographer, co-working space, charity) run on it in the fixture matrix and must never get a pack of their own. Write a pack only when an industry needs its own vocabulary, attributes, eligibility or regulator rules.

2. Scaffold

npx --prefix server tsx server/src/packs/cli.ts pack scaffold pet-care \
  --name "Pet care" \
  --description "Dog grooming salon and pet sitting: bath and trim appointments, a monthly grooming plan. Book online or call." \
  --kinds service,plan --conversions booking,inquiry,call --locales en,ar

The kit writes a complete pack that already validates: pack.yaml, a taxonomy, attributes.json (the generic core set), intake.json, kernel.yaml (the generic prohibited list), sources.yaml, wizard.yaml (the generic wizard), two graph-parameterised mission templates, panel seeds per locale and a fixture business generated from your description (tests/fixture-business.yaml, tests/expected.yaml). Kinds and conversion types are suggested from the description when you leave them out. The pack starts as status: draft.

3. Fill it in

FileWhat to change
pack.yamldisplay names per language; display_strings (the industry nouns the console and documents show instead of the neutral words: offering, customer, conversion, location, person, plus section labels such as section_booking); surfaces (required / recommended / conditional with has(<kind or conversion type or entity>), not, and, or); classification.keywords per language (the words that point at your industry at sign-up); value_model (an amount, or rule: ask_at_onboarding); changelog.
taxonomyThree levels of category paths separated by > . Add keywords to nodes; optional gpc_id.
attributes.jsonTyped attributes with x-agora.kind (string, number, enum, boolean, quantity with a UCUM unit), required_for surfaces and a comparison_weight. Everything else a merchant needs can be a free typed attribute in the console; do not add attributes only one merchant uses.
intake.jsonFields and qualification rules per enabled conversion type.
kernel.yamlProhibited claims per regulator and jurisdiction; required disclosures. A regulated pack needs a counsel_signoff for its exact version before status: published.
missions/Keep the templates (template: true, {{param}} placeholders filled from the graph), or add 2-4 concrete missions in shopper language.
panels/Seed queries per language or market; size is the expanded panel (at least 50).
tests/Make the fixture business realistic (fictional names, DEMO- licences); keep expected.yaml in step.

Generate a fresh fixture from a better description at any time:

npx --prefix server tsx server/src/packs/cli.ts pack fixture packs/pet-care --description "..." --write

4. Check it

npx --prefix server tsx server/src/packs/cli.ts pack validate packs/pet-care     # schema + semantic rules, per file
npx --prefix server tsx server/src/packs/cli.ts pack conformance packs/pet-care  # wizard, projectors, MCP tools, missions

validate reports errors and warnings per file (also served as POST /v1/packs/validate and POST /api/packs/validate). conformance loads every fixture business through the onboarding wizard into a demo world, resolves your surface declarations against its graph, projects and validates each active surface through the real projectors, checks the artefacts (JSON-LD, llms.txt, MCP manifest, listings), the MCP tool set, the conversion matrix cells your offerings use (hand-over 4.4) and your mission expectations. A pack is ready when both pass; then set status: published (with counsel sign-off when regulated).

5. What CI does with it

The generality job runs the static scan (no pack ids, kind literals, currencies, locales or jurisdictions in services), the copy lint, pack CI for every pack (the generic pack first), the fixture matrix and the any-business tests. Your PR should touch only packs/, missions/, policies/ and docs (ABT-8).

6. Upgrades

Renaming an attribute is a migrations: entry in pack.yaml ("1.5.0": { from: "^1.4.0", renames: { old: new } }). Merchants pin a version and upgrade explicitly from the console (Vertical packs → Merchants) or the API; the migration rewrites their attribute bags without data loss.

Source: docs/portal/docs/add-your-industry.md + docs/packs-authoring.md