ccf-core/ccf-agent v1.0.1: hard min-gate coupling, QAC trust updates, and runtime certificates. Gate C exercised the computed runtime on Seed-class ARM hardware with driver-fed input. Unless a post cites a specific run, do not read it as proof of live sensors, mBot2 behaviour, Cognitum store validation, or production deployment.Editor's note — June 2026 (post-Provisional 6 correction). An earlier version of this post framed the Sinkhorn–Knopp / doubly-stochastic projection as the mechanism that proves or enforces trust. That framing is superseded. The doubly-stochastic projection is conservative normalization — a gauge/presentation step, not the causal trust-transfer law. The causal update is the hard minimum gate followed by a quotient-affine contraction (QAC), audited per step by a residual certificate. CCF does not claim unconditional convergence from min-gating, and any numeric tolerance is a per-platform calibrated floor (there is no universal
1e-9). See The Normalization Is Not the Trust and Trust You Can Falsify.
The mathematics behind the shy robot
CCF — the Context Coherence Field — is a framework for emergent social behaviour in autonomous systems. This post is the technical companion to our announcement. If you just want to run the code, see Get started.
Why not machine learning?
Training a social model requires labelled data: thousands of examples of "this interaction was warm" and "this interaction was cold". That data doesn't exist for most deployments, and collecting it raises consent questions we'd rather avoid.
CCF is a prior-free approach. It derives social state from raw sensor readings and accumulates evidence over time without supervision.
Primitive 1: Context-keyed accumulators
A context key is a 32-bit FNV-1a hash of a normalised sensor feature vector. If your robot has 6 sensors (presence, light, sound, touch, attention, time-of-day), the feature vector is a 6-float array in [0, 1]^6. The hash maps this to a discrete context identity.
// ccf-core public API
let key = ContextKey::<MbotSensors, 8>::new(sensors);
let hash = key.context_hash_u32(); // deterministic across restarts
Each context key has an associated CoherenceAccumulator holding two values:
- α_s (short-run EMA): fast-decaying, tracks instantaneous stimulus
- α_l (long-run EMA): slow-decaying, tracks accumulated history
α_s(t) = λ_s · event(t) + (1 - λ_s) · α_s(t-1)
α_l(t) = λ_l · event(t) + (1 - λ_l) · α_l(t-1)
event(t) is 1 on a positive interaction tick, 0 otherwise. λ_s >> λ_l.
Primitive 2: The minimum gate
The gate maps (α_s, α_l) to a SocialPhase. The key insight is the AND condition:
gate_open = α_s > θ_instant ∧ α_l > θ_context
Neither condition alone is sufficient. This is why the robot can't be socially engineered by a burst of positive stimulus: α_l simply hasn't had time to accumulate.
The Personality struct modulates the thresholds:
pub struct Personality {
pub warmth: f32, // scales θ_context down (easier to trust)
pub reactivity: f32, // scales λ_s up (faster instantaneous response)
pub caution: f32, // scales θ_instant up (harder to open the gate)
}
All fields are bounded to [0, 1] and validated on construction. The gate logic itself is independent of personality — personality only shifts thresholds.
Primitive 3: Graph min-cut
CCF maintains a weighted undirected graph G = (V, E) where:
- Each vertex v_i is a context key that has ever been active
- Edge weight w(v_i, v_j) = cosine_similarity(feature_vec_i, feature_vec_j)
The Stoer–Wagner algorithm finds the global minimum cut (S, T) of G in O(|V|^3) time. This partition separates the context space into two groups: contexts that are structurally similar go on the same side of the cut.
let result = field.partition();
// result.min_cut_value: f32 — weight of the weakest partition boundary
// result.partition_s: &[ContextKey] — one side of the cut
Cross-partition trust influence is proportional to min_cut_value. A high cut weight
means the two context groups are similar, and trust flows more freely between them.
A low cut weight means they're distinct, and influence is bounded tightly.
Normalization gauge: Sinkhorn–Knopp
After cross-partition mixing, the coherence matrix is renormalised so that rows and columns sum to 1 (doubly-stochastic). The Sinkhorn–Knopp algorithm iteratively normalises rows and columns until convergence:
A* = lim_{k→∞} D_r^(k) · A · D_c^(k)
This is a conservative normalization — a gauge/presentation step. It keeps the presented "social budget" conserved across contexts so the totals can't be inflated or concentrated. It does not by itself decide or enforce trust: the causal update is the minimum gate (Primitive 2) followed by a quotient-affine contraction. The normalization keeps the books honest; the gate and contraction do the enforcement.
The result
Four social phases emerge from the gate:
| Phase | α_s | α_l | Behaviour | |-------|-----|-----|-----------| | ShyObserver | low | low | Default. Reserved, minimal expression. | | StartledRetreat | high | low | Novel stimulus, no baseline. Cautious. | | QuietlyBeloved | low | high | Familiar context. Warm, unhurried. | | ProtectiveGuardian | high | high | Both high. Active, engaged, protective. |
No phase is programmed. Each emerges from accumulated evidence through the gate.
Full implementation: github.com/Hulupeep/CCF API docs: docs.rs/ccf-core Patent: US 63/988,438 · Patent Pending