# Public catalogs & IDs

> Reference for the public OpenEng catalogs (agents, skills, templates, models, cells, plugins, roles, library, loops, connectors and integrations): where each one lives, how big it is, its ID prefix and catalog.json contract, how IDs and <id>@<version> pins work, and the public release feed.

The ready-made building blocks OpenEng offers come from public catalogs. Each catalog is a small
website of its own at `<kind>.openeng.app`, where you can browse and search it, and each publishes the
same data as JSON for the Console and the engine to read. Everything on this page is public: no
sign-in and no key.

You don't need any of these files to use OpenEng. The Console shows every catalog on its own pages
and lets you adopt or import entries from there ([The Console](console.md)). This page is for anyone
who wants to script against the catalogs, check what a config refers to, or pin a version.

## The catalogs

Each catalog's name links to its site. Entry counts are from each `catalog.json` on September 25,
2026; the catalogs grow, so read `count` (or the length of the entry list) for the current number.

| Catalog | Entries | ID prefix | What an entry is |
| --- | --- | --- | --- |
| [Agents](https://agents.openeng.app) | 1,092 | `agent_def_` | An agent's operating brief: a single worker (810) or an orchestrator that delegates to sub-agents (282). In the Console: Building blocks → Agents ([Agents](agents.md)). |
| [Skills](https://skills.openeng.app) | 885 | `skill_def_` | A focused playbook the engine adds to a turn. Building blocks → Skills ([Skills](skills.md)). |
| [Templates](https://templates.openeng.app) | 754 | `tpl_def_` | A prompt set: a system prompt the engine combines with your prompt. Building blocks → Templates ([Templates](templates.md)). |
| [Models](https://models.openeng.app) | 28 | `mdl_def_` | An on-device, Ollama-library model (it runs through a local Ollama daemon you install) with its minimum requirements. Building blocks → Models ([Models](models.md)). |
| [Cells](https://cells.openeng.app) | 550 | `cell_def_` | A small tool server for one cloud service that you deploy in your own cloud account: 260 for AWS, 150 for Azure and 140 for Google Cloud; 435 read and 115 write. Connect → Cells ([Cells](cells.md)). |
| [Plugins](https://plugins.openeng.app) | 14 | `plg_def_` | A behavior that gates, transforms, observes or enriches a call at the engine's gateway. Govern → Plugins ([Plugins](plugins.md)). |
| [Roles](https://roles.openeng.app) | 1,524 | `role_def_` | A behavioral rule-set that makes an agent work like a named professional. Govern → Roles ([Roles](roles.md)). |
| [Library](https://library.openeng.app) | 8 | `lib_def_` | A bundle of agents, skills, templates and cells, with optional model picks, that you import into a config as one unit. Building blocks → Library ([Library](library.md)). |
| [Loops](https://loops.openeng.app) | 6 | `loop_def_` | A global loop: a request, a source of iterations and a stopping rule. Two run as published; the four work-items loops need a source that works first ([The loop catalog](loops.md#loop-catalog)). Building blocks → Loops. |
| [Connectors](https://connectors.openeng.app) | 252 | `connector_def_` | A connector for the engineering apps: source you deploy in your own cloud to reach a cloud or data system from Terminal, Kubernetes or Data. 240 capability packages (80 capabilities, each for AWS, Google Cloud and Azure) and 12 standalone connectors (Kubernetes, Kafka, two object stores and eight databases) ([Connectors](connectors.md)). |
| [Integrations](https://connectors.openeng.app/integrations) | 7 | `connector_def_` | An integration for OpenEng AI: GitHub, GitLab, Jira, Canva, ElevenLabs, Datadog and Kubernetes, each a remote endpoint your engine dials. Connect → Connectors ([Integrations](integrations.md)). |

Two catalogs share the connectors site but are different things: the **connectors** are for the
engineering apps, and the **integrations** are what the Console's Connect → Connectors page lists
([Glossary](glossary.md#connector-cell-integration)).

Each entry also has a page on its catalog site, such as
[models.openeng.app/m/codegemma-7b](https://models.openeng.app/m/codegemma-7b). The part of that URL
after the path prefix is a URL-friendly name, and it isn't always the same as the end of the entry's
id: that model's id is `mdl_def_codegemma_7b`.

## IDs

Every item's id says where it came from.

| Form | Example | What it means |
| --- | --- | --- |
| `<prefix>_def_<name>` | `tpl_def_ab-experiment-plan`, `cell_def_aws-cloudwatch-logs` | A shipped default from a public catalog. It's the same for everyone, and no one can edit it. |
| `<prefix>_usr_<uid>_<suffix>` | `agt_usr_<uid>_…` | Something you created, adopted or copied in the Console. `<uid>` is your user id: once the API is live it checks the owner on every read and write, so only your account, and anyone you share a config or public template with, can read the item. |
| `<name>_<suffix>` | | A config. The API makes up the id when you create the config; the Configs page shows it on each card with a copy button ([Configs](configs.md#the-configs-list)). |

Prefixes you'll see on your own items include `mdl` (models), `agt` (agents), `tpl` (templates),
`sch` (schedulers), `cell` (cells), `mcp` (MCP servers), `stp` (storage points), `skill`, `loop` and
`connector`.

### Version pins: `<id>@<version>`

Once something is published it never changes, and `<id>@<version>` names exactly one published
version:

- **Configs.** Every publish freezes a new version of the config. The Console's version timeline
  offers the pinned id `<id>@<version>` for copying ([The version timeline](configs.md#the-version-timeline)),
  and the engine's log names the config version it serves the same way, for example
  `warm-up: config <id>@<version> READY`.
- **Templates.** Publishing a template you wrote freezes an unchangeable copy of it at
  `<id>@<version>` ([Templates](templates.md)).
- **Catalogs.** Each catalog version is frozen in its own file, `catalog/v<version>.json`
  ([below](#catalog-json)).

## The catalog.json contract

Every catalog site serves the same files:

| Path | What it is |
| --- | --- |
| `/catalog.json` | The current catalog. This is what the Console reads. |
| `/catalog/index.json` | The published versions of the catalog: `{"latest": …, "versions": […]}`. |
| `/catalog/v<version>.json` | One version of the catalog, frozen: it never changes once published. |
| `/<name>.md` | For agents, skills, templates and roles: one entry's full Markdown body, where `<name>` is the entry's id without its `<prefix>_def_` part. |

The integrations catalog is the exception: it's at `connectors.openeng.app/integrations/catalog.json`
and has no index or versioned copies.

The catalogs don't all use the same envelope. Each one is a JSON object with the entries in a list
named after the catalog, plus version fields:

| Catalog | Envelope | Pinned file today |
| --- | --- | --- |
| agents, templates, cells, connectors | `{ "version", "generatedAt", "<entries>": […] }` | `catalog/v1.0.0.json` |
| library | `{ "version", "generatedAt", "library": […] }` | `catalog/v1.json` |
| skills, plugins, roles | `{ "schemaVersion", "count", "<entries>": […] }` | `catalog/v1.json` |
| models | `{ "schemaVersion", "count", "models": […], "roleGroups": {…} }` | `catalog/v3.json` (v1 and v2 are still served) |
| loops | `{ "schemaVersion", "count", "loops": […] }` | `catalog/v2.json` |
| integrations | `{ "version", "generatedBy", "law", "connectors": […] }` | none |

An entry's id is in its `id` field, its `publicId` field, or both, depending on the catalog.

```bash
curl -s https://skills.openeng.app/catalog.json | jq '.count'     # 885 on September 25, 2026
curl -s https://agents.openeng.app/catalog/index.json             # {"latest":"1.0.0","versions":["1.0.0"]}
curl -s https://templates.openeng.app/ab-experiment-plan.md       # one template's full prompt
```

A few catalog sites publish more than the catalog:

- **models.openeng.app** also serves `runtimes.json` (13 runtimes and the model formats each one
  runs) and `providers.json` (12 providers) ([Models](models.md)).
- **loops.openeng.app** also serves `catalog/strategies.json` and a `/reference` page: the iteration
  strategies the engine uses inside a single turn, published as reference data. They aren't loops you
  run ([Loop strategies](loops.md#iteration-strategies)).
- **connectors.openeng.app** also serves each connector's source as a zip under `/packages/`, and the
  write-key generator at [connectors.openeng.app/write-key](https://connectors.openeng.app/write-key)
  ([Connectors](connectors.md)).
- **roles.openeng.app** is for browsing. The AI engine doesn't read it: it uses the signed roles pack
  from releases.openeng.app ([Release integrity](security.md#release-integrity)).

## The public release feed

[releases.openeng.app](https://releases.openeng.app) shows the engineering apps' releases with their
release notes; `releases.openeng.app/app/<product>` shows one product. The feeds behind it, and those
of the AI engine's packs, are public JSON:

```text
https://releases.openeng.app/v1/<product>/<channel>/latest      # the newest release
https://releases.openeng.app/v1/<product>/<channel>/versions    # {"versions": [ … ]}, newest first
```

Products with a feed on September 25, 2026:

| Product | Newest version | What it is |
| --- | --- | --- |
| `terminal` | 0.0.4 | The Terminal engine |
| `kubernetes` | 0.0.5 | The Kubernetes engine |
| `data` | 0.0.4 | The Data engine |
| `git` | 0.0.1 | The Git engine. It has a release record but no published binary ([Install](install.md#installers)). |
| `roles` | 1.1.0 | The signed behavioral-roles pack the AI engine uses |
| `specialists` | 1.0.0 | The AI engine's sub-agent specialist pack |

The engineering-app releases are filed on the `beta` channel, and the `stable` URLs serve the same
releases, because that's what the engines check. So a record you fetch from a `stable` URL can say
`"channel": "beta"`. The AI engine checks the `engine` product on its own channel (`stable` unless you
set `OPENENG_UPDATE_CHANNEL`); on September 25, 2026 that feed has no release yet
([The engine](engine.md#updates)).

> **Note:** A product or channel with no release answers `latest` with the releases site's web page,
> even though the response says `application/json`, and its `versions` can be that page too or an
> empty list (`{"versions": []}`, as for `chat`). If you script against the feed, check that the body
> starts with `{` and that the list isn't empty.

A release record, shortened:

```json
{
  "product": "terminal",
  "channel": "beta",
  "version": "0.0.4",
  "releaseDate": "2026-09-19",
  "notes": "OpenEng Terminal Engine 0.0.4 — every endpoint moves to openeng.app.",
  "changelog": ["…"],
  "critical": false,
  "minSupportedVersion": "0.0.1",
  "artifacts": [
    {
      "platform": "linux",
      "arch": "x86_64",
      "url": "https://openeng.app/engine/terminal/bin/openeng-terminal-linux-x86_64",
      "checksum": "sha256:6e07aa7f…"
    }
  ]
}
```

- **`artifacts`** has one entry per platform and CPU: where the binary is and its `sha256:` checksum.
  Release records hold only these pointers; the binaries are served from openeng.app. Every engine
  checks the checksum before it installs an update ([Release integrity](security.md#release-integrity)).
- **`critical`** and **`minSupportedVersion`**: a critical release, or any newer release when the
  running AI engine is older than `minSupportedVersion`, is swapped in on disk right away instead of at
  the engine's next start, and the engine asks you to restart it ([The engine](engine.md#updates)).
  App engines always move to the newest release when they start.
- Each version is its own record, so `versions` is the full history.
