instar 1.3.503 → 1.3.505
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 +84 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/core/AutonomousSessions.d.ts +19 -0
- package/dist/core/AutonomousSessions.d.ts.map +1 -1
- package/dist/core/AutonomousSessions.js +71 -0
- package/dist/core/AutonomousSessions.js.map +1 -1
- package/dist/core/MachinePoolRegistry.d.ts +4 -0
- package/dist/core/MachinePoolRegistry.d.ts.map +1 -1
- package/dist/core/MachinePoolRegistry.js +4 -0
- package/dist/core/MachinePoolRegistry.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +13 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionRouter.d.ts +11 -0
- package/dist/core/SessionRouter.d.ts.map +1 -1
- package/dist/core/SessionRouter.js +10 -0
- package/dist/core/SessionRouter.js.map +1 -1
- package/dist/core/TransferByNickname.d.ts +11 -0
- package/dist/core/TransferByNickname.d.ts.map +1 -1
- package/dist/core/TransferByNickname.js +29 -6
- package/dist/core/TransferByNickname.js.map +1 -1
- package/dist/core/types.d.ts +13 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/SessionReaper.d.ts +27 -0
- package/dist/monitoring/SessionReaper.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.js +41 -2
- package/dist/monitoring/SessionReaper.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/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +50 -2
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +63 -63
- package/src/scaffold/templates.ts +2 -1
- package/upgrades/1.3.504.md +51 -0
- package/upgrades/1.3.505.md +57 -0
- package/upgrades/side-effects/multi-machine-seamlessness-ws11.md +105 -0
- package/upgrades/side-effects/multi-machine-seamlessness-ws12-ws14.md +197 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAyG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAS3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAyG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAyID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA4zCD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,EAKhG,mBAAmB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,GACpD,IAAI,CA8eN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgqYtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -384,6 +384,9 @@ let _inboundQueueStop = null;
|
|
|
384
384
|
* (forward/spawn on another machine → must NOT also dispatch locally) from a
|
|
385
385
|
* self placement. Set once in startServer()'s mesh block. */
|
|
386
386
|
let _meshSelfId = null;
|
|
387
|
+
/** WS1.1: read-only ownership lookup for the drain's spawn-boundary re-check
|
|
388
|
+
* (the registry is constructed later in startServer's pool block). */
|
|
389
|
+
let _ownershipReadForDrain = null;
|
|
387
390
|
/** Resolve the current router (Telegram-owning lease holder)'s base URL, or null if
|
|
388
391
|
* this machine IS the router / none is known. Used by the owner-side resume to fetch
|
|
389
392
|
* a moved topic's prior history from the router (bug #2). Set in the mesh block where
|
|
@@ -2014,6 +2017,22 @@ getAttentionTopicId) {
|
|
|
2014
2017
|
return { kind: 'local-delivered', injectError: err instanceof Error ? err.message : String(err) };
|
|
2015
2018
|
}
|
|
2016
2019
|
}
|
|
2020
|
+
// WS1.1 (MULTI-MACHINE-SEAMLESSNESS-SPEC): ownership re-check at the SPAWN
|
|
2021
|
+
// boundary. route() consulted ownership above, but ownership can move in
|
|
2022
|
+
// the window between that verdict and this spawn (entry queued under owner
|
|
2023
|
+
// A, transferred to B mid-queue, drained on A) — a non-owner spawn is the
|
|
2024
|
+
// double-session bug (audit F20). Bounce to un-routable: the entry
|
|
2025
|
+
// re-queues and the next drain pass re-routes against FRESH ownership
|
|
2026
|
+
// (forward to the real owner / queue). Direct-inject into an EXISTING
|
|
2027
|
+
// local session above is not gated — a live local session for the topic is
|
|
2028
|
+
// itself the strongest local-serving signal, and the reconciler/closeout
|
|
2029
|
+
// own its lifecycle.
|
|
2030
|
+
if (_ownershipReadForDrain && _meshSelfId) {
|
|
2031
|
+
const ownRec = _ownershipReadForDrain(dmsg.sessionKey);
|
|
2032
|
+
if (ownRec && ownRec.status === 'active' && ownRec.ownerMachineId !== _meshSelfId) {
|
|
2033
|
+
return { kind: 'un-routable', reason: 'ownership-moved-before-spawn' };
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2017
2036
|
// Respawn / auto-spawn path. The spawn-in-progress guard maps to
|
|
2018
2037
|
// un-routable (§3.1) — never a silent skip.
|
|
2019
2038
|
if (spawningTopics.has(topicId)) {
|
|
@@ -11394,6 +11413,27 @@ export async function startServer(options) {
|
|
|
11394
11413
|
return false; /* @silent-fallback-ok — no pin signal → hold not applied, closeout behaves as before */
|
|
11395
11414
|
}
|
|
11396
11415
|
},
|
|
11416
|
+
// WS1.2 P19 breaker escalation: ONE deduped attention item when the
|
|
11417
|
+
// post-transfer closeout gives up on a permanently-vetoing session.
|
|
11418
|
+
// The attention store dedupes on id, so a re-opening breaker within
|
|
11419
|
+
// the same episode never floods (P17). Best-effort — the audit row in
|
|
11420
|
+
// sentinel-events.jsonl is the durable record either way.
|
|
11421
|
+
raiseAttention: (item) => {
|
|
11422
|
+
try {
|
|
11423
|
+
if (!telegram)
|
|
11424
|
+
return;
|
|
11425
|
+
void telegram.createAttentionItem({
|
|
11426
|
+
id: item.id,
|
|
11427
|
+
title: item.title,
|
|
11428
|
+
summary: item.summary,
|
|
11429
|
+
description: item.description,
|
|
11430
|
+
category: 'sessions',
|
|
11431
|
+
priority: 'NORMAL',
|
|
11432
|
+
sourceContext: 'session-reaper:closeout-breaker',
|
|
11433
|
+
}).catch(() => { });
|
|
11434
|
+
}
|
|
11435
|
+
catch { /* @silent-fallback-ok — telegram not wired yet (TDZ window) → audit-only */ }
|
|
11436
|
+
},
|
|
11397
11437
|
audit: reaperAuditSink(config.stateDir),
|
|
11398
11438
|
},
|
|
11399
11439
|
// developmentAgent gate (standard_development_agent_dark_feature_gate):
|
|
@@ -11892,6 +11932,10 @@ export async function startServer(options) {
|
|
|
11892
11932
|
loadAvg: osMod.loadavg()[0],
|
|
11893
11933
|
quotaState: selfQuotaState(),
|
|
11894
11934
|
guardPosture: selfGuardPosture(),
|
|
11935
|
+
// WS1.1 capability advertisement (spec invariant 5): a bounded
|
|
11936
|
+
// fixed-size summary, never an inventory. Reported live each
|
|
11937
|
+
// heartbeat so a queue going dark withdraws the capability.
|
|
11938
|
+
seamlessnessFlags: { ws11DeliverReceive: !!_inboundQueue },
|
|
11895
11939
|
// Durable Inbound Message Queue §5.1: depth + oldest + tenure +
|
|
11896
11940
|
// bounded top-K — the survivor's loss-SUSPECTED item, capped
|
|
11897
11941
|
// re-placement arm, and supersede-dedupe key all read these.
|
|
@@ -11984,6 +12028,10 @@ export async function startServer(options) {
|
|
|
11984
12028
|
logger: (m) => console.log(pc.dim(` ${m}`)),
|
|
11985
12029
|
});
|
|
11986
12030
|
const ownReg = sessionOwnershipRegistry;
|
|
12031
|
+
// WS1.1: expose a read-only ownership lookup to the drain's
|
|
12032
|
+
// spawn-boundary re-check (module-scope; the drain closure is defined
|
|
12033
|
+
// before this block runs).
|
|
12034
|
+
_ownershipReadForDrain = (sk) => ownReg.read(sk);
|
|
11987
12035
|
// ── WS3 one-voice: bind the election's late pool deps ──
|
|
11988
12036
|
// From here on the SpeakerElection sees the real pool: online machine
|
|
11989
12037
|
// ids from the capacity registry and live topic ownership from the
|
|
@@ -13147,6 +13195,17 @@ export async function startServer(options) {
|
|
|
13147
13195
|
// sending its sessions down the existing failover re-place path
|
|
13148
13196
|
// without each message re-paying the retry tax.
|
|
13149
13197
|
isMachineAlive: (m) => m === meshSelfId || ((machinePoolRegistry?.getCapacity(m)?.online ?? false) && !ownerSuspectBreaker.isSuspect(m)),
|
|
13198
|
+
// WS1.1 skew gate: read the owner's advertised receive capability
|
|
13199
|
+
// from its last heartbeat. A peer with NO flags field is an older
|
|
13200
|
+
// version → false (the conservative side: queue, don't forward into
|
|
13201
|
+
// a 501→failover steal). A peer the registry doesn't know → null
|
|
13202
|
+
// (unknown; the alive-check upstream already filters those).
|
|
13203
|
+
ownerSupportsForward: (m) => {
|
|
13204
|
+
const cap = machinePoolRegistry?.getCapacity(m);
|
|
13205
|
+
if (!cap)
|
|
13206
|
+
return null;
|
|
13207
|
+
return cap.seamlessnessFlags?.ws11DeliverReceive === true;
|
|
13208
|
+
},
|
|
13150
13209
|
markOwnerSuspect: (m) => ownerSuspectBreaker.markSuspect(m),
|
|
13151
13210
|
onOwnerResponsive: (m) => ownerSuspectBreaker.recordSuccess(m),
|
|
13152
13211
|
casClaimOwnership: (sk, machineId) => {
|
|
@@ -13567,6 +13626,7 @@ export async function startServer(options) {
|
|
|
13567
13626
|
// Inert unless the rollout stage is past 'dark' (gated at the call site).
|
|
13568
13627
|
const nickMod = await import('../core/NicknameCommand.js');
|
|
13569
13628
|
const transferMod = await import('../core/TransferByNickname.js');
|
|
13629
|
+
const autonomousSessionsModule = await import('../core/AutonomousSessions.js');
|
|
13570
13630
|
const pinMod = await import('../core/TopicPlacementPinStore.js');
|
|
13571
13631
|
const relocSetMod = await import('../core/RelocationNicknameSet.js');
|
|
13572
13632
|
const nickAssignMod = await import('../core/NicknameAssigner.js');
|
|
@@ -13627,6 +13687,30 @@ export async function startServer(options) {
|
|
|
13627
13687
|
currentPinOf: (sk) => _topicPinStore?.get(sk)?.preferredMachine ?? null,
|
|
13628
13688
|
lastPlacementUpdateAt: (sk) => _topicPinStore?.lastUpdatedAtMs(sk) ?? null,
|
|
13629
13689
|
now: () => Date.now(),
|
|
13690
|
+
// WS1.4 consent gate: a LIVE local autonomous run on this topic
|
|
13691
|
+
// requires explicit confirmation before a move. The confirmed
|
|
13692
|
+
// move goes through POST /pool/transfer with confirm:true
|
|
13693
|
+
// (which performs the turn-boundary suspend); this NL arm only
|
|
13694
|
+
// ever needs to ASK. Local-registry evidence only — a run on a
|
|
13695
|
+
// remote owner is covered when the WS1.2 drain verb lands.
|
|
13696
|
+
autonomousRunActive: (sk) => {
|
|
13697
|
+
try {
|
|
13698
|
+
const autoMod = autonomousSessionsModule;
|
|
13699
|
+
const job = autoMod?.listAutonomousJobs(config.stateDir).find((j) => j.topic === sk && j.active && !j.paused);
|
|
13700
|
+
if (!job)
|
|
13701
|
+
return null;
|
|
13702
|
+
let remainingMinutes = null;
|
|
13703
|
+
if (job.startedAt && job.durationSeconds != null) {
|
|
13704
|
+
const endMs = Date.parse(job.startedAt) + job.durationSeconds * 1000;
|
|
13705
|
+
if (Number.isFinite(endMs))
|
|
13706
|
+
remainingMinutes = Math.max(0, Math.round((endMs - Date.now()) / 60_000));
|
|
13707
|
+
}
|
|
13708
|
+
return { goal: job.goal, remainingMinutes };
|
|
13709
|
+
}
|
|
13710
|
+
catch {
|
|
13711
|
+
return null; /* @silent-fallback-ok — unreadable run registry → veto not applied; the NL move behaves as before WS1.4 */
|
|
13712
|
+
}
|
|
13713
|
+
},
|
|
13630
13714
|
}, sessionKey);
|
|
13631
13715
|
if (plan.action === 'transfer' || plan.action === 'noop') {
|
|
13632
13716
|
const target = plan.targetMachine;
|