# Relicex Manifest + Package Authoring Spec for LLMs

本文档是一份**单文件、自包含**的 Relicex 包生成规范。任何大模型、人类创作者或自动化工具读完后，都应该能够不依赖 `relicex_skill`，手动生成符合 Relicex `relicex.pack.v0` 标准的 `package.zip`。

`relicex_skill` 仍然是官方推荐的自动化路径，但不是生成合规包的唯一方式。合规包的本质是：一个 zip 文件，根目录包含合规 `manifest.json`、`README.md`、所有被 manifest 引用的文件，并且不包含真实密钥、隐私数据或未授权内容。

---

## 0. 给大模型的最短指令

把下面这段连同本文档一起交给任意大模型：

```text
请生成一个符合 Relicex relicex.pack.v0 的 package.zip。只包含公开可授权内容，不要包含 API key、token、password、cookie、private key、.env、个人隐私或未授权内容。

必须输出：
1. zip 根目录 manifest.json。
2. zip 根目录 README.md。
3. manifest.files 中列出的所有文件。
4. 如果 kind=capability_pack，必须有 runtime、inputs_schema、outputs_schema、workflow、evaluation，并提供 code/main.py:run 或等价入口。
5. capability_pack 的主输入/输出契约是 JSON object；如果使用文件输入或生成文件产物，必须遵循本文的运行时 I/O 目录约定。

manifest.id 必须匹配 ^[a-z0-9][a-z0-9_-]{2,79}$。不要把 _v1 / _v2 写进 id，版本写入 manifest.version。
listing 的价格、库存、免费/无限、发布状态、订阅和商业授权不属于 manifest.json。
真实凭证不能写入包内；只能用 secret_requirements 声明运行时需要的环境变量名。
文件型 capability_pack 使用 inputs/input.json、inputs/files/、outputs/result.json、artifacts/、logs/、tmp/；输出 JSON 中只用相对路径引用 artifacts，禁止绝对路径和 ../。
```

---

## 1. 输出物：package.zip

最终生成一个 zip：

```text
package.zip
```

zip 根目录必须包含：

```text
manifest.json
README.md
```

推荐结构：

```text
package.zip
├── manifest.json                 # 必须，位于 zip 根目录
├── README.md                     # 必须，人类和 Agent 阅读
├── docs/                         # 可选，支持文档
│   └── usage.md
├── prompts/                      # 可选，提示词资产
│   └── system_prompt.md
├── templates/                    # 可选，可复用模板
│   └── report.md
├── examples/                     # 推荐，输入输出示例
│   ├── example_input.json
│   └── example_output.md
├── code/                         # capability_pack 可执行包使用
│   └── main.py
├── assets/                       # 可选，静态资产
└── memory/                       # memory_pack 可选

# 运行时目录不是 package.zip 的固定内容；runner/用户运行包时创建：
# relicex_runs/<package_name>_<timestamp>/inputs/input.json
# relicex_runs/<package_name>_<timestamp>/inputs/files/
# relicex_runs/<package_name>_<timestamp>/outputs/result.json
# relicex_runs/<package_name>_<timestamp>/artifacts/
# relicex_runs/<package_name>_<timestamp>/logs/
# relicex_runs/<package_name>_<timestamp>/tmp/
```

新包必须把 `manifest.json` 放在 zip 根目录。旧兼容路径可能能读取嵌套 manifest，但不要依赖旧行为。

---

## 2. 一个统一 Manifest 标准

Relicex 使用一个统一标准：

```json
{
  "api_version": "relicex.pack.v0",
  "kind": "capability_pack"
}
```

`kind` 只能是以下三种之一：

| kind | 用途 |
|---|---|
| `memory_pack` | 长期记忆、项目历史、偏好、上下文和事实材料。 |
| `experience_pack` | 工作流、方法论、模板、提示词、案例和最佳实践。 |
| `capability_pack` | 可执行能力、工具、工作流、输入输出 schema、运行权限和评估。 |

不要把三类包理解成三套 manifest。它们都是 `relicex.pack.v0`，只是 `kind` 不同。

---

## 3. 包名与版本规范

`manifest.id` 是 Relicex 包的**规范包名 / canonical package name**。它会被本地包库、下载记录、runner、Agent 和用户用来识别包。

必须满足：

```text
^[a-z0-9][a-z0-9_-]{2,79}$
```

推荐：

```text
github_radar
bybit_market_scanner
competitor_analysis_playbook
openai_prompt_optimizer
```

不要使用：

```text
GitHub Radar       # 有大写和空格
github radar       # 有空格
github/radar       # 有斜杠
my_pack_v1         # 把版本塞进 id
your_pack_v2       # 把版本塞进 id
中文包名            # 非 ASCII 包名不建议作为 manifest.id
```

版本必须单独写：

```json
"version": "0.1.0"
```

`manifest.title` 是给人看的展示名，可以包含空格和自然语言。

---

## 4. 通用顶层字段

每个包都应该包含这些基础字段：

```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,
  "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": []
  }
}
```

字段说明：

| 字段 | 规则 |
|---|---|
| `api_version` | 固定为 `relicex.pack.v0`。 |
| `kind` | `memory_pack` / `experience_pack` / `capability_pack`。 |
| `id` | 规范包名，匹配 `^[a-z0-9][a-z0-9_-]{2,79}$`。 |
| `version` | 版本号，例如 `0.1.0`。 |
| `title` | 展示名。 |
| `description` | 包用途说明。 |
| `author` | 创作者或团队元数据。 |
| `tags` | 搜索和分类标签。 |
| `mode` | `text` / `code` 等包模式。 |
| `runtime` | 可执行包的运行入口；非运行包通常为 `null`。 |
| `files` | README、docs、code、prompts、templates、examples、assets 的路径索引。 |
| `secret_requirements` | 运行时凭证声明，不能包含真实值。 |
| `secret_groups` | 多凭证组合或服务二选一规则。 |
| `runtime_permissions` | 网络、文件系统等运行权限声明。 |
| `redaction` | 输出或日志脱敏规则。 |

---

## 5. `files` 路径规则

`manifest.files` 中列出的每个路径都必须在 zip 中真实存在。

正确：

```json
"files": {
  "readme": "README.md",
  "docs": ["docs/usage.md"],
  "code": ["code/main.py"],
  "prompts": ["prompts/system_prompt.md"],
  "templates": ["templates/report.md"],
  "examples": ["examples/example_input.json", "examples/example_output.md"],
  "assets": []
}
```

要求：

- 路径使用相对 zip 根目录的路径。
- 不要使用绝对路径。
- 不要使用 `../` 跳出包目录。
- 不要引用不存在的文件。
- `files.readme` 应该指向根目录 `README.md`。

---

## 6. `memory_pack` 规范

当包主要是可复用上下文、记忆、偏好、项目历史、事实材料，而不是运行代码时，使用 `memory_pack`。

示例：

```json
{
  "api_version": "relicex.pack.v0",
  "kind": "memory_pack",
  "id": "product_strategy_memory",
  "version": "0.1.0",
  "title": "Product Strategy Memory",
  "description": "Reusable product strategy context and preferences.",
  "author": { "name": "creator_or_team", "id": "creator_id" },
  "tags": ["memory", "strategy"],
  "mode": "text",
  "runtime": null,
  "memory": {
    "scope": "project",
    "profiles": {},
    "projects": ["memory/projects.md"],
    "preferences": "memory/preferences.json",
    "summaries": ["memory/summary.md"],
    "artifacts": []
  },
  "files": {
    "readme": "README.md",
    "docs": [],
    "code": [],
    "prompts": [],
    "templates": [],
    "examples": [],
    "assets": ["memory/projects.md", "memory/preferences.json", "memory/summary.md"]
  },
  "secret_requirements": [],
  "secret_groups": [],
  "runtime_permissions": {
    "network": { "required": false, "allow_domains": [] },
    "filesystem": { "writes": [] }
  }
}
```

---

## 7. `experience_pack` 规范

当包主要是方法论、流程、提示词、模板、案例、最佳实践时，使用 `experience_pack`。它通常不需要可执行 runtime。

最小模板：

```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": ["Do not mix 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": []
  }
}
```

---

## 8. `capability_pack` 规范

当包包含可执行能力、工具代码、工作流、输入输出 schema 和运行权限时，使用 `capability_pack`。

普通 `capability_pack` 因为包含运行入口和权限声明，属于“发布前需确认 / review-required”，但**不是默认高风险**。只有当扫描发现真实 secret、个人数据、prompt-injection、危险可执行扩展名，或 manifest 显式声明 `risk_level: "high"` 时，才应标为高风险。

`capability_pack` 必须包含：

```text
runtime
inputs_schema
outputs_schema
workflow
evaluation
```

最小模板：

```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"] }
  }
}
```

Python 入口示例：

```python
# 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"
            }
        ]
    }
```

运行规则：

- 入口函数建议命名为 `run`。
- 输入为 `dict`。
- 输出必须是可 JSON 序列化的 `dict`。
- 输出字段应符合 `outputs_schema`。
- 不要在导入模块时直接执行网络请求或副作用逻辑。

---

## 9. 能力包 runtime I/O 约定

`inputs_schema` 和 `outputs_schema` 是能力包的主契约；运行时文件夹是文件型能力包的落盘约定。纯 JSON 能力包可以只实现 `run(inputs: dict) -> dict`，但只要读取用户文件、生成报告、CSV、图片、PDF、Markdown 或其他 artifact，就必须使用下面的目录和文件格式。

标准运行目录由 runner 创建，不应该作为固定内容打进 `package.zip`：

```text
relicex_runs/<package_name>_<timestamp>/
├── inputs/
│   ├── input.json                 # 主输入 JSON object，必须符合 inputs_schema
│   └── files/                     # 用户上传或传入的 CSV、PDF、图片、数据文件等
├── outputs/
│   └── result.json                # 主输出 JSON object，必须符合 outputs_schema
├── artifacts/                     # Markdown、PDF、CSV、PNG、HTML 等非 JSON 产物
├── logs/                          # 可选脱敏日志，不得包含密钥
└── tmp/                           # 临时文件，可被清理，不能作为最终结果依赖
```

运行时环境变量：

```text
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
RELICEX_PACKAGE_DIR
RELICEX_DELIVERY_DIR
```

规则：

1. `inputs/input.json` 必须是 JSON object，并符合 `manifest.inputs_schema`。
2. 大文件、二进制文件、CSV、PDF、图片等输入必须放在 `inputs/files/`。
3. `outputs/result.json` 必须是 JSON object，并符合 `manifest.outputs_schema`。
4. 生成的 Markdown、CSV、PNG、PDF、HTML 等非 JSON 产物必须放在 `artifacts/`。
5. `outputs/result.json` 里引用文件时，必须使用相对路径，例如 `artifacts/report.md`。
6. 不要使用绝对路径、`~`、用户主目录、`..` 跳出目录或机器特定路径。
7. `logs/` 只允许写脱敏日志，不能写 API key、token、cookie、password、private key 或 Secret Vault 返回值。
8. `tmp/` 只是临时目录，最终结果不能依赖 `tmp/` 中的文件。

输入 JSON 示例：

```json
{
  "csv_path": "inputs/files/customers.csv",
  "language": "zh",
  "max_rows": 1000
}
```

输出 JSON 示例：

```json
{
  "summary": "Generated a customer report for 120 rows.",
  "artifacts": [
    {
      "name": "customer_report",
      "path": "artifacts/customer_report.md",
      "mime_type": "text/markdown"
    }
  ]
}
```

推荐的 artifact schema 片段：

```json
{
  "artifacts": {
    "type": "array",
    "items": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "path": { "type": "string" },
        "mime_type": { "type": "string" },
        "description": { "type": "string" }
      },
      "required": ["name", "path"]
    }
  }
}
```

如果能力包会读取或写入文件，`runtime_permissions.filesystem` 应声明标准读写边界，例如：

```json
{
  "runtime_permissions": {
    "network": { "required": false, "allow_domains": [] },
    "filesystem": { "reads": ["./inputs"], "writes": ["./outputs", "./artifacts", "./logs", "./tmp"] }
  }
}
```

官方 runner 会把 `RELICEX_OUTPUT_JSON` 指向 `outputs/result.json`，并在 Python entry wrapper 中保留旧行为：`run()` 返回值会继续打印到 stdout，同时也会写入 `outputs/result.json`。如果用户显式传 `--output-json`，则写入用户指定文件。

如果 runner 同时设置了 `RELICEX_RUN_INPUTS_JSON`，它表示主输入 JSON 字符串；如果设置了 `RELICEX_RUN_OUTPUT_JSON`，Python entry wrapper 会把 `run()` 返回值写入该文件。

未来的 manifest 版本可以把这套约定升级为机器可读的 `runtime_io` 字段；在 `relicex.pack.v0` 中先按本节约定执行。

---


## 10. 运行凭证规范：只声明，不写真实值

如果包运行时需要 OpenAI、Anthropic、GitHub、Bybit 等凭证，只能在 `secret_requirements` 中声明环境变量名，不能把真实值写入包内。

示例：

```json
{
  "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 the OpenAI API.",
      "placement": [
        { "type": "env", "name": "OPENAI_API_KEY" }
      ]
    }
  ],
  "secret_groups": []
}
```

最重要字段是：

```text
secret_requirements[].placement[].name
```

它连接三件事：

```text
manifest placement name: OPENAI_API_KEY
= 买家 Credential Vault env_name: OPENAI_API_KEY
= runner 子进程环境变量: OPENAI_API_KEY
```

匹配规则：

1. 如果买家显式绑定了某个 requirement 到已保存凭证，使用该绑定。
2. 否则读取 requirement 的 env placement name，例如 `OPENAI_API_KEY`。
3. 查找买家 Credential Vault 中 `env_name` 完全匹配的 active credential。
4. 如果唯一匹配，可以直接使用。
5. 如果没有匹配，提示用户配置凭证。
6. 如果有多个匹配，提示用户选择并绑定。

### 多个凭证：all_of

一个服务需要多个值时，不要新增 `credential_bundle` 字段，直接声明多个 requirement，再用 `secret_groups` 表达组合关系。

```json
{
  "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`：

```json
{
  "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"] }
      ]
    }
  ]
}
```

---

## 11. 运行权限规范

`runtime_permissions` 应该诚实声明运行时需要的权限。不要声明比实际需要更宽的权限。

无网络权限示例：

```json
{
  "runtime_permissions": {
    "network": { "required": false, "allow_domains": [] },
    "filesystem": { "writes": [] }
  }
}
```

需要访问 GitHub API 示例：

```json
{
  "runtime_permissions": {
    "network": {
      "required": true,
      "allow_domains": ["api.github.com"]
    },
    "filesystem": {
      "reads": ["./inputs"],
      "writes": ["./outputs", "./artifacts", "./logs", "./tmp"]
    }
  }
}
```

规则：

- 网络权限需要列出目标域名。
- 文件型能力包需要声明标准读取目录 `./inputs`，以及预计写入目录 `./outputs`、`./artifacts`、`./logs`、`./tmp`。
- 不要声明 `*` 或过宽路径，除非确有必要。
- 不要要求访问系统敏感目录。

---

## 12. README.md 应该包含什么

`README.md` 是给人类和 Agent 看的使用说明，建议包含：

```md
# Package Title

## What this package does

说明包用途。

## When to use it

说明适用场景。

## Inputs

说明输入字段或用户需要提供的信息。

## Outputs

说明输出内容。

## How to run

如果是 capability_pack，说明运行入口和必要凭证。

## Secrets and permissions

说明 secret_requirements 和 runtime_permissions。

## Limitations

说明不适用场景、风险和边界。

## License / usage boundaries

说明授权边界，不能包含与 listing 相冲突的价格/库存信息。
```

README 可以解释授权边界，但不要把平台 listing 的具体价格、库存、发布状态写入 README 或 manifest。

---

## 13. 不属于 manifest 的内容

以下内容属于 marketplace listing、订单、授权、交付或发布流程，不属于 `manifest.json`：

```text
price
price_cents
supply
free/unlimited 选项
listing status
publish visibility
subscription eligibility
commercial price
commercial license terms chosen in listing UI
reference pricing
seller payout settings
payment settings
order status
entitlement status
delivery watermark value
```

包内可以描述用途和能力，但不应该把市场上架信息混入 manifest。

---

## 14. 绝对不能打包的内容

包内不得包含：

```text
.env
.env.local
.relicex/
API keys
tokens
passwords
cookies
private keys
SSH keys
OAuth refresh tokens
buyer credentials
个人隐私
未授权版权内容
node_modules/
.git/
__pycache__/
大型无关文件
```

如果需要凭证，只声明环境变量名：

```json
"placement": [{ "type": "env", "name": "OPENAI_API_KEY" }]
```

不要写：

```json
"value": "sk-..."
```

---

## 15. 本地检查与打包命令

从包含 `manifest.json` 的包目录内执行：

```bash
python -m json.tool manifest.json > /tmp/manifest.normalized.json
python - <<'PY'
import json, pathlib, re
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 re.match(r'^[a-z0-9][a-z0-9_-]{2,79}$', m['id'])
assert pathlib.Path(m['files']['readme']).exists()
for group in ['docs', 'code', 'prompts', 'templates', 'examples', 'assets']:
    for p in m.get('files', {}).get(group, []):
        assert pathlib.Path(p).exists(), p
PY
zip -r ../package.zip manifest.json README.md docs prompts templates examples code assets memory \
  -x '*.env' '.git/*' '__pycache__/*' 'node_modules/*' '.relicex/*'
```

如果使用官方 skill，可进一步校验：

```bash
python skills/relicex_skill/scripts/validate_pack.py package.zip
```

---

## 16. 上传前最终 checklist

交付给平台或创作者中心前，逐项检查：

- [ ] zip 根目录存在 `manifest.json`。
- [ ] zip 根目录存在 `README.md`。
- [ ] `manifest.api_version` 是 `relicex.pack.v0`。
- [ ] `manifest.kind` 是 `memory_pack` / `experience_pack` / `capability_pack`。
- [ ] `manifest.id` 匹配 `^[a-z0-9][a-z0-9_-]{2,79}$`。
- [ ] `manifest.id` 不包含 `_v1` / `_v2` 等版本后缀。
- [ ] `manifest.version` 单独填写。
- [ ] `manifest.files` 中引用的所有文件都存在。
- [ ] `README.md` 解释用途、输入、输出、使用方式、限制和授权边界。
- [ ] `capability_pack` 有 `runtime`、`inputs_schema`、`outputs_schema`、`workflow`、`evaluation`。
- [ ] 如果 capability_pack 读取/生成文件，使用 `inputs/input.json`、`inputs/files/`、`outputs/result.json`、`artifacts/`、`logs/`、`tmp/` 运行时 I/O 约定。
- [ ] artifact 路径为相对路径，没有绝对路径或 `../`。
- [ ] runtime 入口文件真实存在，例如 `code/main.py`。
- [ ] `secret_requirements` 只包含元数据和 env name，没有真实密钥值。
- [ ] `runtime_permissions` 没有声明过宽权限。
- [ ] manifest 里没有 `price`、`supply`、`status`、`subscription`、`commercial_price`。
- [ ] zip 内没有 `.env`、私钥、cookies、tokens、password、`.git`、`node_modules` 或无关大文件。
- [ ] 所有内容都是创作者有权授权和分发的内容。

---

## 17. 常见错误

### 错误：把版本写进 id

不要：

```json
"id": "github_radar_v1",
"version": "0.1.0"
```

应该：

```json
"id": "github_radar",
"version": "0.1.0"
```

### 错误：把价格和库存写进 manifest

不要：

```json
{
  "price_cents": 9900,
  "supply": 100
}
```

价格、库存、免费、无限供应、订阅、商业授权都在 listing 草稿中配置，不在 manifest 中配置。

### 错误：把真实密钥写进包

不要：

```json
{
  "openai_api_key": "sk-..."
}
```

应该：

```json
{
  "secret_requirements": [
    {
      "id": "openai_api_key",
      "placement": [{ "type": "env", "name": "OPENAI_API_KEY" }],
      "required": true,
      "sensitive": true
    }
  ]
}
```

### 错误：manifest.files 引用了不存在文件

如果写了：

```json
"docs": ["docs/usage.md"]
```

zip 内必须真的有：

```text
docs/usage.md
```

---

## 18. 最小合规包示例

目录：

```text
my_pack/
├── manifest.json
├── README.md
├── prompts/
│   └── system_prompt.md
├── templates/
│   └── report.md
└── examples/
    ├── example_input.json
    └── example_output.md
```

`manifest.json`：

```json
{
  "api_version": "relicex.pack.v0",
  "kind": "experience_pack",
  "id": "market_research_playbook",
  "version": "0.1.0",
  "title": "Market Research Playbook",
  "description": "A reusable research workflow for competitor, customer, and positioning analysis.",
  "author": { "name": "creator_or_team", "id": "creator_id" },
  "tags": ["research", "strategy", "workflow"],
  "mode": "text",
  "runtime": null,
  "experience": {
    "goal": "Guide an Agent through structured market research.",
    "inputs_hint": {
      "required": ["target market", "product description"],
      "optional": ["competitors", "geography", "customer segment"]
    },
    "pitfalls": ["Do not invent unsupported market data", "Separate assumptions from facts"],
    "recommended_params": {},
    "examples": ["examples/example_input.json"]
  },
  "files": {
    "readme": "README.md",
    "docs": [],
    "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": [] }
}
```

---

## 19. 生成结果应该如何交付给用户

如果大模型能直接创建文件，应输出：

```text
package.zip
```

如果大模型只能输出文本，应输出：

```text
1. manifest.json 内容
2. README.md 内容
3. 每个 referenced file 的路径和内容
4. 打包命令
5. 上传前 checklist 结果
```

创作者或自动化工具再按这些文件生成 zip。

---

## 20. 一句话总结

合规 Relicex 包 = `package.zip` 根目录有 `manifest.json` 和 `README.md`，`manifest.id` 是规范包名，`kind` 明确，引用文件都存在，能力包声明运行入口和 schema，凭证只声明环境变量名不写真实值，价格/库存/发布状态留给 listing 草稿处理。
