---
sidebar_position: 11
title: Catalog metadata
---

# Catalog metadata

Everything here reaches the **card**. Most of it is presentation, and most of it
is deliberately excluded from the update signal, so improving your copy never
pops an "Update available" badge on somebody's deployed agent for nothing.

## Identity and presentation

| Name | Type | Required | Allowed values | Default | Update behavior |
|---|---|---|---|---|---|
| `slug` | string | **Yes** | the agent's identity — the folder name, the deploy route, the row of everybody who already installed it | — | **Never change it** |
| `tagline` | string | No | one clamped line — on the detail card this *is* the header | `''` | Card only |
| `tags` | string[] | No | catalog sections; the card is grouped by the first one in section order | `[]` | Card only |
| `browseRank` | number | No | lower sorts first; no rank sorts last | none | Card only |
| `capabilities` | string[] | No | around five bullets, each one thing, each starting with a verb | `[]` | Card only |
| `conversationStarters` | string[] | No | example prompts — the first five appear as "Try asking" on the detail card | `[]` | Card only |
| `icon` | string | No | `./icon.png` beside your graph, or an `https://` URL | the Zibby mark | Card only |
| `iconPrompt` / `iconBackground` | string | No | inputs to the offline icon generator | none | Card only |
| `releaseNotes` | string | No | markdown — see below | `''` | Card only |
| `defaultSlug` | string | No | pre-fills the "Deploy as" field | the slug | Seeded once |

:::tip Tagline vs description
The detail card reads **tagline first**; the browse cards and the featured hero
read **description first**. So keep the tagline to a few words and let the
description be two real sentences. They are not interchangeable.
:::

## Behaviour and availability

| Name | Type | Required | Allowed values | Default | Update behavior |
|---|---|---|---|---|---|
| `maxRuntimeMinutes` | number | No | clamped to the platform window; the default is 25 and the ceiling 60 | none | **Seeded once** — a number you set on the Settings tab survives every Update |
| `selfHostOnly` | boolean | No | `true` when the agent needs a service container | `false` | Re-applied |
| `hidden` | boolean | No | `true` keeps the card out of browse while remaining installable by slug | `false` | Re-applied |
| `kind` | string | No | `fleet`, `app` — see [Composition](./composition.md) | none | Re-applied |
| `deps` | object | No | extra runtime dependencies the agent needs beyond `@zibby/core` | `{}` | **Frozen at deploy** |

### `maxRuntimeMinutes` — measure it, don't guess

Declare it when you actually know your agent's cost. One shipped agent measured
a first pass at 24 minutes 53 seconds against a 25-minute default, which made
its repair pass unreachable on every fresh install — so it declares 60. Another
declares 30 because a cap that is too *low* gets the container killed between
two steps and strands work.

A cap that is too low is worse than one that is too high.

### `selfHostOnly` means exactly one thing

**"This agent needs a service container."** It does not mean "absent from the
cloud": the card still ships to the cloud catalog so its documentation stays
readable everywhere. Only the deploy is refused, and the refusal says why.

## Release notes

`releaseNotes` is what the "Update available" dialog shows somebody who already
runs your agent. It is **mandatory for any user-visible change**, and it is
short.

1. **This version only.** One line per change.
2. **The outcome, not the mechanism.** What is different for them, in their
   words — not what you refactored.
3. **Do not accumulate history.** Drop the previous version's notes rather than
   prepending to them.
4. **Ten short lines at most.**

Good:

```
Answering the team's question is now just replying, once, like a person.
• Reply in your own words — any wording, any language.
• Answer on one ticket of a plan and it counts for the whole plan.
• You no longer touch labels.
```

Bad: a changelog going back to the initial release, or a paragraph about which
module was rewritten.

No notes at all gives the user *"No release notes provided by the author"*.

## Gotchas

**`hidden` and `selfHostOnly` are different axes.** `hidden` is visibility;
`selfHostOnly` is a real constraint. A card can be one, the other, or both.

**A `kind` the platform does not recognise is dropped.** The section you meant
to appear in simply never appears — check the allowed values.

**Your `spec` block lives outside your template directory**, so a
metadata-only change moves no source file. The platform tracks it separately, so
your edit still reaches the card — see [Update behavior](./update-behavior.md).

## See also

- [Update behavior](./update-behavior.md)
- [The declaration model](./index.md)
