instar 0.28.65 → 0.28.67
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/cli.js +53 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/AutoDispatcher.d.ts +4 -1
- package/dist/core/AutoDispatcher.d.ts.map +1 -1
- package/dist/core/AutoDispatcher.js +5 -4
- package/dist/core/AutoDispatcher.js.map +1 -1
- package/dist/core/AutoUpdater.d.ts +6 -1
- package/dist/core/AutoUpdater.d.ts.map +1 -1
- package/dist/core/AutoUpdater.js +7 -4
- package/dist/core/AutoUpdater.js.map +1 -1
- package/dist/lifeline/LifelineHealthWatchdog.d.ts +81 -0
- package/dist/lifeline/LifelineHealthWatchdog.d.ts.map +1 -0
- package/dist/lifeline/LifelineHealthWatchdog.js +122 -0
- package/dist/lifeline/LifelineHealthWatchdog.js.map +1 -0
- package/dist/lifeline/RestartOrchestrator.d.ts +73 -0
- package/dist/lifeline/RestartOrchestrator.d.ts.map +1 -0
- package/dist/lifeline/RestartOrchestrator.js +124 -0
- package/dist/lifeline/RestartOrchestrator.js.map +1 -0
- package/dist/lifeline/TelegramLifeline.d.ts +55 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +364 -41
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/lifeline/droppedMessages.d.ts +67 -0
- package/dist/lifeline/droppedMessages.d.ts.map +1 -0
- package/dist/lifeline/droppedMessages.js +179 -0
- package/dist/lifeline/droppedMessages.js.map +1 -0
- package/dist/lifeline/forwardErrors.d.ts +38 -0
- package/dist/lifeline/forwardErrors.d.ts.map +1 -0
- package/dist/lifeline/forwardErrors.js +53 -0
- package/dist/lifeline/forwardErrors.js.map +1 -0
- package/dist/lifeline/rateLimitState.d.ts +63 -0
- package/dist/lifeline/rateLimitState.d.ts.map +1 -0
- package/dist/lifeline/rateLimitState.js +110 -0
- package/dist/lifeline/rateLimitState.js.map +1 -0
- package/dist/lifeline/retryWithBackoff.d.ts +28 -0
- package/dist/lifeline/retryWithBackoff.d.ts.map +1 -0
- package/dist/lifeline/retryWithBackoff.js +34 -0
- package/dist/lifeline/retryWithBackoff.js.map +1 -0
- package/dist/lifeline/startupMarker.d.ts +20 -0
- package/dist/lifeline/startupMarker.d.ts.map +1 -0
- package/dist/lifeline/startupMarker.js +52 -0
- package/dist/lifeline/startupMarker.js.map +1 -0
- package/dist/lifeline/versionHandshake.d.ts +40 -0
- package/dist/lifeline/versionHandshake.d.ts.map +1 -0
- package/dist/lifeline/versionHandshake.js +45 -0
- package/dist/lifeline/versionHandshake.js.map +1 -0
- package/dist/messaging/shared/compactionResumePayload.d.ts +1 -1
- package/dist/messaging/shared/compactionResumePayload.d.ts.map +1 -1
- package/dist/messaging/shared/compactionResumePayload.js +14 -5
- package/dist/messaging/shared/compactionResumePayload.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +58 -1
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +82 -82
- package/upgrades/0.28.66.md +44 -0
- package/upgrades/0.28.67.md +58 -0
- package/upgrades/side-effects/0.28.65.md +59 -0
- package/upgrades/side-effects/0.28.66.md +130 -0
- package/upgrades/side-effects/lifeline-message-drop-stage-a.md +155 -0
- package/upgrades/side-effects/lifeline-self-restart-stage-b.md +129 -0
- package/upgrades/NEXT.md +0 -53
package/dist/server/routes.js
CHANGED
|
@@ -13,6 +13,7 @@ import path from 'node:path';
|
|
|
13
13
|
import { rateLimiter, signViewPath } from './middleware.js';
|
|
14
14
|
import { validateWriteToken, canPerformOperation } from '../core/StateWriteAuthority.js';
|
|
15
15
|
import { DegradationReporter } from '../monitoring/DegradationReporter.js';
|
|
16
|
+
import { parseVersion, compareVersions } from '../lifeline/versionHandshake.js';
|
|
16
17
|
import { GATE_ROUTE_VERSION, GATE_ROUTE_MINIMUM_VERSION, getHotPathState, setKillSwitch, getKillSwitch, recordSessionStart, getMode, setMode, } from './stopGate.js';
|
|
17
18
|
import { assembleReminder, } from '../core/UnjustifiedStopGate.js';
|
|
18
19
|
import { dayKeyFor } from '../core/StopGateDb.js';
|
|
@@ -5608,8 +5609,64 @@ export function createRoutes(ctx) {
|
|
|
5608
5609
|
// ── Internal: Lifeline Telegram Forward ─────────────────────────
|
|
5609
5610
|
// Receives messages from the Telegram Lifeline process and injects
|
|
5610
5611
|
// them into the appropriate session, just like TelegramAdapter would.
|
|
5612
|
+
// Cache serverVersion once at route-registration time. Use ProcessIntegrity
|
|
5613
|
+
// (the running-in-memory version frozen at boot) rather than a live disk
|
|
5614
|
+
// read that can drift after npm install -g. Stale-version prevention
|
|
5615
|
+
// guardrail: routes.ts tests assert this path is NOT a live read. Per spec,
|
|
5616
|
+
// if this fails to resolve to parseable semver, /internal/telegram-forward
|
|
5617
|
+
// responds 503 to skip the handshake path.
|
|
5618
|
+
const _serverVersionString = ProcessIntegrity.getInstance()?.getState().runningVersion ?? '';
|
|
5619
|
+
const _serverVersionParsed = parseVersion(_serverVersionString);
|
|
5611
5620
|
router.post('/internal/telegram-forward', async (req, res) => {
|
|
5612
|
-
const { topicId, text, fromUserId, fromUsername, fromFirstName, messageId } = req.body;
|
|
5621
|
+
const { topicId, text, fromUserId, fromUsername, fromFirstName, messageId, lifelineVersion } = req.body;
|
|
5622
|
+
// Server boot window: if version cache wasn't populated, skip handshake
|
|
5623
|
+
// rather than 426-erroneously. Lifeline retries after retryAfterMs.
|
|
5624
|
+
if (!_serverVersionParsed) {
|
|
5625
|
+
res.status(503).json({ ok: false, reason: 'server-boot-incomplete', retryAfterMs: 1000 });
|
|
5626
|
+
return;
|
|
5627
|
+
}
|
|
5628
|
+
// Version-handshake (only when lifelineVersion field is present AND
|
|
5629
|
+
// auth is configured — dev-mode with empty authToken skips the handshake
|
|
5630
|
+
// to avoid unauth'd fingerprinting channel if bearer-auth ever regresses).
|
|
5631
|
+
const authEnabled = Boolean(ctx.config.authToken);
|
|
5632
|
+
if (lifelineVersion !== undefined && authEnabled) {
|
|
5633
|
+
const clientVersion = parseVersion(lifelineVersion);
|
|
5634
|
+
if (!clientVersion) {
|
|
5635
|
+
res.status(400).json({ ok: false, error: 'invalid lifelineVersion' });
|
|
5636
|
+
return;
|
|
5637
|
+
}
|
|
5638
|
+
const decision = compareVersions(_serverVersionParsed, clientVersion);
|
|
5639
|
+
if (decision.kind === 'upgrade-required') {
|
|
5640
|
+
res.status(426).json({
|
|
5641
|
+
ok: false,
|
|
5642
|
+
upgradeRequired: true,
|
|
5643
|
+
serverVersion: decision.serverVersionString,
|
|
5644
|
+
action: 'restart',
|
|
5645
|
+
reason: 'major-minor-mismatch',
|
|
5646
|
+
});
|
|
5647
|
+
return;
|
|
5648
|
+
}
|
|
5649
|
+
if (decision.kind === 'accept-with-patch-info') {
|
|
5650
|
+
DegradationReporter.getInstance().report({
|
|
5651
|
+
feature: 'TelegramLifeline.versionSkewInfo',
|
|
5652
|
+
primary: 'Informational — lifeline patch drift beyond policy',
|
|
5653
|
+
fallback: 'No behavior change; forward accepted',
|
|
5654
|
+
reason: `patch drift ${decision.patchDiff} between lifeline and server`,
|
|
5655
|
+
impact: 'Lifeline hasn’t restarted in a while; consider manual kick.',
|
|
5656
|
+
});
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
else if (lifelineVersion === undefined && authEnabled) {
|
|
5660
|
+
// Backward-compat: pre-Stage-B lifelines don't send the field. Accept,
|
|
5661
|
+
// emit informational signal once per cooldown.
|
|
5662
|
+
DegradationReporter.getInstance().report({
|
|
5663
|
+
feature: 'TelegramLifeline.versionMissing',
|
|
5664
|
+
primary: 'Forward from Stage-B lifeline with version field',
|
|
5665
|
+
fallback: 'Forward from pre-Stage-B lifeline (no version)',
|
|
5666
|
+
reason: 'lifelineVersion field absent — backward-compat path',
|
|
5667
|
+
impact: 'Observability only; lifeline needs a restart to pick up Stage B.',
|
|
5668
|
+
});
|
|
5669
|
+
}
|
|
5613
5670
|
if (!topicId || !text) {
|
|
5614
5671
|
res.status(400).json({ error: 'topicId and text required' });
|
|
5615
5672
|
return;
|