From 2c3e63ed29fbdcd111d4c9b3d945f0cec8fd19d1 Mon Sep 17 00:00:00 2001 From: Julian lechner Date: Thu, 17 Sep 2026 08:31:38 +0200 Subject: [PATCH] feat(prompt-budget): enforce absolute context caps --- adapters/prompt-budget-baseline.json | 2 +- adapters/prompt-budget-baseline.tsv | 4 ++-- scripts/prompt-budget.ps1 | 15 ++++++++++++--- scripts/prompt-budget.sh | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/adapters/prompt-budget-baseline.json b/adapters/prompt-budget-baseline.json index 89a10d2..a136008 100644 --- a/adapters/prompt-budget-baseline.json +++ b/adapters/prompt-budget-baseline.json @@ -1 +1 @@ -{"Claude permanent context":5030,"Codex permanent context":4828} +{"Claude permanent context":5030,"Codex permanent context":4828,"Claude permanent context absolute limit":6500,"Codex permanent context absolute limit":6500} diff --git a/adapters/prompt-budget-baseline.tsv b/adapters/prompt-budget-baseline.tsv index 14812ee..5bf50ac 100644 --- a/adapters/prompt-budget-baseline.tsv +++ b/adapters/prompt-budget-baseline.tsv @@ -1,2 +1,2 @@ -Claude 5030 -Codex 4828 +Claude 5030 6500 +Codex 4828 6500 diff --git a/scripts/prompt-budget.ps1 b/scripts/prompt-budget.ps1 index 2bbd273..e587171 100644 --- a/scripts/prompt-budget.ps1 +++ b/scripts/prompt-budget.ps1 @@ -19,7 +19,16 @@ $baseline = Join-Path $root 'adapters/prompt-budget-baseline.json' $old = if (Test-Path $baseline) { Get-Content $baseline -Raw | ConvertFrom-Json } else { $null } $rows = @([pscustomobject]@{Name='Claude permanent context';Bytes=$claude;Tokens=(Tokens $claude)},[pscustomobject]@{Name='Codex permanent context';Bytes=$codex;Tokens=(Tokens $codex)},[pscustomobject]@{Name='Claude skill files (lazy)';Bytes=$skills;Tokens=(Tokens $skills)},[pscustomobject]@{Name='Rule trigger metadata';Bytes=$triggers;Tokens=(Tokens $triggers)},[pscustomobject]@{Name='Largest lazy rule';Bytes=$lazy;Tokens=(Tokens $lazy)}) $fail = $false -if ($old) { foreach ($row in $rows | Select-Object -First 2) { $previous = [double]$old.($row.Name); if ($previous -gt 0 -and $row.Bytes -gt $previous * 1.15) { $fail = $true } } } -if ($Summary) { Write-Output 'Prompt Budget'; $rows | ForEach-Object { Write-Output ('{0,-28} {1,8} bytes {2,6} tokens' -f $_.Name,$_.Bytes,$_.Tokens) } } else { $rows | ForEach-Object { Write-Output ('{0}: {1} bytes / {2} tokens' -f $_.Name,$_.Bytes,$_.Tokens) } } -if ($fail) { Write-Error 'Prompt budget: permanent context increased by more than 15 percent.'; exit 1 } +$baselineValues = @{} +if ($old) { + foreach ($row in $rows | Select-Object -First 2) { + $previous = [double]$old.($row.Name) + $absolute = [double]$old.(($row.Name + ' absolute limit')) + $baselineValues[$row.Name] = @($previous, $absolute) + if ($previous -gt 0 -and $row.Bytes -gt $previous * 1.15) { $fail = $true; Write-Error "Prompt budget relative limit failed: $($row.Name) $($row.Bytes) bytes (baseline $previous, limit 15%)." } + if ($absolute -gt 0 -and $row.Bytes -gt $absolute) { $fail = $true; Write-Error "Prompt budget absolute limit failed: $($row.Name) $($row.Bytes) bytes (absolute limit $absolute)." } + } +} +if ($Summary) { Write-Output 'Prompt Budget'; foreach ($row in $rows | Select-Object -First 2) { $limits = $baselineValues[$row.Name]; $base = if($limits){$limits[0]}else{'-'}; $absolute = if($limits){$limits[1]}else{'-'}; Write-Output ('{0,-28} {1,8} bytes baseline {2} relative 115% absolute {3}' -f $row.Name,$row.Bytes,$base,$absolute) }; $rows | Select-Object -Skip 2 | ForEach-Object { Write-Output ('{0,-28} {1,8} bytes {2,6} tokens' -f $_.Name,$_.Bytes,$_.Tokens) } } else { $rows | ForEach-Object { Write-Output ('{0}: {1} bytes / {2} tokens' -f $_.Name,$_.Bytes,$_.Tokens) } } +if ($fail) { exit 1 } exit 0 diff --git a/scripts/prompt-budget.sh b/scripts/prompt-budget.sh index 59c23c0..ea1e087 100644 --- a/scripts/prompt-budget.sh +++ b/scripts/prompt-budget.sh @@ -9,7 +9,17 @@ bytes() { wc -c < "$1" | tr -d ' '; } tree_bytes() { find "$1" -type f -printf '%s\n' 2>/dev/null | awk '{s+=$1} END {print s+0}'; } tokens() { awk -v b="$1" 'BEGIN { printf "%d", (b + 3) / 4 }'; } claude=$(bytes "$generated/claude-bash/CLAUDE.md"); codex=$(bytes "$generated/codex-bash/AGENTS.md"); skills=$(tree_bytes "$generated/claude-bash/skills"); triggers=$(bytes "$root/adapters/claude/rule-skills.tsv"); lazy=$(find "$root/shared/rules" -type f -printf '%s %p\n' | sort -nr | awk 'NR==1 {print $1+0}'); fail=false -if [ -f "$root/adapters/prompt-budget-baseline.tsv" ]; then while IFS=$'\t' read -r name old; do current=$([ "$name" = Claude ] && printf '%s' "$claude" || printf '%s' "$codex"); awk -v n="$current" -v o="$old" 'BEGIN { exit !(o > 0 && n > o * 1.15) }' && fail=true; done < "$root/adapters/prompt-budget-baseline.tsv"; fi -if [ "$summary" = true ]; then printf 'Prompt Budget\nClaude permanent context %8s bytes %6s tokens\nCodex permanent context %8s bytes %6s tokens\nClaude skill files (lazy) %8s bytes %6s tokens\nRule trigger metadata %8s bytes %6s tokens\nLargest lazy rule %8s bytes %6s tokens\n' "$claude" "$(tokens "$claude")" "$codex" "$(tokens "$codex")" "$skills" "$(tokens "$skills")" "$triggers" "$(tokens "$triggers")" "$lazy" "$(tokens "$lazy")"; else printf 'Prompt budget: Claude %s bytes, Codex %s bytes, skills %s bytes, triggers %s bytes, largest lazy rule %s bytes\n' "$claude" "$codex" "$skills" "$triggers" "$lazy"; fi +claude_baseline=0; codex_baseline=0; claude_absolute=0; codex_absolute=0 +if [ -f "$root/adapters/prompt-budget-baseline.tsv" ]; then + while IFS=$'\t' read -r name old absolute; do + [ "$name" = Claude ] || [ "$name" = Codex ] || continue + current=$([ "$name" = Claude ] && printf '%s' "$claude" || printf '%s' "$codex") + [ "$name" = Claude ] && claude_baseline=$old && claude_absolute=$absolute + [ "$name" = Codex ] && codex_baseline=$old && codex_absolute=$absolute + if awk -v n="$current" -v o="$old" 'BEGIN { exit !(o > 0 && n > o * 1.15) }'; then printf 'Prompt budget relative limit failed: %s %s bytes (baseline %s, limit 15%%).\n' "$name" "$current" "$old" >&2; fail=true; fi + if awk -v n="$current" -v a="$absolute" 'BEGIN { exit !(a > 0 && n > a) }'; then printf 'Prompt budget absolute limit failed: %s %s bytes (absolute limit %s).\n' "$name" "$current" "$absolute" >&2; fail=true; fi + done < "$root/adapters/prompt-budget-baseline.tsv" +fi +if [ "$summary" = true ]; then printf 'Prompt Budget\nClaude permanent context %8s bytes baseline %s relative 115%% absolute %s\nCodex permanent context %8s bytes baseline %s relative 115%% absolute %s\nClaude skill files (lazy) %8s bytes %6s tokens\nRule trigger metadata %8s bytes %6s tokens\nLargest lazy rule %8s bytes %6s tokens\n' "$claude" "$claude_baseline" "$claude_absolute" "$codex" "$codex_baseline" "$codex_absolute" "$skills" "$(tokens "$skills")" "$triggers" "$(tokens "$triggers")" "$lazy" "$(tokens "$lazy")"; else printf 'Prompt budget: Claude %s bytes, Codex %s bytes, skills %s bytes, triggers %s bytes, largest lazy rule %s bytes\n' "$claude" "$codex" "$skills" "$triggers" "$lazy"; fi $fail && { printf 'Prompt budget: permanent context increased by more than 15 percent.\n' >&2; exit 1; } exit 0