P4: budget battery — DBBudget (rolling 7-day) over run.Budget

Second Tier-2 battery, plugging into run.Ports.Budget:
- budget.go: skillexec's BudgetTracker / NoOpBudget / DBBudget moved clean
  (stdlib only). Check/Commit match run.Budget exactly (compile-time proof in
  run.go: NoOpBudget and *DBBudget are run.Budget).
- storage.go: the BudgetStorage seam + SkillBudget domain, split out of mort's
  GORM file (the GORM impl stays in mort).
- memory.go: NewMemory() — zero-dependency in-process BudgetStorage with the
  7-day rolling-window rollover in Add.

Tests: per-user cap enforced, window rolls over after 7 days, NoOp always
allows. CI invariant: core imports ZERO from the budget battery.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-26 22:17:51 -04:00
parent 4d2f85d139
commit 9116abcae2
6 changed files with 311 additions and 1 deletions
+2 -1
View File
@@ -75,7 +75,8 @@ BATTERIES (opt-in siblings, each nil-safe + a default):
critic/ two-tier timeout state machine + Escalator [P4]
schedule/ cron runner cores [P4]
checkpoint/ durable resume seam [P4]
budget/ rolling-window tracker (+ NoOp) [P4]
budget/ DBBudget rolling-7d + NoOp (run.Budget); [P4]
BudgetStorage iface + Memory default
contrib/store/ SECOND module (+ modernc.org/sqlite): [P4]
in-memory + pure-Go SQLite impls of every *Store seam