instar 1.3.382 → 1.3.383

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.382",
3
+ "version": "1.3.383",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-06T21:57:08.261Z",
5
- "instarVersion": "1.3.382",
4
+ "generatedAt": "2026-06-06T22:01:27.206Z",
5
+ "instarVersion": "1.3.383",
6
6
  "entryCount": 199,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -17,6 +17,19 @@ leading *i* to start a word and refuses to match when "promise" continues into
17
17
  promised/promises. Real first-person commitments ("I promise to…",
18
18
  "I'll make sure…", "you can count on me to…") still trip exactly as before.
19
19
 
20
+ The quota collector (which writes quota-state.json) and the QuotaManager that
21
+ drives its adaptive polling were nested inside the server's
22
+ "I own Telegram polling" block. On any agent whose LIFELINE owns polling — the
23
+ normal production topology — that block is skipped, so the collector never ran:
24
+ quota-state.json was never written, the tracker read an absent file, and
25
+ quota-aware placement stayed permanently fail-open (the exact rate-limit-stall
26
+ hazard from the EXO incident it exists to prevent). Turning on quotaTracking
27
+ alone could not fix it; the writer was gated behind an unrelated condition.
28
+
29
+ The account switcher + collector + QuotaManager pipeline now live at top scope
30
+ (after the scheduler is constructed, so migration wiring is real), gated only on
31
+ the quota tracker — so the collector runs regardless of who polls Telegram.
32
+
20
33
  ## What to Tell Your User
21
34
 
22
35
  Nothing — fewer spurious "message blocked" interruptions when the agent
@@ -25,6 +38,13 @@ mentions promises as a topic rather than making one.
25
38
  - audience: agent-only
26
39
  - maturity: stable
27
40
 
41
+ If you run a lifeline-driven agent and turned on quota tracking but never saw
42
+ quota data, this is why — now it collects. Quota-aware placement (routing work
43
+ away from a rate-limited machine) actually has data to act on.
44
+
45
+ - audience: agent-only
46
+ - maturity: stable
47
+
28
48
  ## Summary of New Capabilities
29
49
 
30
50
  - Word-boundary guards on the commitment_overreach pattern in
@@ -33,6 +53,11 @@ mentions promises as a topic rather than making one.
33
53
  - Existing agents receive the fixed script automatically (convergence-check.sh
34
54
  is always-overwritten from the template on every migration pass).
35
55
 
56
+ - Quota collection + adaptive polling run independent of Telegram-polling
57
+ ownership (was send-only-server dead).
58
+ - accountSwitcher hoisted to top scope (still consumed by the polling block's
59
+ wireTelegramCallbacks when that path runs).
60
+
36
61
  ## Evidence
37
62
 
38
63
  - `tests/unit/convergence-check.test.ts` (+6): the five live false positives
@@ -41,3 +66,11 @@ mentions promises as a topic rather than making one.
41
66
  - `tests/unit/convergence-checker-commitment-boundary.test.ts` (new): the same
42
67
  both-sides matrix against the TS checker.
43
68
  - Pattern verified on macOS (BSD) grep -E with 12 probe strings before patching.
69
+
70
+ - `tests/unit/quota-collector-polling-independence-wiring.test.ts` (new, 3
71
+ tests): quotaManager.start() is reached before the !lifelineOwnsPolling
72
+ block; the pipeline is constructed after the scheduler; no second
73
+ QuotaManager construction (no double-start).
74
+ - Live: echo logs "Telegram send-only mode (lifeline owns polling)" + "No quota
75
+ state file found — fail-open" pre-fix; quota-state.json + real GET /quota data
76
+ post-fix (live re-verify after release).
@@ -0,0 +1,62 @@
1
+ # Side-Effects Review — Quota collector polling independence (finding A1)
2
+
3
+ **Version / slug:** `quota-collector-polling-independence`
4
+ **Date:** `2026-06-06`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required`
7
+
8
+ ## Summary of the change
9
+
10
+ The QuotaManager/collector/accountSwitcher pipeline was hoisted out of the
11
+ `if (telegramConfig && !skipTelegram && !isStandbyTelegram && !lifelineOwnsPolling)`
12
+ block to top scope (after the scheduler exists), gated only on quotaTracker.
13
+ On lifeline-owns-polling agents the collector never started → fail-open
14
+ placement (finding A1).
15
+
16
+ ## Decision-point inventory
17
+
18
+ One: WHERE the pipeline runs. Now: top scope, after scheduler, gated on
19
+ quotaTracker. Before: inside the server-owns-polling block.
20
+
21
+ ## 1. Over-block
22
+
23
+ None. The pipeline now runs in MORE cases (send-only servers too), never fewer.
24
+
25
+ ## 2. Under-block
26
+
27
+ The collector still no-ops for non-claude-code frameworks (unchanged) and when
28
+ quotaTracking is off (unchanged). A missing OAuth credential still degrades to
29
+ JSONL estimation inside QuotaCollector (unchanged).
30
+
31
+ ## 3. Level-of-abstraction fit
32
+
33
+ Quota collection is independent of Telegram-polling ownership; placing it with
34
+ the other top-scope monitoring setup (after scheduler, beside telemetry
35
+ heartbeat) is the correct layer. accountSwitcher moves with it; its later
36
+ consumer (wireTelegramCallbacks, inside the polling block) resolves it from the
37
+ enclosing scope — verified by tsc.
38
+
39
+ ## 4. Signal vs authority compliance
40
+
41
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
42
+
43
+ No authority change. quota-aware placement remains fail-open on absent data;
44
+ this fix simply lets the data exist.
45
+
46
+ ## 5. Interactions
47
+
48
+ - Scheduler: the pipeline now runs after `scheduler` is constructed, so
49
+ setScheduler() wires a real scheduler (was already conditional on `scheduler`).
50
+ - wireTelegramCallbacks (polling block): consumes the hoisted accountSwitcher
51
+ from the enclosing scope — only runs in the polling path, harmless otherwise.
52
+ - notify(): defined at outer scope (function decl), called lazily on threshold
53
+ crossings — safe to construct the notifier earlier.
54
+ - Double-start: the old in-block copy was REMOVED (test asserts a single
55
+ QuotaManager construction) — no risk of two pollers.
56
+ - guard-posture tripwire: already observed quotaTracking re-enabled; this fix
57
+ makes that enablement actually produce data.
58
+
59
+ ## 6. External surfaces
60
+
61
+ No new routes/config/notifications. `GET /quota` now returns real data on
62
+ lifeline-driven agents instead of `no_data`.