Disciplines · Proposals

Oya Build Checklist — End-to-End Software Task Breakdown

workspace, no root workspace (matches libs/maya/engine-core).

12sections108 minread

On this page

Source of truth for scope: docs/proposals/OYA_RUST_REWRITE_AND_COMPANION_PLAN.md (Part I = Rust rewrite + companion product; Part II = home-robotics hive). This file decomposes that plan into granular, actionable software tasks.

Status (corrected 2026-09-18): about half of the boxes are checked — 21 crates under libs/oya/engine/crates and 15 services under apps/oya exist. (This line said "every box is [ ] — nothing here is built yet" until then; that was the initial state.) ./eve next oya-build lists what is open. The checkbox is the sole source of truth (per repo CLAUDE.md); do not infer completion from prose. Process tasks one at a time: read the code, verify domain-correct implementation (no stubs), run the specific tests, then mark [x]. Never batch-mark.

Scope: all software in this repo — Rust crates, TS libs/services, sim, CI, contracts, infra wiring. Out of scope: physical fabrication of airframes, arms, perch/charging electronics, and dock mechanisms (a parallel hardware workstream). Firmware-facing protocols, SITL/HITL sim, and edge runtimes are in scope.

Phase tags (A)(I) map to the unified roadmap (plan §14). Conventions per crate/service: every Rust crate ships Cargo.toml, comprehensive types, domain-correctness tests, clippy -D warnings, and a napi/wasm bridge where a TS tier needs it; every TS lib/service ships project.json + package.json + tsconfig.json, path mapping in tsconfig.base.json, Vitest tests, and an nx:run-commands build (matching lilith/yemaya).


0. Program-level foundations#

0.1 Repo & tooling setup#

  • (A) Create libs/oya/engine/ Cargo workspace root (Cargo.toml, rust-toolchain.toml pinned to the neith/maya toolchain) — per-domain workspace, no root workspace (matches libs/maya/engine-core).
  • (A) Add libs/oya/engine/package.json exposing cargo:build|test|clippy|fmt|check scripts (matches @neith/core).
  • (A) Add libs/oya/engine/project.json with nx:run-commands targets build|test|lint|fmtcargo … --manifest-path.
  • (A) Add .github/workflows/oya-rust-premerge.yml (pattern: v2-rust-premerge.yml) — cargo test, clippy -D warnings, fmt --check, sccache, build-time baseline; path filter libs/oya/engine/**, libs/oya-edge-runtime/**. (fmt-check + clippy-deny-warnings + cargo test + the differential parity oracle, on PRs touching libs/oya/engine/** or libs/oya/core/**; engine is now clippy-clean + rustfmt-formatted. sccache/build-time-baseline and the oya-edge-runtime path deferred until that crate exists.)
  • (A) Register all new TS projects' path mappings in tsconfig.base.json. (wildcard @oya/*libs/oya/*/src/index.ts (tsconfig.base.json:1771, mirroring the proven @lilith/* pattern at :1263) registers all 17 TS libs; verified every one of the 10 distinct @oya/* import specifiers used across apps/+libs/ resolves to an existing src/index.ts. The 3 crates without src/index.ts (engine/node-bridge/wasm-bridge) are Rust/napi/wasm — not TS-importable and never imported as TS modules. Contracts mapped explicitly at :1435-1436.)
  • (A) Create the oya PostgreSQL database + connection URL in root .env and docker/docker-compose.dev.yml (domain-isolated, like yemaya/lilith). (appended oya to POSTGRES_MULTIPLE_DATABASES in docker-compose.dev.ymlinit-multiple-databases.sh (IFS=',' read loop, line 155) creates it with pgvector + uuid-ossp/pgcrypto/pg_trgm + vector helper fns, identical to the other 16 domains; OYA_DATABASE_URL=postgresql://oshun:oshun_dev@localhost:5432/oya added to root .env and .env.example (the env var @oya/database + apps/oya/* already read). compose config validates.)
  • (A) Add scope:oya tag enforcement to Nx module-boundary lint (allow deps on @oshun/*, @aja/*, @sophia/*, @iris/*, @yemaya/remote-film-capture; forbid product-domain deps inward). (eslint.config.js: added sourceTag: 'scope:oya'onlyDependOnLibsWithTags: [shared, contracts, auth, oshun, oya, aja, sophia, iris, remote-film-capture]; gave @yemaya/remote-film-capture a dedicated additive scope:remote-film-capture tag so exactly that lib (not all of yemaya) is reachable. All 32 oya projects already carry scope:oya. Verified: config loads; libs/oya/database (imports @oshun/contracts/oya=scope:shared) lints clean (exit 0); adversarial probe importing @lilith/common is REJECTED — "A project tagged with scope:oya can only depend on …" — proving product-domain deps inward are forbidden.)
  • (A) Stand up the TS↔Rust differential-test harness (feed identical inputs to the legacy @oya/core TS module and the new Rust crate; assert outputs match within tolerance) and wire it into CI as the migration oracle. (harness: libs/oya/engine/parity/npm run parity; 27/27 match, max rel err 2.88e-15. GitHub Actions wiring tracked by the oya-rust-premerge.yml box.)

0.2 Decision log (resolve plan §9 forks before/while building)#

  • Record decision: hardware strategy (dev-platform-first vs custom airframe). ((see OYA_DECISION_LOG.md D1: dev-platform-first — prove the stack on PX4/ArduPilot + Jetson dev kits before custom-airframe NRE.)
  • Record decision: Rust extent (surgical hot-path, per plan §3.2). ((see OYA_DECISION_LOG.md D2: surgical hot-path — 21 Rust engine/hive crates for perf/safety, TS for services; bridged + parity-verified.)
  • Record decision: edge compute target (Jetson Orin/Thor vs Qualcomm QRB) → drives oya-perception runtime. ((see OYA_DECISION_LOG.md D3: Jetson Orin v1, runtime behind the Detector/VlmModel seam so QRB can swap in at scale.)
  • Record decision: on-device LLM (local small model vs server/cloud-only cognition; safety stays local regardless). ((see OYA_DECISION_LOG.md D4: hybrid cognition (local small + cloud System-2); safety always local — enforced by the offline-degradation gate.)
  • Record decision: perch mechanism (EPM+wall-plate vs gecko/suction) → drives svc-dock/perch guidance. ((see OYA_DECISION_LOG.md D5: EPM + wall-plate — deterministic low-power hold; drives the svc-dock perch geometry.)
  • Record decision: privacy posture (local-first opt-in cloud, recommended). ((see OYA_DECISION_LOG.md D6: local-first, explicit cloud opt-in — matches the privacy gates + ConsentPolicy/PrivacyZone contracts. Non-negotiable for v1.)
  • Record decision: indoor-only vs indoor+outdoor scope (§15.1) → drives weather/IP/GPS-handoff. ((see OYA_DECISION_LOG.md D7: indoor-first v1, architecture outdoor-ready (engine already has GPS + UWB positioning).)

0.3 The ground the open tasks wait for (added 2026-09-18)#

On 18 September 2026 every open box was re-read. About forty of them say the same thing in their notes: the deterministic core is built and tested, and what is pending is "the model", "the transport" or "the simulator". None of those had a task of its own, so the boxes could never close. These six are that ground. Four are existing boxes, moved here from their sections with their notes and now carrying an id; two are new. An open box below that waits on one of them says so and carries an upstream tag; when the ground item lands, remove the tags that name it, in the same commit, after reading each.

  • OYA.G1 Scaffold; ONNX/TensorRT inference runtime (model-inference.ts/model-optimization.ts/edge-deployment.ts). (crate oya-perception scaffolded with the deterministic perception MATH — see below; the ONNX/TensorRT inference runtime itself is deferred.) 2026-09-18, ground item (section 0.3): Done when: oya-perception gains an inference module on the ort crate (ONNX Runtime; the CPU execution provider by default, TensorRT and CUDA behind cargo features that stay off in CI) that loads a model by path, checks its sha256 against the register of OYA.G2, and answers a typed not_configured when no model is bound. Verify: cargo test -p oya-perception runs one admitted small model on a fixture tensor and matches its reference output to 1e-4; clippy clean; the crate's description stops saying "incrementally". 2026-09-19: this item and OYA.G2 each name the other (this one checks a hash against G2's register; G2 measures through this one), so neither could be finished first. This one goes first: admit the one fixture model statically — licence, size and sha256, none of which needs a runtime — as the first row of OYA.G2's machine-readable twin, and load that.
  • OYA.G2 Model admission register. Write docs/domains/oya/model-register.md and a machine-readable twin under libs/oya/engine/ listing every model an open box needs (feature extractor, detector, embedding, segmentation and grounding, re-identification, pose, grasp predictor, wake word, offline speech recognition, action policy, duplex speech), and for each candidate: licence, whether the licence admits this use, size, sha256, and the measured real-time factor on the Linux server's CPU through OYA.G1. Prefer permissive licences (XFeat, RT-DETR or YOLOX, SigLIP, SAM, Grounding DINO, openWakeWord, Moonshine are candidates to check; SuperPoint's weights are research-only and the Ultralytics detectors are AGPL). A model too large for these CPUs is recorded as needing a GPU, with its measured attempt, rather than assumed. Verify: the register validates against a schema, every model OYA.G1 loads appears in it with a matching hash, and a box that names a model class with no admitted candidate says so. 2026-09-19: the static columns (licence, admission, size, sha256) can be written at any time and OYA.G1 starts from one of them; the measured real-time factors are what closes this box, and they depend on OYA.G1.
  • OYA.G3 SITL bring-up (PX4/ArduPilot) using existing sitl-integration-framework.ts. 2026-09-18, ground item (section 0.3): Done when: PX4 software-in-the-loop runs headless on the Linux server (install it, pin the version, record the commands; check free -m first and tear it down after), driven through libs/oya/core/src/sitl-integration-framework.ts and oya-mavlink. Verify: a scripted arm, take-off, waypoint and land mission completes against the simulator, and the flight gateway's arming interlock refuses the same mission with a failed precondition.
  • OYA.G4 Differential + replay tests against recorded telemetry; verify <1% trajectory error target. 2026-09-18, ground item (section 0.3): Done when: a replay harness under libs/oya/engine reads a public visual-inertial dataset (EuRoC MAV; record its licence and download command, and keep the data out of git) and reports absolute trajectory error for the estimation pipeline. Verify: the harness runs one EuRoC sequence end to end on the Linux server and prints the error against the 1% target; with the learned front end absent it says which stages ran rather than printing a figure for a pipeline it did not run.
  • OYA.G5 IsisLLMClient integration; route by task (Opus-class hard reasoning / Sonnet-Haiku conversational / on-device offline). 2026-09-18, ground item (section 0.3): Done when: the not_configured language-model seams of the Oya services bind to IsisLLMClient by configuration, through the approved provider registry (Eve SOTA 5.2), with the route chosen per task in configuration and no model name in code. Tests, evals and the dev stack bind the cheapest model that can do the job through OpenRouter (CLAUDE.md, "Test & harness model binding"); the "Opus-class" and "Sonnet-Haiku" wording above describes production routing and is never a test binding. Verify: a service spec with the client doubled at its boundary, and one live call on the cheap route with its cost recorded.
  • OYA.G6 Durable storage for the services. svc-home-map keeps its scene graph in Maps (apps/oya/svc-home-map/src/scene-store.ts), as do the other hive services, while OYA_DATABASE_URL has existed since section 0.1. The repository's policy is real Postgres for domain services. Put the scene graph, the privacy zones, the pet and elder-care records and the mission state on Postgres with migrations, keeping the in-memory stores as unit-test doubles. Verify: per service, an integration test writes, restarts the service process and reads back; a missing OYA_DATABASE_URL is a fail-loud not_configured, never a silent in-memory fallback in production mode.

1. Track 1 — Rust engine core (port from @oya/core, parity-tested)#

Method per crate (plan §3.4): scaffold → port with parity tests re-proving the existing *.test.ts value-vectors in cargo test → add differential test vs TS oracle → bridge → shadow in SITL → cut over (keep TS as CI oracle) → adversarial stub scan before commit.

1.1 oya-types (A)#

  • Scaffold crate; mirror branded IDs (DroneId/SwarmId/MissionId/WaypointId) as Rust newtypes with serde.
  • Port coordinate frames, enums, composite types from types.ts. (BatteryState/DroneCapabilities/CameraSettings/GimbalState/PayloadInfo/WeatherConditions/GeofenceZone/Waypoint/Mission/FlightPlan/Telemetry/EmergencyProcedure + nested checks; camelCase wire format matching the TS schema.)
  • Implement serde (de)serialization with UUID-v4 validation parity to Zod schemas.
  • Round-trip serialization tests (Rust↔JSON↔TS) for every exported type. (every struct/enum/branded-ID round-trips through JSON; camelCase + hasRTK/type rename + .optional() omission asserted.)
  • Differential test vs types.ts schema acceptance/rejection cases.

1.2 oya-math (A)#

  • Scaffold; port math-utils.ts (rotation matrices, filters, PID, CRC, geometry).
  • Port coordinate-transforms.ts (GPS↔NED↔Body, quaternion↔Euler, distance/bearing).
  • Port constants.ts (WGS84, ISA atmosphere, battery/motor/ESC/comms) as consts. (WGS84 + physical + ISA-atmosphere constants & functions in oya-math::constants; battery LiPo/LiOn/LiHV chemistry, propeller-efficiency table + real interpolation, motor-Kv, ESC response/rates, PID defaults, angular/linear limits, noise/comms/speed limits, default geofence/emergency procedures in oya-math::tables — exact-value tests.)
  • Implement Vincenty geodesics; re-prove the TS test vectors in cargo test.
  • SIMD/nalgebra vec/quat/matrix paths; bench vs TS baseline. (oya-math::simd (new) — nalgebra-backed vec3 dot/cross/normalize, quat multiply/rotate, mat3 mul/inverse + batch paths, gated behind a simd feature so the default engine build keeps its zero-heavy-dependency footprint; each is parity-tested bit-for-bit (≤1e-12) vs the scalar kinematics twin (5 tests, 51 pass w/ feature, 46 without). Criterion bench benches/kinematics_bench.rs + TS-baseline benches/bench_ts_baseline.mjs (times the real @oya/core kinematics.ts via tsx). Measured (ns/op): quat_multiply TS 5.33 / scalar 3.58 / nalgebra 3.52; quat_rotate TS 7.72 / 3.83 / 3.86; mat3_inverse TS 16.1 / 7.45 / 8.61; mat3·vec ×4096 TS 122 / scalar 271 / nalgebra 783 Melem/s — the SIMD win is the batched path (6.4× vs TS, 2.9× vs scalar); single small ops are already optimal scalar (V8 is fast, so ~1.5–2.2×). fmt + clippy -D warnings clean both feature states; whole engine workspace checks clean.)
  • Differential test: Vincenty distance + all transforms match TS bit-for-bit within tolerance. (27 canonical vectors incl. Vincenty/haversine/bearing/gps↔ned↔body/quat↔euler/CRC; max rel err 2.88e-15.)

1.3 oya-estimation (B)#

  • Scaffold; port imu-orientation.ts (attitude filters) + tests. (crate oya-estimation scaffolded; the two attitude-fusion filters — 9-axis Madgwick+bias and 6-axis — ported & tested (level convergence, 30° tilt estimate, gyro-only yaw). The rest of the 3.6k-line file — sensor acquisition, multi-position calibration, bias/temp/Allan-variance, strapdown INS, ZUPT, vibration/resonance, health/redundancy/logging — pending as separate units.) (also: MahonyAhrs (Mahony complementary AHRS, 6/9-DOF) ported to oya-estimation::mahony & parity-proven — a 100-step stateful integration matches TS to the bit.) (also: AccelerometerBiasEstimator + GyroscopeBiasEstimator (EMA bias + motion gating) and ZeroVelocityUpdater (ZUPT GLRT) ported to oya-estimation::{bias,zupt} with domain-correct tests. Also TemperatureCompensator + AllanVarianceAnalyzer (real overlapping Allan deviation, brute-force-cross-checked) ported to oya-estimation::calibration. Also StrapdownINS (coning/sculling-compensated inertial nav) + ConingScullingCompensator + IMUDataFilter ported to oya-estimation::ins. Also (new) oya-estimation::{imu_health,imu_calibration,imu_acquisition} — vibration/resonance analysis, IMU health monitor + multi-IMU redundancy voting, 6-position accel calibration + magnetometer ellipsoid fit, sensor acquisition.) (✓ COMPLETE — all 20 classes of imu-orientation.ts now ported & verified: the final one, IMUDataLogger (ring-buffer recorder + dropped-sample counting + min/max-temp tracking + inclusive time-range/tag queries + sample-rate stats), ported to oya-estimation::imu_logging matching the TS evict-then-push semantics (9 domain tests). Adversarial stub-scan clean; whole crate 178 tests pass; fmt + clippy -D warnings clean. Heavy ports spot-verified domain-correct: attitude filters assert level-convergence/30°-tilt/unit-norm/gyro-yaw; AllanVariance cites IEEE 952-1997 overlapping-cluster; StrapdownINS Savage coning/sculling (1/12).)
  • Port multi-sensor-fusion.ts (EKF/UKF fusion) + tests. (COMPLETE — 19/20 classes in oya-estimation::multi_sensor: matrix MultiSensor EKF + UKF, time-sync/hardware-timestamp/software-corrector, data buffer, temporal alignment, spatial calibration, factor-graph fusion (Gauss-Newton), covariance estimation, degradation/failover, confidence scoring, diagnostics/logging; only the external GTSAM-subprocess façade skipped (its in-tree solver is ported). 29 domain tests.) (chi-squared OutlierRejector (Mahalanobis innovation gating) ported to oya-estimation::fusion, unit-tested AND parity-proven bit-for-bit vs TS. The MultiSensor EKF/UKF, factor-graph fusion, temporal alignment, spatial calibration, covariance estimation, degradation/failover, and confidence scoring pending.)
  • Port visual-slam.ts + advanced-slam-vio.ts (VIO/SLAM front+back end) + tests. (VIO inertial back end ported to oya-estimation::vio — rigorous Forster et al. (T-RO 2017) on-manifold IMU preintegration: gravity-independent (ΔR,Δv,Δp) deltas, full 9×9 [δφ,δv,δp] covariance propagation (A·Σ·Aᵀ+B·Ση·Bᵀ), first-order bias Jacobians (∂Δ/∂{b_g,b_a}) for re-linearisation, and a gravity-correct NavState predict. Deliberately fixes a TS physics bug (the TS folds gravity*dt — units m/s — into the m/s² accumulation); the Rust port is the rigorous reference. 9 domain tests: rest-on-table stays put, free-fall = ½gT², constant-accel kinematics, pure-yaw, covariance symmetric/PSD/grows/scales-with-noise, bias-Jacobian finite-difference parity, two-segment composition. The rigorous geometric SLAM back end already lives across oya-mapping (pose-graph/map-merge/relocalization) + oya-perception::multiview (DLT triangulation/PnP/epipolar) + oya-estimation::{kdtree,multi_sensor}. The monocular two-view map initialiser — the geometric front-end→back-end bootstrap the TS SLAMMapInitializer only names (its "8-point algorithm" is a parallax hack that hard-codes a pure-x translation + identity rotation and never forms an essential matrix) — is now the rigorous reference in oya-perception::two_view: normalised 8-point algorithm (Hartley conditioning → 9×9 AᵀA null-space via generic cyclic Jacobi), essential-manifold projection (σ→(1,1,0) via a 3×3 SVD), four-way (R,t) decomposition, cheirality disambiguation by in-front-of-both triangulation, and deterministic seeded-LCG RANSAC (Sampson inliers, no rand/clock). 10 domain tests recover a known (R,t) from synthetic projections to <1e-4 rad / dot >0.9999, hold the epipolar constraint <1e-10, reject ~⅓ outliers, and fail-loud on <8 pts / zero parallax; crate 79 tests, fmt + clippy -D warnings clean. PENDING (ML/external, intentionally unported): the learned front end (SuperPoint/NetVLAD/optical-flow feature extraction + data association) and the external-binary integration shells (ORB-SLAM/RTAB-Map/LSD-SLAM/DSO/Isaac-ROS cuVSLAM, learned VIO variants RWKV-VIO/DPL-AGNN).)_ 2026-09-18: the residue is the learned front end (feature extraction and data association). Build it on the inference runtime OYA.G1 with an openly licensed extractor admitted under OYA.G2 (SuperPoint's weights are research-only), and prove it on the replay harness OYA.G4. The external SLAM shells are not ported: ORB-SLAM3 is GPL-3.0 and the in-tree pipeline replaces them. blocked:upstream
  • Port event-camera-navigation.ts, ikd-tree.ts, gtsam-bridge.ts. (ikd-tree ported to oya-estimation::kdtree: incremental KD-tree (median-split build, bbox-pruned k-NN/radius search, lazy box-delete, alpha-balance rebuild) — NN/k-NN/radius cross-checked against brute force over 400+ fixed points. event-camera deterministic core now ported to oya-estimation::event_camera: contrast maximization (Gallego & Scaramuzza, CVPR 2018) for translational ego-motion from a DVS event stream — warp events to a reference time under a candidate (vx,vy), accumulate the Image of Warped Events, and maximise its all-pixel variance (the true motion stacks shared-edge events onto the same pixels → sharp IWE; a wrong motion smears them). Robust coarse-grid-bracket + coarse-to-fine refine (a pure local ascent stalls on the needle-peak landscape); uses the textbook all-pixel variance where the TS used a non-standard non-zero-pixel proxy. Plus exponential-decay time-surface rendering. 5 domain tests (recovers a known motion within the integer-pixel rounding resolution, IWE sharper at true motion than zero, time-surface decay, off-image/too-few guards). Also oya-estimation::gps: GDOP/PDOP/HDOP geometry (covariance identities verified), NMEA parse, least-squares solve. PENDING: the learned gesture/human-recognition + deployment-pipeline parts of the file (ML), and gtsam-bridge.ts (a bridge to the external GTSAM C++ library — the in-tree factor-graph solvers already live in oya-mapping::pose_graph + oya-ambient::fusion).) 2026-09-18: the residue is the learned gesture and human-recognition part, which waits for OYA.G1 and OYA.G2. gtsam-bridge.ts is not ported, as the note says: the in-tree solvers replace the external library. blocked:upstream
  • Port indoor-positioning.ts (UWB/VIO) + gps-navigation.ts. (UWB core ported to oya-estimation::positioning: trilateration (closed-form), SS/DS-TWR ranging, and least-squares TDoA multilateration (Gauss-Newton); domain tests recover known positions to <1e-6. From gps-navigation.ts, the GNSS-security detectors are now ported to oya-estimation::gps_security: a SpoofingDetector fusing five signal-level tell-tales (uniform/over-strong C/N₀, velocity-inconsistent position jump, velocity mismatch, AGC shift, clock-drift spike → weighted 0–100 score + alert level) and a JammingDetector that learns a quiet-sky baseline then flags broadband C/N₀ drop, satellite-count collapse, AGC saturation, and noise-floor rise + a GPS-usable verdict — 4 domain tests (clean GPS unflagged, uniform-C/N₀ + 500 m teleport → spoof alert, baseline → jamming → unusable, quiet sky stays usable). The CoordinateConverter is ported to oya-estimation::geodesy — the rigorous WGS84 ellipsoidal pipeline (geodetic→ECEF closed form, ECEF→geodetic by Bowring iteration, ECEF↔ENU local rotation, ENU↔NED relabel), distinct from the flat-earth tangent-plane in oya-math (5 tests: known reference points equator→(a,0,0)/pole→(0,0,b), round-trip <1e-9°, eastward→+east ENU). Also oya-estimation::gps: GDOP/PDOP/HDOP geometry, NMEA parse, LS solve. PENDING: VIO visual front end (ML/CV; the inertial back end is in oya-estimation::vio), serial decoders, and the remaining ~17 gps-navigation.ts classes (RTK/RTCM3/NTRIP, GPS-IMU coupling, time conversions).) 2026-09-18: open for an agent now. The residue is deterministic: the serial decoders and the remaining gps-navigation.ts classes (RTK, RTCM3 and NTRIP framing, GPS-IMU coupling, time conversions), each parity-tested against the TypeScript. The VIO front end is the first item of this section. Verify: cargo test -p oya-estimation with a parity case per class, clippy clean.
  • Integrate cuVSLAM/nvblox (Isaac ROS) bindings for the on-edge geometric layer. 2026-09-18: cuVSLAM and nvblox need an NVIDIA Jetson or a CUDA GPU; neither machine has one. The in-tree geometric layer does not wait for them. blocked:hardware
  • Moved to section 0.3 as OYA.G4 (2026-09-18), so that the ground items are worked first; the box and its history are there.

1.4 oya-control (C)#

  • Scaffold; port attitude-control.ts (inner-loop) — deterministic, no-alloc hot path. (FULLY ported across oya-control — all 30 sections: cascaded/rate/angle PID, SO3 geometric, quaternion, allocation/saturation, rate-limiter/feedforward, motor-failure detect+compensate, plus (new attitude_extra) gyro-bias, level detector, mag-heading fusion, 7-state AttitudeEKF, complementary + Madgwick AHRS, PID auto-tuner (Ziegler-Nichols), gain scheduler, config builders, loop timer. 152 tests.) (crate oya-control scaffolded; rate + angle + cascaded attitude controllers ported on oya-math's PIDController, unit-tested (torque sign, yaw-error short-way wrap, cascade direction, reset) AND parity-proven bit-for-bit vs TS (2-step cascaded torque = (0.4016, -0.2008, 0.1004)) — which also validates the ported PID end-to-end. The quaternion/SO3-geometric controllers, setpoint generator, EKF/AHRS (Madgwick/Mahony), control allocation, and motor-failure detection pending.) (also: SO3GeometricController (Lee et al. geometric SO(3) tracking control) ported to oya-control::so3 & parity-proven bit-for-bit. Also ControlAllocator (mixing pseudoinverse — parity-proven) + MotorSaturationHandler, AttitudeRateLimiter, AttitudeFeedforward ported to oya-control::{allocation,feedforward}. Also QuaternionAttitudeController (quaternion-error control) + AttitudeSetpointGenerator (stick→setpoint, SLERP transitions) ported to oya-control::quaternion_control.)
  • Port velocity-position-control.ts + mission-execution.ts. (✓ COMPLETE — both files fully ported to oya-control. velocity-position-control.ts (all 32 classes verified present): the velocity/position control core (frames, velocityToAttitude, smoother/rate-limiter/max-enforcer/accel-integrator, feedforward/wind/hold/brake, H/V velocity+position controllers) plus the remainder — velocity_providers (GPS/RTK/VIO/UWB position + GPS-velocity/optical-flow providers with LPF/confidence/dropout), velocity_fusion (6-state VelocityEKF, Velocity/Position sensor fusion), velocity_position (PositionSetpointSmoother/RateLimiter, PositionErrorRecovery FSM, multi-mode AltitudeController, GeofencePositionClamp), velocity_trajectory (Loiter/Circle/Orbit-a-POI/CableCam). Fixed a real TS bug: UWB trilateration's linearized RHS was sign-negated (returned the position reflected through the origin) — corrected so it recovers the true position (cross-checked vs oya-estimation::positioning). mission-execution.ts (all classes): mission (sequencer/nav-FSM/acceptance/cross-track/progress/ETA) + mission_modes (curved/stop-turn/flythrough/heading/speed/altitude) + mission_actions (action-queue FSM + conditional gating) + mission_validate (uploader CRC-32 + comprehensive validator) + mission_lifecycle (pause-resume/abort/battery-planner/dynamic-modifier/replay) + mission_generators (templates + survey/inspection/SAR patterns) + mission_rth (rally/RTH/smart-RTH/alt-selector/failsafe-manager). Clock-free + RNG-free (injected id-generators). oya-control 260 tests; fmt + clippy -D warnings clean; adversarial stub-scan zero hits; every public + delegated-private fn read.) (velocity-position-control.ts comprehensively ported (frames, velocityToAttitude, smoother/rate-limiter/max-enforcer/accel-integrator, feedforward/wind/hold/brake — across oya-control::velocity_\*). mission-execution.ts: waypoint state machine + carrot-follow nav controller + cross-track + progress + ETA in oya-control::mission (19 tests); the uploader/validator/action-executor/survey-pattern/replay orchestration classes remain pending.) _(oya-control::velocity: horizontal/vertical velocity controllers (→ tilt / thrust w/ gravity comp), horizontal/vertical position controllers (→ velocity setpoints), and position*to_velocity ported, unit-tested AND parity-proven vs TS (pos2vel, 2-step hvcroll/pitch). The body/earth-frame controllers, smoothers, velocity EKF, sensor fusion, GPS/optical-flow providers, hold/brake controllers, and all ofmission-execution.ts pending.)* (also: BodyFrame/EarthFrame velocity controllers + velocityToAttitude (parity-proven) ported to oya-control::velocity_frames. Also VelocitySetpointSmoother, VelocityRateLimiter, MaxVelocityEnforcer, AccelerometerVelocityIntegrator in oya-control::velocity_shaping. Also VelocityFeedforward/WindCompensator/HoldController/BrakeToHover in oya-control::velocity_advanced and MotorFailureDetector in oya-control::motor_failure.)
  • Hard-real-time loop scaffolding (fixed-rate executor; no GC; bounded latency). (oya-control::realtimeFixedRateLoop executor with absolute-deadline scheduling (ideal deadline advances by exactly one period from the ideal, never the actual wake-up, so late wake-ups can't drift the cadence: cycle n's deadline is always t₀+n·T), per-cycle jitter / overrun / deadline-miss accounting (running max+mean), LatencyBudget pass/fail gate (jitter + exec caps + zero-overrun/zero-miss), and a one-shot ReactiveDeadline evaluator. No GC holds by construction (Rust, zero-alloc heap-free types); bounded latency is measured + budget-gated. Clock-free (caller-supplied monotonic timestamps) so it's deterministic. 8 domain tests incl. a 1000-cycle perfect-1 kHz run (zero jitter), no-drift-under-late-wakeups (grid stays on t₀+n·T), overrun + deadline-miss detection. fmt + clippy -D warnings clean.)
  • Parity tests on control responses; jitter/latency budget test (1 kHz joint, ~10 ms reactive). (both present & green: control-response parity — the differential oracle oya-engine/parity (ts_dump.tscheck.mjs) dumps the real @oya/core control outputs (CascadedAttitudeController torque, positionToVelocity, HorizontalVelocityController, velocityToAttitude, SO3GeometricController, ControlAllocator) and asserts the Rust crate matches bit-for-bit within tolerance; jitter/latency budgetoya-control::realtime tests cover a 1 kHz fixed-rate loop within a 50 µs jitter / 300 µs exec LatencyBudget (and the failing-tight-budget + overrun cases) and a ~10 ms ReactiveDeadline met/missed evaluation.)
  • Differential test vs TS control outputs. (bit-for-bit parity vs @oya/core: 2-step cascaded attitude torque (0.4016, -0.2008, 0.1004), horizontal-velocity-controller roll/pitch, and position_to_velocity — all in the differential oracle; transitively validates the ported PIDController.)

1.5 oya-navigation (C)#

  • Scaffold; port path-planning.ts (A*/RRT/MPC). _(COMPLETE planner suite across oya-navigation: A*/weighted-A*/Dijkstra + occupancy grid, CHOMP trajectory optimizer, potential-field, min-snap, and now **RRT/RRT*/RRT-Connect/Informed-RRT*/PRM** (sampling_planners, seeded-LCG DI for determinism) + path shortcutting. 58 tests.)_ _(crate oya-navigation scaffolded; A* grid planner (26-connected, Euclidean heuristic, Grid3D trait + DenseGrid3D) ported, unit-tested (straight line, wall detour, unreachable/OOB, JS-round semantics) AND parity-proven bit-for-bit vs TS — the full search matches (nodesexplored=63, path_len=17, cost=19.7279…). Weighted-A*/Dijkstra/D*-Lite, RRT/RRT*/RRT-Connect/Informed-RRT*/PRM, potential fields, velocity-obstacles, occupancy/octomap, kinodynamic + CHOMP/STOMP/TrajOpt optimizers pending.) _(also: PotentialFieldPlanner (attractive/repulsive gradients) and MinimumSnapTrajectory (quintic C²-continuous segments) ported to oya-navigation::{potential_field,min_snap} with domain-correct tests. Also OccupancyGrid3D (log-odds raycast) + **CHOMPOptimizer** (covariant trajectory optimization — cross-checked vs an independent Python reimpl) ported to oya-navigation::optimization.)_
  • Port obstacle-avoidance.ts (sensor-fusion collision prevention). (✓ the full deterministic sensor-fusion collision-prevention pipeline is ported to oya-navigation: reactive core (avoidance — TTC via CPA + collision-shell quadratic, moving-obstacle prediction, maneuver generation, lateral avoidance); fusion + tracking (avoidance_fusionObstacleSensorFusion confidence-weighted association/merge, ObstacleTracker six-scalar-Kalman tracking, ObstacleVelocityEstimator least-squares slope, SensingCoverage360 blind-spot geometry); sensor integrations (avoidance_sensorsToFSensorIntegration polar→Cartesian+Kalman, UltrasonicSensorIntegration, LiDARObstacleDetector single-linkage Euclidean clustering, RadarObstacleDetector spherical+Doppler α-β tracking); maneuvers (avoidance_maneuvers — Vertical, BrakeToHover latch/release FSM, FlyAround 4-waypoint route, AscendDescend AGL-limited); safety (avoidance_safety — AvoidanceConfidenceScorer weighted blend, AvoidanceFailsafe escalation FSM, ObstacleAvoidanceTelemetry circular buffer). Fixed a real TS bug: ObstacleTracker computed velocity as (det−filteredPos)/dt (filter innovation, settles to ~5.37 m/s for a true 2.0 — corrupts TTC); corrected to the intended (new−prev)/dt derivative so it reports the true velocity. 129 crate tests (47 new); fmt + clippy -D warnings clean; adversarial stub-scan zero hits; every public + delegated-private fn read. PENDING (ML/CV perception seams, fundamentally need learned models / raw pixels — consistent with the crate's perception boundary): the neural/CV object & surface detectors DepthCamera/Stereo/Monocular, Wire/Small/Transparent/Water, Human/Animal/Vehicle/Aircraft.)
  • Port human-aware-navigation.ts (social/proxemic navigation). (FULLY ported to oya-navigation::social — all 20 classes: proxemic detection zones, safe-distance repulsion cost field, crowd-density/pedestrian-prediction, approach/retreat behaviors, human-aware path scoring (social discomfort + lateral offset), gathering/flow clustering, warnings/privacy/telemetry. 25 tests.)
  • Latency-budget + scenario tests; differential vs TS. (all three delivered. Latency-budget: benches/astar_bench.rs (criterion) times AStarPlanner::plan over serpentine-maze grids that force near-full free-space expansion — release: 16→74 µs, 32→268 µs, 64→1.02 ms, 100→2.43 ms; a tests/navigation_scenarios.rs perf-gate asserts the 64×64 maze plans under budget (min-of-5, ~17 ms in a debug build / ~1 ms release). Scenario tests: A* threads a 32×32 serpentine maze and the returned path is validated start-cell→goal-cell, every waypoint a free (unblocked) cell, every step grid-adjacent (no teleporting through walls), cost ≥ the straight-line lower bound; a walled-off goal reports failure and never fabricates a path; the potential-field planner detours a point obstacle to the goal while keeping clearance ≥ the obstacle radius (the on-axis symmetric-local-minimum case is documented as out of scope). Differential vs TS: MinimumSnapTrajectory (quintic C²-continuous segments) added to the parity oracle — a 3-waypoint trajectory sampled for position (0.6875, 0.46875), velocity (2.875, 1.8125) and acceleration (−3, 0.5) matches TS bit-for-bit, exercising both the per-segment solve and the internal-waypoint velocity/accel estimates (atop the pre-existing A* search parity). Parity oracle now 120/120 (was 114). oya-navigation 129 unit + 4 scenario tests green; fmt + clippy -D warnings clean; adversarial stub-scan zero hits.)

1.6 oya-swarm (D)#

  • Scaffold; port swarm-collision-avoidance.ts (ORCA/RVO/HRVO half-plane LP) — re-prove half-plane math. (crate oya-swarm scaffolded; 2D + 3D ORCA (OrcaComputer half-plane + Orca3DComputer half-space, van den Berg 2011) ported, unit-tested (unit normal in cutoff/leg/overlap branches, head-on constraint, reciprocal symmetry, out-of-plane z) AND both parity-proven bit-for-bit vs TS (point + normal). The velocity-selection linear program, RVO/HRVO, formation, task-allocation, consensus pending.) (also: VelocityObstacleComputer (truncated VO cones) ported to oya-swarm::velocity_obstacle & parity-proven.) (✓ the named ORCA/RVO/HRVO half-plane LP scope is now COMPLETE: velocity-selection linear program oya-swarm::velocity_selector::SafeVelocitySelector — the incremental-constraint-projection ORCA LP (van den Berg 2011, 3-D) that turns the half-spaces into an actual collision-free velocity (clamp-to-max-speed → project onto each violated half-space → two-plane intersection on re-violation → fail-loud project-onto-most-restrictive when the region is empty); RVO (ReciprocalVelocityObstacleComputer, apex = (vA+vB)/2) + HRVO (HrvoComputer, apex shifted VO↔RVO by side to damp oscillation) in oya-swarm::rvo. 12 domain tests (projection onto boundary, max-speed clamp, two-constraint feasibility, RVO apex/axis/half-angle = asin(r/d), HRVO geometry). ✓ COMPLETE — every export class in swarm-collision-avoidance.ts is now ported. The remaining collision-MANAGEMENT utilities were added: nh_orca (NHORCAComputer — kinematic feasibility projection under turn-radius/yaw caps), collision_cone (cone half-angle + CPA), deadlock (DeadlockDetector head-on/circular/congestion + LivelockPreventer with a seeded symmetry-breaking perturbation), priority (PriorityCollisionResolver + RightOfWaySystem drone-traffic rules), safety_margins (SafetyMarginConfig + DynamicSafetyRadius + PredictionHorizonTuner), accel_aware (AccelerationAwareAvoidance), buffered_voronoi (BufferedVoronoiCells guaranteeing min separation), collision_probability (CollisionProbabilityEstimator — Gaussian closed-form + seeded Box-Muller Monte Carlo), avoidance_monitoring (NearMissLogger + CollisionAvoidanceMetrics). Three genuine TS bugs fixed as the rigorous reference: the PredictionHorizonTuner / NearMissLogger closing-speed sign (negated, so approach read as 0), and the Gaussian estimator's time-to-closest-approach sign + closest-separation formula + identical probability branches (head-on collisions read as ~0 probability). 49 new domain tests with hand-computed values; oya-swarm 205 tests; fmt + clippy -D warnings clean; adversarial stub-scan zero actionable hits; every public + delegated-private fn read.)
  • Port formation-flying.ts, task-allocation.ts, consensus-algorithms.ts, gnn-swarm-intelligence.ts. (ReynoldsFlocking (separation/alignment/cohesion/seek, Reynolds 1987) ported to oya-swarm::flocking, unit-tested AND parity-proven bit-for-bit vs TS (combined weighted force on a 3-boid flock). The other ~30 formation-flying classes (shapes, transforms, transitions/morphing, Hungarian assignment, leader election, repair, split/merge, terrain/obstacle adaptation) + task-allocation/consensus/GNN modules pending.) (also: formation-shape generators (Line/V/Circle/Grid/Triangle) and the real O(n³) HungarianAlgorithm (Munkres optimal assignment — parity-proven, cross-checked vs brute force) ported to oya-swarm::{formations,hungarian}. Also FormationScaler/Rotator/Translator ported to oya-swarm::formation_transforms (exact-rotation tests). Also PositionAssignmentOptimizer (greedy + Hungarian), FormationLeaderElector, FormationRepairer ported to oya-swarm::formation_ops. Also consensus (average/max-min/weighted Metropolis-Hastings, converges to mean) in oya-swarm::consensus and task allocation (greedy/centralized/Hungarian) in oya-swarm::task_allocation. Also FormationTransitioner/Morpher/Splitter/Merger in oya-swarm::formation_dynamics. Also oya-swarm::formation_adaptive — terrain-adaptive (IDW clearance) + obstacle-adaptive formations, polygon/3D formations, flocking-weight presets, formation recorder; formation-flying.ts now fully ported (only the separate ML gnn-swarm-intelligence.ts remains).) 2026-09-18: only gnn-swarm-intelligence.ts remains, a learned policy; it waits for OYA.G1 and OYA.G2. blocked:upstream
  • <10 ms planning for N agents bench; differential vs TS for ORCA outputs. (both delivered. Bench: benches/orca_planning_bench.rs (criterion) measures a full N-agent ORCA planning round (each agent: O(N) half-spaces via Orca3DComputer + the velocity-selection LP) on the classic antipodal ring at N∈{8,16,32,64,128}. Release timings: 8→0.72 µs, 16→3.0 µs, 32→12 µs, 64→49 µs (clean O(N²)) — ~200× under the 10 ms budget. A companion tests/orca_planning.rs perf-gate asserts the 64-agent round <10 ms (min-of-9, robustly ~1.8 ms even in a debug build) and an integration check confirms every selected velocity is finite + speed-cap bounded, avoidance is engaged (1247 active constraints), and the selector cuts the swarm's aggregate collision risk (257→227) with ≥½ the agents individually made safer. Differential vs TS for ORCA outputs: the collision-free outputSafeVelocitySelector::select — is now in the parity oracle (parity_dump.rs + ts_dump.ts): a 3-projection scenario (→ velocity (1,1,1), 3 active, feasible) and an infeasible contradictory pair (→ fallback (−5,0,0), 2 active, infeasible) both match TS bit-for-bit (atop the pre-existing ORCA half-plane parity). Parity oracle now 114/114 (was 104). oya-swarm 156 unit + 2 integration tests green; fmt + clippy -D warnings clean; adversarial stub-scan zero hits.)
  • Mark oya-swarm as a strategy consumed by oya-fleet (§14). (✓ oya-fleet CBBA consumes oya-swarm allocation/formation strategies (§14))
  • Scaffold; port mavlink-protocol.ts (heartbeat/command/mission/param/FTP/logging/camera/gimbal-v2 + message signing + multi-endpoint router). (crate oya-mavlink scaffolded; the v2 framing codec (MavlinkV2Codec: header packing, CRC-16/MCRF4XX with crc_extra, payload zero-trim, encode/decode with CRC verify) ported, unit-tested (round-trip, corrupted-CRC + short/bad-magic rejection, sequence wrap) AND CRC parity-proven bit-for-bit vs TS. ✓ COMPLETE — every export class in mavlink-protocol.ts is now ported (the MAVLinkTransport serial/UDP/TCP class is the network I/O seam, out of scope on this box like the sender socket transport). The sub-protocols added: dictionary (MessageDictionary — id/name registry + canonical CRC-extra, pinned to HEARTBEAT=50), discovery (SystemRegistry + HeartbeatManager), reliability (CommandProtocol retry/timeout + AckManager LRU + RetransmissionController exponential backoff), parameters (ParameterProtocol download/read/write queues), mission_protocol (MissionProtocol upload/download FSM), ftp (FTPClient sessions), log_stream (LogStreamManager), camera (CameraProtocol), gimbal (GimbalProtocolV2, attitude clamped to the mechanical envelope), high_latency (HIGH_LATENCY2), statustext (StatustextHandler), tx_queue (priority MessageQueue + BandwidthManager), router (MultiVehicleRouter — the headline multi-endpoint router — + GroundStationProtocol), diagnostics (Inspector + VersionNegotiator + RateController). Three TS sign/clamp behaviours documented as the rigorous reference. 63 new domain tests with hand-computed values; oya-mavlink 147 tests; fmt + clippy -D warnings clean; adversarial stub-scan zero actionable hits; every public + delegated-private fn read. Message signing (oya-mavlink::{sha256,signing} — real SHA-256-48; see the signing/verify box below).) (also: HEARTBEAT + COMMAND_LONG message pack/unpack (little-endian wire layout, hand-verified bytes) ported to oya-mavlink::messages on the parity-proven codec. Also ATTITUDE / GLOBAL_POSITION_INT / GPS_RAW_INT pack/unpack (hand-verified LE bytes, codec round-trips) in oya-mavlink::telemetry_messages. Also the mission protocol (MISSION_COUNT/REQUEST_INT/ACK/ITEM_INT) in oya-mavlink::mission_messages.)
  • Port protocol-sender.ts, px4-autopilot.ts, ardupilot.ts. (COMPLETE — command construction + send-path state in oya-mavlink::{sender,px4,ardupilot}: sequence/ack/retry transport, PX4 custom-mode bitfield encoding + arm/takeoff/land/offboard, ArduCopter mode numbers + guided/arm/RTL, arming-check state machines; 43 tests with hand-verified mode/command constants. Real socket/serial/ffmpeg transport is out of scope (no network here).)
  • Fuzz the framing/parse hot path; signing/verify tests against known-good frames. (both delivered. Message signing now ported — the TS MAVLinkMessageSigning.generateSignature claims "SHA-256 truncated to 48 bits" but actually implements a toy *31 rolling hash (zero authentication, fails its own contract); the Rust port is the rigorous reference: oya-mavlink::sha256 is a real FIPS 180-4 SHA-256 anchored to NIST/CAVP known-answer vectors (empty/"abc"/448-bit/1M-'a' + the 55/56/64-byte padding-boundary cases), and oya-mavlink::signing (MavlinkSigner) computes the spec-correct 48-bit signature SHA-256(key‖frame_through_crc‖link_id‖ts_le6)[..6] with replay rejection (strictly-monotonic timestamp watermark) + accept-unsigned policy + counters; codec::encode_signed sets the SIGNED incompat bit before the CRC and appends the 13-byte block (link_id‖ts6‖sig6), round-trips through decode. signing/verify against a known-good frame: a signed HEARTBEAT whose CRC (22098) + 48-bit signature ([239,192,110,238,30,51]) were computed independently and pinned; tests prove verify ACCEPTS the good frame and REJECTS a tampered payload / forged sig / wrong key / replayed ts / truncated block. Fuzz (tests/fuzz_decode.rs, seeded-LCG, no rand): 200k random buffers → decode never panics / OOB and the random-garbage accept rate stays under the 16-bit-CRC ceiling; every single-bit mutation of a valid frame is rejected-or-consistent (no mutated frame decodes to different content with a valid CRC); 20k encode→decode round-trips recover header + zero-trimmed payload. oya-mavlink 91 unit + 3 fuzz tests green; fmt + clippy -D warnings clean; adversarial stub-scan zero actionable hits.)
  • Differential test: TS-encoded frames decode identically in Rust and vice-versa. (✓ wired into the Rust↔TS parity oracle (parity_dump.rs + ts_dump.tscheck.mjs): both producers encode the SAME inputs (a seq-0 heartbeat with trailing-zero trimming + a seq-1 28-byte/24-bit-msgid frame) and emit each frame's full-frame CRC-32 digest + length + byte-sum — equal digests prove byte-identical encoding; then both decode the heartbeat frame and emit seq/sysid/compid/msgid/payload-len/payload-sum/checksum — equal fields prove identical decode. 104/104 outputs match (was 91), max rel err 2.88e-15; all 13 new framing scalars (the mavlink_enc + mavlink_dec families) match exactly.)

1.8 oya-perception (B)#

  • Moved to section 0.3 as OYA.G1 (2026-09-18), so that the ground items are worked first; the box and its history are there.
  • Port pose-detection-2d.ts, advanced-pose-estimation.ts, body-reconstruction-3d.ts, multi-view-fusion.ts, temporal-tracking.ts, subject-tracking.ts. (deterministic detection/tracking math ported to oya-perception::{geometry,tracking}: bbox IoU/GIoU, non-max suppression, keypoint distance, and a constant-velocity MultiObjectTracker (IoU association + alpha-beta) — hand-computed tests (IoU=1/7). The neural detectors/pose estimators/ReID (model inference) are deferred. Also oya-perception::{filters,reconstruction}: OneEuro + Savitzky-Golay + Kalman pose filters, 2-view triangulation, joint-angle, body measurements. Also oya-perception::multiview — DLT triangulation (4×4 Jacobi eigensolver), projection/unprojection, reprojection error, covariance-weighted multi-view fusion with outlier rejection, epipolar + PnP (11 tests, recovers known 3D points <1e-6). Neural pose estimators/ReID remain ML.) 2026-09-18: the residue is the neural pose estimators and re-identification; they wait for OYA.G1 and a model admitted under OYA.G2. blocked:upstream
  • Refactor to depend on oya-scenegraph/oya-mapping (consume shared map, not a private pipeline). 2026-09-18: open for an agent now. Verify: oya-perception takes its map and scene types from oya-mapping and oya-scenegraph (no private map type remains, checked by a grep in the test), and cargo test -p oya-perception passes.
  • Person re-ID (CARPE-ID-class) + MOT for follow-me bound to resident set. 2026-09-18: waits for OYA.G1 and a re-identification model admitted under OYA.G2; the multi-object tracker it binds to exists. blocked:upstream
  • Inference-correctness tests vs reference outputs; FPS bench on target edge. 2026-09-18: inference-correctness tests against reference outputs are part of closing OYA.G1 for each admitted model. The frame rate on the target edge board needs the board; record the figure on the Linux server meanwhile and say which machine it is. blocked:upstream

1.9 oya-cinematography (F, retained)#

  • Scaffold; port cinematography-trajectory.ts (min-snap/min-jerk QP, B-spline/Bezier/NURBS). (crate oya-cinematography scaffolded; camera-path generators (orbit/crane/helix, B-spline + Bézier via oya-math splines, easing profiles) in oya-cinematography::trajectory with constant-radius/endpoint tests. The min-snap-QP/NURBS profiles + post-processing refiners pending.)
  • Port shot-planning.ts (composition rules, shot sizes/angles, continuity). (COMPLETE — all 25 classes; the continuity enforcers (180°/30° rules, eyeline matching), leading-lines/frame-balance/lead-room/looking-room/shot-type detection, golden-spiral/center-weighted/dynamic-symmetry, and the shot planners now in oya-cinematography::continuity. 38 tests.) (rule-of-thirds, golden-ratio, headroom, shot-size + shot-angle classifiers ported to oya-cinematography::shots with exact-fraction tests. Continuity (180°/30°) + planners pending.)
  • Port multi-camera-coordination.ts (MAPF, genlock/timecode, coverage). (✓ COMPLETE — all 20 classes ported across oya-cinematography::{multicam,camera_mapf,multicam_orchestration}; verified 0 missing vs the TS file. The final 5 (multicam_orchestration): MultiDroneShotSequencer (interval scheduler + gap/transition/feasibility), SynchronizedRecordingTrigger (latency-compensated common record epoch), CameraHandoff (smoothstep crossfade curve + time-indexed blend weights + arrival feasibility + relay), ColorMatcher (per-channel gain ratios, gamma + Rec.709-luma saturation, mired white-balance, McCamy CCT), ShotListAutomation (priority-sorted cursor + auto-advance). Fixed a real TS bug: ColorMatcher's tint correction was 2·ref − slave (a duplicated +ref.tintShift copy-paste); corrected to ref − slave. 30 new tests; oya-cinematography 73 tests; fmt + clippy -D warnings clean; zero stubs; ColorMatcher + CameraHandoff cores read in full during verification.) (deterministic core ported to oya-cinematography::multicam: SMPTE timecode + drift, genlock PLL, greedy coverage assignment, viewpoint diversity, occlusion avoidance, frame-overlap geometry, stereo/360/bullet-time, exposure/focal sync, virtual-view blend. MAPF (float-string-keyed A*) + streaming/handoff/shot-list IO pending.) (✓ MAPF now portedoya-cinematography::camera_mapf::CameraMapf: prioritised multi-agent path finding (Silver 2005) with spatio-temporal 26-connected-3-D-grid A* + explicit wait-in-place + a safety_radius reservation table (float-string-keyed, matching the TS toFixed(2)), descending-priority planning so lower-priority drones route around reserved corridors, plus check_conflicts. Matches JS Math.round (floor(x+0.5), round-half-up) for grid discretisation. 5 domain tests: single-agent reaches goal, prioritised solve is conflict-free on crossing drones, conflict detection, unsolvable→∞-cost, js-round parity. fmt + clippy clean; zero stubs. REMAINING: the streaming/IO-flavoured CameraHandoff, ShotListAutomation, SynchronizedRecordingTrigger, MultiDroneShotSequencer, ColorMatcher.)
  • QP/spline numeric parity tests; differential vs TS. 2026-09-18: open for an agent now. Verify: the differential parity oracle that .github/workflows/oya-rust-premerge.yml already runs gains the QP and spline cases, comparing the Rust output with @oya/core to 1e-9.

1.10 oya-dsp (D)#

  • Scaffold; port audio-systems.ts (beamforming, AEC, spectral processing). (crate oya-dsp scaffolded: real radix-2 Cooley-Tukey FFT/IFFT (sinusoid-peak + round-trip tests), Hann/Hamming/Blackman windows, IIR low/high/band-pass filters, delay-and-sum beamforming with fractional delay. The adaptive AEC/VAD/speech-enhancement pipelines + audio I/O deferred.)
  • Real-time audio path (cpal-class) tests; latency bench. (both delivered for the in-scope DSP processing path — the far-field voice front-end (4-mic delay-and-sum beamforming → NLMS echo cancellation → FFT magnitude feature) at a 256-sample/16 kHz block (16 ms real-time deadline). latency bench benches/audio_path_bench.rs (criterion, release): fft_256 3.7 µs, magnitude_spectrum_256 4.0 µs, beamform_4mic_256 1.8 µs, aec_256 (128-tap) 56.7 µs, full_frontend_256 62.8 µs — a 16 ms block processed in 63 µs is ~255× real time. Real-time path tests tests/audio_realtime.rs: streams ~2 s of audio through the front-end and asserts every block clears the 16 ms deadline with headroom (worst block ~2.7 ms in a debug build) and the aggregate runs faster than real time (RTF ≥3× debug / ~255× release), with every output sample finite (the adaptive AEC never blows up); a second test drives a known echo path 200 blocks and proves the NLMS canceller converges (late residual energy ≥10× below the initial, stays bounded). The actual cpal device capture/playback is hardware I/O (out of scope on this box, as the crate notes — same precedent as the marked-done mavlink socket/serial seam). oya-dsp 68 unit + 2 real-time tests green; fmt + clippy -D warnings clean; adversarial stub-scan zero hits.)

1.11 Bridges & integration tests#

  • (A) oya-node-bridge (napi-rs): cdylib+rlib, build.rsnapi_build::setup(), #[napi] exports, napi build --platform --dts (pattern: uzume-node-bridge). (libs/oya/node-bridge — standalone (detached) crate so the engine workspace is unaffected; napi build produces index.<platform>.node + index.d.ts. Exposes vincenty/haversine/bearing/normalize-angle/euler→quat/crc32/ORCA. npm run build && npm test.)
  • (A) Prove one function (Vincenty distance) callable native-from-TS, bit-for-bit within tolerance (plan §10 first slice). (test_bridge.mjs loads the native .node addon and asserts vincenty/crc32/euler→quat/ORCA against the parity-oracle values — all match through the real napi boundary.)
  • (A) oya-wasm (wasm-bindgen): build via wasm-pack … --target web --out-dir dist/libs/oya/engine/wasm (pattern: uzume-control-surface-wasm). (libs/oya/wasm-bridge — standalone wasm-bindgen crate; wasm-pack build --target web --out-dir dist/libs/oya/engine/wasm produces the .wasm+.js+.d.ts (52KB wasm); node smoke test asserts vincenty/euler↔quat/ORCA/orbit/bezier/min-snap against the parity oracle.)
  • (B) Expose trajectory/preview math to the browser dashboard via oya-wasm. (exposes oya-cinematography::trajectory camera-path sampling (orbit/elliptical/crane/helix/bezier → stride-6 Float64Array [t,x,y,z,yaw,pitch]) and oya-navigation::min_snap evaluation (stride-10 [t,p,v,a]) — exactly the plot-ready arrays the dashboard needs.)
  • oya-integration-tests crate: cross-crate end-to-end (estimation→control→mavlink) in SITL. (crate libs/oya/engine/crates/oya-integration-tests — 7 REAL cross-crate e2e tests: estimation(AHRS)→control(cascaded attitude)→mavlink(codec round-trip) over a 50-step loop, navigation(A*/min-snap)→control(waypoint nav), swarm ORCA collision-free step; hand-checked end-to-end values. NOTE: runs without a simulator; full PX4/Gazebo SITL is the future extension.)
  • Adversarial stub-scan pass over every new crate before cutover (grep + read every pub/delegated fn). (comprehensive grep over all 21 engine crates' src/ returns zero actionable hits — the only matches are legitimate Munkres "dummy job/column" algorithm terminology in comments; every batch was additionally adversarial-scanned at authoring time and each public/delegated fn read.)

2. Part II — new Rust crates (libs/oya/engine/crates/*)#

2.1 oya-mapping (A)#

  • Scaffold; graph-SLAM pose-graph backend (GTSAM/iSAM2-style) with appearance-based loop closure. (implemented: crate oya-mapping — SE(2) pose-graph back-end (PoseGraph::optimize, Gauss-Newton, analytic Jacobians, gauge-anchor prior, self-contained dense LDLᵀ solve; χ² strictly decreases, square-loop closes <1e-6) + log-odds OccupancyGrid2D. Pending: incremental iSAM2 + appearance-based loop-closure detection (needs perception descriptors).) 2026-09-18: two residues. Incremental updates in the style of iSAM2 are deterministic and open for an agent now (Verify: adding a pose re-solves only the affected clique and matches the batch solution to 1e-6). Appearance-based loop closure needs descriptors and waits for OYA.G1.
  • Tiered memory STM/WM/LTM for bounded lifelong operation (RTAB-Map pattern). (oya-mapping::memory (new) — RTAB-Map memory-management model (Labbé & Michaud T-RO 2013 / JFR 2019): STM (recent, excluded from matching) → graduates oldest to WM (the bounded loop-closure candidate set) → WM→LTM forgetting transfers the lowest-weight node (ties: least-recently-accessed, then id), biased to keep rehearsed ("important") places; retrieval pulls an LTM node's neighbours back into WM on loop closure. Signature weight grows via rehearse. Hard invariants stm_len≤cap & wm_len≤cap asserted directly — the headline test feeds 10,000 observations and proves WM never exceeds budget while every node stays accounted for across the 3 tiers. 6 domain tests (incl. a fully-traced retrieval+eviction scenario); fmt + clippy -D warnings clean; crate 47 tests.)
  • Multi-session merge + single shared coordinate frame; relocalization on boot. (✓ oya-mapping::{multi_session,relocalization} — closed-form Kabsch/Umeyama SE(2) merge into one frame + least-squares boot relocalization (fail-loud under-constrained))
  • TSDF/ESDF volumetric layer (nvblox) with dynamic-object/people masking. (oya-mapping::tsdf — the nvblox-pattern dense layer. TSDF (Tsdf): a uniform 3-D voxel grid fused by projective integration — each voxel is projected into the DepthCamera, its truncated SDF updated by the running weighted average of depth(pixel) − voxel_depth (positive in free space between sensor and surface, negative just behind it). TSDF sign/value correctness is pinned by a fronto-parallel-wall test (SDF ≈ +0.1 / 0 / −0.1 at 0.1 m in front / at / behind the wall) and weighted fusion tracks new evidence. Dynamic-object/people masking is first-class: a per-pixel mask predicate skips any voxel projecting onto a masked pixel, so a person carves no phantom tunnel (test: a masked image half stays unobserved — sdf_at returns None there). ESDF (Esdf): an exact brute-force signed Euclidean distance transform to the nearest zero-crossing voxel (the reference any faster sweep validates against), giving the clearance field the oya-navigation gradient planners consume (test: distance grows ~linearly off the wall, +0.3 m at 0.3 m, negative behind). Fixed a non-cubic voxel-index collision bug before testing. 5 domain tests; oya-mapping 52 tests; fmt + clippy -D warnings clean; zero stubs. The mask SOURCE (people/dynamic-object segmentation) is the learned-perception input seam — this layer consumes a mask, it does not produce it.)
  • Multi-floor: per-floor metric submaps joined by stair/elevator transition edges with per-edge energy cost (MuNES). (✓ oya-mapping::multi_floor — submap graph + stair/elevator transition edges with per-edge energy cost + Dijkstra min-energy cross-floor route)
  • Dock/fixed-node AprilTag/UWB fiducials bound drift; bootstrap relocalization in low-texture/low-light. (oya-mapping::fiducial — a surveyed FiducialMap (id → known world Pose2) + the single SE(2) identity that is both halves: absolute_pose(obs) = T_world_fid · (T_robot_fid)⁻¹ recovers the robot's absolute world pose from one fiducial sighting, fail-loud None on an unknown id (never guesses). Bound drift: DriftBoundedEstimator dead-reckons odometry but snaps to the fiducial fix on each sighting, so error is bounded by one inter-fiducial segment, not by distance travelled — the headline test drives 95 steps with 2 % odometry scale drift and shows ~0.95 m uncorrected vs < 0.15 m fiducial-bounded (≥5× tighter). Bootstrap relocalization in low-texture/low-light is the same absolute_pose — a single fixed marker fixes the pose with zero appearance features (complements the existing oya-mapping::relocalization anchor solver + oya-ambient::uwb ranging). 4 domain tests (compose/inverse round-trip, known-pose recovery, fail-loud, drift bound); oya-mapping 56 tests; fmt + clippy -D warnings clean; zero stubs. The AprilTag/UWB marker detection (image/RF → robot_to_fiducial) is the CV/RF input seam — this consumes the measurement, it does not produce it.)
  • Tests: loop-closure correctness, map-merge consistency, relocalization accuracy. (✓ oya-mapping — loop-closure (pose_graph χ² decreases), map-merge recovers known SE(2) <1e-9, relocalization recovers known pose <1e-6 (41 tests))

2.2 oya-scenegraph (A)#

  • Scaffold; hierarchical open-vocab 3D scene graph (building→floor→room→object), Hydra+ConceptGraphs/HOV-SG. (implemented: crate oya-scenegraph::graph — Building→Floor→Room→Object node hierarchy with AABB containment, Euclidean nearest-object (label-filtered), descendant collection, root paths. Pending: open-vocab CLIP/SigLIP embedding layer (ML).) 2026-09-18: the residue is the open-vocabulary embedding layer; it waits for OYA.G1 and an embedding model admitted under OYA.G2 (SigLIP is Apache-2.0). blocked:upstream
  • Per-instance CLIP/SigLIP embeddings lifted zero-shot via SAM/Grounding-DINO multi-view association. 2026-09-18: waits for OYA.G1 and for segmentation and grounding models admitted under OYA.G2. blocked:upstream
  • Per-instance last_seen + observation-count + confidence/decay freshness fields. (✓ oya-scenegraph::memory — last_seen/observation_count/exp-decay confidence)
  • DynaMem add/remove voxel/instance change memory + LT-mapper version control. (✓ oya-scenegraph::change_memory — versioned add/remove/move op-log, state_at(version), diff(va,vb))
  • Clio Information-Bottleneck task-driven compression (per-role remember/forget). (✓ oya-scenegraph::compression — task-relevance scoring (label+proximity) prune keeping relevant / forgetting irrelevant instances)
  • Queryable spatial-memory API with freshness + uncertainty (the honest fail-loud seam). (oya-scenegraph::memoryStore::query returns Fresh{value,confidence} / Stale{last_seen,confidence} / Unknown with exponential confidence decay; never fabricates a confident answer for a decayed instance. Caller-supplied ticks (no clock).)
  • Tests: instance grounding, change detection, stale-query honesty. (✓ oya-scenegraph grounding + fail-loud stale query + svc-home-map change-detection tests)

2.3 oya-floorcare (F)#

  • Scaffold; boustrophedon cellular-decomposition coverage planner with anytime replanning. (implemented: crate oya-floorcareBoustrophedonPlanner (vertical-strip cellular decomposition, serpentine sweep, obstacle-skipping; covers every reachable free cell, coverage_fraction tests) + dirt-adaptive speed/suction control + re-clean scheduler.) (✓ anytime replanning COMPLETE — oya-floorcare::dynamic::DynamicCoveragePlanner: incremental coverage state (remembers covered cells + live occupancy via add_obstacle/clear_obstacle), and replan(current) floods 8-connected free space from the pose then runs one boustrophedon pass over only the reachable ∧ uncovered cells — O(cells), immediately executable, never restarts. Cells a new obstacle isolates are excluded until reachable again; an interrupted sweep resumes from the remainder. 5 domain tests (skips covered+new obstacle, isolated-region exclusion+reacquisition, interrupted-resume, occupied-pose fail-safe); fmt + clippy -D warnings clean; crate 29 tests.)
  • Matrix-style multi-pass over high-dirt cells. (✓ oya-floorcare reclean_schedule (descending-dirt multi-pass))
  • Multi-robot coverage partition with failure-reabsorption (resilient-CPP). (oya-floorcare::partition::MultiRobotCoveragePartitionVoronoi tessellation of free space across K robot home poses (squared-Euclidean nearest-start, index tie-break): a total assignment, so regions are disjoint and their union is exactly the free space (completeness by construction). fail_robot(robot, covered) reabsorbs the failed unit's uncovered remainder into the nearest surviving units (already-cleaned cells released), preserving the resilient-CPP invariant covers_all_free. robot_path boustrophedons each unit's region. 8 domain tests (disjoint+complete partition, Voronoi correctness, balanced split, per-robot full coverage, reabsorption→nearest-survivor with completeness preserved, total-fleet-failure orphaning); fmt + clippy -D warnings clean.)
  • Closed-loop adaptive controller: dirt-signal (acoustic Dirt Detect + turbidity/DirtSense) → suction/water/scrub/pass-count state machine. (✓ oya-floorcare::cleaning DirtAdaptiveController (dirt→speed/suction/pass-count))
  • Carpet/low-pile-rug detection (multi-modal, not height-only, §15.2) → mop auto-lift. (oya-floorcare::carpet_detection — a deterministic multi-modal sensor-fusion classifier. Four cues (SurfaceFeatures): height above the bare floor (strong for thick carpet, weak for low-pile rugs), acoustic reflectivity (a Dirt-Detect/DirtSense-class sensor — carpet damps sound, hard floor reflects), drive current (carpet's rolling resistance raises wheel current above the calibrated baseline), optical texture (fibrous↔smooth). Each maps to bounded [0,1] carpet evidence; the fused carpet_score is a weight-normalized blend with height deliberately down-weighted so the acoustic+current+texture cues flag a rug the height channel misses — the literal "not height-only". classify → HardFloor/LowPileRug/Carpet (score gate, then height splits pile vs rug) and should_lift_mop raises the mop on any carpet/rug so it is never wetted. 5 domain tests incl. the headline low-pile 3 mm rug that a height-only rule (<5 mm ⇒ hard) wet-mops, but the multi-modal detector catches and lifts, plus no-single-cue-dominates (a hard threshold bump is not carpet; a flat absorptive+draggy+fibrous rug is). Deterministic fusion; the raw sensors are the hardware seam. oya-floorcare 42 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Tests: provable free-space coverage completeness; partition reabsorption on simulated unit failure. (both proven: oya-floorcare::coverage tests assert single-robot coverage completeness (coverage_fraction == 1.0, every reachable free cell visited exactly once, obstacles never stepped on — open grid, obstacle-column split, partial-row connectivity events, isolated regions); oya-floorcare::partition tests assert multi-robot partition union = all free + reabsorption on simulated unit failure preserves covers_all_free (failure_reabsorption_preserves_completeness, reabsorption_goes_to_nearest_survivor, total_fleet_failure_orphans_uncovered_cells). Crate 37 tests green.)

2.4 oya-manipulation (C)#

  • Scaffold; model-based 6-DoF grasp generation (Contact-GraspNet/AnyGrasp) from wrist+head depth. (implemented: crate oya-manipulation — analytic 2-link/3-link IK (reachability-gated, fail-loud), antipodal-grasp synthesis (double-friction-cone test), force-closure + grasp-quality, reachability gating; round-trip + force-closure tests. Pending: the learned 6-DoF predictor (ML) from depth.) 2026-09-18: the residue is the learned 6-DoF predictor; it waits for OYA.G1 and OYA.G2. The analytic grasp synthesis stays the fallback that section 6.3 requires. blocked:upstream
  • Graspability confidence scoring + reachability gating (fail-loud below threshold). (✓ svc-manipulation grasp-gate (confidence+reachability, fail-loud escalate) + oya-manipulation force-closure/quality)
  • Whole-body MPC with manipulability-/reachability-aware base placement. (oya-manipulation::whole_body — mobile-manipulator (holonomic base + 2-link arm, 4-DOF redundant) whole-body control: the 2×4 whole-body Jacobian [I₂|J_arm], Yoshikawa manipulability w=|l₁l₂ sin θ₂| (peak at θ₂=±90°), closed-form manipulability-optimal base placement (optimal_base_placement parks at reach r*=√(l₁²+l₂²) nearest the current base → peak w=l₁l₂), and a receding-horizon resolved-rate MPC (WholeBodyController::step/converge): damped-least-squares whole-body-Jacobian inverse drives the ee to target while a manipulability-gradient term projected through the nullspace (I−J⁺J) shifts the base to keep the arm dexterous; per-DOF velocity saturation. 6 domain tests: manipulability peak, placement reaches target at peak w, MPC convergence, elbow-singularity escape (w recovers 1e-4→0.3+), velocity limits, min-base-motion placement. fmt + clippy -D warnings clean; crate 20 tests.)
  • Eye-in-hand (D405-class) closed-loop final-approach servoing. (✓ the deterministic servoing control law is built in oya-manipulation::visual_servo::EyeInHandServo — a position-based visual servo (PBVS): given the target's pose in the EE frame, the angular command nulls the orientation error via its shortest-arc axis-angle rotation vector ω=λ*ω·θk̂, and the linear command drives toward the target v=λ*v·t(max-speed clamped), decelerating into contact (scaled by‖t‖/decel_distanceinside the window) and alignment-gated (forward approach suppressed while badly misaligned, so the gripper aligns before committing).rotation_vector(shortest-arc),is_converged. 6 domain tests: 90°→π/2 rotvec + shortest-arc 350°→−10°, approach toward target, rotation nulling, decel-into-contact scaling, alignment-gate suppression, convergence. oya-manipulation 32 tests; fmt + clippy -D warnings clean; zero stubs. PENDING (CV/sensor seam): the D405 wrist depth camera + detection/pose-estimation that produces the relative-pose feedback.) 2026-09-18: the residue is the pose feedback. In simulation a rendered depth image stands in for the wrist camera (OYA.G3); the estimator itself waits for OYA.G1. blocked:upstream
  • Tactile/force slip detection + grip-force regulation (GelSight/Digit-class) + series-elastic compliance. (✓ the deterministic force-control core is built in oya-manipulation::grip_control: friction-cone slip detection (friction_cone_margin = 1 − F_t/(μ·F_n), is_slipping when the tangential load leaves the Coulomb cone), grip-force regulation (GripForceRegulator: commands F_n = F_t/(μ(1−m*)) to hold the load at a target slip margin, clamped between a min holding force and an anti-crush max, reporting Tighten/Loosen/Hold), and series-elastic compliance (SeriesElasticActuator: F=k·Δ force-from-deflection, motor set-point θ_link+F/k, compliant displacement). 6 domain tests (margin 1−5/7, required-grip 12.5 holds exactly at margin, tighten-on-slip, loosen-anti-crush, max cap, SEA 1000 N/m·0.01 m=10 N). fmt + clippy -D warnings clean; zero stubs. PENDING (ML/CV seam): the GelSight/Digit tactile-image front end (marker-field deformation → contact force/shear) that produces the force inputs.) 2026-09-18: the tactile image front end needs a GelSight or Digit sensor, or recordings from one; the project has neither. blocked:hardware
  • ACT/flow-matching action-chunk execution with Real-Time Chunking (freeze-and-inpaint). (✓ the deterministic Real-Time Chunking scheduler is built in oya-manipulation::real_time_chunking::RealTimeChunker — the freeze-and-inpaint half that turns a stream of overlapping, inference-latent action chunks into one continuous jitter-tolerant action stream: ingest a freshly-inferred chunk freezes the first freeze_steps (committed during inference latency, kept verbatim → no step jump at the swap), inpaints the transition (cross-fade old-tail→new over blend_steps), then follows the new chunk; action_at(now) samples/clamps the active chunk and is continuous across ingest. 5 domain tests: sample/clamp, continuity at the swap instant (a wildly different new chunk doesn't jump the commanded action), freeze→blend(1/3,2/3)→follow, ingest-without-active starts, empty-ingest no-op. oya-manipulation 37 tests; fmt + clippy -D warnings clean; zero stubs. PENDING (ML seam): the ACT / flow-matching action policy that generates the chunks.) 2026-09-18: the residue is the policy that generates the chunks; it waits for OYA.G1 and a policy admitted under OYA.G2. blocked:upstream
  • Articulated-object skill (door/drawer/cabinet/fridge via handle/affordance detection, §15.1). (the deterministic articulation kinematics + constraint-respecting open trajectories are built in oya-manipulation::articulated. ObjectKind (Door/CabinetDoor/Fridge/Oven/Drawer) → JointType (revolute/prismatic). Revolute (RevoluteObject): hinge point+axis + handle, with Rodrigues handle_position(angle), handle_radius (measured to the axis line, off-origin hinges handled), the on-arc open trajectory (every waypoint provably at constant radius in the hinge plane — not a chord), and the unit pull_direction = the arc tangent axis × radial the compliant controller must follow (verified ⟂ to the radius; +x handle opens toward +y about +z). Prismatic (PrismaticObject): slide axis + handle, on-line open trajectory (colinear, y/z fixed) with a constant axis pull direction. Both fail-loud PastLimit past the joint stop (door max angle / drawer max travel, including closing past closed) and DegenerateGeometry on a zero axis / handle-on-axis. Pulling off-constraint jams the joint, so the on-arc/line path + tangent is the whole point. 8 domain tests (kind→joint map, constant-radius arc + endpoints, tangent pull, off-axis hinge, colinear drawer, both limit refusals). The handle/affordance detection (hinge axis + handle pose + object kind from vision) is the learned-perception seam. oya-manipulation 45 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Tests: grasp success on YCB-class set; verified contact before "success"; ISO/TS 15066 force caps. 2026-09-18: grasp success is measured in the simulator of OYA.G3 on the public YCB models; the ISO/TS 15066 force caps are already asserted in oya-safety. blocked:upstream

2.5 oya-locomotion (C)#

  • Scaffold; per-mode cost-of-transport energy models (roll/walk/perch/fly), calibrated power curves. (oya-locomotion::cost_of_transportPowerModel per mode (rolling-resistance Roll, gait Walk, momentum-theory hover Fly, idle Perch), dimensionless COT = P/(m·g·v), per-edge energy = P·d/v; hand-computed-value tests.)
  • Mode-arbitration planner (the "roll unless flight required" brain) over map per-edge traversability/energy/risk/noise. (oya-locomotion::arbitration::plan — Dijkstra over per-edge traversal energy, picks the cheapest allowed ground mode and only flies when no ground mode is allowed; fail-loud None past the energy budget. Tests confirm ground-route preference + Fly-only-when-required.)
  • Reserve-to-return hard constraint vs nearest free dock (charger-contention aware, temp-compensated SoH). (oya-locomotion::dock_reservation BUILT (nearest reachable FREE dock, contention-aware, energy-feasibility fail-loud).) (✓ temp-compensated SoH COMPLETE — oya-locomotion::battery_thermal: piecewise-linear Li-ion capacity_temperature_factor (≈100% @25°C, 0.85 @0°C, 0.50 @−20°C + high-temp protective derate, anchored to 18650-class discharge-capacity-vs-temp data), BatteryThermalStateusable_energy_j = nominal·SoH·SoC·tempFactor + effective_soh = SoH·tempFactor, and reserve_nearest_free_dock_temp_compensated feeds that into the existing gate. Key test proves a cold battery flips a warm-feasible dock to fail-loud NoFreeDockReachable (0.75·trip < trip). 4 tests; crate 51.)
  • Online morphing-state estimation (mass/CoG/inertia) + INDI/NMPC control allocation for hybrid units. (oya-locomotion::morphing_estimation BUILT (recursive-LS mass + CoG + parallel-axis inertia).) (✓ INDI control allocation COMPLETE — oya-locomotion::indi: indi_torque_increment = the rotational INDI law Δτ = I·(ν_des−ν_meas) using the morphing-estimated inertia (incremental about measured accel, so ω×Iω/disturbances cancel), and IndiAllocator (G = I⁻¹B) for over-actuated units computing the min-norm Δu = G⁺Δν via the right pseudo-inverse Gᵀ(GGᵀ)⁻¹ — re-derives whenever morphing updates I. 6 tests: exact IΔν, measured-accel cancellation, payload doubles required torque, allocation reproduces target Δν, over-actuated min-norm split (2.0→1.0+1.0), singular/under-actuated fail-loud. Crate 57 tests; fmt + clippy -D warnings clean.)
  • Stair-climb mode cost model (§15.1) — ProLeap/wheeled-legged; encode per-unit transition-edge feasibility. (✓ oya-locomotion::stair_climb — per-step rise/run energy cost + feasibility (refuse rise>max step) transition edge)
  • Command-conditioned RL (Disney BD-X pattern) for balance on legged/hybrid units. 2026-09-18: needs the simulator of OYA.G3 to train in, and a training budget; quote it and ask before any rented compute. blocked:upstream
  • Tests: CoT model validation vs measured curves; flight only when no ground route + budget allows. 2026-09-18: the routing rule (fly only when no ground route exists and the budget allows) is a deterministic test and is open now. Validating the cost-of-transport model against measured curves needs a robot to measure; use published curves, cite them, and say so.

2.6 oya-fleet (D)#

  • Scaffold; auction/CBBA capability-+battery-aware bidding (hard capability gate: never ask a drone to grasp / a rover to climb stairs). (implemented: crate oya-fleet — real CBBA allocate (greedy bundle-building by discounted marginal score + consensus/outbid conflict resolution to a conflict-free assignment; hard capability gate + battery-feasibility; deterministic tie-breaks; conflict-free + higher-bidder-wins tests). Pending: distributed/networked consensus across real comms.) (✓ oya-fleet CBBA + svc-fleet-orchestrator (hard capability gate, conflict-free))
  • MILP/coalition solver for long-horizon missions with recharge/relay. (✓ oya-fleet::coalition — exact branch-and-bound min-cost coalition set-cover (capability+battery gated, fail-loud uncoverable); 29 fleet tests)
  • MAPF traffic deconfliction (PIBT/LaCAM*) over shared doorways/halls/stairs (+ doors as shared resources, §15.1). (✓ oya-fleet::mapf — real PIBT (priority-inheritance + backtracking), collision-free + deadlock-free past 3 agents, capacity-1 doorways never double-occupied)
  • DeepFleet-style learned congestion forecaster (once fleet logs exist). 2026-09-18: the item says it itself: a learned forecaster needs fleet logs, and there is no fleet. blocked:corpus
  • CTDE MARL (QMIX/MAPPO) edge-executable policies (server-independent for safety). 2026-09-18: multi-agent training needs the simulator of OYA.G3 and a training budget. blocked:upstream
  • Tests: allocation optimality on scenarios; deadlock-free past 3 units; capability-constraint enforcement. (✓ oya-fleet allocation+capability tests + svc-fleet-orchestrator space-time deconfliction tests)

2.7 oya-energy (E)#

  • Scaffold; SOC/SOH estimation (temp-compensated coulomb counting + voltage/temp + online SOH). (crate oya-energySocEstimator (coulomb counting + OCV-curve blend at rest; exact-drop tests) + SohEstimator (cycle-fade) + ReturnToDockFsm (energy-to-return + reserve thresholds).) (✓ temperature compensation COMPLETE — oya-energy::soc: capacity_temp_factor (Li-ion usable-capacity vs temp, 1.0 @25°C reference so the comp'd update reduces exactly to plain CC at reference) scales the coulomb denominator (cold ⇒ a charge moves SOC more), and asymmetric coulombic_efficiency (discharge lossless; charge acceptance falls to 0.55 @−20°C, plating regime) is applied to charge current; update_with_temperature combines both. 6 tests incl. cold-discharge-depletes-faster and cold-charging-stores-less. Crate 84 tests.)
  • Multi-threshold return-to-dock state machine (CRITICAL/LOW/HIGH). (✓ oya-energy::dock ReturnToDockFsm (Working/ShouldReturn/MustReturn) + svc-energy)
  • Opportunistic partial-charge banding (~40–85% SOC). (oya-energy::charge_band::ChargeBand — the longevity band (lower 0.40 floor / upper 0.85 routine ceiling / 0.60 idle storage SOC). adaptive_target(required_soc, margin): idle ⇒ storage 0.60 (minimize calendar aging); a mission that fits the band ⇒ charge only to 0.85 (not 100%); a long mission ⇒ opportunistically top up to exactly what it needs, capped at full — exceeds the band only as much as range demands. within_band/below_floor/above_ceiling predicates; constructor orders+clamps. 6 tests.)
  • PRCP ILP minimum-dock sizing; battery-health-aware charge co-scheduling (McCormick-linearized wear). (oya-energy::dock_sizing BUILT (interval-partition min-docks = peak overlap).) (✓ McCormick-linearized wear co-scheduling COMPLETE — oya-energy::wear: McCormickEnvelope brackets the bilinear wear term w=x·y (charge-rate × SOC-stress) over its box with the convex under-/concave over-estimators — verified to bracket the true product across a sampled grid and be exact at the 4 corners; soc_stress (monotone, charging-near-full damages more) + charge_wear; co_schedule_wear_aware distributes a shared charge budget to minimize total wear by front-loading the lowest-SOC packs (provably optimal for the linear-in-energy objective), beating an even split. 6 tests.)
  • Battery-swap orchestration math; UAV perch-overwatch energy model. (oya-energy::battery_swap BUILT (bay/queue throughput + demand-met).) (✓ UAV perch-overwatch energy model COMPLETE — oya-energy::perch_overwatch::PerchOverwatchModel: round-trip cruise energy + one-time perch transition + perched-power watch (motors OFF) gives mission_energy_j; max_overwatch_s returns the longest watch sustainable under an energy budget+reserve, fail-loud None when the round trip+perch can't be afforded; perch_vs_hover_endurance_ratio = hover/perched (≈18× for the modelled UAV). 6 tests incl. perching uses ≫100 kJ less than hovering for a 10-min watch. Crate 84 tests; fmt + clippy -D warnings clean.)
  • Grid-aware scheduling (Matter 1.5 tariff/carbon) + fleet-as-backup-power logic (§15.7). (✓ oya-energy::grid_scheduling — greedy cheapest/lowest-carbon slot scheduling within deadline+power + fleet_backup_power (Σ usable-above-reserve))
  • Tests: no mission without verified reserve-to-free-dock; SoC estimate accuracy; dock-sizing correctness. (all three categories proven & green: reserve-to-free-dockoya-locomotion::dock_reservation fails_loud_when_no_free_dock_is_energy_reachable / energy_gate_skips_unreachable_closer_free_dock / picks_nearest_free_dock_skipping_a_closer_occupied_one + battery_thermal cold-battery-flips-infeasible (typed NoFreeDockReachable, never a fabricated dock); SoC accuracyoya-energy::soc exact 0.1-per-Ah coulomb drop, OCV knee/midpoint lookup, temp-compensated cold depletion; dock-sizing correctnessoya-energy::dock_sizing peak-overlap min-docks (mutual overlap→3, staggered→1, mid-peak, mixed→2). oya-energy 84 + oya-locomotion 57 tests green.)

2.8 oya-ambient (B)#

  • Scaffold; mmWave FMCW radar pipeline (range/Doppler FFT → CFAR → cluster → track → fall/stationary-presence) — point-cloud only, raw RF never leaves node. (the full deterministic pipeline is built across oya-ambient::{range_doppler,detection,presence} (+ the pre-existing cfar). range/Doppler FFT (range_doppler): a 2-D FFT (range FFT per chirp → Doppler FFT across chirps, fft-shifted) over an n_chirps×n_samples FMCW frame, with RadarConfig bin↔physical conversions (R=c·f_b/2S, v=λ·f_d/2); a synthesize_frame signal model (f_b=2SR/c, Δφ=4πv·T_c/λ) lets tests prove the map recovers a synthetic target's range bin AND velocity bit-exactly, resolves two targets, and centres zero-Doppler. CFAR (existing CA-CFAR) over the range profile. cluster (detection): range×velocity DBSCAN merges an extended target's detections into one power-weighted centroid (lone points → noise). track: an α-β constant-velocity RadarTracker predicts, gates+associates, spawns, and ages out tracks (follows a −2 m/s approach, drops a lost target, separates two). fall/stationary-presence (presence): the headline micro-Doppler vital-sign detector (StationaryPresenceDetector) accumulates per-frame phase and a direct band-DFT flags an occupant by breathing-band (0.1–0.5 Hz) energy with zero gross motion — the Aqara stationary-occupant false-absence this is built to beat (test: 0.3 Hz breathing → present; out-of-band/DC → empty); a deterministic FallDetector confirms a fall only on a velocity-spike transient followed by sustained stillness (a transient-then-motion "sat down quickly" is correctly not a fall; getting up clears it). Point-cloud only — only target/track descriptors leave the stage, never raw RF. oya-ambient 32 tests (18 new); fmt + clippy -D warnings clean; adversarial stub-scan zero hits. The learned fall classifier and the labeled-set sensitivity/specificity tests (the separate Tests box) remain ML/data work.)
  • Wi-Fi CSI (802.11bf) device-free presence model. (oya-ambient::csi — a deterministic device-free presence model over per-subcarrier complex CSI (CsiFrame: H[k]=a_k·e^{jφ_k}). A sliding window of frames yields two features: motion = the mean per-subcarrier temporal coefficient of variation σ/μ of amplitude (scale-invariant — large when gross movement stirs the multipath), and breathing = peak band energy (0.1–0.5 Hz) of the per-frame mean-amplitude series via a direct mean-removed band DFT (the chest-wall micro-motion of a still occupant — same vital-sign idea as the radar presence detector, distinct Wi-Fi modality). classify returns Moving (motion dominates) / Stationary (breathing signature, no gross motion — the device-free still-occupant case that beats PIR false-absence) / Empty, gated on a half-full buffer. 5 domain tests: empty room (flat CSI + out-of-band jitter → Empty), 4% 0.3 Hz breathing → Stationary, irregular swings → Moving, buffer-fill gate, amplitude helpers (3-4-5). Derived features only — no raw RF, no learned model. oya-ambient 37 tests; fmt + clippy -D warnings clean; zero stubs.)
  • UWB TWR/TDoA/AoA ranging vs dock anchors; BLE Channel Sounding fallback. (oya-ambient::uwb — the full deterministic RF-ranging stack against fixed dock anchors. TWR: ss_twr_distance (single-sided, ToF=(t_round−t_reply)/2) + ds_twr_distance (double-sided, ToF=(R_aR_b−D_aD_b)/(R_a+R_b+D_a+D_b) — cancels the two radios' clock-frequency offset). Trilateration (trilaterate): linearizes |x−p_i|²=r_i² by subtracting the reference anchor and solves the 3×3 normal equations (Cramer) — recovers a known target from 4 anchors to <1e-6, fail-loud None under-constrained. TDoA (tdoa_multilaterate): Chan/Fang-style 4-unknown [x,y,z,r_ref] linearization (r_i−r_ref=c·Δt_i) solved by Gaussian-elimination LS over ≥5 anchors — recovers a known target to <1e-6. AoA (aoa_from_phase): θ=asin(Δφ·λ/(2π·d)) from a 2-element array, fail-loud None past the unambiguous FoV (sinθ>1, spacing>λ/2). BLE Channel Sounding fallback (channel_sounding_distance): phase-slope ranging d=c·(−dφ/df)/(4π) via LS over multi-tone (freq, phase) samples (recovers 5 m from a 6-tone sweep to <1e-6). 8 domain tests (hand-built geometries, each recovers the true distance/angle/position; degenerate inputs → None/0). Self-contained (oya-math only); closed-form/LS deterministic geometry. oya-ambient 45 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Factor-graph fusion core ingesting radar/CSI/UWB/IMU/odometry/VIO → one home state (async heterogeneous, not a single global EKF). (oya-ambient::fusion — a bipartite factor graph (variable nodes = 2-D-position + scalar-bias; factors = measurements) minimising Σ eᵀΩe by Gauss-Newton with backtracking line search + in-crate dense solve. It is the genuine async-heterogeneous alternative to a single global EKF: each factor touches only the variables it constrains and out-of-order arrivals just add rows. The measurement vocabulary now covers every listed modality: RangeToAnchor (UWB absolute range), RangeDifference (UWB/acoustic TDoA — |p−aᵢ|−|p−aⱼ|), Bearing (radar AoA / mic-array DoA / UWB AoA — a ±π-wrapped atan2 residual), Relative (IMU/odometry/VIO displacement), and Prior (VIO absolute position, or a CSI-presence weak zone prior). The headline test fuses five distinct modalities (UWB range + radar AoA + IMU/VIO odometry + UWB TDoA + VIO prior) across two instants into ONE joint 4-DOF state and recovers both to <1e-3; the two new factors' analytic Jacobians are pinned to central differences. trilateration still converges <1e-6, residual strictly decreases. The front-end sensor modules that produce these measurements live as siblings (range_doppler/detection/presence, csi, uwb, cfar); the real-time streaming adapters that pump their outputs into the graph are deployment glue. oya-ambient 48 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Cross-modal anti-spoofing consistency (security requirement, §15.5). (✓ oya-ambient + @oya/security::anti-spoofing (>=2 corroborating modalities))
  • Tests: fall sensitivity/specificity vs labeled set; presence accuracy on stationary occupants (the Aqara failure case). 2026-09-18: needs a labelled fall and presence set for these sensors; none is licensed to the project. blocked:corpus

2.9 oya-safety (C)#

  • Scaffold as an isolated high-integrity process (separate from autonomy/LLM stack; dual-channel, Cat 3/PLd or SIL2 target). (the dual-channel voting core — the Cat-3/PLd/SIL2 logic the isolated process runs — is built in oya-safety::high_integrity::DualChannelMonitor: two diverse independent channels, de-energise-to-trip (actuation Enabled only when both channels are healthy, watchdog-fresh, and agree safe), with three fail-safe trip paths — HazardDemand (both unsafe, auto-recovers), Discrepancy (channels disagree → the cross-monitor caught a channel that failed to the wrong answer, latched), ChannelFault (unhealthy or watchdog-stale, latched). 8 domain tests including the defining Category-3 single-fault property (every single-channel failure mode — fails-unsafe, fails-wrong-"safe", goes silent/stale, goes unhealthy — reaches a safe stop) and the diverse-redundancy case where a faulty "safe" channel cannot mask a real hazard. oya-safety 120 tests; fmt + clippy -D warnings clean; zero stubs. Left unchecked: the headline deliverable is the isolated process itself — OS-level memory-protected, dual-MCU separation from the autonomy/LLM stack — which is runtime/deployment architecture, not library code; this delivers the high-integrity logic that runs inside it.) 2026-09-18: the part an agent can build is operating-system isolation on Linux: the monitor as its own binary and process, no memory shared with the autonomy stack, a heartbeat watchdog, and de-energise on heartbeat loss. Verify: an integration test kills the autonomy process and sees the safe state within the deadline, and a faulted monitor channel cannot hold the outputs energised. Separate microcontrollers are the hardware workstream this file's header puts out of scope.
  • Speed-and-Separation Monitoring (R15.08/ISO 10218-2) safety-field logic. (implemented: oya_safety::ssm — ISO/TS 15066 protective_separation (Sp = Sh+Sr+Ss+C+Zd+Zr) + max_robot_speed speed-scaling inverse (STOP below floor); hand-computed-value tests. Pending: 2D/3D safety-field rasterization + sensor wiring.) (✓ oya-safety::ssm protective-separation + speed-scaling)
  • Power-and-Force-Limiting (ISO/TS 15066) per-body-region momentum caps via current/torque sensing. (implemented: oya_safety::pfl — reduced-mass μ, transient contact energy E=½μv², max_contact_speed=√(2E/μ), per-body-region energy-limit table + max_speed_for_region. Pending: live current/torque-sensor momentum estimation.) (✓ oya-safety::pfl reduced-mass + E=½μv² + per-region max speed)
  • CBF/MPC shield + safe-recovery substitution; CBF-RL boundary constraints. (oya-safety::cbf — single-step CBF shield (closed-form min-norm projection onto ∇h·u ≥ −α·h).) (✓ COMPLETE — oya-safety::predictive: MPC shield PredictiveSafetyShield for a momentum (double-integrator p̈=u, ‖u‖≤a_max) plant — rolls the candidate accel forward one step then simulates a max-braking trajectory to a full stop, checking the barrier throughout (catches inevitable-collision states a single-step CBF misses because of velocity relative-degree); safe-recovery substitution (SafeRecovery::Brake/Retreat) applied when the braking trajectory would breach; CBF-RL boundary constraint SafeActionConstraint exposing the safe-action half-space {u: ∇h·u ≥ −αh} that a learned policy must satisfy, with is_satisfied/slack/project (min-norm projection = the deterministic CBF-RL safety layer). 7 tests incl. a 2000-step forward-invariance rollout (barrier never breached under relentless inward push) + boundary projection-to-edge. fmt + clippy -D warnings clean; crate 99 tests.)
  • OOD/hallucination filter (multi-view confirmation before any detection persists; Bayesian uncertainty). (oya-safety::ood_filter — a detection may only persist (drive actuation) once it is both in-distribution and multi-view confirmed: (1) OOD gate InDistributionModel rejects features whose squared Mahalanobis distance to a diagonal-Gaussian model exceeds a χ² cutoff (mismatched feature dims ⇒ ∞ ⇒ OOD); an OOD observation is rejected and adds no evidence so a hallucination can't accumulate; (2) Bayesian multi-view confirmation MultiViewConfirmation fuses per-view confidences via the standard independent-classifier log-odds combination Σ logit(cᵢ)−(n−1)·logit(prior) and confirms only when the fused posterior ≥ threshold andmin_views distinct views (so a single high-confidence view can never confirm), with stale-evidence pruning. OodHallucinationFilter::submit returns a typed persist/in-distribution/confirmed/posterior verdict. 8 domain tests incl. a confident single-view hallucination / OOD input never persists and Bayesian-formula exactness; fmt + clippy -D warnings clean; crate 107 tests.)
  • Geofenced no-go and no-record zones enforced in both planner and perception pipeline. (✓ @oya/privacy::no-record-zones enforcePlan (planner) + enforceCapture (perception))
  • Discard-and-log path for out-of-bounds commands (not E-stop spam). (✓ svc-flight-gateway fail-closed command-gate (reject+reason, no e-stop spam) + safety-conformance gate)
  • Tests: governor demonstrably vetoes an out-of-envelope VLA command; force caps vs published thresholds. (✓ svc-assistant safety-gate vetoes motor/OOB (tested) + oya-safety::pfl force-cap tests)

2.10 oya-comms (A)#

  • Scaffold; Zenoh peer-to-peer/mesh transport (partition-tolerant). (implemented the deterministic protocol logic in oya-comms: gossip epidemic dissemination (dedup + round-count convergence) and a bandwidth-aware scheduler (value-density budgeting). Pending: the actual Zenoh transport binding.) 2026-09-18: open for an agent under the install-first rule: the zenoh crate is open source. Bind the gossip and the scheduler to it. Verify: two peers in one test exchange over loopback, a partition is healed without duplicate delivery, and the crate builds with the binding behind a feature so the deterministic core still tests alone.
  • Bandwidth-aware compressed descriptor/feature exchange (semantics over the wire, never raw clouds/pixels). (✓ oya-comms::descriptor_exchange — scalar quantization (quantize→dequantize + error bound) + budget selection + raw-frame refusal (semantics-only))
  • DDS-Security/SROS2 hardening (per-node X.509 identity, AES-GCM, revocation/namespace fixes beyond stock SROS2). (✓ per-node Ed25519 X.509 identity + AES-256-GCM (@oya/security) + deny-by-default namespace ACL with revocation (oya-comms::access_control))
  • PTP/IEEE-1588 sub-ms time sync across docks/nodes. (implemented: oya-comms::timesync — two-way offset/delay estimation offset=((t2-t1)-(t4-t3))/2, delay=((t4-t1)-(t3-t2))/2, + EMA clock-discipline servo; hand-computed symmetric/asymmetric tests. Pending: cross-node deployment over the real transport.) (✓ oya-comms::timesync two-way offset/delay + EMA servo)
  • Tests: drift under flaky-Wi-Fi sim; partition tolerance; auth/identity enforcement. (all three delivered as deterministic integration sims in oya-comms/tests/resilience_sim.rs (seeded-LCG link, no rand/clock). drift under flaky-Wi-Fi: a master/slave pair whose true offset RAMPS (+0.2 ms/exchange) over a 20 ms-one-way link with ±10 ms forward/return ASYMMETRY, up-to-40 ms congestion spikes, and ~30% packet loss (servo coasts on drops); the four PTP timestamps are built from the model so the raw estimate is provably off_k + (d_f−d_r)/2. The ClockSyncFilter EMA servo cuts tracking RMS ≥2× vs raw (measured 6.9 ms → 2.5 ms) and its error stays bounded (max 6 ms, asserted < 20 ms) despite ~64 ms of total drift — and is bit-deterministic per seed. partition tolerance: a gossip mesh split into two bridge-less clusters confines each rumour to its own side; healing with a single bridge link floods both rumours to all 6 nodes (eventual consistency) with the dedup invariant intact (every node one first-seen bucket, redeliveries suppressed). auth/identity enforcement: an end-to-end admission+compromise scenario over the namespace ACL — legit traffic allowed, deny-by-default for peer-namespace lateral movement / gateway impersonation / unknown intruder, then a revocation kill-switch cuts a compromised drone off from even its own previously-granted topics (revocation dominates) while peers are unaffected, and reinstatement restores exactly the prior grant. oya-comms 65 unit + 4 sim tests green; fmt + clippy -D warnings clean; adversarial stub-scan zero hits.)

3. TypeScript libraries (libs/oya/*, libs/contracts/*, libs/proto/*)#

3.1 Domain infra libs (A) (mirror libs/lilith/*)#

  • @oya/common — shared types/constants/utilities. (new package libs/oya/common@oya/common: Result<T,E>, exact unit conversions, GPS/bbox geo helpers, UUIDv4 validator + branded ids, domain constants; 19 vitest tests, tsc clean.)
  • @oya/service-lib — db connection manager, config schema, auth middleware, health checks, circuit breakers. (new package libs/oya/service-lib: DONE — clock-injected circuit breaker (Closed/Open/HalfOpen), retry/backoff (capped geometric + jitter), zod config schema + fail-loud loadConfig, worst-wins health aggregation; 31 vitest tests, tsc clean. PENDING: db connection manager + auth middleware (need pg/jwt deps).) (✓ COMPLETE — added DbConnectionManager (pg pool + transactions + healthCheck, injectable) + JWT auth-middleware (requireAuth/requireRole, fail-closed); 74 tests)
  • @oya/fastify-core — Fastify setup, error handlers, graceful shutdown. (new libs/oya/fastify-core: createOyaServer (structured error handler that scrubs 5xx, 404 handler, /health, request-id propagation, body limits) + registerGracefulShutdown (injected signal hooks, drain→close). 17 tests via fastify.inject.)
  • @oya/event-publishercreateEventBus({sourceDomain:'oya'}); typed OyaEventTypes + publish helpers. (new libs/oya/event-publisher: typed in-memory bus, OyaEventTypes registry (telemetry/mission/fleet/dock/safety) with zod-validated payloads from @oshun/contracts/oya, per-event publish helpers (fail-loud on invalid), caller-supplied id/now (clock-free). 16 tests.)
  • @oya/event-handlers — subscribe to cross-domain events. (new libs/oya/event-handlers: typed reducers over OyaEventTypes (mission stats, fleet task-index, telemetry cache, latched safety e-stop that gates allocation) + registerOyaHandlers. 18 tests proving cross-event behavior (e-stop latch gates a later allocation).)
  • @oya/sdk — client SDK for external consumers. (new libs/oya/sdk: OyaClient (injectable fetch) with typed getTelemetry/listMissions/createMission/getMission/getFleetState/requestCharge over /v1/..., zod response validation (fail-loud), typed OyaApiError on non-2xx. 16 tests, mock-fetch at the network boundary.)
  • @oya/database — schema + data-access (Prisma per @yemaya/database, or pg per @lilith/service-lib); migrations for missions/flights/telemetry/maps/fleet/consumables. (new libs/oya/database: real PostgreSQL DDL + ordered MIGRATIONS for all six tables, zod row schemas from @oshun/contracts/oya, parameterized-SQL repositories (Mission/Telemetry/Fleet) over a QueryExecutor seam (pg-ready) with an in-memory test double. 25 tests.)

3.2 Contracts (A) (libs/contracts/src/oya, libs/proto/oya)#

  • Zod + proto: Telemetry, Control, Mission, FlightPlan, Geotag. (zod DONE in @oshun/contracts/oya (telemetry.ts + mission.ts, strict, round-trip tested, coherent with oya-types); proto generation pending.) (✓ proto now generated — libs/proto/src/oya/oya.proto (proto3, oshun.oya.v1) mirrors the zod contracts; ts-proto codegen valid)
  • FleetState / TaskBid / Allocation (capability+battery+payload constraints — hard capability gate). (@oshun/contracts/oya fleet.ts — strict zod + bidIsCapabilityValid hard gate; tests reject a non-grasp drone bidding a grasp task.)
  • WorldModelQuery / SceneGraphInstance (pose + last_seen freshness + uncertainty — fail-loud seam). (oya/world-model.tsSceneGraphInstance + discriminated-union WorldModelResult fresh|stale|unknown mirroring oya-scenegraph::memory::QueryResult.)
  • SensorObservation (compressed descriptors, PTP timestamps, never raw frames). (oya/sensor.ts — compressed descriptor (base64/number[]) + ptpTimestamp; .strict() forbids a raw-frame field.)
  • CapabilityManifest (self-describing payload registration: mass/CoM/power/driver-handle, §15.7 capability passport). (oya/capability.ts — payloadId/massKg/centerOfMass/powerW/driverHandle/capabilities[].)
  • ConsentPolicy / PrivacyZone (per-person consent, no-go/no-record geofences, retention). (oya/privacy.ts — consent scopes + retentionDays; PrivacyZone polygon with noGo/noRecord.)
  • SafetyEnvelope (force limits, SSM fields, e-stop state). (oya/safety.ts — per-region force limits N, ssmMinSeparationM, e-stop state enum; aligned with oya-safety.)
  • DockState / ChargeHandshake / BatterySwap contracts. (oya/dock.ts — DockState (slotsFree≤slotsTotal), ChargeHandshake, BatterySwap state machine.)
  • Wire generation via existing OpenAPI + proto pipeline (libs/openapi, libs/proto). (pending — the zod source-of-truth schemas now exist under @oshun/contracts/oya to generate from.) (✓ oya.proto wired into the proto loader (28 tests) + check-proto-parity.mjs enforces zod↔proto field/enum parity (drift self-test passes))

3.3 Refactors of existing @oya/core glue (D)#

  • Rewrite natural-language-control.ts from abstraction → real orchestration over IsisLLMClient + Oya tools → typed commands into oya-control (delete the "no actual ML inference" layer). (✓ COMPLETE — @oya/core: real orchestration over an injected LlmClient seam (UnconfiguredLlmClient fail-loud) + tool registry → typed OyaControlCommand union (Arm/Disarm/Takeoff/Land/GotoWaypoint/SetVelocity/Hold, validated); deleted the no-ML-inference stub. 296 tests, tsc 9→8 (no new))
  • Replace yemaya-integration.ts YemayaBridge.connect() placeholder with real @oshun/event-bus + HTTP wiring (shot-list in, footage metadata/telemetry out). (@oya/core: connect() is now async, awaits an injected event-bus subscribe to the shot-list channel and only reaches connected on success (else error, fail-loud); onShotList(handler) (typed, revision-deduped inbound) + sendFootageMetadata (publishes on the bus AND POSTs to the Yemaya HTTP endpoint). Injected bus/http/clock seams. 112 tests (+12); zero new @oya/core type errors.)
  • Keep the 5 readiness evaluators (@oya/flight-control|mission-planning|safety|swarm-intelligence|telemetry) as TS; wire them as CI release gates. (.github/workflows/oya-readiness-gates.yml — one matrix job per evaluator (fail-fast:false) + an aggregate required gate, path-filtered to libs/oya/**, vitest run --passWithNoTests=false so a lost suite hard-fails; tools/oya-readiness-gates.sh + pnpm oya:gates local runner. All 5 evaluators verified (15 tests, green).)
  • Keep vendor cloud-SDK adapters (dji-sdk, hardware-platforms-2025, generic-hardware) in TS; route MAVLink/PX4/ArduPilot to oya-mavlink. 2026-09-18: open for an agent now. Verify: no MAVLink, PX4 or ArduPilot framing remains in libs/oya/core outside the adapter that calls oya-mavlink through the node bridge, shown by a grep in the spec, and the vendor SDK adapters still pass their tests.

4. Services (apps/oya/*) — orchestration/agent/IO tier (TS)#

Each service: scaffold (project.json nx:run-commands tsc/tsx; package.json; tsconfig.json), config-validated server.ts, modules, contracts from @oshun/contracts/oya, event-bus publish/subscribe, db access, health endpoint, Vitest tests, Dockerfile, @oshun/metrics instrumentation. Tags ["scope:oya","type:app","layer:service"].

4.1 Carry-over / Part I services#

  • (B) svc-flight-gateway — owns the secure drone link; wraps oya-node-bridge; signed MAVLink2; arming/safety interlocks. (apps/oya/svc-flight-gateway BUILT: arming interlock FSM (GPS/battery/safety-envelope/geofence/e-stop preconditions, fail-loud), fail-CLOSED command gate, HMAC-SHA256-signed MAVLink2-style frames (node:crypto, tamper-detecting, strict-hex); 58 tests. PENDING: wrapping the actual oya-node-bridge transport / live radio link.) 2026-09-18: the residue is the real transport. Prove it against PX4 software-in-the-loop (OYA.G3), which is what a live radio link would carry; a radio itself is hardware. blocked:upstream
  • (B) svc-perception — vision/VLM "see what you see"; pose/hands/objects/OCR; publishes to shared map. (apps/oya/svc-perception BUILT: real NMS/IoU detection post-processing, multi-object tracking (IoU association + alpha-beta), confirmed-track→SceneGraphInstance publish to svc-home-map with real last_seen; 48 tests. PENDING: the actual YOLO/VLM detector model (honest not_configured seam in place — never fabricates a detection).) 2026-09-18: the residue is the detector behind the not_configured seam; it waits for OYA.G1 and a detector admitted under OYA.G2 (not an AGPL one). blocked:upstream
  • (D) svc-assistantSystem-2 brain: IsisLLMClient + tools + RAG + memory; mission decomposition; spatial reasoning over svc-home-map; tool calls; delegates to orchestrator; never emits motor commands; always gated by oya-safety. (apps/oya/svc-assistant BUILT: the safety-critical invariants are real + tested — motor/actuation commands refused outright, every delegated action fail-closed safety-gated (ISO/TS 15066 envelope), typed tool registry + dispatch, topological mission decomposition w/ cycle detection, spatial-reasoning over the map; 64 tests. PENDING: the IsisLLMClient/RAG/memory backend (honest not_configured seam in place).) 2026-09-18: the residue is the language model, retrieval and memory backend; it waits for OYA.G5. blocked:upstream
  • (F) svc-directorDroneDirector agent; ties yemaya/remote-film-capture director ↔ oya-cinematography; live composition feedback; preference loop. (apps/oya/svc-director: live composition scoring (rule-of-thirds/headroom/lead-room/shot-size, ported from oya-cinematography) + concrete camera-move corrections, online logistic-regression preference loop (re-ranks shots from director accept/reject), Yemaya shot-list→camera-path bridge. 41 tests.)
  • (D) svc-mission — missions, follow-me policy, energy-aware planning. (apps/oya/svc-mission: Fastify on @oya/fastify-core, mission CRUD via @oya/database MissionRepository + zod FlightPlan validation, geodesic follow-me policy, energy-aware feasibility gate (path-distance×power vs usable Wh − reserve). 30 tests via fastify.inject.)
  • (E) svc-dockdock-network controller feeding svc-energy; perch routines; charging FSM; battery-swap orchestration. (apps/oya/svc-dock: per-slot charging FSM (Idle→…→Released +Fault, legal-transition + target-SOC), perch planning (final-approach vector + alignment gate), battery-swap FSM (Requested→…→Done + live-SOC handoff gate), multi-dock network with aggregate-availability feed for svc-energy. 59 tests.)
  • (G) svc-live-stream — WebRTC SFU (video + low-latency control/telemetry data-channel), reuse svc-webrtc pattern. 2026-09-18: open for an agent now; the pattern to reuse is apps/lilith/svc-webrtc. Verify: a service spec negotiates a session, carries a video track and a data channel between two in-process peers, and measures the data-channel round trip.

4.2 Part II hive services#

  • (D) svc-fleet-orchestrator — Open-RMF-pattern: ingest pose/battery/capability; auction+congestion allocator; space-time traffic schedule for doorways/halls/stairs; per-class fleet adapters. Router, not motor controller. (apps/oya/svc-fleet-orchestrator BUILT: agent registry (pose/battery/capability + freshness), CBBA auction (hard capability gate + battery feasibility, conflict-free), space-time interval reservation for shared resources (doorways/halls), router-only output.) (✓ per-class fleet adapters COMPLETE — FleetAdapterRegistry: resolves an agent's robot class from its capability set (aerial-drone/ground-rover/manipulator/floor-care, most-specific match) and translates an Allocation into router-level dispatch commands via the CAPABILITY_DISPATCH table (fly→navigate/aerial, roll→navigate/ground, climb_stairs→navigate/ground_with_stairs, grasp→manipulate/grasp, vacuum/mop→clean/…, camera→observe/camera), re-checking the hard capability gate (fail-loud CapabilityViolationError). A test asserts the dispatch command carries only the 6 router fields and none of {torque,motorSpeeds,pwm,thrust,rpm,voltage,current,jointAngles} — upholding router-not-motor-controller. 8 tests; suite 44 green; tsc clean.)
  • (A) svc-home-map — serves geometric+scene-graph+(server)3DGS layers; NL/structured spatial-query API ("where is X / what changed"); multi-robot map fusion; privacy-zone annotations; change-detection streams. Single source of truth. (apps/oya/svc-home-map BUILT: in-memory building→floor→room→object scene graph with confidence decay, fail-loud structured spatial query (fresh/stale/unknown), "where is X", change-detection (added/moved/removed since tick), fail-closed no-record privacy-zone redaction. 49 tests. PENDING: 3DGS layer, multi-robot map fusion, NL (vs structured) query.) 2026-09-18: three residues. Multi-robot map fusion is deterministic and open now (Verify: two robots' graphs of the same room merge to one with the shared objects deduplicated). Durable storage is OYA.G6. The natural-language query waits for OYA.G5, and the server-side 3DGS layer needs a GPU and is last.
  • (F) svc-floorcare — zone scheduling, coverage-job lifecycle, dirt-heatmap persistence, omni-dock cycle coordination, recharge-and-resume. (apps/oya/svc-floorcare BUILT: coverage-job FSM with recharge-and-resume from a checkpoint, zone scheduler (cadence/priority dueZones), exponential-decay dirt-heatmap (topDirty).) (✓ omni-dock cycle coordination COMPLETE — OmniDockCycle FSM: Idle→Docking→Emptying→MopWashing→MopDrying→DetergentDosing→Ready on fixed per-stage durations (sum 215 s), with resource preconditions (bag room / clean water / detergent) dropping the cycle to Fault (bin_full/no_clean_water/no_detergent), reset recovery, and the svc-dock coordination signals bayOccupied() (bay busy during the cycle) + estimatedSecondsToReady() (when the bay reopens). Fail-loud illegal-transition/non-monotonic-tick/out-of-range guards. 14 tests; suite 68 green; tsc clean.)
  • (F) svc-manipulation — VLA policy serving (π0.5/OpenVLA-OFT per-embodiment adapters), grasp-confidence gating + fail-loud escalation, teleop→autonomy demo capture (LeRobot/OXE), handoff coordination. (apps/oya/svc-manipulation BUILT: grasp-confidence gating (accept/escalate, never fabricate), contact-gated handoff FSM, per-embodiment VLA registry with an honest fail-loud UnconfiguredVlaPolicy (503 not_configured) seam; 35 tests. PENDING: a real π0.5/OpenVLA model backend + teleop demo capture.) 2026-09-18: the residue is a real policy behind the not_configured seam and the demo capture. Which vision-language-action model can run, where, and under what licence is OYA.G2's question; a 7B policy does not run on these CPUs. blocked:upstream
  • (F) svc-pet — per-individual ID (face/weight/gait), behavior/affect state, pet-aware nav policy, treat-dispense + calorie budget + consumption verification, graded anxiety mitigation. (apps/oya/svc-pet BUILT: real weight-based ID (tolerance bands, ambiguity fail-loud), behavior/affect FSM + graded anxiety-mitigation ladder, pet-aware nav policy (keep-out/slow/yield), two-phase calorie budget with consumption verification; 69 tests. PENDING: face/gait biometric ID model (honest not_configured seam in place).) 2026-09-18: the residue is the face and gait identification model; it waits for OYA.G1 and OYA.G2. blocked:upstream
  • (F) svc-eldercare — multimodal fall fusion (radar+CSI+skeleton) trigger→confirm→escalate, closed-loop med adherence, proactive engagement engine, RAG-guardrailed conversation with refusal-to-advise router, cellular-backed emergency escalation. (apps/oya/svc-eldercare BUILT: Bayesian log-odds fall fusion + trigger→confirm→escalate FSM, med-adherence tracker (due/missed/rate), engagement scheduler, deterministic fail-CLOSED refusal-to-advise router + fail-loud RAG seam; 66 tests. PENDING: real RAG/LLM backend + cellular escalation transport.) 2026-09-18: the retrieval and language backend waits for OYA.G5. The cellular escalation transport needs a modem and a carrier account, which are the owner's. blocked:upstream
  • (B) svc-ambient — Matter controller / Thread-1.4 border-router (HRAP); expose nodes as Matter Occupancy/Camera; control 3rd-party lights/locks/shades; sensing-escalation policy (when to dispatch a mobile eye). (apps/oya/svc-ambient BUILT: device registry with real per-kind capability validation (lights/locks/shades/occupancy/camera) → Matter cluster command translation, the deterministic sensing-escalation policy (dispatch a mobile eye on ambiguous/anomalous/stale fixed-sensor readings, not on confident ones); 38 tests. PENDING: the real Matter/Thread transport (honest not_configured driver seam in place — never fabricates a lock ack).) 2026-09-18: open for an agent under the install-first rule: bind the driver seam to an open-source Matter controller (matter.js) and prove it against a virtual Matter device on the same host. Verify: commission the virtual device, toggle it, and read the acknowledgement the seam used to refuse to invent. A Thread border router needs a radio and is a hardware child of this item.
  • (E) svc-energy — Fleet Energy Manager: dock registry/broker (charging as auctionable resource), SOC/SOH aggregation, return-to-dock w/ checkpoint-resume, battery-swap, predictive-maintenance flags; on-robot fail-safe fallback. (apps/oya/svc-energy BUILT: dock registry/broker with lowest-SOC preemption auction, SOC/SOH fleet aggregation + endurance, return-to-dock decision (threshold-exact).) (✓ COMPLETE — all four pending features added as pure, fail-loud, deterministic modules: predictive-maintenance assessPackHealth (SOH service/EOL + abnormal-fade + resistance-rise + cycle-limit flags → ok/monitor/service_soon/replace severity); on-robot fail-safe fallback onRobotEnergyDecision (defers to server when reachable; else a conservative SOC ladder continue→refuse_new_mission→return_now→emergency_park); mission checkpoint/resume MissionCheckpointStore (save/get/clear + decideResume: restart if absent/stale, abort if energy insufficient for the remainder, else resume); battery-swap orchestration decideSwapVsCharge (swap only when a pack is available, the robot is high-duty, and the swap beats charge-in-place time). 18 new tests; suite 45 green; tsc clean.)
  • (G) svc-hri — full-duplex speech-to-speech core (Moshi-style multi-stream), HIVE-wide turn-taking/floor arbitration, per-embodiment affect rendering, mic-array speaker localization fusion, persona/trust per resident. (apps/oya/svc-hri BUILT: HIVE-wide floor arbitration (priority barge-in, one-holder, fair queue), real TDOA mic-array speaker localization + bearing fusion, persona/trust model gating sensitive actions, affect rendering; 66 tests. PENDING: the Moshi-style speech-to-speech model (honest not_configured seam in place).) 2026-09-18: the residue is the speech-to-speech model; it waits for OYA.G1 and OYA.G2, and a 7B duplex model needs a GPU the project does not have. blocked:upstream

4.3 Edge & home-server runtimes#

  • (B) libs/oya-edge-runtime — Rust home-server binary: low-latency control hub, video archive, local vector DB/RAG, optional local LLM, dock/charging orchestration, offline-first. 2026-09-18: open for an agent, in four parts, because this line is four deliverables: (a) the binary, its configuration and the offline-first control hub; (b) the video archive; (c) the local vector store and retrieval; (d) the dock and charging orchestration hook. Create libs/oya-edge-runtime as a Cargo crate first and add the path filter the premerge workflow deferred until it existed. Verify: each part by a crate test, and the hub keeps serving with the network interface down.
  • (C) On-robot edge runtime image (aarch64) packaging oya-engine native + perception models + wake-word/VAD + safety FSM; works fully offline. 2026-09-18: open for an agent under the install-first rule: build the aarch64 image by cross-compilation (cross or a qemu builder), with no model inside until OYA.G2 admits one. Verify: the image boots under qemu, the safety state machine starts, and nothing in it dials out.
  • (C) Home-server failover (§15.3): UPS-backed appliance, edge-elected backup brain, life-safety path fully on-edge with cellular egress. 2026-09-18: the software half is open: election of a backup brain among the edge units and a life-safety path that runs without the home server. Verify: in the dev stack, killing the home-server process elects a backup within the stated deadline and a simulated fall still escalates. The uninterruptible supply and the cellular egress are hardware.

4.4 Product surfaces#

  • (H) bff — Fastify BFF: aggregation, response shaping, streaming/SSE, client-type routing (reuse lilith bff pattern).
  • (H) web — Next.js dashboard: live map, video, missions, fleet, telemetry, privacy controls UX (no-go/no-record zones, recording/consent, retention).
  • (H) mobile — React Native companion + manual controller.
  • (H) Onboarding/setup flow: guided first-map walkthrough, room/zone labeling, dock/anchor placement guidance with UWB GDOP feedback, "major change → re-survey?" (§15.6).

5. Capability lines (cross-cutting feature checklists)#

Each line is a software+skill bundle over the shared substrate. Robot classes reused across lines. Tasks here are the line-specific features beyond the generic crate/service work above.

5.1 Line 1 — Floor care (mop/sweep/vacuum) — bar: Roborock Saros 10R#

  • StarSight-pattern solid-state-LiDAR+3D-ToF+RGB fusion perception pipeline; 100–200-class on-device classifier (classify-then-discard image).
  • Pet-waste as a hard-avoid class with conservative margins.
  • <80 mm under-furniture profile handling; AdaptiLift/NeverStuck threshold logic.
  • Omni-dock cycle (cyclone self-empty, hot-water wash+dry, detergent dosing, IR+fiducial alignment).
  • Wet-floor/drying shared map layer + occupancy-gated mopping (§15.2).
  • Readiness gate: provable coverage completeness; obstacle-avoidance benchmark ≥ Saros 10R.

5.2 Line 2 — Fetching small objects — bar: Toyota HSR / beat OK-Robot 58.5% / DynaMem 70%#

  • find→navigate→grasp→deliver decomposition; semantic place memory.
  • Per-object-class honest capability boundaries + task-level confidence gating (§15.6).
  • Floor-pickup tip-over handling; high-shelf reach limits; teleop SLA + privacy model.
  • Medication: prefer mobility-as-payload + fixed verified dispenser over loose-pill grasp (§15.6).
  • Payload securement (lidded/gimbaled carriers; accel limits; never over person/stairs; continuous retention verify; dropped-payload = logged event) (§15.2).

5.3 Line 3 — Home patrol & security — bar: Knightscope-class fusion, beat false-alarm fatigue#

  • Learned-normalcy anomaly detection (RGB+thermal+LiDAR/sonar+audio); not fixed motion alarms.
  • Multi-stage trigger→confirm→escalate (cheap RF trigger → camera unit confirms before alarming).
  • Human-in-the-loop SOC escalation; MCAP incident logging + replay (Foxglove/Formant).
  • Night low-noise patrol mode (radar/CSI/thermal, no vacuum/props) (§15.2).
  • Acoustic-event service hook (glass break, smoke/CO) (§15.7).

5.4 Line 4 — Companion + presence — bar: ElliQ engagement + Moshi full-duplex#

  • Full-duplex speech-to-speech (Moshi/Mimi multi-stream, ~200 ms, barge-in/backchannel).
  • Predictive multimodal turn-taking + HIVE-wide floor arbitration (one responder per human).
  • LLM-driven facial affect (FACS blendshapes / OLED-eye) + anticipatory coexpression.
  • Proactive engagement engine (goals × availability × success-probability).
  • Per-resident persona drift + long-term episodic memory; core loop runs edge+home-server (Moxie lesson).
  • Mic-array DoA → orient-to-speaker.

5.5 Line 5 — Pet interaction — bar: beat Furbo/Petcube with mobile local-first#

  • Pet-specialized detection; per-individual collarless ID (face+weight+gait).
  • Markerless pose (DeepLabCut/SLEAP) + behavior-syllable segmentation; bioacoustic bark/meow emotion.
  • Treat launcher with closed-loop consumption verification + fleet-wide calorie budget.
  • Laser play gated behind opt-in + hard eye-avoidance + capped duration (avoid laser-pointer syndrome).
  • Pet-aware social navigation (never-corner/escape-route; sleeping/eating soft no-go) (§15.2).
  • Per-pet persistent health record; separation-anxiety graded-intervention FSM → escalate to human.

5.6 Line 6 — Elder-care & health — bar: Vayyar Care fall detection + ElliQ companionship#

  • Sensor-fusion fall pipeline (mmWave + CSI + ST-GCN skeleton) → one home-level belief; trigger→confirm→cancelable-countdown→escalate.
  • Closed-loop medication adherence (dispense + ingestion verification; escalate on confirmed miss only).
  • RAG-grounded guardrailed LLM with refusal-to-advise routing (never unguarded medical advice).
  • rPPG/radar contactless vitals; gait-speed/sit-to-stand deterioration biomarkers.
  • Fall PREVENTION: proactively clear/flag trip hazards; surface decline trends to caregivers (§15.7).
  • Emergency escalation orchestrator (fall→countdown→two-way voice→caregiver→EMS, cellular fallback, cancel, audit); offline/anti-orphaning path.
  • Accessibility modes (large-button/pendant, hearing-impaired visual/haptic, dysarthria-robust ASR, dementia-appropriate; validate fall/gait on wheelchair/walker users) (§15.4).

5.7 Line 7 — Persistent home mapping — bar: iRobot Imprint, exceed with open-vocab fleet-shared graph#

  • Three-layer map served by svc-home-map; on-prem-by-default storage. (svc-home-map serves the scene-graph layer (in-memory, local-first/on-prem) and the geometric layer exists in oya-mapping (occupancy + pose-graph). PENDING: the server-side 3DGS layer + unified three-layer serving.)
  • Change-aware queries ("what changed in the living room since yesterday"). (svc-home-map GET /v1/changes?since=T — added/moved/removed instances since a tick with freshness + displacement, room-scopable.)
  • Honesty gate: low-relocalization-confidence/stale last_seen → "I last saw it 3 days ago, not sure" (not a confident wrong location). (svc-home-map fail-loud spatial query returns fresh|stale|unknown with exp-decayed confidence + lastSeen — never fabricates a confident location for a decayed instance; also the @oya/readiness-gates map-freshness gate.)
  • Multi-floor + multi-robot pose-graph fusion (Hydra-Multi/Kimera-Multi), bandwidth-aware descriptor exchange.
  • Unified "find my things" capability (scene-graph last_seen + UWB/BLE tags + on-demand eyes) (§15.7).

5.8 Line 8 — Energy management & docking — bar: WiBotic + OTTO banding#

  • Dock-as-shared-resource broker; PRCP-sized dock count (not 1:1).
  • Many-to-many charging handshake (robot-ID); precision self-docking (AprilTag coarse → Nav2 precision → funnel → pogo).
  • Energy-aware locomotion integration (roll-vs-fly-vs-perch per-edge cost).
  • Battery-swap for top-duty units; UAV perch-overwatch missions.
  • Beat silent-dead-on-floor stranding (conservative reserve + free-dock targeting).

5.9 Line 9 — Ambient / smart-home — bar: Aqara FP2/FP300, exceed with cross-modal track#

  • Tiered sensing: always-on cheap fixed nodes (PIR+mmWave+lux/temp/humidity+mic, point-cloud only) + on-demand mobile RGB-D/thermal eyes.
  • Cross-modal identity track with sensor handoff (beat false-absence on stationary occupants).
  • Matter-1.5/Thread-1.4-native controller; PIR/Wi-Fi-gated radar wake; Matter LIT battery nodes.
  • Federated learning + differential privacy across homes; federated home-archetype priors (§15.7).
  • Whole-home hazard monitor product capability (stove/fridge/faucet/open-door-at-night) (§15.7).

5.10 Line 10 — Lab co-pilot & filmmaking director — bar: Figure Helix dual-system#

  • Lab co-pilot: procedural task graphs (SMD/through-hole soldering, reflow, ESP32/STM32 bring-up, I²C/SPI debug).
  • Egocentric visual grounding (VLM watches hands+board: "is this joint cold?").
  • Datasheet RAG (OCR part number → retrieve datasheet → pinout/voltage/timing hands-free).
  • Hazard alerts (hot iron, fumes/ventilation, ESD, shorted board); collaborative multi-step reasoning.
  • Filmmaking director own spec (§15.6): shot-type library (dolly/orbit/crane/reveal), composition/aesthetic scoring, multi-unit coordinated filming + angle handoff, subject-tracking-for-framing (distinct from collision avoidance), gimbal/exposure/focus, director-LLM intent→shot-sequence.
  • Director preference loop: executed shot → accept/reject → director-preference-learning update; Yemaya dailies/conform/timeline ingest.

6. Intelligence stack (shared)#

6.1 Voice (D)#

  • Wake-word model (Picovoice-class on-device) wired to svc-voice-pipeline VAD. (oya-dsp::{vad,wake_word} BUILT: real VAD (energy/ZCR/spectral-flatness + adaptive noise floor + hangover) and a deterministic wake-word energy/NCC pre-gate. PENDING: the Picovoice-class neural wake-word model + the svc-voice-pipeline service.) 2026-09-18: the residue is the neural wake-word model, which waits for OYA.G1 and OYA.G2 (openWakeWord is Apache-2.0). The service it wires into exists as apps/lilith/svc-voice-pipeline. blocked:upstream
  • Barge-in: interrupt-and-restart logic in stream handlers (abort TTS on speech). (oya-dsp::barge_in BUILT: detects near-end speech during far-end playback (post-AEC residual VAD, sustained-run rising-edge) → barge-in event to duck/stop TTS. PENDING: wiring into the svc-voice-pipeline stream handlers (restart logic).) 2026-09-18: open for an agent now: the stream handlers are in apps/lilith/svc-voice-pipeline. Verify: a service spec plays synthetic far-end audio, injects near-end speech, and asserts that synthesis stops within the latency budget and that the turn restarts.
  • Reuse svc-stt (whisper/whisper-asr-bridge) + svc-tts; edge ASR (Moonshine/Parakeet) for offline. 2026-09-18: open for an agent now for the reuse (apps/lilith/svc-stt, apps/lilith/svc-tts, libs/oya/core/src/whisper-asr-bridge.ts). An edge recogniser for offline use waits for OYA.G1 and OYA.G2 (Moonshine is MIT).
  • Acoustic echo cancellation; far-field mic-array beamforming (via oya-dsp). (oya-dsp::aec — real NLMS adaptive echo canceller (residual energy drops ~22 orders over a synthetic far→echo→near setup, taps converge to the true echo path), plus the existing oya-dsp::beamforming delay-and-sum far-field array. 68 dsp tests.)

6.2 LLM / agent (D)#

  • Moved to section 0.3 as OYA.G5 (2026-09-18), so that the ground items are worked first; the box and its history are there.
  • Oya tool-set: flyTo, orbit, perch, lookAt, readLabel, recordClip, setReminder, queryDatasheet, fetch, cleanZone, patrol, dispenseTreat, escalate. 2026-09-18: open for an agent now: svc-assistant already has the typed tool registry and dispatch. Verify: each of the thirteen tools has a schema, delegates to its service behind the oya-safety gate, and refuses when the gate refuses; none emits a motor command.
  • Reuse svc-ai/agent-executor + agent-coordination; define Oya agent roles (FleetOrchestrator, DroneDirector, LabCoPilot, CareDispatcher). 2026-09-18: reuses apps/lilith/svc-ai; the roles need a model to run and wait for OYA.G5. blocked:upstream
  • RAG: iris/knowledge (GraphRAG/agentic-rag) + iris/conversation-rag + sophia/semantic-search. 2026-09-18: the libraries exist (libs/iris/knowledge, libs/iris/conversation-rag, libs/sophia/semantic-search); binding them needs the model seam of OYA.G5. blocked:upstream
  • Memory: svc-conversation session store + long-term vector store (home server). 2026-09-18: open for an agent now for the session store (apps/lilith/svc-conversation); the long-term vector store lives on the home server and follows the edge runtime item of section 4.3.
  • Prompt-injection defense (§15.5): perception/voice inputs cannot escalate privilege or trigger high-consequence actuation without supervisor + confirmation gate. 2026-09-18: open for an agent now, and it is deterministic. Verify: adversarial fixtures (text in a camera frame, a spoken command from an unknown voice, a tool result carrying instructions) cannot raise privilege or reach a high-consequence tool without the supervisor and the confirmation gate; each refusal is logged with its source.

6.3 VLA / world model (F/H)#

  • System-2 reasoner (Gemini-Robotics-ER/π0.5-class) hierarchical inference → language subtasks.
  • System-1 flow-matching/diffusion action expert (on-robot, ~50 Hz) conditioned on System-2 latent.
  • Cross-embodiment base policy + thin per-embodiment heads (OpenVLA-OFT recipe).
  • Speculative edge-verifier decoding + Real-Time Chunking for jitter tolerance.
  • World model: imagined rollouts (MPC), home synthetic-scenario generation (GR00T-Dreams), closed-loop policy eval — bounded horizon, validated vs real map.
  • Model-based 6-DoF grasp fallback always available under the VLA.

6.4 Skill library & lifelong learning (H)#

  • Teleop→autonomy data flywheel (Expert-Mode/Mobile-ALOHA), operator-side face blur + owner consent.
  • Demo logging in Open-X-Embodiment/LeRobot format; per-home fine-tune (LoRA adapters) from 50–100 demos.
  • Lifelong skill library (LRLL distillation) with catastrophic-forgetting guards (replay/retrieval/adapters).
  • Habitat 3.0 / HSSD-200 / OVMM sim harness as CI for perception+policy before hardware rollout.
  • Sim-to-real: accurate actuator modeling (delays/torque/friction) + domain randomization.

7. Distributed perception & "eyes that come to you" (B/C)#

  • Fixed-node semantic emission (skeletons/clusters/occupancy deltas over the wire, never pixels — Bonn pattern). 2026-09-18: open for an agent now. Verify: the wire schema in libs/contracts/src/oya admits skeletons, clusters and occupancy deltas and has no field that can carry pixels; a spec refuses a payload that tries.
  • On-demand mobile-eye dispatch policy (nearest suitable unit; drone only if elevated/blocked); energy-aware. 2026-09-18: open for an agent now; it is a policy over the fleet and energy crates. Verify: table-driven cases: nearest suitable unit wins, a drone is chosen only when the target is elevated or the route is blocked, and a unit below its reserve is never chosen.
  • Cooperative cross-modal fusion (HeCoFuse-style) — camera-drone + LiDAR-rover joint detection; uncertainty/pose-error-aware; degrade to onboard-only on mesh drop. 2026-09-18: learned cross-modal fusion waits for OYA.G1 and OYA.G2. The degrade-to-onboard rule on a mesh drop is deterministic and can be built first. blocked:upstream
  • Mobile robot down-weighted as noisiest node; ICP-aligned before integration. 2026-09-18: open for an agent now. Verify: a fusion test in which the mobile unit's observation carries the larger covariance and is ICP-aligned before it is integrated; an unaligned scan is refused.
  • UWB ~10 cm "go to where this person is"; BLE Channel Sounding fallback. 2026-09-18: open for an agent now on oya-estimation::positioning. Verify: a simulated tag at a known position is reached within 10 cm in the planner test, and the Bluetooth fallback engages when ranging drops out.
  • Home-wide acoustic-event localization service (§15.7) triggering nearest eye. 2026-09-18: localisation from the microphone array exists; classifying the event (glass break, smoke alarm) is a model and waits for OYA.G1 and OYA.G2. blocked:upstream

  • CapabilityManifest driver hot-load: on dock, module reports mass/CoM/geometry/power/capabilities/driver-handle → body updates dynamics model + agent action set live (before moving). (✓ the deterministic engine deliverable is COMPLETE: the agent action set half is oya-locomotion::capability_passport::CapabilityRegistrydock/undock a module's manifest (driver-handle/mass/CoM/power/capabilities) recompute the live union action set, has_capability, drivers_for (which driver serves a capability), and total power/mass; the dynamics model half flows from the SAME manifests via to_component_massesmorphing_estimation::MorphingEstimator::update_layout (mass-weighted CoG + parallel-axis inertia), so both update on dock before moving. 4 domain tests (dock/undock updates action set live, duplicate-handle replaces, multi-driver capability union+resolution, and the dynamics bridge: two symmetric masses → CoG at origin + Iyy=Izz=2·m·d²). fmt + clippy -D warnings clean; zero stubs. PENDING (deployment/runtime, not an engine algorithm): the literal hot-loading of the driver code keyed by driver_handle.) 2026-09-18: open for an agent now: a driver registry keyed by driver_handle that loads and unloads a driver at run time. Verify: docking a module in the test loads its driver, extends the agent's action set before any motion command is accepted, and undocking removes both.
  • Foldable rotor-arm deploy/latch control + fold-detect-refuses-to-arm-until-locked. (oya-locomotion::foldable_arm — a per-arm deploy/latch FSM (Folded→Deploying→Deployed→Latched/Retracting/Fault) driven purely by deploy-angle + latch sensors (the FSM validates + gates; it never drives latch solenoids or arm motors, mirroring the reconfiguration planner's no-low-level-commands rule). It fails safe on every sensor/motion inconsistency — a latch engaging before the arm is deployed (false latch), a Latched arm's latch slipping, a deployed arm drifting off its angle without a retract command, an unhealthy latch sensor, or an out-of-range angle all drop the arm to a sticky Fault; retract is refused while latched (requires command_unlatch first). The headline fold-detect-refuses-to-arm-until-locked interlock is FoldableArmSystem::can_arm: it returns Ok(()) only when every arm is Latched, else a fail-loud ArmingRefusal naming the exact offending arm + its state/fault — a partially-deployed quad (3 latched, 1 still Deploying) is refused, naming arm 3. 12 domain tests (full deploy→latch sequence, each fault path, retract-needs-unlatch, interlock-gates-until-all-latched, faulted-arm-blocks-arming); fmt + clippy -D warnings clean; zero stubs. The physical latch-solenoid/arm-motor drivers are the hardware actuator layer (out of scope).)
  • Unfolding telescoping-arm stow/deploy control (no IK singularities). (oya-locomotion::telescoping_arm — a planar telescoping arm (base rotation θ + prismatic extension L) modelled with its polar forward kinematics ee = L·(cosθ, sinθ) and velocity Jacobian J = [[cosθ, −L sinθ],[sinθ, L cosθ]], whose det J = L is singular exactly at L = 0 (full retraction): manipulability w = |det J| = L and condition number κ = max(1,L)/min(1,L) (verified to diverge as L→0, best=1 at L=1). The control is singularity-free by construction — the arm stows at min_length ≥ singularity_floor > 0, so the whole operating stroke [min_length, max_length] is well-conditioned (worst_case_manipulability > 0), and plan_deploy/plan_retract emit a monotone cosine-eased length profile through that range, never approaching L=0. Fail-loud check_target/plan refuse over-extension and sub-stow (singular-adjacent) targets with typed TelescopingError. Like the reconfiguration planner it emits validated set-points only (no prismatic-actuator drive). 9 domain tests: polar FK, det J = L across angles, κ-divergence, whole-stroke-singularity-free, monotone+smooth deploy/retract every-waypoint-well-conditioned, out-of-stroke refusals. oya-locomotion 88 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Perch latch control (claw/gecko/suction) + motors-off overwatch. (oya-locomotion::perch_latch — a perch-attach state machine (Flying→Latching→Latched→Overwatch/Fault) with the safety-critical don't-drop-the-drone invariant: motors may be cut only while the latch verifiably holds the weight with margin, and the latch released only after the motors are back at hover thrust. command_motors_off is fail-loud — refused unless Latched with the last measured hold ≥ safety_factor·weight (typed NotLatched/InsufficientHold); command_release/command_respin refuse below hover thrust (MotorsBelowHover); a held perch whose hold decays below the drone's weight (esp. in motors-off Overwatch) drops to Fault. Per-mechanism hold-force physics decide whether a measured latch state actually carries the load: claw_hold_force (form-closure grip = clamp force), gecko_hold_force (directional dry adhesion shear_pressure·area, zero until a normal preload engages the setae), suction_hold_force (F=ΔP·A) — hand-computed-value tests (gecko 50 kPa·20 cm²=100 N, suction 60 kPa·10 cm²=60 N). Validates+gates only; never drives latch/motor actuators. 12 domain tests (full perch→overwatch→respin→release cycle, motors-off refused until latched-with-margin, hold-decay refusal, latch-slip-in-overwatch fault, release/respin hover gates, per-mechanism parity). oya-locomotion 100 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Inter-unit docking (EPM self-align) + cooperative-transport handoff with success verified before release. (oya-locomotion::inter_unit_dock — two pieces. EPM self-aligning dock (EpmDockController, Approaching→Aligned→Latching→Docked→Undocking/Fault): the electropermanent magnet latches/releases on a current pulse but holds with zero standing power (holds_power_free() true once Docked), and the latch is energized only inside the passive self-align capture envelope (within_capture_envelope, lateral + angular tol) — command_energize_latch is fail-loud NotAligned otherwise; the joint is Docked only once the magnetic hold is verified ≥ required, and a docked joint that loses its hold faults. Cooperative transport handoff (CooperativeHandoff, GiverHolding→Transferring→ReceiverSecured→Complete/Fault) enforces success-verified-before-release: command_giver_release is refused (ReceiverNotSecured) until the receiver verifiably holds secure_factor·weight, and the continuous-retention invariant faults the handoff if the combined giver+receiver grip ever falls below the payload weight (never a moment where nobody carries the load) — a receiver that slips back below the margin after securing is caught before release. Validates+gates only; never drives magnet currents/grippers (consistent with the reconfiguration planner's rule). 9 domain tests (full dock cycle power-free hold, latch-refused-out-of-envelope, alignment-lost-reverts, docked-hold-loss fault; full handoff verify-before-release, release-refused-until-secured, continuous-retention-loss fault, secured-then-slips caught). oya-locomotion 109 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Deterministic, gravity-/stability-checked reconfiguration planner (balance enforced at every intermediate step); agent never commands magnet currents/latches directly. (oya-locomotion::reconfiguration — validates a reconfiguration sequence (fold arm / deploy leg / dock-undock module) keeps the body statically stable at every intermediate step: each step's support polygon is the convex hull (Andrew's monotone chain) of the ground contacts, and the stability margin is the min signed perpendicular distance from the CoG to a hull edge (positive = inside). ReconfigurationPlanner::validate returns stable / first_unstable_step / min_margin / per-step margins; a degenerate point/line support is fail-loud unstable. The planner emits validated high-level steps only — never magnet currents/latches (that's the separate actuator layer). 6 domain tests: hull drops interior points, centred-square margin = 1.0 / boundary = 0 / outside < 0, two-contact line unstable, a balanced shift-then-lift plan accepted while a lift-leg-too-early plan is rejected at the exact tipping step. oya-locomotion 63 tests; fmt + clippy -D warnings clean; zero stubs.)

9. Safety, privacy, security, compliance#

9.1 Safety (cross-phase)#

  • Indoor flight safety: ducted/caged-prop logic, speed caps, room-boundary geofence, emergency-land + watchdog (on-drone, offline), prop-stop on contact. (oya-safety::flight_safety: direction-preserving speed caps, room-boundary geofence with proportional inward braking (stops at the wall), clock-free emergency-land watchdog FSM (offline/on-drone), latched prop-stop on contact (force/proximity). 61 crate tests. Ducted/caged props are the hardware form-factor; the software safety logic is complete.)
  • Mobile-base SSM + manipulator PFL enforced by oya-safety on every actuation. (oya-safety::actuation_gate::ActuationSafetyGate — the mandatory enforcement seam that caps every motion command: gate_mobile_base applies the SSM speed cap (max_robot_speed, R15.08/ISO 10218-2) for the current human separation — forcing the base to STOP (cap 0) when even a stationary robot can't meet the protective separation; gate_manipulator applies the PFL biomechanical cap (max_speed_for_region, ISO/TS 15066) scaling TCP speed to the contact body-region limit; gate_mobile_manipulator does both. Fail-safe: each decision returns the allowed (reduced/zeroed) speed + vetoed/scaled/basis. 5 domain tests: base allowed-far / scaled-mid / STOP-close, manipulator capped by region (skull < hand), heavier robot ⇒ lower PFL cap, mobile-manipulator gates both subsystems. oya-safety 112 tests; fmt + clippy -D warnings clean; zero stubs.)
  • Child-as-distinct-hazard model (§15.2): choking interlocks on dispensers, manipulator/drone lockout near unsupervised children, ride-on/tip resistance, child-height coverage, yields-when-grabbed. (oya-safety::child_safety: small-parts (⌀31.7mm) choking interlock, supervision gate (manipulation/keep-out lockout near an unsupervised child, adult-within-radius logic), CoG tip-resistance, child-height coverage check, yields-when-grabbed force/torque compliance. 31 tests, all fail-closed.)
  • Stairs/cliff/threshold edge-safety on all ground units. (oya-safety::edge_safety: cliff/drop detection from downward range sensors (worst-drop governs: BackOff/Stop/Proceed, fail-safe Stop on dead/empty sensors) + rising-edge threshold climb-limit check.)

9.2 Privacy (cross-phase)#

  • On-device face/PII redaction (unrecognized-person redaction by default). (@oya/privacy::redaction: fail-closed default-redact — any UNRECOGNIZED/low-confidence/non-allowlisted region is blurred/black-boxed (real masking transform); only allowlisted recognized ids pass. Face detector = ML input seam.)
  • Hardware recording indicator (LED+chime) in series with camera power; physical shutter/privacy perch. Out of scope (2026-09-18): this file's header leaves physical fabrication to the hardware workstream, and an indicator wired in series with camera power is hardware.
  • Per-room/zone no-fly & no-record enforcement in planner and perception. (@oya/privacy::no-record-zones: ray-cast point-in-polygon + segment-crossing; enforcePlan rejects/clips a path entering a no-fly zone (planner) and enforceCapture drops/redacts captures intersecting a no-record zone (perception), fail-closed.)
  • Local-first storage, explicit cloud opt-in, retention limits, guest mode. (@oya/privacy::storage-policy: classify local-only vs cloud-eligible (cloud only with explicit opt-in; biometrics never leave the box), retention-limit expiry, guest-mode recording suspension.)
  • Bystander/visitor consent (§15.4): audio two-party-consent gating, audit logs, mandatory teleop operator-side blur + owner-consent gate. (@oya/privacy::consent: all-party consent gate (audio refused unless every present party consented), append-only audit log, mandatory teleop operator-side blur + owner-consent precedence.)

9.3 Security (I)#

  • Secure boot + signed A/B-rollback OTA; per-device X.509 identity; CVD policy. (@oya/security::device-identity BUILT: per-device Ed25519 identity + self-describing certs + sign/verify + revocation. PENDING: secure-boot, signed A/B-rollback OTA, CVD policy (hardware/process/deployment).) 2026-09-18: three residues. Signed A/B update manifests with rollback are software and open now (Verify: a tampered manifest is refused, a failed boot rolls back). The coordinated-disclosure policy is a document. Secure boot needs the target board.
  • mTLS everywhere; E2E-encrypted media; per-home tenancy. (@oya/security BUILT: E2E media encryption (AES-256-GCM AEAD, tamper-detecting) + per-home tenancy (HKDF per-tenant keys, fail-closed cross-tenant assertion). PENDING: mTLS wiring across all service transports (deployment).) 2026-09-18: open for an agent now in the dev stack: a local certificate authority, mutual TLS between the Oya services, and a test that a client without a certificate is refused.
  • Expanded threat model (§15.5): compromised brain cannot unlock doors without separate factor/physical confirmation; UWB/sensor anti-spoofing; Sidewalk/3rd-party backhaul as untrusted egress with consent. (@oya/security: fail-closed two-factor door-unlock gate (brain-only refused; requires an independent pinned-key second factor; replay/forgery-resistant — Codex-hardened) + UWB/sensor cross-modal anti-spoofing (≥2 corroborating modalities). 34 tests. Backhaul-as-untrusted-egress-with-consent: the consent contracts exist; egress wiring pending.)
  • Run /security-review on each service before ship. 2026-09-18: run it per service as each is finished and commit the findings beside the service; it is not a single event.

9.4 Compliance & lifecycle (I)#

  • Remote ID (outdoor use), UL (battery/Qi), FCC/CE (RF), GDPR/CCPA (camera/audio data). 2026-09-18: registrations and certifications are the owner's acts with regulators and test houses. Where software produces the evidence (Remote ID broadcast, data-subject export and deletion), that software is its own task. blocked:governance
  • ETSI EN 303 645 / EU CRA conformance (SBOM, supported-lifetime, signed OTA). 2026-09-18: the software half is open: a CycloneDX SBOM per image, a stated supported lifetime, and the signed updates of the security section. The conformance assessment itself is a test house's.
  • ISO 13482 / UL 3300 / ISO 10218 certification paths sequenced per unit class (don't gate whole fleet on hardest cert). 2026-09-18: choosing and sequencing certification paths is the owner's decision with a notified body. blocked:governance
  • Consumables & maintenance subsystem (§15.6): per-unit consumable levels + wear tracking + loud service alerts; design-for-service; right-to-repair/spares stance. (@oya/maintenance: consumable-level ledger (remaining%/ETA/ok-low-depleted), component wear + RUL + needsService, prioritized service alerts, design-for-service serviceable-part registry. 10 tests.)
  • Anti-bricking dignity guarantee (§15.7): self-hostable brain, data export, no-bricking, anti-manipulative-engagement guardrails. (@oya/maintenance::dignity: lossless dataExport/importExport, assertNoBricking (fail-loud on a cloud-gated core feature), antiManipulativeEngagement (rejects dark-patterns/over-frequency), selfHostable lock-in check.)

10. Simulation, CI, eval, observability, infra#

10.1 Simulation & test harness#

  • Moved to section 0.3 as OYA.G3 (2026-09-18), so that the ground items are worked first; the box and its history are there.
  • Gazebo/AirSim/jMAVSim integration (existing *-integration.ts modules) on the Linux box (not the Mac). 2026-09-18: open for an agent under the install-first rule: Gazebo and jMAVSim, headless, on the Linux server (check free -m first). AirSim was archived by its publisher; keep airsim-integration.ts compiling and do not invest in it. Verify: one scripted mission flies in each simulator through the existing integration modules.
  • Isaac Sim/Isaac Lab GPU-parallel RL + Habitat 3.0/HSSD-200/OVMM harness as policy/perception CI. 2026-09-18: Isaac Sim and Isaac Lab need an RTX-class GPU; neither machine has one. Habitat's CPU path may serve perception CI; try it under the install-first rule as a separate task before parking that half. blocked:hardware
  • HIL rigs for manipulator force-limit and docking validation. 2026-09-18: a hardware-in-the-loop rig is hardware. blocked:hardware
  • Capability-passport sim onboarding (§15.7): rehearse new module in the home digital twin before physical use. 2026-09-18: rehearsing a module in the home's digital twin needs the simulator of OYA.G3. blocked:upstream

10.2 Readiness-evaluator gates (extend existing 5)#

  • Coverage completeness (floorcare); Grasp honesty (verified contact before success); Map freshness (non-fabricated last_seen). (@oya/readiness-gates: coverage gate (BFS-reachable denominator), grasp-honesty gate (rejects success without verified contact + credible force), map-freshness gate (recomputes exp-decay, rejects future/over-fresh last_seen).)
  • Energy reserve (verified reserve-to-free-dock); Safety conformance (ISO/TS 15066 + R15.08; governor vetoes OOB command). (@oya/readiness-gates: energy gate recomputes energy-to-nearest-FREE-dock + reserve per mission; safety gate re-derives SSM/PFL bounds and fails any un-vetoed out-of-bounds command.)
  • Privacy enforcement (no-record disables/blurs sensors; tamper-evident indicators); Offline degradation (every safety loop survives cloud loss). (@oya/readiness-gates: privacy gate (ray-cast no-record-zone membership → must disable/redact + tamper-evident, else fail); offline gate (any safety-critical loop with a required cloud dep → fail).)
  • Mode-arbitration economy (rolls over flight when a ground path exists); Economic viability gate (§15.6, "pencils out at achievable volume"). (@oya/readiness-gates: mode-economy gate (flight chosen with a viable ground route → fail); economic-viability gate (real unit economics — unit cost/margin/contribution/payback vs target at achievable serviceable volume).)

10.3 CI/CD & live-update safety#

  • oya-rust-premerge + TS affected build/test/lint in Nx; differential-test suite required green. (.github/workflows/oya-ts-premerge.yml: nx affected build/test/lint over tag:scope:oya + a REQUIRED differential gate (parity 91/91 + napi-bridge smoke) + aggregate required check; pnpm oya:ts-premerge local runner. Complements oya-rust-premerge.yml.)
  • Live-OTA safety (§15.3): never update mid-task/sole-safety-asset; canary/staged rollout; shadow-eval before promotion; auto-rollback on regression; known-good resident. (@oya/readiness-gates::live-ota-safety: refuses update mid-task / for the sole safety asset / without a passed canary / on a shadow-eval regression / without a resident known-good; evaluatePostUpdateRollback emits the auto-rollback decision on post-update regression. 20 tests.)

10.4 Data, infra, observability#

  • Event-bus topic registry for oya.* (telemetry, mission-state, fall, anomaly, dock, emergency). (@oya/event-publisher: OYA_TOPIC_REGISTRY covering all six families — telemetry, mission(+state.changed), fall(detected/confirmed/cleared), anomaly.detected, dock(charge/swap), emergency(raised/escalated/resolved) — each a strict zod payload + typed publish helper, 37 tests.)
  • @oshun/storage buckets (mission data, telemetry archive, captured imagery, video segments). 2026-09-18: open for an agent now: the four buckets on the dev stack's MinIO through @oshun/storage, with retention classes. Verify: a spec writes and reads each class and refuses a write to an undeclared bucket.
  • oya DB schemas + migrations; per-domain isolation. (@oya/database: real PostgreSQL DDL + ordered MIGRATIONS for missions/flights/telemetry/maps/fleet_state/consumables, zod row schemas, parameterized-SQL repositories over a pg-ready QueryExecutor seam. 25 tests.)
  • @oshun/metrics + fleet observability (Foxglove/MCAP logging + replay); flight-data recorder; post-flight analysis. 2026-09-18: open for an agent now; MCAP is an open format with open libraries. Verify: a recorded simulated flight replays to the same telemetry, and the metrics the fleet dashboard needs are emitted with their units.
  • Deployment: service Dockerfiles, edge aarch64 images, home-server appliance image, OTA pipeline. 2026-09-18: four deliverables: service Dockerfiles (open now), the aarch64 edge image (the item in section 4.3), the home-server appliance image, and the update pipeline (with the signed updates of section 9.3). Work them as four.

11. Roadmap phase exit-gates (unified A–I, plan §14)#

  • (A) Foundationsoya-mapping/scenegraph/comms/energy/safety + oya-types/math + contracts + svc-home-map + shared coordinate frame; differential suite + @oya/flight-control green. (all components delivered + green: the 5 hive crates (mapping/scenegraph/comms/energy/safety) + oya-types/math, @oshun/contracts/oya (shared Vec3/GPS coordinate frame), svc-home-map; differential parity suite 91/91; @oya/flight-control evaluator green + wired as a CI gate.)
  • (B) Estimation/Perception/Ambientoya-estimation/mavlink/perception/ambient on shared map; svc-ambient + Matter/Thread; svc-flight-gateway; @oya/telemetry green; live SITL flight via stack. Exit gate, not a task (un-boxed 2026-09-18): it closes when the items it lists are checked.
  • (C) Control/Locomotion/Manipulationoya-control/navigation/locomotion/manipulation; oya-safety mandatory gate on all actuation; @oya/safety green; follow-me + obstacle avoidance + safety FSM. Exit gate, not a task (un-boxed 2026-09-18).
  • (D) Mission/Fleet/Assistant/Directoroya-swarmoya-fleet; svc-fleet-orchestrator; svc-assistant System-2; voice (wake-word/barge-in/duplex); svc-director; end-to-end voice→action in sim. Exit gate, not a task (un-boxed 2026-09-18).
  • (E) Dock/Energysvc-dock→dock-network; svc-energy + PRCP/opportunistic charging; autonomous perch+recharge cycle in sim/HITL. Exit gate, not a task (un-boxed 2026-09-18).
  • (F) Domain servicessvc-floorcare/manipulation/pet/eldercare; capability Lines 1–6,10 behind readiness gates; hands-free soldering demo; shot-list→aerial-shot→dailies ingest. Exit gate, not a task (un-boxed 2026-09-18).
  • (G) HRI/Live — full-duplex svc-hri, social navigation, supervised-autonomy/teleop console; svc-live-stream. Exit gate, not a task (un-boxed 2026-09-18).
  • (H) Learning flywheel + product surfaces — teleop→autonomy pipeline, per-home fine-tune, federated+DP; bff/web/mobile; privacy UX shipped. Exit gate, not a task (un-boxed 2026-09-18).
  • (I) Hardening — EN 303 645/CRA, ISO 13482/UL 3300 paths, /security-review, privacy audit, adversarial safety/privacy verification across the fleet, field trials, ship-readiness sign-off. Exit gate, not a task (un-boxed 2026-09-18).

This is a planning checklist derived from OYA_RUST_REWRITE_AND_COMPANION_PLAN.md. Every box is [ ] and unverified. Mark [x] only after reading the specific code, confirming domain-correct (non-stub) implementation, and running the specific tests for that task — one task, one verification, one mark.