fix(exec): allow uploaded files in active workspaces

PR #748 — visual proof pack for issue #739

Bug

Active workspace files under deny-roots were rejected by exec even when they belonged to the current upload/team scope.

Root Cause

Path exemptions were static and non-shell-aware, so quoted, prefixed, and legacy screenshot-era upload paths still matched the deny root.

Fix

Shell-aware parsing + canonical path checks now exempt the active personal .uploads subtree, the legacy uploads subtree, and the active team workspace.

Before source: stable claw:3000 backed by the unfixed /opt/goclaw deployment (v2.7.1). After source: temporary PR deployment on claw:3001, backed by goclaw-pr748:local built from the fixed code commit 83fa1342. Both UI captures use fresh chats with the same user and GLM thục bô. Callout border marks the reviewed exec row.

UI Before / After

Before
Before: stable claw blocks absolute .goclaw upload path

Stable claw release, fresh chat with GLM thục bô: the agent runs the exact absolute /app/.goclaw/.../.uploads/...jpg copy command and the exec row fails with the safety-policy .goclaw/ denial.

After
After: fixed temporary claw deployment allows absolute .goclaw upload path

Temporary fixed deployment on claw:3001, fresh chat with the same agent: the same absolute /app/.goclaw/.../.uploads/...jpg copy command now completes successfully and returns /tmp/partner-abs.png.

Gateway Reproduction

Before
$ ssh claw 'docker run --rm -v /tmp/goclaw-739-before:/src -w /src golang:1.26 sh -lc "/usr/local/go/bin/go test ./cmd -run TestSetupToolRegistryExecWorkspacePaths -count=1 -v"'
=== RUN   TestSetupToolRegistryExecWorkspacePaths
=== RUN   TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed
gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths.../001
=== RUN   TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed
gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths.../001
=== RUN   TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed
gateway_setup_exec_workspace_test.go:133: denied = true, want false; output = command denied by safety policy: matches pattern /tmp/TestSetupToolRegistryExecWorkspacePaths.../001
FAIL

Baseline source on claw: the exact gateway wiring still rejects all three representative workspace-path forms.

After
$ go test ./cmd -run TestSetupToolRegistryExecWorkspacePaths -count=1 -v
=== RUN   TestSetupToolRegistryExecWorkspacePaths
=== RUN   TestSetupToolRegistryExecWorkspacePaths/personal_workspace_prefixed_uploads_allowed
=== RUN   TestSetupToolRegistryExecWorkspacePaths/team_workspace_quoted_input_allowed
=== RUN   TestSetupToolRegistryExecWorkspacePaths/legacy_dotgoclaw_uploads_layout_allowed
--- PASS: TestSetupToolRegistryExecWorkspacePaths (0.01s)
    --- PASS: personal_workspace_prefixed_uploads_allowed
    --- PASS: team_workspace_quoted_input_allowed
    --- PASS: legacy_dotgoclaw_uploads_layout_allowed
PASS

Current worktree: the same gateway path handling now passes for personal uploads, team workspace paths, and the screenshot-era legacy .goclaw/.../uploads layout.

Supporting Live Recreation on claw

Live claw recreation with GLM thục bô

This earlier live run documents the same production agent and workspace context on stable claw. The report’s primary Before/After pair above is the clean isolated proof you asked for; this screenshot is kept as supporting context for the reproduction journey.

What This Proves