Skip to content

Conversation

@bb-connor
Copy link
Collaborator

@bb-connor bb-connor commented Feb 11, 2026

Summary

  • add integrated Policy Workbench panel in Forensics River with editor/tester, validation, history, and dirty-state protections
  • add desktop bridge/client plumbing for load/validate/eval/save policy flows
  • add feature-flag rollout controls and rollout docs for safe enable/disable
  • add hushd eval-surface regression tests for path traversal, userinfo spoofed host inputs, and private-IP egress

Testing

  • node node_modules/typescript/bin/tsc --noEmit -p apps/desktop/tsconfig.json
  • node apps/desktop/node_modules/vitest/vitest.mjs --run
  • cargo test -p hushd --test integration test_eval_policy_event
  • cargo test --workspace

Note

Medium Risk
Touches policy enforcement-adjacent APIs and desktop policy-editing flows; mistakes could lead to incorrect validation/save behavior or operational regressions, though changes are gated by auth scopes and a feature flag.

Overview
Adds an integrated Policy Workbench to the Desktop Forensics River view, providing in-place policy YAML load/edit/validate/save and canonical PolicyEvent test execution with history, dirty-draft UX protections, and feature-flag rollout controls.

Extends hushd with POST /api/v1/policy/validate, enriches GET /api/v1/policy responses with source + schema metadata, and returns canonical policy_hash on policy update/reload/bundle update; integration tests add regression coverage for eval-surface edge cases (path traversal targets, userinfo-spoofed hosts, private-IP egress).

Updates desktop plumbing to support both Tauri invoke bridge commands (policy_load/policy_validate/policy_eval_event/policy_save) and direct HTTP via HushdClient (including wrapping /api/v1/eval payloads under { event }), modernizes routing to a data router with navigation blocking on dirty drafts, and adds a manual GitHub Actions workflow to build/upload unsigned macOS .dmg/.app artifacts with checksums.

Written by Cursor Bugbot for commit aee4292. This will update automatically on new commits. Configure here.

@bb-connor
Copy link
Collaborator Author

@codex

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3152a5ee47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Addressed review feedback in commit 008c5f5:\n\n- Prevented dirty-draft overwrite on reconnect: auto-reload now skips when draft is dirty and requires explicit reload.\n- Fixed in-flight save race: save uses snapshot + preserves newer draft edits if the draft changed while save was pending; editor is read-only during save.\n- Fixed network target mapping for IPv6: bare IPv6 is treated as host-only (default port) and bracketed IPv6 host:port parsing is covered.\n- Fixed update response hash to return canonical engine policy hash (not raw request YAML hash).\n\nValidation run:\n- Desktop: tsc, eslint, vitest (PolicyWorkbenchPanel/mapping/state tests)\n- hushd: cargo test -p hushd --test integration test_update_policy_returns_canonical_policy_hash\n

@bb-connor
Copy link
Collaborator Author

Follow-up correction: in the prior note, the API route reference should read PUT /api/v1/policy (canonical policy hash fix), and it has been validated with the new hushd integration test.

@bb-connor
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 008c5f5a78

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Addressed latest Codex review comment in commit 2e2bee4.

  • /api/v1/policy/validate now runs HushEngine builder build after parse to enforce deployability checks used by update and save paths.
  • If engine build fails, validation returns valid false with policy_engine_invalid and preserves normalized_version.
  • Added integration regression test: test_validate_policy_rejects_undeployable_custom_guard_policy.

Validation run:

  • cargo test -p hushd --test integration test_validate_policy_ (3 passing tests).

@bb-connor
Copy link
Collaborator Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2e2bee4e6d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Addressed latest open review comments in commit 3d1f74f (reload confirmation, stale load response suppression, loadError cleanup after save, and removal of unused PolicyWorkbenchError export).\n\nValidation run:\n- desktop tsc\n- desktop eslint (touched files)\n- vitest: PolicyWorkbenchPanel/state/mapping + policyWorkbenchClient tests (18 passing)\n\n@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d1f74f704

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Addressed the remaining five review findings in commit edd69df6:

  • refresh loadedVersion on save success paths
  • render validation warnings in-panel
  • clear dirty shell event on panel unmount
  • sequence-guard save validation + suppress debounced validate while saving
  • deduplicate placeholder mapping via shared helper

Also added targeted regressions in PolicyWorkbenchPanel.test.tsx, state.test.ts, and mapping.test.ts.

Local verification:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/state.test.ts src/features/forensics/policy-workbench/mapping.test.ts src/features/forensics/policy-workbench/PolicyWorkbenchPanel.test.tsx
  • npx eslint on touched files

All review threads are resolved; CI is running on this commit.

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: edd69df607

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Completed another pass:

  1. Fixed all remaining adapter package README cross-repo links to absolute GitHub URLs so npm-rendered docs do not depend on repo-relative paths.
  2. Also replaced the OpenClaw README getting-started pointer with an absolute guide link.
  3. Addressed latest bot findings from commit edd69df6 in commit c6e95b06:
    • narrow invalid-event error classification in policyWorkbenchClient
    • normalize IPv6 URL hosts in policy test mapping
    • added regressions in policyWorkbenchClient.test.ts and mapping.test.ts

Local validation:

  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/mapping.test.ts src/services/policyWorkbenchClient.test.ts
  • npm --prefix apps/desktop run typecheck
  • targeted eslint on touched TS files

All currently open review threads are resolved again.

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6e95b06d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@bb-connor
Copy link
Collaborator Author

Addressed latest hash-format review in commit c55c3a23:

  • PUT /api/v1/policy/bundle now returns the canonical active policy hash (same source/format as GET /api/v1/policy, PUT /api/v1/policy, and POST /api/v1/policy/reload)
  • bundle-update audit metadata now carries canonical policy_hash and explicit bundle_policy_hash
  • added regression test test_update_policy_bundle_returns_canonical_policy_hash

Validation run:

  • cargo test -p hushd --test integration test_update_policy_bundle_
  • cargo test -p hushd --test integration test_update_policy_returns_canonical_policy_hash

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c55c3a23f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Addressed the remaining command parsing review item in commit 29a313a8:

  • replaced raw whitespace tokenization for command_exec targets with quote/escape-aware parsing in mapping.ts
  • added regressions for quoted args, escaped spaces, and unclosed quote errors in mapping.test.ts

Validation run:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/mapping.test.ts

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 29a313a823

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@bb-connor
Copy link
Collaborator Author

Addressed the latest 3 review findings in commit 0eca3f50:

  • command tokenizer now preserves literal backslashes inside double-quoted args unless the escape sequence is shell-valid
  • confirmed reload now uses a force-apply path so explicit discard+reload cannot be silently skipped by stale-draft protection
  • validate_error now clears stale validation errors/warnings

Added/updated regressions:

  • mapping.test.ts: literal backslash preservation in double-quoted command args
  • PolicyWorkbenchPanel.test.tsx: confirmed reload still applies when user types during in-flight reload
  • state.test.ts: validate_error clears stale errors/warnings

Validation run:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/mapping.test.ts src/features/forensics/policy-workbench/state.test.ts src/features/forensics/policy-workbench/PolicyWorkbenchPanel.test.tsx

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0eca3f50db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bb-connor
Copy link
Collaborator Author

Addressed the URL default-port mapping review item in commit 0a602626:

  • URL network_egress parsing now uses protocol-specific defaults (http/https/ws/wss/ftp/ftps) instead of treating all non-HTTP as 443
  • preserved prior fallback of 443 for unknown URL schemes to avoid breaking existing behavior
  • added mapping regressions for ws://... => 80 and ftp://... => 21

Validation run:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/mapping.test.ts

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. You're on a roll.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@bb-connor
Copy link
Collaborator Author

Addressed the engine-swap ordering issue in commit d52fdc3b:

  • moved canonical policy_hash derivation to happen on new_engine before *engine = new_engine in both update_policy and update_policy_bundle
  • this removes the partial-update path where the in-memory engine could be updated before a hash-derivation error bubbles up

Validation run:

  • cargo test -p hushd --test integration test_update_policy_

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. 🎉

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@bb-connor
Copy link
Collaborator Author

Implemented PR1 + PR2 in commit 0ac74061:

  • metadata/icon cleanup for desktop Tauri app (productName, production bundle id, window title, full icon set including .icns/.ico/PNG sizes)
  • new manual unsigned macOS artifact workflow: .github/workflows/desktop-release.yml
    • builds desktop with Tauri
    • collects .dmg + .app.tar.gz
    • generates SHA256SUMS
    • uploads as workflow artifact
  • README updates for naming + unsigned artifact workflow usage

Validation run:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop run tauri build -- --bundles app,dmg (local success; produced unsigned .app and .dmg)

Next slice would be PR3: wire signing + notarization secrets and CI notarization/stapling.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@bb-connor
Copy link
Collaborator Author

Addressed the remaining open review threads and runtime regression in commits 10a5564f and aee4292c.

What was fixed:

  • Router crash on app startup (useBlocker must be used within a data router): migrated ShellApp to createHashRouter + RouterProvider so useBlocker in ShellLayout runs in a data-router context.
  • App naming updated to Clawdstrike SDR (productName + window title) and desktop README references updated.
  • Policy Workbench save UX hardening:
    • Save button now disables when daemon is disconnected.
    • handleSave now fail-fast guards disconnected state.
    • Added regression test: disconnected save is disabled and no save/validate request is sent.
  • update_policy_bundle now clears policy_engine_cache after engine swap (matches update_policy behavior).
  • Stale/skipped load behavior no longer clears prior load errors:
    • load_start no longer clears loadError.
    • Added reducer regression test covering this.
  • Daemon endpoint switch now reloads policy automatically when connected:
    • Added daemonUrl change detection in the auto-load effect.
    • Added regression test for daemonUrl-triggered reload.
  • normalizeNetworkHost retained and applied across all parse return paths; this runtime still returns bracketed IPv6 hostnames from URL.hostname (covered by existing IPv6 URL mapping test), so explicit normalization remains required for canonical host output.

Validation run:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/PolicyWorkbenchPanel.test.tsx src/features/forensics/policy-workbench/state.test.ts src/features/forensics/policy-workbench/mapping.test.ts src/shell/policyDraftGuard.test.ts
  • cargo test -p hushd --test integration test_update_policy_bundle_returns_canonical_policy_hash
  • cargo test -p hushd --test integration test_update_policy_bundle_rejects_policy_hash_mismatch
  • npm --prefix apps/desktop run tauri build -- --bundles app

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

<div className="flex items-center gap-2">
<GlowButton
data-testid="policy-test-run"
disabled={isRunningTest || !testForm.target.trim()}
Copy link

Choose a reason for hiding this comment

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

Run Test button not disabled when daemon disconnected

Low Severity

The "Run Test" button's disabled prop only checks isRunningTest || !testForm.target.trim() but does not check connected, unlike the Save button which correctly uses !connected || !dirty || state.isSaving. A disconnected user can click "Run Test," triggering a network request that will fail. The runPolicyTest callback also omits a connected guard, unlike handleSave and validateYaml.

Additional Locations (1)

Fix in Cursor Fix in Web

normalized_version?: string;
}
export type PolicyEvalModel = PolicyEvalResponse;
export type PolicySaveModel = PolicySaveResult;
Copy link

Choose a reason for hiding this comment

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

Exported type aliases unused outside defining file

Low Severity

PolicyLoadModel, PolicyValidationModel, PolicyEvalModel, and PolicySaveModel are exported but never imported anywhere in the codebase. They exist only as return-type aliases on PolicyWorkbenchClient methods. Consumers reference the methods' return types implicitly through inference rather than importing these named aliases, making them dead exports that add noise to the module surface.

Fix in Cursor Fix in Web

@bb-connor
Copy link
Collaborator Author

Follow-up update:

  • Confirmed remaining review threads are resolved.
  • ShellApp now uses a data router (createHashRouter + RouterProvider), so useBlocker no longer crashes at runtime.
  • Desktop app/window naming updated to Clawdstrike SDR.
  • Rebuilt and smoke-installed latest macOS app bundle from this branch.

Local checks rerun:

  • npm --prefix apps/desktop run typecheck
  • npm --prefix apps/desktop test -- src/features/forensics/policy-workbench/PolicyWorkbenchPanel.test.tsx src/features/forensics/policy-workbench/state.test.ts src/features/forensics/policy-workbench/mapping.test.ts src/shell/policyDraftGuard.test.ts
  • npm --prefix apps/desktop run tauri build -- --bundles app

@bb-connor bb-connor merged commit e2a25d3 into main Feb 12, 2026
34 checks passed
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