Skip to content

clarus — PoC Roadmap: CAP Vista Submission to 6-Month Audit Log

  • Updated: 2026-04-27 (input adapter complete)
  • Scope: Phase 0 (build → submit) through Phase 2 (PoC site → actuarial-grade data)
  • Hard deadlines: PIER71: 15 June 2026 · CAP Vista: 30 June 2026

Architecture in one diagram

flowchart TD
    SIM["Simulation"]
    VID["Video"]
    NAV["Navigation Signal"]
    PTS["Point Sensor"]

    ES["EntityStream<br/>id · type · pos · vel · timestamp"]

    subgraph Engine["Rust Logic Engine  ❰never changes❱"]
        P["Physics<br/>distance · rel_velocity<br/>braking_dist · TTC · zone"]
        RU["Rules<br/>rules.json evaluation"]
    end

    RE["RiskEvent<br/>rule_id · value · threshold<br/>regulation_citation · severity"]

    subgraph Explanation["LLM Explanation  ❰local · no cloud❱"]
        RAG["Regulatory RAG<br/>KB snippet retrieval"]
        LLM["Local LLM<br/>Mistral / Llama 3"]
    end

    subgraph Audit["edgesentry-audit  ❰BLAKE3 + Ed25519❱"]
        SEAL["seal(payload, prev_hash, key)"]
    end

    AR["AuditRecord<br/>timestamp · rule · measured_value<br/>regulation_citation · sensor_hash<br/>prev_hash · signature"]

    subgraph Output["Output Adapter"]
        DASH["Alert dashboard<br/>+ MOM Report PDF"]
        CHAIN["Tamper-proof<br/>AuditRecord chain"]
        API["Webhook / MQTT<br/>→ PSA CITOS / VTS"]
    end

    SIM --> ES
    VID --> ES
    NAV --> ES
    PTS --> ES
    ES --> P
    P --> RU
    RU --> RE
    RE --> RAG
    RAG --> LLM
    LLM --> SEAL
    RE --> SEAL
    SEAL --> AR
    AR --> DASH
    AR --> CHAIN
    AR --> API

    style Engine fill:#1a1a2e,color:#e0e0e0,stroke:#4a4a8a
    style Audit fill:#0f3460,color:#e0e0e0,stroke:#4a4a8a
    style SIM fill:#2d2d2d,color:#aaaaaa,stroke:#555555

Invariant: the Rust engine and audit layer never change across inputs. The Input Adapter normalises any source into EntityStream — the engine sees only positions, velocities, and timestamps regardless of sensor type.


Input Adapter — source types

Categories are defined by data modality (what the signal is), not by use case or industry.

Simulation — synthetic coordinates (dev/test only)

Source Phase Notes
Unity UDP coords Phase 0 Simulation output at 10 Hz; never deployed in production
CSV / JSON replay Dev / test Deterministic regression testing from recorded sessions

Video — pixel frames requiring vision model

Source Phase Notes
Video file upload Phase 0 demo Offline analysis; same adapter as RTSP without live streaming
Webcam / smartphone IP camera Phase 0 dev Home miniature verification; same YOLOv8 + tracker pipeline as RTSP; scale defined in profiles/home-test/params.toml
RTSP stream — IP camera Phase 2 Existing CCTV; vision model (YOLOv8) + tracker → EntityStream
RTSP stream — thermal camera Phase 2 Same adapter as IP camera; perimeter / night operations
Source Phase Notes
AIS NMEA 0183 Phase 2 Vessel position and kinematics; Rust re-implementation of arktrace logic
Radar track data Phase 2+ Vessel or vehicle detection; ASTERIX or proprietary format
GPS / GNSS Phase 2+ Vehicle or worker outdoor positioning
UWB tag Phase 2+ Sub-metre indoor worker/vehicle position; low latency
RFID tag Phase 2+ Zone-level worker/vehicle identification and position

Point sensor — spatial ranging or zone trigger hardware

Source Phase Notes
LiDAR 2D/3D Phase 2+ Hokuyo; direct entity positioning — no vision model required
Area sensor / light curtain Phase 2+ Omron; boolean zone breach maps directly to zone_membership rule

Phase 0 — Build and Submit (now → 30 June 2026)

Exit criteria: CAP Vista submitted. PIER71 submitted if incorporation is complete by 8 June.

Week 1–2: Rust engine + Unity input (due: 11 May)

Goal: EntityStreamRiskEvent. No vision, no LLM. Deterministic and testable.

Tasks:

  • [x] crates/input-adapter/src/unity_udp.rs — UDP receiver, deserialise JSON into EntityStream (PR #10, 13 tests passing)
  • [x] crates/engine/src/physics.rs — implement: (PR #7, 39 tests passing)
  • euclidean_distance(a: &Entity, b: &Entity) -> f32
  • relative_velocity(a: &Entity, b: &Entity) -> f32
  • braking_distance(speed: f32, entity_class: EntityClass) -> f32
  • time_to_collision(distance: f32, approach_rate: f32) -> f32
  • zone_membership(pos: Vec2, polygon: &[Vec2]) -> bool
  • [x] crates/engine/src/rules.rs — load rules.json, evaluate each rule against EntityStream, emit RiskEvent (PR #8, 21 tests passing)
  • [x] profiles/sg-port-safety/rules.json — 3 seed rules encoded (PR #8):
    { "rule_id": "MPA_CLEARANCE_5M",      "condition": "distance < 5.0",  "severity": "HIGH",     "regulation": "MPA Port Safety Circular No. 14 of 2023 §3.1" }
    { "rule_id": "EXCLUSION_ZONE_BREACH", "condition": "zone_member",     "severity": "CRITICAL", "regulation": "PSA Terminal Safety Rules §4.2" }
    { "rule_id": "TTC_CRITICAL_3S",       "condition": "ttc < 3.0",       "severity": "HIGH",     "regulation": "MPA Port Safety Circular No. 14 of 2023 §3.2" }
    
  • [x] Unity scene: C# scripts + setup guide — ClarusUdpExporter.cs, ClarusEntity.cs, ForkliftPath.cs (PR #14, see unity/README.md)
  • [x] CLI binary (main.rs) + CSV file replay (file_replay.rs) — (PR #10)

Deliverable:cargo run --bin clarus -- --input file://fixtures/forklift_approach.csv --profile profiles/demo fires MPA_CLEARANCE_5M (HIGH) + TTC_CRITICAL_3S (HIGH) across all 15 frames; TTC drops 2.29 s → 0.89 s as FL-01 closes to 1.24 m. (86 tests passing across engine + adapter)

Live UDP: --input udp://127.0.0.1:9000 ready; requires Unity scene (issue #6 — pending).


Week 3–4: LLM explanation + regulatory RAG (due: 25 May)

Goal: RiskEvent → natural-language explanation with verifiable regulation citation.

Tasks:

  • [x] crates/explanation/src/llm.rs — Ollama HTTP client (POST /api/generate); model configurable, default llama3.2 (PR #13)
  • [x] crates/explanation/src/kb.rs — KB lookup: maps rule_id → text snippet from profiles/<profile>/kb/<RULE_ID>.txt (PR #13)
  • [x] crates/explanation/src/explainer.rs — orchestrates KB lookup → prompt → LLM → §N.N grounding check → Explanation (PR #13)
  • [x] profiles/sg-port-safety/kb/ — 3 seed files: MPA_CLEARANCE_5M.txt, TTC_CRITICAL_3S.txt, EXCLUSION_ZONE_BREACH.txt (PR #13)
  • [x] Grounding check: rejects LLM output if it cites a §N.N clause absent from the KB snippet (PR #13)
  • [x] --explain flag wired into clarus binary — --ollama-url and --model configurable (PR #13)
  • [ ] Pipe RiskEvent + explanation into edgesentry-audit::seal()AuditRecord

Deliverable:cargo run --bin clarus -- --input file://fixtures/forklift_approach.csv --profile profiles/demo --explain calls local Ollama for each RiskEvent and prints a grounded plain-language alert with / ⚠ ungrounded marker. (97 tests passing: 60 engine + 11 explanation + 26 adapter)

Remaining: AuditRecord seal (blocked on edgesentry-audit integration — Week 3–4 follow-on).


Week 5: Browser demo (due: 1 June)

Goal: end-to-end screen-recordable demo showing Flow 1 (live alerts) → Flow 2 (analytics).

Implemented (PR #52, merged 2026-05-02):

  • [x] analytics/ — Cloudflare Pages app (DuckDB WASM + Observable Plot, no build step)
  • [x] /live Operations Monitor — site status, calibration drift chart, evidence quality chart, alert table with filters
  • [x] /live LLM explanation — llama.cpp via Caddy HTTPS proxy; evidence quality sentence injected deterministically by JS; OPFS-backed cache
  • [x] / Risk Intelligence — 500-vessel fleet overview + per-vessel behavioral scorecard
  • [x] / Premium Impact — Traditional baseline ($180k) → EdgeSentry signals → $340k (+89%)
  • [x] Flow 1→2 link — V-001 alert links to MV Fortune Star MMSI 563012345
  • [x] edge/ — Rust edge daemon (CV sim → evaluate → sign → R2 upload) (#54)
  • [x] R2 infrastructure — clarus-dev-public-raw, clarus-dev-public-analytics, clarus-dev-public-audit (Object Lock) + naming convention documented
  • [x] scripts/run_llama.sh — llama-server + Caddy HTTPS proxy setup

Remaining:

  • [ ] /audit chain verification page — sequence continuity check + hash chain visual (#55)
  • [ ] Record 5-min demo video (Flow 1 → Flow 2, CAP Vista scenario)

Deployed at: https://feat-analytics-scorecard.clarus-analytics.pages.dev 3. (2:30–4:00) Click the event → explanation appears → regulation citation shown 4. (4:00–5:00) Click "Generate MOM Report" → PDF opens → run verify → green checkmark

Deliverable: demo-capvista-2026.mp4 (5 min, screen recording at 1080p).


Week 6: CAP Vista submission + PIER71 if eligible (due: 30 June)

CAP Vista (due 30 June):

  • [ ] Add Tier-2 security scenario to Unity scene: vessel entity approaching restricted zone polygon
  • [ ] Add profiles/sg-maritime-security/rules.json:
  • RESTRICTED_ZONE_APPROACH — CPA < 0.5 NM to defined polygon
  • AIS_TRACK_GAP — AIS silence > 8 min within port limits
  • [ ] Swap KB to profiles/sg-maritime-security/kb/ (COLREGs, Infrastructure Protection Act zones)
  • [ ] Adjust LLM prompt for security context ("threat actor" framing vs "worker safety" framing)
  • [ ] Complete application form narrative
  • [ ] Submit by 30 June, 13:00 SGT

PIER71 (due 15 June — only if incorporation confirmed by 8 June):

  • [ ] Reuse port safety demo (Tier-1 only; vessel scenario not required for PIER71-14)
  • [ ] Complete PIER71 application form
  • [ ] Submit by 15 June

If incorporation is not confirmed by 8 June: skip PIER71, redirect time to CAP Vista polish.


Phase 1 — Post-Submission Preparation (July – October 2026)

Exit criteria: PoC deployment package ready; Singapore port safety profile at production quality; first insurer contact made.

Production-quality profile

Production profiles with jurisdiction-specific regulatory citations are commercial IP and distributed separately. The profile format is documented in edgesentry-rs/docs/pipeline/profile-authoring.md.

  • [ ] Expand sg-port-safety profile from 3 seed rules to full set:
  • All MPA Port Safety Circular No. 14 of 2023 rules (§§3–7)
  • MOM WSH (Docks) Regulations §§12, 14, 18
  • Crane exclusion zone rules (swing radius by crane class)
  • Mooring line snap-back zone geometry
  • Gangway boarding swell check (if wave height sensor available)
  • [ ] Add params.toml — validated per-class braking distances:
  • Forklift 3.5T @ 10 km/h: 4.1 m
  • Reach stacker @ 15 km/h: 8.2 m
  • Terminal tractor @ 20 km/h: 12.4 m
  • Person (pedestrian): 0 (static threshold)
  • [ ] Add manifest.toml:
    jurisdiction = "SG"
    regulations = ["MPA-Circular-14-2023", "MOM-WSH-Docks-Regs-2020"]
    profile_version = "1.0.0"
    validated_date = "2026-07-01"
    

Actuarial-grade audit log

Implement the full AuditRecord schema (required for Phase 2 insurance contact):

pub struct AuditRecord {
    pub event_id:           Uuid,
    pub timestamp_utc:      DateTime<Utc>,      // millisecond precision
    pub rule_id:            String,
    pub regulation_citation: String,            // "MPA Port Safety Circular No. 14 of 2023 §3.1"
    pub measured_value:     serde_json::Value,  // { "clearance_m": 3.2, "ttc_s": 2.3 }
    pub threshold_value:    serde_json::Value,  // { "min_clearance_m": 5.0 }
    pub sensor_id:          String,
    pub sensor_hash:        String,             // SHA-256 of firmware version + config
    pub profile_version:    String,             // "sg-port-safety@1.0.0"
    pub model_version:      Option<String>,     // vision model hash (Phase 2)
    pub prev_record_hash:   String,             // BLAKE3 of previous AuditRecord
    pub signature:          String,             // Ed25519 over all above fields
}
  • [ ] Heartbeat records every 5 minutes (uptime proof)
  • [ ] edgesentry-audit verify-chain <log-file> — validates entire hash chain
  • [ ] Export: edgesentry-audit export --format wica — aligned with MOM WICA indicator definitions

PoC deployment package

  • [ ] deploy/README.md — step-by-step: install, configure sensor, start clarus, verify audit log
  • [ ] deploy/docker-compose.yml — clarus + edgesentry-audit + local log storage
  • [ ] deploy/sensor-test.sh — confirm Input Adapter is receiving EntityStream from site sensor
  • [ ] deploy/health-check.sh — confirm heartbeat records are writing, chain is valid

Phase 2 — PoC Execution (November 2026 – April 2027)

Exit criteria: 6 months of tamper-proof audit logs from 1–2 sites. Data packaged for actuarial presentation.

Per-site setup (1–2 weeks per site)

  • [ ] Identify sensor type at site: RTSP CCTV or AIS feed
  • [ ] Implement site-specific Input Adapter:
  • RTSP: crates/input-adapter/src/rtsp.rs — vision model (YOLOv8 export) + tracker → EntityStream
  • AIS: crates/input-adapter/src/ais_nmea.rs — NMEA 0183 decoder → EntityStream (Rust re-implementation of arktrace logic; arktrace itself is Python and not a runtime dependency)
  • [ ] Deploy production profile + run sensor-test.sh
  • [ ] First AuditRecord generated → run edgesentry-audit verify → confirm chain valid
  • [ ] Hand site contact the read-only audit log viewer URL

Monthly during PoC

Each month, run:

# Generate monthly summary for PoC site and CAP Vista coordinator
clarus report monthly \
  --log audit.db \
  --from 2026-11-01 --to 2026-11-30 \
  --format pdf \
  --out reports/2026-11-monthly.pdf

Report contains: - Total events by severity (CRITICAL / HIGH / MEDIUM / LOW) - Month-on-month trend - Top 3 rule IDs by frequency - Uptime percentage (heartbeat coverage) - Chain integrity: PASS / FAIL

Send to PoC site safety manager + CAP Vista programme coordinator.

Month 4–6: Insurer data preparation

Build the Actuarial Simulation Environment CLI:

# Insurer feeds historical incident CSV → physics engine re-runs each event
clarus actuarial-sim \
  --incidents historical_incidents_2022_2024.csv \
  --profile profiles/demo \
  --output actuarial_forecast_gard_2026.pdf

Output report structure: 1. Events re-run: N 2. Would have triggered HIGH/CRITICAL alert: X (Y%) 3. Median lead time before impact: Z seconds 4. Estimated incidents preventable per 100,000 man-hours: A 5. Corresponding expected claims reduction: SGD B / year (at insurer's own claim cost figures)

6-month data package (April 2027)

clarus-poc-results-2027-04/
  audit-chain.db          ← full 6-month AuditRecord chain
  chain-verify.txt        ← output of edgesentry-audit verify-chain (PASS)
  monthly-reports/        ← 6 × monthly PDFs
  actuarial-forecast.pdf  ← insurer simulation output
  profile-manifest.toml   ← exact rule set active throughout PoC
  sensor-config-hash.txt  ← SHA-256 of sensor firmware + config at each site

This package is the deliverable to CAP Vista, MPA, and the first insurer contact (Gard / Skuld / Sompo Japan Loss Prevention).


Definition of Done — per phase

Phase Done when
Phase 0 CAP Vista application submitted and receipt confirmed
Phase 1 deploy/ package on a clean machine produces a valid AuditRecord in < 30 minutes
Phase 2 edgesentry-audit verify-chain audit.db exits 0 on 6 months of records; actuarial-forecast.pdf generated

Scope boundary (hard)

In scope for Phase 0 Out of scope until Phase 2
Unity numeric input → RiskEvent Live RTSP CCTV stream inference
Local LLM (no cloud) Cloud sync or remote log storage
Browser demo + screen recording Mobile or embedded deployment
edgesentry-audit chain Multi-site log aggregation
PDF report generation Real-time API push to PSA CITOS / MPA VTS

Key dependencies

Dependency Source Notes
edgesentry-audit edgesentry/edgesentry-rs Production-ready; reuse from documaris
AIS parser crates/input-adapter/src/ais_nmea.rs Rust re-implementation of arktrace logic; arktrace (Python) is not a runtime dependency. If CPA/NMEA logic is later needed by other Rust projects, extract to a shared crate.
LLM runtime llama.cpp or mlx Apple Silicon; no cloud API
Vision model (Phase 2) YOLOv8n export (ONNX) Apache 2.0; fine-tune locally
Unity Unity 2023 LTS UDP export via custom C# component