ワンクリックで
delivery-routing
Route research summaries to local markdown, Telegram, or Slack with approval gates and delivery-state updates.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Route research summaries to local markdown, Telegram, or Slack with approval gates and delivery-state updates.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Full interactive setup for the agentic CRM personal assistant template. Use at first boot or whenever the user asks to configure/reconfigure the assistant.
Discover, research, and CONNECT the tools a tool-agnostic personal assistant needs — email, calendar, contacts, meeting notes, messaging, CRM. CLI-first, research-driven, verified. Use during setup and whenever a workflow fails because a tool is missing or not authed.
You need to create a new agent, restart a crashed agent, change an agent's model or config, fix a Telegram bot token, troubleshoot why an agent is not responding, enable or disable an agent, spawn an agent for another user, manage PM2 process management, reset crash limits, or do anything that touches an agent's lifecycle, configuration, or credentials. This is the definitive guide for every agent operation in cortextOS.
You need to create a new agent, restart a crashed agent, change an agent's model or config, fix a Telegram bot token, troubleshoot why an agent is not responding, enable or disable an agent, spawn an agent for another user, manage PM2 process management, reset crash limits, or do anything that touches an agent's lifecycle, configuration, or credentials. This is the definitive guide for every agent operation in cortextOS.
You need to create a new agent, restart a crashed agent, change an agent's model or config, fix a Telegram bot token, troubleshoot why an agent is not responding, enable or disable an agent, spawn an agent for another user, manage PM2 process management, reset crash limits, or do anything that touches an agent's lifecycle, configuration, or credentials. This is the definitive guide for every agent operation in cortextOS.
You need to create a new agent, restart a crashed agent, change an agent's model or config, fix a Telegram bot token, troubleshoot why an agent is not responding, enable or disable an agent, spawn an agent for another user, manage PM2 process management, reset crash limits, or do anything that touches an agent's lifecycle, configuration, or credentials. This is the definitive guide for every agent operation in cortextOS.
| name | delivery-routing |
| description | Route research summaries to local markdown, Telegram, or Slack with approval gates and delivery-state updates. |
Send the run summary to the configured destination through cortextOS-safe delivery paths. Mark items as delivered only after successful delivery.
After brief-generation writes the run summary.
research/output/YYYY-MM-DD/summary.mdresearch/output/YYYY-MM-DD/signals-selected.json (needed to mark delivered_at on success)config.json (delivery config)research/db/signals.db (to mark delivered_at after successful delivery)delivered_at set on delivered items in research/db/signals.dbresearch/output/YYYY-MM-DD/run.logAlways check research.delivery.requires_approval before sending externally.
External destinations are telegram and slack. local_markdown and none do
not leave the machine.
true (default)Create a cortextOS approval, write a local approval context file, notify the user, and stop. Do not send externally until the approval is granted.
Every approval must have a parent task. If this delivery was started by a cron
or ad-hoc workflow and no task exists yet, create a run task first and mark it
in_progress.
research/output/YYYY-MM-DD/PENDING-APPROVAL.md
# Delivery Pending Approval -- YYYY-MM-DD
Run complete. Summary ready but not sent (`research.delivery.requires_approval = true`).
**Approval:** Created through `cortextos bus create-approval`.
**Summary path:** research/output/YYYY-MM-DD/summary.md
**Signals selected:** N
**Top signals:**
1. [Title] (score: X.X)
2. [Title] (score: X.X)
3. [Title] (score: X.X)
Use the normal approval workflow:
APPR_ID=$(cortextos bus create-approval \
"Send research summary for YYYY-MM-DD" \
external-comms \
"Destination: ${DESTINATION}. Summary: research/output/YYYY-MM-DD/summary.md. Pending context: research/output/YYYY-MM-DD/PENDING-APPROVAL.md")
cortextos bus send-telegram "$CTX_TELEGRAM_CHAT_ID" \
"Approval needed: research summary for YYYY-MM-DD is ready. Check dashboard approval ${APPR_ID}."
cortextos bus log-event action approval_created info \
--meta "{\"approval_id\":\"${APPR_ID}\",\"destination\":\"${DESTINATION}\"}"
If this run has a parent task, block that task on the approval. If it was cron started and has no parent task, create one before requesting approval, then block that task on the approval ID.
Log: Delivery pending approval. Request at research/output/YYYY-MM-DD/PENDING-APPROVAL.md approval_id=$APPR_ID
falseSend to configured destination automatically, then mark delivered_at.
cortextos bus send-telegram "$CTX_TELEGRAM_CHAT_ID" "$MESSAGE"
Message format: run date, signals collected vs. selected, top 3-5 titles with scores, any source failures, path to full output folder.
Keep under 4,096 characters. If longer, split into two messages.
Use Slack only when the workspace webhook is configured and approval policy allows external delivery.
curl -s -X POST "${SLACK_WEBHOOK_URL}" \
-H "Content-Type: application/json" \
-d '{"text": "MESSAGE"}'
Write research/output/YYYY-MM-DD/DELIVERED-summary.md as a copy of the summary.
No external HTTP calls.
No delivery. Summary stays at research/output/YYYY-MM-DD/summary.md.
Send only the summary -- not full brief text. The full briefs live on disk at
research/output/YYYY-MM-DD/briefs/.
Minimum content:
Retry up to 3 times with 5-minute intervals between attempts.
import time
def deliver_with_retry(send_fn, max_retries=3, delay_seconds=300):
for attempt in range(1, max_retries + 1):
try:
send_fn()
return True
except Exception as e:
log(f"delivery_failure attempt={attempt} detail={e}")
if attempt < max_retries:
time.sleep(delay_seconds)
return False
If all 3 attempts fail:
research/output/YYYY-MM-DD/DELIVERY-FAILED-summary.md.delivery_fallback path=research/output/YYYY-MM-DD/DELIVERY-FAILED-summary.mdRead delivery settings from config.json:
{
"research": {
"delivery": {
"destination": "local_markdown",
"requires_approval": true,
"summary_only": true
}
}
}
Supported destinations:
local_markdowntelegramslacknoneAfter the message sends successfully, call mark_delivered():
import sqlite3, datetime as dt, json
def mark_delivered(db_path, selected_json_path):
with open(selected_json_path) as f:
selected = json.load(f)
conn = sqlite3.connect(db_path)
now = dt.datetime.utcnow().isoformat()
for item in selected:
conn.execute(
"UPDATE items SET delivered_at=? WHERE canonical_key=?",
(now, item["canonical_key"])
)
conn.execute(
"""UPDATE daily_brief_items
SET delivered=1, delivered_at=?
WHERE item_id = (SELECT id FROM items WHERE canonical_key = ?)""",
(now, item["canonical_key"])
)
conn.commit()
conn.close()
This ensures items are only suppressed from future runs if delivery actually succeeded. If delivery failed, they remain eligible for the next run.