Private
Public Access
0
0
Files
manual_slop/scripts/tier2/setup_tier2_clone.ps1
T
ed 9cd8536455 fix(tier2): top-level permission allowlist - sandbox paths now enforced
Regression: a Tier 2 session was denied access to
C:\\projects\\manual_slop_tier2\\scripts\\run_tests_batched.py
with 'Allowed base directories are: gencpp, manual_slop'. The
tier2-autonomous agent had a correct permission.read allowlist, but
the top-level permission block (inherited from the main repo's
opencode.json via 'git clone') had no read/write keys, and OpenCode
uses the top-level for the default agent path. The agent's
permission.read was merged but apparently not enforced for the
default-agent access check.

Fix:
1. Add a top-level 'permission' block to
   conductor/tier2/opencode.json.fragment with:
   - permission.edit: 'deny' (default agents locked down)
   - permission.read: deny *, allow sandbox clone + app-data dirs
   - permission.write: same
   - permission.bash: deny *, allowlist of read-only git commands +
     uv run python scripts/{run_tests_batched.py,tier2/*} + basic
     shell commands. git push/checkout/restore/reset remain denied.

2. Update setup_tier2_clone.ps1 to also patch the top-level
   'permission' block (was only merging the tier2-autonomous agent
   block). The script preserves the user's mcp, model, instructions,
   watcher, and plugin settings from the inherited opencode.json.

3. Update test_tier2_slash_command_spec.py:
   - Rename test_command_fetches_origin_main -> ..._master (we
     changed the slash command on 2026-06-17).
   - Add test_config_fragment_has_top_level_permission to assert
     the new top-level permission block has the right deny-all +
     allowlist shape.

The tier2-autonomous agent's permission block is unchanged; it
overrides the top-level for that agent's tool calls.
2026-06-17 13:43:53 -04:00

125 lines
6.3 KiB
PowerShell

# scripts/tier2/setup_tier2_clone.ps1
<#
.SYNOPSIS
One-time bootstrap for the Tier 2 autonomous sandbox.
.DESCRIPTION
Clones the main repo to C:\projects\manual_slop_tier2\, sets origin
to the main repo's local path, copies the agent/command/opencode.json
templates, installs the git hooks, creates the app-data temp dir with
restricted ACLs, and creates a "Tier 2 (Sandboxed)" desktop shortcut.
Idempotent: re-running updates templates and re-fetches, but does not
destroy existing feature branches in the clone.
.PARAMETER WhatIf
Show what would happen without making changes.
.PARAMETER MainRepoPath
Path to the main repo. Default: C:\projects\manual_slop
.PARAMETER Tier2ClonePath
Path to the Tier 2 clone. Default: C:\projects\manual_slop_tier2
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[string]$MainRepoPath = "C:\projects\manual_slop",
[string]$Tier2ClonePath = "C:\projects\manual_slop_tier2",
[string]$AppDataDir = "$env:LOCALAPPDATA\manual_slop\tier2"
)
$ErrorActionPreference = "Stop"
# Resolve to absolute paths
$MainRepoPath = (Resolve-Path $MainRepoPath).Path
$AppDataFailuresDir = "$env:LOCALAPPDATA\manual_slop\tier2_failures"
if ($PSCmdlet.ShouldProcess("Bootstrap Tier 2 clone at $Tier2ClonePath")) {
Write-Host "[tier2-bootstrap] starting bootstrap"
Write-Host "[tier2-bootstrap] main repo: $MainRepoPath"
Write-Host "[tier2-bootstrap] tier2 clone: $Tier2ClonePath"
# 1. Clone the main repo (if not already present)
if (-not (Test-Path $Tier2ClonePath)) {
Write-Host "[tier2-bootstrap] cloning $MainRepoPath -> $Tier2ClonePath"
git clone $MainRepoPath $Tier2ClonePath
if ($LASTEXITCODE -ne 0) { throw "git clone failed" }
} else {
Write-Host "[tier2-bootstrap] clone already exists, skipping clone"
}
# 2. Set origin to the main repo's local path (if not already)
Push-Location $Tier2ClonePath
try {
$currentOrigin = git remote get-url origin 2>$null
if ($currentOrigin -ne $MainRepoPath) {
Write-Host "[tier2-bootstrap] setting origin to $MainRepoPath"
git remote set-url origin $MainRepoPath
} else {
Write-Host "[tier2-bootstrap] origin already set correctly"
}
# 3. Copy templates
Write-Host "[tier2-bootstrap] copying templates"
New-Item -ItemType Directory -Force -Path "$Tier2ClonePath\.opencode\agents" | Out-Null
New-Item -ItemType Directory -Force -Path "$Tier2ClonePath\.opencode\commands" | Out-Null
Copy-Item -Force "$MainRepoPath\conductor\tier2\agents\tier2-autonomous.md" "$Tier2ClonePath\.opencode\agents\tier2-autonomous.md"
Copy-Item -Force "$MainRepoPath\conductor\tier2\commands\tier-2-auto-execute.md" "$Tier2ClonePath\.opencode\commands\tier-2-auto-execute.md"
# Merge opencode.json.fragment into the clone's opencode.json.
# The clone inherits a copy of the main repo's opencode.json (via
# `git clone`), which has top-level `permission.edit: ask` and
# `permission.bash: ask`. Those would be unsafe in the sandbox: the
# build/plan default agents could read/write anywhere on disk, and
# there is no file-system allowlist at the top level. We replace
# the top-level `permission` with the hardened sandbox version
# (deny-all + allowlist for the sandbox dirs + the tier2-autonomous
# agent's permission block). The agent's `permission` overrides the
# top-level for that agent's tool calls.
$cloneConfig = "$Tier2ClonePath\opencode.json"
$fragment = Get-Content "$MainRepoPath\conductor\tier2\opencode.json.fragment" -Raw | ConvertFrom-Json
if (Test-Path $cloneConfig) {
$existing = Get-Content $cloneConfig -Raw | ConvertFrom-Json
if (-not $existing.agent) { $existing | Add-Member -MemberType NoteProperty -Name agent -Value ([PSCustomObject]@{}) }
$existing.agent | Add-Member -MemberType NoteProperty -Name "tier2-autonomous" -Value $fragment.agent."tier2-autonomous" -Force
if (-not $existing.permission) { $existing | Add-Member -MemberType NoteProperty -Name permission -Value ([PSCustomObject]@{}) }
$existing.permission = $fragment.permission
$existing | Add-Member -MemberType NoteProperty -Name default_agent -Value "tier2-autonomous" -Force
$existing | ConvertTo-Json -Depth 10 | Set-Content $cloneConfig
} else {
Copy-Item -Force "$MainRepoPath\conductor\tier2\opencode.json.fragment" $cloneConfig
}
# 4. Install git hooks
Write-Host "[tier2-bootstrap] installing git hooks"
Copy-Item -Force "$MainRepoPath\conductor\tier2\githooks\pre-push" "$Tier2ClonePath\.git\hooks\pre-push"
Copy-Item -Force "$MainRepoPath\conductor\tier2\githooks\post-checkout" "$Tier2ClonePath\.git\hooks\post-checkout"
# 5. Create app-data dir with restricted ACLs
Write-Host "[tier2-bootstrap] creating app-data dir: $AppDataDir"
New-Item -ItemType Directory -Force -Path $AppDataDir | Out-Null
New-Item -ItemType Directory -Force -Path $AppDataFailuresDir | Out-Null
$acl = Get-Acl $AppDataDir
$acl.SetAccessRuleProtection($true, $false)
$userRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$env:USERNAME, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow"
)
$acl.AddAccessRule($userRule)
Set-Acl $AppDataDir $acl
Set-Acl $AppDataFailuresDir (Get-Acl $AppDataDir)
# 6. Create desktop shortcut
Write-Host "[tier2-bootstrap] creating desktop shortcut"
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut("$env:USERPROFILE\Desktop\Tier 2 (Sandboxed).lnk")
$shortcut.TargetPath = "pwsh.exe"
$shortcut.Arguments = "-File `"$MainRepoPath\scripts\tier2\run_tier2_sandboxed.ps1`""
$shortcut.WorkingDirectory = $Tier2ClonePath
$shortcut.Description = "Open OpenCode in the Tier 2 sandboxed clone"
$shortcut.Save()
} finally {
Pop-Location
}
Write-Host "[tier2-bootstrap] done"
Write-Host "[tier2-bootstrap] next steps:"
Write-Host "[tier2-bootstrap] 1. Double-click 'Tier 2 (Sandboxed)' on your desktop"
Write-Host "[tier2-bootstrap] 2. Type: /tier-2-auto-execute <track-name>"
}