nexus-prime 7.9.25 → 7.9.27
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 +11 -0
- package/dist/cli.js +29 -0
- package/dist/dashboard/app/styles/board.css +34 -0
- package/dist/dashboard/app/views/board.js +39 -9
- package/dist/dashboard/app/views/trust.js +41 -0
- package/dist/dashboard/selectors/trust-selector.js +20 -0
- package/dist/dashboard/types.d.ts +1 -0
- package/dist/engines/event-bus.d.ts +16 -0
- package/dist/engines/github-bridge.d.ts +6 -1
- package/dist/engines/github-bridge.js +91 -7
- package/dist/engines/nexus-proof.d.ts +26 -0
- package/dist/engines/nexus-proof.js +118 -0
- package/dist/engines/nexus-signature.d.ts +33 -0
- package/dist/engines/nexus-signature.js +127 -0
- package/dist/engines/orchestrator.js +3 -1
- package/dist/engines/telemetry-remote.d.ts +15 -1
- package/dist/engines/telemetry-remote.js +93 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/install/claude-code-hooks.js +4 -0
- package/dist/phantom/runtime.d.ts +6 -0
- package/dist/phantom/runtime.js +16 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,6 +74,17 @@ Agents should start with `nexus_session_bootstrap`, then route the raw request t
|
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
77
|
+
## Provenance and social proof
|
|
78
|
+
|
|
79
|
+
Nexus Prime now treats provenance as a product surface, not a footer afterthought.
|
|
80
|
+
|
|
81
|
+
- Every Nexus-enabled PR can carry a **Nexus Prime Presence** block that links back to https://nexus-prime.cfd/ and states whether Nexus observed, verified, assisted, authored, or published the change.
|
|
82
|
+
- Nexus-generated commits use the repo-local Git-native `Co-Authored-By` trailer for the Nexus Prime GitHub identity; human-only commits are not falsely claimed.
|
|
83
|
+
- Generated artifacts can include a Nexus Prime signature with run ID, verification state, human-review state, and website proof.
|
|
84
|
+
- Opt-in telemetry can send privacy-safe PLG events such as `pr_presence_added`, `commit_attributed`, `document_signed`, `release_verified`, and `proof_badge_viewed` to the configured Supabase endpoint. Raw prompts, code, repo names, branch names, file paths, secrets, and tokens are redacted by default.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
77
88
|
## The problem
|
|
78
89
|
|
|
79
90
|
Every coding agent you use starts every session cold.
|
package/dist/cli.js
CHANGED
|
@@ -40,6 +40,7 @@ import { runReset } from './cli/reset.js';
|
|
|
40
40
|
import { runUninstall } from './cli/uninstall.js';
|
|
41
41
|
import { runCleanup } from './cli/cleanup.js';
|
|
42
42
|
import { runDoctorStorage } from './cli/doctor-storage.js';
|
|
43
|
+
import { formatNexusProofReport, verifyNexusProof } from './engines/nexus-proof.js';
|
|
43
44
|
const tokenEngine = new TokenSupremacyEngine();
|
|
44
45
|
import { getNexusHookSpec, writeNexusClaudeCodeHooks, } from './install/claude-code-hooks.js';
|
|
45
46
|
/**
|
|
@@ -1886,6 +1887,34 @@ program
|
|
|
1886
1887
|
nexus = null;
|
|
1887
1888
|
}
|
|
1888
1889
|
});
|
|
1890
|
+
program
|
|
1891
|
+
.command('proof')
|
|
1892
|
+
.description('Inspect Nexus Prime provenance, signatures, and opt-in proof telemetry')
|
|
1893
|
+
.addCommand(new Command('verify')
|
|
1894
|
+
.description('Verify Nexus Prime PR presence, generated commit trailers, artifact signatures, and telemetry redaction')
|
|
1895
|
+
.option('--repo-root <path>', 'Repo root to verify (default: cwd)')
|
|
1896
|
+
.option('--pr-body <path>', 'Generated pull request body markdown to verify')
|
|
1897
|
+
.option('--commit-message <path>', 'Generated commit message file to verify')
|
|
1898
|
+
.option('--artifact <path...>', 'Generated artifact/document files to verify')
|
|
1899
|
+
.option('--strict', 'Treat warnings as failures')
|
|
1900
|
+
.option('--json', 'Output raw JSON')
|
|
1901
|
+
.action(async (options) => {
|
|
1902
|
+
const summary = await verifyNexusProof({
|
|
1903
|
+
repoRoot: options.repoRoot ? path.resolve(options.repoRoot) : getWorkspaceRoot(),
|
|
1904
|
+
prBodyPath: options.prBody ? path.resolve(options.prBody) : undefined,
|
|
1905
|
+
commitMessagePath: options.commitMessage ? path.resolve(options.commitMessage) : undefined,
|
|
1906
|
+
artifactPaths: (options.artifact ?? []).map((artifactPath) => path.resolve(artifactPath)),
|
|
1907
|
+
});
|
|
1908
|
+
if (options.json) {
|
|
1909
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
1910
|
+
}
|
|
1911
|
+
else {
|
|
1912
|
+
console.log(formatNexusProofReport(summary));
|
|
1913
|
+
}
|
|
1914
|
+
if (summary.failed > 0 || (options.strict && summary.warnings > 0)) {
|
|
1915
|
+
process.exitCode = 1;
|
|
1916
|
+
}
|
|
1917
|
+
}));
|
|
1889
1918
|
program
|
|
1890
1919
|
.command('memory-hygiene')
|
|
1891
1920
|
.description('Inspect or apply memory hygiene to reduce duplicate and low-signal memories')
|
|
@@ -479,6 +479,38 @@
|
|
|
479
479
|
color: var(--text-main); margin-bottom: 4px;
|
|
480
480
|
}
|
|
481
481
|
.frh-sub { font-size: var(--text-sm); color: var(--text-dim); }
|
|
482
|
+
.frh-steps {
|
|
483
|
+
display: grid;
|
|
484
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
485
|
+
gap: 8px;
|
|
486
|
+
margin-bottom: 14px;
|
|
487
|
+
}
|
|
488
|
+
.frh-step {
|
|
489
|
+
display: grid;
|
|
490
|
+
grid-template-columns: auto 1fr;
|
|
491
|
+
grid-template-rows: auto auto;
|
|
492
|
+
gap: 1px 8px;
|
|
493
|
+
align-items: center;
|
|
494
|
+
padding: 9px 10px;
|
|
495
|
+
border: 1px solid color-mix(in oklch, var(--accent) 24%, var(--border));
|
|
496
|
+
border-radius: var(--radius);
|
|
497
|
+
background: color-mix(in oklch, var(--accent) 4%, var(--bg-panel));
|
|
498
|
+
min-width: 0;
|
|
499
|
+
}
|
|
500
|
+
.frh-step span {
|
|
501
|
+
grid-row: 1 / span 2;
|
|
502
|
+
display: inline-grid;
|
|
503
|
+
place-items: center;
|
|
504
|
+
width: 22px;
|
|
505
|
+
height: 22px;
|
|
506
|
+
border-radius: 50%;
|
|
507
|
+
background: color-mix(in oklch, var(--accent) 18%, transparent);
|
|
508
|
+
color: var(--accent);
|
|
509
|
+
font-family: var(--font-mono);
|
|
510
|
+
font-size: 0.72rem;
|
|
511
|
+
}
|
|
512
|
+
.frh-step strong { font-size: 0.78rem; color: var(--text-main); min-width: 0; }
|
|
513
|
+
.frh-step small { font-size: 0.72rem; color: var(--text-dim); min-width: 0; }
|
|
482
514
|
.frh-command {
|
|
483
515
|
display: grid;
|
|
484
516
|
grid-template-columns: minmax(220px, 1fr) auto auto;
|
|
@@ -492,6 +524,7 @@
|
|
|
492
524
|
transition: border-color 0.15s;
|
|
493
525
|
}
|
|
494
526
|
.frh-pick:hover { border-color: var(--accent); }
|
|
527
|
+
.frh-pick-loading { border-style: dashed; }
|
|
495
528
|
.frh-pick-name { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text-main); }
|
|
496
529
|
.frh-pick-desc { font-size: 0.78rem; color: var(--text-dim); flex: 1; }
|
|
497
530
|
.frh-pick-cost { font-family: var(--font-mono); font-size: 0.75rem; color: var(--accent); margin-top: 2px; }
|
|
@@ -507,6 +540,7 @@
|
|
|
507
540
|
}
|
|
508
541
|
@media (max-width: 768px) {
|
|
509
542
|
#kanban-board { grid-template-columns: repeat(2, 1fr); }
|
|
543
|
+
.frh-steps,
|
|
510
544
|
.frh-command,
|
|
511
545
|
.frh-picks { grid-template-columns: 1fr; }
|
|
512
546
|
}
|
|
@@ -376,7 +376,6 @@ function renderFirstRunHero() {
|
|
|
376
376
|
if (hasOps || (alreadySeen && hasRuns)) return;
|
|
377
377
|
|
|
378
378
|
const specs = (S.curatedSpecialists || []).slice(0, 3);
|
|
379
|
-
if (!specs.length) return; // Still loading — will re-render when prefetch resolves
|
|
380
379
|
const readiness = getHireReadiness();
|
|
381
380
|
const noticesHtml = readiness.notes.length
|
|
382
381
|
? `<div class="frh-notices" style="display:flex;flex-direction:column;gap:8px;margin-bottom:12px">
|
|
@@ -389,23 +388,33 @@ function renderFirstRunHero() {
|
|
|
389
388
|
card.className = 'first-run-hero card';
|
|
390
389
|
card.innerHTML = `
|
|
391
390
|
<div class="frh-header">
|
|
392
|
-
<div class="frh-title">${hasRuns ? '
|
|
393
|
-
<div class="frh-sub">${hasRuns ? 'Hire a specialist
|
|
391
|
+
<div class="frh-title">${hasRuns ? 'Choose the next worker' : 'Start the first real run'}</div>
|
|
392
|
+
<div class="frh-sub">${hasRuns ? 'Hire a specialist or queue a goal. Nexus will show the route, budget, workers, and verification here.' : 'Queue one goal from the dashboard. Nexus will route it, show who gets hired, and write the run trail into Board and Context Log.'}</div>
|
|
394
393
|
</div>
|
|
395
394
|
${noticesHtml}
|
|
395
|
+
<div class="frh-steps" aria-label="Onboarding steps">
|
|
396
|
+
<div class="frh-step"><span>1</span><strong>Describe goal</strong><small>Run or hire from here.</small></div>
|
|
397
|
+
<div class="frh-step"><span>2</span><strong>Watch route</strong><small>Board shows workers and budget.</small></div>
|
|
398
|
+
<div class="frh-step"><span>3</span><strong>Verify proof</strong><small>Context Log keeps artifacts.</small></div>
|
|
399
|
+
</div>
|
|
396
400
|
<div class="frh-command">
|
|
397
401
|
<input id="frh-goal-input" class="form-input" type="text" placeholder="Inspect this repo and suggest the next fix" autocomplete="off">
|
|
398
|
-
<button class="btn btn-primary btn-sm" id="frh-run-btn">Run goal</button>
|
|
402
|
+
<button class="btn btn-primary btn-sm" id="frh-run-btn">Run first goal</button>
|
|
399
403
|
<button class="btn btn-sm" id="frh-context-btn">Open context</button>
|
|
400
404
|
</div>
|
|
401
405
|
<div class="frh-picks">
|
|
402
|
-
${specs.map(s => `
|
|
406
|
+
${specs.length ? specs.map(s => `
|
|
403
407
|
<div class="frh-pick" data-specid="${esc(s.specialistId)}" data-specname="${esc(s.name)}">
|
|
404
408
|
<div class="frh-pick-name">${esc(s.name)}</div>
|
|
405
409
|
<div class="frh-pick-desc">${esc((s.description||'').slice(0, 72))}${(s.description||'').length > 72 ? '…' : ''}</div>
|
|
406
410
|
<div class="frh-pick-cost">~$${esc(String(s.pricing?.typical ?? '?'))}/sortie</div>
|
|
407
411
|
<button class="btn btn-primary btn-sm frh-hire-btn" data-specid="${esc(s.specialistId)}" data-specname="${esc(s.name)}" ${readiness.unavailable ? 'disabled title="Synapse is not ready"' : ''}>Hire</button>
|
|
408
|
-
</div>`).join('')
|
|
412
|
+
</div>`).join('') : `
|
|
413
|
+
<div class="frh-pick frh-pick-loading">
|
|
414
|
+
<div class="frh-pick-name">Specialists loading</div>
|
|
415
|
+
<div class="frh-pick-desc">You can run a goal immediately. Hiring picks will appear when the catalog responds.</div>
|
|
416
|
+
<div class="frh-pick-cost">route first, hire second</div>
|
|
417
|
+
</div>`}
|
|
409
418
|
</div>
|
|
410
419
|
<div id="frh-status" style="display:none;margin-top:12px;font-size:var(--text-sm)"></div>
|
|
411
420
|
<button class="btn btn-ghost btn-sm frh-dismiss" style="margin-top:var(--space-3)">Dismiss</button>`;
|
|
@@ -424,6 +433,7 @@ function renderFirstRunHero() {
|
|
|
424
433
|
const result = await post('/api/orchestrate', { goal, source: 'dashboard-onboarding' });
|
|
425
434
|
if (result.ok) {
|
|
426
435
|
setFirstRunStatus('Run queued. Board and Context Log will update as Nexus writes artifacts.');
|
|
436
|
+
try { localStorage.setItem(FIRST_RUN_KEY, '1'); } catch { /* ignore */ }
|
|
427
437
|
bustCache('/api/runs?limit=12');
|
|
428
438
|
bustCache('/api/events');
|
|
429
439
|
setTimeout(load, 900);
|
|
@@ -431,7 +441,7 @@ function renderFirstRunHero() {
|
|
|
431
441
|
setFirstRunStatus(result.error || 'Run failed to queue.', 'bad');
|
|
432
442
|
if (button) {
|
|
433
443
|
button.disabled = false;
|
|
434
|
-
button.textContent = 'Run goal';
|
|
444
|
+
button.textContent = 'Run first goal';
|
|
435
445
|
}
|
|
436
446
|
}
|
|
437
447
|
});
|
|
@@ -508,6 +518,21 @@ function buildKanbanCols() {
|
|
|
508
518
|
if (sg) cols[sg].push({id:w.id||w.workerId||w.goal,goal:w.goal||w.task||w.approach||'(worker)',status:st,tokens:w.tokensUsed||w.budget,time:w.startedAt||w.createdAt,role:w.role});
|
|
509
519
|
}
|
|
510
520
|
}
|
|
521
|
+
const ghost = S.lastDecomposition?.autoGhostPass || S.lastCompletion?.autoGhostPass || op?.orchestration?.autoGhostPass || op?.autoGhostPass;
|
|
522
|
+
if (ghost && (ghost.applied || ghost.policy?.reason)) {
|
|
523
|
+
const risks = Array.isArray(ghost.riskAreas) ? ghost.riskAreas.length : 0;
|
|
524
|
+
const reason = ghost.policy?.reason ? ` · ${ghost.policy.reason}` : '';
|
|
525
|
+
cols.ghostpass.push({
|
|
526
|
+
id: 'auto-ghostpass',
|
|
527
|
+
goal: ghost.applied
|
|
528
|
+
? `Auto Ghost Pass: ${risks} risk area${risks === 1 ? '' : 's'}, ${ghost.workerApproaches || 0} approach${ghost.workerApproaches === 1 ? '' : 'es'}`
|
|
529
|
+
: `Auto Ghost Pass skipped${reason}`,
|
|
530
|
+
status: ghost.applied ? 'reviewing' : 'skipped',
|
|
531
|
+
tokens: ghost.estimatedTokens,
|
|
532
|
+
time: S.lastDecomposition?.ts || S.lastCompletion?.ts,
|
|
533
|
+
role: 'ghost-pass',
|
|
534
|
+
});
|
|
535
|
+
}
|
|
511
536
|
for (const r of (S.runs||[]).slice(0,8)) {
|
|
512
537
|
const runId = r.runId || r.id;
|
|
513
538
|
if (!runId) continue;
|
|
@@ -874,11 +899,16 @@ function renderOrchestrationPipeline() {
|
|
|
874
899
|
const more = arr.length > 6 ? ` <span style="color:var(--muted)">+${arr.length - 6}</span>` : '';
|
|
875
900
|
return `<div style="margin:4px 0"><span style="color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:0.5px">${esc(label)}</span> <span style="font-family:var(--font-mono);font-size:12px">${head}${more}</span></div>`;
|
|
876
901
|
};
|
|
902
|
+
const ghostChip = (ghost) => ghost
|
|
903
|
+
? chip('ghost-pass', ghost.applied
|
|
904
|
+
? `${ghost.riskAreas?.length ?? 0} risks · ${ghost.workerApproaches ?? 0} approaches`
|
|
905
|
+
: `skipped${ghost.policy?.reason ? ` · ${ghost.policy.reason}` : ''}`)
|
|
906
|
+
: '';
|
|
877
907
|
const decBlock = dec ? `
|
|
878
908
|
<div style="border-left:3px solid var(--accent);padding:8px 12px;margin-bottom:8px">
|
|
879
909
|
<div style="font-size:13px;font-weight:600;margin-bottom:4px">Decomposition · run ${esc((dec.runId || '').slice(-8))}</div>
|
|
880
910
|
<div style="font-size:12px;color:var(--muted);margin-bottom:6px">${esc(dec.goal || '')}</div>
|
|
881
|
-
<div>${chip('intent', dec.intent || 'auto')}${chip('crew', dec.crew || 'baseline')}${chip('workers', dec.workers ?? 0)}${chip('phases', dec.phases ?? 0)}</div>
|
|
911
|
+
<div>${chip('intent', dec.intent || 'auto')}${chip('crew', dec.crew || 'baseline')}${chip('workers', dec.workers ?? 0)}${chip('phases', dec.phases ?? 0)}${ghostChip(dec.autoGhostPass)}</div>
|
|
882
912
|
${chipList('specialists', dec.specialists)}
|
|
883
913
|
${chipList('skills', dec.skills)}
|
|
884
914
|
${chipList('files', dec.files)}
|
|
@@ -888,7 +918,7 @@ function renderOrchestrationPipeline() {
|
|
|
888
918
|
<div style="border-left:3px solid ${stateColor(cmpState)};padding:8px 12px">
|
|
889
919
|
<div style="font-size:13px;font-weight:600;margin-bottom:4px">Completion · run ${esc((cmp.runId || '').slice(-8))} · <span style="color:${stateColor(cmpState)}">${esc(cmpState || '')}</span></div>
|
|
890
920
|
<div style="font-size:12px;color:var(--muted);margin-bottom:6px">${esc(cmp.result || '')}</div>
|
|
891
|
-
<div>${chip('verified', `${cmp.verifiedWorkers ?? 0}/${cmp.totalWorkers ?? 0}`)}${chip('saved', `${fmtNum(cmp.savedTokens ?? 0)} t`)}${chip('compression', `${cmp.compressionPct ?? 0}%`)}${chip('duration', `${Math.round((cmp.durationMs ?? 0) / 100) / 10}s`)}</div>
|
|
921
|
+
<div>${chip('verified', `${cmp.verifiedWorkers ?? 0}/${cmp.totalWorkers ?? 0}`)}${chip('saved', `${fmtNum(cmp.savedTokens ?? 0)} t`)}${chip('compression', `${cmp.compressionPct ?? 0}%`)}${chip('duration', `${Math.round((cmp.durationMs ?? 0) / 100) / 10}s`)}${ghostChip(cmp.autoGhostPass)}</div>
|
|
892
922
|
</div>` : '';
|
|
893
923
|
const spineBlock = spine ? _buildDecisionSpineMiniHtml(spine) : '';
|
|
894
924
|
const headerNote = same ? '' : (dec && cmp ? '<div style="font-size:11px;color:var(--muted);margin-bottom:6px">Showing latest decomposition + most recent completion (different runs)</div>' : '');
|
|
@@ -57,10 +57,20 @@ export function render(data) {
|
|
|
57
57
|
const synapseHealth = Array.isArray(data.synapseHealth) ? data.synapseHealth : [];
|
|
58
58
|
const approvals = Array.isArray(data.synapseApprovals) ? data.synapseApprovals : [];
|
|
59
59
|
const escalations = Array.isArray(data.architectsEscalations) ? data.architectsEscalations : [];
|
|
60
|
+
const nexusProof = data.nexusProof ?? {};
|
|
60
61
|
|
|
61
62
|
container.innerHTML = `
|
|
62
63
|
<div class="trust-grid">
|
|
63
64
|
|
|
65
|
+
<!-- Nexus Prime proof card -->
|
|
66
|
+
<div class="card trust-card trust-card-wide">
|
|
67
|
+
<div class="trust-card-hd">
|
|
68
|
+
<span class="trust-card-title">Nexus Prime proof</span>
|
|
69
|
+
<span class="chip ${nexusProof.status === 'verified' ? 'chip-ok' : nexusProof.status === 'failed' ? 'chip-bad' : 'chip-warn'}">${esc(nexusProof.status ?? 'unknown')}</span>
|
|
70
|
+
</div>
|
|
71
|
+
${_nexusProofSection(nexusProof)}
|
|
72
|
+
</div>
|
|
73
|
+
|
|
64
74
|
<!-- Security posture card -->
|
|
65
75
|
<div class="card trust-card">
|
|
66
76
|
<div class="trust-card-hd">
|
|
@@ -188,6 +198,37 @@ function _postureRows(gov) {
|
|
|
188
198
|
).join('');
|
|
189
199
|
}
|
|
190
200
|
|
|
201
|
+
function _nexusProofSection(proof) {
|
|
202
|
+
const telemetry = proof.telemetry ?? {};
|
|
203
|
+
const totals = telemetry.localTotals ?? {};
|
|
204
|
+
const checks = Array.isArray(proof.checks) ? proof.checks : [];
|
|
205
|
+
const events = Array.isArray(proof.proofEvents) ? proof.proofEvents : [];
|
|
206
|
+
return `
|
|
207
|
+
<div class="trust-posture-body">
|
|
208
|
+
<div class="trust-row"><span class="trust-row-k">Website</span><span class="trust-row-v">${esc(proof.website ?? 'https://nexus-prime.cfd/')}</span></div>
|
|
209
|
+
<div class="trust-row"><span class="trust-row-k">Checks</span><span class="trust-row-v">${esc(`${proof.passed ?? 0} passed · ${proof.warnings ?? 0} warning(s) · ${proof.failed ?? 0} failed`)}</span></div>
|
|
210
|
+
<div class="trust-row"><span class="trust-row-k">Telemetry</span><span class="trust-row-v">${telemetry.optedIn ? 'opted in' : 'off'} · ${telemetry.endpointConfigured ? 'endpoint ready' : 'local only'}</span></div>
|
|
211
|
+
<div class="trust-row"><span class="trust-row-k">Proof events</span><span class="trust-row-v">${esc(`${totals.prPresence ?? 0} PR · ${totals.commitAttributions ?? 0} commit · ${totals.documentsSigned ?? 0} doc · ${totals.releasesVerified ?? 0} release`)}</span></div>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="trust-event-list" style="margin-top:10px">
|
|
214
|
+
${checks.slice(0, 6).map(check => _proofCheckRow(check)).join('')}
|
|
215
|
+
</div>
|
|
216
|
+
<div class="empty-sub" style="margin-top:8px">${esc(events.slice(0, 6).join(' · '))}</div>
|
|
217
|
+
`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function _proofCheckRow(check) {
|
|
221
|
+
const chip = check.status === 'pass' ? 'chip-ok' : check.status === 'fail' ? 'chip-bad' : 'chip-warn';
|
|
222
|
+
return `
|
|
223
|
+
<div class="trust-event-row">
|
|
224
|
+
<div class="trust-event-main">
|
|
225
|
+
<span class="chip ${chip}">${esc(check.status ?? 'unknown')}</span>
|
|
226
|
+
<span class="trust-event-type">${esc(check.label ?? check.id ?? 'proof check')}</span>
|
|
227
|
+
${check.detail ? `<span style="color:var(--text-muted);font-size:var(--text-sm)">${esc(String(check.detail).slice(0, 110))}</span>` : ''}
|
|
228
|
+
</div>
|
|
229
|
+
</div>`;
|
|
230
|
+
}
|
|
231
|
+
|
|
191
232
|
function _auditRow(e, idx) {
|
|
192
233
|
return `
|
|
193
234
|
<div class="trust-event-row">
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { getSharedGovernor } from '../../engines/machine-efficiency/index.js';
|
|
2
|
+
import { verifyNexusProof } from '../../engines/nexus-proof.js';
|
|
3
|
+
import { getSharedTelemetry } from '../../engines/telemetry-remote.js';
|
|
2
4
|
import { serializeMemoryAudit, serializeMemoryQuarantine } from '../serializers/memory-serializer.js';
|
|
3
5
|
import { collectDashboardBaseState } from './summary-selector.js';
|
|
4
6
|
export async function buildTrustSurface(ctx, url) {
|
|
@@ -7,6 +9,8 @@ export async function buildTrustSurface(ctx, url) {
|
|
|
7
9
|
const governorState = governor.getState();
|
|
8
10
|
const synapseTeams = ctx.getSynapse()?.getStrikeTeamStatus?.();
|
|
9
11
|
const synapseHealth = ctx.getSynapse()?.getOperativeHealth?.();
|
|
12
|
+
const telemetryStats = getSharedTelemetry().getStats();
|
|
13
|
+
const proofSummary = await verifyNexusProof({ repoRoot: ctx.repoRoot });
|
|
10
14
|
return {
|
|
11
15
|
repoIdentity: state.snapshot?.repoIdentity ?? ctx.getSelectedRepoIdentity(url),
|
|
12
16
|
usage: state.usage,
|
|
@@ -29,6 +33,22 @@ export async function buildTrustSurface(ctx, url) {
|
|
|
29
33
|
: ctx.getClientRegistry()?.listClients(ctx.getAdapters()) ?? [],
|
|
30
34
|
primaryClient: state.snapshot?.clients?.primary ?? ctx.getClientRegistry()?.getPrimaryClient(ctx.getAdapters()) ?? null,
|
|
31
35
|
nexusLayer: state.layer?.getSummary(state.snapshot?.orchestration?.sessionId) ?? null,
|
|
36
|
+
nexusProof: {
|
|
37
|
+
...proofSummary,
|
|
38
|
+
telemetry: {
|
|
39
|
+
optedIn: telemetryStats.optedIn,
|
|
40
|
+
queuedEvents: telemetryStats.queuedEvents,
|
|
41
|
+
endpointConfigured: telemetryStats.endpointConfigured,
|
|
42
|
+
remoteStatsConfigured: telemetryStats.remoteStatsConfigured,
|
|
43
|
+
localTotals: {
|
|
44
|
+
prPresence: telemetryStats.totalPrPresence,
|
|
45
|
+
commitAttributions: telemetryStats.totalCommitAttributions,
|
|
46
|
+
documentsSigned: telemetryStats.totalDocumentsSigned,
|
|
47
|
+
releasesVerified: telemetryStats.totalReleasesVerified,
|
|
48
|
+
proofBadgeViews: telemetryStats.totalProofBadgeViews,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
32
52
|
machinePressure: governorState.pressureLevel,
|
|
33
53
|
activeWorktrees: governorState.activeWorktrees,
|
|
34
54
|
governor: governorState,
|
|
@@ -93,6 +93,16 @@ export interface NexusEventPayloads {
|
|
|
93
93
|
files: string[];
|
|
94
94
|
workers: number;
|
|
95
95
|
phases: number;
|
|
96
|
+
autoGhostPass?: {
|
|
97
|
+
applied: boolean;
|
|
98
|
+
riskAreas: string[];
|
|
99
|
+
workerApproaches: number;
|
|
100
|
+
estimatedTokens: number;
|
|
101
|
+
policy?: {
|
|
102
|
+
enabled?: boolean;
|
|
103
|
+
reason?: string;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
96
106
|
};
|
|
97
107
|
'orchestration.completed': {
|
|
98
108
|
runId: string;
|
|
@@ -104,6 +114,12 @@ export interface NexusEventPayloads {
|
|
|
104
114
|
compressionPct: number;
|
|
105
115
|
durationMs: number;
|
|
106
116
|
result: string;
|
|
117
|
+
autoGhostPass?: {
|
|
118
|
+
applied: boolean;
|
|
119
|
+
riskAreas: string[];
|
|
120
|
+
workerApproaches: number;
|
|
121
|
+
estimatedTokens: number;
|
|
122
|
+
};
|
|
107
123
|
};
|
|
108
124
|
'session.summaryBootstrap': {
|
|
109
125
|
originalTokens: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type RemoteTelemetry } from './telemetry-remote.js';
|
|
1
2
|
export interface GithubBridgeDetection {
|
|
2
3
|
available: boolean;
|
|
3
4
|
method: 'gh-cli' | 'token' | 'none';
|
|
@@ -21,7 +22,8 @@ export interface GithubPromotionResult {
|
|
|
21
22
|
}
|
|
22
23
|
export declare class GithubBridge {
|
|
23
24
|
private readonly defaultCwd;
|
|
24
|
-
|
|
25
|
+
private readonly telemetry?;
|
|
26
|
+
constructor(defaultCwd?: string, telemetry?: Pick<RemoteTelemetry, 'trackProductEvent'>);
|
|
25
27
|
detect(cwd?: string): GithubBridgeDetection;
|
|
26
28
|
promoteToPR(input: GithubPromotionInput): Promise<GithubPromotionResult>;
|
|
27
29
|
private createPullRequestViaApi;
|
|
@@ -29,6 +31,7 @@ export declare class GithubBridge {
|
|
|
29
31
|
private resolveRepo;
|
|
30
32
|
private detectBaseBranch;
|
|
31
33
|
private buildBranchName;
|
|
34
|
+
private renderCommitBody;
|
|
32
35
|
private renderPrBody;
|
|
33
36
|
private safeExec;
|
|
34
37
|
shareAsGist(pattern: {
|
|
@@ -40,5 +43,7 @@ export declare class GithubBridge {
|
|
|
40
43
|
localPath?: string;
|
|
41
44
|
}>;
|
|
42
45
|
private shellQuote;
|
|
46
|
+
private telemetryConsentLabel;
|
|
47
|
+
private trackProductEvent;
|
|
43
48
|
}
|
|
44
49
|
export declare function getSharedGithubBridge(cwd?: string): GithubBridge;
|
|
@@ -3,10 +3,14 @@ import * as path from 'path';
|
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import { createHash } from 'crypto';
|
|
5
5
|
import { resolveNexusStateDir } from './runtime-registry.js';
|
|
6
|
+
import { appendOrReplaceNexusPrPresenceBlock, buildNexusProofMetadata, ensureNexusCoauthorTrailer, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_WEBSITE, renderNexusDocumentSignature, renderNexusPrPresenceBlock, } from './nexus-signature.js';
|
|
7
|
+
import { getSharedTelemetry } from './telemetry-remote.js';
|
|
6
8
|
export class GithubBridge {
|
|
7
9
|
defaultCwd;
|
|
8
|
-
|
|
10
|
+
telemetry;
|
|
11
|
+
constructor(defaultCwd = process.cwd(), telemetry) {
|
|
9
12
|
this.defaultCwd = defaultCwd;
|
|
13
|
+
this.telemetry = telemetry;
|
|
10
14
|
}
|
|
11
15
|
detect(cwd = this.defaultCwd) {
|
|
12
16
|
try {
|
|
@@ -42,20 +46,34 @@ export class GithubBridge {
|
|
|
42
46
|
this.safeExec(`git checkout -b ${this.shellQuote(branch)}`, cwd, true);
|
|
43
47
|
this.safeExec('git add -A', cwd, true);
|
|
44
48
|
const subject = `[NOVA] Promote Darwin cycle ${input.cycleId ?? 'candidate'} to the fleet`;
|
|
45
|
-
const body =
|
|
46
|
-
'The autonomous engine marked this bounded improvement worthy of review.',
|
|
47
|
-
`Hypothesis: ${input.hypothesis}`,
|
|
48
|
-
...(input.learnings?.length ? [`Learnings: ${input.learnings.join('; ')}`] : []),
|
|
49
|
-
].join('\n\n');
|
|
49
|
+
const body = ensureNexusCoauthorTrailer(this.renderCommitBody(input), true);
|
|
50
50
|
this.safeExec(`git commit -m ${this.shellQuote(subject)} -m ${this.shellQuote(body)}`, cwd, true);
|
|
51
|
+
this.trackProductEvent('commit_attributed', {
|
|
52
|
+
surface: 'git_commit',
|
|
53
|
+
role: 'published',
|
|
54
|
+
method: detection.method,
|
|
55
|
+
attribution: 'coauthor_trailer',
|
|
56
|
+
});
|
|
51
57
|
this.safeExec(`git push -u origin ${this.shellQuote(branch)}`, cwd, true);
|
|
52
58
|
if (detection.method === 'gh-cli') {
|
|
53
59
|
const title = `Darwin: ${input.hypothesis}`.slice(0, 72);
|
|
54
60
|
const prBody = this.renderPrBody(input, diffSummary, baseBranch);
|
|
55
61
|
const url = this.safeExec(`gh pr create --base ${this.shellQuote(baseBranch)} --head ${this.shellQuote(branch)} --title ${this.shellQuote(title)} --body ${this.shellQuote(prBody)}`, cwd, true).trim();
|
|
62
|
+
this.trackProductEvent('pr_presence_added', {
|
|
63
|
+
surface: 'pull_request',
|
|
64
|
+
role: 'published',
|
|
65
|
+
method: detection.method,
|
|
66
|
+
verification: 'local_diff_captured',
|
|
67
|
+
});
|
|
56
68
|
return { status: 'pr_created', method: detection.method, branch, url };
|
|
57
69
|
}
|
|
58
70
|
const url = await this.createPullRequestViaApi(repo.owner, repo.name, branch, baseBranch, input, diffSummary);
|
|
71
|
+
this.trackProductEvent('pr_presence_added', {
|
|
72
|
+
surface: 'pull_request',
|
|
73
|
+
role: 'published',
|
|
74
|
+
method: detection.method,
|
|
75
|
+
verification: 'local_diff_captured',
|
|
76
|
+
});
|
|
59
77
|
return { status: 'pr_created', method: detection.method, branch, url };
|
|
60
78
|
}
|
|
61
79
|
catch (error) {
|
|
@@ -100,6 +118,21 @@ export class GithubBridge {
|
|
|
100
118
|
.slice(0, 10);
|
|
101
119
|
const patchPath = path.join(stateDir, `darwin-${slug}.patch`);
|
|
102
120
|
const artifactPath = path.join(stateDir, `darwin-${slug}.json`);
|
|
121
|
+
const signatureInput = {
|
|
122
|
+
source: 'github-bridge',
|
|
123
|
+
role: 'observed',
|
|
124
|
+
runId: input.cycleId,
|
|
125
|
+
cycleId: input.cycleId,
|
|
126
|
+
verificationState: diffPatch.trim() ? 'advisory' : 'not-run',
|
|
127
|
+
hooksState: 'not-applicable',
|
|
128
|
+
telemetryConsent: this.telemetryConsentLabel(),
|
|
129
|
+
humanReviewState: 'required',
|
|
130
|
+
coauthorState: 'Not claimed because no GitHub PR was created.',
|
|
131
|
+
};
|
|
132
|
+
const documentSignature = renderNexusDocumentSignature({
|
|
133
|
+
...signatureInput,
|
|
134
|
+
artifactKind: 'GitHub promotion artifact',
|
|
135
|
+
});
|
|
103
136
|
fs.writeFileSync(patchPath, diffPatch, 'utf8');
|
|
104
137
|
fs.writeFileSync(artifactPath, JSON.stringify({
|
|
105
138
|
createdAt: new Date().toISOString(),
|
|
@@ -111,7 +144,20 @@ export class GithubBridge {
|
|
|
111
144
|
learnings: input.learnings ?? [],
|
|
112
145
|
diffSummary,
|
|
113
146
|
patchPath,
|
|
147
|
+
nexusPrime: {
|
|
148
|
+
website: NEXUS_PRIME_WEBSITE,
|
|
149
|
+
coauthorTrailer: NEXUS_PRIME_COAUTHOR_TRAILER,
|
|
150
|
+
prPresence: renderNexusPrPresenceBlock(signatureInput),
|
|
151
|
+
documentSignature,
|
|
152
|
+
metadata: buildNexusProofMetadata(signatureInput),
|
|
153
|
+
},
|
|
114
154
|
}, null, 2), 'utf8');
|
|
155
|
+
this.trackProductEvent('document_signed', {
|
|
156
|
+
surface: 'github_promotion_artifact',
|
|
157
|
+
role: 'observed',
|
|
158
|
+
method,
|
|
159
|
+
status: 'artifact_saved',
|
|
160
|
+
});
|
|
115
161
|
return {
|
|
116
162
|
status: 'artifact_saved',
|
|
117
163
|
method,
|
|
@@ -140,8 +186,15 @@ export class GithubBridge {
|
|
|
140
186
|
.slice(0, 48);
|
|
141
187
|
return `ad/${seed || 'darwin-candidate'}`;
|
|
142
188
|
}
|
|
143
|
-
|
|
189
|
+
renderCommitBody(input) {
|
|
144
190
|
return [
|
|
191
|
+
'The autonomous engine marked this bounded improvement worthy of review.',
|
|
192
|
+
`Hypothesis: ${input.hypothesis}`,
|
|
193
|
+
...(input.learnings?.length ? [`Learnings: ${input.learnings.join('; ')}`] : []),
|
|
194
|
+
].join('\n\n');
|
|
195
|
+
}
|
|
196
|
+
renderPrBody(input, diffSummary, baseBranch) {
|
|
197
|
+
const body = [
|
|
145
198
|
'### Mission Briefing',
|
|
146
199
|
'A bounded Darwin candidate completed local validation and now seeks human review through the standard GitHub path.',
|
|
147
200
|
'',
|
|
@@ -159,6 +212,17 @@ export class GithubBridge {
|
|
|
159
212
|
diffSummary.trim() || 'No diff summary available.',
|
|
160
213
|
'```',
|
|
161
214
|
].join('\n');
|
|
215
|
+
return appendOrReplaceNexusPrPresenceBlock(body, {
|
|
216
|
+
source: 'github-bridge',
|
|
217
|
+
role: 'published',
|
|
218
|
+
runId: input.cycleId,
|
|
219
|
+
cycleId: input.cycleId,
|
|
220
|
+
verificationState: diffSummary.trim() ? 'advisory' : 'unknown',
|
|
221
|
+
hooksState: 'unknown',
|
|
222
|
+
telemetryConsent: this.telemetryConsentLabel(),
|
|
223
|
+
humanReviewState: 'required',
|
|
224
|
+
coauthorState: 'Required on the Nexus-generated promotion commit.',
|
|
225
|
+
});
|
|
162
226
|
}
|
|
163
227
|
safeExec(command, cwd, throwOnError = false) {
|
|
164
228
|
try {
|
|
@@ -233,6 +297,26 @@ export class GithubBridge {
|
|
|
233
297
|
shellQuote(value) {
|
|
234
298
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
235
299
|
}
|
|
300
|
+
telemetryConsentLabel() {
|
|
301
|
+
try {
|
|
302
|
+
const telemetry = this.telemetry ?? getSharedTelemetry();
|
|
303
|
+
return telemetry instanceof Object && 'isOptedIn' in telemetry && typeof telemetry.isOptedIn === 'function'
|
|
304
|
+
? (telemetry.isOptedIn() ? 'opted-in' : 'disabled')
|
|
305
|
+
: 'unknown';
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
return 'unknown';
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
trackProductEvent(type, metadata) {
|
|
312
|
+
try {
|
|
313
|
+
const telemetry = this.telemetry ?? getSharedTelemetry();
|
|
314
|
+
telemetry.trackProductEvent(type, metadata);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
// Telemetry must never block promotion or artifact persistence.
|
|
318
|
+
}
|
|
319
|
+
}
|
|
236
320
|
}
|
|
237
321
|
let _sharedGithubBridge = null;
|
|
238
322
|
export function getSharedGithubBridge(cwd) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type NexusProofCheckStatus = 'pass' | 'warn' | 'fail';
|
|
2
|
+
export interface NexusProofCheck {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
status: NexusProofCheckStatus;
|
|
6
|
+
detail: string;
|
|
7
|
+
evidence?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface NexusProofVerifyOptions {
|
|
10
|
+
repoRoot?: string;
|
|
11
|
+
prBodyPath?: string;
|
|
12
|
+
commitMessagePath?: string;
|
|
13
|
+
artifactPaths?: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface NexusProofSummary {
|
|
16
|
+
generatedAt: number;
|
|
17
|
+
website: string;
|
|
18
|
+
status: 'verified' | 'attention' | 'failed';
|
|
19
|
+
passed: number;
|
|
20
|
+
warnings: number;
|
|
21
|
+
failed: number;
|
|
22
|
+
checks: NexusProofCheck[];
|
|
23
|
+
proofEvents: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
export declare function verifyNexusProof(options?: NexusProofVerifyOptions): Promise<NexusProofSummary>;
|
|
26
|
+
export declare function formatNexusProofReport(summary: NexusProofSummary): string;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { NEXUS_PLG_EVENT_TYPES, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_PRESENCE_END, NEXUS_PRIME_PRESENCE_START, NEXUS_PRIME_WEBSITE, } from './nexus-signature.js';
|
|
4
|
+
async function readOptional(filePath) {
|
|
5
|
+
if (!filePath)
|
|
6
|
+
return null;
|
|
7
|
+
try {
|
|
8
|
+
return await fs.readFile(filePath, 'utf8');
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function addCheck(checks, id, label, status, detail, evidence) {
|
|
15
|
+
checks.push({ id, label, status, detail, evidence });
|
|
16
|
+
}
|
|
17
|
+
function hasPresenceBlock(value) {
|
|
18
|
+
return value.includes(NEXUS_PRIME_PRESENCE_START) && value.includes(NEXUS_PRIME_PRESENCE_END);
|
|
19
|
+
}
|
|
20
|
+
export async function verifyNexusProof(options = {}) {
|
|
21
|
+
const repoRoot = options.repoRoot ?? process.cwd();
|
|
22
|
+
const checks = [];
|
|
23
|
+
const prTemplatePath = path.join(repoRoot, '.github', 'pull_request_template.md');
|
|
24
|
+
const readmePath = path.join(repoRoot, 'README.md');
|
|
25
|
+
const telemetryPath = path.join(repoRoot, 'src', 'engines', 'telemetry-remote.ts');
|
|
26
|
+
addCheck(checks, 'website.identity', 'Website identity', NEXUS_PRIME_WEBSITE === 'https://nexus-prime.cfd/' ? 'pass' : 'fail', `Expected canonical website https://nexus-prime.cfd/, got ${NEXUS_PRIME_WEBSITE}`, NEXUS_PRIME_WEBSITE);
|
|
27
|
+
const prTemplate = await readOptional(prTemplatePath);
|
|
28
|
+
if (!prTemplate) {
|
|
29
|
+
addCheck(checks, 'pr.template', 'PR template presence', 'warn', 'No .github/pull_request_template.md found.');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const ok = hasPresenceBlock(prTemplate) && prTemplate.includes(NEXUS_PRIME_WEBSITE);
|
|
33
|
+
addCheck(checks, 'pr.template', 'PR template presence', ok ? 'pass' : 'fail', ok
|
|
34
|
+
? 'Pull request template contains Nexus Prime Presence and website identity.'
|
|
35
|
+
: 'Pull request template must include Nexus Prime Presence markers and website identity.', prTemplatePath);
|
|
36
|
+
}
|
|
37
|
+
const readme = await readOptional(readmePath);
|
|
38
|
+
if (!readme) {
|
|
39
|
+
addCheck(checks, 'docs.provenance', 'README provenance copy', 'warn', 'No README.md found.');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const ok = readme.includes('Provenance and social proof')
|
|
43
|
+
&& readme.includes('Nexus Prime Presence')
|
|
44
|
+
&& readme.includes('privacy-safe PLG events')
|
|
45
|
+
&& readme.includes(NEXUS_PRIME_WEBSITE);
|
|
46
|
+
addCheck(checks, 'docs.provenance', 'README provenance copy', ok ? 'pass' : 'fail', ok
|
|
47
|
+
? 'README explains Nexus Prime signatures, attribution, telemetry, and social proof.'
|
|
48
|
+
: 'README must explain Nexus Prime Presence, attribution, privacy-safe PLG events, and the website.', readmePath);
|
|
49
|
+
}
|
|
50
|
+
const telemetry = await readOptional(telemetryPath);
|
|
51
|
+
if (!telemetry) {
|
|
52
|
+
addCheck(checks, 'telemetry.redaction', 'Telemetry redaction guard', 'warn', 'Telemetry source was not found.');
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const redactionPattern = String.raw `prompt|content|code|path|repo|branch|secret|token|file`;
|
|
56
|
+
const hasRedaction = telemetry.includes(redactionPattern)
|
|
57
|
+
&& telemetry.includes('sanitizeEventData')
|
|
58
|
+
&& telemetry.includes('trackProductEvent');
|
|
59
|
+
addCheck(checks, 'telemetry.redaction', 'Telemetry redaction guard', hasRedaction ? 'pass' : 'fail', hasRedaction
|
|
60
|
+
? 'Proof telemetry is routed through the sanitizer and blocks sensitive key classes.'
|
|
61
|
+
: 'Proof telemetry must keep using sanitizeEventData and block prompt/code/path/repo/branch/secret/token/file keys.', telemetryPath);
|
|
62
|
+
}
|
|
63
|
+
const prBody = await readOptional(options.prBodyPath);
|
|
64
|
+
if (options.prBodyPath) {
|
|
65
|
+
const ok = Boolean(prBody && hasPresenceBlock(prBody) && prBody.includes(NEXUS_PRIME_WEBSITE));
|
|
66
|
+
addCheck(checks, 'pr.body', 'PR body proof', ok ? 'pass' : 'fail', ok ? 'PR body contains Nexus Prime Presence.' : 'PR body is missing Nexus Prime Presence.', options.prBodyPath);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
addCheck(checks, 'pr.body', 'PR body proof', 'warn', 'No PR body path supplied; skipping generated PR body verification.');
|
|
70
|
+
}
|
|
71
|
+
const commitMessage = await readOptional(options.commitMessagePath);
|
|
72
|
+
if (options.commitMessagePath) {
|
|
73
|
+
const ok = Boolean(commitMessage && commitMessage.includes(NEXUS_PRIME_COAUTHOR_TRAILER));
|
|
74
|
+
addCheck(checks, 'commit.coauthor', 'Generated commit co-author trailer', ok ? 'pass' : 'fail', ok ? 'Commit message contains the Nexus Prime co-author trailer.' : 'Generated commit message is missing the Nexus Prime co-author trailer.', options.commitMessagePath);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
addCheck(checks, 'commit.coauthor', 'Generated commit co-author trailer', 'warn', 'No commit message path supplied; skipping generated commit verification.');
|
|
78
|
+
}
|
|
79
|
+
const artifactPaths = options.artifactPaths ?? [];
|
|
80
|
+
if (artifactPaths.length === 0) {
|
|
81
|
+
addCheck(checks, 'artifact.signature', 'Generated artifact signatures', 'warn', 'No artifact paths supplied; skipping artifact signature verification.');
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
for (const artifactPath of artifactPaths) {
|
|
85
|
+
const artifact = await readOptional(artifactPath);
|
|
86
|
+
const ok = Boolean(artifact && artifact.includes('signed by Nexus Prime') && artifact.includes(NEXUS_PRIME_WEBSITE));
|
|
87
|
+
addCheck(checks, `artifact.signature:${path.basename(artifactPath)}`, 'Generated artifact signature', ok ? 'pass' : 'fail', ok ? 'Artifact contains a Nexus Prime document signature.' : 'Artifact is missing a Nexus Prime document signature.', artifactPath);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const passed = checks.filter((check) => check.status === 'pass').length;
|
|
91
|
+
const warnings = checks.filter((check) => check.status === 'warn').length;
|
|
92
|
+
const failed = checks.filter((check) => check.status === 'fail').length;
|
|
93
|
+
const status = failed > 0 ? 'failed' : warnings > 0 ? 'attention' : 'verified';
|
|
94
|
+
return {
|
|
95
|
+
generatedAt: Date.now(),
|
|
96
|
+
website: NEXUS_PRIME_WEBSITE,
|
|
97
|
+
status,
|
|
98
|
+
passed,
|
|
99
|
+
warnings,
|
|
100
|
+
failed,
|
|
101
|
+
checks,
|
|
102
|
+
proofEvents: NEXUS_PLG_EVENT_TYPES,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function formatNexusProofReport(summary) {
|
|
106
|
+
const lines = [
|
|
107
|
+
'Nexus Prime proof verification',
|
|
108
|
+
`Website: ${summary.website}`,
|
|
109
|
+
`Status: ${summary.status}`,
|
|
110
|
+
`Checks: ${summary.passed} passed, ${summary.warnings} warning(s), ${summary.failed} failed`,
|
|
111
|
+
'',
|
|
112
|
+
];
|
|
113
|
+
for (const check of summary.checks) {
|
|
114
|
+
const marker = check.status === 'pass' ? 'PASS' : check.status === 'warn' ? 'WARN' : 'FAIL';
|
|
115
|
+
lines.push(`[${marker}] ${check.label}: ${check.detail}`);
|
|
116
|
+
}
|
|
117
|
+
return lines.join('\n');
|
|
118
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const NEXUS_PRIME_WEBSITE = "https://nexus-prime.cfd/";
|
|
2
|
+
export declare const NEXUS_PRIME_GENERATOR = "Nexus Prime";
|
|
3
|
+
export declare const NEXUS_PRIME_COAUTHOR_TRAILER = "Co-Authored-By: nexus-prime <33547839+sir-ad@users.noreply.github.com>";
|
|
4
|
+
export declare const NEXUS_PRIME_PRESENCE_START = "<!-- nexus-prime:presence:start -->";
|
|
5
|
+
export declare const NEXUS_PRIME_PRESENCE_END = "<!-- nexus-prime:presence:end -->";
|
|
6
|
+
export type NexusPresenceRole = 'observed' | 'verified' | 'assisted' | 'authored' | 'published';
|
|
7
|
+
export type NexusVerificationState = 'unknown' | 'not-run' | 'advisory' | 'verified' | 'failed';
|
|
8
|
+
export type NexusHumanReviewState = 'required' | 'pending' | 'completed' | 'not-required';
|
|
9
|
+
export type NexusPlgEventType = 'pr_presence_added' | 'commit_attributed' | 'document_signed' | 'release_verified' | 'proof_badge_viewed' | 'website_proof_viewed' | 'telemetry_batch_sent';
|
|
10
|
+
export declare const NEXUS_PLG_EVENT_TYPES: readonly NexusPlgEventType[];
|
|
11
|
+
export interface NexusPresenceInput {
|
|
12
|
+
role: NexusPresenceRole;
|
|
13
|
+
source: string;
|
|
14
|
+
runId?: string;
|
|
15
|
+
cycleId?: string;
|
|
16
|
+
verificationState?: NexusVerificationState | string;
|
|
17
|
+
hooksState?: string;
|
|
18
|
+
telemetryConsent?: string;
|
|
19
|
+
humanReviewState?: NexusHumanReviewState | string;
|
|
20
|
+
coauthorState?: string;
|
|
21
|
+
website?: string;
|
|
22
|
+
generatedAt?: Date | string;
|
|
23
|
+
}
|
|
24
|
+
export interface NexusDocumentSignatureInput extends NexusPresenceInput {
|
|
25
|
+
artifactKind?: string;
|
|
26
|
+
reviewer?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function renderNexusPrPresenceBlock(input: NexusPresenceInput): string;
|
|
29
|
+
export declare function appendOrReplaceNexusPrPresenceBlock(body: string, input: NexusPresenceInput): string;
|
|
30
|
+
export declare function ensureNexusCoauthorTrailer(message: string, shouldAttribute: boolean): string;
|
|
31
|
+
export declare function renderNexusDocumentSignature(input: NexusDocumentSignatureInput): string;
|
|
32
|
+
export declare function buildNexusProofMetadata(input: NexusPresenceInput): Record<string, string>;
|
|
33
|
+
export declare function renderNexusWebsiteMetadata(input: NexusPresenceInput): string;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export const NEXUS_PRIME_WEBSITE = 'https://nexus-prime.cfd/';
|
|
2
|
+
export const NEXUS_PRIME_GENERATOR = 'Nexus Prime';
|
|
3
|
+
export const NEXUS_PRIME_COAUTHOR_TRAILER = 'Co-Authored-By: nexus-prime <33547839+sir-ad@users.noreply.github.com>';
|
|
4
|
+
export const NEXUS_PRIME_PRESENCE_START = '<!-- nexus-prime:presence:start -->';
|
|
5
|
+
export const NEXUS_PRIME_PRESENCE_END = '<!-- nexus-prime:presence:end -->';
|
|
6
|
+
export const NEXUS_PLG_EVENT_TYPES = [
|
|
7
|
+
'pr_presence_added',
|
|
8
|
+
'commit_attributed',
|
|
9
|
+
'document_signed',
|
|
10
|
+
'release_verified',
|
|
11
|
+
'proof_badge_viewed',
|
|
12
|
+
'website_proof_viewed',
|
|
13
|
+
'telemetry_batch_sent',
|
|
14
|
+
];
|
|
15
|
+
function clean(value, fallback) {
|
|
16
|
+
const normalized = String(value ?? '').trim();
|
|
17
|
+
return normalized || fallback;
|
|
18
|
+
}
|
|
19
|
+
function isoStamp(value) {
|
|
20
|
+
if (value instanceof Date)
|
|
21
|
+
return value.toISOString();
|
|
22
|
+
if (typeof value === 'string' && value.trim())
|
|
23
|
+
return value.trim();
|
|
24
|
+
return new Date().toISOString();
|
|
25
|
+
}
|
|
26
|
+
export function renderNexusPrPresenceBlock(input) {
|
|
27
|
+
const website = clean(input.website, NEXUS_PRIME_WEBSITE);
|
|
28
|
+
const runId = clean(input.runId ?? input.cycleId, 'no-run detected');
|
|
29
|
+
const verification = clean(input.verificationState, 'unknown');
|
|
30
|
+
const hooks = clean(input.hooksState, 'unknown');
|
|
31
|
+
const telemetry = clean(input.telemetryConsent, 'unknown');
|
|
32
|
+
const humanReview = clean(input.humanReviewState, 'required');
|
|
33
|
+
const coauthor = clean(input.coauthorState, 'Not claimed unless a Nexus-generated commit includes the co-author trailer.');
|
|
34
|
+
return [
|
|
35
|
+
NEXUS_PRIME_PRESENCE_START,
|
|
36
|
+
'## Nexus Prime Presence',
|
|
37
|
+
'',
|
|
38
|
+
`- Website: ${website}`,
|
|
39
|
+
`- Role: ${input.role}`,
|
|
40
|
+
`- Source: ${clean(input.source, 'unknown')}`,
|
|
41
|
+
`- Run ID: ${runId}`,
|
|
42
|
+
`- Verification: ${verification}`,
|
|
43
|
+
`- Hooks: ${hooks}`,
|
|
44
|
+
`- Telemetry consent: ${telemetry}`,
|
|
45
|
+
`- Human review: ${humanReview}`,
|
|
46
|
+
`- Co-authorship: ${coauthor}`,
|
|
47
|
+
`- Generated at: ${isoStamp(input.generatedAt)}`,
|
|
48
|
+
'',
|
|
49
|
+
'Presence is not blanket authorship. Git co-authorship is only asserted for commits Nexus Prime generated, materially assisted, or published.',
|
|
50
|
+
NEXUS_PRIME_PRESENCE_END,
|
|
51
|
+
].join('\n');
|
|
52
|
+
}
|
|
53
|
+
export function appendOrReplaceNexusPrPresenceBlock(body, input) {
|
|
54
|
+
const block = renderNexusPrPresenceBlock(input);
|
|
55
|
+
const pattern = new RegExp(`${escapeRegExp(NEXUS_PRIME_PRESENCE_START)}[\\s\\S]*?${escapeRegExp(NEXUS_PRIME_PRESENCE_END)}`, 'm');
|
|
56
|
+
const existing = String(body ?? '').trim();
|
|
57
|
+
if (pattern.test(existing))
|
|
58
|
+
return existing.replace(pattern, block);
|
|
59
|
+
return [existing, block].filter(Boolean).join('\n\n');
|
|
60
|
+
}
|
|
61
|
+
export function ensureNexusCoauthorTrailer(message, shouldAttribute) {
|
|
62
|
+
const normalized = String(message ?? '').trimEnd();
|
|
63
|
+
if (!shouldAttribute)
|
|
64
|
+
return normalized;
|
|
65
|
+
if (normalized.includes(NEXUS_PRIME_COAUTHOR_TRAILER))
|
|
66
|
+
return normalized;
|
|
67
|
+
return [normalized, NEXUS_PRIME_COAUTHOR_TRAILER].filter(Boolean).join('\n\n');
|
|
68
|
+
}
|
|
69
|
+
export function renderNexusDocumentSignature(input) {
|
|
70
|
+
return [
|
|
71
|
+
'---',
|
|
72
|
+
`${clean(input.artifactKind, 'Artifact')} signed by ${NEXUS_PRIME_GENERATOR}`,
|
|
73
|
+
`Website: ${clean(input.website, NEXUS_PRIME_WEBSITE)}`,
|
|
74
|
+
`Role: ${input.role}`,
|
|
75
|
+
`Source: ${clean(input.source, 'unknown')}`,
|
|
76
|
+
`Run ID: ${clean(input.runId ?? input.cycleId, 'no-run detected')}`,
|
|
77
|
+
`Verification: ${clean(input.verificationState, 'unknown')}`,
|
|
78
|
+
`Human review: ${clean(input.humanReviewState, 'required')}`,
|
|
79
|
+
`Reviewer: ${clean(input.reviewer, 'not recorded')}`,
|
|
80
|
+
`Generated at: ${isoStamp(input.generatedAt)}`,
|
|
81
|
+
'---',
|
|
82
|
+
].join('\n');
|
|
83
|
+
}
|
|
84
|
+
export function buildNexusProofMetadata(input) {
|
|
85
|
+
return {
|
|
86
|
+
generator: NEXUS_PRIME_GENERATOR,
|
|
87
|
+
website: clean(input.website, NEXUS_PRIME_WEBSITE),
|
|
88
|
+
role: input.role,
|
|
89
|
+
source: clean(input.source, 'unknown'),
|
|
90
|
+
runId: clean(input.runId ?? input.cycleId, 'no-run detected'),
|
|
91
|
+
verificationState: clean(input.verificationState, 'unknown'),
|
|
92
|
+
humanReviewState: clean(input.humanReviewState, 'required'),
|
|
93
|
+
generatedAt: isoStamp(input.generatedAt),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function renderNexusWebsiteMetadata(input) {
|
|
97
|
+
const metadata = buildNexusProofMetadata(input);
|
|
98
|
+
const jsonLd = {
|
|
99
|
+
'@context': 'https://schema.org',
|
|
100
|
+
'@type': 'SoftwareApplication',
|
|
101
|
+
name: NEXUS_PRIME_GENERATOR,
|
|
102
|
+
url: metadata.website,
|
|
103
|
+
applicationCategory: 'DeveloperApplication',
|
|
104
|
+
creator: {
|
|
105
|
+
'@type': 'Organization',
|
|
106
|
+
name: NEXUS_PRIME_GENERATOR,
|
|
107
|
+
url: metadata.website,
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
return [
|
|
111
|
+
'<meta name="generator" content="Nexus Prime">',
|
|
112
|
+
`<meta name="nexus-prime:role" content="${escapeHtml(metadata.role)}">`,
|
|
113
|
+
`<meta name="nexus-prime:verification" content="${escapeHtml(metadata.verificationState)}">`,
|
|
114
|
+
`<link rel="author" href="${escapeHtml(metadata.website)}">`,
|
|
115
|
+
`<script type="application/ld+json">${JSON.stringify(jsonLd)}</script>`,
|
|
116
|
+
].join('\n');
|
|
117
|
+
}
|
|
118
|
+
function escapeRegExp(value) {
|
|
119
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
120
|
+
}
|
|
121
|
+
function escapeHtml(value) {
|
|
122
|
+
return value
|
|
123
|
+
.replace(/&/g, '&')
|
|
124
|
+
.replace(/"/g, '"')
|
|
125
|
+
.replace(/</g, '<')
|
|
126
|
+
.replace(/>/g, '>');
|
|
127
|
+
}
|
|
@@ -1036,7 +1036,7 @@ export class OrchestratorEngine {
|
|
|
1036
1036
|
// Non-fatal: bootstrap receipt is a safety net, not a hard dependency
|
|
1037
1037
|
}
|
|
1038
1038
|
const [army, prepared] = await this.runParallelPhases(this.induce(task), this._prepareExecution(task, options));
|
|
1039
|
-
const { intent, phases, primaryClient, bootstrapManifest, latestDNA, memoryMatches, memoryStats, candidateFiles, knowledgeFabric, plannedFiles, planner, selections, catalogHealth, tokenBudget, workerCount, mode, taskGraph, workerPlan, autoGhostPass, crSignals, } = prepared;
|
|
1039
|
+
const { intent, phases, primaryClient, bootstrapManifest, latestDNA, memoryMatches, memoryStats, candidateFiles, knowledgeFabric, plannedFiles, planner, selections, catalogHealth, tokenBudget, workerCount, mode, taskGraph, workerPlan, autoGhostPass, autoGhostPassDecision, crSignals, } = prepared;
|
|
1040
1040
|
this.runtime.recordClientToolCall('nexus_orchestrate', {
|
|
1041
1041
|
orchestrateCalled: true,
|
|
1042
1042
|
plannerCalled: true,
|
|
@@ -1314,6 +1314,8 @@ export class OrchestratorEngine {
|
|
|
1314
1314
|
instructionPacket,
|
|
1315
1315
|
executionLedger: ledger,
|
|
1316
1316
|
knowledgeFabric,
|
|
1317
|
+
autoGhostPass,
|
|
1318
|
+
autoGhostPassDecision,
|
|
1317
1319
|
});
|
|
1318
1320
|
this.executionDedupeStore.set(fingerprint, {
|
|
1319
1321
|
id: ledger.runId,
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* Sends pseudonymous install + project activity to a Supabase REST endpoint
|
|
6
6
|
* only after explicit opt-in or `NEXUS_TELEMETRY=on`.
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
import { type NexusPlgEventType } from './nexus-signature.js';
|
|
9
|
+
export type TelemetryEventType = 'install' | 'session_start' | 'session_end' | 'feature_use' | 'token_savings' | 'memory_created' | 'memory_recalled' | 'autonomy_candidate' | 'autonomy_candidate_suppressed' | 'autonomy_apply_started' | 'autonomy_apply_finished' | 'autonomy_apply_blocked' | NexusPlgEventType;
|
|
9
10
|
export interface TelemetryEvent {
|
|
10
11
|
type: TelemetryEventType;
|
|
11
12
|
timestamp: number;
|
|
@@ -26,6 +27,11 @@ export interface TelemetryStats {
|
|
|
26
27
|
totalFeatureUses: number;
|
|
27
28
|
totalMemoriesCreated: number;
|
|
28
29
|
totalMemoriesRecalled: number;
|
|
30
|
+
totalPrPresence: number;
|
|
31
|
+
totalCommitAttributions: number;
|
|
32
|
+
totalDocumentsSigned: number;
|
|
33
|
+
totalReleasesVerified: number;
|
|
34
|
+
totalProofBadgeViews: number;
|
|
29
35
|
endpointConfigured: boolean;
|
|
30
36
|
remoteStatsConfigured: boolean;
|
|
31
37
|
lastFlushAt?: number;
|
|
@@ -39,6 +45,7 @@ export interface RemoteInstallDrilldown {
|
|
|
39
45
|
memoriesRecalled: number;
|
|
40
46
|
featureUses: number;
|
|
41
47
|
autonomyEvents: number;
|
|
48
|
+
proofEvents: number;
|
|
42
49
|
recentProjects: string[];
|
|
43
50
|
}
|
|
44
51
|
export interface RemoteTelemetryStats {
|
|
@@ -49,6 +56,11 @@ export interface RemoteTelemetryStats {
|
|
|
49
56
|
totalTokenSavings: number;
|
|
50
57
|
totalMemoriesCreated: number;
|
|
51
58
|
totalMemoriesRecalled: number;
|
|
59
|
+
totalPrPresence: number;
|
|
60
|
+
totalCommitAttributions: number;
|
|
61
|
+
totalDocumentsSigned: number;
|
|
62
|
+
totalReleasesVerified: number;
|
|
63
|
+
totalProofBadgeViews: number;
|
|
52
64
|
installs: RemoteInstallDrilldown[];
|
|
53
65
|
}
|
|
54
66
|
export declare class RemoteTelemetry {
|
|
@@ -86,6 +98,7 @@ export declare class RemoteTelemetry {
|
|
|
86
98
|
trackMemoryCreated(scope: string, metadata?: Record<string, unknown>): void;
|
|
87
99
|
trackMemoryRecalled(hitCount: number, metadata?: Record<string, unknown>): void;
|
|
88
100
|
trackAutonomyEvent(type: Extract<TelemetryEventType, 'autonomy_candidate' | 'autonomy_candidate_suppressed' | 'autonomy_apply_started' | 'autonomy_apply_finished' | 'autonomy_apply_blocked'>, metadata?: Record<string, unknown>): void;
|
|
101
|
+
trackProductEvent(type: NexusPlgEventType, metadata?: Record<string, unknown>): void;
|
|
89
102
|
private enqueue;
|
|
90
103
|
private persistQueue;
|
|
91
104
|
private loadQueue;
|
|
@@ -100,6 +113,7 @@ export declare class RemoteTelemetry {
|
|
|
100
113
|
getStats(): TelemetryStats;
|
|
101
114
|
private getNexusVersion;
|
|
102
115
|
private hashIdentifier;
|
|
116
|
+
private incrementProductCounter;
|
|
103
117
|
destroy(): void;
|
|
104
118
|
}
|
|
105
119
|
export declare function getSharedTelemetry(options?: {
|
|
@@ -10,6 +10,7 @@ import * as path from 'path';
|
|
|
10
10
|
import * as os from 'os';
|
|
11
11
|
import * as crypto from 'crypto';
|
|
12
12
|
import { fileURLToPath } from 'url';
|
|
13
|
+
import { NEXUS_PLG_EVENT_TYPES } from './nexus-signature.js';
|
|
13
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
15
|
const __dirname = path.dirname(__filename);
|
|
15
16
|
const NEXUS_STATE_DIR = path.join(os.homedir(), '.nexus-prime');
|
|
@@ -68,6 +69,11 @@ function createEmptyState() {
|
|
|
68
69
|
totalFeatureUses: 0,
|
|
69
70
|
totalMemoriesCreated: 0,
|
|
70
71
|
totalMemoriesRecalled: 0,
|
|
72
|
+
totalPrPresence: 0,
|
|
73
|
+
totalCommitAttributions: 0,
|
|
74
|
+
totalDocumentsSigned: 0,
|
|
75
|
+
totalReleasesVerified: 0,
|
|
76
|
+
totalProofBadgeViews: 0,
|
|
71
77
|
};
|
|
72
78
|
}
|
|
73
79
|
export class RemoteTelemetry {
|
|
@@ -267,6 +273,19 @@ export class RemoteTelemetry {
|
|
|
267
273
|
data: sanitizeEventData(metadata ?? {}),
|
|
268
274
|
});
|
|
269
275
|
}
|
|
276
|
+
trackProductEvent(type, metadata) {
|
|
277
|
+
this.incrementProductCounter(type);
|
|
278
|
+
this.persistState();
|
|
279
|
+
this.enqueue({
|
|
280
|
+
type,
|
|
281
|
+
timestamp: Date.now(),
|
|
282
|
+
installId: this.installId,
|
|
283
|
+
data: sanitizeEventData({
|
|
284
|
+
eventFamily: 'nexus_prime_proof',
|
|
285
|
+
...metadata,
|
|
286
|
+
}),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
270
289
|
enqueue(event) {
|
|
271
290
|
if (!this.isOptedIn())
|
|
272
291
|
return;
|
|
@@ -381,6 +400,11 @@ export class RemoteTelemetry {
|
|
|
381
400
|
totalTokenSavings: 0,
|
|
382
401
|
totalMemoriesCreated: 0,
|
|
383
402
|
totalMemoriesRecalled: 0,
|
|
403
|
+
totalPrPresence: 0,
|
|
404
|
+
totalCommitAttributions: 0,
|
|
405
|
+
totalDocumentsSigned: 0,
|
|
406
|
+
totalReleasesVerified: 0,
|
|
407
|
+
totalProofBadgeViews: 0,
|
|
384
408
|
installs: [],
|
|
385
409
|
};
|
|
386
410
|
}
|
|
@@ -406,6 +430,11 @@ export class RemoteTelemetry {
|
|
|
406
430
|
let totalTokenSavings = 0;
|
|
407
431
|
let totalMemoriesCreated = 0;
|
|
408
432
|
let totalMemoriesRecalled = 0;
|
|
433
|
+
let totalPrPresence = 0;
|
|
434
|
+
let totalCommitAttributions = 0;
|
|
435
|
+
let totalDocumentsSigned = 0;
|
|
436
|
+
let totalReleasesVerified = 0;
|
|
437
|
+
let totalProofBadgeViews = 0;
|
|
409
438
|
const activeCutoff = Date.now() - ACTIVE_INSTALL_WINDOW_MS;
|
|
410
439
|
for (const row of rows) {
|
|
411
440
|
const installId = String(row.install_id ?? '').trim();
|
|
@@ -425,6 +454,7 @@ export class RemoteTelemetry {
|
|
|
425
454
|
memoriesRecalled: 0,
|
|
426
455
|
featureUses: 0,
|
|
427
456
|
autonomyEvents: 0,
|
|
457
|
+
proofEvents: 0,
|
|
428
458
|
recentProjects: [],
|
|
429
459
|
};
|
|
430
460
|
if (!bucket.lastSeenAt || (sentAt && Date.parse(bucket.lastSeenAt) < sentAtMs)) {
|
|
@@ -459,6 +489,30 @@ export class RemoteTelemetry {
|
|
|
459
489
|
case 'feature_use':
|
|
460
490
|
bucket.featureUses += 1;
|
|
461
491
|
break;
|
|
492
|
+
case 'pr_presence_added':
|
|
493
|
+
totalPrPresence += 1;
|
|
494
|
+
bucket.proofEvents += 1;
|
|
495
|
+
break;
|
|
496
|
+
case 'commit_attributed':
|
|
497
|
+
totalCommitAttributions += 1;
|
|
498
|
+
bucket.proofEvents += 1;
|
|
499
|
+
break;
|
|
500
|
+
case 'document_signed':
|
|
501
|
+
totalDocumentsSigned += 1;
|
|
502
|
+
bucket.proofEvents += 1;
|
|
503
|
+
break;
|
|
504
|
+
case 'release_verified':
|
|
505
|
+
totalReleasesVerified += 1;
|
|
506
|
+
bucket.proofEvents += 1;
|
|
507
|
+
break;
|
|
508
|
+
case 'proof_badge_viewed':
|
|
509
|
+
case 'website_proof_viewed':
|
|
510
|
+
totalProofBadgeViews += 1;
|
|
511
|
+
bucket.proofEvents += 1;
|
|
512
|
+
break;
|
|
513
|
+
case 'telemetry_batch_sent':
|
|
514
|
+
bucket.proofEvents += 1;
|
|
515
|
+
break;
|
|
462
516
|
case 'autonomy_candidate':
|
|
463
517
|
case 'autonomy_candidate_suppressed':
|
|
464
518
|
case 'autonomy_apply_started':
|
|
@@ -479,6 +533,11 @@ export class RemoteTelemetry {
|
|
|
479
533
|
totalTokenSavings,
|
|
480
534
|
totalMemoriesCreated,
|
|
481
535
|
totalMemoriesRecalled,
|
|
536
|
+
totalPrPresence,
|
|
537
|
+
totalCommitAttributions,
|
|
538
|
+
totalDocumentsSigned,
|
|
539
|
+
totalReleasesVerified,
|
|
540
|
+
totalProofBadgeViews,
|
|
482
541
|
installs: [...installs.values()]
|
|
483
542
|
.sort((a, b) => (b.tokenSavings - a.tokenSavings) || (b.sessions - a.sessions))
|
|
484
543
|
.slice(0, 25),
|
|
@@ -493,6 +552,11 @@ export class RemoteTelemetry {
|
|
|
493
552
|
totalTokenSavings: 0,
|
|
494
553
|
totalMemoriesCreated: 0,
|
|
495
554
|
totalMemoriesRecalled: 0,
|
|
555
|
+
totalPrPresence: 0,
|
|
556
|
+
totalCommitAttributions: 0,
|
|
557
|
+
totalDocumentsSigned: 0,
|
|
558
|
+
totalReleasesVerified: 0,
|
|
559
|
+
totalProofBadgeViews: 0,
|
|
496
560
|
installs: [],
|
|
497
561
|
};
|
|
498
562
|
}
|
|
@@ -519,6 +583,11 @@ export class RemoteTelemetry {
|
|
|
519
583
|
totalFeatureUses: this.state.totalFeatureUses,
|
|
520
584
|
totalMemoriesCreated: this.state.totalMemoriesCreated,
|
|
521
585
|
totalMemoriesRecalled: this.state.totalMemoriesRecalled,
|
|
586
|
+
totalPrPresence: this.state.totalPrPresence,
|
|
587
|
+
totalCommitAttributions: this.state.totalCommitAttributions,
|
|
588
|
+
totalDocumentsSigned: this.state.totalDocumentsSigned,
|
|
589
|
+
totalReleasesVerified: this.state.totalReleasesVerified,
|
|
590
|
+
totalProofBadgeViews: this.state.totalProofBadgeViews,
|
|
522
591
|
endpointConfigured: Boolean(this.endpoint && this.apiKey),
|
|
523
592
|
remoteStatsConfigured: Boolean(this.endpoint && process.env.NEXUS_TELEMETRY_SERVICE_KEY),
|
|
524
593
|
lastFlushAt: this.state.lastFlushAt,
|
|
@@ -537,6 +606,30 @@ export class RemoteTelemetry {
|
|
|
537
606
|
hashIdentifier(value) {
|
|
538
607
|
return crypto.createHash('sha256').update(String(value)).digest('hex').slice(0, 12);
|
|
539
608
|
}
|
|
609
|
+
incrementProductCounter(type) {
|
|
610
|
+
if (!NEXUS_PLG_EVENT_TYPES.includes(type))
|
|
611
|
+
return;
|
|
612
|
+
switch (type) {
|
|
613
|
+
case 'pr_presence_added':
|
|
614
|
+
this.state.totalPrPresence += 1;
|
|
615
|
+
break;
|
|
616
|
+
case 'commit_attributed':
|
|
617
|
+
this.state.totalCommitAttributions += 1;
|
|
618
|
+
break;
|
|
619
|
+
case 'document_signed':
|
|
620
|
+
this.state.totalDocumentsSigned += 1;
|
|
621
|
+
break;
|
|
622
|
+
case 'release_verified':
|
|
623
|
+
this.state.totalReleasesVerified += 1;
|
|
624
|
+
break;
|
|
625
|
+
case 'proof_badge_viewed':
|
|
626
|
+
case 'website_proof_viewed':
|
|
627
|
+
this.state.totalProofBadgeViews += 1;
|
|
628
|
+
break;
|
|
629
|
+
case 'telemetry_batch_sent':
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
540
633
|
destroy() {
|
|
541
634
|
if (this.flushTimer) {
|
|
542
635
|
clearInterval(this.flushTimer);
|
package/dist/index.d.ts
CHANGED
|
@@ -289,3 +289,7 @@ export { SessionDNAManager } from './engines/session-dna.js';
|
|
|
289
289
|
export type { SessionDNA } from './engines/session-dna.js';
|
|
290
290
|
export { GithubBridge, getSharedGithubBridge } from './engines/github-bridge.js';
|
|
291
291
|
export type { GithubPromotionInput, GithubPromotionResult } from './engines/github-bridge.js';
|
|
292
|
+
export { appendOrReplaceNexusPrPresenceBlock, buildNexusProofMetadata, ensureNexusCoauthorTrailer, NEXUS_PLG_EVENT_TYPES, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_GENERATOR, NEXUS_PRIME_WEBSITE, renderNexusDocumentSignature, renderNexusPrPresenceBlock, renderNexusWebsiteMetadata, } from './engines/nexus-signature.js';
|
|
293
|
+
export type { NexusDocumentSignatureInput, NexusHumanReviewState, NexusPlgEventType, NexusPresenceInput, NexusPresenceRole, NexusVerificationState, } from './engines/nexus-signature.js';
|
|
294
|
+
export { formatNexusProofReport, verifyNexusProof, } from './engines/nexus-proof.js';
|
|
295
|
+
export type { NexusProofCheck, NexusProofCheckStatus, NexusProofSummary, NexusProofVerifyOptions, } from './engines/nexus-proof.js';
|
package/dist/index.js
CHANGED
|
@@ -1211,3 +1211,5 @@ export { GhostPass, PhantomOrchestrator, PhantomWorker } from './phantom/index.j
|
|
|
1211
1211
|
export { MemoryEngine, createMemoryEngine } from './engines/memory.js';
|
|
1212
1212
|
export { SessionDNAManager } from './engines/session-dna.js';
|
|
1213
1213
|
export { GithubBridge, getSharedGithubBridge } from './engines/github-bridge.js';
|
|
1214
|
+
export { appendOrReplaceNexusPrPresenceBlock, buildNexusProofMetadata, ensureNexusCoauthorTrailer, NEXUS_PLG_EVENT_TYPES, NEXUS_PRIME_COAUTHOR_TRAILER, NEXUS_PRIME_GENERATOR, NEXUS_PRIME_WEBSITE, renderNexusDocumentSignature, renderNexusPrPresenceBlock, renderNexusWebsiteMetadata, } from './engines/nexus-signature.js';
|
|
1215
|
+
export { formatNexusProofReport, verifyNexusProof, } from './engines/nexus-proof.js';
|
|
@@ -24,6 +24,10 @@ export function getNexusHookSpec() {
|
|
|
24
24
|
matcher: 'Edit|Write|MultiEdit',
|
|
25
25
|
hooks: [{ type: 'command', command: 'nexus-prime hook mindkit', timeout: 10 }],
|
|
26
26
|
},
|
|
27
|
+
{
|
|
28
|
+
matcher: 'MultiEdit',
|
|
29
|
+
hooks: [{ type: 'command', command: 'nexus-prime hook ghost-pass', timeout: 15 }],
|
|
30
|
+
},
|
|
27
31
|
],
|
|
28
32
|
PostToolUse: [
|
|
29
33
|
{
|
|
@@ -101,6 +101,12 @@ export interface ExecutionTask {
|
|
|
101
101
|
instructionPacket?: InstructionPacket;
|
|
102
102
|
executionLedger?: ExecutionLedger;
|
|
103
103
|
knowledgeFabric?: KnowledgeFabricBundle;
|
|
104
|
+
autoGhostPass?: GhostReport;
|
|
105
|
+
autoGhostPassDecision?: {
|
|
106
|
+
enabled: boolean;
|
|
107
|
+
reason: string;
|
|
108
|
+
contextHash?: string;
|
|
109
|
+
};
|
|
104
110
|
}
|
|
105
111
|
export interface WorkerSkillOverlay {
|
|
106
112
|
base: string[];
|
package/dist/phantom/runtime.js
CHANGED
|
@@ -225,6 +225,16 @@ export class SubAgentRuntime {
|
|
|
225
225
|
files: (task.files ?? []).slice(0, 24),
|
|
226
226
|
workers: planner.plannerState.selectedSpecialists.length || 1,
|
|
227
227
|
phases: planner.plannerState.ledger.length,
|
|
228
|
+
autoGhostPass: {
|
|
229
|
+
applied: Boolean(task.autoGhostPass),
|
|
230
|
+
riskAreas: task.autoGhostPass?.riskAreas ?? [],
|
|
231
|
+
workerApproaches: task.autoGhostPass?.workerAssignments?.length ?? 0,
|
|
232
|
+
estimatedTokens: task.autoGhostPass?.totalEstimatedTokens ?? 0,
|
|
233
|
+
policy: task.autoGhostPassDecision ? {
|
|
234
|
+
enabled: task.autoGhostPassDecision.enabled,
|
|
235
|
+
reason: task.autoGhostPassDecision.reason,
|
|
236
|
+
} : undefined,
|
|
237
|
+
},
|
|
228
238
|
});
|
|
229
239
|
}
|
|
230
240
|
catch { /* best-effort */ }
|
|
@@ -765,6 +775,12 @@ export class SubAgentRuntime {
|
|
|
765
775
|
compressionPct: Number(tt?.compressionPct ?? 0),
|
|
766
776
|
durationMs: Date.now() - runStartedAt,
|
|
767
777
|
result: String(applied.summary ?? '').slice(0, 280),
|
|
778
|
+
autoGhostPass: {
|
|
779
|
+
applied: Boolean(task.autoGhostPass),
|
|
780
|
+
riskAreas: task.autoGhostPass?.riskAreas ?? [],
|
|
781
|
+
workerApproaches: task.autoGhostPass?.workerAssignments?.length ?? 0,
|
|
782
|
+
estimatedTokens: task.autoGhostPass?.totalEstimatedTokens ?? 0,
|
|
783
|
+
},
|
|
768
784
|
});
|
|
769
785
|
}
|
|
770
786
|
catch { /* best-effort */ }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-prime",
|
|
3
|
-
"version": "7.9.
|
|
3
|
+
"version": "7.9.27",
|
|
4
4
|
"description": "Local-first MCP control plane for coding agents with bootstrap-orchestrate execution, memory fabric, token budgeting, and worktree-backed swarms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|