Overview
CSM-1 (Compact State Message v1) is a human-readable token format for encoding VCP context. It's designed to be:
- Compact — Minimal bytes, fits in headers and logs
- Human-readable — Developers can inspect tokens visually
- Privacy-preserving — Private data is represented by markers only
- Versioned — Forward compatible with future extensions
Token Format
A CSM-1 token consists of 7 lines:
VCP:<version>:<profile_id>
C:<constitution_id>@<version>
P:<persona>:<adherence>
G:<goal>:<experience>:<learning_style>
X:<constraint_flags>
F:<active_flags>
S:<private_markers> Example Token
VCP:1.0:user_001
C:learning-assistant@1.0
P:godparent:3
G:learn_guitar:beginner:visual
X:<i class="fa-solid fa-volume-xmark" aria-hidden="true"></i>quiet:<i class="fa-solid fa-coins" aria-hidden="true"></i>low:<i class="fa-solid fa-stopwatch" aria-hidden="true"></i>30minutes
F:time_limited|budget_limited
S:<i class="fa-solid fa-lock" aria-hidden="true"></i>work|<i class="fa-solid fa-lock" aria-hidden="true"></i>housing Line-by-Line Breakdown
Line 1: Header
VCP:<version>:<profile_id> | Field | Type | Description |
|---|---|---|
| version | string | VCP protocol version (e.g., "1.0") |
| profile_id | string | Unique user/profile identifier |
Line 2: Constitution Reference
C:<constitution_id>@<version> | Field | Type | Description |
|---|---|---|
| constitution_id | string | Constitution identifier (e.g., "learning-assistant") |
| version | string | Constitution version |
Line 3: Persona
P:<persona>:<adherence> | Field | Type | Values |
|---|---|---|
| persona | enum | godparent, sentinel, ambassador, anchor, nanny |
| adherence | 1-5 | How strictly to follow constitution rules |
Line 4: Goal Context
G:<goal>:<experience>:<learning_style> | Field | Type | Values |
|---|---|---|
| goal | string | User's primary goal (e.g., "learn_guitar") |
| experience | enum | beginner, intermediate, advanced, expert |
| learning_style | enum | visual, auditory, hands_on, reading, mixed |
Line 5: Constraint Flags (X-line)
X:<emoji_flags> Colon-separated constraint markers using emoji shortcodes:
| Emoji | Meaning | Example |
|---|---|---|
| Quiet mode preference | quiet | |
| Silent required | silent | |
| Budget tier | low | |
| 🆓 | Free only | 🆓 |
| Premium budget | high | |
| Energy variable | var | |
| ⏰ | Time limited | ⏰lim |
| Session length | 30minutes | |
| Irregular schedule | irreg |
If no constraints: X:none
Line 6: Active Flags (F-line)
F:<flag1>|<flag2>|... Pipe-separated list of currently active constraint flags:
time_limitedbudget_limitednoise_restrictedenergy_variableschedule_irregularmobility_limitedhealth_considerations
If none: F:none
Line 7: Private Markers (S-line)
S:<category1>|<category2>|... Shows categories of private data that influenced the context, but never the values:
work— Work-related private context existshousing— Housing-related private context existshealth— Health-related private context existsfinancial— Financial private context exists
If no private context: S:none
Encoding Rules
String Encoding
- All strings are UTF-8
- Spaces in values are replaced with underscores
- Colons (
:) in values must be escaped as\: - Pipes (
|) in values must be escaped as\|
Optional Fields
- Missing goal:
G:unset:beginner:mixed - Missing persona:
P:godparent:3(default) - Empty constraints:
X:none
Parsing
To parse a CSM-1 token:
function parseCSM1(token: string) {
const lines = token.split('\n');
const result = {};
for (const line of lines) {
const [key, ...values] = line.split(':');
result[key] = values.join(':');
}
return result;
}
// Returns:
// {
// VCP: "1.0:user_001",
// C: "learning-assistant@1.0",
// P: "muse:3",
// G: "learn_guitar:beginner:visual",
// X: "<i class="fa-solid fa-volume-xmark" aria-hidden="true"></i>quiet:<i class="fa-solid fa-coins" aria-hidden="true"></i>low:<i class="fa-solid fa-stopwatch" aria-hidden="true"></i>30minutes",
// F: "time_limited|budget_limited",
// S: "<i class="fa-solid fa-lock" aria-hidden="true"></i>work|<i class="fa-solid fa-lock" aria-hidden="true"></i>housing"
// } Display Formatting
For visual display, tokens can be boxed:
┌────────────────────────────────────────┐
│ VCP:1.0:user_001 │
│ C:learning-assistant@1.0 │
│ P:godparent:3 │
│ G:learn_guitar:beginner:visual │
│ X:<i class="fa-solid fa-volume-xmark" aria-hidden="true"></i>quiet:<i class="fa-solid fa-coins" aria-hidden="true"></i>low:<i class="fa-solid fa-stopwatch" aria-hidden="true"></i>30minutes │
│ F:time_limited|budget_limited │
│ S:<i class="fa-solid fa-lock" aria-hidden="true"></i>work|<i class="fa-solid fa-lock" aria-hidden="true"></i>housing │
└────────────────────────────────────────┘ Security Considerations
What CSM-1 Guarantees
- Private context values are never included in tokens
- Only category names appear in the S-line, not values
- Tokens can be logged and inspected without privacy leakage
What CSM-1 Does NOT Do
- Encryption — Tokens are readable by anyone who receives them
- Authentication — Tokens don't prove who created them
- Integrity — Tokens can be modified in transit (use signing separately)
Extensions
CSM-1 is designed for forward compatibility. Future versions may add:
- Additional lines for new context types
- New emoji shortcodes for constraints
- Compression for high-volume scenarios
Parsers should ignore unrecognized lines gracefully.
Next Steps
- API Reference — Encoding/decoding functions
- Playground — Build tokens interactively