CSM-1 specification

Reference for CSM-1 (Constitutional Safety Minicode) codes and the CSM-1 v1.1 token; the normative text is VCP/S §2 in VCP-Spec.

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
Version note: The VCP protocol is at v3.1, the current source baseline. The CSM-1 format is at v1.1. The token header reads 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

LetterPersonaFocusDefault adherence
NNannyChild safety and family-appropriate content5
ZSentinelSecurity, privacy and operational safety4
GGodparentEthical guidance and moral reasoning4
AAmbassadorProfessional conduct and diplomatic communication3
MMuseCreativity and artistic expression2
DMediatorFair resolution and balanced mediation3
CCustomA user-defined constitution; requires :NAMESPACE3

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

CodeScopeContext
FFamilyFamily-appropriate, child-safe
WWorkProfessional workplace
PPrivacyData protection
EEducationEducational context
TTechnicalDeveloper or technical context
OOfficialGovernmental, policy-compliant
VVulnerableVulnerable populations
AAdultAdult-only; mature content allowed
HHealthHealthcare and medical
SSocialSocial media and community
RReligiousReligious 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

TierExampleAddsUsed for
NANON5+E+FPersona, adherence and scopesHTTP headers and wire protocols
MICRON5+E+F:ELEM@1.2.0An optional namespace and versionAPI parameters and config files
COMPACTCS1|nanny|5|family.safe.guide|E,FThe lowercase persona name and a UVC tokenHuman 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>
FieldTypeDescription
versionstringToken header version, currently "1.0" (not the VCP protocol release and not the CSM-1 format version; parsers accept any non-empty value)
profile_idstringUnique user/profile identifier

Line 2: Constitution reference

C:<constitution_id>@<version>
FieldTypeDescription
constitution_idstringConstitution identifier, a UVC token (the VCP/I identity token), e.g., "personal.growth.creative"
versionstringConstitution version (e.g., "1.0.0")

Line 3: Persona

P:<persona>:<adherence>
FieldTypeValues
personaletterOne uppercase letter: N (Nanny), Z (Sentinel), G (Godparent), A (Ambassador), M (Muse), D (Mediator), C (Custom)
adherence0-5How 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.

FieldTypeValues
goalstringUser's primary goal (e.g., "learn_guitar")
experiencestringbeginner, intermediate, advanced, expert
learning_stylestringvisual, 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.

MarkerMeaningKind
🔇Noise restricted (noise_restricted)Constraint
⏰limTime limited (time_limited)Constraint
⚡varEnergy variable (energy_variable)Constraint
💰limBudget limited (budget_limited)Constraint
📅irrIrregular schedule (schedule_irregular)Constraint
🚶limMobility limited (mobility_limited)Constraint
💊careHealth considerations (health_considerations)Constraint
🔇quietQuiet mode preferredPreference
🔕silentSilence requiredPreference
💰lowLow budgetPreference
🆓Free options onlyPreference
⏱️30minutesPreferred session lengthPreference

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_limited
  • budget_limited
  • noise_restricted
  • energy_variable
  • schedule_irregular
  • mobility_limited
  • health_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):

SymbolDimensionValuesIntensity
🧠Cognitive Statefocused, distracted, overloaded, foggy, reflective1–5
💭Emotional Tonecalm, tense, frustrated, neutral, uplifted1–5
🔋Energy Levelrested, low_energy, fatigued, wired, depleted1–5
⚡Perceived Urgencyunhurried, time_aware, pressured, critical1–5
🩺Body Signalsneutral, discomfort, pain, unwell, recovering1–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.

SymbolDimensionExample
⏰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:

CodeScopeDescription
$EconomicGeneral economic activity
$PProcurementPurchasing goods and services
$CContractingEntering agreements with duration
$AAdvertisingAd spend and marketing budget
$DDataData acquisition and licensing
$IInfrastructureCompute, storage, networking
$LLaborEngaging human or agent labor

Economic adherence levels

The existing 0–5 adherence scale maps to economic governance with domain-specific semantics:

LevelEconomic meaning
0No economic governance (unsafe; should not be used)
1Logging only — all transactions permitted, all audited
2Soft limits — overspend generates warnings
3Hard limits — transactions blocked above thresholds
4Escalation required for any novel transaction type
5Pre-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 CSM1Code parser 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