instar 1.3.1088 → 1.3.1090

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.
Files changed (79) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +51 -38
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/GuardPostureStore.d.ts.map +1 -1
  5. package/dist/core/GuardPostureStore.js +1 -0
  6. package/dist/core/GuardPostureStore.js.map +1 -1
  7. package/dist/core/TelegramRelay.d.ts +2 -0
  8. package/dist/core/TelegramRelay.d.ts.map +1 -1
  9. package/dist/core/TelegramRelay.js +3 -1
  10. package/dist/core/TelegramRelay.js.map +1 -1
  11. package/dist/core/types.d.ts +2 -0
  12. package/dist/core/types.d.ts.map +1 -1
  13. package/dist/core/types.js.map +1 -1
  14. package/dist/data/standards-guard-index.json +1 -1
  15. package/dist/data/standards-guard-index.meta.json +2 -2
  16. package/dist/data/standards-registry.meta.json +1 -1
  17. package/dist/messaging/TelegramAdapter.d.ts +8 -0
  18. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  19. package/dist/messaging/TelegramAdapter.js +11 -0
  20. package/dist/messaging/TelegramAdapter.js.map +1 -1
  21. package/dist/messaging/shared/MessageLogger.d.ts +4 -0
  22. package/dist/messaging/shared/MessageLogger.d.ts.map +1 -1
  23. package/dist/messaging/shared/MessageLogger.js.map +1 -1
  24. package/dist/messaging/shared/MessageProvenance.d.ts +12 -0
  25. package/dist/messaging/shared/MessageProvenance.d.ts.map +1 -0
  26. package/dist/messaging/shared/MessageProvenance.js +15 -0
  27. package/dist/messaging/shared/MessageProvenance.js.map +1 -0
  28. package/dist/messaging/shared/MessagingEventBus.d.ts +2 -0
  29. package/dist/messaging/shared/MessagingEventBus.d.ts.map +1 -1
  30. package/dist/messaging/shared/MessagingEventBus.js.map +1 -1
  31. package/dist/monitoring/AgentWorktreeReaper.d.ts +69 -4
  32. package/dist/monitoring/AgentWorktreeReaper.d.ts.map +1 -1
  33. package/dist/monitoring/AgentWorktreeReaper.js +135 -18
  34. package/dist/monitoring/AgentWorktreeReaper.js.map +1 -1
  35. package/dist/monitoring/CoherenceMonitor.d.ts.map +1 -1
  36. package/dist/monitoring/CoherenceMonitor.js +3 -1
  37. package/dist/monitoring/CoherenceMonitor.js.map +1 -1
  38. package/dist/monitoring/CommitmentSentinel.d.ts.map +1 -1
  39. package/dist/monitoring/CommitmentSentinel.js +20 -9
  40. package/dist/monitoring/CommitmentSentinel.js.map +1 -1
  41. package/dist/monitoring/GuardRegistry.d.ts +4 -0
  42. package/dist/monitoring/GuardRegistry.d.ts.map +1 -1
  43. package/dist/monitoring/GuardRegistry.js.map +1 -1
  44. package/dist/monitoring/OrphanedWorkSentinel.d.ts +33 -3
  45. package/dist/monitoring/OrphanedWorkSentinel.d.ts.map +1 -1
  46. package/dist/monitoring/OrphanedWorkSentinel.js +90 -9
  47. package/dist/monitoring/OrphanedWorkSentinel.js.map +1 -1
  48. package/dist/monitoring/WorktreeEnumerationFailureStore.d.ts +13 -0
  49. package/dist/monitoring/WorktreeEnumerationFailureStore.d.ts.map +1 -0
  50. package/dist/monitoring/WorktreeEnumerationFailureStore.js +103 -0
  51. package/dist/monitoring/WorktreeEnumerationFailureStore.js.map +1 -0
  52. package/dist/monitoring/agentWorktreeGit.d.ts.map +1 -1
  53. package/dist/monitoring/agentWorktreeGit.js +18 -3
  54. package/dist/monitoring/agentWorktreeGit.js.map +1 -1
  55. package/dist/monitoring/guardManifest.js +2 -2
  56. package/dist/monitoring/guardManifest.js.map +1 -1
  57. package/dist/monitoring/guardPostureView.d.ts +5 -2
  58. package/dist/monitoring/guardPostureView.d.ts.map +1 -1
  59. package/dist/monitoring/guardPostureView.js +17 -2
  60. package/dist/monitoring/guardPostureView.js.map +1 -1
  61. package/dist/monitoring/orphanedWorkGit.d.ts.map +1 -1
  62. package/dist/monitoring/orphanedWorkGit.js.map +1 -1
  63. package/dist/monitoring/worktreeEnumeration.d.ts +63 -0
  64. package/dist/monitoring/worktreeEnumeration.d.ts.map +1 -0
  65. package/dist/monitoring/worktreeEnumeration.js +37 -0
  66. package/dist/monitoring/worktreeEnumeration.js.map +1 -0
  67. package/dist/server/routes.d.ts.map +1 -1
  68. package/dist/server/routes.js +12 -0
  69. package/dist/server/routes.js.map +1 -1
  70. package/package.json +1 -1
  71. package/src/data/builtin-manifest.json +46 -46
  72. package/src/data/standards-guard-index.json +1 -1
  73. package/src/data/standards-guard-index.meta.json +2 -2
  74. package/src/data/standards-registry.meta.json +1 -1
  75. package/src/data/state-coherence-registry.json +17 -0
  76. package/upgrades/1.3.1089.md +34 -0
  77. package/upgrades/1.3.1090.md +30 -0
  78. package/upgrades/side-effects/guard-enumeration-fail-visible.md +78 -0
  79. package/upgrades/side-effects/message-store-provenance.md +115 -0
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8EH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA0BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA8H7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAuID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA+rDD;;;;;;;;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,CAwtBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4vqBtE;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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8EH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAU3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AA0BjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AA8H7D,OAAO,KAAK,EAAW,oBAAoB,EAAe,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACjG,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgFtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAUT;AAuID,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA+rDD;;;;;;;;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,CAwtBN;AAgmBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0wqBtE;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"}
@@ -11568,7 +11568,7 @@ export async function startServer(options) {
11568
11568
  const resp = await fetch(`http://localhost:${config.port}/telegram/reply/${topicId}`, {
11569
11569
  method: 'POST',
11570
11570
  headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.authToken}` },
11571
- body: JSON.stringify({ text }),
11571
+ body: JSON.stringify({ text, metadata: { provenance: 'automation' } }),
11572
11572
  });
11573
11573
  return resp.ok;
11574
11574
  },
@@ -11837,7 +11837,7 @@ export async function startServer(options) {
11837
11837
  const resp = await fetch(`http://localhost:${config.port}/telegram/reply/${topicId}`, {
11838
11838
  method: 'POST',
11839
11839
  headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${config.authToken}` },
11840
- body: JSON.stringify({ text }),
11840
+ body: JSON.stringify({ text, metadata: { provenance: 'automation' } }),
11841
11841
  });
11842
11842
  return resp.ok;
11843
11843
  }
@@ -13062,9 +13062,9 @@ export async function startServer(options) {
13062
13062
  const messagesLogPath = path.join(config.stateDir, 'telegram-messages.jsonl');
13063
13063
  const slackMessagesLogPath = path.join(config.stateDir, 'slack-messages.jsonl');
13064
13064
  // Shared helper: check a messages log file for SUBSTANTIVE agent
13065
- // responses after a timestamp. Filters out system/proxy messages via
13066
- // isSystemOrProxyMessage AND brief acks via isBriefAck both kinds
13067
- // of messages are non-cancelling from PresenceProxy's perspective.
13065
+ // responses after a timestamp. New Telegram rows use structural
13066
+ // provenance; legacy Telegram and Slack rows retain the text classifier
13067
+ // until their writers have migrated. Brief acks remain non-cancelling.
13068
13068
  //
13069
13069
  // The brief-ack filter is what closes the gap from PR #128: that PR
13070
13070
  // taught the event path (recordAgentMessage) to ignore acks, but the
@@ -13086,10 +13086,13 @@ export async function startServer(options) {
13086
13086
  const matchesTopic = msg.topicId === topicId
13087
13087
  || (topicId < 0 && msg.channelId && slackChannelToSyntheticId(String(msg.channelId)) === topicId);
13088
13088
  if (matchesTopic && !msg.fromUser && msg.timestamp > sinceIso) {
13089
+ if (msg.provenance === 'automation' || msg.provenance === 'user')
13090
+ continue;
13089
13091
  // Non-cancelling agent message kinds: system/proxy
13090
- // chrome, and brief acks ("On it"). Both leave tier
13091
- // timers running.
13092
- const isNonCancelling = isSystemOrProxyMessage(msg.text)
13092
+ // chrome on legacy rows, and brief acks ("On it"). Both
13093
+ // leave tier timers running. A structurally agent-authored
13094
+ // row is never reclassified from its text prefix.
13095
+ const isNonCancelling = (msg.provenance !== 'agent' && isSystemOrProxyMessage(msg.text))
13093
13096
  || isBriefAck(msg.text);
13094
13097
  if (isNonCancelling)
13095
13098
  continue;
@@ -17712,15 +17715,21 @@ export async function startServer(options) {
17712
17715
  // disabled. Observability at GET /worktrees/agent-reaper.
17713
17716
  const { AgentWorktreeReaper } = await import('../monitoring/AgentWorktreeReaper.js');
17714
17717
  const { makeAgentWorktreeReaperDeps } = await import('../monitoring/agentWorktreeGit.js');
17718
+ const { WorktreeEnumerationFailureStore } = await import('../monitoring/WorktreeEnumerationFailureStore.js');
17715
17719
  const _agentWorktreesDir = path.join(path.dirname(config.stateDir), '.worktrees');
17716
- const agentWorktreeReaper = new AgentWorktreeReaper(makeAgentWorktreeReaperDeps({
17717
- instarRepo: config.projectDir,
17718
- worktreesDir: _agentWorktreesDir,
17719
- // Multi-commit squash-merge detection via GitHub merged-PR state (default
17720
- // on; fail-safe to cherry-only). Off only if explicitly disabled in config.
17721
- githubMergeCheck: config.monitoring?.agentWorktreeReaper?.githubMergeCheck ?? true,
17722
- }), config.monitoring?.agentWorktreeReaper);
17720
+ const _worktreeEnumerationFailureStore = new WorktreeEnumerationFailureStore(path.join(config.stateDir, 'state', 'worktree-enumeration-failures.json'));
17721
+ const agentWorktreeReaper = new AgentWorktreeReaper({
17722
+ ...makeAgentWorktreeReaperDeps({
17723
+ instarRepo: config.projectDir,
17724
+ worktreesDir: _agentWorktreesDir,
17725
+ // Multi-commit squash-merge detection via GitHub merged-PR state (default
17726
+ // on; fail-safe to cherry-only). Off only if explicitly disabled in config.
17727
+ githubMergeCheck: config.monitoring?.agentWorktreeReaper?.githubMergeCheck ?? true,
17728
+ }),
17729
+ failureHistory: _worktreeEnumerationFailureStore.forGuard('agent-worktree-reaper'),
17730
+ }, config.monitoring?.agentWorktreeReaper);
17723
17731
  agentWorktreeReaper.start();
17732
+ guardRegistry.register('monitoring.agentWorktreeReaper.enabled', () => agentWorktreeReaper.guardStatus());
17724
17733
  if (config.monitoring?.agentWorktreeReaper?.enabled) {
17725
17734
  console.log(pc.green(config.monitoring.agentWorktreeReaper.dryRun === false
17726
17735
  ? ' AgentWorktreeReaper enabled (stale-worktree reclaim — LIVE)'
@@ -17926,30 +17935,34 @@ export async function startServer(options) {
17926
17935
  try {
17927
17936
  const { OrphanedWorkSentinel } = await import('../monitoring/OrphanedWorkSentinel.js');
17928
17937
  const { makeOrphanedWorkSentinelDeps } = await import('../monitoring/orphanedWorkGit.js');
17929
- orphanedWorkSentinel = new OrphanedWorkSentinel(makeOrphanedWorkSentinelDeps({
17930
- instarRepo: config.projectDir,
17931
- worktreesDir: _agentWorktreesDir,
17932
- stateDir: path.join(config.stateDir, 'state'),
17933
- raiseAttention: telegram
17934
- ? (event) => {
17935
- const slug = event.path.split('/').filter(Boolean).pop() ?? 'worktree';
17936
- void telegram.createAttentionItem({
17937
- id: `orphaned-work:${slug}:${event.workSig}`,
17938
- title: `Stranded work in worktree "${slug}"`,
17939
- summary: 'A build/session died with uncommitted changes — revive the worktree to finish, or discard.',
17940
- description: `Worktree ${event.path} (branch ${event.branch ?? 'detached'}) has uncommitted changes ` +
17941
- `but its owning session is gone. The work is still on disk` +
17942
- `${event.preserved ? ' and a preservation patch was written' : ''}. ` +
17943
- `Open the worktree to finish + commit, or discard if no longer needed.`,
17944
- category: 'agent-health',
17945
- priority: 'NORMAL',
17946
- sourceContext: `orphaned-work:${slug}`,
17947
- });
17948
- }
17949
- : () => { },
17950
- now: () => Date.now(),
17951
- }), { ...config.monitoring?.orphanedWorkSentinel, enabled: _orphanedWorkEnabled });
17938
+ orphanedWorkSentinel = new OrphanedWorkSentinel({
17939
+ ...makeOrphanedWorkSentinelDeps({
17940
+ instarRepo: config.projectDir,
17941
+ worktreesDir: _agentWorktreesDir,
17942
+ stateDir: path.join(config.stateDir, 'state'),
17943
+ raiseAttention: telegram
17944
+ ? (event) => {
17945
+ const slug = event.path.split('/').filter(Boolean).pop() ?? 'worktree';
17946
+ void telegram.createAttentionItem({
17947
+ id: `orphaned-work:${slug}:${event.workSig}`,
17948
+ title: `Stranded work in worktree "${slug}"`,
17949
+ summary: 'A build/session died with uncommitted changes revive the worktree to finish, or discard.',
17950
+ description: `Worktree ${event.path} (branch ${event.branch ?? 'detached'}) has uncommitted changes ` +
17951
+ `but its owning session is gone. The work is still on disk` +
17952
+ `${event.preserved ? ' and a preservation patch was written' : ''}. ` +
17953
+ `Open the worktree to finish + commit, or discard if no longer needed.`,
17954
+ category: 'agent-health',
17955
+ priority: 'NORMAL',
17956
+ sourceContext: `orphaned-work:${slug}`,
17957
+ });
17958
+ }
17959
+ : () => { },
17960
+ now: () => Date.now(),
17961
+ }),
17962
+ failureHistory: _worktreeEnumerationFailureStore.forGuard('orphaned-work-sentinel'),
17963
+ }, { ...config.monitoring?.orphanedWorkSentinel, enabled: _orphanedWorkEnabled });
17952
17964
  orphanedWorkSentinel.start();
17965
+ guardRegistry.register('monitoring.orphanedWorkSentinel.enabled', () => orphanedWorkSentinel.guardStatus());
17953
17966
  if (_orphanedWorkEnabled) {
17954
17967
  console.log(pc.green(' OrphanedWorkSentinel enabled (silent-uncommitted-death backstop — signal-only)'));
17955
17968
  }