Agent Messaging Guide
How to send and receive messages between AILANG core and external projects using the unified messaging system.
Quick Reference
# List all messages
ailang messages list
# Show only unread messages
ailang messages list --unread
# Read full message content
ailang messages read MSG_ID
# Acknowledge (mark as read)
ailang messages ack MSG_ID
ailang messages ack --all
# Send a message
ailang messages send user "Your message" --title "Title" --from "agent-name"
# Send with GitHub sync
ailang messages send user "Bug report" --title "Parser crash" --type bug --github
# Semantic search
ailang messages search "parser error"
ailang messages search "bugs" --neural # Uses Ollama embeddings
# Find duplicates
ailang messages dedupe
ailang messages dedupe --apply # Mark duplicates
Storage Backend — one canonical store, plus a private local one
Messages live in one of two places, and by default ailang messages reads only the local one:
| Store | Selected by | Holds |
|---|---|---|
Canonical cloud (prod Firestore, ailang-multivac) | AILANG_STORAGE_MESSAGING=gcp + AILANG_MESSAGES_PROJECT=ailang-multivac | public + package feedback, coordinator completions, cross-machine agent traffic |
| Local SQLite (per-machine, private) | default | that machine's own agent inbox, sprint state |
- Local location:
~/.ailang/state/collaboration.db - Accessible via: CLI (
ailang messages) and Collaboration Hub dashboard - Message statuses:
unread,read,archived,deleted
Anything written from outside this machine is in the cloud store and is invisible to a bare
ailang messages list — including the SessionStart hook's inbox summary. So every machine doing
AILANG work (the voightkampff Studio, cloud sessions, Claude Code managed runs, the attended
laptop) should export the canonical store in its shell profile:
export AILANG_STORAGE_MESSAGING=gcp
export AILANG_MESSAGES_PROJECT=ailang-multivac
These are safe to export. AILANG_STORAGE_MESSAGING is the per-store override of the ONE
plane switch AILANG_STORAGE=local|gcp|hybrid (M-V1-SIMPLIFY-S3 M3; the siblings are
AILANG_STORAGE_COORDINATOR and AILANG_STORAGE_OBSERVATORY). It moves messaging alone and
leaves the coordinator and observatory backends (eval banking, ailang chains) on local storage —
verify with ailang storage status, which prints one line per store with its mode, the variable
it came from, and the path or project:
messaging gcp (AILANG_STORAGE_MESSAGING) project ailang-multivac (AILANG_CLOUD_PROJECT)
coordinator local (default) ~/.ailang/state/coordinator.db
observatory local (default) ~/.ailang/state/observatory.db
To read this machine's private inbox, override for one command:
AILANG_STORAGE_MESSAGING=local ailang messages list --unread.
The scoped selector this replaced, AILANG_MESSAGES_STORE, is a hard error for one release
(AILANG_MESSAGES_STORE was removed in v1.0.0 …; set AILANG_STORAGE_MESSAGING=gcp), as are
AILANG_COORDINATOR_REMOTE, AILANG_CHAINS_READ and AILANG_CHAINS_CLOUD. A value that is now
ignored must not look honoured.
Any listing against a non-local store prints store: gcp (Firestore, project ...) in its header.
Read it: an empty inbox and a read against the wrong project are otherwise indistinguishable, and
GOOGLE_CLOUD_PROJECT is ignored — only AILANG_CLOUD_PROJECT (or the AILANG_MESSAGES_PROJECT
override) selects the project. AILANG_CLOUD_PROJECT is commonly pinned per-machine to
ailang-multivac-dev, a stale graveyard, which is why the messaging-scoped override exists and wins.
Triaging Public and Package Feedback
External user feedback is written to the PROD project (ailang-multivac). The public MCP
(mcp.ailang.sunholo.com) writes to prod Firestore; any agent session reading dev-only, or reading
local SQLite, is blind to real users. With the canonical store exported (above), the ordinary
commands reach it:
# Everything unread, across every inbox — the query to start from:
ailang messages list --unread
# Public feedback from real users:
ailang messages list --inbox public-feedback --unread
# Package-scoped feedback lands in pkg:<vendor>/<name> inboxes:
ailang messages list --inbox "pkg:sunholo/ailang-parse" --unread
Acking writes back to the same prod store: ailang messages ack <id> sets status="read" and clears
it from the queue. There is no CLI verb to set status="resolved" or attach a resolution note, so the
authoritative resolution record is the CHANGELOG (which cites ticket IDs like fb_cef305) plus the git
commits — not the inbox. Do not hand-write prod Firestore via curl PATCH; use the CLI.
Three traps when reading the cloud store
Measured 2026-08-25 against prod:
-
--inbox public-feedbackis not the whole channel. Package feedback routes topkg:<vendor>/<name>. Prefer--unreadwith no--inbox, which spans every inbox, over guessing names. -
The list view truncates IDs to 8 characters, so every cloud
inbox_<epoch>_<hash>message renders as(inbox_17)and cannot be acked from what you see — take full IDs from--json(JSON goes to stdout; warnings go to stderr). An ambiguous prefix errors loudly rather than acking the wrong message. -
messages read <id>marks the message read as a side effect. Triaging by reading silently drains the unread queue, so the next session sees an empty inbox and concludes nothing arrived. To inspect without acking, read the body out of--jsoninstead. -
A binary that predates the store selector ignores it SILENTLY.
AILANG_STORAGE_MESSAGINGlanded with M-V1-SIMPLIFY-S3 M3 (its predecessorAILANG_MESSAGES_STOREin6759ea4fa); an olderailangonPATHdoes not merely fail to reach the cloud, it accepts the variable, reads local SQLite, and exits 0 — so every trap above is unreachable and the session believes it read the canonical store. The control is one command: a deliberately invalid value must be REFUSED.ailang messages list --unread # a store this does not name in its header is LOCALAILANG_STORAGE_MESSAGING=not-a-real-store ailang messages list --unread# current binary: Error: invalid storage selection: AILANG_STORAGE_MESSAGING="not-a-real-store" (valid: local, gcp)# stale binary: prints a normal listing, rc=0 <-- you are reading local, silentlyA non-local listing names its store in the header (
store: gcp (Firestore, project ...)). No header, no cloud.
Note on the cross-inbox index, because "declared" is not "live". Cross-inbox
--unreadneeds aninbox_messages(statusASC,created_atDESC) composite index; both older indexes lead withto_inboxand so serve only the per-inbox fallback. Without it the CLI failsFailedPrecondition— meaning the one query trap 1 tells you to prefer is the one that cannot run, and sessions fall back to naming inboxes they already thought of.The index is declared in
terraform/firestore.tfin theailang-multivacdeploy repo (not this one — this repo tracks zero.tffiles). A declaration only takes effect when an apply runs: on 2026-08-25 the declaration landed at 19:15 and prod still had no index at 20:33, where the query failedrc=1, deterministic 2/2. Verify against prod rather than against the Terraform, with the query itself:AILANG_STORAGE_MESSAGING=gcp AILANG_MESSAGES_PROJECT=ailang-multivac ailang messages list --unreadrc=0 means the index is live;
FailedPreconditionmeans it is declared and unapplied.
For real-time notification (Discord/macOS) of prod feedback, the notify daemon must dual-subscribe dev + prod — see Cloud Messaging Integration → Dual-subscribe.
Message Format
Messages in the system contain:
{
"id": "uuid",
"message_id": "msg_20251210_123456_abc123",
"from_agent": "agent-name",
"to_inbox": "user",
"message_type": "notification",
"title": "Brief title",
"payload": "Detailed message content",
"category": "bug|feature|general",
"github_issue": 42,
"github_repo": "owner/repo",
"simhash": 1234567890123456789,
"dup_of": "original_message_id",
"embedding": "[0.123, 0.456, ...]",
"embedding_model": "ollama:nomic-embed-text",
"status": "unread",
"created_at": "2025-12-10T12:34:56Z"
}
Semantic Search Fields (v0.5.11+)
| Field | Description |
|---|---|
simhash | 64-bit locality-sensitive hash for fast similarity |
dup_of | Message ID this is a duplicate of (set by dedupe) |
embedding | JSON-encoded float32 vector (neural search) |
embedding_model | Model used to generate embedding (e.g., "ollama:nomic-embed-text") |
envelope | JSON object with named embedding vectors (v0.8.1+, see Semantic Envelope) |
Architecture
External Project AILANG Core
| |
| ailang messages send user "msg" |
|------------------------------------>|
| -> collaboration.db |
| |
| (Optional) --github flag |
|------------------------------------>|
| -> GitHub Issue created |
| |
|<------------------------------------|
| ailang messages send proj "..." |
| -> collaboration.db |
Workflows
Responding to Bug Reports
- Check inbox:
ailang messages list --unread - Read full message:
ailang messages read MSG_ID - Create design doc if needed
- Send acknowledgment:
ailang messages send PROJECT_NAME "Bug acknowledged - design doc created for vX.Y.Z" \--title "Bug acknowledged" --from "ailang"
- Acknowledge original:
ailang messages ack MSG_ID
Sending to GitHub Issues
Use the --github flag to also create a GitHub issue:
# Report a bug (creates GitHub issue with "bug" label)
ailang messages send user "Parser crashes on nested records" \
--title "Parser crash bug" --type bug --github
# Request a feature
ailang messages send user "Add async/await syntax" \
--title "Async support" --type feature --github
# The message is ALWAYS saved locally first
# GitHub sync is optional and fails gracefully
Automated Feedback (Advanced)
Set up automatic feedback when your CI/CD detects AILANG issues:
#!/bin/bash
# In your CI pipeline
# Run AILANG tests
if ! ailang run --caps IO --entry main tests/integration.ail 2>error.log; then
# Send failure report
ERROR=$(cat error.log | head -50)
VERSION=$(ailang --version)
OS=$(uname -a)
ailang messages send user "CI failure: $ERROR. Version: $VERSION, OS: $OS" \
--title "CI failure on $(git rev-parse --short HEAD)" \
--from "my-project-ci" \
--type bug \
--github
fi
CLI Commands
List Messages
ailang messages list # All messages
ailang messages list --unread # Only unread
ailang messages list --inbox user # Filter by inbox
ailang messages list --from agent-name # Filter by sender
ailang messages list --json # JSON output
ailang messages list --limit 50 # Limit results
Read Message Content
ailang messages read MSG_ID # Full content, marks as read
ailang messages read MSG_ID --peek # View without marking read
ailang messages read MSG_ID --json # JSON output
Acknowledge Messages
ailang messages ack MSG_ID # Mark specific message as read
ailang messages ack --all # Mark all as read
ailang messages ack --all --inbox user # Mark all in inbox as read
Un-acknowledge (Mark Unread)
ailang messages unack MSG_ID # Move back to unread
Send Messages
# Basic send
ailang messages send INBOX "message content" --title "Title" --from "agent"
# With GitHub sync
ailang messages send INBOX "message" --type bug --github
ailang messages send INBOX "message" --type feature --github
ailang messages send INBOX "message" --github --repo owner/repo
# With semantic envelope (v0.8.1+)
ailang messages send INBOX "Fix parser bug" --title "Bug" \
--envelope-code internal/parser/parser.go
ailang messages send INBOX "Fix bug" --title "Bug" \
--envelope-context "reviewing ast type switches"
# Tag-routed sends (v0.23.0+, M-COORD-TAG-ROUTING-LASTMILE)
# The --requires flag stamps worker tags on the message; the daemon
# publishes to Pub/Sub with those tags as attributes. Subscriptions
# whose worker_tags ⊇ requires claim it; others NACK and stay idle.
ailang messages send eval-rig "Run motoko fizzbuzz smoke" \
--requires agent:motoko \
--from $(hostname) \
--title "tag-routed motoko smoke"
# Multiple tags (set intersection — worker must advertise ALL of them):
ailang messages send eval-rig "Run on the GPU-equipped Mac with local Ollama" \
--requires "gpu:m4-max-40core,ollama:gemma4-26b-ailang" \
--from laptop.dev \
--title "GPU+Ollama only"
Prerequisites for --requires (M-COORD-TAG-ROUTING-LASTMILE):
- Local daemon must have its HTTP listener bound (
ailang coordinator statusmust showHTTP: ✓ ...). v0.23.0+ plists do this by default; if your install pre-dates that, runmake coord-installonce. - At least one worker must advertise the required tag set in
~/.ailang/config.yamlworker_tags. See the coordinator-workers guide for setup. - Without
--requires, behavior is unchanged from v0.22.0 — the SQLite-only fire-and-forget path is the default for inbox-addressed messages.
Reply to GitHub Issues
Add comments to existing GitHub issue threads:
# Reply to a message that has a linked GitHub issue
ailang messages reply MSG_ID "Fixed in v0.5.10" --from "claude-code"
# Reply with explicit repo override
ailang messages reply MSG_ID "Working on it" --repo owner/repo
The reply command only works for messages created with --github flag. It adds a comment to the same issue thread, keeping the conversation together.
Import from GitHub
ailang messages import-github # Import from default repo
ailang messages import-github --repo owner/repo # Specific repo
ailang messages import-github --labels bug,help # Filter by labels
ailang messages import-github --dry-run # Preview without importing
Cleanup Old Messages
ailang messages cleanup --older-than 7d # Remove messages older than 7 days
ailang messages cleanup --expired # Remove expired messages
ailang messages cleanup --dry-run # Preview without deleting
Watch for New Messages
ailang messages watch # Watch all inboxes
ailang messages watch --inbox user # Watch specific inbox
GitHub Integration
Configuration
Create ~/.ailang/config.yaml:
github:
expected_user: YourGitHubUsername # REQUIRED: Must match gh auth status
default_repo: owner/repo # Default repo for issues
create_labels: # Labels added to created issues
- ailang-message
watch_labels: # Labels to filter when importing
- ailang-message
auto_import: true # Auto-import on session start
How It Works
-
Account Validation: The
expected_usermust match the activeghaccount- Run
gh auth statusto check current account - Switch accounts with
gh auth switch --user USERNAME - This prevents accidentally creating issues in wrong repos
- Run
-
Auto-Label Creation: Labels are automatically created if they don't exist
from:agent-name(purple) - who sent the messagebug(red),feature(cyan),general(light blue)ailang-message(blue) - identifies AILANG messages
-
Title Prefix: Issues are prefixed with sender name
[agent-name] Original Title
-
Issue Linking: Created issue number is saved to database
- Query with:
SELECT * FROM inbox_messages WHERE github_issue_number IS NOT NULL
- Query with:
Workflow
# 1. Check GitHub auth
gh auth status
# 2. Switch account if needed
gh auth switch --user YourUsername
# 3. Send message with GitHub sync
ailang messages send user "Bug: parser crashes" --type bug --github
# 4. Import issues from GitHub on session start (automatic via hook)
ailang messages import-github
Integration with Claude Code
The SessionStart hook (scripts/hooks/session_start.sh) automatically:
- Imports GitHub issues as messages (respects
auto_importconfig) - Checks for unread messages
- Injects message summary into system reminders
Messages appear at session start. After handling:
ailang messages ack <message-id> # Acknowledge specific message
ailang messages ack --all # Acknowledge all messages
Message Types and Routing
| Type | Purpose | Goes to GitHub? |
|---|---|---|
bug | Bug report | Yes (with --github) |
feature | Feature request | Yes (with --github) |
general | General communication | No (local only) |
Routing guidance:
- Bugs and features → Use
--githubfor visibility across all AILANG instances - Coordination messages → Local only, for agent-to-agent communication
- Instructions from humans → Create GitHub issues, they'll be imported automatically
Bi-directional GitHub Sync
The messaging system supports two-way sync with GitHub:
Sending to GitHub (Agent → GitHub)
# Bug reports and feature requests go to GitHub for visibility
ailang messages send user "Parser crash" --type bug --github
Importing from GitHub (GitHub → Local)
# Import issues from GitHub (runs automatically on session start)
ailang messages import-github
# Or manually with filters
ailang messages import-github --labels help-wanted
Use case: Human instructions via GitHub
You can write instructions as GitHub issues and have agents pick them up:
- Create issue on GitHub with
ailang-messagelabel - Next session,
import-githubruns automatically - Issue appears in agent's inbox as a message
- Agent reads and acts on the instructions
Semantic Search
Find messages by meaning, not just exact text matches. AILANG uses SimHash (locality-sensitive hashing) for fast, zero-cost semantic search.
Search Commands
# Search for messages by semantic content
ailang messages search "parser error handling"
ailang messages search "type inference bugs" --threshold 0.5
# Find messages similar to a specific message
ailang messages list --similar-to MSG_ID --threshold 0.70
# Hide duplicate messages (collapsed view)
ailang messages list --collapsed
# Show only duplicates of a specific message
ailang messages list --duplicates-of MSG_ID
# Search by envelope space (v0.8.1+)
ailang messages search --space code "internal/types"
ailang messages search --space intent "fix crash"
ailang messages search --space resolution "parser"
Search Flags
| Flag | Default | Description |
|---|---|---|
--threshold | 0.70 | Minimum similarity (0.0-1.0) |
--limit | 20 | Maximum results |
--max-scan | 1000 | Maximum messages to scan |
--inbox | (all) | Filter by inbox |
--neural | false | Use neural embeddings (requires Ollama) |
--simhash | true | Force SimHash mode (default, fast) |
--space | (none) | Search a specific envelope space (v0.8.1+) |
--json | false | Output as JSON |
How SimHash Works
SimHash generates a 64-bit fingerprint for each message based on word frequencies. Similar messages have similar fingerprints, allowing fast similarity comparison using Hamming distance:
- Score 1.0: Identical or near-identical messages
- Score 0.9+: Very similar (likely duplicates)
- Score 0.7-0.9: Related topics
- Score below 0.7: Different content
Benefits:
- ✅ Zero API costs (runs locally)
- ✅ Fast (O(1) comparison)
- ✅ Deterministic (same input → same output)
- ✅ Works offline
Deduplication
Find and mark duplicate messages to reduce inbox noise.
Dedupe Commands
# Report duplicates (dry run)
ailang messages dedupe
# Report with custom threshold
ailang messages dedupe --threshold 0.90
# Actually mark duplicates
ailang messages dedupe --apply
# Filter by inbox
ailang messages dedupe --inbox user --apply
How Deduplication Works
- Find groups: Messages with similarity ≥ threshold are grouped
- Select representative: Oldest message in each group is kept
- Mark duplicates: Newer messages get
dup_ofset to representative's ID - View behavior:
--collapsedhides messages withdup_ofset
Dedupe Report
Duplicate Report
Found 3 duplicate groups (7 messages)
Group 1 (95% similar, 2 duplicates):
* Keep: msg_20251210_123456_abc123
Parser crashes on nested records
- Archive: msg_20251210_134500_def456
Parser crash with nested records
- Archive: msg_20251210_145600_ghi789
Nested record parser crash
Neural Embeddings (Ollama)
For more sophisticated semantic search, use neural embeddings via local Ollama.
Prerequisites
- Install Ollama: https://ollama.ai
- Start Ollama server:
ollama serve - Pull an embedding model:
ollama pull nomic-embed-text # Fast, good qualityollama pull embeddinggemma # Google's embedding modelollama pull mxbai-embed-large # High quality, slower
Configuration
Create or update ~/.ailang/config.yaml:
embeddings:
# Provider: "ollama" (local), "openai", "gemini", or "none" (SimHash only)
provider: ollama
ollama:
# Model name - see 'ollama list' for available models
model: nomic-embed-text
# Ollama API endpoint
endpoint: http://localhost:11434
# Request timeout
timeout: 30s
# OpenAI embeddings (v0.8.1+)
openai:
# api_key: sk-... # Or set OPENAI_API_KEY env var
model: text-embedding-3-small # text-embedding-3-small, text-embedding-3-large, text-embedding-ada-002
# dimension: 1536 # 0 = model default
# Gemini embeddings (v0.8.1+)
gemini:
# api_key: ... # Or set GOOGLE_API_KEY env var
model: text-embedding-004 # text-embedding-004, embedding-001
# dimension: 768 # 0 = model default
search:
# Default search mode: "simhash" (fast) or "neural" (semantic)
default_mode: simhash
# Similarity thresholds (0.0-1.0)
simhash_threshold: 0.70
neural_threshold: 0.75
Environment Variables
Override config with environment variables:
# Provider (ollama, openai, gemini, none)
export AILANG_EMBED_PROVIDER=ollama
# Ollama settings
export AILANG_OLLAMA_MODEL=nomic-embed-text
export AILANG_OLLAMA_ENDPOINT=http://localhost:11434
# OpenAI settings (v0.8.1+)
export OPENAI_API_KEY=sk-...
# Gemini settings (v0.8.1+)
export GOOGLE_API_KEY=...
Using Neural Search
# Require Ollama to be running
ailang messages search "parser bugs" --neural
# Compare: SimHash (default, fast)
ailang messages search "parser bugs" --simhash
How Neural Search Works
- Query embedding: Your search query is converted to a vector
- Lazy embedding: Messages without embeddings are embedded on-demand (up to 50 per search)
- Cosine similarity: Vectors are compared using cosine similarity
- Cached: Embeddings are stored in the database for reuse
Benefits:
- ✅ Understands semantic meaning ("error" matches "bug", "crash", "failure")
- ✅ Cross-lingual potential (with multilingual models)
- ✅ Better for conceptual search
Trade-offs:
- ⚠️ Requires Ollama running locally
- ⚠️ First search embeds messages (slower startup)
- ⚠️ Uses more storage (768+ floats per message)
Model Recommendations
| Model | Dimension | Speed | Quality | Use Case |
|---|---|---|---|---|
nomic-embed-text | 768 | Fast | Good | General purpose |
mxbai-embed-large | 1024 | Medium | Better | High accuracy needs |
embeddinggemma | 768 | Fast | Good | Google model |
all-minilm | 384 | Very Fast | OK | Quick searches |
Checking Ollama Status
# Check if Ollama is running
curl http://localhost:11434/api/tags
# List available models
ollama list
# Pull a model
ollama pull nomic-embed-text
Semantic Envelope (v0.8.1+)
Messages can carry a semantic envelope — a set of named embedding vectors, each capturing a different aspect of the message's meaning. Unlike the single text-derived embedding used for search, the envelope provides multiple "channels" of semantic information designed for machine-to-machine communication.
The 5 Envelope Slots
| Slot | Source | When Computed | Use Case |
|---|---|---|---|
intent | Title + first 200 chars of payload | Auto (if embedder configured) | "What is being asked?" — triage, dedup |
code | File paths + code snippets | Explicit (--envelope-code) | "What code is affected?" — cluster by subsystem |
context | Session context description | Explicit (--envelope-context) | "What was the sender working on?" |
skill | Compiler phases, file patterns | Explicit (builder API) | "What expertise is needed?" |
resolution | Git diff + commit message | Auto (on task completion) | "How was this resolved?" — knowledge base |
Sending with Envelope
# Attach code context (embeds the file content)
ailang messages send executor "Fix parser bug" --title "Bug: Parser" \
--envelope-code internal/parser/parser.go
# Attach multiple files
ailang messages send executor "Fix type system" \
--envelope-code internal/types/unify.go,internal/types/subst.go
# Attach session context
ailang messages send executor "Fix crash" \
--envelope-context "reviewing ast.Type switches, found missing TypeVar case"
# Both
ailang messages send executor "Fix bug" \
--envelope-code internal/iface/builder.go \
--envelope-context "constructor type variables are TypeVar not SimpleType"
Multi-Space Search
Search different envelope slots to get different results:
# Search by what code is affected
ailang messages search --space code "internal/types/unify.go"
# Search by what action is needed
ailang messages search --space intent "fix crash"
# Find past resolutions for similar problems
ailang messages search --space resolution "parser"
The same query returns different results depending on which slot is searched.
Resolution Feedback Loop
When the coordinator completes a task:
- Git diff and commit message are extracted from the worktree
- A resolution embedding is computed
- The original message's envelope is updated with the
resolutionslot
This builds a searchable knowledge base over time — new problems can be matched against past solutions.
Triage
Cluster unread messages by envelope similarity:
# Cluster by intent (default)
ailang messages triage
# Cluster by code region
ailang messages triage --cluster-by code
# Filter to specific inbox
ailang messages triage --inbox user
# Show top 5 clusters
ailang messages triage --top 5
# JSON output
ailang messages triage --json
Example output:
Triage Report — 18 messages, 5 clusters (by code)
Cluster 1: Type system bugs (8 msgs)
a1b2c3d4 Fix unification crash eval-suite
e5f6g7h8 Type variable missing demos
Cluster 2: CLI commands (5 msgs)
i9j0k1l2 Add --verbose flag user
m3n4o5p6 Fix help text cli
Cluster 3: Eval harness (3 msgs)
q7r8s9t0 Benchmark timeout eval-suite
...
Triage Flags
| Flag | Default | Description |
|---|---|---|
--inbox | (all) | Filter by inbox |
--cluster-by | intent | Envelope slot to cluster on |
--top | 10 | Show top-N clusters |
--threshold | 0.75 | Minimum similarity for clustering |
--json | false | Output as JSON |
Embedding Providers
The envelope uses the same embedding provider configured for neural search. Three providers are supported:
| Provider | Config | Models | Cost |
|---|---|---|---|
| Ollama | provider: ollama | nomic-embed-text, embeddinggemma | Free (local) |
| OpenAI | provider: openai | text-embedding-3-small, text-embedding-3-large | Per token |
| Gemini | provider: gemini | text-embedding-004 | Per token |
Package Coordination Messages (M-PKG-MSG)
Package coordination messages are structured messages that carry typed envelopes for multi-agent package management. They use the ailang.package-message/v1 schema.
Package-Scoped Inboxes
Messages use typed addressing prefixes:
| Prefix | Example | Use Case |
|---|---|---|
pkg:vendor/name | pkg:sunholo/auth | Package maintainer inbox |
workspace:name | workspace:docparse | Consumer workspace inbox |
team:name | team:registry-admin | Team review inbox |
Message Kinds
| Kind | When Emitted | Action Required |
|---|---|---|
upgrade-available | New version published | Check compatibility |
interface-change-notice | Exported API changed | Verify imports |
effect-widening-warning | Effect ceiling expanded | Policy review |
compatibility-request | Maintainer asks for validation | Run tests |
compatibility-report | Downstream reports pass/fail | Track status |
contract-regression | Previously working API broken | Escalate |
migration-request | Downstream needs help upgrading | Provide guidance |
deprecation-notice | API will be removed | Plan migration |
upgrade-complete | Downstream adopted new version | Close task |
blocked | Migration stalled | Investigate |
superseded | Newer release obsoletes this | No action |
Auto-Emission
When you run ailang publish, the system automatically emits:
upgrade-availableif the version changedinterface-change-noticeif the interface hash changedeffect-widening-warningif the effect ceiling expanded- Older open messages for the same package are marked
superseded
CLI Commands
# Emit upgrade notification
ailang pkg notify-upgrade sunholo/auth@0.2.0 --summary "Tightened validation"
# Find affected workspaces
ailang pkg affected-by sunholo/auth
# View package-scoped messages
ailang messages list --inbox pkg:sunholo/auth
# Filter all package inboxes
ailang messages list --inbox pkg:sunholo/auth --unread
Message Lifecycle
Messages follow enforced state transitions:
open → acknowledged → in_progress → completed
↘ blocked → in_progress
↘ rejected
open → superseded (when newer version published)
Terminal states: completed, rejected, superseded.
Triage Classification
Package messages are automatically classified by actionability:
| Action | Meaning | Triggered By |
|---|---|---|
no_action | No downstream impact | Internal-only change, passing compat report |
verify_local | Local verification recommended | Content change, interface change |
migrate | Downstream migration needed | Contract change, deprecation |
escalate | Needs maintainer attention | Contract regression, blocked |
policy_block | Policy review required | Effect widening |
Aliases
The messages command has an alias for convenience:
ailang msg list # Same as: ailang messages list
ailang msg send ... # Same as: ailang messages send ...
See Also
- Collaboration Hub - Web UI shares the same SQLite database
- Coordinator Guide - Message routing and task execution
- Semantic Search - Deep dive on SimHash and neural embeddings
- Semantic Caching vs Vector DBs - When to use semantic caching
- Agent Workflows - Automated agent workflows
- State System - Persistent state management