scoutica send
send is the first step of Scoutica’s agent-to-agent messaging layer. It composes a schema-valid message envelope addressed to another party’s Skill Card and writes it to your local outbox. It is how a recruiter’s agent pitches a role to a candidate’s agent, or how any agent opens a conversation with another.
Command Syntax
Section titled “Command Syntax”scoutica send <recipient_card_url> [options]<recipient_card_url> is the URL of the card you are messaging (the value published in the recipient’s scoutica.json).
Options
Section titled “Options”| Option | Behavior |
|---|---|
--type <message_type> |
The message type. Defaults to opportunity.pitch. See the type table below. |
--role <path> |
Path to a local role.json. Its role_url and a compensation_summary (base_min / base_max / currency) are attached to the payload. |
--message <text> |
Free-text note added to payload.message. |
--card <dir> |
Your own card directory, used to fill in sender.card_url. When omitted, Scoutica uses the current directory only if it contains exactly one distinct local card identity. |
The sender identity is read from scoutica.json or recruiter_profile.json. Missing, empty, or conflicting card_url values fail closed before any outbox, pending-delivery, or log artifact is created. Publish and point your card first so recipients can verify who composed the message.
Message types
Section titled “Message types”These are the canonical envelope types from message.schema.json:
| Type | Meaning |
|---|---|
opportunity.pitch |
Initial outreach about a role (default). |
opportunity.offer |
A concrete offer, typically carrying a --role. |
rules.check |
Ask whether a role clears the recipient’s rules.yaml. |
status.check |
Nudge for the status of an open thread. |
response.accept |
Accept — normally sent via scoutica reply --accept. |
response.reject |
Reject — normally sent via scoutica reply --reject. |
response.withdraw |
Withdraw from a thread. |
event.ghosting |
Record that the other party went silent. |
What gets written
Section titled “What gets written”A single send produces the message envelope in two places and appends one audit line:
~/.scoutica/outbox/<msg_id>.json # your copy of record~/.scoutica/pending_delivery/<recipient_hash>/<msg_id>.json # staged for deliver~/.scoutica/privacy/access_log.jsonl # transparency log (appended)<msg_id>ismsg_followed by 16 hexadecimal characters from a SHA-256 hash of the recipient and a microsecond-resolution composition time.<recipient_hash>is a 12-char SHA-256 hash of the recipient URL — the routing key used by the Git registry.- The
conversation_id(conv_...) is derived from the recipient URL, sender card URL, and message type, so repeated pitches on the same topic thread together.
Every envelope also records ttl_hours: 168 (7 days) and transport_used: "git".
The complete envelope is checked against the bundled trusted message.schema.json, including URI and date-time formats, before the first write. Each artifact is written atomically and symlinked destinations are refused.
Writes are serialized across local Scoutica processes, then ordered as outbox, pending delivery, and transparency log. If an ordinary failure leaves exactly one validated outbox entry without its matching final log record, repeating the same sender, recipient, type, payload, and conversation resumes that message id and fills only its missing pending/log steps. Conflicting or multiple incomplete matches fail closed. A matching final log marks the send complete even after deliver removes its pending file; the same command then intentionally creates a fresh message instead of becoming permanent content deduplication.
Example message envelope
Section titled “Example message envelope”{ "message_id": "msg_9f3a1c7d", "type": "opportunity.offer", "sender": { "card_url": "https://github.com/acme-corp/hiring-card" }, "recipient": "https://github.com/alice-developer/my-card", "conversation_id": "conv_2b8e4a10", "timestamp": "2026-07-08T14:20:00Z", "ttl_hours": 168, "transport_used": "git", "payload": { "message": "Your Rust + distributed systems background is a strong fit.", "role_url": "./roles/staff-backend.json", "compensation_summary": { "base_min": 140000, "base_max": 180000, "currency": "EUR" } }}Example
Section titled “Example”# A recruiter agent pitches a role to Alice's cardscoutica send https://github.com/alice-developer/my-card \ --type opportunity.offer \ --role ./roles/staff-backend.json \ --message "Your Rust + distributed systems background is a strong fit." \ --card ./acme-hiring-card
# Then push it to the recipientscoutica deliverSecurity posture
Section titled “Security posture”- No auto-send.
sendonly writes local files. The recipient is never contacted and no data leaves your machine at this step — delivery is a separate, explicit action. - Transparency log. Every send appends a
message_sentrecord to~/.scoutica/privacy/access_log.jsonl, so you always have an auditable trail of what you sent, to whom, and when. - Fail-closed generation. Invalid message types, sender identities, recipient URIs, or malformed role attachments create no outbound artifacts.
- Safe fetching downstream. When the recipient’s card URL is later resolved, that fetch runs through Scoutica’s URL guard — HTTPS is enforced and
localhost, private, link-local, and reserved addresses are rejected (SSRF prevention). Seescoutica resolve.
The message flow
Section titled “The message flow”Compose
scoutica send stages the message in your outbox and pending-delivery folder.
Deliver
scoutica deliver pushes staged messages toward recipients (via a registry PR today).
Receive
The recipient sees it with scoutica inbox.
Respond
They answer with scoutica reply --accept / --reject.