Specification
Service manifest
The .asmp.yaml file that declares what a service is and what it can do.
Every service ships a source manifest with the code. The host registry copies it into the index.
| Location | Role |
|---|---|
asmp.yaml (repo root) | Source of truth — ships with software |
infra/asmp.yaml | Alias for infra-heavy projects |
~/.asmp/services/{name}.asmp.yaml | Host index — written by scan or announce |
Index filename: {name}.asmp.yaml
See Ship with software for the author checklist.
Full example
asmp: "0.1"
kind: service
# ── Identity ────────────────────────────────────────────────
name: email-daemon
description: "Email intelligence — ingest, analyze, decide, verify"
version: "1.0.0"
created_by: claude-code
owner: daniel
created_at: "2026-03-31T03:00:00Z"
# ── Runtime ─────────────────────────────────────────────────
run:
command: python3
args: [main.py]
working_dir: ~/repos-personal/aic-director-daemon
env:
PYTHONPATH: .
restart: always
depends_on:
- name: apple-mail
kind: soft
lifecycle:
start: "launchctl load ~/Library/LaunchAgents/com.example.email-daemon.plist"
stop: "launchctl unload ~/Library/LaunchAgents/com.example.email-daemon.plist"
reload: "launchctl kickstart -k gui/501/com.example.email-daemon"
state: running
# ── Network ─────────────────────────────────────────────────
endpoints:
- protocol: http
host: 127.0.0.1
port: 7400
path: /
visibility: loopback
health:
method: http
target: http://127.0.0.1:7400/health
interval: 30s
timeout: 5s
# ── Capabilities ────────────────────────────────────────────
capabilities:
provides:
- email.ingest
- email.classify
- email.search
owns:
- email.workflow.intelligence
- email.question.answering
supports:
- crm.contact.create
aliases:
- email brain
- inbox intelligence
anti_routes:
- calendar.schedule
- filesystem.backup
requires:
- apple-mail.envelope-index:read
- filesystem:read:~/Library/Mail
positive_examples:
- "answer a question from recent email"
- "classify inbound mail"
negative_examples:
- query: "schedule a meeting from this email"
handoff: calendar-agent
when_not_to_use:
- "Do not use for calendar writes; hand off to the calendar service."
# ── Data ────────────────────────────────────────────────────
data:
sensitivity: medium
stores:
- path: ~/data/email-brain.db
type: sqlite
contains: [email_metadata, email_bodies]
# ── Mods ────────────────────────────────────────────────────
mods:
- name: compliance-scanner
description: "Scans emails for PII violations"
agent: security-mod
attaches_to: [email.classify]
capabilities:
provides: [compliance.pii_detect]
requires: [email.read]
state: available
# ── Observability ───────────────────────────────────────────
logs:
path: ~/.local/log/email-daemon.log
format: text
repo: ~/repos-personal/aic-director-daemon
# ── Display ─────────────────────────────────────────────────
display:
icon: "✉️"
section: tools
critical: true
url: http://localhost:7400/status
Sections
Identity
| Field | Required | Description |
|---|---|---|
name | yes | Lowercase, hyphens ok. Stable identifier. |
description | yes | One-line summary for discovery |
version | yes | Semver |
created_by | yes | Agent or human that wrote the manifest |
owner | yes | Responsible human |
created_at | no | ISO 8601 timestamp |
Runtime
How the service runs. The host runtime maps this to native format (plist, systemd unit, compose file).
| Field | Description |
|---|---|
run.command | Executable |
run.args | Command arguments |
run.working_dir | Working directory |
run.env | Environment variables |
run.restart | always, on-failure, no |
run.depends_on | Other services this needs |
lifecycle.start/stop/reload | Shell commands for lifecycle |
state | running, stopped, planned |
Network
| Field | Description |
|---|---|
endpoints[].protocol | http, grpc, mcp, stdio |
endpoints[].port | Port number |
endpoints[].visibility | loopback, tailnet, public |
health.method | http, tcp, exec |
health.target | URL, address, or command |
Capabilities
The discovery layer. Other agents query by provides. Registration validates that requires are satisfiable.
For vague natural-language routing, manifests may also declare:
| Field | Description |
|---|---|
owns | Primary owner for a workflow or question type |
supports | Can assist, but is not the default owner |
aliases | Plain-language names |
positive_examples | Queries this service should win |
negative_examples | Queries to reject (query + handoff) |
anti_routes | Topics or capability prefixes to disqualify |
when_not_to_use | Human-readable guardrails |
See Routing boundaries for how hosts apply policy when candidates tie.
Data
| Field | Description |
|---|---|
sensitivity | low, medium, high, regulated |
stores[] | Paths, types, and contents for audit |
Display
Metadata for dashboards. Icon, section grouping, criticality flag, status URL.
Index metadata (host only)
When synced by scan or announce, the index may add fields the source manifest does not carry:
| Field | Description |
|---|---|
source | Absolute path to shipped asmp.yaml |
last_seen | ISO 8601 timestamp of last scan or announce |
generation | Monotonic handshake counter |
sync | scan or announce |
status | registered or stale |