Skip to content

scoutica reply

reply answers a message you received. Point it at a message_id from your inbox, pick an action, and Scoutica builds the correctly-threaded response envelope, stages it for delivery, and files the original away.

Terminal window
scoutica reply <message_id> --accept [--card <dir>]
scoutica reply <message_id> --reject [--card <dir>]
scoutica reply <message_id> --withdraw [--card <dir>]

<message_id> is the id shown by scoutica inbox (for example msg_9f3a1c7d). Exactly one action flag is required.

Flag Response type Notes
--accept response.accept Adds your note to payload.message when --message is given.
--reject response.reject Records reasons. Without --message, the payload is marked auto_rejected: true with reason auto_rejected_by_rules.
--withdraw response.withdraw Adds your note to payload.reason when --message is given.
--message <text> Optional free text attached to any of the above.
--card <dir> Your local responder card. Its card_url becomes the reply sender and must equal the original recipient. Without this option, the current directory must resolve to exactly one local identity.

If you supply no action flag, the command exits with an error asking for --accept, --reject, or --withdraw. If the message_id is not found in your inbox, it tells you to check scoutica inbox.

Finds the original

Scans the actionable part of ~/.scoutica/inbox/ for the matching message_id. The processed/ subtree is excluded; it is consulted only to recognize an exact idempotent retry.

Builds the threaded response

Sets sender.card_url from your local card, addresses recipient to the original sender, sets in_reply_to to the original id, and carries over conversation_id. The original recipient must match the selected local card.

Stages it for delivery

After full schema and URI/date-time format validation, writes atomically in this order: ~/.scoutica/outbox/, ~/.scoutica/pending_delivery/<sender_hash>/, then one deduplicated reply_sent line in ~/.scoutica/privacy/access_log.jsonl.

Files the original

Moves the original last, preserving its relative inbox path under ~/.scoutica/inbox/processed/. Nested files with the same basename cannot overwrite each other.

A --reject with no message:

{
"message_id": "msg_4c1e88fa",
"type": "response.reject",
"sender": { "card_url": "https://github.com/alice-developer/my-card" },
"recipient": "https://github.com/acme-corp/hiring-card",
"conversation_id": "conv_2b8e4a10",
"in_reply_to": "msg_9f3a1c7d",
"timestamp": "2026-07-08T15:05:00Z",
"ttl_hours": 168,
"transport_used": "git",
"payload": {
"reasons": ["auto_rejected_by_rules"],
"auto_rejected": true
}
}
Terminal window
# Accept an offer with a note
scoutica reply msg_9f3a1c7d --accept --message "Happy to talk — Tuesday works." --card ./my-card
# Reject with a specific reason
scoutica reply msg_9f3a1c7d --reject --message "Below my salary floor."
# Reject and let the rules speak for themselves
scoutica reply msg_9f3a1c7d --reject
# Withdraw from a thread you started
scoutica reply msg_9f3a1c7d --withdraw --message "Position filled internally."
# Then push the response
scoutica deliver
  • No auto-send. reply only writes local files; your response reaches no one until you deliver it deliberately.
  • Consent is explicit. A message sits untouched in your inbox until you choose to answer. Nothing responds on your behalf, and the original is only consumed (moved to processed/) when you reply.
  • Auditable. Every reply is logged to your transparency log with its type, the id it answers, and the recipient.
  • Idempotent and resumable. The reply id is derived from the original id, action, and local sender. Retrying the identical action fills only missing ordered artifacts and never duplicates the log. A changed action, message, sender, or conflicting existing artifact is refused.
  • Concurrent-safe locally. A private no-follow lock serializes the complete state transition across Scoutica processes, so concurrent replies cannot mint divergent timestamps or lose transparency-log entries.
  • No partial invalid writes. Both the received envelope and generated reply are fully validated before mutation. Invalid messages leave the original actionable and create no outbound artifacts.

Your reply is staged, not sent. Push it with scoutica deliver; the sender then sees it in their own scoutica inbox.