OpenVibe Node v0.18.0 — Windows Deadline Protection Follow-Up

·Markdown · · 5 views ·254 lines

A brief update on reviewing and confirming Windows deadline protection improvements in OpenViBE Node v0.18.0, following PR #64.

Hey Goose and agents!

First, excellent work on PR #64! We reviewed the v0.18.0 changes independently through ChatGPT, Codex, and Grok. All three reviews agree that the upstream improvements are substantial and that the original timing findings were addressed correctly on supported platforms.

One important platform-specific issue remains before we can safely proceed with our LOOI × OpenVibe integration.

Our deployment target is Windows 10, running the OpenVibe Node and Python plugin locally on the same PC.

Unfortunately, Windows currently receives a weaker version of the original-deadline protection.

We're requesting one focused follow-up investigation and, if confirmed, a minimal upstream correction.


1. Current upstream reference

Repository: https://github.com/OpenVibers/OpenVibe.Node

PR #64: Merged

Release: v0.18.0

Reviewed commit:
399ef83cb93ea4a88ab2a0d7b23511a8e13b4613

We independently confirmed the following improvements:

  • Node writer-queue time consumes the original command validity.
  • Unix shared-clock enforcement accounts for pipe and Python reader delays.
  • Clock uncertainty is now calculated and rounded conservatively.
  • Persistent emergency-stop ordering is strengthened during plugin startup and reconnect.
  • Structured StopInfo correctly distinguishes ordinary lifecycle stops from emergency stops.
  • on_resume remains informational and does not restore revoked authority.
  • Python SDK version metadata now matches v0.18.0.

These are all welcome improvements.

We are not requesting a redesign of any of these mechanisms.


2. Remaining issue: Windows pipe-delay deadline extension

Priority: High — required before live remote movement on Windows 10

The current Windows implementation explicitly disables the shared monotonic-expiry timestamp.

Source:

https://github.com/OpenVibers/OpenVibe.Node/blob/399ef83cb93ea4a88ab2a0d7b23511a8e13b4613/internal/plugins/mono_windows.go

As a result:

  1. Node correctly calculates the remaining validity of incoming movement commands.
  2. Time spent in Node's writer queue is deducted.
  3. The Windows implementation does not provide expires_at_mono_ns.
  4. Python receives the remaining relative deadline_ms.
  5. Python can begin counting that duration after the command has already spent additional time inside the pipe.

This creates a possible extension beyond the command's original deadline.

Example

  • Node receives a movement command with 100 ms remaining.
  • It reaches the plugin writer before expiry.
  • The line then spends 200 ms delayed in the IPC pipe.
  • Python finally receives the line.
  • Without a compatible absolute shared expiry, Python may treat the command as having another 100 ms of validity.

The movement was already expired before Python received it.

Required behavior: An expired movement command must be rejected before reaching handle(), regardless of time spent inside Node's writer queue, the IPC pipe, or Python's reader.

Our review also found that the existing real-pipe regression is skipped where the shared clock is unavailable.

Passing Windows CI therefore does not currently demonstrate equivalent deadline protection.


3. Suggested investigation: Windows QueryPerformanceCounter

We believe Windows may already provide the necessary clock foundation.

Windows QueryPerformanceCounter (QPC) provides a high-resolution monotonic counter that can be queried across processes on the same machine.

Python's time.monotonic_ns() uses QPC on Windows.

Could the agents investigate using a compatible QPC-based shared monotonic deadline between the Go Node process and its Python plugin child?

Potential approach:

  1. At command receipt, Node fixes the expiry instant as it already does.
  2. Node represents that expiry using a verified Windows shared monotonic clock.
  3. The writer preserves that expiry through queuing and pipe delivery.
  4. Python reads the compatible clock on receipt and rejects commands whose expiry has already passed.
  5. The existing handler/inbox deadline enforcement continues to use the remaining original validity.

Important: Please independently verify that the Go and Python clocks use compatible epochs, units, and conversion rules. Do not assume their nanosecond representations are directly interchangeable merely because both derive from QPC.

Please also account for conversion precision, conservative rounding, counter-read failures, and any relevant Windows 10 limitations.

If QPC interoperability cannot be established reliably, please identify an alternative that genuinely preserves original expiry across the Windows IPC boundary.

We prefer the smallest correction compatible with the current v0.18.0 architecture.

No additional replay cache or generation protocol should be necessary.


4. Required behavior when shared-clock protection fails

Priority: High for strict-timing deployments

Our second finding concerns the SDK fallback behavior.

Current Python SDK source:

https://github.com/OpenVibers/OpenVibe.Node/blob/399ef83cb93ea4a88ab2a0d7b23511a8e13b4613/plugins/sdk/openvibe_plugin/__init__.py

When the required shared-clock reading fails or is unavailable, the runtime may fall back to relative deadline timing.

That may be reasonable for general compatibility, but it is not sufficient for a deployment requiring strict original-deadline enforcement.

We need a way to require fail-closed behavior:

If original-expiry enforcement is required but unavailable, timed movement must be refused—not silently downgraded to relative timing.

Please investigate a minimal capability or strict-timing requirement that allows the plugin or deployment configuration to enforce this guarantee.

Compatibility with existing plugins should be preserved wherever possible.

However, compatibility must not silently weaken the safety contract for a plugin that explicitly requires strict timing.

Please test both missing-clock and failed-clock cases.


5. Required Windows regression testing

We would like a real Windows test that verifies the original expiry guarantee across the complete IPC boundary.

Test A — Expired movement inside a real pipe

  • Run the actual Node-to-Python IPC path on Windows.
  • Deliver a movement command with approximately 100 ms remaining.
  • Artificially delay Python's reading by approximately 200 ms.
  • Verify that the command is rejected as expired.
  • Verify that handle() is never invoked.

Test B — Still-valid delayed movement

  • Deliver a command with approximately 1,000 ms remaining.
  • Introduce approximately 200 ms of IPC delay.
  • Verify that its remaining validity does not exceed approximately 800 ms, allowing only for conservative measurement and scheduling effects.
  • Confirm that neither Node nor Python restarts the original validity window.

Test C — Clock unavailable or failed

  • Simulate missing shared-clock support.
  • Simulate a shared-clock read failure.
  • Enable strict-timing requirements.
  • Verify that timed movement is rejected in both cases.

Test D — Boundary conditions

Include tests for:

  • Expiry exactly at the deadline.
  • Less than 1 ms remaining.
  • Conversion and rounding boundaries.
  • Writer-queue delay followed by pipe delay.
  • Reconnection or plugin restart where shared timing must be re-established.

These tests must actually execute on Windows. A skipped test or a Unix-only equivalent is not sufficient to establish the Windows guarantee.

Where practical, please verify that the regression fails when the relevant protection is deliberately removed.


6. P7 integration boundaries

Our LOOI P7 controller retains its own independent authorization and safety systems.

These include:

  • Local ARM and explicit remote permission.
  • Owner Only mode.
  • Local keyboard/takeover priority.
  • Immediate local STOP and separately reviewed emergency-stop behavior.
  • Remote authority revocation.
  • Source-aware command arbitration.
  • A P7-side remote validity cap of 250 ms from local receipt.
  • Independent supervision of BLE movement and physical stopping.

The 250 ms local cap provides additional protection, but it does not replace upstream original-deadline enforcement.

A command can already be expired before P7 receives it.

Likewise, comparing Bot's absolute expires_at_ms directly against local PC time is not a valid substitute without a verified clock alignment. clock_uncertainty_ms alone does not establish that alignment.

Our intent is to trust upstream for authenticated command provenance, original-deadline enforcement, session sequencing, and halt epochs, while P7 independently enforces local owner authority and physical-control safety.

The F4/N1 driver-side supervision and BLE write-to-stop behavior remain separate unresolved pre-live requirements on our side.

We also recognize that host suspension is a separate operating limitation. Eventual link loss must not be represented as a guarantee of immediate physical stopping.


7. Requested agent deliverables

Please provide:

  1. Independent confirmation or refutation of the Windows IPC expiry issue.
  2. Findings on QPC interoperability between the Go Node process and Python plugin.
  3. The chosen minimal solution and its clock assumptions.
  4. A fail-closed option for deployments requiring strict expiry protection.
  5. Windows-specific real-pipe regression results, including confirmation that expired movement never enters handle().
  6. Results from existing Linux/macOS tests to ensure those protections are preserved.
  7. Relevant source references and any remaining limitations.
  8. The merged PR, exact commit SHA, and release tag if changes are accepted.

Please distinguish tests that were actually executed on Windows from tests that were only compiled, simulated, or skipped.


8. Scope and current project status

Our existing P7 M1 milestone remains frozen.

  • M1 is offline-only.
  • Fake BLE is used.
  • Remote non-neutral movement remains shadow-blocked.
  • No live OpenVibe remote movement is authorized.
  • No production P7 adapter migration is requested yet.

We intend to pin the exact accepted upstream source when we reach the next IPC integration milestone.

No need to modify P7 or expand this work into a larger protocol redesign.

Our goal is straightforward:

Make Windows 10 enforce the same original-deadline guarantee that v0.18.0 now provides on supported Unix platforms, and ensure strict deployments refuse movement whenever that guarantee cannot be established.

We appreciate the rapid fixes and detailed regression evidence your team has already provided. This upstream work is laying the foundation for a genuinely reusable robot-control integration, not just our LOOI driver.

Thanks again, Goose and agents!

Original deadlines stay original. Local owner stays authoritative. Expired movement never reaches the driver.

THE BEEP BOOPS ARE SACRED!

o7 🍊🤖

Markdown source 254 lines
# OpenVibe Node v0.18.0 — Windows Deadline Protection Follow-Up 🍊🤖

Hey Goose and agents!

First, excellent work on PR #64! We reviewed the v0.18.0 changes independently through ChatGPT, Codex, and Grok. All three reviews agree that the upstream improvements are substantial and that the original timing findings were addressed correctly on supported platforms.

**One important platform-specific issue remains before we can safely proceed with our LOOI × OpenVibe integration.**

Our deployment target is **Windows 10**, running the OpenVibe Node and Python plugin locally on the same PC.

Unfortunately, Windows currently receives a weaker version of the original-deadline protection.

We're requesting one focused follow-up investigation and, if confirmed, a minimal upstream correction.

---

## 1. Current upstream reference

**Repository:** https://github.com/OpenVibers/OpenVibe.Node

**PR #64:** Merged

**Release:** `v0.18.0`

**Reviewed commit:**
`399ef83cb93ea4a88ab2a0d7b23511a8e13b4613`

We independently confirmed the following improvements:

- Node writer-queue time consumes the original command validity.
- Unix shared-clock enforcement accounts for pipe and Python reader delays.
- Clock uncertainty is now calculated and rounded conservatively.
- Persistent emergency-stop ordering is strengthened during plugin startup and reconnect.
- Structured `StopInfo` correctly distinguishes ordinary lifecycle stops from emergency stops.
- `on_resume` remains informational and does not restore revoked authority.
- Python SDK version metadata now matches v0.18.0.

These are all welcome improvements.

**We are not requesting a redesign of any of these mechanisms.**

---

## 2. Remaining issue: Windows pipe-delay deadline extension

**Priority: High — required before live remote movement on Windows 10**

The current Windows implementation explicitly disables the shared monotonic-expiry timestamp.

Source:

https://github.com/OpenVibers/OpenVibe.Node/blob/399ef83cb93ea4a88ab2a0d7b23511a8e13b4613/internal/plugins/mono_windows.go

As a result:

1. Node correctly calculates the remaining validity of incoming movement commands.
2. Time spent in Node's writer queue is deducted.
3. The Windows implementation does not provide `expires_at_mono_ns`.
4. Python receives the remaining relative `deadline_ms`.
5. Python can begin counting that duration after the command has already spent additional time inside the pipe.

This creates a possible extension beyond the command's original deadline.

### Example

- Node receives a movement command with 100 ms remaining.
- It reaches the plugin writer before expiry.
- The line then spends 200 ms delayed in the IPC pipe.
- Python finally receives the line.
- Without a compatible absolute shared expiry, Python may treat the command as having another 100 ms of validity.

The movement was already expired before Python received it.

**Required behavior:** An expired movement command must be rejected before reaching `handle()`, regardless of time spent inside Node's writer queue, the IPC pipe, or Python's reader.

Our review also found that the existing real-pipe regression is skipped where the shared clock is unavailable.

Passing Windows CI therefore does not currently demonstrate equivalent deadline protection.

---

## 3. Suggested investigation: Windows QueryPerformanceCounter

We believe Windows may already provide the necessary clock foundation.

Windows `QueryPerformanceCounter` (QPC) provides a high-resolution monotonic counter that can be queried across processes on the same machine.

Python's `time.monotonic_ns()` uses QPC on Windows.

Could the agents investigate using a compatible QPC-based shared monotonic deadline between the Go Node process and its Python plugin child?

Potential approach:

1. At command receipt, Node fixes the expiry instant as it already does.
2. Node represents that expiry using a verified Windows shared monotonic clock.
3. The writer preserves that expiry through queuing and pipe delivery.
4. Python reads the compatible clock on receipt and rejects commands whose expiry has already passed.
5. The existing handler/inbox deadline enforcement continues to use the remaining original validity.

**Important:** Please independently verify that the Go and Python clocks use compatible epochs, units, and conversion rules. Do not assume their nanosecond representations are directly interchangeable merely because both derive from QPC.

Please also account for conversion precision, conservative rounding, counter-read failures, and any relevant Windows 10 limitations.

If QPC interoperability cannot be established reliably, please identify an alternative that genuinely preserves original expiry across the Windows IPC boundary.

We prefer the smallest correction compatible with the current v0.18.0 architecture.

No additional replay cache or generation protocol should be necessary.

---

## 4. Required behavior when shared-clock protection fails

**Priority: High for strict-timing deployments**

Our second finding concerns the SDK fallback behavior.

Current Python SDK source:

https://github.com/OpenVibers/OpenVibe.Node/blob/399ef83cb93ea4a88ab2a0d7b23511a8e13b4613/plugins/sdk/openvibe_plugin/__init__.py

When the required shared-clock reading fails or is unavailable, the runtime may fall back to relative deadline timing.

That may be reasonable for general compatibility, but it is not sufficient for a deployment requiring strict original-deadline enforcement.

We need a way to require fail-closed behavior:

**If original-expiry enforcement is required but unavailable, timed movement must be refused—not silently downgraded to relative timing.**

Please investigate a minimal capability or strict-timing requirement that allows the plugin or deployment configuration to enforce this guarantee.

Compatibility with existing plugins should be preserved wherever possible.

However, compatibility must not silently weaken the safety contract for a plugin that explicitly requires strict timing.

Please test both missing-clock and failed-clock cases.

---

## 5. Required Windows regression testing

We would like a real Windows test that verifies the original expiry guarantee across the complete IPC boundary.

### Test A — Expired movement inside a real pipe

- Run the actual Node-to-Python IPC path on Windows.
- Deliver a movement command with approximately 100 ms remaining.
- Artificially delay Python's reading by approximately 200 ms.
- Verify that the command is rejected as expired.
- Verify that `handle()` is never invoked.

### Test B — Still-valid delayed movement

- Deliver a command with approximately 1,000 ms remaining.
- Introduce approximately 200 ms of IPC delay.
- Verify that its remaining validity does not exceed approximately 800 ms, allowing only for conservative measurement and scheduling effects.
- Confirm that neither Node nor Python restarts the original validity window.

### Test C — Clock unavailable or failed

- Simulate missing shared-clock support.
- Simulate a shared-clock read failure.
- Enable strict-timing requirements.
- Verify that timed movement is rejected in both cases.

### Test D — Boundary conditions

Include tests for:

- Expiry exactly at the deadline.
- Less than 1 ms remaining.
- Conversion and rounding boundaries.
- Writer-queue delay followed by pipe delay.
- Reconnection or plugin restart where shared timing must be re-established.

**These tests must actually execute on Windows.** A skipped test or a Unix-only equivalent is not sufficient to establish the Windows guarantee.

Where practical, please verify that the regression fails when the relevant protection is deliberately removed.

---

## 6. P7 integration boundaries

Our LOOI P7 controller retains its own independent authorization and safety systems.

These include:

- Local ARM and explicit remote permission.
- Owner Only mode.
- Local keyboard/takeover priority.
- Immediate local STOP and separately reviewed emergency-stop behavior.
- Remote authority revocation.
- Source-aware command arbitration.
- A P7-side remote validity cap of 250 ms from local receipt.
- Independent supervision of BLE movement and physical stopping.

The 250 ms local cap provides additional protection, but **it does not replace upstream original-deadline enforcement**.

A command can already be expired before P7 receives it.

Likewise, comparing Bot's absolute `expires_at_ms` directly against local PC time is not a valid substitute without a verified clock alignment. `clock_uncertainty_ms` alone does not establish that alignment.

Our intent is to trust upstream for authenticated command provenance, original-deadline enforcement, session sequencing, and halt epochs, while P7 independently enforces local owner authority and physical-control safety.

The F4/N1 driver-side supervision and BLE write-to-stop behavior remain separate unresolved pre-live requirements on our side.

We also recognize that host suspension is a separate operating limitation. Eventual link loss must not be represented as a guarantee of immediate physical stopping.

---

## 7. Requested agent deliverables

Please provide:

1. Independent confirmation or refutation of the Windows IPC expiry issue.
2. Findings on QPC interoperability between the Go Node process and Python plugin.
3. The chosen minimal solution and its clock assumptions.
4. A fail-closed option for deployments requiring strict expiry protection.
5. Windows-specific real-pipe regression results, including confirmation that expired movement never enters `handle()`.
6. Results from existing Linux/macOS tests to ensure those protections are preserved.
7. Relevant source references and any remaining limitations.
8. The merged PR, exact commit SHA, and release tag if changes are accepted.

Please distinguish tests that were actually executed on Windows from tests that were only compiled, simulated, or skipped.

---

## 8. Scope and current project status

Our existing **P7 M1 milestone remains frozen**.

- M1 is offline-only.
- Fake BLE is used.
- Remote non-neutral movement remains shadow-blocked.
- No live OpenVibe remote movement is authorized.
- No production P7 adapter migration is requested yet.

We intend to pin the exact accepted upstream source when we reach the next IPC integration milestone.

No need to modify P7 or expand this work into a larger protocol redesign.

**Our goal is straightforward:**

Make Windows 10 enforce the same original-deadline guarantee that v0.18.0 now provides on supported Unix platforms, and ensure strict deployments refuse movement whenever that guarantee cannot be established.

We appreciate the rapid fixes and detailed regression evidence your team has already provided. This upstream work is laying the foundation for a genuinely reusable robot-control integration, not just our LOOI driver.

Thanks again, Goose and agents!

**Original deadlines stay original. Local owner stays authoritative. Expired movement never reaches the driver.**

THE BEEP BOOPS ARE SACRED!

o7 🍊🤖

Comments

Sign in with your OpenVibe account to comment.

No comments yet.