协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
cross-project-mail【开发与工程】Use when sending or receiving messages between AI agents working in different sibling projects on the same host. Provides a flat-file mailbox (`~/.ai-mailbox/`), a `cpmail` CLI (send/list/read/ack/migrate/doctor), and a SessionStart hook that prints unread count per project. v1 is single-host trust model (no HMAC, no daemon, no MCP server) — cross-ma…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
~/.ai-mailbox/), a cpmail CLI (send/list/read/ack/migrate/doctor), and a SessionStart hook that prints unread count per project. v1 is single-host trust model (no HMAC, no daemon, no MCP server) — cross-machine and adversarial trust deferred to v2 (M3). Subsumes the manual cross-repo-review.md Outbound/Inbound convention via a one-shot idempotent migrator.A flat-file mailbox so AI agents in sibling projects on one host can leave each other messages that survive session boundaries. Replaces the manual cross-repo-review.md Outbound/Inbound file convention with a real CLI + SessionStart notification + idempotent migrator.
v1 trust model: single-user, single-host. All agents on this host share user trust. The only enforced XPIA defense is <user_data> delimiter wrapping on read; HMAC / quarantine / sender-allowlist deferred to v2 (M3) where cross-host trust boundaries make them pay their way.
Not in v1: MCP server, FastMCP transport, polling daemon, mcp_agent_mail wrapper, cross-machine (AB) mode, VS Code Copilot Chat integration, wiki-MCP. See docs/plans/2026-05-16-cross-project-mail-v1-design.md for the staged roadmap and the rationale for de-scoping from the full Stage 2 design.
cross-repo-review.md file to mailbox messages (one-shot, idempotent)cpmail doctor)# Install (one-time, per host)
bash ~/.claude/skills/cross-project-mail/install/install.sh
# Send a message
echo "Reviewed your Windows installer fix — looks good, merging" | \
cpmail send --to vs-code-foundry --subject "installer PR ack" --source-type human
# List unread for current project
cpmail list --unread
# Read a specific message (body is wrapped in <user_data>...</user_data>)
cpmail read 01HXY7K3M9TBVN8P4ZQGRJ2WAD
# Acknowledge (moves to .acked/)
cpmail ack 01HXY7K3M9TBVN8P4ZQGRJ2WAD
# Migrate an existing cross-repo-review.md (idempotent — safe to re-run)
cpmail migrate --from /path/to/vs-code-foundry/cross-repo-review.md
# Validate mailbox layout
cpmail doctor
| Command | Purpose |
|---|---|
cpmail send --to <project> [--agent <slug>] --subject <s> [--source-type <t>] [--reply-to <ulid>] [--label <l>]... [--from <stdin|@file>] | Compose and write a message envelope. Body from stdin or @path/to/file. |
cpmail list [--project <slug>] [--unread|--all|--acked] [--limit N] [--since <iso>] | List messages in an inbox. Defaults to current project + unread. |
cpmail read <ulid> | Print frontmatter + body. Body is wrapped in <user_data>...</user_data>. |
cpmail ack <ulid> | Mark as acked. Moves file to inbox/<project>/.acked/. |
cpmail migrate --from <path> [--dry-run] | Convert a cross-repo-review.md file into mailbox messages. Idempotent. |
cpmail doctor [--mailbox <path>] | Validate layout, report orphans, corrupted frontmatter, unknown enums. |
cpmail _detect-project [--from-cwd <path>] | Internal: detect current project name. Used by SessionStart hook. |
cpmail --help | Show all commands. |
0 — success1 — runtime error (filesystem, permissions, etc.)2 — invalid input (bad schema, missing required field, invalid enum value)3 — not found (message id, project, file)| Anti-Pattern | Why it fails | Correct |
|---|---|---|
cat ~/.ai-mailbox/inbox/foundry-lab/01HXY...md | Bypasses the <user_data> delimiter wrap — exposes prompt-injection surface | cpmail read 01HXY... |
| Hand-editing a message file | Skips schema validation; may corrupt the closed-set field whitelist | Use cpmail send (re-send if you need to amend); cpmail ack to close |
Sending with source_type: human for an AI-summarized web fetch | False provenance — recipient under-applies skepticism | Use source_type: web_fetch_quoted when body quotes web content; ai_summary when AI-condensed |
Polling ~/.ai-mailbox/inbox/ from a tight loop | DoS yourself; the hook is for SessionStart only | Use cpmail list --unread on demand |
| Storing secrets in message body | The mailbox is plain markdown on disk, mode 0600 but not encrypted | Reference secrets by path or env-var name; never inline them |
Cross-machine sync via rsync ~/.ai-mailbox/ | v1 has no consistency model for concurrent writers across hosts | Wait for M3 (mcp_agent_mail wrapper) or use git mirror with careful single-writer discipline |
Sending without a subject | All commands require subject; sender-discipline (recipient grep relies on it) | Include --subject "..."; ≤200 chars |
Modifying ~/.ai-mailbox/inbox/*/.acked/ files | The ack archive is intentionally read-once-write-once | Never; use cpmail doctor if state seems wrong |
~/.ai-mailbox/
├── inbox/<recipient-project>/
│ ├── <ulid>.md # unread messages
│ └── .acked/<ulid>.md # acked archive
├── outbox/<sender-project>/ # symlinks back into inbox/
└── .config.yaml # optional path overrides, project aliases
See schemas/envelope.v1.json for the formal JSON Schema. Example:
---
schema_version: "1"
msg_id: 01HXY7K3M9TBVN8P4ZQGRJ2WAD
sent_at: "2026-05-17T14:32:10Z"
sender:
project: vs-code-foundry
agent: claude_code
host: workstation
recipient:
project: foundry-lab
agent: null
subject: "Windows installer cmd+ps1 hardening"
source_type: human
reply_to: null
thread_id: null
labels: [cross-repo-review, installer]
ack_state: unread
attachments: []
---
Two cross-platform installer bugs that no Linux session could surface...
Installed at ~/.claude/skills/cross-project-mail/hooks/session-start.sh. Budget: <100ms. Wired into Claude Code via ~/.claude/settings.json hooks.SessionStart. Codex + Gemini parity via symlinks. Copilot CLI: documented gap (#971) — workaround is a shell alias.
Output (only when unread > 0):
[mail] 3 unread for foundry-lab (run: cpmail list --unread)
tests/test_cpmail.py covers ~30 cases: envelope round-trip, CLI send/list/read/ack, SessionStart hook (0 / N unread), migrator idempotency, doctor on broken mailbox, performance budgets (p95 hook <100ms with 100 unread; cpmail list p95 <200ms with 1000 messages). Run: cd tests && python3 -m pytest.
docs/plans/2026-05-16-cross-project-mail-v1-design.mdprogress/forge-cycle-s034/stage2-design/process-observation (telemetry sink we may use in M2), wiki (M4 substrate)