nexus-prime 3.17.0 → 3.18.0

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/README.md CHANGED
@@ -293,9 +293,9 @@ Read the full tiered market map: [Comparison](https://sir-ad.github.io/nexus-pri
293
293
  <details>
294
294
  <summary><b>🧭 Platform Feature Registry</b></summary>
295
295
 
296
- Generated from shared feature metadata at 2026-03-14T14:43:20.108Z.
296
+ Generated from shared feature metadata at 2026-03-21T02:48:13.064Z.
297
297
 
298
- Inventory Snapshot: 109 skills · 64 workflows · 5 hooks · 3 automations · 7 crews · 139 specialists
298
+ Inventory Snapshot: 109 skills · 64 workflows · 9 hooks · 5 automations · 7 crews · 139 specialists
299
299
 
300
300
  Control Plane Snapshot: 9 MCP surfaces · 6 client targets · 5 dashboard capabilities · 6 runtime subsystems · 5 release gates
301
301
 
@@ -310,11 +310,11 @@ Operator-facing entrypoints and expert control surfaces.
310
310
  | nexus_orchestrate | core MCP | Plan, select assets, execute through worktree-backed runtime, and persist truth. | Default raw-prompt execution path. |
311
311
  | nexus_plan_execution | planning MCP | Inspect the planner ledger before mutation. | Used when operators want a pre-run ledger. |
312
312
  | nexus_recall_memory / nexus_memory_stats / nexus_store_memory | memory MCP | Inspect and persist durable learnings. | Feeds the memory fabric and handoff flow. |
313
- | nexus_optimize_tokens | optimization MCP | Inspect or override source-aware token budgeting. | Manual/diagnostic surface; orchestration applies budgeting automatically. |
314
- | nexus_mindkit_check / nexus_ghost_pass / nexus_spawn_workers | safety + runtime MCP | Run governance preflight, pre-read analysis, and explicit swarm control. | Expert or low-level surfaces. |
313
+ | nexus_optimize_tokens | optimization MCP | Generate a token-saving reading plan before broad file inspection. | Mandatory before reading 3+ files from client-visible intent. |
314
+ | nexus_mindkit_check / nexus_ghost_pass / nexus_spawn_workers | safety + runtime MCP | Run governance preflight, refactor pre-flight analysis, and explicit swarm control. | Mindkit and ghost-pass are required lifecycle checks for risky or multi-file mutation. |
315
315
  | nexus_memory_export / import / backup / maintain / trace | memory portability MCP | Export, restore, maintain, and inspect local-first memory bundles. | Supports backup/resume and OpenClaw-oriented bridge packs. |
316
316
  | nexus_list_skills / workflows / hooks / automations / specialists / crews | catalog MCP | Expose what the runtime can activate. | Used for explicit operator control and diagnostics. |
317
- | nexus_run_status / nexus_federation_status / nexus_session_dna | runtime truth MCP | Inspect persisted run state, federation status, and handoff DNA. | Used after execution or during operating-layer work. |
317
+ | nexus_run_status / nexus_federation_status / nexus_session_dna | runtime truth MCP | Inspect persisted run state, federation status, and handoff DNA. | Session DNA generation is mandatory before ending a meaningful session. |
318
318
 
319
319
  </details>
320
320
 
@@ -362,7 +362,7 @@ Core architecture layers that shape execution, memory, and visibility.
362
362
  | Source-Aware Token Budget | runtime subsystem | Allocates token budget across repo, memory, RAG, patterns, and runtime traces. | Persists selected and dropped context. |
363
363
  | Bootstrap Manifest Truth | runtime subsystem | Tracks configured client bootstrap artifacts independently from active heartbeats. | Supports installed vs active truth in the dashboard. |
364
364
  | Artifact Selection Audit | runtime subsystem | Explains why skills/workflows/crews/specialists were selected or rejected. | Persists auditable selection rationale. |
365
- | Bundled assets: 109 skills · 64 workflows · 5 hooks · 3 automations · 7 crews · 139 specialists | runtime subsystem | Summarizes the current bundled runtime inventory. | Detailed lists live in the runtime catalog section and dashboard catalog view. |
365
+ | Bundled assets: 109 skills · 64 workflows · 9 hooks · 5 automations · 7 crews · 139 specialists | runtime subsystem | Summarizes the current bundled runtime inventory. | Detailed lists live in the runtime catalog section and dashboard catalog view. |
366
366
 
367
367
  </details>
368
368
 
@@ -390,7 +390,7 @@ Quality and security checks required before release.
390
390
 
391
391
  Generated from bundled runtime catalogs plus repo-local overrides via `npm run generate:readme-catalog`.
392
392
 
393
- Inventory Snapshot: 109 skills · 64 workflows · 5 hooks · 3 automations · 7 crews
393
+ Inventory Snapshot: 109 skills · 64 workflows · 9 hooks · 5 automations · 7 crews
394
394
 
395
395
  <details>
396
396
  <summary><b>Skills</b> (109)</summary>
@@ -582,12 +582,16 @@ Inventory Snapshot: 109 skills · 64 workflows · 5 hooks · 3 automations · 7
582
582
  </details>
583
583
 
584
584
  <details>
585
- <summary><b>Hooks</b> (5)</summary>
585
+ <summary><b>Hooks</b> (9)</summary>
586
586
 
587
587
  | Name | Type/Scope | Purpose | Trigger / When used |
588
588
  | --- | --- | --- | --- |
589
+ | before-compaction-flush | read · base | Flush memory prefrontal to SQLite before context compaction. | before-compaction · context budget nearing limit |
590
+ | before-mutate-guard | read · base | Local checkpoint before bounded file mutation. | before-mutate |
589
591
  | before-verify-approval | orchestrate · base | Attach approval-loop workflows before verification for domain work. | before-verify · verification checkpoint |
592
+ | failure-summary | read · base | Local failure checkpoint for recovery notes and retry scope. | run.failed |
590
593
  | memory-shield-escalation | read · base | Flag stored memories for shield review when policy risk is detected. | memory.stored · high priority memory stored |
594
+ | memory-stored-review | read · base | Local review hook for important stored memories. | memory.stored |
591
595
  | promotion-audit | read · base | Require a security-oriented audit note on promotion approval. | promotion.approved · promotion approved |
592
596
  | retry-narrow-scope | orchestrate · base | Focus retries on the failing surface after an error cluster. | retry · retry requested |
593
597
  | run-created-brief | read · base | Attach planning context and default orchestration on run creation. | run.created · run created |
@@ -595,12 +599,14 @@ Inventory Snapshot: 109 skills · 64 workflows · 5 hooks · 3 automations · 7
595
599
  </details>
596
600
 
597
601
  <details>
598
- <summary><b>Automations</b> (3)</summary>
602
+ <summary><b>Automations</b> (5)</summary>
599
603
 
600
604
  | Name | Type/Scope | Purpose | Trigger / When used |
601
605
  | --- | --- | --- | --- |
606
+ | failure-followup | event · base | Queue a bounded retry follow-up after a failed run. | event:run.failed |
602
607
  | failure-recovery-automation | event · base | Queue retry and review workflows after a failed run. | event:run.failed |
603
608
  | memory-governance-automation | event · base | Attach memory and security review after memory storage events. | event:memory.stored |
609
+ | session-close-followup | event · base | Queue a bounded approval follow-up after a verified run. | event:run.verified |
604
610
  | verified-followup-automation | event · base | Queue a bounded approval workflow after a verified run. | event:run.verified |
605
611
 
606
612
  </details>
@@ -626,6 +632,17 @@ Inventory Snapshot: 109 skills · 64 workflows · 5 hooks · 3 automations · 7
626
632
  ## 📜 Release History
627
633
 
628
634
  <details open>
635
+ <summary><b>v3.18.0</b> · 2026-03-21 · Lifecycle hardening across MCP, bootstrap artifacts, and release surfaces</summary>
636
+
637
+ - **Lifecycle checklists and footers**: `nexus_session_bootstrap` now appends a mandatory protocol checklist, and `nexus_orchestrate` now appends a mandatory remaining-steps footer.
638
+ - **Lifecycle warnings**: MCP responses now warn when 15+ post-orchestrate tool calls happen without `nexus_store_memory`, and when Nexus-visible 3+ file intent appears without `nexus_optimize_tokens`.
639
+ - **Shared instruction closure**: `CLAUDE.md`, `AGENTS.md`, client bootstrap artifacts, and the feature registry now agree that `nexus_orchestrate` does not replace during-work or end-of-session lifecycle steps.
640
+ - **Release-surface alignment**: Protocol, integrations, knowledge-base, README, and generated bootstrap surfaces now use the same mandatory lifecycle wording.
641
+
642
+ Full notes: [releases/v3.18.0.md](./releases/v3.18.0.md) · Full history: [CHANGELOG.md](./CHANGELOG.md)
643
+ </details>
644
+
645
+ <details>
629
646
  <summary><b>v3.17.0</b> · 2026-03-20 · Agent adoption hardening, memory readability, atlas code intelligence peer</summary>
630
647
 
631
648
  - **Hard bootstrap enforcement**: Non-bootstrap MCP tool calls return a structured `blocked` response with next-step guidance instead of a soft warning agents ignored. Read-only tools remain exempt.
@@ -24,6 +24,10 @@ export declare class MCPAdapter implements Adapter {
24
24
  private getRuntime;
25
25
  private getOrchestrator;
26
26
  private getToolProfile;
27
+ private formatProtocolChecklist;
28
+ private formatRemainingProtocolSteps;
29
+ private prependTextToResponse;
30
+ private decorateLifecycleResponse;
27
31
  private describeClientInstructionStatus;
28
32
  private finalizeToolDefinitions;
29
33
  private decorateToolDescription;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/agents/adapters/mcp.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAiE5C,KAAK,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAC5C,KAAK,iBAAiB,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,CAAC;AAmKF,qBAAa,UAAW,YAAW,OAAO;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAG,KAAK,CAAU;IACtB,SAAS,UAAS;IAClB,MAAM,EAAE,MAAM,EAAE,CAAM;IAEtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,OAAO,CAAC,CAAkB;IAElC,OAAO,CAAC,cAAc;IA+BtB,OAAO,CAAC,GAAG;;IAmBX,OAAO,CAAC,gBAAgB;IA4BxB,WAAW,CAAC,KAAK,EAAE,UAAU;IAI7B,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,+BAA+B;IAMvC,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,uBAAuB;IAsB/B,cAAc,CAAC,OAAO,GAAE,cAAsC,GAAG,iBAAiB,EAAE;IAIpF,OAAO,CAAC,oBAAoB;IA8yB5B,OAAO,CAAC,iBAAiB;YAyFX,cAAc;IAy1D5B,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAItC,OAAO,CAAC,IAAI;IAmBN,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB3B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CACzC"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/agents/adapters/mcp.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAiE5C,KAAK,cAAc,GAAG,YAAY,GAAG,MAAM,CAAC;AAE5C,KAAK,iBAAiB,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC,CAAC;AA4SF,qBAAa,UAAW,YAAW,OAAO;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAG,KAAK,CAAU;IACtB,SAAS,UAAS;IAClB,MAAM,EAAE,MAAM,EAAE,CAAM;IAEtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,OAAO,CAAC,CAAkB;IAElC,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,GAAG;;IAmBX,OAAO,CAAC,gBAAgB;IA4BxB,WAAW,CAAC,KAAK,EAAE,UAAU;IAI7B,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,4BAA4B;IAWpC,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,yBAAyB;IA8BjC,OAAO,CAAC,+BAA+B;IAMvC,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,uBAAuB;IAkC/B,cAAc,CAAC,OAAO,GAAE,cAAsC,GAAG,iBAAiB,EAAE;IAIpF,OAAO,CAAC,oBAAoB;IA8yB5B,OAAO,CAAC,iBAAiB;YA4FX,cAAc;IA01D5B,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE;IAItC,OAAO,CAAC,IAAI;IAmBN,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAOxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB3B,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAClD,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;CACzC"}
@@ -130,11 +130,122 @@ class SessionTelemetry {
130
130
  tokensOptimized = 0;
131
131
  memoriesStored = 0;
132
132
  memoriesRecalled = 0;
133
+ lifecyclePhase = 'pre-bootstrap';
134
+ optimizeTokensCalled = false;
135
+ mindkitCheckCalled = false;
136
+ storeMemoryCalledPostOrchestrate = false;
137
+ sessionDnaCalled = false;
138
+ fileReadIntentCount = 0;
139
+ callsSinceOrchestrate = 0;
140
+ fileIntentPaths = new Set();
133
141
  bootstrapped = false;
134
- recordCall() { this.callCount++; }
142
+ recordCall() {
143
+ this.callCount++;
144
+ if (this.isPostOrchestratePhase()) {
145
+ this.callsSinceOrchestrate++;
146
+ }
147
+ }
135
148
  recordTokens(saved) { this.tokensOptimized += saved; }
136
149
  recordStore() { this.memoriesStored++; }
137
150
  recordRecall(count) { this.memoriesRecalled += count; }
151
+ snapshot() {
152
+ return {
153
+ callCount: this.callCount,
154
+ tokensOptimized: this.tokensOptimized,
155
+ memoriesStored: this.memoriesStored,
156
+ memoriesRecalled: this.memoriesRecalled,
157
+ lifecyclePhase: this.lifecyclePhase,
158
+ optimizeTokensCalled: this.optimizeTokensCalled,
159
+ mindkitCheckCalled: this.mindkitCheckCalled,
160
+ storeMemoryCalledPostOrchestrate: this.storeMemoryCalledPostOrchestrate,
161
+ sessionDnaCalled: this.sessionDnaCalled,
162
+ fileReadIntentCount: this.fileReadIntentCount,
163
+ callsSinceOrchestrate: this.callsSinceOrchestrate,
164
+ };
165
+ }
166
+ advancePhase(nextPhase) {
167
+ if (this.lifecyclePhase === nextPhase)
168
+ return;
169
+ this.lifecyclePhase = nextPhase;
170
+ if (nextPhase === 'bootstrapped' || nextPhase === 'orchestrated') {
171
+ this.resetFileIntentTracking();
172
+ this.optimizeTokensCalled = false;
173
+ }
174
+ if (nextPhase === 'orchestrated') {
175
+ this.mindkitCheckCalled = false;
176
+ this.storeMemoryCalledPostOrchestrate = false;
177
+ this.sessionDnaCalled = false;
178
+ this.callsSinceOrchestrate = 0;
179
+ }
180
+ }
181
+ observeSuccessfulToolCall(toolName, args) {
182
+ if (toolName === 'nexus_session_bootstrap') {
183
+ this.bootstrapped = true;
184
+ this.advancePhase('bootstrapped');
185
+ this.noteFileIntent(args.files);
186
+ return;
187
+ }
188
+ if (toolName === 'nexus_orchestrate') {
189
+ this.advancePhase('orchestrated');
190
+ this.noteFileIntent(args.files);
191
+ return;
192
+ }
193
+ if (toolName === 'nexus_optimize_tokens') {
194
+ this.optimizeTokensCalled = true;
195
+ if (this.lifecyclePhase === 'orchestrated')
196
+ this.advancePhase('working');
197
+ this.noteFileIntent(args.files);
198
+ return;
199
+ }
200
+ if (toolName === 'nexus_mindkit_check') {
201
+ this.mindkitCheckCalled = true;
202
+ if (this.lifecyclePhase === 'orchestrated')
203
+ this.advancePhase('working');
204
+ this.noteFileIntent(args.filesToModify);
205
+ return;
206
+ }
207
+ if (toolName === 'nexus_ghost_pass') {
208
+ if (this.lifecyclePhase === 'orchestrated')
209
+ this.advancePhase('working');
210
+ this.noteFileIntent(args.files);
211
+ return;
212
+ }
213
+ if (toolName === 'nexus_store_memory') {
214
+ if (this.isPostOrchestratePhase()) {
215
+ this.storeMemoryCalledPostOrchestrate = true;
216
+ }
217
+ if (this.lifecyclePhase === 'orchestrated')
218
+ this.advancePhase('working');
219
+ return;
220
+ }
221
+ if (toolName === 'nexus_session_dna' && String(args.action ?? 'load') === 'generate') {
222
+ this.sessionDnaCalled = true;
223
+ this.advancePhase('closing');
224
+ return;
225
+ }
226
+ if (this.lifecyclePhase === 'orchestrated') {
227
+ this.advancePhase('working');
228
+ }
229
+ }
230
+ needsOptimizeTokens(currentToolName) {
231
+ if (currentToolName === 'nexus_optimize_tokens')
232
+ return false;
233
+ if (this.lifecyclePhase === 'pre-bootstrap')
234
+ return false;
235
+ return this.fileReadIntentCount >= 3 && !this.optimizeTokensCalled;
236
+ }
237
+ needsStoreMemory(currentToolName) {
238
+ if (currentToolName === 'nexus_store_memory')
239
+ return false;
240
+ return this.isPostOrchestratePhase()
241
+ && this.callsSinceOrchestrate >= 15
242
+ && !this.storeMemoryCalledPostOrchestrate;
243
+ }
244
+ needsSessionDna(currentToolName) {
245
+ if (currentToolName === 'nexus_session_dna')
246
+ return false;
247
+ return this.isPostOrchestratePhase() && !this.sessionDnaCalled;
248
+ }
138
249
  notifyStore(priority, tags, memStats) {
139
250
  return `\nMemory telemetry: priority ${priority.toFixed(2)} · tags ${tags.join(', ') || 'none'} · cortex ${memStats.cortex} · zettel ${memStats.totalLinks}`;
140
251
  }
@@ -175,14 +286,14 @@ class SessionTelemetry {
175
286
  nudges.push('Guardrail FAILED. Do NOT proceed. Re-scope the task or call nexus_ghost_pass for a safer approach.');
176
287
  break;
177
288
  case 'high_call_count':
178
- if (this.callCount > 20) {
179
- nudges.push('20+ tool calls reached. Next: call nexus_store_memory with a session summary.');
289
+ if (this.callsSinceOrchestrate >= 15 && !this.storeMemoryCalledPostOrchestrate) {
290
+ nudges.push('15+ post-orchestrate tool calls reached. Next: call nexus_store_memory with a session summary.');
180
291
  }
181
292
  break;
182
293
  }
183
294
  if (nudges.length === 0)
184
295
  return '';
185
- return `\n<nexus-next-step>\n${nudges.map(n => ` → ${n}`).join('\n')}\n</nexus-next-step>`;
296
+ return `\n\nMANDATORY NEXT STEPS:\n${nudges.map((n) => `- ${n}`).join('\n')}\nDo NOT proceed without completing these steps.`;
186
297
  }
187
298
  format(memStats) {
188
299
  const uptime = Math.round((Date.now() - this.startTime) / 1000);
@@ -190,9 +301,30 @@ class SessionTelemetry {
190
301
  const parts = [
191
302
  `${this.callCount} calls`,
192
303
  memStats ? `${memStats.totalLinks} Zettel links` : null,
304
+ `phase ${this.lifecyclePhase}`,
193
305
  ].filter(Boolean);
194
306
  return `\nSession telemetry (${uptimeStr}): ${parts.join(' · ')}`;
195
307
  }
308
+ noteFileIntent(rawPaths) {
309
+ if (!Array.isArray(rawPaths))
310
+ return;
311
+ for (const rawPath of rawPaths) {
312
+ const normalized = String(rawPath || '').trim();
313
+ if (!normalized)
314
+ continue;
315
+ this.fileIntentPaths.add(normalized);
316
+ }
317
+ this.fileReadIntentCount = this.fileIntentPaths.size;
318
+ }
319
+ resetFileIntentTracking() {
320
+ this.fileIntentPaths.clear();
321
+ this.fileReadIntentCount = 0;
322
+ }
323
+ isPostOrchestratePhase() {
324
+ return this.lifecyclePhase === 'orchestrated'
325
+ || this.lifecyclePhase === 'working'
326
+ || this.lifecyclePhase === 'closing';
327
+ }
196
328
  }
197
329
  function formatBullets(lines) {
198
330
  return lines.filter(Boolean).map((line) => `- ${line}`).join('\n');
@@ -223,11 +355,9 @@ export class MCPAdapter {
223
355
  for (let i = 0; i < keys.length; i += 2) {
224
356
  const k1 = keys[i];
225
357
  const v1 = String(metrics[k1]).substring(0, 20);
226
- const p1 = `\x1b[33m${k1}:\x1b[0m ${v1}`.padEnd(42, ' ');
227
358
  if (i + 1 < keys.length) {
228
359
  const k2 = keys[i + 1];
229
360
  const v2 = String(metrics[k2]).substring(0, 20);
230
- const p2 = `\x1b[33m${k2}:\x1b[0m ${v2}`.padEnd(42, ' ');
231
361
  // We have to hardcode padding because ansi escape codes mess with .padEnd length
232
362
  console.error(`\x1b[36m║ \x1b[33m${k1}:\x1b[37m ${v1.padEnd(20, ' ')} │ \x1b[33m${k2}:\x1b[37m ${v2.padEnd(19, ' ')} \x1b[36m║\x1b[0m`);
233
363
  }
@@ -312,9 +442,60 @@ export class MCPAdapter {
312
442
  ? 'full'
313
443
  : 'autonomous';
314
444
  }
445
+ formatProtocolChecklist() {
446
+ return [
447
+ 'PROTOCOL CHECKLIST (follow every step):',
448
+ '[x] nexus_session_bootstrap — DONE',
449
+ '[ ] nexus_orchestrate — Call NOW with the user\'s request',
450
+ '[ ] nexus_optimize_tokens — Call BEFORE reading 3+ files',
451
+ '[ ] nexus_mindkit_check — Call BEFORE any file modifications',
452
+ '[ ] nexus_store_memory — Call AFTER significant findings AND at session end',
453
+ '[ ] nexus_session_dna — Call BEFORE ending this session',
454
+ ].join('\n');
455
+ }
456
+ formatRemainingProtocolSteps() {
457
+ return [
458
+ 'REMAINING PROTOCOL STEPS (MANDATORY):',
459
+ '- Call nexus_optimize_tokens(goal, files) BEFORE reading 3+ files',
460
+ '- Call nexus_mindkit_check(action, filesToModify) BEFORE modifying any files',
461
+ '- Call nexus_store_memory(content, priority, tags) with key findings from this work',
462
+ '- Call nexus_session_dna(action="generate") BEFORE ending this session',
463
+ 'Do NOT skip these steps. The orchestrate call handled planning and execution, but these lifecycle steps are your responsibility.',
464
+ ].join('\n');
465
+ }
466
+ prependTextToResponse(result, text) {
467
+ if (!text.trim())
468
+ return result;
469
+ const content = result.content.map((item, index) => {
470
+ if (index === 0 && item.type === 'text') {
471
+ return {
472
+ ...item,
473
+ text: `${text}\n\n${item.text}`,
474
+ };
475
+ }
476
+ return item;
477
+ });
478
+ return { ...result, content };
479
+ }
480
+ decorateLifecycleResponse(toolName, result) {
481
+ const telemetry = this.telemetry.snapshot();
482
+ const warnings = [];
483
+ if (this.telemetry.needsOptimizeTokens(toolName)) {
484
+ warnings.push(`Nexus only sees best-effort file intent from tool arguments. Current intent references ${telemetry.fileReadIntentCount} file(s), and nexus_optimize_tokens has not been called in this phase. Call nexus_optimize_tokens(goal, files) before broad reading.`);
485
+ }
486
+ if (this.telemetry.needsStoreMemory(toolName)) {
487
+ warnings.push(`${telemetry.callsSinceOrchestrate} post-orchestrate tool calls have happened without nexus_store_memory. Store the key findings before continuing.`);
488
+ }
489
+ if (warnings.length === 0)
490
+ return result;
491
+ return this.prependTextToResponse(result, [
492
+ 'LIFECYCLE WARNING:',
493
+ ...warnings.map((warning) => `- ${warning}`),
494
+ ].join('\n'));
495
+ }
315
496
  describeClientInstructionStatus(profile) {
316
497
  return profile === 'autonomous'
317
- ? 'Autonomous MCP profile active. Prefer nexus_session_bootstrap then nexus_orchestrate.'
498
+ ? 'Autonomous MCP profile active. REQUIRED start: nexus_session_bootstrap, then nexus_orchestrate. During-work and session-close lifecycle tools remain mandatory.'
318
499
  : 'Full MCP profile active. Low-level and authoring tools are exposed.';
319
500
  }
320
501
  finalizeToolDefinitions(tools, profile = this.getToolProfile()) {
@@ -347,7 +528,19 @@ export class MCPAdapter {
347
528
  return 'Optional: Inspect the execution ledger before calling nexus_orchestrate. Skip unless you need pre-run visibility into what Nexus will choose.';
348
529
  }
349
530
  if (name === 'nexus_optimize_tokens') {
350
- return 'Call when reading 3+ files. Returns a reading plan that saves 50-90% tokens. Follow the plan output do not bulk-read the repo.';
531
+ return 'MANDATORY before reading 3+ files. Returns a token-saving reading plan. Follow it exactly and do not bulk-read the repo.';
532
+ }
533
+ if (name === 'nexus_mindkit_check') {
534
+ return 'MANDATORY before any file modification or destructive operation. Returns PASS/FAIL. Do NOT proceed if it returns FAIL.';
535
+ }
536
+ if (name === 'nexus_store_memory') {
537
+ return 'MANDATORY after significant findings and at session end. Store root causes, architecture decisions, and reusable patterns.';
538
+ }
539
+ if (name === 'nexus_session_dna') {
540
+ return 'MANDATORY at session end. Generates the handover snapshot for this session. Never skip this step.';
541
+ }
542
+ if (name === 'nexus_ghost_pass') {
543
+ return 'MANDATORY before refactoring 3+ files. Provides a safe execution plan, risk map, and worker guidance.';
351
544
  }
352
545
  if (name === 'nexus_spawn_workers') {
353
546
  return 'Call when modifying 3+ interrelated files or when nexus_ghost_pass recommends parallel execution. Prefer nexus_orchestrate for automatic worker management.';
@@ -365,7 +558,7 @@ export class MCPAdapter {
365
558
  // ── Memory ────────────────────────────────────────────────────────
366
559
  {
367
560
  name: 'nexus_store_memory',
368
- description: 'Store a finding, insight, or memory into Nexus Prime. Use after discovering bugs, architecture decisions, or patterns. Priority 0-1 (1.0 = critical). High-priority items auto-fission to long-term memory.',
561
+ description: 'Store a finding, insight, or memory into Nexus Prime. MANDATORY after significant findings and at session end. Priority 0-1 (1.0 = critical). High-priority items auto-fission to long-term memory.',
369
562
  inputSchema: {
370
563
  type: 'object',
371
564
  properties: {
@@ -616,7 +809,7 @@ export class MCPAdapter {
616
809
  },
617
810
  {
618
811
  name: 'nexus_session_dna',
619
- description: 'Generate or load a Session DNA snapshot. Captures files accessed/modified, decisions made, skills used, and recommended next steps for perfect session handover. Use "generate" to create a snapshot of the current session, "load" to retrieve the most recent previous session\'s DNA.',
812
+ description: 'Generate or load a Session DNA snapshot. MANDATORY at session end when using "generate". Captures files accessed/modified, decisions made, skills used, and recommended next steps for perfect session handover.',
620
813
  inputSchema: {
621
814
  type: 'object',
622
815
  properties: {
@@ -1196,13 +1389,14 @@ export class MCPAdapter {
1196
1389
  if (toolName === 'nexus_session_bootstrap') {
1197
1390
  this.telemetry.bootstrapped = true;
1198
1391
  }
1392
+ const args = request.params?.arguments ?? {};
1199
1393
  const callId = `mcp_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
1200
1394
  const startTimeMs = Date.now();
1201
1395
  nexusEventBus.emit('mcp.call.start', {
1202
1396
  callId,
1203
1397
  serverName: 'nexus-prime',
1204
1398
  toolName,
1205
- args: request.params?.arguments ?? {}
1399
+ args,
1206
1400
  });
1207
1401
  let result;
1208
1402
  try {
@@ -1228,6 +1422,7 @@ export class MCPAdapter {
1228
1422
  });
1229
1423
  throw error;
1230
1424
  }
1425
+ this.telemetry.observeSuccessfulToolCall(toolName, args);
1231
1426
  if (!this.telemetry.bootstrapped &&
1232
1427
  toolName !== 'nexus_session_bootstrap' &&
1233
1428
  toolName !== 'nexus_memory_stats' &&
@@ -1246,7 +1441,7 @@ export class MCPAdapter {
1246
1441
  }]
1247
1442
  };
1248
1443
  }
1249
- return result;
1444
+ return this.decorateLifecycleResponse(toolName, result);
1250
1445
  });
1251
1446
  }
1252
1447
  async handleToolCall(request) {
@@ -1329,6 +1524,7 @@ export class MCPAdapter {
1329
1524
  `Bootstrap status: ${bootstrap.clientBootstrapStatus?.clients?.length || 0} client manifests tracked`,
1330
1525
  ]),
1331
1526
  formatJsonDetails('Structured details', payload),
1527
+ this.formatProtocolChecklist(),
1332
1528
  ].join('\n\n'),
1333
1529
  }],
1334
1530
  };
@@ -1432,6 +1628,7 @@ export class MCPAdapter {
1432
1628
  ]),
1433
1629
  execution.result ? `Result\n\`\`\`\n${execution.result}\n\`\`\`` : '',
1434
1630
  formatJsonDetails('Structured details', payload),
1631
+ this.formatRemainingProtocolSteps(),
1435
1632
  ].filter(Boolean).join('\n\n'),
1436
1633
  }],
1437
1634
  };
@@ -1461,6 +1658,7 @@ export class MCPAdapter {
1461
1658
  runtimeUsage?.skipReasons?.length ? `Skipped stages: ${runtimeUsage.skipReasons.join(' · ')}` : 'Skipped stages: not recorded',
1462
1659
  ]),
1463
1660
  formatJsonDetails('Structured details', payload),
1661
+ this.formatRemainingProtocolSteps(),
1464
1662
  ].join('\n\n'),
1465
1663
  }],
1466
1664
  };
@@ -1486,8 +1684,6 @@ export class MCPAdapter {
1486
1684
  const id = this.nexusRef.storeMemory(content, priority, tags);
1487
1685
  this.telemetry.recordStore();
1488
1686
  this.sessionDNA.recordMemoryStore();
1489
- const memStats = this.nexusRef.getMemoryStats();
1490
- const notification = this.telemetry.notifyStore(priority, tags, memStats);
1491
1687
  const nudge = this.telemetry.planningNudge('store', { priority });
1492
1688
  // Auto-Gist Publish Phase 8
1493
1689
  let autoGistNote = '';
@@ -1526,8 +1722,6 @@ export class MCPAdapter {
1526
1722
  nexusEventBus.emit('memory.recall', { query, count: memories.length });
1527
1723
  this.telemetry.recordRecall(memories.length);
1528
1724
  this.sessionDNA.recordMemoryRecall();
1529
- const memStats = this.nexusRef.getMemoryStats();
1530
- const notification = this.telemetry.notifyRecall(memories.length, query, memStats);
1531
1725
  const nudge = this.telemetry.planningNudge('recall', { count: memories.length });
1532
1726
  // Console ASCII UI
1533
1727
  this.box('🔍 CORTEX MEMORY RECALL', [
@@ -2078,12 +2272,14 @@ export class MCPAdapter {
2078
2272
  ? String(request.params.arguments.sessionId)
2079
2273
  : undefined;
2080
2274
  if (action === 'generate') {
2275
+ this.telemetry.observeSuccessfulToolCall('nexus_session_dna', { action });
2081
2276
  // Sync counters from telemetry before generating
2277
+ const telemetry = this.telemetry.snapshot();
2082
2278
  this.sessionDNA.syncFromTelemetry({
2083
- callCount: this.telemetry.callCount ?? 0,
2084
- memoriesStored: this.telemetry.memoriesStored ?? 0,
2085
- memoriesRecalled: this.telemetry.memoriesRecalled ?? 0,
2086
- tokensOptimized: this.telemetry.tokensOptimized ?? 0,
2279
+ callCount: telemetry.callCount,
2280
+ memoriesStored: telemetry.memoriesStored,
2281
+ memoriesRecalled: telemetry.memoriesRecalled,
2282
+ tokensOptimized: telemetry.tokensOptimized,
2087
2283
  });
2088
2284
  const dna = this.sessionDNA.flush();
2089
2285
  const formatted = SessionDNAManager.format(dna);
@@ -2995,11 +3191,12 @@ export class MCPAdapter {
2995
3191
  async disconnect() {
2996
3192
  // Auto-flush Session DNA on disconnect
2997
3193
  try {
3194
+ const telemetry = this.telemetry.snapshot();
2998
3195
  this.sessionDNA.syncFromTelemetry({
2999
- callCount: this.telemetry.callCount ?? 0,
3000
- memoriesStored: this.telemetry.memoriesStored ?? 0,
3001
- memoriesRecalled: this.telemetry.memoriesRecalled ?? 0,
3002
- tokensOptimized: this.telemetry.tokensOptimized ?? 0,
3196
+ callCount: telemetry.callCount,
3197
+ memoriesStored: telemetry.memoriesStored,
3198
+ memoriesRecalled: telemetry.memoriesRecalled,
3199
+ tokensOptimized: telemetry.tokensOptimized,
3003
3200
  });
3004
3201
  this.sessionDNA.flush();
3005
3202
  console.error('[MCP Adapter] Session DNA flushed');