Skip to content

refactor(core): validate object shapes at boundaries - #6640

Merged
cv merged 4 commits into
mainfrom
codex/refactor-object-record-guards
Jul 10, 2026
Merged

refactor(core): validate object shapes at boundaries#6640
cv merged 4 commits into
mainfrom
codex/refactor-object-record-guards

Conversation

@cv

@cv cv commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Consolidate ambiguous isRecord predicates into explicit isObjectRecord and isPlainObject helpers, then keep those checks at real trust boundaries. Serialized YAML, JSON, environment, and process data is validated once into a domain type; internal TypeScript paths trust that type instead of defensively rechecking it.

This also hardens malformed sandbox-registry normalization without changing supported user-facing configuration.

Changes

  • Add shared object-record helpers and semantic tests for the CLI, plugin, and Hermes compilation boundaries; retain the immutable integrity-pinned credential helper unchanged.
  • Decode messaging setup plans once through the canonical parseSandboxMessagingPlan boundary, removing the duplicate plan validator, nine typed-plan rechecks, and the custom recursive JSON-serializability walk.
  • Read the sandbox registry as unknown, validate its object shape and entries during load, and let typed serialization iterate SandboxRegistry directly.
  • Refine the OpenShell policy parser's return type so the runner can trust validated version and network_policies fields.
  • Remove object checks made redundant by TypeScript narrowing, successful native import(), and prior Hermes plan narrowing.
  • Require registry entry names to be nonblank and match their map keys, preserve stale-default diagnostics, and repair invalid defaults with the correct ownership revision on persistence.
  • Reject non-plain prototype objects at the OpenClaw config-merge boundary, where prototype identity is a real runtime invariant.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: a documentation-writer review confirmed that commands, flags, supported configuration, persisted schemas, and workflows are unchanged; the changes are internal boundary/type semantics.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: a full provenance audit classified each guard by input source, retained checks at external boundaries, and removed only checks proven redundant by validated domain types or language/runtime guarantees; CodeQL, CodeRabbit, and both PR review advisors pass on the final commit.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification: final focused suites passed 80 CLI tests, 55 integration tests, and 117 plugin tests; the previously flaky gateway-recovery file passed 11/11 locally.
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result: env -u SSH_CONNECTION -u SSH_CLIENT -u SSH_TTY npm run check passed on final commit af7907afc, including full CLI/integration and plugin coverage.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved and standardized validation for configuration, manifests, policies, messaging plans, and runtime data.
    • Rejected malformed or non-plain object shapes more consistently across parsing and merge flows.
    • Prevented stale sandbox default selections from being persisted, with stricter registry entry handling during normalization and merges.
    • Tightened enablement checks and serialization behavior for persisted registry state.
  • Tests
    • Added tests for object-record/plain-object guards.
    • Added/updated coverage for sandbox registry normalization and invalid config/merge inputs.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv self-assigned this Jul 10, 2026
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This change centralizes object-shape type guards, distinguishing general object records from plain objects. The guards are applied across Hermes, NemoClaw, messaging, state, registry, OpenClaw merge, scripts, tooling, and tests, with registry persistence behavior additionally updated and covered by new tests.

Changes

Object-shape validation

Layer / File(s) Summary
Shared guard contracts
src/lib/core/json-types.ts, nemoclaw/src/shared/object-record.ts, */object-record.test.ts
Adds isObjectRecord, isPlainObject, and shared record types, with tests covering prototypes, arrays, primitives, and null values.
Hermes and blueprint validation
agents/hermes/config/*, nemoclaw/src/blueprint/*, nemoclaw/src/onboard/config.ts
Replaces local guards with shared predicates and tightens blueprint, manifest, onboarding, migration, and state-patch shape checks.
Messaging and application validation
src/lib/messaging/*, src/lib/agent/*, src/lib/onboard/*, src/lib/policy/*, src/lib/security/*
Applies shared object-record checks to messaging plans, hooks, manifests, policies, provenance, frontmatter, and configuration merges.
State and registry behavior
src/lib/state/*
Uses shared guards for state and OpenClaw restoration flows, and validates sandbox entries while repairing stale default-sandbox persistence.
Tooling and test adapters
scripts/*, tools/*, test/*
Renames local predicates and updates script, advisor, benchmark, installer, and test-helper validation paths.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5174: Both changes update OpenClaw restored-config merge validation and helper usage.

Suggested labels: refactor

Suggested reviewers: ericksoa, jyaunches

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.39% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: strengthening object-shape validation at boundaries.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/refactor-object-record-guards

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the codex/refactor-objec... branch remains at 96%, unchanged from the main branch.

Show a code coverage summary of the most impacted files.
File main a3a2e4f codex/refactor-objec... af7907a +/-
nemoclaw/src/co...ration-state.ts 94% 94% 0%
nemoclaw/src/onboard/config.ts 98% 98% 0%
nemoclaw/src/bl...eprint/state.ts 98% 98% 0%
nemoclaw/src/sh...cy-boundary.cts 100% 100% 0%
nemoclaw/src/bl...print/runner.ts 95% 96% +1%
nemoclaw/src/sh...bject-record.ts 0% 100% +100%

TypeScript / code-coverage/cli

The overall coverage in the codex/refactor-objec... branch remains at 77%, unchanged from the main branch.

Show a code coverage summary of the most impacted files.
File main 2b84a04 codex/refactor-objec... af7907a +/-
src/lib/messagi...etup-applier.ts 90% 59% -31%
src/lib/state/o...oard-session.ts 82% 81% -1%
src/lib/state/o...config-merge.ts 91% 94% +3%
src/lib/state/registry.ts 78% 84% +6%
src/lib/actions...estore-phase.ts 87% 93% +6%
src/lib/sandbox...vileged-exec.ts 82% 89% +7%
src/lib/actions...de-preflight.ts 51% 60% +9%
src/lib/actions...confirmation.ts 69% 81% +12%
src/lib/actions...light-guards.ts 71% 88% +17%
src/lib/state/r...ormalization.ts 0% 100% +100%

Updated July 10, 2026 17:41 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: cloud-onboard, credential-sanitization, security-posture, channels-add-remove, channels-stop-start, full-e2e, hermes-e2e, inference-routing, network-policy, onboard-repair, onboard-resume, state-backup-restore, upgrade-stale-sandbox
Optional E2E: credential-migration, messaging-providers, rebuild-hermes, sandbox-operations

Dispatch hint: cloud-onboard,credential-sanitization,security-posture,channels-add-remove,channels-stop-start,full-e2e,hermes-e2e,inference-routing,network-policy,onboard-repair,onboard-resume,state-backup-restore,upgrade-stale-sandbox

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • cloud-onboard: Required by the deterministic risk plan for installer/platform changes in scripts/install.sh and validates full hosted onboarding on a clean supported host.
  • credential-sanitization: Required by the deterministic risk plan for credential/security-boundary changes to ensure plaintext credentials do not cross logs, snapshots, artifacts, or sandbox boundaries.
  • security-posture: Required by the deterministic risk plan for policy, shields, and credential-security changes; validates fail-closed posture for OpenClaw and Hermes sandboxes.
  • channels-add-remove: Required by the deterministic risk plan for messaging lifecycle changes; validates channel credentials, policy, runtime setup, and teardown through add/remove flows.
  • channels-stop-start: Required by the deterministic risk plan for messaging lifecycle changes; validates restart/stop/start restoration of configured channels.
  • full-e2e: Required by the deterministic risk plan for shared agent abstractions; validates OpenClaw onboarding readiness and a real assistant turn.
  • hermes-e2e: Required by the deterministic risk plan for shared agent and Hermes config changes; validates Hermes onboarding readiness and a real assistant turn.
  • inference-routing: Required by the deterministic risk plan for policy/preset changes; validates provider selection, reachability classification, and routing behavior.
  • network-policy: Required by the deterministic risk plan for inference-policy and OpenShell policy-boundary changes; validates intended egress is permitted and unintended egress is denied.
  • onboard-repair: Required by the deterministic risk plan for lifecycle-state changes; validates repair convergence from damaged or partial onboarding state.
  • onboard-resume: Required by the deterministic risk plan for lifecycle-state changes; validates resume convergence from interrupted onboarding state.
  • state-backup-restore: Required by the deterministic risk plan for upgrade/rebuild state preservation changes; validates snapshot and restore preserve intended user state.
  • upgrade-stale-sandbox: Required by the deterministic risk plan for upgrade/rebuild changes; validates stale runtime replacement while preserving user state and retryability.

Optional E2E

  • credential-migration: Migration-state credential stripping and config snapshot handling changed; this is useful adjacent coverage for legacy credential migration paths.
  • messaging-providers: Messaging provider plan validation and channel health hooks changed; this adds provider-specific placeholder/redaction confidence beyond the required lifecycle add/remove and stop/start jobs.
  • rebuild-hermes: Hermes config parsing and shared object-record helpers changed; this adds rebuild/backup hygiene confidence for Hermes beyond the required steady-state Hermes E2E.
  • sandbox-operations: Sandbox registry/state code changed; this provides adjacent live coverage for process/gateway recovery and sandbox operation behavior.

New E2E recommendations

  • None.

Dispatch hint

  • Workflow: .github/workflows/e2e.yaml
  • jobs input: cloud-onboard,credential-sanitization,security-posture,channels-add-remove,channels-stop-start,full-e2e,hermes-e2e,inference-routing,network-policy,onboard-repair,onboard-resume,state-backup-restore,upgrade-stale-sandbox

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

E2E Target Recommendation

Required E2E targets: cloud-onboard, credential-sanitization, security-posture, channels-add-remove, channels-stop-start, full-e2e, hermes-e2e, inference-routing, network-policy, onboard-repair, onboard-resume, state-backup-restore, upgrade-stale-sandbox, e2e-all
Optional E2E targets: None

Dispatch required E2E targets:

  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=credential-sanitization
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=security-posture
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=channels-add-remove
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=channels-stop-start
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=full-e2e
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-e2e
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=inference-routing
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=network-policy
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=state-backup-restore
  • gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox
  • gh workflow run e2e.yaml --ref <pr-head-ref>

Workflow run

Full E2E target advisor summary

E2E Target Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E targets

  • cloud-onboard: Installer and platform changes must work on a clean supported host with the pinned runtime dependencies.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=cloud-onboard
  • credential-sanitization: Credential and security-boundary changes must preserve secrecy, sanitization, and fail-closed policy behavior.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=credential-sanitization
  • security-posture: Credential and security-boundary changes must preserve secrecy, sanitization, and fail-closed policy behavior.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=security-posture
  • channels-add-remove: Messaging changes must preserve the manifest-to-policy-to-runtime lifecycle through restart and removal.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=channels-add-remove
  • channels-stop-start: Messaging changes must preserve the manifest-to-policy-to-runtime lifecycle through restart and removal.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=channels-stop-start
  • full-e2e: Shared agent abstractions must retain equivalent lifecycle behavior for OpenClaw and Hermes.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=full-e2e
  • hermes-e2e: Shared agent abstractions must retain equivalent lifecycle behavior for OpenClaw and Hermes.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=hermes-e2e
  • inference-routing: Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=inference-routing
  • network-policy: Inference selection, reachability, and network policy must agree at the real host-to-sandbox boundary.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=network-policy
  • onboard-repair: Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-repair
  • onboard-resume: Onboarding and sandbox state must converge across persisted metadata, reported status, and the live runtime.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=onboard-resume
  • state-backup-restore: Upgrade, rebuild, snapshot, and restore operations must preserve user state while replacing stale runtime state.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=state-backup-restore
  • upgrade-stale-sandbox: Upgrade, rebuild, snapshot, and restore operations must preserve user state while replacing stale runtime state.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref> --field jobs=upgrade-stale-sandbox
  • e2e-all: test/e2e/registry/manifests.ts changes target registry manifest validation, which is shared E2E target registry machinery; policy requires the full e2e-all fan-out.
    • Dispatch: gh workflow run e2e.yaml --ref <pr-head-ref>

Optional E2E targets

  • None.

Relevant changed files

  • agents/hermes/config/build-env.ts
  • agents/hermes/config/hermes-config.ts
  • agents/hermes/config/model-specific-setup.ts
  • agents/hermes/config/object-record.ts
  • nemoclaw/src/blueprint/runner.ts
  • nemoclaw/src/blueprint/state.ts
  • nemoclaw/src/commands/migration-state.ts
  • nemoclaw/src/onboard/config.ts
  • nemoclaw/src/shared/object-record.ts
  • nemoclaw/src/shared/openshell-policy-boundary.cts
  • scripts/install.sh
  • src/lib/agent/manifest-readers.ts
  • src/lib/agent/runtime-manifest.ts
  • src/lib/messaging/applier/agent-config.ts
  • src/lib/messaging/applier/setup-applier.ts
  • src/lib/messaging/channels/openclaw-bridge-health.ts
  • src/lib/messaging/channels/slack/hooks/socket-mode-gateway-conflict.ts
  • src/lib/messaging/channels/slack/hooks/socket-mode-gateway-status.ts
  • src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts
  • src/lib/messaging/channels/telegram/hooks/get-me-reachability.ts
  • src/lib/messaging/channels/telegram/hooks/openclaw-bridge-health.ts
  • src/lib/messaging/compiler/engines/agent-render-engine.ts
  • src/lib/messaging/plan-validation.ts
  • src/lib/onboard/agents-manifest.ts
  • src/lib/onboard/initial-policy.ts
  • src/lib/policy/preset-parsing.ts
  • src/lib/policy/tiers.ts
  • src/lib/security/credential-filter.ts
  • src/lib/shields/index.ts
  • src/lib/shields/timer-control.ts
  • src/lib/shields/timer.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/openclaw-config-merge.ts
  • src/lib/state/openclaw-plugin-restore.ts
  • src/lib/state/registry-mcp.ts
  • src/lib/state/registry-normalization.ts
  • src/lib/state/registry.ts
  • src/lib/state/sandbox.ts
  • test/e2e/registry/manifests.ts

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: Add or justify PRA-T1 and any related test follow-ups.
Open items: 0 required · 0 warnings · 0 suggestions · 5 test follow-ups
Since last review: 0 prior items resolved · 0 still apply · 0 new items found

Action checklist

  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Run the `cloud-onboard` E2E job for Installer and platform changes must work on a clean supported host with the pinned runtime dependencies. Matched files: `scripts/install.sh`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Focused checked-in tests cover the localized refactor and malformed-state behavior, but the risk plan is tier 3 and spans live host/sandbox/network-policy boundaries. Required job execution was not observed or claimed in this static review.
  • PRA-T2 Runtime validation — Run the `cloud-onboard` E2E job to validate a clean supported host installs the intended pinned dependencies and reaches a usable agent after the scripts/install.sh registry-inspection change.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Focused checked-in tests cover the localized refactor and malformed-state behavior, but the risk plan is tier 3 and spans live host/sandbox/network-policy boundaries. Required job execution was not observed or claimed in this static review.
  • PRA-T3 Runtime validation — Run the `credential-sanitization` E2E job for Credential and security-boundary changes must preserve secrecy, sanitization, and fail-closed policy behavior. Matched files: `src/lib/policy/preset-parsing.ts`, `src/lib/policy/tiers.ts`, `src/lib/security/credential-filter.ts`, `src/lib/shields/index.ts`, `src/lib/shields/timer-control.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Focused checked-in tests cover the localized refactor and malformed-state behavior, but the risk plan is tier 3 and spans live host/sandbox/network-policy boundaries. Required job execution was not observed or claimed in this static review.
  • PRA-T4 Runtime validation — Run the `credential-sanitization` E2E job to validate plaintext credentials do not cross logs, snapshots, artifacts, or sandbox boundaries after credential/security-boundary guard changes.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Focused checked-in tests cover the localized refactor and malformed-state behavior, but the risk plan is tier 3 and spans live host/sandbox/network-policy boundaries. Required job execution was not observed or claimed in this static review.
  • PRA-T5 Runtime validation — Run the `security-posture` E2E job for Credential and security-boundary changes must preserve secrecy, sanitization, and fail-closed policy behavior. Matched files: `src/lib/policy/preset-parsing.ts`, `src/lib/policy/tiers.ts`, `src/lib/security/credential-filter.ts`, `src/lib/shields/index.ts`, `src/lib/shields/timer-control.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Focused checked-in tests cover the localized refactor and malformed-state behavior, but the risk plan is tier 3 and spans live host/sandbox/network-policy boundaries. Required job execution was not observed or claimed in this static review.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: Add or justify PRA-T1 and any related test follow-ups.
Open items: 0 required · 0 warnings · 0 suggestions · 5 test follow-ups
Since last review: 1 prior item resolved · 0 still apply · 0 new items found

Action checklist

  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Run the `cloud-onboard` E2E job for Installer and platform changes must work on a clean supported host with the pinned runtime dependencies. Matched files: `scripts/install.sh`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Deterministic regression risks require live validation across 7 risk families (lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security) with 13 required E2E jobs as validation floor. Unit tests cover guard semantics but cannot verify host-to-sandbox network policy agreement, credential sanitization across logs/snapshots, installer on clean host, channel lifecycle through restart/removal, or shared agent runtime equivalence.
  • PRA-T2 Runtime validation — Run the `credential-sanitization` E2E job for Credential and security-boundary changes must preserve secrecy, sanitization, and fail-closed policy behavior. Matched files: `src/lib/policy/preset-parsing.ts`, `src/lib/policy/tiers.ts`, `src/lib/security/credential-filter.ts`, `src/lib/shields/index.ts`, `src/lib/shields/timer-control.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Deterministic regression risks require live validation across 7 risk families (lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security) with 13 required E2E jobs as validation floor. Unit tests cover guard semantics but cannot verify host-to-sandbox network policy agreement, credential sanitization across logs/snapshots, installer on clean host, channel lifecycle through restart/removal, or shared agent runtime equivalence.
  • PRA-T3 Runtime validation — Run the `security-posture` E2E job for Credential and security-boundary changes must preserve secrecy, sanitization, and fail-closed policy behavior. Matched files: `src/lib/policy/preset-parsing.ts`, `src/lib/policy/tiers.ts`, `src/lib/security/credential-filter.ts`, `src/lib/shields/index.ts`, `src/lib/shields/timer-control.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Deterministic regression risks require live validation across 7 risk families (lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security) with 13 required E2E jobs as validation floor. Unit tests cover guard semantics but cannot verify host-to-sandbox network policy agreement, credential sanitization across logs/snapshots, installer on clean host, channel lifecycle through restart/removal, or shared agent runtime equivalence.
  • PRA-T4 Runtime validation — Run the `channels-add-remove` E2E job for Messaging changes must preserve the manifest-to-policy-to-runtime lifecycle through restart and removal. Matched files: `src/lib/messaging/applier/agent-config.ts`, `src/lib/messaging/applier/setup-applier.ts`, `src/lib/messaging/channels/openclaw-bridge-health.ts`, `src/lib/messaging/channels/slack/hooks/socket-mode-gateway-conflict.ts`, `src/lib/messaging/channels/slack/hooks/socket-mode-gateway-status.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Deterministic regression risks require live validation across 7 risk families (lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security) with 13 required E2E jobs as validation floor. Unit tests cover guard semantics but cannot verify host-to-sandbox network policy agreement, credential sanitization across logs/snapshots, installer on clean host, channel lifecycle through restart/removal, or shared agent runtime equivalence.
  • PRA-T5 Runtime validation — Run the `channels-stop-start` E2E job for Messaging changes must preserve the manifest-to-policy-to-runtime lifecycle through restart and removal. Matched files: `src/lib/messaging/applier/agent-config.ts`, `src/lib/messaging/applier/setup-applier.ts`, `src/lib/messaging/channels/openclaw-bridge-health.ts`, `src/lib/messaging/channels/slack/hooks/socket-mode-gateway-conflict.ts`, `src/lib/messaging/channels/slack/hooks/socket-mode-gateway-status.ts`.. Deterministic regression risks require live validation: lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security. Deterministic regression risks require live validation across 7 risk families (lifecycle-state, upgrade-rebuild, shared-agent, inference-policy, messaging-lifecycle, platform-install, credentials-security) with 13 required E2E jobs as validation floor. Unit tests cover guard semantics but cannot verify host-to-sandbox network policy agreement, credential sanitization across logs/snapshots, installer on clean host, channel lifecycle through restart/removal, or shared agent runtime equivalence.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator Author

PR Review Advisor follow-up:

  • PRA-1 is addressed in 7fbd958dc: registry entry/default normalization helpers moved to src/lib/state/registry-normalization.ts. src/lib/state/registry.ts is now 729 lines versus 731 on origin/main (down from 755 in the first revision). Focused registry tests passed 15/15; CLI type-check, Biome, diff checks, and normal commit/pre-push hooks also passed.
  • PRA-2 / PRA-T2 / PRA-T6 are already covered and do not reflect changed behavior. The scripts/install.sh diff only renames the local predicate from isRecord to isObjectRecord; key/name validation plus count and ambiguous-names behavior already exist on origin/main. test/install-openshell-upgrade-prompt.test.ts sources the real installer and covers legacy ambiguous rows, malformed JSON, mismatched key/name fail-closed behavior, and a validated empty registry count. Its focused integration run passed 17/17. No duplicate harness was added for the symbol-only rename.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts (1)

211-229: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Extract duplicated parseRegistryEntries into a shared helper.

The guard swap to isObjectRecord is fine, but this whole function (and its TeamsHostForwardPortConflictRegistryEntry-shaped type) is duplicated verbatim in src/lib/messaging/channels/slack/hooks/socket-mode-gateway-conflict.ts and socket-mode-gateway-status.ts. Consolidating into a shared messaging-hook utility would avoid future drift between channels for this security-relevant registry-entry parsing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts` around
lines 211 - 229, Extract the duplicated parseRegistryEntries logic and its
registry-entry type into a shared messaging-hook utility, then import and reuse
that helper from the Teams hook and both Slack hooks
(socket-mode-gateway-conflict.ts and socket-mode-gateway-status.ts). Preserve
the existing isObjectRecord validation, name checks, and messaging.plan
extraction so all channels use identical parsing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/install.sh`:
- Around line 1710-1712: Update isObjectRecord or the associated registry-name
validation around entry.name to reject names that are empty or contain only
whitespace, using a trimmed-value check before accepting the record. Ensure the
validation used by upgrade/count decisions enforces the nonblank-name invariant.

---

Outside diff comments:
In `@src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts`:
- Around line 211-229: Extract the duplicated parseRegistryEntries logic and its
registry-entry type into a shared messaging-hook utility, then import and reuse
that helper from the Teams hook and both Slack hooks
(socket-mode-gateway-conflict.ts and socket-mode-gateway-status.ts). Preserve
the existing isObjectRecord validation, name checks, and messaging.plan
extraction so all channels use identical parsing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ab486c12-6553-4a65-9f51-f580f18454ed

📥 Commits

Reviewing files that changed from the base of the PR and between 2b84a04 and 2c07ab0.

📒 Files selected for processing (55)
  • agents/hermes/config/build-env.ts
  • agents/hermes/config/hermes-config.ts
  • agents/hermes/config/model-specific-setup.ts
  • agents/hermes/config/object-record.ts
  • nemoclaw/src/blueprint/runner.ts
  • nemoclaw/src/blueprint/state.ts
  • nemoclaw/src/commands/migration-state.ts
  • nemoclaw/src/onboard/config.ts
  • nemoclaw/src/shared/object-record.test.ts
  • nemoclaw/src/shared/object-record.ts
  • scripts/bench/lib.ts
  • scripts/check-test-file-size-budget.ts
  • scripts/install.sh
  • scripts/patch-openclaw-tool-catalog.js
  • scripts/validate-openclaw-tool-search.mts
  • src/lib/agent/manifest-readers.ts
  • src/lib/agent/runtime-manifest.ts
  • src/lib/core/json-types.test.ts
  • src/lib/core/json-types.ts
  • src/lib/messaging/applier/agent-config.ts
  • src/lib/messaging/applier/setup-applier.ts
  • src/lib/messaging/channels/openclaw-bridge-health.ts
  • src/lib/messaging/channels/slack/hooks/socket-mode-gateway-conflict.ts
  • src/lib/messaging/channels/slack/hooks/socket-mode-gateway-status.ts
  • src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts
  • src/lib/messaging/channels/telegram/hooks/get-me-reachability.ts
  • src/lib/messaging/channels/telegram/hooks/openclaw-bridge-health.ts
  • src/lib/messaging/compiler/engines/agent-render-engine.ts
  • src/lib/messaging/plan-validation.ts
  • src/lib/onboard/agents-manifest.ts
  • src/lib/onboard/initial-policy.ts
  • src/lib/openclaw/agent-json-provenance.ts
  • src/lib/policy/preset-parsing.ts
  • src/lib/policy/tiers.ts
  • src/lib/security/credential-filter.ts
  • src/lib/shields/index.ts
  • src/lib/shields/timer-control.ts
  • src/lib/shields/timer.ts
  • src/lib/skill-install.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/openclaw-config-merge.test.ts
  • src/lib/state/openclaw-config-merge.ts
  • src/lib/state/openclaw-plugin-restore.ts
  • src/lib/state/registry-mcp.ts
  • src/lib/state/registry-normalization.test.ts
  • src/lib/state/registry.ts
  • src/lib/state/sandbox.ts
  • src/lib/status-command-deps.ts
  • src/lib/tunnel/services.ts
  • test/credential-rotation.test.ts
  • test/e2e/registry/manifests.ts
  • test/messaging-plan-test-helper.ts
  • tools/advisors/json.mts
  • tools/e2e-advisor/post-merge-risk-gate.mts
  • tools/pr-review-advisor/analyze.mts

Comment thread scripts/install.sh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/state/registry-normalization.ts`:
- Around line 27-30: Update the default sandbox validation logic to verify that
defaultSandbox is an own property of sandboxes before reading
sandboxes[defaultSandbox]. In the relevant normalization function, use an
ownership check such as Object.prototype.hasOwnProperty.call, then retain the
existing entry and pendingRouteReservation checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 78a5e903-dd3f-44d4-a44e-4df144d87091

📥 Commits

Reviewing files that changed from the base of the PR and between 2c07ab0 and 7fbd958.

📒 Files selected for processing (2)
  • src/lib/state/registry-normalization.ts
  • src/lib/state/registry.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/state/registry.ts

Comment thread src/lib/state/registry-normalization.ts Outdated
cv added 2 commits July 10, 2026 09:37
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv changed the title refactor(core): distinguish object record guards refactor(core): validate object shapes at boundaries Jul 10, 2026
@cv
cv merged commit bce8c8b into main Jul 10, 2026
51 checks passed
@cv
cv deleted the codex/refactor-object-record-guards branch July 10, 2026 17:50
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Consolidate ambiguous `isRecord` predicates into explicit
`isObjectRecord` and `isPlainObject` helpers, then keep those checks at
real trust boundaries. Serialized YAML, JSON, environment, and process
data is validated once into a domain type; internal TypeScript paths
trust that type instead of defensively rechecking it.

This also hardens malformed sandbox-registry normalization without
changing supported user-facing configuration.

## Changes
- Add shared object-record helpers and semantic tests for the CLI,
plugin, and Hermes compilation boundaries; retain the immutable
integrity-pinned credential helper unchanged.
- Decode messaging setup plans once through the canonical
`parseSandboxMessagingPlan` boundary, removing the duplicate plan
validator, nine typed-plan rechecks, and the custom recursive
JSON-serializability walk.
- Read the sandbox registry as `unknown`, validate its object shape and
entries during load, and let typed serialization iterate
`SandboxRegistry` directly.
- Refine the OpenShell policy parser's return type so the runner can
trust validated `version` and `network_policies` fields.
- Remove object checks made redundant by TypeScript narrowing,
successful native `import()`, and prior Hermes plan narrowing.
- Require registry entry names to be nonblank and match their map keys,
preserve stale-default diagnostics, and repair invalid defaults with the
correct ownership revision on persistence.
- Reject non-plain prototype objects at the OpenClaw config-merge
boundary, where prototype identity is a real runtime invariant.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
<!-- Check exactly one tests line and one docs line. Check other lines
when applicable. Add every requested justification or approval
reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: a documentation-writer review
confirmed that commands, flags, supported configuration, persisted
schemas, and workflows are unchanged; the changes are internal
boundary/type semantics.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: a full provenance audit
classified each guard by input source, retained checks at external
boundaries, and removed only checks proven redundant by validated domain
types or language/runtime guarantees; CodeQL, CodeRabbit, and both PR
review advisors pass on the final commit.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect that behavior. Do
not rerun hook-covered checks. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification: final
focused suites passed 80 CLI tests, 55 integration tests, and 117 plugin
tests; the previously flaky gateway-recovery file passed 11/11 locally.
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: `env -u SSH_CONNECTION -u
SSH_CLIENT -u SSH_TTY npm run check` passed on final commit `af7907afc`,
including full CLI/integration and plugin coverage.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved and standardized validation for configuration, manifests,
policies, messaging plans, and runtime data.
* Rejected malformed or non-plain object shapes more consistently across
parsing and merge flows.
* Prevented stale sandbox default selections from being persisted, with
stricter registry entry handling during normalization and merges.
* Tightened enablement checks and serialization behavior for persisted
registry state.
* **Tests**
  * Added tests for object-record/plain-object guards.
* Added/updated coverage for sandbox registry normalization and invalid
config/merge inputs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@wscurran wscurran added area: architecture Architecture, design debt, major refactors, or maintainability refactor PR restructures code without intended behavior change labels Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: architecture Architecture, design debt, major refactors, or maintainability refactor PR restructures code without intended behavior change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants