Stabilize NeuroRift↔OpenClaw runtime: sandboxing, approval forwarding, and deterministic compose#26
Conversation
|
CodeAnt AI is reviewing your PR. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
📝 WalkthroughWalkthroughThis pull request stabilizes the NeuroRift and OpenClaw integration by introducing production-hardened runtime controls, structured logging, approval workflows, heartbeat discipline, and deterministic Docker orchestration. Configuration, deployment definitions, documentation, and core adapter logic are updated to enforce security policies, sandbox isolation, and lifecycle management across the unified system. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as WebSocket Client
participant Adapter as NeuroRiftOpenClawAdapter
participant Policy as Policy Validator
participant Approver as ExecutionApprovalForwarder
participant Logger as StructuredLogger
participant Gateway as OpenClaw Gateway
Client->>Adapter: rpc.request event
Adapter->>Adapter: resolve session context
Adapter->>Policy: validate exec policy<br/>(allow/deny, terminal-only)
Policy-->>Adapter: policy status
alt High-Risk Command
Adapter->>Logger: log approval request
Adapter->>Approver: evaluate(command, session_id,<br/>correlation_id)
Approver->>Logger: log approval decision
Approver-->>Adapter: ApprovalResult
alt Approved
Adapter->>Adapter: build RPC frame
Adapter->>Logger: log execution
Adapter->>Gateway: send frame with sandbox params
else Not Approved
Adapter->>Logger: log approval rejection
Adapter->>Gateway: send approval-required response
end
else Standard Command
Adapter->>Adapter: build RPC frame
Adapter->>Logger: log execution
Adapter->>Gateway: send frame
end
par Concurrent Heartbeat Loop
Adapter->>Adapter: heartbeat interval elapsed
Adapter->>Logger: emit heartbeat event
Adapter->>Gateway: send heartbeat frame
end
Gateway-->>Client: response/heartbeat
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
|
|
Overall Grade Focus Area: Complexity |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| Python | Feb 27, 2026 12:52p.m. | Review ↗ |
Nitpicks 🔍
|
|
CodeAnt AI finished reviewing your PR. |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (1)
integrations/openclaw/openclaw_gateway_adapter.py (1)
30-60: Policy is duplicated in code instead of sourced from runtime config.These hardcoded allow/deny/risk patterns can drift from
openclaw.json5and weaken policy governance over time.Load these values from
OPENCLAW_CONFIG_PATH(with safe defaults), then enforce using the loaded policy set.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@integrations/openclaw/openclaw_gateway_adapter.py` around lines 30 - 60, Replace the hardcoded policy constants DEFAULT_TOOL_ALLOW, DEFAULT_TOOL_DENY, and HIGH_RISK_PATTERNS with values loaded at runtime from the OPENCLAW_CONFIG_PATH JSON5 config (falling back to the existing defaults if the file/members are missing or invalid); implement a loader function (e.g., load_openclaw_policy) that reads OPENCLAW_CONFIG_PATH, parses json5, validates keys (allow/deny/high_risk_patterns), compiles regex strings into regex objects for HIGH_RISK_PATTERNS, and exposes a policy object used everywhere the code currently references DEFAULT_TOOL_ALLOW/DEFAULT_TOOL_DENY/HIGH_RISK_PATTERNS (keep TOOL_METHOD_MAP as-is unless specified in config), and ensure any failures to read/parse the config log a warning and use the safe defaults.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@BOOT.md`:
- Around line 26-55: The runbook currently starts core services twice; update
BOOT.md to present two mutually exclusive modes — e.g., "all-docker" and
"local-adapter" — and move commands into mode-specific sections so each service
is started only once: put the `docker compose up -d --build gateway
neurorift-core rust-engine web-ui ollama sandbox-runner` and `docker compose ps`
health check under the "all-docker" mode, and under a separate "local-adapter"
mode include `python3 modules/web/bridge_server.py`, `curl -s
http://127.0.0.1:8766/health`, `openclaw gateway --config ./openclaw.json5`, and
`python3 integrations/openclaw/openclaw_gateway_adapter.py`; ensure you add a
short note at the top instructing users to choose one mode and remove duplicated
startup steps for `gateway`/`neurorift-core` between modes.
In `@docker-compose.yml`:
- Line 86: The gateway service currently uses a mutable image tag
("neurorift/openclaw:latest"); update the gateway image reference to an
immutable identifier by replacing the :latest tag with a concrete version tag or
an image digest (e.g., neurorift/openclaw:vX.Y.Z or
neurorift/openclaw@sha256:<digest>) so deployments are deterministic and do not
drift.
- Line 79: The healthcheck in docker-compose.yml currently uses a CMD-SHELL that
depends on /dev/tcp (see the healthcheck test entry around the existing "test:
[\"CMD-SHELL\", \"curl -sf http://localhost:8765/health 2>/dev/null || (echo
>/dev/tcp/localhost/8765) 2>/dev/null || exit 1\"]"), which is shell-dependent
and can false-fail; fix by removing /dev/tcp usage and making the probe
portable: either (A) ensure the container images guarantee a bash-compatible
shell by adding an explicit SHELL or bash installation in the related
Dockerfile(s) (so /bin/bash is available), or (B) replace the CMD-SHELL
healthcheck with a pure binary probe that exists in the image (e.g., use
curl/wget/nc in the healthcheck command), and apply the same change for the
other healthcheck instance (the similar entry referenced at line 105). Ensure
the chosen probe (curl/wget/nc) is installed in the image or the Dockerfile is
updated accordingly so the healthcheck will not rely on /dev/tcp.
In `@integrations/openclaw/openclaw_gateway_adapter.py`:
- Around line 409-415: The receive loop around ws.recv/json.loads and the rpc
handling (calls to json.loads, event.get, _build_rpc_frame, and ws.send) is
unprotected and a malformed frame or policy exception can unwind the loop; wrap
the json.loads + event parsing and the await self._build_rpc_frame(...) / await
ws.send(...) calls in a try/except that catches broad exceptions (at least
Exception), logs the error (include the raw incoming string and exception) and
continues the loop instead of letting the exception propagate, and optionally
send a safe error-response frame when appropriate; apply the same protection to
the other receive branch around the code at lines ~430-440 so both places use
identical try/except resilience around parsing and frame-building/sending.
- Around line 183-187: The approval flow currently auto-denies immediately
because the code uses await asyncio.sleep(0) before creating the ApprovalResult;
change this to actually wait for the configured timeout (e.g., await
asyncio.sleep(timeout_seconds)) or use an awaitable that respects
timeout_seconds (for example asyncio.wait_for or waiting on the human approval
event with timeout_seconds) so the ApprovalResult(approved=False, reason=...) is
only created after the timeout elapses; update the block around result =
ApprovalResult(...) in openclaw_gateway_adapter.py (the approval routine that
references timeout_seconds and ApprovalResult) to wait the configured duration
rather than sleeping 0 seconds.
- Around line 274-281: The _validate_exec_policy function currently only
inspects the first token allowing command chaining to bypass policy; update
_validate_exec_policy to reject or safely parse commands containing shell
metacharacters (e.g., ;, &&, ||, |, ``, $(), &, >, <, \n) or any
subshell/redirect constructs and raise PermissionError when such operators are
present, or alternatively split the command into discrete tokens and validate
every executable token against DEFAULT_TOOL_DENY and DEFAULT_TOOL_ALLOW; target
the _validate_exec_policy function and the constants DEFAULT_TOOL_DENY /
DEFAULT_TOOL_ALLOW to ensure every potential executed program is checked rather
than only the initial token.
In `@openclaw.json5`:
- Line 202: The absoluteTimes entry for id "daily-summary" uses a past timestamp
(at: "2026-01-01T00:00:00Z") which can trigger missed or immediate catch-up
runs; update the absoluteTimes configuration (the object with id "daily-summary"
and its at field) to a future ISO8601 timestamp or replace it with a
relative/recurring schedule instead so the scheduler won't treat it as a past
event.
In `@scripts/openclaw_doctor.py`:
- Around line 44-47: The preflight currently only warns when required ports are
occupied; change the logic so that after computing collisions = [port for port
in PORTS if _port_in_use(port)] the script prints an error (not just a warn) and
exits with a non-zero status (e.g., sys.exit(1)) when collisions is non-empty;
update the branch that handles collisions to use PORTS, _port_in_use and
collisions to emit a clear error message listing the ports and then terminate
the process with a failing exit code.
---
Nitpick comments:
In `@integrations/openclaw/openclaw_gateway_adapter.py`:
- Around line 30-60: Replace the hardcoded policy constants DEFAULT_TOOL_ALLOW,
DEFAULT_TOOL_DENY, and HIGH_RISK_PATTERNS with values loaded at runtime from the
OPENCLAW_CONFIG_PATH JSON5 config (falling back to the existing defaults if the
file/members are missing or invalid); implement a loader function (e.g.,
load_openclaw_policy) that reads OPENCLAW_CONFIG_PATH, parses json5, validates
keys (allow/deny/high_risk_patterns), compiles regex strings into regex objects
for HIGH_RISK_PATTERNS, and exposes a policy object used everywhere the code
currently references DEFAULT_TOOL_ALLOW/DEFAULT_TOOL_DENY/HIGH_RISK_PATTERNS
(keep TOOL_METHOD_MAP as-is unless specified in config), and ensure any failures
to read/parse the config log a warning and use the safe defaults.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
BOOT.mddocker-compose.dev.ymldocker-compose.ymldocs/OPENCLAW_INTEGRATION_AUDIT.mdintegrations/openclaw/openclaw_gateway_adapter.pyopenclaw.json5scripts/openclaw_doctor.py
| ## 2) Start deterministic Docker runtime | ||
|
|
||
| ```bash | ||
| curl -s http://127.0.0.1:8766/health | ||
| docker compose up -d --build gateway neurorift-core rust-engine web-ui ollama sandbox-runner | ||
| ``` | ||
|
|
||
| ## 3) Start OpenClaw gateway | ||
| Verify service health: | ||
|
|
||
| ```bash | ||
| docker compose ps | ||
| ``` | ||
|
|
||
| Use your OpenClaw runtime with the unified config: | ||
| ## 3) Start NeuroRift FastAPI bridge | ||
|
|
||
| ```bash | ||
| openclaw gateway --config ./openclaw.json5 | ||
| python3 modules/web/bridge_server.py | ||
| ``` | ||
|
|
||
| ## 4) Start the adapter bridge | ||
| Health check: | ||
|
|
||
| ```bash | ||
| curl -s http://127.0.0.1:8766/health | ||
| ``` | ||
|
|
||
| ## 4) Start OpenClaw gateway and adapter | ||
|
|
||
| ```bash | ||
| openclaw gateway --config ./openclaw.json5 | ||
| python3 integrations/openclaw/openclaw_gateway_adapter.py | ||
| ``` |
There was a problem hiding this comment.
Runbook currently starts core components twice (container + host).
Step 2 already starts gateway/neurorift-core; Step 3/4 then starts bridge/gateway again manually. This creates conflicting runtime paths and ambiguous troubleshooting.
Please split the guide into explicit mutually-exclusive modes (e.g., all-docker vs local-adapter) and keep only one startup path per mode.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@BOOT.md` around lines 26 - 55, The runbook currently starts core services
twice; update BOOT.md to present two mutually exclusive modes — e.g.,
"all-docker" and "local-adapter" — and move commands into mode-specific sections
so each service is started only once: put the `docker compose up -d --build
gateway neurorift-core rust-engine web-ui ollama sandbox-runner` and `docker
compose ps` health check under the "all-docker" mode, and under a separate
"local-adapter" mode include `python3 modules/web/bridge_server.py`, `curl -s
http://127.0.0.1:8766/health`, `openclaw gateway --config ./openclaw.json5`, and
`python3 integrations/openclaw/openclaw_gateway_adapter.py`; ensure you add a
short note at the top instructing users to choose one mode and remove duplicated
startup steps for `gateway`/`neurorift-core` between modes.
| healthcheck: | ||
| # TCP-level check: try to open port 8765 | ||
| test: [ "CMD-SHELL", "curl -sf http://localhost:8765/health 2>/dev/null || (echo >/dev/tcp/localhost/8765) 2>/dev/null || exit 1" ] | ||
| test: ["CMD-SHELL", "curl -sf http://localhost:8765/health 2>/dev/null || (echo >/dev/tcp/localhost/8765) 2>/dev/null || exit 1"] |
There was a problem hiding this comment.
Healthchecks rely on /dev/tcp, which is shell-dependent and can false-fail.
Line 79 and Line 105 depend on /dev/tcp; this is not portable across all /bin/sh implementations and can keep healthy services marked unhealthy.
Run this read-only verification to confirm whether the image/tooling guarantees support for these probes.
Expected result: either explicit bash/SHELL support or a portable probe binary (curl/wget/nc) used in healthchecks.
#!/bin/bash
set -euo pipefail
echo "== Compose healthchecks using /dev/tcp =="
rg -n 'dev/tcp|healthcheck' docker-compose.yml -C2
echo
echo "== Dockerfile shell/probe capabilities =="
for f in $(fd -a 'Dockerfile' docker | sort); do
echo "--- $f"
rg -n '^(FROM|SHELL|RUN .*bash|RUN .*curl|RUN .*wget|RUN .*nc|RUN .*netcat)' "$f" || true
doneAlso applies to: 105-105
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docker-compose.yml` at line 79, The healthcheck in docker-compose.yml
currently uses a CMD-SHELL that depends on /dev/tcp (see the healthcheck test
entry around the existing "test: [\"CMD-SHELL\", \"curl -sf
http://localhost:8765/health 2>/dev/null || (echo >/dev/tcp/localhost/8765)
2>/dev/null || exit 1\"]"), which is shell-dependent and can false-fail; fix by
removing /dev/tcp usage and making the probe portable: either (A) ensure the
container images guarantee a bash-compatible shell by adding an explicit SHELL
or bash installation in the related Dockerfile(s) (so /bin/bash is available),
or (B) replace the CMD-SHELL healthcheck with a pure binary probe that exists in
the image (e.g., use curl/wget/nc in the healthcheck command), and apply the
same change for the other healthcheck instance (the similar entry referenced at
line 105). Ensure the chosen probe (curl/wget/nc) is installed in the image or
the Dockerfile is updated accordingly so the healthcheck will not rely on
/dev/tcp.
| start_period: 45s | ||
|
|
||
| gateway: | ||
| image: neurorift/openclaw:latest |
There was a problem hiding this comment.
Pin gateway image to an immutable version (not latest).
Line 86 currently uses a mutable tag, which conflicts with deterministic runtime guarantees and can drift between deployments.
Suggested patch
- image: neurorift/openclaw:latest
+ image: "neurorift/openclaw:${OPENCLAW_IMAGE_TAG:?set OPENCLAW_IMAGE_TAG}"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| image: neurorift/openclaw:latest | |
| image: "neurorift/openclaw:${OPENCLAW_IMAGE_TAG:?set OPENCLAW_IMAGE_TAG}" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docker-compose.yml` at line 86, The gateway service currently uses a mutable
image tag ("neurorift/openclaw:latest"); update the gateway image reference to
an immutable identifier by replacing the :latest tag with a concrete version tag
or an image digest (e.g., neurorift/openclaw:vX.Y.Z or
neurorift/openclaw@sha256:<digest>) so deployments are deterministic and do not
drift.
| # Human callback hook should flip result in external controller. | ||
| await asyncio.sleep(0) | ||
| return ApprovalResult(approved=False, reason="approval pending/timeout -> deny") | ||
| result = ApprovalResult( | ||
| approved=False, reason="approval pending/timeout -> deny" | ||
| ) |
There was a problem hiding this comment.
Approval flow ignores configured timeout and auto-denies immediately.
Lines 183–187 never wait for timeout_seconds; high-risk commands are denied right away, not on timeout.
Minimal behavior-alignment patch
- await asyncio.sleep(0)
+ await asyncio.sleep(self.timeout_seconds)
result = ApprovalResult(
- approved=False, reason="approval pending/timeout -> deny"
+ approved=False, reason="approval timeout -> deny"
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Human callback hook should flip result in external controller. | |
| await asyncio.sleep(0) | |
| return ApprovalResult(approved=False, reason="approval pending/timeout -> deny") | |
| result = ApprovalResult( | |
| approved=False, reason="approval pending/timeout -> deny" | |
| ) | |
| # Human callback hook should flip result in external controller. | |
| await asyncio.sleep(self.timeout_seconds) | |
| result = ApprovalResult( | |
| approved=False, reason="approval timeout -> deny" | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@integrations/openclaw/openclaw_gateway_adapter.py` around lines 183 - 187,
The approval flow currently auto-denies immediately because the code uses await
asyncio.sleep(0) before creating the ApprovalResult; change this to actually
wait for the configured timeout (e.g., await asyncio.sleep(timeout_seconds)) or
use an awaitable that respects timeout_seconds (for example asyncio.wait_for or
waiting on the human approval event with timeout_seconds) so the
ApprovalResult(approved=False, reason=...) is only created after the timeout
elapses; update the block around result = ApprovalResult(...) in
openclaw_gateway_adapter.py (the approval routine that references
timeout_seconds and ApprovalResult) to wait the configured duration rather than
sleeping 0 seconds.
| def _validate_exec_policy(self, command: str) -> None: | ||
| base_cmd = command.strip().split()[0] if command.strip() else "" | ||
| if not base_cmd: | ||
| raise ValueError("Empty exec command") | ||
| if base_cmd in DEFAULT_TOOL_DENY: | ||
| raise PermissionError(f"Tool denied by policy: {base_cmd}") | ||
| if base_cmd not in DEFAULT_TOOL_ALLOW: | ||
| raise PermissionError(f"Tool not in allow-list: {base_cmd}") |
There was a problem hiding this comment.
Allow/deny policy is bypassable via command chaining.
Line 275 only checks the first token. A payload like nmap ...; shutdown now passes base-command allow checks while still executing forbidden operations.
Suggested hardening patch
import os
import re
+import shlex
import signal
@@
def _validate_exec_policy(self, command: str) -> None:
- base_cmd = command.strip().split()[0] if command.strip() else ""
- if not base_cmd:
+ raw = command.strip()
+ if not raw:
raise ValueError("Empty exec command")
+ if any(op in raw for op in (";", "&&", "||", "|", "`", "$(", ">", "<")):
+ raise PermissionError("Shell operators are not allowed in exec commands")
+ try:
+ parts = shlex.split(raw, posix=True)
+ except ValueError as exc:
+ raise PermissionError("Malformed exec command") from exc
+ base_cmd = os.path.basename(parts[0]) if parts else ""
if base_cmd in DEFAULT_TOOL_DENY:
raise PermissionError(f"Tool denied by policy: {base_cmd}")
if base_cmd not in DEFAULT_TOOL_ALLOW:
raise PermissionError(f"Tool not in allow-list: {base_cmd}")🧰 Tools
🪛 Ruff (0.15.2)
[warning] 277-277: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 279-279: Avoid specifying long messages outside the exception class
(TRY003)
[warning] 281-281: Avoid specifying long messages outside the exception class
(TRY003)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@integrations/openclaw/openclaw_gateway_adapter.py` around lines 274 - 281,
The _validate_exec_policy function currently only inspects the first token
allowing command chaining to bypass policy; update _validate_exec_policy to
reject or safely parse commands containing shell metacharacters (e.g., ;, &&,
||, |, ``, $(), &, >, <, \n) or any subshell/redirect constructs and raise
PermissionError when such operators are present, or alternatively split the
command into discrete tokens and validate every executable token against
DEFAULT_TOOL_DENY and DEFAULT_TOOL_ALLOW; target the _validate_exec_policy
function and the constants DEFAULT_TOOL_DENY / DEFAULT_TOOL_ALLOW to ensure
every potential executed program is checked rather than only the initial token.
| incoming = await ws.recv() | ||
| event = json.loads(incoming) | ||
| event_type = event.get("type") | ||
|
|
||
| if event_type == "rpc.request": | ||
| frame = await self._build_rpc_frame(event) | ||
| await ws.send(json.dumps(frame)) |
There was a problem hiding this comment.
Malformed or policy-failing frames can crash the main receive loop.
Line 410 and Line 414 are not protected. A bad frame or policy exception can unwind the loop and prematurely stop the adapter.
Suggested resilience patch
import asyncio
+import contextlib
import json
@@
while not self._stop_event.is_set():
incoming = await ws.recv()
- event = json.loads(incoming)
+ try:
+ event = json.loads(incoming)
+ except json.JSONDecodeError:
+ self.logger.emit("gateway.invalid_json", raw=str(incoming)[:256])
+ continue
event_type = event.get("type")
@@
if event_type == "rpc.request":
- frame = await self._build_rpc_frame(event)
+ try:
+ frame = await self._build_rpc_frame(event)
+ except (ValueError, PermissionError) as exc:
+ frame = {
+ "type": "rpc.response",
+ "id": str(event.get("id") or uuid.uuid4()),
+ "error": {"code": "policy_error", "message": str(exc)},
+ }
await ws.send(json.dumps(frame))
@@
finally:
lifecycle_task.cancel()
- await ws.send(
+ with contextlib.suppress(asyncio.CancelledError):
+ await lifecycle_task
+ if not ws.closed:
+ await ws.send(
json.dumps(
{
"type": "lifecycle.update",
"state": "stopped",
"session": {"id": self.session_id, "mode": "isolated"},
}
)
)Also applies to: 430-440
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@integrations/openclaw/openclaw_gateway_adapter.py` around lines 409 - 415,
The receive loop around ws.recv/json.loads and the rpc handling (calls to
json.loads, event.get, _build_rpc_frame, and ws.send) is unprotected and a
malformed frame or policy exception can unwind the loop; wrap the json.loads +
event parsing and the await self._build_rpc_frame(...) / await ws.send(...)
calls in a try/except that catches broad exceptions (at least Exception), logs
the error (include the raw incoming string and exception) and continues the loop
instead of letting the exception propagate, and optionally send a safe
error-response frame when appropriate; apply the same protection to the other
receive branch around the code at lines ~430-440 so both places use identical
try/except resilience around parsing and frame-building/sending.
| }, | ||
| ], | ||
| relativeIntervals: [{ id: "heartbeat-cycle", every: "15m", mode: "isolated" }], | ||
| absoluteTimes: [{ id: "daily-summary", at: "2026-01-01T00:00:00Z", mode: "isolated" }], |
There was a problem hiding this comment.
absoluteTimes is configured to a past timestamp.
Line 202 uses 2026-01-01T00:00:00Z, which is already in the past as of February 27, 2026. This can cause missed schedules or immediate catch-up behavior.
Suggested patch
- absoluteTimes: [{ id: "daily-summary", at: "2026-01-01T00:00:00Z", mode: "isolated" }],
+ absoluteTimes: [{ id: "daily-summary", at: "2026-03-01T00:00:00Z", mode: "isolated" }],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| absoluteTimes: [{ id: "daily-summary", at: "2026-01-01T00:00:00Z", mode: "isolated" }], | |
| absoluteTimes: [{ id: "daily-summary", at: "2026-03-01T00:00:00Z", mode: "isolated" }], |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@openclaw.json5` at line 202, The absoluteTimes entry for id "daily-summary"
uses a past timestamp (at: "2026-01-01T00:00:00Z") which can trigger missed or
immediate catch-up runs; update the absoluteTimes configuration (the object with
id "daily-summary" and its at field) to a future ISO8601 timestamp or replace it
with a relative/recurring schedule instead so the scheduler won't treat it as a
past event.
| collisions = [port for port in PORTS if _port_in_use(port)] | ||
| if collisions: | ||
| print(f"[WARN] Ports currently in use: {', '.join(map(str, collisions))}") | ||
| else: |
There was a problem hiding this comment.
Port collisions should fail mandatory preflight, not just warn.
Lines 44–47 currently keep exit code 0 when required ports are occupied, which weakens the preflight gate.
Suggested patch
collisions = [port for port in PORTS if _port_in_use(port)]
if collisions:
- print(f"[WARN] Ports currently in use: {', '.join(map(str, collisions))}")
+ print(f"[FAIL] Ports currently in use: {', '.join(map(str, collisions))}")
+ return 1
else:
print("[OK] No expected runtime ports in use")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| collisions = [port for port in PORTS if _port_in_use(port)] | |
| if collisions: | |
| print(f"[WARN] Ports currently in use: {', '.join(map(str, collisions))}") | |
| else: | |
| collisions = [port for port in PORTS if _port_in_use(port)] | |
| if collisions: | |
| print(f"[FAIL] Ports currently in use: {', '.join(map(str, collisions))}") | |
| return 1 | |
| else: |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/openclaw_doctor.py` around lines 44 - 47, The preflight currently
only warns when required ports are occupied; change the logic so that after
computing collisions = [port for port in PORTS if _port_in_use(port)] the script
prints an error (not just a warn) and exits with a non-zero status (e.g.,
sys.exit(1)) when collisions is non-empty; update the branch that handles
collisions to use PORTS, _port_in_use and collisions to emit a clear error
message listing the ports and then terminate the process with a failing exit
code.
User description
Motivation
Description
BOOT.mdto require normalized runtime env, runscripts/openclaw_doctor.pyfor preflight checks, and usedocker compose up -d --build gateway neurorift-core rust-engine web-ui ollama sandbox-runnerfor deterministic startup.docker-compose.ymlanddocker-compose.dev.ymlto rename services (neurorift->neurorift-core,openclaw->rust-engine), addgatewayandsandbox-runnerservices, tighten healthchecks, consolidate volumes, and update service env/ports for consistent wiring.integrations/openclaw/openclaw_gateway_adapter.pyto add strict environment normalization, structured logging, session context resolution, terminal-only execution policy, tool allow/deny lists, high-risk pattern detection, approval forwarding with event emissions, heartbeat emission, lifecycle handling, and safer RPC frame construction.openclaw.json5with a visiblesystemPrompt, operator and sandbox policies, approvalForwarder configuration, heartbeat and scheduling guards, observability event emission, evolution controls, and runtime mode isolation flags.scripts/openclaw_doctor.pyas a preflight checker for required env variables and runtime port collisions and addeddocs/OPENCLAW_INTEGRATION_AUDIT.mddocumenting the stabilization scope and residual risks.Testing
python3 scripts/openclaw_doctor.pyas a preflight check to validate required environment variables and port availability and observed successful completion (exit 0) in local verification.docker compose configand confirmed the updateddocker-compose.ymlloads without configuration errors.Codex Task
CodeAnt-AI Description
Stabilize NeuroRift↔OpenClaw runtime with sandboxed execution, approval forwarding, and startup validation
What Changed
Impact
✅ Fewer startup failures due to missing env or port collisions✅ Safer command execution with explicit allow/deny and human approval✅ Clearer operational events for audits and troubleshooting💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.
Summary by CodeRabbit
Documentation
New Features
Chores