Relicex asset-pack spec · for any LLM

Generate package.zip files that can be sold standalone or reused by solutions

This spec tells creators and any LLM which files belong in the zip, how to write manifest.json, how capability packs declare runtime, inputs, outputs, credentials, and permissions, and how an asset pack can become a solution component.

manifest.jsonREADME.mdrelicex.pack.v0package.zip

Dual-core positioning

An asset pack is both a product and a solution component

Buyers can purchase asset packs directly, or buy complete solutions powered by multiple asset packs. package.zip and manifest.json describe the underlying capability; listing, solution, and checkout records describe price, entitlement, delivery, and settlement.

Standalone sale

An asset pack can be purchased and licensed directly from Asset Library.

Solution reuse

It can also support a solution as a memory, experience, capability, or evaluation component.

Reuse royalties

When a solution references the pack, settlement can recognize the upstream asset contribution.

Shortest instruction for an LLM

Copy this prompt to any model

When you do not want to explain the whole platform, have the model read this first, then the manifest templates below.

LLM Prompt
Generate a Relicex relicex.pack.v0 package.zip. Include only public/licensable content. Do not include API keys, tokens, passwords, cookies, private keys, .env files, private data, or unauthorized content.

Required output:
1. manifest.json at the zip root.
2. README.md at the zip root.
3. Every file referenced by manifest.files.
4. If kind=capability_pack, include runtime, inputs_schema, outputs_schema, workflow, evaluation, and a code/main.py:run or equivalent entrypoint.

manifest.id must match ^[a-z0-9][a-z0-9_-]{2,79}$. Do not put _v1 in the id; put versions in manifest.version.
If a capability_pack reads files or emits Markdown, CSV, PDF, images, or other artifacts, use the runtime I/O convention: inputs/input.json, inputs/files/, outputs/result.json, artifacts/, logs/, and tmp/. Reference artifacts from output JSON by relative path only.
Normal capability_pack assets are review-required before publishing, not high-risk by default. Mark high risk only for real secrets, personal data, prompt-injection text, dangerous extensions, or risk_level=high.
Listing price, supply, status, subscription settings, and commercial licensing do not belong in manifest.json.
Real credentials must never be placed in the package; declare runtime environment variable names with secret_requirements only.

Hard contract

A compliant Relicex asset pack must satisfy these rules

Platform validation, Agent reads, delivery, download, and local execution all depend on these files and fields.

Fixed root

manifest.json and README.md must be at the zip root. Every path referenced by manifest.files must exist.

Package name

manifest.id is the canonical package name: stable, machine-readable, and not version-suffixed.

Clear kind

kind must be memory_pack, experience_pack, or capability_pack. Each kind has required sections.

Risk labels

Normal capability packs are review-required, not red/high-risk by default.

Standard I/O

File-based capability packs use inputs/, outputs/, artifacts/, logs/, and tmp/ runtime directories.

No secrets

Packages must not contain real credentials; declare runtime env vars with secret_requirements only.

Recommended zip directory structure

manifest.json must be at the root. Other folders can be organized by asset type, but manifest.files paths must match the zip paths exactly.

package.zip
package.zip
├── manifest.json                 # required, at zip root
├── README.md                     # required for humans and Agents
├── docs/                         # optional supporting docs
│   └── usage.md
├── prompts/                      # optional prompt assets
│   └── system_prompt.md
├── templates/                    # optional reusable templates
│   └── report.md
├── examples/                     # recommended examples
│   ├── example_input.json
│   └── example_output.md
├── code/                         # capability_pack only, if executable
│   └── main.py
├── assets/                       # optional static assets
└── memory/                       # memory_pack only, if needed

Minimal experience_pack manifest template

Experience packs are for methods, workflows, prompts, templates, and examples. They usually do not need a runtime.

manifest.json
{
  "api_version": "relicex.pack.v0",
  "kind": "experience_pack",
  "id": "api_design_playbook",
  "version": "0.1.0",
  "title": "API Design Playbook",
  "description": "A reusable workflow for designing API resources, auth, errors, and examples.",
  "author": {
    "name": "creator_or_team",
    "id": "creator_id"
  },
  "tags": ["api", "workflow", "experience"],
  "mode": "text",
  "runtime": null,
  "experience": {
    "goal": "Help an Agent design consistent API specs and implementation plans.",
    "inputs_hint": {
      "required": ["product goal", "users", "core entities"],
      "optional": ["existing API", "security constraints"]
    },
    "pitfalls": ["Mixing listing price or supply into manifest.json"],
    "recommended_params": {},
    "examples": ["examples/example_input.json"]
  },
  "files": {
    "readme": "README.md",
    "docs": ["docs/usage.md"],
    "code": [],
    "prompts": ["prompts/system_prompt.md"],
    "templates": ["templates/report.md"],
    "examples": ["examples/example_input.json", "examples/example_output.md"],
    "assets": []
  },
  "secret_requirements": [],
  "secret_groups": [],
  "runtime_permissions": {
    "network": { "required": false, "allow_domains": [] },
    "filesystem": { "writes": [] }
  },
  "redaction": {
    "enabled": true,
    "patterns": []
  }
}

capability_pack runtime template

Capability packs are executable assets and must declare runtime, input/output schemas, workflow, and evaluation. A Python entry can be code/main.py:run.

manifest.json
{
  "api_version": "relicex.pack.v0",
  "kind": "capability_pack",
  "id": "github_issue_summarizer",
  "version": "0.1.0",
  "title": "GitHub Issue Summarizer",
  "description": "Summarizes GitHub issue JSON into a prioritized action report.",
  "author": { "name": "creator_or_team", "id": "creator_id" },
  "tags": ["github", "summary", "automation"],
  "mode": "code",
  "runtime": {
    "kind": "interpreted",
    "profile": "python311-base@1",
    "entry": { "kind": "python", "value": "code/main.py:run" }
  },
  "inputs_schema": {
    "type": "object",
    "properties": {
      "issues": { "type": "array", "items": { "type": "object" } }
    },
    "required": ["issues"]
  },
  "outputs_schema": {
    "type": "object",
    "properties": {
      "summary": { "type": "string" },
      "report_md": { "type": "string" },
      "artifacts": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "path": { "type": "string" },
            "mime_type": { "type": "string" }
          },
          "required": ["name", "path"]
        }
      }
    },
    "required": ["summary", "report_md"]
  },
  "workflow": [
    {
      "id": "summarize",
      "executor": { "type": "code", "entry": "code/main.py:run" },
      "in": { "issues": "${inputs.issues}" },
      "out": ["summary", "report_md", "artifacts"]
    }
  ],
  "evaluation": {
    "required_outputs": ["summary", "report_md"]
  },
  "files": {
    "readme": "README.md",
    "docs": ["docs/usage.md"],
    "code": ["code/main.py"],
    "prompts": [],
    "templates": [],
    "examples": ["examples/example_input.json", "examples/example_output.md"],
    "assets": []
  },
  "secret_requirements": [],
  "secret_groups": [],
  "runtime_permissions": {
    "network": { "required": false, "allow_domains": [] },
    "filesystem": {
      "reads": ["./inputs"],
      "writes": ["./outputs", "./artifacts", "./logs", "./tmp"]
    }
  }
}
code/main.py
# code/main.py
from __future__ import annotations

import os
from pathlib import Path


def run(inputs: dict | None = None) -> dict:
    inputs = inputs or {}
    issues = inputs.get("issues") or []
    lines = ["# Issue summary", ""]
    for index, issue in enumerate(issues, start=1):
        title = issue.get("title", "Untitled") if isinstance(issue, dict) else str(issue)
        lines.append(f"{index}. {title}")
    report_md = "\n".join(lines)
    artifact_dir = Path(os.environ.get("RELICEX_ARTIFACT_DIR", "artifacts"))
    artifact_dir.mkdir(parents=True, exist_ok=True)
    (artifact_dir / "issue_summary.md").write_text(report_md, encoding="utf-8")
    return {
        "summary": f"Summarized {len(issues)} issues.",
        "report_md": report_md,
        "artifacts": [
            {
                "name": "issue_summary",
                "path": "artifacts/issue_summary.md",
                "mime_type": "text/markdown",
            }
        ],
    }

Capability runtime I/O convention

The core contract is still JSON: run(inputs: dict) -> dict, inputs_schema, and outputs_schema. Pure JSON packs can just return a dict; packs that read user files or emit reports, CSVs, PDFs, images, or other artifacts should use these directories.

Runtime workspace
<run_dir>/
├── inputs/
│   ├── input.json       # primary JSON object matching inputs_schema
│   └── files/           # CSV, PDF, images, uploaded data files
├── outputs/
│   └── result.json      # primary JSON object matching outputs_schema
├── artifacts/           # Markdown, CSV, PDF, charts, images, binaries
├── logs/                # redacted logs only
└── tmp/                 # temporary files, safe to delete
Runner usage and env vars
# Run with the standard runtime workspace
python scripts/relicex_run.py github_issue_summarizer \
  --inputs-json @examples/example_input.json \
  --run-dir ./runs/github_issue_summarizer_demo

# Common env vars made available to package code
RELICEX_RUN_DIR
RELICEX_INPUT_DIR
RELICEX_INPUT_FILES_DIR
RELICEX_INPUT_JSON / RELICEX_INPUT_FILE
RELICEX_OUTPUT_DIR
RELICEX_OUTPUT_JSON / RELICEX_OUTPUT_FILE
RELICEX_ARTIFACT_DIR
RELICEX_LOG_DIR
RELICEX_TMP_DIR
inputs/input.json and outputs/result.json must be JSON objects matching their schemas.
Large inputs go under inputs/files/; non-JSON outputs go under artifacts/.
Output JSON must reference artifacts by relative paths such as artifacts/report.md.
Never use absolute paths, ../ traversal, or unredacted logs.

Declare runtime credentials, never real values

If a package needs OpenAI, Bybit, GitHub, or similar credentials at runtime, declare environment variable names in secret_requirements only. Real values are injected by the buyer's Credential Vault or local environment at runtime.

secret_requirements example
{
  "secret_requirements": [
    {
      "id": "openai_api_key",
      "label": "OpenAI API Key",
      "provider": "openai",
      "type": "api_key",
      "required": true,
      "sensitive": true,
      "description": "Used only at runtime. The value is supplied by the buyer's Credential Vault.",
      "placement": [
        { "type": "env", "name": "OPENAI_API_KEY" }
      ]
    }
  ],
  "secret_groups": []
}

Pre-package checklist

After the model generates files, check them against this list.

manifest.api_version is exactly relicex.pack.v0.
manifest.id matches ^[a-z0-9][a-z0-9_-]{2,79}$ and version is separate.
README.md explains purpose, inputs, outputs, usage, limits, and license boundaries.
All files listed in files.readme/docs/code/prompts/templates/examples/assets exist.
capability_pack has runtime, inputs_schema, outputs_schema, workflow, and evaluation.
Normal capability_pack is review-required, not high-risk by default; mark high risk only for real severe signals.
File-based capability_pack uses the inputs/input.json, inputs/files/, outputs/result.json, artifacts/, logs/, and tmp/ convention.
outputs/result.json references artifacts by relative paths only, such as artifacts/report.md; do not use absolute paths or ../.
secret_requirements contain metadata and env names only, never real values.
Do not put price, supply, status, subscription, or commercial_price into manifest.
The zip has no .env, private keys, cookies, tokens, node_modules, .git, or unrelated large files.
Local packaging example
# From inside the package directory that contains manifest.json:
python -m json.tool manifest.json > /tmp/manifest.normalized.json
python - <<'PY'
import json, pathlib
m = json.loads(pathlib.Path('manifest.json').read_text(encoding='utf-8'))
assert m['api_version'] == 'relicex.pack.v0'
assert m['kind'] in {'memory_pack', 'experience_pack', 'capability_pack'}
assert pathlib.Path(m['files']['readme']).exists()
PY
zip -r ../package.zip manifest.json README.md docs prompts templates examples code assets memory -x '*.env' '.git/*' '__pycache__/*'

Upload, publishing, and solution-reuse boundary

package.zip describes asset content and runtime contract only. Price, supply, free/unlimited choices, subscription, commercial licensing, upstream references, publication status, and solution composition belong to listing, solution, and checkout records, not the manifest.

package.zip

Content, README, manifest, code, templates, examples, and assets.

draft_listing

Price, supply, license scope, subscription, commercial price, category, title, description, and upstream references.

Human publish

Upload should create an asset-pack draft only; the creator confirms rights, safety, and risk before public publishing or solution reuse.

Relicex