Manifest spec
manifest.json is the technical contract that lets asset packs enter the solution network
Creators, buyers, Agents, delivery services, and local runners use the manifest to understand what an asset pack is, how it runs, which credentials it needs, what it outputs, and how it can be reused as a solution component. Relicex uses one unified standard, relicex.pack.v0, with kind selecting memory, experience, or capability packs.
One standard, three pack kinds
Do not treat memory, experience, and capability packs as three incompatible manifest formats. They are relicex.pack.v0 variants selected by kind.
memory_pack
Long-term memory, project history, preferences, context, and factual material.
experience_pack
Workflows, methods, templates, prompts, examples, and best practices.
capability_pack
Executable capabilities, tools, workflows, input/output schemas, and evaluation.
How it connects to solutions
The manifest does not own pricing or sales, but it tells Relicex what role an asset pack can play inside a solution. Solution pages, checkout, and settlement use these technical facts to explain capability, entitlement, and reuse boundaries.
asset_kind
memory / experience / capability identifies the pack's base kind.
component_role
Solution composition can describe whether it acts as a data source, workflow, agent skill, evaluation, template, or runnable capability.
entitlement_policy
Whether a solution purchase grants standalone asset entitlement is decided by checkout and solution composition.
Core fields
All packs should use the same top-level field model. Listing price, supply, publication status, and solution composition do not belong in the manifest; they live in marketplace records, solution records, and checkout quotes.
api_version
Always relicex.pack.v0.
kind
memory_pack, experience_pack, or capability_pack.
id / version
Stable package identity and version.
title / description
Human- and Agent-readable summary.
runtime
Execution entrypoint for runnable packs; usually null otherwise.
files
Index of README, code, templates, examples, and assets.
{
"api_version": "relicex.pack.v0",
"kind": "capability_pack",
"id": "my_pack",
"version": "0.1.0",
"title": "My Pack",
"description": "What this pack does.",
"author": { "name": "creator", "id": "creator_id" },
"tags": ["capability"],
"mode": "code",
"runtime": {
"kind": "interpreted",
"profile": "python311-base@1",
"entry": { "kind": "python", "value": "code/main.py:run" }
},
"inputs_schema": { "type": "object" },
"outputs_schema": { "type": "object" },
"files": { "readme": "README.md", "code": ["code/main.py"] },
"secret_requirements": [],
"secret_groups": [],
"runtime_permissions": {
"network": { "required": false, "allow_domains": [] },
"filesystem": { "reads": ["./inputs"], "writes": ["./outputs", "./artifacts", "./logs", "./tmp"] }
},
"redaction": { "enabled": true, "patterns": [] }
}How runtime credentials are declared
A pack only declares what credentials it needs. It must never contain real API keys, tokens, passwords, or private keys. The key matching field is placement[].name.
One name connects three places
manifest.secret_requirements[].placement[].name = the buyer Credential Vault credential name / env name = the environment variable injected by the runner.
{
"secret_requirements": [
{
"id": "openai_api_key",
"label": "OpenAI API Key",
"provider": "openai",
"type": "api_key",
"required": true,
"sensitive": true,
"description": "Used by this package to call OpenAI.",
"placement": [{ "type": "env", "name": "OPENAI_API_KEY" }]
}
]
}Capability runtime I/O folders
inputs_schema and outputs_schema are the primary contract. When a capability reads user files or generates Markdown, CSV, PDF, images, or other non-JSON artifacts, use the standard runtime workspace so runners, Agents, and users can find results consistently.
relicex_runs/<package_name>_<timestamp>/
├── inputs/
│ ├── input.json
│ └── files/
├── outputs/
│ └── result.json
├── artifacts/
├── logs/
└── tmp/Multiple credentials and provider choices
If one service needs multiple values, do not add a credential_bundle field. Declare multiple secret_requirements and use secret_groups to express configuration rules.
all_of
all_of means all listed credentials must be configured, such as BYBIT_API_KEY + BYBIT_API_SECRET.
{
"secret_requirements": [
{
"id": "bybit_api_key",
"label": "Bybit API Key",
"provider": "bybit",
"type": "api_key",
"required": true,
"sensitive": true,
"placement": [{ "type": "env", "name": "BYBIT_API_KEY" }]
},
{
"id": "bybit_api_secret",
"label": "Bybit API Secret",
"provider": "bybit",
"type": "api_secret",
"required": true,
"sensitive": true,
"placement": [{ "type": "env", "name": "BYBIT_API_SECRET" }]
}
],
"secret_groups": [
{
"id": "bybit_credentials",
"label": "Bybit API credentials",
"mode": "all_of",
"required": true,
"members": ["bybit_api_key", "bybit_api_secret"]
}
]
}one_of
one_of means the user chooses one service, such as OpenAI or Anthropic.
{
"secret_groups": [
{
"id": "llm_provider",
"label": "LLM Provider",
"mode": "one_of",
"required": true,
"options": [
{ "id": "openai", "label": "OpenAI", "members": ["openai_api_key"] },
{ "id": "anthropic", "label": "Anthropic", "members": ["anthropic_api_key"] }
]
}
]
}Legacy fields and safety boundaries
Older packs may contain requires.secret_slots. It remains compatibility-only; new packs should use secret_requirements.
Relicex
What should creators do next?
Start from a starter template, then validate the manifest with relicex_skill validate_pack.