# AgentPack Specification v0.1

**Status:** Draft
**Date:** 2026-06-07
**Implements:** CR-20260607-001 rev.2 §6.3 (FR-006/007/008) + §7.3 (SR-003)

An **AgentPack** is a downloadable, installable, versioned bundle of one or
more agents plus their prompts, knowledge, and metadata. It is the unit a
ResearchAgent Desktop user installs to gain a new capability ("top journal
reviewer", "literature mapper", …).

AgentPacks are a thin packaging layer over the existing agent-template
concept (`agent_dir` with `agent-config.yml` + optional `agents/`
sub-agents). A pack does NOT introduce a new runtime — `entrypoint` resolves
to an ordinary lambdagent config that runs through the same
`from_config()` / instance mechanism as any other agent. This deliberately
avoids the "agent vs instance vs pack" concept fragmentation flagged in the
CR review.

## 1. Directory layout

```
<pack-id>/
  manifest.yml          REQUIRED — pack metadata + permissions
  agents/               REQUIRED — agent configs (entrypoint lives here or at root)
    <entrypoint>.yml
    <sub-agent>.yml ...
  prompts/              OPTIONAL — extracted reusable prompt fragments
  knowledge/            OPTIONAL — bundled reference material (guides, rubrics)
  examples/             OPTIONAL — sample inputs / expected outputs
  README.md             OPTIONAL — human description
```

When installed, a pack lives at:

```
<data_dir>/agentpacks/<pack-id>/<version>/
```

(`<data_dir>` = `~/LambdAgentDesktop` in desktop mode, per FR-002.)

Multiple versions of the same pack may coexist; the newest is used unless an
agent pins a version.

## 2. manifest.yml schema

```yaml
# ── Identity (all REQUIRED) ──
id: research.top-journal-reviewer   # reverse-dotted, [a-z0-9.-], unique
name: Top Journal Reviewer          # human-readable
version: 0.1.0                       # semver
domain: research                    # research | medical | general | <free>
entrypoint: agents/reviewer.yml      # path (relative to pack root) to the
                                     # lambdagent config that runs first

# ── Audience (OPTIONAL, informational) ──
audience:
  - professor
  - phd_student

# ── Description (OPTIONAL) ──
description: >
  Generates a top-journal-grade peer review with acceptance estimate
  and an actionable revision checklist.

# ── Permissions (REQUIRED — see §3) ──
permissions:
  network: false              # outbound network access
  shell: false                # shell command execution
  file_write: workspace       # none | workspace | knowledge
  read_knowledge: true        # read the user's knowledge base
  read_filesystem: false      # read files outside KB + workspace

# ── Model recommendation (OPTIONAL, informational) ──
model:
  recommended:
    - claude-code/sonnet
    - anthropic/claude-sonnet
    - ollama/qwen

# ── Provenance (OPTIONAL) ──
author: kenny67nju
homepage: https://github.com/kenny67nju/lambdagentpaas
license: BUSL-1.1
```

### Field rules

| Field | Required | Validation |
|---|---|---|
| `id` | yes | matches `^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$`; reverse-dotted recommended |
| `name` | yes | non-empty string |
| `version` | yes | semver `MAJOR.MINOR.PATCH` |
| `domain` | yes | non-empty string (enum suggested, not enforced) |
| `entrypoint` | yes | relative path; must exist after install; must NOT escape pack root |
| `permissions` | yes | object; see §3 |
| `audience` | no | list of strings |
| `description` | no | string |
| `model.recommended` | no | list of `provider/model` strings |

## 3. Permission model (SR-003)

Every pack MUST declare its permissions. The installer shows a plain-language
summary before installing (FR-007). The runtime enforces them.

| Permission | Type | Default | Meaning |
|---|---|---|---|
| `network` | bool | `false` | Pack agents may make outbound network / web calls |
| `shell` | bool | `false` | Pack agents may execute shell commands |
| `file_write` | enum | `workspace` | Where agents may write: `none` / `workspace` (run dir only) / `knowledge` (also the KB) |
| `read_knowledge` | bool | `true` | Agents may read the user's knowledge base |
| `read_filesystem` | bool | `false` | Agents may read files outside KB + workspace |

### MVP enforcement rules

- **Third-party packs default to `shell: false`** and the installer **refuses**
  a third-party pack that declares `shell: true` unless the user passes an
  explicit `--allow-shell` override (CR §SR-003). Built-in / first-party packs
  (shipped in `agentexample/`) may declare `shell: true`.
- A pack declaring a permission it doesn't list is treated as that permission
  being `false` / `none` (deny by default).
- The runtime maps permissions onto the tool registry: `shell: false` removes
  `Bash`; `network: false` removes `WebSearch`/`WebFetch`; `file_write` scopes
  the working dir; etc. (Enforcement wiring is incremental — v0.1 validates +
  surfaces the declaration; full tool-registry gating lands alongside Phase F.)

## 4. Lifecycle

### Install (FR-007)

1. Source: local `.zip` OR GitHub Release URL (Q6 — GitHub Releases is the
   v1 registry).
2. Unzip to a temp dir; locate `manifest.yml`.
3. Validate manifest (§2 rules). Reject on any error.
4. Verify `entrypoint` exists and stays within the pack root (no `../` escape).
5. Show permission summary (FR-007):
   > 此智能体包将读取本地知识库，写入 workspace，不执行 shell，不访问网络。
6. On confirm: move into `<data_dir>/agentpacks/<id>/<version>/`.

### List

Enumerate `<data_dir>/agentpacks/*/*/manifest.yml`, return id/name/version/
domain/permissions per installed pack.

### Uninstall

Remove `<data_dir>/agentpacks/<id>/<version>/` (or all versions of an id).

### Use

Creating an agent "from a pack" sets the agent's `agent_dir` to the pack's
installed path; `entrypoint` is the config `from_config()` compiles. The pack
is otherwise an ordinary agent template.

## 5. Built-in packs (FR-008)

Shipped in-repo under `agentexample/`, each gaining a `manifest.yml`:

| Pack id | Source dir | Function |
|---|---|---|
| `research.literature-mapper` | research67 | PDF set → 文献地图 + 方法谱系 + BibTeX |
| `research.top-journal-reviewer` | physics67 reviewer | 论文 → 顶刊审稿意见 + 接收概率 + 修改清单 |
| `research.grant-planner` | research67 | 方向 + 材料 → 立项依据 + 创新点 + 技术路线 |

## 6. Security notes

- Pack zips are untrusted input. Unzip MUST guard against path traversal
  (zip-slip): reject any member whose resolved path escapes the temp dir.
- `pickle`-based knowledge artifacts are forbidden in packs (audit #17).
- Manifest parsing uses `yaml.safe_load` only.
- The `entrypoint` and any `config:` sub-agent references are resolved
  relative to the pack root and may not escape it.
