instar 1.3.1582 → 1.3.1584
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/dashboard/console/console.css +14 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +98 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/core/AppConversationService.d.ts +15 -0
- package/dist/core/AppConversationService.d.ts.map +1 -1
- package/dist/core/AppConversationService.js +20 -0
- package/dist/core/AppConversationService.js.map +1 -1
- package/dist/core/AppConversationStore.d.ts +21 -3
- package/dist/core/AppConversationStore.d.ts.map +1 -1
- package/dist/core/AppConversationStore.js +35 -5
- package/dist/core/AppConversationStore.js.map +1 -1
- package/dist/core/AppConversationsReplicatedStore.js +1 -1
- package/dist/core/AppConversationsReplicatedStore.js.map +1 -1
- package/dist/core/AppRecordSignatures.d.ts +102 -0
- package/dist/core/AppRecordSignatures.d.ts.map +1 -0
- package/dist/core/AppRecordSignatures.js +247 -0
- package/dist/core/AppRecordSignatures.js.map +1 -0
- package/dist/core/CoherenceJournal.d.ts +1 -1
- package/dist/core/CoherenceJournal.d.ts.map +1 -1
- package/dist/core/CoherenceJournal.js +10 -2
- package/dist/core/CoherenceJournal.js.map +1 -1
- package/dist/core/MobileDeviceKeyLedger.d.ts +93 -0
- package/dist/core/MobileDeviceKeyLedger.d.ts.map +1 -0
- package/dist/core/MobileDeviceKeyLedger.js +323 -0
- package/dist/core/MobileDeviceKeyLedger.js.map +1 -0
- package/dist/core/MobileDeviceKeyLedgerReplicatedStore.d.ts +19 -0
- package/dist/core/MobileDeviceKeyLedgerReplicatedStore.d.ts.map +1 -0
- package/dist/core/MobileDeviceKeyLedgerReplicatedStore.js +53 -0
- package/dist/core/MobileDeviceKeyLedgerReplicatedStore.js.map +1 -0
- package/dist/core/MobileDeviceKeys.d.ts +9 -2
- package/dist/core/MobileDeviceKeys.d.ts.map +1 -1
- package/dist/core/MobileDeviceKeys.js +8 -4
- package/dist/core/MobileDeviceKeys.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +3 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +22 -2
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ReplicatedStoreReconcilerWiring.d.ts.map +1 -1
- package/dist/core/ReplicatedStoreReconcilerWiring.js +1 -0
- package/dist/core/ReplicatedStoreReconcilerWiring.js.map +1 -1
- package/dist/core/devGatedFeatures.js +1 -1
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/core/peerHomebaseAwareness.d.ts +2 -0
- package/dist/core/peerHomebaseAwareness.d.ts.map +1 -1
- package/dist/core/peerHomebaseAwareness.js +12 -0
- package/dist/core/peerHomebaseAwareness.js.map +1 -1
- package/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +31 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.js +1 -1
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/mobileConversationRoutes.d.ts +22 -9
- package/dist/server/mobileConversationRoutes.d.ts.map +1 -1
- package/dist/server/mobileConversationRoutes.js +99 -25
- package/dist/server/mobileConversationRoutes.js.map +1 -1
- package/dist/server/mobilePairingRoutes.d.ts +10 -1
- package/dist/server/mobilePairingRoutes.d.ts.map +1 -1
- package/dist/server/mobilePairingRoutes.js +105 -6
- package/dist/server/mobilePairingRoutes.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +10 -2
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/PeerUserMeantJudge.d.ts +135 -0
- package/dist/threadline/PeerUserMeantJudge.d.ts.map +1 -0
- package/dist/threadline/PeerUserMeantJudge.js +394 -0
- package/dist/threadline/PeerUserMeantJudge.js.map +1 -0
- package/dist/threadline/ThreadlineEndpoints.d.ts +1 -0
- package/dist/threadline/ThreadlineEndpoints.d.ts.map +1 -1
- package/dist/threadline/ThreadlineEndpoints.js +2 -0
- package/dist/threadline/ThreadlineEndpoints.js.map +1 -1
- package/dist/threadline/ThreadlineRouter.d.ts +9 -1
- package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
- package/dist/threadline/ThreadlineRouter.js +17 -2
- package/dist/threadline/ThreadlineRouter.js.map +1 -1
- package/dist/threadline/TopicLinkageHandler.d.ts +21 -0
- package/dist/threadline/TopicLinkageHandler.d.ts.map +1 -1
- package/dist/threadline/TopicLinkageHandler.js +41 -15
- package/dist/threadline/TopicLinkageHandler.js.map +1 -1
- package/dist/threadline/peerHomebaseRelay.d.ts +32 -4
- package/dist/threadline/peerHomebaseRelay.d.ts.map +1 -1
- package/dist/threadline/peerHomebaseRelay.js +143 -35
- package/dist/threadline/peerHomebaseRelay.js.map +1 -1
- package/package.json +1 -1
- package/scripts/install-windows-desktop-companion.ps1 +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/src/data/state-coherence-registry.json +17 -0
- package/upgrades/1.3.1583.md +42 -0
- package/upgrades/1.3.1584.md +28 -0
- package/upgrades/side-effects/console-session-desktop-layout.eli16.md +9 -0
- package/upgrades/side-effects/console-session-desktop-layout.md +16 -0
- package/upgrades/side-effects/mobile-native-conversations-inc2.md +142 -0
- package/upgrades/side-effects/peer-homebase-per-message.md +149 -0
- package/upgrades/side-effects/windows-companion-no-console.md +45 -0
|
@@ -998,6 +998,19 @@ button.run-mark:focus-visible { outline: 2px solid var(--accent); outline-offset
|
|
|
998
998
|
.sess-actions a.btn-quiet { display: inline-flex; align-items: center; text-decoration: none; }
|
|
999
999
|
.sess-default-row { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: baseline; margin-top: var(--s-3); }
|
|
1000
1000
|
.sess-default-row .card-note { margin: 0; }
|
|
1001
|
+
/* Desktop: an open session fills the window beside the list, so the composer is
|
|
1002
|
+
always on screen (no page scroll to reach it) and the terminal takes the rest. */
|
|
1003
|
+
@media (min-width: 900px) {
|
|
1004
|
+
.main:has(> .sessions-page.has-open) { max-width: 1680px; padding-top: var(--s-6); padding-bottom: var(--s-6); }
|
|
1005
|
+
.sessions-page.has-open { grid-template-columns: minmax(280px, 340px) 1fr; }
|
|
1006
|
+
.sessions-page.has-open .sess-list .page-title { font-size: 28px; }
|
|
1007
|
+
.sessions-page.has-open .sess-view { top: calc(56px + var(--s-4)); height: calc(100dvh - 56px - var(--preview-h, 0px) - var(--s-6) - var(--s-4)); }
|
|
1008
|
+
.app:has(> .preview-banner) { --preview-h: 37px; }
|
|
1009
|
+
.sessions-page.has-open .sess-open { height: 100%; min-height: 0; }
|
|
1010
|
+
.sessions-page.has-open .sess-term-wrap { min-height: 0; }
|
|
1011
|
+
.sessions-page.has-open .sess-term { height: auto; min-height: 0; }
|
|
1012
|
+
.sessions-page.has-open .sess-composer { position: static; padding-bottom: 0; }
|
|
1013
|
+
}
|
|
1001
1014
|
.sess-default-box:empty { display: none; }
|
|
1002
1015
|
.sess-default-box { border: 1px solid var(--hairline); border-radius: var(--r-md); padding: var(--s-3); margin: var(--s-2) 0; }
|
|
1003
1016
|
.skeleton-row { pointer-events: none; }
|
|
@@ -1115,7 +1128,7 @@ button.run-mark:focus-visible { outline: 2px solid var(--accent); outline-offset
|
|
|
1115
1128
|
.mb-pace { margin-top: 4px; }
|
|
1116
1129
|
|
|
1117
1130
|
/* Preview address: say plainly that this is work in progress. */
|
|
1118
|
-
.preview-banner { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; padding: 8px 16px; background: #3a2f0b; color: #f6d77a; font-size: 14px; line-height: 1.4; }
|
|
1131
|
+
.preview-banner { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: baseline; padding: 8px 16px; background: #3a2f0b; color: #f6d77a; font-size: 14px; line-height: 1.4; }
|
|
1119
1132
|
.preview-banner a { color: inherit; text-decoration: underline; margin-left: auto; }
|
|
1120
1133
|
|
|
1121
1134
|
/* Home headline as a link to the first thing that needs the operator. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAuHA,OAAO,EAAE,cAAc,EAAwD,MAAM,2BAA2B,CAAC;AAgBjH,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA6BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA6J7D,OAAO,KAAK,EAAW,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA4GtD,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AA0ID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA0DD,+EAA+E;AAC/E,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,IAAI,CAAC,OAAO,2BAA2B,EAAE,cAAc,EAAE,QAAQ,CAAC,GAAG,IAAI,EACpF,OAAO,EAAE,MAAM,GACd,IAAI,CAEN;AAukBD,wBAAsB,oBAAoB,CACxC,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,kBAAkB,CAAC,EAAE,MAAM;AAC3B;;qCAEqC;AACrC,WAAW,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AACzD;;wEAEwE;AACxE,SAAS,CAAC,EAAE;IACV,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;sEAGkE;IAClE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GACA,OAAO,CAAC,MAAM,CAAC,CAiZjB;AA0xBD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,oBAAoB,GAAG,IAAI,GACxC;IACD,YAAY,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,CAqBA;AAED,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,EAQrD,oBAAoB,CAAC,EAAE,MAAM;IAC3B,YAAY,EAAE,OAAO,kBAAkB,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,GACP,IAAI,CAo4BN;AA+pBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA6x1BtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDzE;AA+BD,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkE5E"}
|
package/dist/commands/server.js
CHANGED
|
@@ -4731,6 +4731,10 @@ export async function startServer(options) {
|
|
|
4731
4731
|
// are on (no separate switch: for a native conversation the store is the only copy).
|
|
4732
4732
|
const { APP_CONVERSATIONS_KIND_REGISTRATION } = await import('../core/AppConversationsReplicatedStore.js');
|
|
4733
4733
|
replicatedKindRegistry.register(APP_CONVERSATIONS_KIND_REGISTRATION);
|
|
4734
|
+
// mobile-native-conversations §4.8 — the `mobileDeviceKeyLedger` kind (inert registration; on
|
|
4735
|
+
// whenever native app conversations are on, so a signed record can be checked on any machine).
|
|
4736
|
+
const { DEVICE_KEY_LEDGER_KIND_REGISTRATION } = await import('../core/MobileDeviceKeyLedgerReplicatedStore.js');
|
|
4737
|
+
replicatedKindRegistry.register(DEVICE_KEY_LEDGER_KIND_REGISTRATION);
|
|
4734
4738
|
// WS2.3 (ws23-relationships-userregistry-security) — register the SECOND concrete
|
|
4735
4739
|
// replicated kind, `relationship-record`, onto the registry: the FIRST PII kind.
|
|
4736
4740
|
// Dual-registry's dynamic half (the static half is CoherenceJournal.JOURNAL_KINDS,
|
|
@@ -4916,6 +4920,15 @@ export async function startServer(options) {
|
|
|
4916
4920
|
_appConversationService?.ingestReplicated(entries.map((e) => appEventFromReplicatedData(e.data)));
|
|
4917
4921
|
}).catch(() => { });
|
|
4918
4922
|
}
|
|
4923
|
+
// Device-key ledger rows: each lands only when it verifies under the pinned key of the machine it names.
|
|
4924
|
+
if (kind === 'mobile-device-key-ledger-row' && _appConversationService?.deps.keyLedger) {
|
|
4925
|
+
const ledger = _appConversationService.deps.keyLedger;
|
|
4926
|
+
for (const e of entries) {
|
|
4927
|
+
const r = ledger.ingestReplicated(e.data);
|
|
4928
|
+
if (r === 'bad-signature' || r === 'unverifiable')
|
|
4929
|
+
console.warn(` [device-key-ledger] a replicated row was not accepted (${r})`);
|
|
4930
|
+
}
|
|
4931
|
+
}
|
|
4919
4932
|
});
|
|
4920
4933
|
// Author-side HLC clock — persisted under the journal dir (atomic temp+rename)
|
|
4921
4934
|
// so the merge total order survives restarts (§3.5). node = this machine's id.
|
|
@@ -5023,7 +5036,7 @@ export async function startServer(options) {
|
|
|
5023
5036
|
const _stateSyncStoresResolved = (() => {
|
|
5024
5037
|
let s = _stateSyncStoresBase ?? {};
|
|
5025
5038
|
if (_appNativeOn)
|
|
5026
|
-
s = { ...s, appConversations: { enabled: true } };
|
|
5039
|
+
s = { ...s, appConversations: { enabled: true }, mobileDeviceKeyLedger: { enabled: true } };
|
|
5027
5040
|
if (_accountFollowMeEnabled)
|
|
5028
5041
|
s = { ...s, subscriptionAccountMeta: { enabled: true } };
|
|
5029
5042
|
if (_pinReplicateEnabled)
|
|
@@ -8588,7 +8601,24 @@ export async function startServer(options) {
|
|
|
8588
8601
|
console.warn(` [app-conversations] reply relay: ${[...r.errors, ...r.degraded].join('; ')}`);
|
|
8589
8602
|
}
|
|
8590
8603
|
let appDispatch = null;
|
|
8604
|
+
// Signed records (§4.6): this machine's identity signer, the signing-key history lookup and
|
|
8605
|
+
// the device-key ledger. No identity ⇒ messages are still stored and delivered, read `unknown`.
|
|
8606
|
+
const [sigMod, ledgerMod, ledgerReplMod] = await Promise.all([
|
|
8607
|
+
import('../core/AppRecordSignatures.js'), import('../core/MobileDeviceKeyLedger.js'), import('../core/MobileDeviceKeyLedgerReplicatedStore.js'),
|
|
8608
|
+
]);
|
|
8609
|
+
const appSigner = sigMod.loadMachineSigner(config.stateDir);
|
|
8610
|
+
const appKeyLookup = sigMod.identityKeyLookup(config.stateDir);
|
|
8611
|
+
if (!appSigner)
|
|
8612
|
+
console.warn(' [app-conversations] this machine has no identity key: app messages will read "couldn\'t check"');
|
|
8613
|
+
const appKeyLedger = appSigner ? new ledgerMod.MobileDeviceKeyLedger({
|
|
8614
|
+
stateDir: config.stateDir, signer: appSigner, keyLookup: appKeyLookup,
|
|
8615
|
+
reportDegradation: (what, detail) => degradationReporter.report({
|
|
8616
|
+
feature: what, primary: 'check signed app messages against the device-key ledger', fallback: 'messages read "couldn\'t check"',
|
|
8617
|
+
reason: detail, impact: 'Signed app messages cannot be checked on this machine.',
|
|
8618
|
+
}),
|
|
8619
|
+
}) : null;
|
|
8591
8620
|
const appSvc = new AppConversationService({
|
|
8621
|
+
signer: appSigner, keyLookup: appKeyLookup, keyLedger: appKeyLedger,
|
|
8592
8622
|
stateDir: config.stateDir,
|
|
8593
8623
|
machineId: () => _meshSelfId ?? os.hostname(),
|
|
8594
8624
|
registry: conversationRegistry,
|
|
@@ -8635,6 +8665,27 @@ export async function startServer(options) {
|
|
|
8635
8665
|
const emitter = replicatedRecordEmitter;
|
|
8636
8666
|
appSvc.store.setReplicationHook((ev) => emitter.emit(replMod.APP_CONVERSATIONS_STORE_KEY, replMod.deriveAppConversationRecordKey(ev.conversationKey, ev.eventId), replMod.buildAppConversationRecordData(ev)));
|
|
8637
8667
|
}
|
|
8668
|
+
if (replicatedRecordEmitter && appKeyLedger) {
|
|
8669
|
+
const emitter = replicatedRecordEmitter;
|
|
8670
|
+
appKeyLedger.setReplicationHook((row) => emitter.emit(ledgerReplMod.DEVICE_KEY_LEDGER_STORE_KEY, ledgerReplMod.deriveDeviceKeyLedgerRecordKey(row), ledgerReplMod.buildDeviceKeyLedgerRecordData(row)));
|
|
8671
|
+
}
|
|
8672
|
+
if (replicatedPeerStreamReader && cjOwnMachineId && appKeyLedger) {
|
|
8673
|
+
try {
|
|
8674
|
+
const reader = replicatedPeerStreamReader;
|
|
8675
|
+
let landed = 0;
|
|
8676
|
+
for (const rk of reader.listRecordKeys(ledgerReplMod.DEVICE_KEY_LEDGER_STORE_KEY)) {
|
|
8677
|
+
for (const r of reader.loadOriginRecords(ledgerReplMod.DEVICE_KEY_LEDGER_STORE_KEY, rk)) {
|
|
8678
|
+
if (r.origin !== cjOwnMachineId && appKeyLedger.ingestReplicated(r.data) === 'accepted')
|
|
8679
|
+
landed++;
|
|
8680
|
+
}
|
|
8681
|
+
}
|
|
8682
|
+
if (landed > 0)
|
|
8683
|
+
console.log(pc.dim(` [device-key-ledger] landed ${landed} replicated row(s) at boot`));
|
|
8684
|
+
}
|
|
8685
|
+
catch (err) {
|
|
8686
|
+
console.warn(` [device-key-ledger] boot replication read failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8638
8689
|
if (replicatedPeerStreamReader && cjOwnMachineId) {
|
|
8639
8690
|
try {
|
|
8640
8691
|
const reader = replicatedPeerStreamReader;
|
|
@@ -17301,10 +17352,41 @@ export async function startServer(options) {
|
|
|
17301
17352
|
profileFor: (peer) => _peerProfileFor?.(peer) ?? null,
|
|
17302
17353
|
conversationFor: (threadId) => conversationStore.get(threadId) ?? null,
|
|
17303
17354
|
});
|
|
17355
|
+
// §2.7: "meant for the user?" is judged PER MESSAGE (Jev first, then the Codex fast tier,
|
|
17356
|
+
// then the shared provider — so a Claude-only agent still judges; no verdict posts). Read
|
|
17357
|
+
// live: `threadline.peerHomebase.perMessageClassification: false` restores first-only.
|
|
17358
|
+
let peerUserMeantJudge = null;
|
|
17359
|
+
try {
|
|
17360
|
+
const { buildPeerUserMeantJudge } = await import('../threadline/PeerUserMeantJudge.js');
|
|
17361
|
+
const { getFeatureMetricsRecorder } = await import('../core/CircuitBreakingIntelligenceProvider.js');
|
|
17362
|
+
const { SecretStore } = await import('../core/SecretStore.js');
|
|
17363
|
+
let userMeantCodex = null;
|
|
17364
|
+
try {
|
|
17365
|
+
const { LlmCircuitBreaker } = await import('../core/LlmCircuitBreaker.js');
|
|
17366
|
+
const { buildIntelligenceProvider: buildUserMeantReferee } = await import('../core/intelligenceProviderFactory.js');
|
|
17367
|
+
userMeantCodex = buildUserMeantReferee({ framework: 'codex-cli', breaker: new LlmCircuitBreaker() });
|
|
17368
|
+
}
|
|
17369
|
+
catch { /* @silent-fallback-ok — no Codex CLI; the shared provider is the next referee */ }
|
|
17370
|
+
peerUserMeantJudge = buildPeerUserMeantJudge({
|
|
17371
|
+
readPeerHomebaseBlock: () => liveConfig.get('threadline.peerHomebase', undefined),
|
|
17372
|
+
readSecret: (name) => new SecretStore({ stateDir: config.stateDir, forceFileKey: config.secrets?.forceFileKey }).get(name),
|
|
17373
|
+
referees: () => [
|
|
17374
|
+
...(userMeantCodex ? [{ name: 'codex', provider: userMeantCodex }] : []),
|
|
17375
|
+
...(sharedIntelligence ? [{ name: 'shared', provider: sharedIntelligence }] : []),
|
|
17376
|
+
],
|
|
17377
|
+
stateDir: config.stateDir,
|
|
17378
|
+
metrics: { record: (r) => getFeatureMetricsRecorder()?.record(r) },
|
|
17379
|
+
});
|
|
17380
|
+
console.log(pc.dim(` Peer user-meant judge: constructed (referees: ${[userMeantCodex ? 'codex' : null, sharedIntelligence ? 'shared' : null].filter(Boolean).join(', ') || 'none'})`));
|
|
17381
|
+
}
|
|
17382
|
+
catch (err) {
|
|
17383
|
+
console.log(pc.yellow(` Peer user-meant judge: not constructed (${err?.message ?? 'unknown'}) — first-only rule applies`));
|
|
17384
|
+
}
|
|
17304
17385
|
const peerHomebaseRelay = telegram
|
|
17305
17386
|
? new PeerHomebaseRelay({
|
|
17306
17387
|
resolve: peerUserTopic,
|
|
17307
17388
|
salienceGate: new (await import('../threadline/SalienceGate.js')).SalienceGate(),
|
|
17389
|
+
userMeantJudge: peerUserMeantJudge,
|
|
17308
17390
|
sendToTopic: (topicId, text) => withThreadlineForwardedAuthor(telegramOriginBoot?.runtime.service, 'inbound', topicId, text, () => telegram.sendToTopic(topicId, text)),
|
|
17309
17391
|
log: (m) => console.log(m),
|
|
17310
17392
|
})
|
|
@@ -17924,7 +18006,11 @@ export async function startServer(options) {
|
|
|
17924
18006
|
const a2aRelayForwardEnabled = () => a2aRelayForwardMod.resolveRelayForwardEnabled(liveConfig.get('threadline.relayForward.enabled', undefined), config);
|
|
17925
18007
|
const salienceGate = new SalienceGate(); // fallback-only for v1; spec §5.4
|
|
17926
18008
|
// §2.6: tell a spawned thread session which topic to use for the user.
|
|
17927
|
-
threadlineRouter.setPeerUserTopicResolver((q) => peerUserTopic({ threadId: q.threadId, peers: q.peers })
|
|
18009
|
+
threadlineRouter.setPeerUserTopicResolver((q) => peerUserTopic({ threadId: q.threadId, peers: q.peers }), {
|
|
18010
|
+
// §2.7: only where the relay has actually taken this thread under per-message judging.
|
|
18011
|
+
serverPostsUserMeant: (threadId) => peerHomebaseRelay?.postsUserMeantFor(threadId) === true
|
|
18012
|
+
&& conversationStore.get(threadId)?.boundTopicId == null,
|
|
18013
|
+
});
|
|
17928
18014
|
let topicLinkageHandler = null;
|
|
17929
18015
|
if (commitmentTracker) {
|
|
17930
18016
|
topicLinkageHandler = new TopicLinkageHandler({
|
|
@@ -17985,6 +18071,15 @@ export async function startServer(options) {
|
|
|
17985
18071
|
const r = peerUserTopic({ threadId: q.threadId, peers: q.peers, existingTopicId: q.originTopicId });
|
|
17986
18072
|
return r.topicId;
|
|
17987
18073
|
},
|
|
18074
|
+
// §2.7: a reply redirected to the homebase is judged per message (null when switched off).
|
|
18075
|
+
judgeUserMeant: async (q) => {
|
|
18076
|
+
if (!peerUserMeantJudge || !peerUserMeantJudge.enabled())
|
|
18077
|
+
return null;
|
|
18078
|
+
const v = await peerUserMeantJudge.judge({ threadId: q.threadId, peer: q.peers[0] ?? '', senderName: q.senderName, text: q.text, deadlineMs: q.deadlineMs });
|
|
18079
|
+
if (v.firstOnly)
|
|
18080
|
+
return null; // the judge's budget is spent: the SalienceGate (first-only) decides
|
|
18081
|
+
return { verdict: v.userMeant ? 'user-visible' : 'agent-internal', reason: `per-message: ${v.decidedBy}/${v.reason}` };
|
|
18082
|
+
},
|
|
17988
18083
|
onRemoteReplyEvent: (event) => {
|
|
17989
18084
|
if (event === 'ask')
|
|
17990
18085
|
a2aRelayForwardCtx.counters.replyAsks++;
|
|
@@ -18821,6 +18916,7 @@ export async function startServer(options) {
|
|
|
18821
18916
|
peers: [senderFingerprint],
|
|
18822
18917
|
senderName,
|
|
18823
18918
|
text: textContent,
|
|
18919
|
+
messageType: typeof msgType === 'string' ? msgType : null,
|
|
18824
18920
|
}).then((r) => { if (!r.posted)
|
|
18825
18921
|
hubSurface(); }, () => hubSurface());
|
|
18826
18922
|
}
|