S05 — Experience Tokens
Tokens quantify completed work as acknowledgements, not assets. They are:
- Non-transferable — a token is bound to the actor that earned it
- Non-tradeable — no market, no exchange
- Append-only — creation is logged as an event; deletion is a constitutional violation (AX-01)
Tokens are the evidence layer; reputation (s04) is computed from tokens. Deleting a token would falsify reputation, which is why deletion is forbidden.
Token levels
| Level | Name | How earned | Persistence |
|---|---|---|---|
| L0 | Raw | Automatically on event completion | Ephemeral (session) |
| L1 | Episode | Complete interaction cycle (commit → deliver → confirm) | Persistent — drives reputation delta |
| L1.5 | Witness | Third-party attestation of work quality | Persistent — weight capped at 0.3 |
| L2a | Correlation | 5+ repetitions of the same pattern detected | Persistent |
| L2b | Proto-causal | Context-invariant or multi-path validated pattern | Persistent |
| L3 | Aggregate | Rule-engine-derived summary of multiple L2b tokens per domain | Derived (non-transferable across forks) |
Promotion flow
event completes
│
▼
┌─────┐ cycle confirmed ┌─────┐
│ L0 │ ────────────────────▶ │ L1 │
└─────┘ └─────┘
│ witness(es) attest
▼
┌──────┐
│ L1.5 │
└──────┘
│ 5+ same-pattern instances
▼
┌─────┐
│ L2a │ — transferable across scenarios
└─────┘
│ diversity + invariance checks
▼
┌─────┐
│ L2b │ — universal trait, context-free
└─────┘
│ κ aggregates per domain
▼
┌─────┐
│ L3 │ — epistemic / moral / systemic
└─────┘
L0 → L1
Interaction cycle must be complete: all phases of the GSD FSM (s15) executed, and the counterparty must confirm delivery. Partial or disputed cycles stay at L0 and expire at session end.
L1 → L1.5 (witness)
Requires a witness with reputation_at_witness ≥ 200. Single-witness weight ≤ 0.3; sum of all witness weights per episode ≤ 0.4 × MIN_EPISODES. Witnesses must be independent: no more than one witness per counterparty per week.
L1/L1.5 → L2a (correlation)
≥5 token instances that share the same normalized context pattern (see §pattern-matching). Tokens must span ≥3 distinct scenarios and ≥3 distinct counterparty classes (diversity check).
L2a → L2b (proto-causal)
The pattern survives context removal: simulated replay under the rule engine (κ) with the context fields nulled must produce the same outcome_class. If outcome changes when context is removed, the pattern is context-bound and cannot be promoted.
L2b → L3 (aggregate)
κ computes L3 claims per domain automatically; actors do not earn L3 directly. L3 is a view onto an actor’s L2b token set, not an independent record.
Token schema
{
"id": "tok_01HXYZ...",
"level": "L2a",
"context": {
"domain": "code_review",
"scenario": "bug_triage",
"counterparty": "agent_class:human_reviewer"
},
"action": "classified_bug_severity",
"outcome": {
"class": "correct",
"delta": 3
},
"witnesses": ["wit_01HAB...", "wit_01HAC..."],
"created_at": 1712880000,
"promoted_from": "tok_01HW1..."
}
promoted_from chains to the token(s) that satisfied the promotion rule, preserving the audit trail. witnesses: [] is valid for L1 (no witnesses required); L1.5 requires at least one.
Witness registry
mcp_witnesses(
witness_id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL,
reputation_at_witness INTEGER NOT NULL, -- frozen at witness time
weight_cap REAL NOT NULL -- ≤ 0.3
)
Witness admission rules:
- Reputation floor.
reputation_at_witness ≥ 200. Frozen at the moment the witness record is created; subsequent reputation changes do not retroactively qualify/disqualify past attestations. - Per-witness weight cap.
weight_cap ≤ 0.3. - Sum cap. For a given episode,
sum(witness_weights) ≤ 0.4 × MIN_EPISODES. - Independence. A counterparty class may contribute at most one witness per rolling 7-day window to the same target actor. This is to prevent cliques.
Violation of any witness rule downgrades the promotion result to L1 (no 1.5 bonus) rather than rejecting the base L1 token.
Pattern-matching algorithm
The promotion step L1/L1.5 → L2a requires matching ≥5 tokens to the “same pattern”. The algorithm:
- Normalize context. Canonicalize
domain,scenario, andcounterpartyto a shared vocabulary. Unknown values are bucketed to*(wildcard) rather than rejected. - Feature extract.
feature_hash = SHA-256(canonical_context || action_type || outcome_class) - Pattern match. All tokens sharing
feature_hashare candidates for a single pattern. - Diversity check (L2a gate). The candidate set must include ≥3 distinct
scenariovalues and ≥3 distinctcounterpartyclasses. Pure repetition of the same scenario with the same counterparty does not count. - Invariance check (L2b gate). Replay each token with
contextfields zeroed; the resultingoutcome_classmust equal the original. If any token’s outcome changes under context removal, the pattern is not invariant and stays at L2a.
The normalization step is deliberately tolerant — the system prefers false positives (promoting too readily) followed by downstream correction over false negatives (starving agents of L2 tokens).
L3 namespace
L3 aggregates are rule-engine-derived views over L2b tokens, scoped to three domains:
| Domain | What it measures | Example L2b inputs |
|---|---|---|
epistemic_mastery |
Domain knowledge that transfers across contexts | repeated correct classifications in code_review, risk_assessment |
moral_standing |
Fairness, restraint, willingness to decline | L2b tokens where action = declined_unsafe_request |
systemic_integrity |
Adherence to rules even when rules cost the actor | L2b tokens where outcome.class = rule_respected_at_cost |
L3 is non-transferable across forks (s07-fork-protocol): when the network forks, each fork’s L3 view is recomputed from that fork’s L2b set. An actor does not carry their L3 reputation across a hostile fork.
Weights per domain are derived by the rule engine (κ) from token density (tokens per epoch, decayed by s04-reputation rules). The exact weighting formula is in s11-rule-engine §aggregation.
Decay and scar supersession
- L0 — ephemeral. Expires at session end. Never decays (too short-lived to decay).
- L1 / L1.5 / L2a / L2b — do not decay. They are permanent records of what happened.
- L3 — recomputed continuously; responds to decay in its inputs but is not itself a decaying store.
Scars supersede. A scar (s04-reputation) is a separate, negative-polarity record attached to a domain. When an actor accumulates a scar in the same domain as an L2b claim, the L2b’s contribution to L3 is voided — not deleted. The L2b token itself remains (append-only), but its weight in the aggregate is clamped to zero until the scar expires or is arbitrated away (s09-arbitration).
This preserves the append-only axiom while honoring the reputational consequence of the scar.
Append-only vs garbage collection
There is an apparent tension between:
- AX-01 (append-only): tokens cannot be deleted.
- Storage pragmatism: keeping every L1 frame forever would exhaust disk.
The resolution:
- The event log is immutable. Every token creation is an event; those events are never GC’d.
- The derived token store (a performance cache of the most recent N frames per actor) may be pruned. Pruning is a local operation that does not alter the event log.
- After pruning, the derived token state is reconstructible: replay the event log for the affected actor and the token store returns to byte-identity.
Therefore GC is a derived-state optimization, not a constitutional violation. Specs and audits read the event log, not the cache.
Phase 0 posture
The mcp_tokens table exists as a schema stub in the Phase 0 database design (src/db/schema.sql, target P0.2.2). No Phase 0 tool writes to it. Token creation begins R101+ (Phase 2, δ intelligence bring-up). Until then, the table is empty and every query returns [].
Cross-references
s04-reputation— how reputation is computed from tokens (and how scars void L3)s11-rule-engine— aggregation formula for L3s15-gsd-contract— the interaction cycle that produces L1s18-identity— how L3 feeds the soul vectordocs/3-world/social/reputation.md— narrative counterpartdocs/3-world/social/identity.md§semantic-translation — how L2b patterns become traits
Implementation Status
Verified against source: 2026-04-16
| Claim | Status | Notes |
|---|---|---|
| Token levels L0 / L1 / L1.5 / L2a / L2b / L3 | Spec-only | mcp_memory_frame in heritage AMS code uses L0/L1/L2 for memory-source classification, not experience tokens. No experience-token domain exists. |
| Promotion rules (L0→L1→L1.5→L2a→L2b→L3) | Spec-only | No promotion logic in source. |
| Witness registry schema | Spec-only | No mcp_witnesses table. |
| Pattern-matching (feature-hash, diversity, invariance) | Spec-only | No canonicalization or replay logic. |
| L3 namespace (epistemic / moral / systemic) | Spec-only | No aggregate view. |
| Non-transferability / non-tradeability | Spec-only | No transferability constraints in source. |
| Append-only token log + derived-state GC | Partial | Heritage mcp_memory_frame uses chain-hashing; a pruning tool exists but no separation between event log and derived cache. |
Summary: S05 is a pure protocol specification. Writes begin R101+ (Phase 2).