Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions AI_AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,177 @@ If this returns results, something violated the rules.
---

*This file is the source of truth for AI agent behavior in this workspace.*

---

## User QoL (Quality of Life) Considerations on Install

*SAIF-processes/methodology — Structured AI Integration Framework*

When setting up the Wave Toolkit or any SpiralSafe ecosystem repository, follow these installation QoL principles to ensure smooth onboarding and consistent execution across sessions.

### 1. Absolute References

**Always use absolute paths** rather than relative paths in scripts and configurations:

```powershell
# ✅ Good: Absolute references
$WaveToolkitPath = "$HOME\wave-toolkit"
$ScriptPath = Join-Path $WaveToolkitPath "scripts\system"

# ❌ Bad: Relative paths that break when working directory changes
$ScriptPath = ".\scripts\system"
```

**Why it matters:**
- AI agents may execute from different working directories
- Cron jobs and scheduled tasks don't inherit the expected `$PWD`
- Sub-processes spawned by agents start with unpredictable paths
- Cross-session persistence requires stable path anchors

**Use these environment-aware patterns:**
```powershell
# Repository root detection (PowerShell 7+ ternary, or if-else for 5.1)
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The comment mentions "PowerShell 7+ ternary" but the code example shown uses the if-else syntax that is compatible with PowerShell 5.1, not the ternary operator. The ternary operator in PowerShell 7+ would be: $RepoRoot = $gitRoot ?? $PSScriptRoot. Consider updating the comment to accurately reflect that this example is specifically for PowerShell 5.1 compatibility, or clarify that both syntaxes work but this one is more compatible.

Suggested change
# Repository root detection (PowerShell 7+ ternary, or if-else for 5.1)
# Repository root detection (PowerShell 5.1-compatible; in PS 7+ you can use: $RepoRoot = $gitRoot ?? $PSScriptRoot)

Copilot uses AI. Check for mistakes.
$gitRoot = git rev-parse --show-toplevel 2>$null
$RepoRoot = if ($gitRoot) { $gitRoot } else { $PSScriptRoot }

# Cross-platform home directory
$UserHome = if ($IsWindows) { $env:USERPROFILE } else { $env:HOME }
Comment on lines +168 to +169
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The cross-platform home directory check uses $IsWindows, which is an automatic variable available in PowerShell 6+. However, this section already mentions compatibility with PowerShell 5.1 in line 164. For PowerShell 5.1 compatibility, consider using: $UserHome = if ($PSVersionTable.PSVersion.Major -ge 6 -and -not $IsWindows) { $env:HOME } else { $env:USERPROFILE } or simply $UserHome = if ($env:HOME) { $env:HOME } else { $env:USERPROFILE }

Suggested change
# Cross-platform home directory
$UserHome = if ($IsWindows) { $env:USERPROFILE } else { $env:HOME }
# Cross-platform home directory (PowerShell 5.1+ safe)
$UserHome = if ($env:HOME) { $env:HOME } else { $env:USERPROFILE }

Copilot uses AI. Check for mistakes.

# Canonical Wave Toolkit path
$WaveRoot = Join-Path $UserHome "wave-toolkit"
```

### 2. Shell Aliases for Cross-Platform Support

**Create aliases for native shell platforms** to ensure consistent command availability:

```powershell
# PowerShell aliases for Unix-like commands
Set-Alias -Name ll -Value Get-ChildItem -Scope Global
Set-Alias -Name grep -Value Select-String -Scope Global
Set-Alias -Name touch -Value New-Item -Scope Global
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The alias touch pointing to New-Item is incomplete and will not work as expected for creating empty files (the typical Unix touch behavior). New-Item requires additional parameters like -ItemType File. Consider changing this to a function wrapper instead: function touch { New-Item -ItemType File -Path $args }

Suggested change
Set-Alias -Name touch -Value New-Item -Scope Global
function touch {
New-Item -ItemType File -Path $args
}

Copilot uses AI. Check for mistakes.
Set-Alias -Name which -Value Get-Command -Scope Global

# Export for persistence
Comment on lines +181 to +186
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The Set-Alias command with -Scope Global may not work as expected within a script context unless the script is dot-sourced. When run in a script, global aliases typically only persist for the script's session and do not automatically persist to the user's profile. Consider clarifying that these aliases should be added to the PowerShell profile for persistence, or that the script containing them should be dot-sourced.

Suggested change
Set-Alias -Name ll -Value Get-ChildItem -Scope Global
Set-Alias -Name grep -Value Select-String -Scope Global
Set-Alias -Name touch -Value New-Item -Scope Global
Set-Alias -Name which -Value Get-Command -Scope Global
# Export for persistence
# For persistence, add these lines to your PowerShell profile (e.g. $PROFILE)
# or dot-source a script that defines them: . "$WaveRoot\tools\aliases.ps1"
Set-Alias -Name ll -Value Get-ChildItem
Set-Alias -Name grep -Value Select-String
Set-Alias -Name touch -Value New-Item
Set-Alias -Name which -Value Get-Command
# Export for persistence when used inside a module

Copilot uses AI. Check for mistakes.
Export-ModuleMember -Alias * -Function *
Comment on lines +186 to +187
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The Export-ModuleMember -Alias * -Function * command should only be used in module files (.psm1), not in profile scripts or standalone scripts. If these aliases are being defined in a profile or script, this line will cause an error. Consider clarifying the context where this command should be used, or providing separate examples for module vs profile scenarios.

Copilot uses AI. Check for mistakes.
```

```cmd
:: CMD aliases (system_aliases.cmd)
@echo off
doskey ll=dir /a $*
doskey grep=findstr $*
doskey cat=type $*
doskey clear=cls
```

**Binding across execution frame 'event horizons':**

When an AI agent spawns processes or hands off to sub-agents, aliases may not persist. To ensure binding:

1. **Profile-level loading**: Add aliases to `$PROFILE` for automatic loading
2. **Explicit sourcing**: Source alias files at the start of each session
3. **Function wrappers**: Prefer functions over aliases for complex operations (functions export more reliably)

```powershell
# Ensure aliases persist across PowerShell sessions
if (Test-Path "$HOME\wave-toolkit\scripts\system\aliases.ps1") {
. "$HOME\wave-toolkit\scripts\system\aliases.ps1"
}
```

### 3. Python Caching for CI/CD Workflows

**Use `actions/setup-python@v5` with pip caching** to improve install performance in GitHub Actions:

```yaml
# .github/workflows/ci.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip' # Enable pip dependency caching
cache-dependency-path: '**/requirements*.txt'

- name: Install dependencies
run: pip install -r requirements.txt
```

**Why caching matters for QoL:**
- Reduces CI run time by 30-60 seconds per workflow
- Decreases load on package registries (pip, npm, etc.)
- Provides consistent dependency resolution across runs
- Enables faster iteration during development

**For other package managers:**
```yaml
# Node.js with npm cache
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

# PowerShell module caching (manual)
- name: Cache PowerShell modules
uses: actions/cache@v4
with:
path: ~/.local/share/powershell/Modules
key: ${{ runner.os }}-pwsh-${{ hashFiles('**/requirements.psd1') }}
Comment on lines +251 to +256
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The PowerShell module cache path ~/.local/share/powershell/Modules is the Linux/macOS path for PowerShell modules. On Windows, the user module path is typically $HOME\Documents\PowerShell\Modules (PowerShell 7+) or $HOME\Documents\WindowsPowerShell\Modules (PowerShell 5.1). Consider using a platform-specific path or providing examples for different operating systems to ensure the cache works correctly in CI environments.

Suggested change
# PowerShell module caching (manual)
- name: Cache PowerShell modules
uses: actions/cache@v4
with:
path: ~/.local/share/powershell/Modules
key: ${{ runner.os }}-pwsh-${{ hashFiles('**/requirements.psd1') }}
# PowerShell module caching (manual, OS-specific paths)
# Linux/macOS
- name: Cache PowerShell modules (Linux/macOS)
if: runner.os != 'Windows'
uses: actions/cache@v4
with:
path: ~/.local/share/powershell/Modules
key: ${{ runner.os }}-pwsh-${{ hashFiles('**/requirements.psd1') }}
# Windows
- name: Cache PowerShell modules (Windows)
if: runner.os == 'Windows'
uses: actions/cache@v4
with:
path: |
${{ env.USERPROFILE }}\Documents\PowerShell\Modules
${{ env.USERPROFILE }}\Documents\WindowsPowerShell\Modules
key: ${{ runner.os }}-pwsh-${{ hashFiles('**/requirements.psd1') }}

Copilot uses AI. Check for mistakes.
```

### 4. Bootstrap Verification Checklist

When running `Setup-Wave.ps1` or similar bootstrap scripts, verify:

| Check | Status | Recovery Action |
|-------|--------|-----------------|
| Git available | `git --version` | Install Git for Windows |
| PowerShell 7+ | `$PSVersionTable.PSVersion` | Install pwsh from Microsoft Store |
| Execution policy allows scripts | `Get-ExecutionPolicy` | `Set-ExecutionPolicy RemoteSigned -Scope CurrentUser` |
| Required directories exist | `Test-Path $WaveRoot` | Run bootstrap again |
| Profile is writable | `Test-Path $PROFILE` | Create profile directory |
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The table row for "Profile is writable" checks Test-Path $PROFILE, but this command only verifies if the profile file exists, not whether it's writable. To actually verify write permissions, consider using: Test-Path $PROFILE -PathType Leaf -ErrorAction SilentlyContinue; (Get-Item $PROFILE -ErrorAction SilentlyContinue).IsReadOnly -eq $false or a similar approach that specifically checks write access.

Suggested change
| Profile is writable | `Test-Path $PROFILE` | Create profile directory |
| Profile is writable | `Test-Path $PROFILE -PathType Leaf -ErrorAction SilentlyContinue -and -not (Get-Item $PROFILE -ErrorAction SilentlyContinue).IsReadOnly` | Create profile directory |

Copilot uses AI. Check for mistakes.

### 5. Event Horizon Boundaries

**"Event horizons"** in this context refer to execution boundaries where context may be lost:

- **New shell session**: Aliases, functions, and variables reset
- **Sub-process spawn**: Child processes don't inherit parent's aliases
- **Agent handoff**: When one AI agent delegates to another
- **Scheduled execution**: Cron/Task Scheduler runs have minimal environment

**Mitigation strategies:**

```powershell
# 1. Environment variable persistence
[Environment]::SetEnvironmentVariable("WAVE_ROOT", $WaveRoot, "User")

# 2. Session checkpoint (for agent handoffs)
@{
Timestamp = Get-Date -Format "o"
WaveRoot = $WaveRoot
Branch = git branch --show-current
Copy link

Copilot AI Jan 21, 2026

Choose a reason for hiding this comment

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

The command git branch --show-current requires Git 2.22 or later (released in June 2019). While this is generally safe to assume in modern environments, for broader compatibility with older Git installations, consider using: git rev-parse --abbrev-ref HEAD as an alternative, or document the Git version requirement in the prerequisites.

Suggested change
Branch = git branch --show-current
Branch = git rev-parse --abbrev-ref HEAD

Copilot uses AI. Check for mistakes.
Aliases = Get-Alias | Select-Object Name, Definition
} | ConvertTo-Json | Out-File ".wave-session.json"

# 3. Reload on session start
if (Test-Path ".wave-session.json") {
$session = Get-Content ".wave-session.json" | ConvertFrom-Json
Write-Host "Resuming Wave session from $($session.Timestamp)"
}
```

---

## Related Documentation

- **[Development Workflow](docs/guides/DEVELOPMENT_WORKFLOW.md)** — Session boundary errors and recovery patterns
- **[Wave Guide](wave.md)** — Philosophy and complete workflow guide
- **[Setup Script](Setup-Wave.ps1)** — One-time bootstrap implementation