Skip to content

feat: NemoClaw remote approvals — egress approval panel + API endpoints#399

Open
vivekchand wants to merge 4 commits intomainfrom
feat/nemoclaw-approvals
Open

feat: NemoClaw remote approvals — egress approval panel + API endpoints#399
vivekchand wants to merge 4 commits intomainfrom
feat/nemoclaw-approvals

Conversation

@vivekchand
Copy link
Copy Markdown
Owner

Summary

Adds NemoClaw remote egress approval management to ClawMetry. Target: Tuesday launch.

Changes

clawmetry/sync.py

  • _parse_sandbox_names() — parses nemoclaw list output into sandbox name list
  • _get_pending_approvals() — polls openshell draft get for all sandboxes, with JSON and text-fallback parsing
  • Included nemoclaw_approvals in heartbeat payload so cloud always has latest pending count

dashboard.py

  • /api/nemoclaw/pending-approvals — GET endpoint returning pending chunks per sandbox
  • /api/nemoclaw/approve — POST endpoint calling openshell draft approve <sandbox> <chunk_id>
  • /api/nemoclaw/reject — POST endpoint calling openshell draft reject <sandbox> <chunk_id> [--reason]
  • Egress Approvals panel in NemoClaw tab (both themes):
    • Shows pending request count badge (red) when items exist
    • Per-request card: sandbox name, rule name, host:port, time ago
    • ✓ Approve / ✗ Reject buttons (with optional reject reason prompt)
    • Auto-refreshes every 15 seconds while NemoClaw tab is active
    • Stops polling when switching away from tab

Design

  • Styled in NemoClaw green (#76b900)
  • Graceful degradation: if openshell not installed, shows "openshell not available" instead of error
  • JSON flag (--json) with text-parsing fallback for openshell CLI compatibility

Testing

  • python3 -c 'import ast; ast.parse(open("clawmetry/sync.py").read())'}
  • py_compile.compile('dashboard.py')

…urn (closes #300)

- New /api/model-attribution endpoint: scans JSONL sessions for model_change
  events and assistant messages to build per-model turn/session counts
- Returns: models[], primary_model, total_turns, model_count, switches, switch_count
- Models tab added to both dashboard themes (light + dark)
- Bar chart of model mix with percentage share per model
- Per-session breakdown table (model, sessions, turns, share%)
- Model switch history section (when models change mid-session)
- Stat cards: primary model, diversity, fallback rate, total turns
- 5 new tests, all 76 tests pass
…ift detection

- Add /api/nemoclaw/governance endpoint (bp_nemoclaw blueprint, now registered)
- Add /api/nemoclaw/governance/acknowledge-drift POST to clear drift alert
- Add loadNemoClaw() JS function wiring the existing page-nemoclaw UI panels:
  - Status dot (running/idle), sandbox count badge, policy hash badge
  - Sandbox status (N/M running), inference provider/model/endpoint
  - Network policies table from ~/.nemoclaw/source/nemoclaw-blueprint/policies/
  - Drift detection: compares policy hash across calls, shows alert with old→new hash
  - Applied presets list
  - Tab auto-shows when NemoClaw detected, stays hidden otherwise
- Fix stray orphaned except block in Context Inspector section (syntax error)
- Add tests/test_nemoclaw_governance.py: 13 tests (8 pass, 5 skipped pending
  create_app() export) covering parser, detect, sensitive key filtering, drift
The NemoClaw backend (bp_nemoclaw blueprint, _detect_nemoclaw helper,
/api/nemoclaw/governance endpoint, policy drift detection) and the
loadNemoClaw() JS function were already implemented in the previous
commit, but theme 2 (the actually-served DASHBOARD_HTML) was missing:

- The 'NemoClaw' nav tab in the tab bar
- The #page-nemoclaw content div
- The switchTab('nemoclaw') case in the second switchTab() function

This commit adds all three, making the NemoClaw governance tab
visible and functional at runtime.

Also wraps the duplicate loadNemoClaw() stub (from theme 1 copy)
in if(false){} to prevent the dead JS from shadowing the real impl.
- clawmetry/sync.py: add _parse_sandbox_names(), _get_pending_approvals()
  polls openshell draft get for pending egress chunks (JSON + text fallback)
  included in heartbeat payload as nemoclaw_approvals
- dashboard.py: add /api/nemoclaw/approve (POST) and /api/nemoclaw/reject (POST)
  executes openshell draft approve/reject on the local node
- dashboard.py: add /api/nemoclaw/pending-approvals (GET) endpoint
- dashboard.py: Egress Approvals panel in both NemoClaw tab themes
  styled in NemoClaw green (#76b900), auto-refreshes every 15s
  Approve/Reject buttons with openshell integration
  shows host:port, sandbox name, rule name, time ago

Closes: NemoClaw remote approvals (Tuesday launch target)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant