instar 1.3.591 → 1.3.592
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +18 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/core/QuotaAwareScheduler.d.ts +25 -0
- package/dist/core/QuotaAwareScheduler.d.ts.map +1 -1
- package/dist/core/QuotaAwareScheduler.js +36 -0
- package/dist/core/QuotaAwareScheduler.js.map +1 -1
- package/dist/monitoring/QuotaTracker.d.ts +56 -0
- package/dist/monitoring/QuotaTracker.d.ts.map +1 -1
- package/dist/monitoring/QuotaTracker.js +112 -4
- package/dist/monitoring/QuotaTracker.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +2 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/src/scaffold/templates.ts +2 -1
- package/upgrades/1.3.592.md +40 -0
- package/upgrades/side-effects/pool-aware-quota-throttle.md +123 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Side-Effects Review — Pool-Aware Quota Throttle
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `pool-aware-quota-throttle`
|
|
4
|
+
**Date:** `2026-06-16`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** spec-converge multi-reviewer panel (6 internal + codex GPT-5.5), 3 rounds — see docs/specs/reports/POOL-AWARE-QUOTA-THROTTLE-convergence.md
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Makes the global quota brake (`QuotaTracker.shouldSpawnSession`) pool-aware. Instead of stopping the
|
|
11
|
+
whole agent when ONE account's usage is high, it consults a new `poolHeadroom` helper in the placement
|
|
12
|
+
module (via an injected provider wired in `server.ts`). `poolHeadroom` shares `selectAccount`'s EXACT
|
|
13
|
+
eligibility predicate — so `placeable ⟺ selectAccount() !== null` (the never-loop invariant) — but
|
|
14
|
+
gates on the MOST-HEADROOM eligible account, so non-critical work runs whenever ANY account has room
|
|
15
|
+
(the 2026-06-16 live-proof fix: gating on `selectAccount`'s use-it-or-lose-it drain-first winner
|
|
16
|
+
wrongly shed medium/autonomous work even with a fresh 0% reserve). Placement (`selectAccount`) still
|
|
17
|
+
drains the soonest-to-reset account. A non-authoritative/implausible/missing reading triggers a
|
|
18
|
+
BOUNDED degraded mode (shed low priority, allow medium+, honor an authoritative 5h wall) rather than
|
|
19
|
+
an unbounded fail-open or a whole-agent stall. Files: `src/monitoring/QuotaTracker.ts` (provider +
|
|
20
|
+
bounded helper + data-quality guard), `src/core/QuotaAwareScheduler.ts` (the shared `poolHeadroom`
|
|
21
|
+
helper), `src/commands/server.ts` (wiring), `src/scaffold/templates.ts` (CLAUDE.md awareness).
|
|
22
|
+
Decision point: the spawn/job quota gate.
|
|
23
|
+
|
|
24
|
+
## Decision-point inventory
|
|
25
|
+
|
|
26
|
+
- `QuotaTracker.shouldSpawnSession` (the spawn/job quota brake) — **modify** — now reasons over pool
|
|
27
|
+
placeability (shared with placement's `selectAccount`) instead of a single account's usage; adds a
|
|
28
|
+
bounded degraded mode. This is the only decision surface touched.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 1. Over-block
|
|
33
|
+
|
|
34
|
+
**What legitimate inputs does this change reject that it shouldn't?**
|
|
35
|
+
|
|
36
|
+
The change REDUCES over-block — its whole purpose is to stop the brake from falsely halting the agent
|
|
37
|
+
when fresh accounts exist. New possible over-block: if EVERY account is status `rate-limited` (not
|
|
38
|
+
just high-usage), `selectAccount` returns null → STOP. This is correct (placement genuinely can't
|
|
39
|
+
land), and it is NOT latched — it re-evaluates every call and self-clears when a window resets. The
|
|
40
|
+
bounded degraded mode sheds `low` priority during untrustworthy readings — intended, conservative.
|
|
41
|
+
|
|
42
|
+
## 2. Under-block
|
|
43
|
+
|
|
44
|
+
**What failure modes does this still miss?**
|
|
45
|
+
|
|
46
|
+
A throttle "allow" guarantees placeability AT DECISION TIME; a concurrent spawn could consume the last
|
|
47
|
+
account before placement runs — placement then returns null, which the caller handles as a normal
|
|
48
|
+
back-off (NOT the old respawn loop, which came from throttle/placement disagreeing — now impossible).
|
|
49
|
+
The provider trusts the pool's own quota-poll freshness (same data placement already relies on); a
|
|
50
|
+
genuinely stale-but-present reading is the pool layer's concern, not newly introduced here.
|
|
51
|
+
|
|
52
|
+
## 3. Level-of-abstraction fit
|
|
53
|
+
|
|
54
|
+
The fix lives in the existing quota-gating module (`QuotaTracker`) and the existing server wiring —
|
|
55
|
+
the correct layer. It reuses placement's `selectAccount`/`bindingUtilization` rather than duplicating
|
|
56
|
+
eligibility logic, so there is one source of truth for "is this account placeable."
|
|
57
|
+
|
|
58
|
+
## 4. Signal vs authority compliance
|
|
59
|
+
|
|
60
|
+
`QuotaTracker` is an EXISTING authority (it gates real spawns). The change does not add a new brittle
|
|
61
|
+
blocking check — it makes the existing authority's decision pool-aware and adds fail-open/bounded
|
|
62
|
+
behavior in the safe direction. Fail-open on degraded data is exactly the Signal-vs-Authority guidance
|
|
63
|
+
(don't let an expensive false-positive stop everything). Lessons-aware reviewer confirmed PASS across 3
|
|
64
|
+
rounds.
|
|
65
|
+
|
|
66
|
+
## 5. Interactions
|
|
67
|
+
|
|
68
|
+
- **Placement (`QuotaAwareScheduler.selectAccount`):** now shared by the throttle — by construction
|
|
69
|
+
they cannot diverge (closes the respawn-loop band). No change to selectAccount itself.
|
|
70
|
+
- **SubscriptionPool:** read-only (`list()`); no mutation.
|
|
71
|
+
- **QuotaCollector / QuotaManager:** unchanged (the earlier collector edit was reverted). The file
|
|
72
|
+
path (single-account / legacy) is byte-identical except the bounded degraded mode.
|
|
73
|
+
- **Scheduler / can-start / spawn gates:** all consume `shouldSpawnSession`/`canRunJob` and benefit
|
|
74
|
+
automatically; no signature change.
|
|
75
|
+
|
|
76
|
+
## 6. External surfaces
|
|
77
|
+
|
|
78
|
+
No new routes, no new config keys, no new dashboard surface. The only user-facing surface is the
|
|
79
|
+
CLAUDE.md template awareness blurb (additive). No external network calls added (the provider reads the
|
|
80
|
+
in-memory pool synchronously).
|
|
81
|
+
|
|
82
|
+
## 6b. Operator-surface quality
|
|
83
|
+
|
|
84
|
+
No operator-facing UI/route changes. The behavior the operator observes ("the agent no longer freezes
|
|
85
|
+
when one account maxes out; idle accounts get used") is the intended improvement, documented in the
|
|
86
|
+
CLAUDE.md awareness section so an agent can explain it conversationally.
|
|
87
|
+
|
|
88
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
89
|
+
|
|
90
|
+
**Machine-local BY DESIGN.** `quota-state.json` and the SubscriptionPool the throttle reads are
|
|
91
|
+
per-machine: each host polls its own account credentials and places sessions locally. Replicating
|
|
92
|
+
would be wrong (machine A's stale view would gate machine B's spawns). The existing
|
|
93
|
+
`GET /subscription-pool?scope=pool` is the unchanged cross-machine quota surface. No durable state is
|
|
94
|
+
introduced that could strand on a topic transfer. Documented in the spec's "Multi-machine posture"
|
|
95
|
+
section.
|
|
96
|
+
|
|
97
|
+
## 8. Rollback cost
|
|
98
|
+
|
|
99
|
+
Low. Pure code change, no persisted-state migration. Disable per-agent by leaving the provider unset
|
|
100
|
+
(or `setPoolQuotaProvider(undefined)`) → file-based gating returns. Full revert = revert the commit +
|
|
101
|
+
rebuild + restart sessions. Solo (single-account) agents are unaffected (no provider wired). No
|
|
102
|
+
dark-gate flag (this is a correctness fix, default-on, fail-safe — the prior behavior was the bug).
|
|
103
|
+
|
|
104
|
+
## Conclusion
|
|
105
|
+
|
|
106
|
+
The change removes a false-positive whole-agent halt, shares placement's exact eligibility so the
|
|
107
|
+
throttle and placer can't diverge (no respawn loop), and bounds degraded-data behavior in the safe
|
|
108
|
+
direction. Reviewed to convergence over 3 rounds (the first two designs were rejected and redesigned).
|
|
109
|
+
All three test tiers green; 253 quota tests pass with no regressions.
|
|
110
|
+
|
|
111
|
+
## Second-pass review (if required)
|
|
112
|
+
|
|
113
|
+
Done — the spec-converge panel (6 internal reviewers + codex GPT-5.5 external) served as the
|
|
114
|
+
multi-reviewer second pass across 3 rounds; both high-signal reviewers returned "CONVERGED — no
|
|
115
|
+
material findings" in the final round. Concurred: true.
|
|
116
|
+
|
|
117
|
+
## Evidence pointers
|
|
118
|
+
|
|
119
|
+
- Spec: `docs/specs/POOL-AWARE-QUOTA-THROTTLE-SPEC.md` (review-convergence + approved)
|
|
120
|
+
- ELI16: `docs/specs/POOL-AWARE-QUOTA-THROTTLE-SPEC.eli16.md`
|
|
121
|
+
- Convergence report: `docs/specs/reports/POOL-AWARE-QUOTA-THROTTLE-convergence.md`
|
|
122
|
+
- Round-1 findings: `docs/specs/reports/POOL-AWARE-QUOTA-THROTTLE-round1-findings.md`
|
|
123
|
+
- Tests: `tests/unit/quota-tracker-pool-aware.test.ts`, `tests/unit/quota-tracker-invalid-input.test.ts`, `tests/integration/pool-aware-quota-canstart.test.ts`
|