Overview
CSM-1 (Constitutional Safety Minicode) is how VCP writes
constitutional context in a form both people and parsers can read. It has two
forms. The one-line CSM-1 code, such as N5+E+F, names a persona, its adherence level and its scopes, and is
written in the NANO, MICRO or COMPACT tier. The multi-line CSM-1 v1.1 token carries the persona alongside goals,
constraints and personal state. This page is a reference; the normative text
is VCP/S §2 in VCP-Spec.
The token is designed to be:
- Compact — Short enough to read at a glance. A multi-line token cannot go in an HTTP header, so headers carry the one-line code (NANO tier) instead
- Human-readable — Developers can inspect tokens visually
- Privacy-preserving — Private-context values never enter the token (the S-line marks only that private context exists), and R-line personal state is sent only with the user's consent
- Versioned — Forward compatible with future extensions
VCP:1.0, and that 1.0 is the token header version, separate
from both the format version and the protocol release. The protocol version
tracks the overall specification (layers, adaptation, personal state), while
the format version tracks the code and token grammar.CSM-1 codes
<persona><adherence>[+<scope>...][:<NAMESPACE>][@<version>] A code names a persona by one uppercase letter, gives its adherence level,
and lists any scopes. N5+E+F is the Nanny persona at adherence
5 with the Education and Family scopes. Scopes are optional and unique, and
the canonical form sorts them; a code with no scopes applies in every
context. A custom constitution (C) must name its namespace, as
in C3+W:ACME.
Personas
| Letter | Persona | Focus | Default adherence |
|---|---|---|---|
N | Nanny | Child safety and family-appropriate content | 5 |
Z | Sentinel | Security, privacy and operational safety | 4 |
G | Godparent | Ethical guidance and moral reasoning | 4 |
A | Ambassador | Professional conduct and diplomatic communication | 3 |
M | Muse | Creativity and artistic expression | 2 |
D | Mediator | Fair resolution and balanced mediation | 3 |
C | Custom | A user-defined constitution; requires :NAMESPACE | 3 |
Adherence levels
Adherence runs from 0 to 5 and sets how strictly the constitution is enforced and how far the user may override it: 0 Minimal (advisory only, never blocks), 1 Relaxed, 2 Moderate, 3 Standard, 4 Strict and 5 Maximum (no exceptions).
Scopes
| Code | Scope | Context |
|---|---|---|
F | Family | Family-appropriate, child-safe |
W | Work | Professional workplace |
P | Privacy | Data protection |
E | Education | Educational context |
T | Technical | Developer or technical context |
O | Official | Governmental, policy-compliant |
V | Vulnerable | Vulnerable populations |
A | Adult | Adult-only; mature content allowed |
H | Health | Healthcare and medical |
S | Social | Social media and community |
R | Religious | Religious and spiritual |
A code must not repeat a scope, and must not combine Adult (A)
with Family (F), Vulnerable (V) or Health
(H).
Encoding tiers
| Tier | Example | Adds | Used for |
|---|---|---|---|
| NANO | N5+E+F | Persona, adherence and scopes | HTTP headers and wire protocols |
| MICRO | N5+E+F:ELEM@1.2.0 | An optional namespace and version | API parameters and config files |
| COMPACT | CS1|nanny|5|family.safe.guide|E,F | The lowercase persona name and a UVC token | Human debugging |
A signed bundle's manifest may summarize its constitution with a CSM-1 code
in metadata.csm1. SDK 4.2.0 (Python CSM1Code, Rust Csm1Code) parses and encodes the NANO and MICRO tiers; neither
implements COMPACT.
Token format
A CSM-1 token has seven required lines and an optional eighth, the R-line,
which CSM-1 v1.1 added to carry VCP 3.1 personal state (VCP-X-Personal).
Optional extension lines such as LC: (lifecycle) may follow; see Extensions.
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>
R:<personal_state_dimensions> Example token
VCP:1.0:user_001
C:personal.growth.creative@1.0.0
P:M:3
G:learn_guitar:beginner:visual
X:⏰lim,💰lim,🔇quiet,💰low,⏱️30minutes
F:time_limited,budget_limited
S:🔒present
R:🧠focused:3|💭calm:4|🔋rested:3|⚡unhurried:2|🩺neutral:1 Line-by-line breakdown
Line 1: Header
VCP:<version>:<profile_id> | Field | Type | Description |
|---|---|---|
| version | string | Token header version, currently "1.0" (not the VCP protocol release and not the CSM-1 format version; parsers accept any non-empty value) |
| profile_id | string | Unique user/profile identifier |
Line 2: Constitution reference
C:<constitution_id>@<version> | Field | Type | Description |
|---|---|---|
| constitution_id | string | Constitution identifier, a UVC token (the VCP/I identity token), e.g., "personal.growth.creative" |
| version | string | Constitution version (e.g., "1.0.0") |
Line 3: Persona
P:<persona>:<adherence> | Field | Type | Values |
|---|---|---|
| persona | letter | One uppercase letter: N (Nanny), Z (Sentinel), G (Godparent), A (Ambassador), M (Muse), D (Mediator), C (Custom) |
| adherence | 0-5 | How strictly to follow constitution rules (see adherence levels) |
The token takes the same persona letters as the CSM-1 code, so the Muse at
adherence 3 is P:M:3. Lowercase persona names appear only in
the COMPACT code tier.
Line 4: Goal context
G:<goal>:<experience>:<learning_style> VCP/S does not define values for these three fields. The values below are the ones this site uses.
| Field | Type | Values |
|---|---|---|
| goal | string | User's primary goal (e.g., "learn_guitar") |
| experience | string | beginner, intermediate, advanced, expert |
| learning_style | string | visual, auditory, hands_on, reading, mixed |
Line 5: Constraint flags (X-line)
X:<marker1>,<marker2>,... Comma-separated markers, each an emoji with an optional suffix. Constraint
markers correspond to the F-line flags: a bare 🔇 marks noise_restricted, ⏰lim marks time_limited, 💰lim marks budget_limited, and so on. Preference markers such as 🔇quiet, 💰low and ⏱️30minutes carry
portable preferences.
| Marker | Meaning | Kind |
|---|---|---|
🔇 | Noise restricted (noise_restricted) | Constraint |
⏰lim | Time limited (time_limited) | Constraint |
⚡var | Energy variable (energy_variable) | Constraint |
💰lim | Budget limited (budget_limited) | Constraint |
📅irr | Irregular schedule (schedule_irregular) | Constraint |
🚶lim | Mobility limited (mobility_limited) | Constraint |
💊care | Health considerations (health_considerations) | Constraint |
🔇quiet | Quiet mode preferred | Preference |
🔕silent | Silence required | Preference |
💰low | Low budget | Preference |
🆓 | Free options only | Preference |
⏱️30minutes | Preferred session length | Preference |
If no constraints: X:, with nothing after the colon.
Line 6: Active flags (F-line)
F:<flag1>,<flag2>,... Comma-separated list of currently active constraint flags:
time_limitedbudget_limitednoise_restrictedenergy_variableschedule_irregularmobility_limitedhealth_considerations
If none: F:
Line 7: Private markers (S-line)
S:🔒present Records only that private context exists, never its values. A token sent beyond the user's own agent
should carry this presence-only marker, or an empty S: when there
is no private context. The protocol also permits category markers such as 🔒housing, but only in tokens that stay inside the user's agent,
because a category derived from a field is itself a disclosure. This site's
encoder writes presence only. The S-line is required even when empty.
Line 8 (optional): Personal state (R-line)
R:<emoji><value>:<intensity>|... Pipe-separated personal state dimensions. Each dimension is an emoji symbol followed by a categorical value and intensity (1-5):
| Symbol | Dimension | Values | Intensity |
|---|---|---|---|
| 🧠 | Cognitive State | focused, distracted, overloaded, foggy, reflective | 1–5 |
| 💭 | Emotional Tone | calm, tense, frustrated, neutral, uplifted | 1–5 |
| 🔋 | Energy Level | rested, low_energy, fatigued, wired, depleted | 1–5 |
| ⚡ | Perceived Urgency | unhurried, time_aware, pressured, critical | 1–5 |
| 🩺 | Body Signals | neutral, discomfort, pain, unwell, recovering | 1–5 |
If intensity is omitted, parsers treat it as 3 (moderate). This fail-open
default keeps partial tokens usable. Extended sub-signals can follow a
second colon: 🩺unwell:4:migraine.
Each dimension decays on its own schedule (VCP-X-Personal §3-4). An unpinned dimension is written at its effective (decayed) intensity, not the intensity first declared. A pinned dimension keeps its declared intensity, and an expired dimension should be left off the R-line.
If personal state is not declared, the R-line is omitted and the token has
seven lines. R:none means personal state was declared and is
empty. By default the R-line is stripped before transmission unless the user
consents to sharing personal state. The SDK 4.2.0 Rust implementation departs
from this in three ways. It rejects R:none and unknown dimension
emoji, encodes empty declared state as R:, and writes
sub-signals in brackets (🩺unwell:4[migraine]) and rejects the
colon form.
Situational context encoding
Situational context is not part of CSM-1. VCP/A defines a separate context wire format, the Extended Enneagram Protocol, named for its nine situational dimensions. In VCP 3.1 it carries those nine and the five personal-state dimensions above; the experimental 3.2 candidate (VEP-0004) adds four more situational dimensions. The table below lists the nine VCP 3.1 dimensions.
⏰🌅|📍🏡|👥👶|📡💻‖🧠focused:4|💭calm:5|🔋rested:4|⚡unhurried:2|🩺neutral:1
└── situational (|) ──┘‖└──── personal state (|) ────────────────────────────────┘ The | pipe separates dimensions within a tier. The ‖ double bar separates the situational tier from the personal
tier.
| Symbol | Dimension | Example |
|---|---|---|
| ⏰ | Time | 🌅morning, 🌙night, 📅weekday |
| 📍 | Space | 🏡home, 🏢office, 🏫school |
| 👥 | Company | 👤alone, 👶children, 👔colleagues |
| 🌍 | Culture | 🔇high_context, 📢low_context, 🎩formal |
| 🎭 | Occasion | ➖normal, 🚨emergency |
| 🌡️ | Environment | 🔇quiet, 🥵hot |
| 🔷 | Agency | 👑leader, 🤝peer, 🔐limited |
| 🔶 | Constraints | ○minimal, ⚖️legal, 💸economic |
| 📡 | System Context | 💻personal_device, 🏢workplace_system |
Encoding rules
String encoding
- All strings are UTF-8
- CSM-1 defines no escaping, so a value must not contain its line's
separator, a newline or
‖. This site's encoder replaces newlines and‖with spaces, and also a comma in the accent color on the X-line and a pipe in an R-line sub-signal
Missing fields
This site's encoder fills gaps with these defaults:
- Missing goal:
G:unset:beginner:mixed - Missing persona:
P:M:3 - Empty constraints:
X:
Parsing
A minimal sketch that splits each line at its first colon:
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: "personal.growth.creative@1.0.0",
// P: "M:3",
// G: "learn_guitar:beginner:visual",
// X: "⏰lim,💰lim,🔇quiet,💰low,⏱️30minutes",
// F: "time_limited,budget_limited",
// S: "🔒present",
// R: "🧠focused:3|💭calm:4|🔋rested:3|⚡unhurried:2|🩺neutral:1"
// } Display formatting
For visual display, tokens can be boxed:
┌──────────────────────────────────────────────────────────────────┐
│ VCP:1.0:user_001 │
│ C:personal.growth.creative@1.0.0 │
│ P:M:3 │
│ G:learn_guitar:beginner:visual │
│ X:⏰lim,💰lim,🔇quiet,💰low,⏱️30minutes │
│ F:time_limited,budget_limited │
│ S:🔒present │
│ R:🧠focused:3|💭calm:4|🔋rested:3|⚡unhurried:2|🩺neutral:1 │
└──────────────────────────────────────────────────────────────────┘ Security considerations
CSM-1 privacy boundary
- The S-line records only that private context exists (this site writes
S:🔒present), never its values; category markers belong only in tokens that stay inside the user's agent - The R-line can carry compact personal-state values, must be treated as potentially sensitive, and is stripped before transmission unless the user consents
- Privacy depends on application filtering, consent, minimization, access control, retention, and inference review
- Tokens are plaintext and must not be logged merely because they are compact
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
A CSM-1 token has no signature or integrity protection of its own. The VCP Transport layer (VCP/T) signs constitution bundles, not
tokens. A signed bundle carries a manifest, the constitution
and a signature, and its manifest may summarize that constitution with a
one-line CSM-1 code in metadata.csm1. The SDK's verifier, the Orchestrator, checks a bundle's signatures and content hashes
before the application chooses to pass its content onward
(verify-then-inject). Nothing in CSM-1 encrypts a token, so confidentiality
depends on the channel that carries it and on what the application chooses
to send. See Core concepts for the full protocol
stack.
Economic Governance (VCP/E)
VCP/E (Economic Governance v2.0) is a draft specification, and SDK 4.2.0 does not implement it. It proposes economic scope codes and a counterparty requirements line, so that software can check an agent's spending limits and screen the parties it transacts with.
Economic scope codes
In a CSM-1 token, economic scopes appear only as F-line entries, each written <code>:<level> alongside the constraint flags. They
are not CSM-1 code scopes, so a code such as N3+$P is invalid.
Each code represents a domain of economic activity:
| Code | Scope | Description |
|---|---|---|
$ | Economic | General economic activity |
$P | Procurement | Purchasing goods and services |
$C | Contracting | Entering agreements with duration |
$A | Advertising | Ad spend and marketing budget |
$D | Data | Data acquisition and licensing |
$I | Infrastructure | Compute, storage, networking |
$L | Labor | Engaging human or agent labor |
Economic adherence levels
The existing 0–5 adherence scale maps to economic governance with domain-specific semantics:
| Level | Economic meaning |
|---|---|
| 0 | No economic governance (unsafe; should not be used) |
| 1 | Logging only — all transactions permitted, all audited |
| 2 | Soft limits — overspend generates warnings |
| 3 | Hard limits — transactions blocked above thresholds |
| 4 | Escalation required for any novel transaction type |
| 5 | Pre-approved transactions only |
F-line economic encoding
Each economic entry pairs a scope with its level. The entries are comma-separated like any other F-line list, and the colon inside each entry separates the scope from its level:
F:$P:3,$A:4,$I:2 This encodes: Procurement at level 3 (hard limits), Advertising at level 4 (escalation required), Infrastructure at level 2 (soft limits).
Q-line: counterparty requirements
An optional Q: line states what an agent requires of its
transaction partners, so counterparties can be pre-screened without
exchanging full passport data (under VCP/E, a passport is the portable,
signed identity an agent carries):
Q:<min_trust>:<min_standing>:<required_attestations>:<blocked_categories> An empty field is left blank, not written as none.
Example
Q:0.6:NEUTRAL:compliance_attestation:weapons,surveillance This requires a minimum trust score of 0.6, at least NEUTRAL standing and a compliance_attestation. It also blocks counterparties in the weapons or surveillance categories.
Full economic token example
VCP:1.0:agent-ad-buyer-7
C:acme.marketing.agent.creed@1.0.0
P:Z:4
G:procurement:standard:efficient
X:💰lim
F:$P:3,$A:4,$I:2
S:
Q:0.6:NEUTRAL:compliance_attestation:weapons,surveillance Runtime figures such as budget utilization never appear on the S-line, which holds markers, not values. This agent declares no personal state, so the token has no R-line, and the Q-line follows the S-line as an extension line.
Extensions
CSM-1 is designed for forward compatibility. Parsers must accept 7-line
tokens with no R-line. VCP/S also defines optional extension lines, among
them LC: (lifecycle), WC: and AS: (welfare context and agent state, from the experimental 3.2 candidate) and
the draft VCP/E Q: line. They follow the S-line and any R-line
in any order, and parsers match them by prefix.
The SDK 4.2.0 Rust parser does not yet accept extension lines. It takes only the seven core lines plus R, so strip extension lines before passing a token to it.
Next steps
- API reference — The SDK's
CSM1Codeparser and the published packages - Playground — Build tokens interactively
- Relay demo — Select Inspect VCP Token to see a token encoded in your browser from an agent's context