@xfxstudio/claworld 2026.4.22-testing.6 → 2026.4.27-testing

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.
@@ -1,3 +1,9 @@
1
+ import {
2
+ buildAgentWorkingMemoryArtifactIndex,
3
+ buildManagementSessionKey,
4
+ createManagementWorkingMemoryBootstrapContext,
5
+ } from './session-routing.js';
6
+
1
7
  export function createDemoSessionBootstrap() {
2
8
  return {
3
9
  defaults: {
@@ -28,5 +34,47 @@ export function createDemoSessionBootstrap() {
28
34
  status: 'planned',
29
35
  };
30
36
  },
37
+ createManagementBootstrapPlan({
38
+ agentId,
39
+ trigger = 'management_wake',
40
+ workingMemoryRoot = '.claworld',
41
+ now = null,
42
+ event = {},
43
+ } = {}) {
44
+ const context = createManagementWorkingMemoryBootstrapContext({
45
+ agentId,
46
+ trigger,
47
+ workingMemoryRoot,
48
+ now,
49
+ event,
50
+ });
51
+ return {
52
+ status: context.sessionKey ? 'planned' : 'invalid',
53
+ sessionKind: 'management',
54
+ sessionKey: context.sessionKey,
55
+ agentId: context.agentId,
56
+ trigger: context.trigger,
57
+ artifactIndex: context.artifactIndex,
58
+ steps: context.bootstrapChecklist,
59
+ };
60
+ },
61
+ createAgentWorkingMemoryPlan({
62
+ agentId,
63
+ workingMemoryRoot = '.claworld',
64
+ now = null,
65
+ } = {}) {
66
+ const artifactIndex = buildAgentWorkingMemoryArtifactIndex({
67
+ agentId,
68
+ root: workingMemoryRoot,
69
+ now,
70
+ });
71
+ return {
72
+ status: 'planned',
73
+ agentId: artifactIndex.agentId,
74
+ sessionKey: buildManagementSessionKey(artifactIndex.agentId),
75
+ artifactIndex,
76
+ requiredFiles: artifactIndex.requiredFiles,
77
+ };
78
+ },
31
79
  };
32
80
  }
@@ -1,4 +1,5 @@
1
1
  import { OPENCLAW_RUNTIME_PATH, createRuntimePathTrace } from './runtime-path.js';
2
+ import { resolveRuntimeSessionTarget } from './session-routing.js';
2
3
 
3
4
  function normalizeText(value, fallback = null) {
4
5
  if (value == null) return fallback;
@@ -17,15 +18,21 @@ export function createInboundSessionRouter() {
17
18
  routeInboundEvent(event = {}, options = {}) {
18
19
  const eventType = normalizeText(event.eventType || event.type, null);
19
20
  const deliveryId = normalizeText(event.deliveryId || event.event_id || event.eventId, null);
20
- const sessionKey = normalizeText(event.sessionKey, null);
21
21
  const payload = normalizePayload(event.payload);
22
+ const target = resolveRuntimeSessionTarget(event, options);
23
+ const sessionKey = target.sessionKey;
22
24
  return {
23
- action: 'route_delivery',
24
- target: normalizeText(options.sessionTarget, 'mainagent'),
25
+ action: target.sessionKind === 'management' ? 'route_management_input' : 'route_delivery',
26
+ target: target.target,
25
27
  fallbackTarget: normalizeText(options.fallbackTarget, 'mainagent'),
28
+ sessionKind: target.sessionKind,
26
29
  eventType,
27
30
  deliveryId,
28
31
  sessionKey,
32
+ managementSessionKey: target.managementSessionKey,
33
+ conversationSessionKey: target.conversationSessionKey,
34
+ targetAgentId: target.targetAgentId,
35
+ conversationKey: target.conversationKey,
29
36
  payload,
30
37
  metadata: event.metadata && typeof event.metadata === 'object' && !Array.isArray(event.metadata)
31
38
  ? { ...event.metadata }
@@ -35,7 +42,16 @@ export function createInboundSessionRouter() {
35
42
  eventId: deliveryId,
36
43
  direction: 'inbound',
37
44
  }),
38
- status: eventType === 'delivery' && deliveryId && sessionKey && normalizeText(payload.text, null)
45
+ status: (
46
+ target.sessionKind === 'management'
47
+ && sessionKey
48
+ && eventType
49
+ ) || (
50
+ eventType === 'delivery'
51
+ && deliveryId
52
+ && sessionKey
53
+ && normalizeText(payload.text, null)
54
+ )
39
55
  ? 'resolved'
40
56
  : 'invalid',
41
57
  };
@@ -4,6 +4,16 @@ function normalizeText(value, fallback = null) {
4
4
  return normalized || fallback;
5
5
  }
6
6
 
7
+ function clonePayload(value = null) {
8
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
9
+ return JSON.parse(JSON.stringify(value));
10
+ }
11
+
12
+ function buildManagementSessionKey(agentId = null) {
13
+ const normalizedAgentId = normalizeText(agentId, null);
14
+ return normalizedAgentId ? `management:${normalizedAgentId}` : null;
15
+ }
16
+
7
17
  export function createOutboundSessionBridge() {
8
18
  return {
9
19
  createReplyEnvelope({
@@ -25,5 +35,55 @@ export function createOutboundSessionBridge() {
25
35
  },
26
36
  };
27
37
  },
38
+ createLongRunningIntentHandoffEnvelope({
39
+ agentId,
40
+ intentId = null,
41
+ summary,
42
+ allowedActions = [],
43
+ reportPolicy = 'material_updates',
44
+ sourceSessionKey = null,
45
+ payload = {},
46
+ } = {}) {
47
+ const sessionKey = buildManagementSessionKey(agentId);
48
+ return {
49
+ eventType: 'management_wake',
50
+ sessionKind: 'management',
51
+ sessionKey,
52
+ payload: {
53
+ eventType: 'management_wake',
54
+ reason: 'external_main_long_running_intent_handoff',
55
+ intentId: normalizeText(intentId, null),
56
+ summary: normalizeText(summary, ''),
57
+ allowedActions: Array.isArray(allowedActions)
58
+ ? allowedActions.map((action) => normalizeText(action, null)).filter(Boolean)
59
+ : [],
60
+ reportPolicy: normalizeText(reportPolicy, 'material_updates'),
61
+ sourceSessionKey: normalizeText(sourceSessionKey, null),
62
+ targetAgentId: normalizeText(agentId, null),
63
+ ...clonePayload(payload),
64
+ },
65
+ };
66
+ },
67
+ createManagementReportEnvelope({
68
+ agentId,
69
+ reportId = null,
70
+ reportText,
71
+ targetSessionKey = null,
72
+ payload = {},
73
+ } = {}) {
74
+ return {
75
+ eventType: 'management_report',
76
+ sessionKind: 'external_main',
77
+ sessionKey: normalizeText(targetSessionKey, null),
78
+ payload: {
79
+ eventType: 'management_report',
80
+ reportId: normalizeText(reportId, null),
81
+ text: normalizeText(reportText, ''),
82
+ sourceSessionKey: buildManagementSessionKey(agentId),
83
+ sourceAgentId: normalizeText(agentId, null),
84
+ ...clonePayload(payload),
85
+ },
86
+ };
87
+ },
28
88
  };
29
89
  }
@@ -146,6 +146,7 @@ function normalizeWorldDetail(payload = {}) {
146
146
  ownerAgentId: normalizeText(payload.ownerAgentId, null),
147
147
  worldRole: normalizeWorldRole(payload.worldRole, null),
148
148
  enabled: typeof payload.enabled === 'boolean' ? payload.enabled : null,
149
+ broadcast: normalizeBroadcastConfig(payload.broadcast),
149
150
  requiredFieldCount: normalizeInteger(payload.requiredFieldCount, requiredFields.length) || requiredFields.length,
150
151
  optionalFieldCount: normalizeInteger(payload.optionalFieldCount, optionalFields.length) || optionalFields.length,
151
152
  requiredFields,
@@ -187,6 +188,7 @@ function normalizeWorldDetail(payload = {}) {
187
188
  worldRole: normalizeWorldRole(payload.worldRole, null),
188
189
  enabled: typeof management.enabled === 'boolean' ? management.enabled : null,
189
190
  statusLabel: normalizeText(management.status, null),
191
+ broadcast: normalizeBroadcastConfig(management.broadcast || payload.broadcast || world.broadcast),
190
192
  requiredFieldCount: 1,
191
193
  optionalFieldCount: 0,
192
194
  requiredFields,
@@ -253,6 +255,16 @@ function normalizeSearchAction(action = null) {
253
255
  };
254
256
  }
255
257
 
258
+ function normalizeBroadcastConfig(broadcast = null) {
259
+ if (!broadcast || typeof broadcast !== 'object' || Array.isArray(broadcast)) return null;
260
+ return {
261
+ enabled: typeof broadcast.enabled === 'boolean' ? broadcast.enabled : null,
262
+ audience: normalizeText(broadcast.audience, null),
263
+ replyPolicy: normalizeText(broadcast.replyPolicy, null),
264
+ excludeSelf: typeof broadcast.excludeSelf === 'boolean' ? broadcast.excludeSelf : null,
265
+ };
266
+ }
267
+
256
268
  function normalizeCompatibilitySignal(signal = {}, index = 0) {
257
269
  return {
258
270
  signalId: normalizeText(signal.signalId, `signal_${index + 1}`),
@@ -348,18 +360,16 @@ function normalizeCandidateFeedResponse(payload = {}, { worldId = null, agentId
348
360
  };
349
361
  }
350
362
 
363
+
364
+ function normalizeActionPayload(value = null) {
365
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
366
+ }
367
+
351
368
  export function normalizeWorldJoinResponse(payload = {}, { worldId = null, agentId = null } = {}) {
352
369
  const membership = payload.membership && typeof payload.membership === 'object' ? payload.membership : null;
353
370
  const normalizedWorldId = normalizeText(payload.worldId, worldId || 'unknown-world');
354
371
  const normalizedAgentId = normalizeText(payload.agentId || membership?.agentId, agentId || null);
355
372
  const membershipStatus = normalizeText(payload.membershipStatus || membership?.status, 'unknown');
356
- const candidateFeed = payload.candidateFeed && typeof payload.candidateFeed === 'object'
357
- ? normalizeCandidateFeedResponse(payload.candidateFeed, {
358
- worldId: normalizedWorldId,
359
- agentId: normalizedAgentId,
360
- })
361
- : null;
362
-
363
373
  return {
364
374
  status: normalizeText(payload.status, membershipStatus === 'active' ? 'joined' : 'accepted'),
365
375
  worldId: normalizedWorldId,
@@ -373,15 +383,15 @@ export function normalizeWorldJoinResponse(payload = {}, { worldId = null, agent
373
383
  membership,
374
384
  nextAction: normalizeText(
375
385
  payload.nextAction,
376
- membershipStatus === 'active' ? 'review_candidate_feed' : null,
386
+ membershipStatus === 'active' ? 'search_world_members_or_view_activity' : null,
377
387
  ),
378
388
  nextStageSummary: payload.nextStageSummary && typeof payload.nextStageSummary === 'object'
379
389
  ? payload.nextStageSummary
380
390
  : {},
381
- candidateFeed,
382
- candidateDelivery: payload.candidateDelivery && typeof payload.candidateDelivery === 'object'
383
- ? payload.candidateDelivery
384
- : null,
391
+ memberSearchAction: normalizeActionPayload(payload.memberSearchAction),
392
+ worldActivityAction: normalizeActionPayload(payload.worldActivityAction),
393
+ subscribeWorldAction: normalizeActionPayload(payload.subscribeWorldAction),
394
+ requestChatAction: normalizeActionPayload(payload.requestChatAction),
385
395
  orchestration: payload.orchestration && typeof payload.orchestration === 'object'
386
396
  ? payload.orchestration
387
397
  : null,
@@ -681,6 +691,64 @@ export async function searchWorlds({
681
691
  });
682
692
  }
683
693
 
694
+ export async function search({
695
+ cfg = {},
696
+ accountId = null,
697
+ runtimeConfig = null,
698
+ scope = 'mixed',
699
+ worldId = null,
700
+ agentId = null,
701
+ query = null,
702
+ limit = null,
703
+ sort = null,
704
+ page = null,
705
+ fetchImpl,
706
+ logger = console,
707
+ } = {}) {
708
+ if (typeof fetchImpl !== 'function') {
709
+ throw new Error('fetch is unavailable for claworld product-shell search helper');
710
+ }
711
+
712
+ const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
713
+ const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
714
+ const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/search`, {
715
+ method: 'POST',
716
+ headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
717
+ accept: 'application/json',
718
+ 'content-type': 'application/json',
719
+ ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
720
+ }),
721
+ body: JSON.stringify({
722
+ scope: normalizeText(scope, 'mixed'),
723
+ worldId: normalizeText(worldId, null),
724
+ agentId: normalizeText(agentId, null),
725
+ query: normalizeText(query, null),
726
+ sort: normalizeText(sort, null),
727
+ limit: limit == null ? null : normalizeInteger(limit, 0),
728
+ page: page == null ? null : normalizeInteger(page, 0),
729
+ }),
730
+ });
731
+
732
+ if (!searchResult.ok) {
733
+ logger.error?.('[claworld:product-shell] search failed', {
734
+ status: searchResult.status,
735
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
736
+ scope: normalizeText(scope, 'mixed'),
737
+ worldId: normalizeText(worldId, null),
738
+ body: searchResult.body,
739
+ });
740
+ throw createProductShellHttpError('search', searchResult, {
741
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
742
+ worldId: normalizeText(worldId, null),
743
+ });
744
+ }
745
+
746
+ return {
747
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
748
+ ...searchResult.body,
749
+ };
750
+ }
751
+
684
752
  export async function joinWorld({
685
753
  cfg = {},
686
754
  accountId = null,
@@ -828,34 +896,67 @@ export async function fetchWorldCandidateFeed({
828
896
 
829
897
  const resolvedRuntimeConfig = runtimeConfig || resolveClaworldRuntimeConfig(cfg, accountId);
830
898
  const baseUrl = normalizeRelayHttpBaseUrl(resolvedRuntimeConfig.serverUrl);
831
- const requestUrl = new URL(`${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/candidates`);
832
- requestUrl.searchParams.set('agentId', resolvedAgentId);
833
899
  const normalizedLimit = normalizeInteger(limit, 0);
834
- if (normalizedLimit > 0) {
835
- requestUrl.searchParams.set('limit', String(normalizedLimit));
836
- }
837
- const candidateFeed = await fetchJson(fetchImpl, requestUrl.toString(), {
900
+ const searchResult = await fetchJson(fetchImpl, `${baseUrl}/v1/worlds/${encodeURIComponent(resolvedWorldId)}/search`, {
901
+ method: 'POST',
838
902
  headers: buildRuntimeAuthHeaders(resolvedRuntimeConfig, {
839
903
  accept: 'application/json',
904
+ 'content-type': 'application/json',
840
905
  ...(resolvedRuntimeConfig.apiKey ? { 'x-api-key': resolvedRuntimeConfig.apiKey } : {}),
841
906
  }),
907
+ body: JSON.stringify({
908
+ agentId: resolvedAgentId,
909
+ query: null,
910
+ sort: 'match',
911
+ limit: normalizedLimit > 0 ? normalizedLimit : null,
912
+ }),
842
913
  });
843
914
 
844
- if (!candidateFeed.ok) {
845
- logger.error?.('[claworld:product-shell] candidate feed fetch failed', {
846
- status: candidateFeed.status,
915
+ if (!searchResult.ok) {
916
+ logger.error?.('[claworld:product-shell] candidate feed compatibility search failed', {
917
+ status: searchResult.status,
847
918
  worldId: resolvedWorldId,
848
919
  agentId: resolvedAgentId,
849
920
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
850
- body: candidateFeed.body,
921
+ body: searchResult.body,
851
922
  });
852
- throw createProductShellHttpError('world_candidate_feed', candidateFeed, {
923
+ throw createProductShellHttpError('world_candidate_feed', searchResult, {
853
924
  accountId: resolvedRuntimeConfig.accountId || accountId || null,
854
925
  worldId: resolvedWorldId,
855
926
  });
856
927
  }
857
928
 
858
- return normalizeCandidateFeedResponse(candidateFeed.body, {
929
+ const searchPayload = searchResult.body && typeof searchResult.body === 'object' ? searchResult.body : {};
930
+ const normalizedSearch = normalizeWorldMemberSearchResponse(searchPayload, {
931
+ accountId: resolvedRuntimeConfig.accountId || accountId || null,
932
+ });
933
+ return normalizeCandidateFeedResponse({
934
+ worldId: resolvedWorldId,
935
+ agentId: resolvedAgentId,
936
+ viewerMembershipId: searchPayload.viewerMembershipId,
937
+ generatedAt: searchPayload.generatedAt,
938
+ limit: normalizedSearch.limit,
939
+ totalCandidates: normalizedSearch.totalMatches,
940
+ candidateSource: searchPayload.candidateSource || 'active_memberships',
941
+ status: normalizedSearch.items.length > 0 ? 'feed_ready' : 'no_candidates_ready',
942
+ nextAction: normalizedSearch.nextAction,
943
+ candidates: normalizedSearch.items.map((item, index) => ({
944
+ candidateId: item.membershipId || `candidate_${index + 1}`,
945
+ sourceMembershipId: item.membershipId || null,
946
+ worldId: item.worldId || resolvedWorldId,
947
+ online: item.online === true,
948
+ rank: index + 1,
949
+ score: item.score,
950
+ agentCode: item.agentCode,
951
+ requestChat: item.requestChat,
952
+ profileSummary: item.profileSummary,
953
+ deliveryReason: {
954
+ summary: item.reasonSummary || item.headline || null,
955
+ },
956
+ worldFeedbackSummary: item.worldFeedbackSummary,
957
+ joinedAt: item.joinedAt,
958
+ })),
959
+ }, {
859
960
  worldId: resolvedWorldId,
860
961
  agentId: resolvedAgentId,
861
962
  });
@@ -0,0 +1,144 @@
1
+ import {
2
+ CLAWORLD_CONTEXT_DIR,
3
+ CLAWORLD_JOURNAL_DIR,
4
+ CLAWORLD_REPORTS_DIR,
5
+ CLAWORLD_WORKING_MEMORY_DIR,
6
+ CLAWORLD_WORKING_MEMORY_FILES,
7
+ } from './working-memory.js';
8
+
9
+ function normalizeText(value, fallback = null) {
10
+ if (value == null) return fallback;
11
+ const normalized = String(value).trim();
12
+ return normalized || fallback;
13
+ }
14
+
15
+ function normalizePayload(payload = null) {
16
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return {};
17
+ return { ...payload };
18
+ }
19
+
20
+ export const CLAWORLD_SESSION_KINDS = Object.freeze({
21
+ externalMain: 'external_main',
22
+ management: 'management',
23
+ conversation: 'conversation',
24
+ });
25
+
26
+ export const CLAWORLD_MANAGEMENT_EVENT_TYPES = Object.freeze([
27
+ 'notification',
28
+ 'domain_notification',
29
+ 'management_wake',
30
+ 'management_tick',
31
+ 'conversation_lifecycle',
32
+ 'platform_recommendation',
33
+ 'ops_recommendation',
34
+ ]);
35
+
36
+ export function buildManagementSessionKey(agentId = null) {
37
+ const normalizedAgentId = normalizeText(agentId, null);
38
+ return normalizedAgentId ? `management:${normalizedAgentId}` : null;
39
+ }
40
+
41
+ export function buildConversationSessionKey(conversationKey = null, fallbackSessionKey = null) {
42
+ const normalizedConversationKey = normalizeText(conversationKey, null);
43
+ if (normalizedConversationKey) return `conversation:${normalizedConversationKey}`;
44
+ return normalizeText(fallbackSessionKey, null);
45
+ }
46
+
47
+ export function resolveRuntimeSessionTarget(event = {}, options = {}) {
48
+ const payload = normalizePayload(event.payload);
49
+ const eventType = normalizeText(event.eventType || event.type || payload.eventType, null);
50
+ const targetAgentId = normalizeText(
51
+ event.targetAgentId,
52
+ normalizeText(payload.targetAgentId, normalizeText(options.targetAgentId, null)),
53
+ );
54
+ const conversationKey = normalizeText(
55
+ event.conversationKey,
56
+ normalizeText(payload.conversationKey, normalizeText(options.conversationKey, null)),
57
+ );
58
+ const providedSessionKey = normalizeText(
59
+ event.sessionKey,
60
+ normalizeText(payload.sessionKey, normalizeText(options.sessionKey, null)),
61
+ );
62
+
63
+ if (CLAWORLD_MANAGEMENT_EVENT_TYPES.includes(eventType)) {
64
+ const managementSessionKey = normalizeText(
65
+ options.managementSessionKey,
66
+ buildManagementSessionKey(targetAgentId),
67
+ );
68
+ return {
69
+ sessionKind: CLAWORLD_SESSION_KINDS.management,
70
+ target: normalizeText(options.managementTarget, 'management_session'),
71
+ sessionKey: managementSessionKey || providedSessionKey,
72
+ managementSessionKey: managementSessionKey || null,
73
+ conversationSessionKey: conversationKey ? buildConversationSessionKey(conversationKey) : null,
74
+ targetAgentId,
75
+ conversationKey,
76
+ };
77
+ }
78
+
79
+ const conversationSessionKey = buildConversationSessionKey(conversationKey, providedSessionKey);
80
+ return {
81
+ sessionKind: CLAWORLD_SESSION_KINDS.conversation,
82
+ target: normalizeText(options.sessionTarget, 'conversation_session'),
83
+ sessionKey: conversationSessionKey,
84
+ managementSessionKey: targetAgentId ? buildManagementSessionKey(targetAgentId) : null,
85
+ conversationSessionKey,
86
+ targetAgentId,
87
+ conversationKey,
88
+ };
89
+ }
90
+
91
+ export function buildAgentWorkingMemoryArtifactIndex({
92
+ agentId = null,
93
+ root = CLAWORLD_WORKING_MEMORY_DIR,
94
+ now = null,
95
+ } = {}) {
96
+ const normalizedAgentId = normalizeText(agentId, 'unknown-agent');
97
+ const basePath = normalizeText(root, CLAWORLD_WORKING_MEMORY_DIR).replace(/\/+$/, '');
98
+ const profilePath = `${basePath}/${CLAWORLD_WORKING_MEMORY_FILES.profile}`;
99
+ const memoryPath = `${basePath}/${CLAWORLD_WORKING_MEMORY_FILES.memory}`;
100
+ const nowPath = `${basePath}/${CLAWORLD_WORKING_MEMORY_FILES.now}`;
101
+ return {
102
+ agentId: normalizedAgentId,
103
+ generatedAt: normalizeText(now, null),
104
+ workingMemoryRoot: basePath,
105
+ profilePath,
106
+ memoryPath,
107
+ nowPath,
108
+ journalPath: `${basePath}/${CLAWORLD_JOURNAL_DIR}/`,
109
+ reportsPath: `${basePath}/${CLAWORLD_REPORTS_DIR}/`,
110
+ contextPath: `${basePath}/${CLAWORLD_CONTEXT_DIR}/`,
111
+ requiredFiles: [profilePath, memoryPath, nowPath],
112
+ };
113
+ }
114
+
115
+ export function createManagementWorkingMemoryBootstrapContext({
116
+ agentId = null,
117
+ trigger = 'management_wake',
118
+ event = {},
119
+ workingMemoryRoot = CLAWORLD_WORKING_MEMORY_DIR,
120
+ now = null,
121
+ } = {}) {
122
+ const artifactIndex = buildAgentWorkingMemoryArtifactIndex({
123
+ agentId,
124
+ root: workingMemoryRoot,
125
+ now,
126
+ });
127
+ return {
128
+ sessionKind: CLAWORLD_SESSION_KINDS.management,
129
+ sessionKey: buildManagementSessionKey(agentId),
130
+ agentId: normalizeText(agentId, null),
131
+ trigger: normalizeText(trigger, 'management_wake'),
132
+ workingMemory: artifactIndex,
133
+ artifactIndex,
134
+ bootstrapChecklist: [
135
+ 'read PROFILE.md for autonomy policy and authorization boundaries',
136
+ 'read MEMORY.md for durable people/world/user preference context',
137
+ 'read NOW.md for active standing intents and report policy',
138
+ 'load recent journal and report pointers before deciding actions',
139
+ 'verify backend facts with public tools before acting',
140
+ 'write journal/report evidence for important management decisions',
141
+ ],
142
+ event: normalizePayload(event),
143
+ };
144
+ }