Policy guardrails for team Windsurf usage: controlling what Cascade can do, enforcing code review for AI output, configuring terminal safety controls, and preventing common AI coding mistakes.
Configure what Cascade can and cannot auto-execute:
// settings.json — Team-wide terminal safety
{
"windsurf.cascadeCommandsAllowList": [
"npm test", "npm run", "npx vitest", "npx tsc",
"git status", "git diff", "git log", "git add",
"eslint", "prettier", "biome",
"ls", "cat", "head", "tail", "wc", "grep"
],
"windsurf.cascadeCommandsDenyList": [
"rm -rf", "rm -r /",
"sudo",
"git push --force", "git reset --hard",
"DROP TABLE", "DELETE FROM", "TRUNCATE",
"curl | bash", "wget | sh",
"chmod 777",
"kill -9",
"shutdown", "reboot", "halt",
"mkfs", "dd if=",
"npm publish", "npx publish"
]
}
Prevent Cascade from accessing sensitive directories:
# .codeiumignore — security boundary
# AI cannot see or modify files matching these patterns
# Credentials
.env
.env.*
credentials/
secrets/
*.pem
*.key
# Infrastructure
terraform.tfstate*
*.tfvars
ansible/vault*
# Customer data
data/production/
exports/
<!-- .windsurf/rules/protected-files.md -->
---
trigger: always_on
---
## Protected Files Policy
- NEVER modify files in migrations/ without explicit request
- NEVER modify Dockerfile or docker-compose.yml without explicit request
- NEVER modify CI/CD workflows (.github/workflows/) without explicit request
- NEVER modify package.json dependencies without explicit request
- ALWAYS ask before changing database schema files
# .github/workflows/ai-code-gate.yml
name: AI Code Quality Gate
on: pull_request
jobs:
ai-review-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Check cascade commit policy
run: |
# Count files changed
FILES=$(git diff --name-only origin/main..HEAD | wc -l)
# Large changesets need explicit review
if [ "$FILES" -gt 15 ]; then
echo "::warning::Large changeset ($FILES files modified)."
echo "If AI-generated, ensure line-by-line review."
fi
# New files must have tests
NEW_SRC=$(git diff --name-only --diff-filter=A origin/main..HEAD | grep -cE '\.(ts|js)$' || true)
NEW_TEST=$(git diff --name-only --diff-filter=A origin/main..HEAD | grep -cE '\.(test|spec)\.' || true)
if [ "$NEW_SRC" -gt 3 ] && [ "$NEW_TEST" -eq 0 ]; then
echo "::error::$NEW_SRC new source files without tests."
echo "Add tests before merging AI-generated code."
exit 1
fi
- name: Scan for hardcoded secrets
run: |
SECRETS_FOUND=$(git diff origin/main..HEAD | grep -cE '(sk_live|sk_test|AKIA[A-Z0-9]|ghp_|glpat-|xoxb-)' || true)
if [ "$SECRETS_FOUND" -gt 0 ]; then
echo "::error::Potential hardcoded secret detected in diff."
exit 1
fi
<!-- docs/windsurf-policy.md — committed to repo -->
# Team Windsurf AI Usage Policy
## Required Practices
1. **Git before Cascade** — commit or stash before every Cascade session
2. **Feature branches only** — never use Cascade on main or develop
3. **Review every diff** — accept changes file-by-file, not "accept all"
4. **Test after accepting** — run tests before committing Cascade changes
5. **Tag AI commits** — prefix with `[cascade]` for traceability
## Prohibited Actions
1. Never paste secrets, API keys, or passwords into Cascade chat
2. Never let Cascade modify production config without manual review
3. Never use Cascade to write security-critical code without expert review
4. Never accept Cascade suggestions for database migrations without DBA review
5. Never use Turbo mode with commands not in the allow list
## Code Review Standards for AI-Generated Code
- Reviewer MUST verify logic, not just syntax
- Reviewer MUST check edge cases (AI often misses boundary conditions)
- Reviewer MUST verify error handling (AI tends to happy-path)
- Reviewer MUST check for AI-specific patterns: unnecessary abstraction,
over-engineering, cargo-cult patterns from training data
## Accountability
- The developer who accepts and commits AI-generated code is responsible
- "Cascade wrote it" is not an excuse for bugs in production
- All standard code review requirements apply to AI-generated code
// .vscode/extensions.json (works in Windsurf)
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"biomejs.biome"
],
"unwantedRecommendations": [
"github.copilot",
"github.copilot-chat",
"tabnine.tabnine-vscode",
"sourcegraph.cody-ai"
]
}
<!-- .windsurf/workflows/safe-cascade.md -->
---
name: safe-cascade
description: Pre-flight checks before Cascade work
---
// turbo-all
1. Run `git status` — verify clean working tree
2. Run `git checkout -b cascade/$(date +%Y%m%d-%H%M%S)` — new branch
3. Run `git log --oneline -3` — note recent context
4. Report: "Ready for Cascade. Branch created. Clean working tree."
5. Ask: "What would you like Cascade to do?"
| Issue | Cause | Solution |
|---|---|---|
| Cascade modifies secrets | Files not in .codeiumignore | Add to .codeiumignore, rotate exposed secret |
| Untested AI code merged | No CI gate | Add test-required check to PR |
| Conflicting suggestions | Multiple AI extensions | Remove competing extensions |
| Developer bypasses policy | No enforcement | Add CI gates, team training |
| Cascade runs destructive command | Not in deny list | Add to cascadeCommandsDenyList |
set -euo pipefail
echo "=== Policy Compliance Check ==="
echo "Branch protection: $(gh api repos/:owner/:repo/branches/main/protection --jq '.required_status_checks.contexts | length' 2>/dev/null || echo 'N/A') checks"
echo ".codeiumignore: $([ -f .codeiumignore ] && echo 'EXISTS' || echo 'MISSING')"
echo "Policy doc: $([ -f docs/windsurf-policy.md ] && echo 'EXISTS' || echo 'MISSING')"
echo "Extension control: $([ -f .vscode/extensions.json ] && echo 'EXISTS' || echo 'MISSING')"
For architecture strategies, see windsurf-architecture-variants.