Intent Testing Guide¶
This document covers testing the intent-based operations system and records the validation results.
Overview¶
Intents are declarative YAML files that define infrastructure operations with: - Policy checks: Prerequisites that must pass before execution - Confirmation: User approval for risky operations - Steps: Sequential commands to execute - Verification: Post-execution checks - Rollback: Automatic recovery on failure - Audit logging: Cryptographically-chained event log
Running Intent Tests¶
Single Intent Test¶
# Dry run (shows what would happen)
/root/tower-fleet/scripts/run-intent.sh <intent.yaml> --params key=value --dry-run
# Execute with confirmation
/root/tower-fleet/scripts/run-intent.sh <intent.yaml> --params key=value --confirm
Parameter Format¶
Parameters are space-separated key=value pairs:
# Correct
--params app=notes-app replicas=2
# Incorrect (comma-separated)
--params app=notes-app,replicas=2
Test Results (2024-12-30)¶
Tested against notes-app deployed to K8s cluster.
Passing Intents¶
| Intent | Risk | Description | Duration |
|---|---|---|---|
create-nextjs-app |
high | Scaffold new Next.js app with auth | ~2 min |
health-check |
read-only | Check single app health | <1s |
health-check-all |
low | Check all apps in namespace | ~2s |
check-logs |
read-only | Retrieve pod logs | <1s |
observe-app |
read-only | Full observability (pods, logs, metrics, events) | ~1s |
restart-app |
medium | Rolling restart deployment | ~12s |
scale-app |
medium | Scale replica count | ~15s |
rollback-app |
high | Revert to previous revision | ~27s |
deploy-app |
high | Full CI/CD pipeline | ~2.5 min |
Skipped Intents¶
| Intent | Reason |
|---|---|
backup-app |
No Velero backups configured |
restore-app |
No Velero backups configured |
verify-backups |
No Velero backups configured |
migrate-schema |
Would need pending migration file |
Fixes Applied During Testing¶
1. Shell Escaping in Template Resolution¶
Problem: Template engine wraps parameter values in single quotes for shell safety. When YAML also had double quotes around ${params.*}, commands broke.
Example:
# Before (broken)
command: echo "${params.app}"
# Resolved to: echo "'notes-app'" (nested quotes)
# After (fixed)
command: |
app=${params.app}
echo "$app"
Files fixed:
- /root/tower-fleet/intents/examples/create-nextjs-app.yaml
- /root/tower-fleet/intents/examples/scale-app.yaml
2. Verify Check Quoting¶
Problem: In scale-app.yaml, the verify check compared shell variable $current with template-resolved ${params.replicas} which became '2' (quoted).
Before:
command: |
current=$(kubectl get deployment ... -o jsonpath='{.status.availableReplicas}')
[ "$current" = "${params.replicas}" ]
# Comparison: "2" = "'2'" (fails)
After:
command: |
replicas=${params.replicas}
current=$(kubectl get deployment ... -o jsonpath='{.status.availableReplicas}')
[ "$current" = "$replicas" ]
# Comparison: "2" = "2" (passes)
3. Scaffold Script Dependencies¶
Problem: scaffold-nextjs.sh was missing dependencies required by shadcn components.
Fix: Added to npm install:
Problem: Layout template referenced wrong export name.
Fix: Changed DevBanner to DevAuthBanner.
Intent System Validation¶
State Machine¶
All states verified working:
Features Verified¶
| Feature | Status | Notes |
|---|---|---|
| Policy prereqs | ✅ | Commands checked before execution |
| Locking | ✅ | Prevents concurrent operations on same resource |
| Confirmation | ✅ | --confirm flag or interactive prompt |
| Step execution | ✅ | Sequential with timeout enforcement |
| Output capture | ✅ | stdout/stderr captured in audit log |
| Verification | ✅ | Post-execution checks run |
| Auto-rollback | ✅ | Triggered on verify failure |
| Audit logging | ✅ | JSONL with SHA-256 hash chain |
Audit Log Example¶
# View audit log for specific request
cat /root/tower-fleet/logs/intents/2025-12-30/req_*.jsonl | jq .
Each event includes:
- event_hash: SHA-256 of current event
- prev_hash: Hash of previous event (chain integrity)
- timestamp: UTC timestamp
- outcome: success/failure status
Writing Testable Intents¶
Best Practices¶
-
Use local variable assignment pattern:
-
Quote shell variables, not template variables:
-
Provide sensible defaults:
-
Include meaningful verify checks:
Troubleshooting¶
Intent Fails on Prereq Check¶
Check that: - Required parameters are provided - Resources exist (deployment, namespace) - kubectl/docker are accessible
Verify Check Fails After Successful Execution¶
Common causes: - Quoting mismatch (template vs shell variables) - Timing issue (resource not ready yet) - Wrong jsonpath selector
Debug by running verify command manually:
Lock Not Released¶
Locks auto-expire after TTL (default 900s). To manually release: