# ccf-core
**Contextual Coherence Fields** — context-aware relational trust for embedded systems and autonomous agents.
[](https://crates.io/crates/ccf-core)
[](https://docs.rs/ccf-core)
[](LICENSE)
[](https://github.com/Hulupeep/ccf-core)
---
## The Problem
Most embedded behavioral systems treat trust and social state as a single global value.
One loud noise and the whole device goes into "scared" mode — regardless of whether the
device has spent 200 hours happily operating in that same noisy environment.
**The environment matters.** A robot that has learned to trust a busy kitchen should not
retreat just because the kitchen is noisy — but it absolutely should retreat if it encounters
an unfamiliar dark room for the first time.
---
## What ccf-core Gives You
A **field** of trust states — one per sensory context — that your device learns continuously
from experience. Trust earned in one environment stays in that environment. It doesn't
bleed into unfamiliar contexts until the device explicitly learns they are similar.
This gives your system:
- **Context-specific trust** — bright+quiet room and dark+loud room have independent trust histories
- **Earned resilience** — trust that has been built up through repeated interaction is protected against transient negative events
- **Four expressive behavioral phases** — `ShyObserver`, `StartledRetreat`, `QuietlyBeloved`, `ProtectiveGuardian` — each with distinct LED tint, motor scale, and narration depth outputs
- **Personality** — tune curiosity, startle sensitivity, and recovery rate per device
- **Emergent comfort-zone boundaries** — the device discovers which contexts belong together via graph min-cut; you don't configure it
- **`no_std` by default** — runs on Cortex-M, ESP32, RP2040, and any bare-metal target with no heap required
---
## Use Cases
### Social and Companion Robots
Your robot has met this family before. It knows Tuesday evenings are noisy and it's fine.
A stranger enters — new sensory context, zero trust, `ShyObserver` mode. It doesn't
over-react or under-react; it behaves consistently with its actual experience of *this* environment.
### Smart Home and Ambient Devices
A speaker learns that "kitchen at 7am" is high-activity, and responds with higher expressiveness.
"Living room at 11pm" is a different context entirely — quiet, familiar, settled. The same
trust architecture handles both without explicit programming.
### Industrial and Field Robotics
A robot arm in a calibration bay has built trust for that specific environment. Moved to
the production floor — different light, different noise, different vibration signature — it
starts cautious and builds trust from scratch. Safety-critical behavior falls out of the
architecture rather than being bolted on.
### Game AI and NPCs
Characters that remember their relational history with the player *in each location*.
The tavern NPC who trusts you in Stormwind has no reason to trust you in the dungeon.
Context-gated trust is the difference between a character that feels alive and one that
just reads a mood variable.
### Wearables and Health Devices
Activity context (running, sleeping, commuting) gates behavioral responses. An alert that
fires during your morning run pattern is different from the same alert firing in an
unfamiliar location. CCF gives you the context-sensitivity layer above your sensor stream.
---
## Quick Start
```toml
[dependencies]
ccf-core = "0.1"
```
### 1. Define your sensor vocabulary
Implement `SensorVocabulary` for whatever sensors your hardware has. The trait is the
only thing that needs to know about your specific hardware.
```rust
use ccf_core::vocabulary::SensorVocabulary;
// Two-sensor example: ambient light + presence detection
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct RoomSensors {
pub light: LightLevel,
pub presence: Presence,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum LightLevel { Dark, Dim, Bright }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Presence { Empty, Near, Far }
impl SensorVocabulary<2> for RoomSensors {
fn to_feature_vec(&self) -> [f32; 2] {
let l = match self.light {
LightLevel::Dark => 0.0,
LightLevel::Dim => 0.5,
LightLevel::Bright => 1.0,
};
let p = match self.presence {
Presence::Empty => 0.0,
Presence::Far => 0.5,
Presence::Near => 1.0,
};
[l, p]
}
}
```
That's the only hardware-specific code. Everything else is generic.
### 2. Create a coherence field
```rust
use ccf_core::vocabulary::ContextKey;
use ccf_core::accumulator::CoherenceField;
use ccf_core::phase::{Personality, PhaseSpace, SocialPhase};
let personality = Personality::new(); // mid-range defaults
let mut field: CoherenceField<RoomSensors, 2> = CoherenceField::new();
let ps = PhaseSpace::new();
let mut phase = SocialPhase::ShyObserver;
```
### 3. Run your main loop
```rust
let mut tick: u64 = 0;
loop {
// Read sensors and build context key
let sensors = RoomSensors { light: LightLevel::Bright, presence: Presence::Near };
let key = ContextKey::new(sensors);
// Record a positive interaction (person waved, task succeeded, user smiled, etc.)
field.positive_interaction(&key, &personality, tick);
// Optionally record a negative event (loud noise, obstacle, failed task)
// field.negative_interaction(&key, &personality, tick);
// Read the effective coherence for the current context
let coherence = field.effective_coherence(&key);
// Classify behavioral phase (tension comes from your homeostasis / task layer)
let tension: f32 = 0.2; // your system provides this
phase = SocialPhase::classify(coherence, tension, phase, &ps);
// Drive outputs from phase
let led = phase.led_tint(); // [r, g, b] — distinct per phase
let scale = phase.expression_scale(); // 0.0–1.0 — scale motors, audio, etc.
// Apply to hardware...
tick += 1;
}
```
### 4. The field remembers
After 50+ positive interactions in `Bright+Near`:
```
coherence in Bright+Near → 0.72 → QuietlyBeloved (expressive, relaxed)
coherence in Dark+Empty → 0.0 → ShyObserver (cautious, minimal)
```
Trust does not transfer between contexts. The device earned trust in one room and
starts fresh in another — exactly as you'd want.
---
## Built-in Sensor Vocabulary: `MbotSensors`
ccf-core ships `MbotSensors` — a ready-to-use 6-dimensional vocabulary covering the
dimensions most relevant to social robotics:
| `brightness` | `BrightnessBand` | Dark / Dim / Bright |
| `noise` | `NoiseBand` | Quiet / Moderate / Loud |
| `presence` | `PresenceSignature` | Absent / Far / Close |
| `motion` | `MotionContext` | Static / Slow / Fast |
| `orientation` | `Orientation` | Upright / Tilted |
| `time_period` | `TimePeriod` | Day / Evening / Night |
```rust
use ccf_core::vocabulary::{MbotSensors, MbotContextKey,
BrightnessBand, NoiseBand, PresenceSignature, MotionContext, Orientation, TimePeriod};
let key = MbotContextKey::new(MbotSensors {
brightness: BrightnessBand::Bright,
noise: NoiseBand::Quiet,
presence: PresenceSignature::Close,
motion: MotionContext::Static,
orientation: Orientation::Upright,
time_period: TimePeriod::Day,
});
```
---
## Behavioral Phases and Outputs
`SocialPhase` maps the 2D space (coherence × tension) to four quadrants,
using Schmitt trigger hysteresis to prevent oscillation at boundaries:
```
│ Low tension │ High tension
──────────────────┼─────────────────────┼──────────────────────
Low coherence │ ShyObserver │ StartledRetreat
High coherence │ QuietlyBeloved │ ProtectiveGuardian
```
Each phase produces distinct outputs:
| `ShyObserver` | Cool blue | 0.35 | Cautious, watching |
| `StartledRetreat` | Red | 0.10 | Withdraw, minimal output |
| `QuietlyBeloved` | Warm white | 1.00 | Full expressiveness |
| `ProtectiveGuardian` | Amber | 0.65 | Alert but grounded |
---
## Personality
Three bounded parameters tune how trust builds and erodes — without changing the
structural invariants of the architecture:
```rust
let personality = Personality {
curiosity_drive: 0.8, // explores new contexts eagerly; higher cold-start baseline
startle_sensitivity: 0.3, // resilient to aversive events; drops less on negative interactions
recovery_speed: 0.7, // rebuilds trust faster after disruption
};
```
---
## Comfort-Zone Boundary Discovery
`MinCutBoundary` runs Stoer-Wagner global min-cut on the trust-weighted context graph.
You don't configure a threshold — the boundary *emerges* from which contexts have
accumulated similar trust histories:
```rust
use ccf_core::boundary::MinCutBoundary;
let mut boundary: MinCutBoundary<RoomSensors, 2> = MinCutBoundary::new();
// As your field accumulates trust, report contexts to the boundary
boundary.report_context_with_key(&bright_near_key, coherence_bright_near);
boundary.report_context_with_key(&dark_empty_key, coherence_dark_empty);
// The partition tells you which side each context is on
let (inside, outside) = boundary.partition();
// inside: contexts the device has "adopted" (high trust cluster)
// outside: unfamiliar or distrusted contexts
// The min-cut value measures how sharp the comfort-zone edge is
let edge_sharpness = boundary.min_cut_value();
```
---
## Trust Mixing with SinkhornKnopp
`SinkhornKnopp` projects a matrix of trust similarities onto the Birkhoff polytope
(doubly stochastic matrices), ensuring no single context dominates trust allocation:
```rust
use ccf_core::sinkhorn::SinkhornKnopp;
let sk = SinkhornKnopp::default();
let mut trust_matrix = [
[1.0, 0.8, 0.1],
[0.8, 1.0, 0.2],
[0.1, 0.2, 1.0],
];
let result = sk.project(&mut trust_matrix);
// trust_matrix is now doubly stochastic — rows and columns each sum to 1.0
```
---
## Platform Support
ccf-core is `#![no_std]` with no heap allocation required in the default configuration.
It compiles for any target Rust supports:
| `x86_64-unknown-linux-gnu` | ✅ tested |
| `thumbv7em-none-eabihf` (Cortex-M4/M7) | ✅ tested |
| `thumbv6m-none-eabi` (Cortex-M0) | ✅ |
| `riscv32imc-unknown-none-elf` (ESP32-C3) | ✅ |
| `xtensa-esp32-none-elf` (ESP32) | ✅ |
| WASM | ✅ (with `std` feature) |
### Features
| `std` | off | Enables `CoherenceField::all_entries()` and persistence helpers |
| `serde` | off | Derives `Serialize` / `Deserialize` on all public types |
---
## Test Coverage
```
cargo test # 98 tests: 64 unit + 34 patent-claim integration tests
```
The integration test file `tests/patent_claims.rs` contains one named test per patent
claim — `test_claim_N_<description>` — each demonstrating the claimed behaviour
end-to-end through the public API only.
---
## Patent Claim Map
Patent pending: US Provisional Application 63/988,438 (priority date 23 Feb 2026).
| `SensorVocabulary` | 1, 8 | Platform-independent trait encoding sensory state as a normalised feature vector |
| `ContextKey<V>` | 1, 8 | Composite context identifier: deterministic FNV hash + cosine similarity |
| `CoherenceAccumulator` | 2–5 | Per-context trust counter with earned floor and asymmetric decay |
| `CoherenceField<V>` | 6–7, 13 | Context-keyed accumulator map with asymmetric min-gate blending |
| `MinCutBoundary<V>` | 9–12 | Stoer-Wagner global min-cut comfort-zone boundary |
| `SocialPhase` | 14–18 | Four-quadrant phase classifier with Schmitt trigger hysteresis |
| `SinkhornKnopp` | 19–23 | Birkhoff polytope projector: doubly stochastic trust mixing |
| `Personality` | 24–28 | Bounded modulators: curiosity, startle sensitivity, recovery rate |
| Full CCF pipeline | 29–34 | Composite system: sensor → context → accumulate → classify → output |
---
## License
Business Source License 1.1. Free for evaluation and non-production use.\
Change date: **23 February 2032** — converts to Apache License 2.0.\
Commercial production use requires a license from Flout Labs (cbyrne@floutlabs.com).