CC Window Aligner: Implementation Guide
| Decision Type | Required Signals | Authority | |---------------|------------------|-----------| | **Type/Schema changes** | Charter + Invariants + Downstream impact | Lock requires review | | **Algorithm changes** | Invariants preserved + Tests pass | Implementation owner | | **Configuration defaults** | Performance + Safety tradeoff | Implementation owner | | **New device support** | DIR-003 compatibility + No breaking changes | Requires integration test |
Full Public Reader
CC Window Aligner: Implementation Guide
Version: 0.1.0
Status: DRAFT
Last Updated: 2025-12-27
---
1. Implementation Rules
1.1 How Decisions Are Made
| Decision Type | Required Signals | Authority |
|---|---|---|
| Type/Schema changes | Charter + Invariants + Downstream impact | Lock requires review |
| Algorithm changes | Invariants preserved + Tests pass | Implementation owner |
| Configuration defaults | Performance + Safety tradeoff | Implementation owner |
| New device support | DIR-003 compatibility + No breaking changes | Requires integration test |
1.2 How Conflicts Are Resolved
| Conflict Type | Resolution |
|---|---|
| Invariants vs. Performance | Invariants always win. Find alternative optimization. |
| Strict vs. Low-Latency | Mode selection by caller. Both must work. |
| Simplicity vs. Completeness | Completeness for invariant-related code. Simplicity elsewhere. |
| Determinism vs. Floating-point efficiency | Determinism wins. Use reproducible operations. |
1.3 What Constitutes "Done"
A component is "done" when:
1. Implementation matches specification in this guide
2. All relevant invariants are enforced (see INVARIANTS.md)
3. Unit tests cover happy path + edge cases + failure modes
4. Integration test with at least one downstream consumer passes
5. Documentation is complete (inline + docs/)
6. No TODOs remain in implementation
1.4 What Constitutes "Blocked"
A component is "blocked" when:
1. Required upstream dependency does not exist
2. Invariant cannot be satisfied with current design
3. Clarification needed from charter (ambiguous requirement)
4. Performance target cannot be met
Blocked items must be logged in CHECKLIST.md with reason.
---
2. Decomposition Rules
2.1 Module Hierarchy
cc-window-aligner/
├── src/
│ ├── lib.rs # Public API: WindowAligner, re-exports
│ ├── types.rs # MotionWindow, SkeletonFrame, DeviceMask, Provenance
│ ├── config.rs # WindowConfig, AlignerMode, InterpolationPolicy
│ ├── error.rs # AlignerError enum
│ ├── stages/
│ │ ├── mod.rs # Stage trait, StageResult
│ │ ├── time_normalize.rs # Stage 1: TimeNormalizer
│ │ ├── resample.rs # Stage 2: Resampler
│ │ ├── coordinate.rs # Stage 3: CoordinateUnifier
│ │ ├── fusion.rs # Stage 4: DeviceFuser
│ │ └── windowing.rs # Stage 5: Windower
│ ├── validation/
│ │ ├── mod.rs # ValidationResult, Validator trait
│ │ ├── invariants.rs # Invariant checks (INV-001 through INV-010)
│ │ └── discontinuity.rs # Discontinuity detection
│ ├── clock/
│ │ ├── mod.rs # ClockMapping, ClockEstimator
│ │ └── sync.rs # Multi-device clock synchronization
│ ├── interpolation/
│ │ ├── mod.rs # Interpolator trait
│ │ ├── linear.rs # Linear interpolation
│ │ ├── slerp.rs # Spherical linear interpolation (quaternions)
│ │ └── hold.rs # Sample-and-hold
│ ├── skeleton/
│ │ ├── mod.rs # Skeleton definition, BoneIndex
│ │ ├── mocopi.rs # Mocopi-specific mapping
│ │ └── transform.rs # Coordinate transformations
│ ├── audit/
│ │ ├── mod.rs # CausalityTrace, AuditLog
│ │ └── trace.rs # Trace recording and querying
│ └── buffer/
│ ├── mod.rs # ReorderBuffer, WatermarkTracker
│ └── ring.rs # Ring buffer for streaming
├── docs/
│ ├── PROJECT_CHARTER.md
│ ├── GLOSSARY.md
│ ├── INVARIANTS.md
│ ├── IMPLEMENTATION_GUIDE.md
│ └── CHECKLIST.md
├── tests/
│ ├── determinism.rs # INV-001 tests
│ ├── integration.rs # End-to-end tests
│ └── stages/ # Per-stage tests
├── benches/
│ └── pipeline.rs # Latency benchmarks
└── Cargo.toml2.2 Maximum Scope Per Task
Each implementation task (checklist item) must:
- Touch at most ONE stage or ONE module
- Produce at most ONE new public type
- Be completable in one session
- Have clear validation criteria
2.3 Required Depth Before Implementation
Before implementing a component:
1. List all invariants it must enforce
2. List all assumptions it relies on
3. Define input/output types
4. Define error cases
5. Write test cases (may be stubs)
---
3. Validation Rules
3.1 What Must Be Validated At Each Stage
| Stage | Validation |
|---|---|
| Stage 1: Time Normalize | Clock mapping residuals < threshold. No negative time deltas. |
| Stage 2: Resample | Output at exact canonical FPS. Interpolation flags set correctly. |
| Stage 3: Coordinate | All frames in BodyFrame. Quaternion norms ≈ 1. Bone indices valid. |
| Stage 4: Fusion | Provenance complete. No conflicting values without resolution. |
| Stage 5: Windowing | Exact frame count. Monotonic timestamps. Coverage computed. |
3.2 What Cannot Move Forward Without Validation
| Gate | Requirement |
|---|---|
| Before Stage 2 | Clock mappings established for all active streams |
| Before Stage 4 | All streams in common coordinate frame |
| Before Emission | All 10 invariants checked (INV-001 through INV-010) |
| Before Release | Integration tests with cc-anticipation pass |
3.3 How Validation Is Documented
Each validation produces a `ValidationResult`:
pub struct ValidationResult {
pub passed: bool,
pub invariant_id: Option<String>, // e.g., "INV-002"
pub message: String,
pub timestamp: f64,
pub details: HashMap<String, String>,
}Failed validations are logged and, for critical invariants, cause emission to fail.
---
4. Pipeline Specification
4.1 Stage 1: Time Normalization
Input: `Vec<RawPacket>` with device-local timestamps
Output: `Vec<NormalizedPacket>` with canonical timestamps
Algorithm:
1. For each device stream, estimate `ClockMapping`:
- Initial: offset from first packet arrival
- Ongoing: Kalman filter on (arrival_time, device_time) pairs
2. Apply mapping: `t_canonical = mapping.to_canonical(t_device)`
3. Emit packets tagged with canonical time
Invariants enforced: INV-009 (no future data)
4.2 Stage 2: Resampling
Input: `Vec<NormalizedPacket>` per stream
Output: `Vec<ResampledFrame>` at canonical FPS
Algorithm:
1. Define canonical frame times: `t[i] = t_start + i / fps`
2. For each frame time, query each stream:
- Find bracketing samples (before, after)
- Apply interpolation policy:
- Positions: linear
- Quaternions: slerp
- Discrete: hold
- If gap > threshold, mark as interpolated
3. Emit frame with provenance
Invariants enforced: INV-003 (explicit missingness), INV-004 (temporal monotonicity)
Interpolation policies (FROZEN):
| Signal Type | Policy | Version |
|---|---|---|
| Position (XYZ) | Linear | v1 |
| Velocity (XYZ) | Linear | v1 |
| Quaternion | Slerp | v1 |
| Angular velocity | Linear | v1 |
| Discrete events | Hold | v1 |
| Scalar (HR, etc.) | Linear | v1 |
4.3 Stage 3: Coordinate Unification
Input: `Vec<ResampledFrame>` per stream in device coordinates
Output: `Vec<UnifiedFrame>` in BodyFrame coordinates
Algorithm:
1. For each stream, apply device-to-body transformation:
- Mocopi: identity (already in body frame after calibration)
- Phone: mounting offset + orientation adjustment
- Watch: mounting offset
- AirPods: mounting offset + head-body relationship
2. For quaternions:
- Ensure consistent hemisphere (dot with reference > 0)
- Normalize to unit length
3. Validate bone hierarchy for mocopi stream
Invariants enforced: INV-005 (coordinate consistency)
4.4 Stage 4: Fusion
Input: `Vec<UnifiedFrame>` per stream, all in BodyFrame
Output: `Vec<FusedFrame>` (one per canonical timestamp)
Algorithm:
1. For each degree of freedom, determine authority:
- Primary: highest-trust device with valid data
- Fallback: next-trust device if primary missing
2. Combine contributions:
- Single source: use directly
- Multiple sources: weighted average or trust-based selection
3. Populate provenance:
- Which device contributed each DOF
- Interpolation flags inherited from sources
4. Compute per-frame uncertainty
Authority table (configurable, default):
| DOF | Primary | Fallback 1 | Fallback 2 |
|---|---|---|---|
| Full-body pose | Mocopi | — | — |
| Hip translation energy | Phone | Mocopi | — |
| Head yaw/pitch | AirPods | Mocopi | — |
| Wrist cadence | Watch | Mocopi | — |
| Heart rate | Watch | — | — |
Invariants enforced: INV-008 (provenance completeness)
4.5 Stage 5: Windowing
Input: `Stream<FusedFrame>`
Output: `Stream<MotionWindow>`
Algorithm:
1. Maintain frame buffer of size `window_size + hop_size`
2. When buffer has enough frames:
- Extract window: frames[0..window_size]
- Compute metadata:
- `t_start`, `t_end` from frame timestamps
- `coverage` = count(non-interpolated) / total
- `device_mask` = OR of all frame device masks
- `window_id` = hash(session_id, t_start, config_version)
- `checksum` = hash(frames + metadata)
- Validate all invariants
- Emit window
- Advance buffer by hop_size
3. Handle end-of-stream:
- In strict mode: wait for watermark
- In low-latency mode: emit partial if coverage >= threshold
Invariants enforced: INV-001 (determinism), INV-002 (boundedness), INV-006 (schema version), INV-007 (checksum), INV-010 (window ID determinism)
---
5. Type Contracts
5.1 MotionWindow (FROZEN after lock)
pub struct MotionWindow {
// Core data
pub frames: Vec<SkeletonFrame>, // Exactly config.frames_per_window
pub latent_frames: Option<Vec<LatentFrame>>, // From LIM-RPS if available
// Temporal bounds
pub t_start: f64, // Canonical time (seconds since epoch)
pub t_end: f64, // t_start + (frames_per_window - 1) / fps
pub fps: f32, // Canonical FPS (e.g., 50.0)
// Coverage & quality
pub coverage: f32, // [0, 1] fraction of non-interpolated
pub device_mask: DeviceMask, // Which devices contributed
pub dropped_frames: Vec<usize>, // Indices of fully-interpolated frames
// Provenance
pub session_id: String, // Session identifier
pub window_id: String, // Deterministic hash
pub aligner_version: String, // e.g., "0.1.0"
pub schema_version: String, // e.g., "0.1.0"
pub config_hash: u64, // Hash of config used
// Integrity
pub checksum: u64, // xxhash of frames + metadata
}5.2 SkeletonFrame (FROZEN after lock)
pub struct SkeletonFrame {
pub timestamp: f64, // Canonical time
pub bones: [BoneState; 27], // 27-bone skeleton
pub root_position: [f32; 3], // Pelvis position in body frame
pub provenance: FrameProvenance, // Per-DOF source tracking
}
pub struct BoneState {
pub rotation: [f32; 4], // Unit quaternion (w, x, y, z)
pub local_position: Option<[f32; 3]>,// For bones with translation
}
pub struct FrameProvenance {
pub device_mask: DeviceMask, // Devices contributing to this frame
pub interpolated: bool, // True if any DOF interpolated
pub per_bone_source: [DeviceMask; 27], // Per-bone source
pub uncertainty: f32, // [0, 1] aggregate uncertainty
}5.3 DeviceMask
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct DeviceMask(u8);
impl DeviceMask {
pub const NONE: Self = Self(0x00);
pub const MOCOPI: Self = Self(0x01);
pub const PHONE: Self = Self(0x02);
pub const WATCH: Self = Self(0x04);
pub const AIRPODS: Self = Self(0x08);
pub const DEPTH_CAMERA: Self = Self(0x10);
pub fn contains(&self, other: Self) -> bool;
pub fn union(&self, other: Self) -> Self;
}5.4 WindowConfig
pub struct WindowConfig {
// Core parameters
pub canonical_fps: f32, // e.g., 50.0
pub frames_per_window: usize, // e.g., 50 (1 second)
pub hop_size: usize, // e.g., 25 (50% overlap)
pub min_coverage: f32, // e.g., 0.9
// Mode
pub mode: AlignerMode, // Strict or LowLatency
// Clock sync
pub reorder_buffer_ms: f64, // e.g., 200.0
pub clock_drift_threshold: f64, // e.g., 0.001 (ms/ms)
// Interpolation
pub max_interpolation_gap_ms: f64, // e.g., 100.0
pub interpolation_policy_version: String, // e.g., "v1"
// Validation
pub discontinuity_threshold_deg: f32,// e.g., 45.0
pub max_velocity_deg_s: f32, // e.g., 720.0
// Versioning
pub schema_version: String, // e.g., "0.1.0"
}
pub enum AlignerMode {
Strict, // Determinism > latency
LowLatency, // Responsiveness > determinism
}---
6. Error Handling
#[derive(Debug, thiserror::Error)]
pub enum AlignerError {
#[error("Invariant violated: {invariant_id} - {message}")]
InvariantViolation {
invariant_id: String,
message: String,
},
#[error("Clock synchronization failed for device {device}: {reason}")]
ClockSyncFailed {
device: String,
reason: String,
},
#[error("Insufficient coverage: {actual} < {required}")]
InsufficientCoverage {
actual: f32,
required: f32,
},
#[error("Invalid configuration: {field} - {reason}")]
InvalidConfig {
field: String,
reason: String,
},
#[error("Discontinuity detected at t={timestamp}: {description}")]
Discontinuity {
timestamp: f64,
description: String,
},
#[error("Schema version mismatch: expected {expected}, got {actual}")]
SchemaVersionMismatch {
expected: String,
actual: String,
},
}---
7. Public API
pub struct WindowAligner {
config: WindowConfig,
// ... internal state
}
impl WindowAligner {
/// Create a new aligner with the given configuration
pub fn new(config: WindowConfig) -> Result<Self, AlignerError>;
/// Process a raw packet from a device
pub fn ingest(&mut self, packet: RawPacket) -> Result<(), AlignerError>;
/// Poll for ready windows (non-blocking)
pub fn poll(&mut self) -> Option<MotionWindow>;
/// Flush remaining data (end of stream)
pub fn flush(&mut self) -> Vec<MotionWindow>;
/// Get current watermark (canonical time)
pub fn watermark(&self) -> f64;
/// Get aligner statistics
pub fn stats(&self) -> AlignerStats;
/// Enable causality tracing
pub fn enable_tracing(&mut self, sink: Box<dyn TraceSink>);
}---
Document ID: CC-WA-IMPL-GUIDE-001
Previous Document: INVARIANTS.md
Next Document: CHECKLIST.md
Promotion Decision
Attach run IDs, datasets, metrics, and reproduction commands.
Source Anchor
Comp-Core/core/motion/cc-window-aligner/docs/IMPLEMENTATION_GUIDE.md
Detected Structure
Method · Evaluation · Code Anchors · Architecture