README: Cohort
Purpose
This document defines the KNAT application profile for a Cohort — a named, stable group of entities whose membership is determined by evaluating a composable Rule against entity traits.
The goal of this profile is to allow KNAT clients to:
- read the current census membership for a named cohort
- monitor evaluation timing and staleness of the census
- subscribe to membership changes across the cohort evaluation interval
- join cohort membership to other surfaces (biologic, jook, stele, game)
This profile intentionally does not model:
- per-frame entity physics or chem state (those are biologic/participant surfaces)
- the rule definition itself (that is the cohort spec document)
- governance or consent scoping (those are handled by the fiction/rule surface)
Conceptual Model
A cohort is a dynamic group defined once in a spec document and evaluated on a schedule by the collation coordinator. The coordinator holds a CohortRegistry and re-evaluates each cohort's rule against current EntityTraits every N frames (or on an adaptive schedule).
Cohort Spec (cohort/v1/spec)
defines: name, rule, description
Collation Coordinator
holds: CohortRegistry
evaluates: rule against EntityTraits
publishes: CohortEvaluationComplete event
Cohort Census (cohort/v1/runtime)
exposes: members, evaluated_at_frame, staleness
The membership list is stable between evaluations. Consumers that need frame-accurate membership should track is_stale and staleness_frames.
Trait Paths: Rules reference entity traits using dot-separated paths (e.g. role.executor, jook.market-square-beat.in_field). Traits are injected into the entity's EntityTraits map by world items (jooks inject proximity traits; executors inject role traits; etc.) before cohort evaluation.
Root Graph
A cohort KNAT surface is rooted at:
/cohort::<cohort_name>/
Top-level families:
/cohort::<cohort_name>/
/census
/frame
The view field on the snapshot indicates whether the surface is complete (full) or policy-shaped (projected). Consumers must not assume completeness when view is projected.
Census Surface
The evaluated membership for this cohort. Updated on the collation coordinator's evaluation schedule, not per-frame.
/cohort::<cohort_name>/census/members
/cohort::<cohort_name>/census/member_count
/cohort::<cohort_name>/census/evaluated_at_frame
/cohort::<cohort_name>/census/staleness_frames
/cohort::<cohort_name>/census/is_stale
/cohort::<cohort_name>/census/aggregates
| node | type | capabilities |
|---|---|---|
members |
Array | read |
member_count |
Integer | read |
evaluated_at_frame |
Integer | read |
staleness_frames |
Integer | read |
is_stale |
Boolean | read |
aggregates |
Object | read |
members is an array of stable string identifiers (participant ids, entity ids). The array is replaced in full on each evaluation; there is no patch/diff format at this surface.
is_stale is true when staleness_frames exceeds the coordinator's configured evaluation interval for this cohort. Consumers polling a stale census should not take high-confidence actions based on membership.
aggregates is optional and contains computed statistics over the current membership (e.g. avg_dissonance, total_dust). Aggregates are only present when the coordinator is configured to compute them for this cohort.
Frame Surface
/cohort::<cohort_name>/frame
| node | type | capabilities |
|---|---|---|
frame |
Integer | read |
Simulation frame number at snapshot time.
Staleness Semantics
Cohort evaluation is not per-frame. The coordinator evaluates each cohort on one of two schedules:
- Fixed interval: every N frames (
CohortSchedule::every_n_frames(n)) - Adaptive: every N frames unless the entity set has changed significantly, in which case re-evaluate sooner (
CohortSchedule::adaptive(interval, delta_threshold))
When is_stale is true:
membersreflects the state fromevaluated_at_frame, not the current frame- membership changes since
evaluated_at_frameare not yet reflected staleness_framesindicates how out-of-date the census is
Consumers that need membership guarantees should either:
- Wait for the next
CohortEvaluationCompleteevent before acting, or - Track
is_staleand degrade gracefully when census data is approximate
Cross-Domain Joins
| From | Via | To |
|---|---|---|
census/members[] |
biologic surface | participant location, chem state, role |
cohort name (as cohort_id) |
jook surface | jook census — same membership, with perception_strength |
cohort name (as cohort_id) |
stele surface | stele participants |
cohort spec name |
cohort/v1/spec | rule definition, description |
Snapshot Format
A full cohort runtime snapshot matches the shape defined in cohort/v1/runtime.json. Key points:
census.membersis the complete membership array at last evaluation timecensus.is_staleindicates whether the evaluation interval has been exceededaggregatesis optional and may be absent if not configured- The snapshot does not include the rule definition — read
cohort/v1/specfor that