instar 1.3.381 → 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/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +63 -60
- package/dist/commands/server.js.map +1 -1
- package/dist/core/ConvergenceChecker.js +1 -1
- package/dist/core/ConvergenceChecker.js.map +1 -1
- package/dist/core/PostUpdateMigrator.js +1 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +20 -20
- package/src/templates/scripts/convergence-check.sh +4 -1
- package/upgrades/1.3.383.md +76 -0
- package/upgrades/side-effects/convergence-commitment-regex-boundaries.md +53 -0
- package/upgrades/side-effects/quota-collector-polling-independence.md +62 -0
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
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": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1122,7 +1122,7 @@
|
|
|
1122
1122
|
"type": "template",
|
|
1123
1123
|
"domain": "operations",
|
|
1124
1124
|
"sourcePath": "src/templates/scripts/convergence-check.sh",
|
|
1125
|
-
"contentHash": "
|
|
1125
|
+
"contentHash": "0908e2775c497fe526b817563b6f8e29ec4d6bedaf5521a87e625857afc367c3",
|
|
1126
1126
|
"since": "2025-01-01"
|
|
1127
1127
|
},
|
|
1128
1128
|
"template:emit-session-clock.sh": {
|
|
@@ -1538,7 +1538,7 @@
|
|
|
1538
1538
|
"type": "subsystem",
|
|
1539
1539
|
"domain": "updates",
|
|
1540
1540
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1541
|
-
"contentHash": "
|
|
1541
|
+
"contentHash": "8bc2ad931e539665db73afc0659619ec51ef9abfe807f2b8a4f79859aa36b1b6",
|
|
1542
1542
|
"since": "2025-01-01"
|
|
1543
1543
|
},
|
|
1544
1544
|
"subsystem:scheduler": {
|
|
@@ -30,7 +30,10 @@ if echo "$CONTENT" | grep -qiE "(unfortunately.{0,20}(i can.t|i.m unable|not (po
|
|
|
30
30
|
fi
|
|
31
31
|
|
|
32
32
|
# 2. COMMITMENT OVERREACH — Promises that may not survive session boundaries
|
|
33
|
-
|
|
33
|
+
# Word-boundary guards (live FPs 2026-06-06): "Mini promises"/"I promised"
|
|
34
|
+
# matched the bare `i (promise...)` — the leading i must start a word and
|
|
35
|
+
# `promise` must not continue into promised/promises.
|
|
36
|
+
if echo "$CONTENT" | grep -qiE "(^|[^a-zA-Z])i.ll (make sure|ensure|guarantee|always|never forget)|(^|[^a-zA-Z])i (promise([^a-zA-Z]|$)|commit to|will always)|you can count on me to|(^|[^a-zA-Z])i.ll remember (to|this)|from now on i.ll"; then
|
|
34
37
|
ISSUES+=("COMMITMENT: You're making a promise that may not survive context compaction or session end. Can your infrastructure actually keep this commitment? If not, reframe as intent rather than guarantee.")
|
|
35
38
|
ISSUE_COUNT=$((ISSUE_COUNT + 1))
|
|
36
39
|
fi
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The pre-messaging quality gate's "commitment overreach" pattern matched the
|
|
9
|
+
bare sequence `i (promise|...)` anywhere in a message — including INSIDE other
|
|
10
|
+
words. "the Mini promises" (a word ending in *i* followed by a plural noun) and
|
|
11
|
+
"everything I promised" (past-tense narration) both tripped it; in one day it
|
|
12
|
+
blocked five legitimate status reports that contained no promise at all.
|
|
13
|
+
|
|
14
|
+
The pattern (all three copies: the shipped shell template, the migrator's
|
|
15
|
+
inline fallback, and the TypeScript ConvergenceChecker) now requires the
|
|
16
|
+
leading *i* to start a word and refuses to match when "promise" continues into
|
|
17
|
+
promised/promises. Real first-person commitments ("I promise to…",
|
|
18
|
+
"I'll make sure…", "you can count on me to…") still trip exactly as before.
|
|
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
|
+
|
|
33
|
+
## What to Tell Your User
|
|
34
|
+
|
|
35
|
+
Nothing — fewer spurious "message blocked" interruptions when the agent
|
|
36
|
+
mentions promises as a topic rather than making one.
|
|
37
|
+
|
|
38
|
+
- audience: agent-only
|
|
39
|
+
- maturity: stable
|
|
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
|
+
|
|
48
|
+
## Summary of New Capabilities
|
|
49
|
+
|
|
50
|
+
- Word-boundary guards on the commitment_overreach pattern in
|
|
51
|
+
`templates/scripts/convergence-check.sh`, the PostUpdateMigrator inline
|
|
52
|
+
fallback, and `ConvergenceChecker.ts` — kept in lockstep.
|
|
53
|
+
- Existing agents receive the fixed script automatically (convergence-check.sh
|
|
54
|
+
is always-overwritten from the template on every migration pass).
|
|
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
|
+
|
|
61
|
+
## Evidence
|
|
62
|
+
|
|
63
|
+
- `tests/unit/convergence-check.test.ts` (+6): the five live false positives
|
|
64
|
+
pass; real present-tense promises, sentence-final "I promise.", and the
|
|
65
|
+
other commitment phrasings still flag. 61/61 in file (runs the REAL script).
|
|
66
|
+
- `tests/unit/convergence-checker-commitment-boundary.test.ts` (new): the same
|
|
67
|
+
both-sides matrix against the TS checker.
|
|
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,53 @@
|
|
|
1
|
+
# Side-Effects Review — Convergence commitment-regex word boundaries
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `convergence-commitment-regex-boundaries`
|
|
4
|
+
**Date:** `2026-06-06`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `not required`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Word-boundary guards on the commitment_overreach pattern (3 lockstep copies:
|
|
11
|
+
shell template, migrator inline fallback, TS checker). Live FPs "Mini
|
|
12
|
+
promises" / "I promised" blocked five legitimate messages in one day.
|
|
13
|
+
|
|
14
|
+
## Decision-point inventory
|
|
15
|
+
|
|
16
|
+
One: the boundary semantics — leading `(^|[^a-zA-Z])i ` and trailing
|
|
17
|
+
`promise([^a-zA-Z]|$)`. Chosen over `\b` for BSD-grep portability; verified
|
|
18
|
+
on macOS grep with a 12-string both-sides probe before patching.
|
|
19
|
+
|
|
20
|
+
## 1. Over-block
|
|
21
|
+
|
|
22
|
+
None added — the new pattern matches a strict SUBSET of the old one.
|
|
23
|
+
|
|
24
|
+
## 2. Under-block
|
|
25
|
+
|
|
26
|
+
Deliberate: past-tense "I promised" no longer flags. That phrasing narrates a
|
|
27
|
+
prior commitment rather than making one; the gate's purpose is catching NEW
|
|
28
|
+
promises that may not survive the session. "I promise" present-tense, bare
|
|
29
|
+
sentence-final, and every other phrasing alternative still flag (tested).
|
|
30
|
+
|
|
31
|
+
## 3. Level-of-abstraction fit
|
|
32
|
+
|
|
33
|
+
The fix lives in the pattern itself, in all three places the pattern exists —
|
|
34
|
+
no new layers. The template is the canonical copy; the migrator's
|
|
35
|
+
always-overwrite delivers it to existing agents (Migration Parity satisfied
|
|
36
|
+
structurally, no new migration needed).
|
|
37
|
+
|
|
38
|
+
## 4. Signal vs authority compliance
|
|
39
|
+
|
|
40
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
41
|
+
|
|
42
|
+
The gate keeps exactly its existing authority (block-before-send); this change
|
|
43
|
+
only narrows its trigger to what it was always meant to catch.
|
|
44
|
+
|
|
45
|
+
## 5. Interactions
|
|
46
|
+
|
|
47
|
+
- grounding-before-messaging.sh consumes the script unchanged.
|
|
48
|
+
- The LLM-side reviewers are unaffected (this is the deterministic tier).
|
|
49
|
+
- Self-Violation Signal / correction loops: fewer false correction inputs.
|
|
50
|
+
|
|
51
|
+
## 6. External surfaces
|
|
52
|
+
|
|
53
|
+
None. No routes, config, or notifications.
|
|
@@ -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`.
|