.md

Pack

What the three files of a pack hold, what never goes in them, where packs live, and the gold packs to copy when you start a new one.

On this page

A Harness Pack is what a runtime installs: one directory, one id and three files that declare a capability's commands, rules and teaching. The pack declares and the runtime executes, so a pack holds nothing that depends on who runs it and moves unchanged between runtimes. Start by copying the gold pack closest to your capability and changing its id, bin, commands and Binding mode.

Layout#

packs/<id>/
  surface.json    manifest — id, adapter, Binding mode, named commands, optional triggers
  policy.json     rules — one row per command and per trigger
  HARNESS.md      Skill — one screen of teaching

The layout is flat, though a runtime may nest directories for its own operations without the pack knowing. The three names are exact and case-sensitive, and install fails when one is missing or when Policy does not cover every command and trigger. surface.json is the manifest's legacy filename, kept for wire stability, and has nothing to do with UI surfaces.

FilePieceYou fill
surface.jsonManifestIdentity (id), how it runs (kind, cliBin, wrap), the credentials it needs (binding.mode), the verbs map of named commands with their CLI forms, and triggers only for an upstream system that pushes, so most packs have none
policy.jsonPolicyFor every command and trigger: operation (read | write), privacy.land, and confirm on writes that must not auto-fire
HARNESS.mdSkillLead, hot-path table, examples, anti-patterns

Optional fields#

Add these to the manifest only when the capability needs them.

FieldWhen
stimulusTriggers[]The upstream system pushes real events
binding.familyRelated packs should share one login
wrap.agent_envThe wrapped bin needs environment defaults it already understands
plane: "control"Admin or operator CLI, which makes it a second pack
transports: [... "mcp"]A runtime will export MCP tools from this pack
pass_throughBootstrap only; promote to named commands
openapikind: openapi
skill_urlA hosted copy of the Skill

What stays out#

  • Secrets, a secrets/ directory or a .env file. The pack names a Binding mode and the runtime's hub mints the credential.
  • User allow-lists, roles, tenant ids and connector types, which belong to runtime grants and Principal scope.
  • A server, since a pack describes an existing CLI or API.
  • A whole binary. A pack names 5 to 12 commands, and allowedSubcommands pass-through is a bootstrap to promote.
  • UI widget catalogs or inbox chrome. A UI host invokes commands from outside.
  • A families/ directory, since family is a manifest field.
  • Extra Markdown for scale. A capability scales by adding packs, never by growing one.

Where packs live#

LocationPurpose
Your repository, packs/<id>/Source of record; one living repo per pack_id
$HCP_HOME/packs/<id>/Installed copy in the runtime store
$HCP_HOME/skills/<id>/SKILL.mdSkill copy written on activate

Gold packs#

PackClassLocation
transitPublic readhcp/examples/packs/transit
ledgerGated writehcp/examples/packs/ledger
echoComposite, sandbox-safehcp/examples/packs/echo
hcp-cliThe bootstrap pack (composite, local Binding)hcp/packs/hcp-cli

Identity#

A pack's identity is its manifest id, which is also pack_id on the wire and surface_id in the Policy file, and lint checks that all three agree. One pack_id maps to one maintained repository. A command is identified by pack_id + verb_key, a pair that stays stable across the CLI face, the JSON face, the Skill, the host tool catalog and any MCP export.

Planes#

planeMeaningBinding
runtime (default)End-user capabilitypublic · user · local
controlAdmin, fleet, operatormothership, in a second pack

A runtime never silently activates a control-plane pack on an end-user Principal, and a domain CLI with both an admin face and a user face is two packs.

Versioning#

An HCP/1.x pack declares protocol affinity hcp: 1 in its metadata and leaves content versioning to its repository. A manifest version field with registry resolution is on the roadmap.

Example#

The gold public-read pack, in full:

JSON
{
  "id": "transit",
  "name": "Transit",
  "kind": "wrap",
  "cliBin": "transit",
  "plane": "runtime",
  "transports": ["cli", "json_exec"],
  "binding": { "mode": "public", "hub": "public" },
  "wrap": { "bin": "../../bins/transit.mjs", "argv_template": ["{{verb}}"] },
  "verbs": {
    "find":   { "description": "Resolve a place.",                       "cli": ["transit", "find", "{{query}}"] },
    "plan":   { "description": "Time-first options between two places.", "cli": ["transit", "plan", "{{from}}", "{{to}}"] },
    "show":   { "description": "Expand one option.",                     "cli": ["transit", "show", "{{optionId}}"] },
    "status": { "description": "Live observation.",                      "cli": ["transit", "status"] },
    "follow": { "description": "Follow a run.",                          "cli": ["transit", "follow", "{{runId}}"] }
  }
}