@memlab/mcp-server 2.52.0 → 2.86.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 +22 -2
- package/dist/anonymized-snapshot.d.ts +75 -0
- package/dist/anonymized-snapshot.d.ts.map +1 -0
- package/dist/anonymized-snapshot.js +101 -0
- package/dist/anonymized-snapshot.js.map +1 -0
- package/dist/eval-hints.d.ts +41 -0
- package/dist/eval-hints.d.ts.map +1 -0
- package/dist/eval-hints.js +115 -0
- package/dist/eval-hints.js.map +1 -0
- package/dist/heap-budget.d.ts +32 -0
- package/dist/heap-budget.d.ts.map +1 -0
- package/dist/heap-budget.js +90 -0
- package/dist/heap-budget.js.map +1 -0
- package/dist/heap-shapes.d.ts +148 -0
- package/dist/heap-shapes.d.ts.map +1 -0
- package/dist/heap-shapes.js +193 -0
- package/dist/heap-shapes.js.map +1 -0
- package/dist/heap-state.d.ts +20 -0
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +8 -1
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +64 -1
- package/dist/index.js.map +1 -1
- package/dist/react-shapes.d.ts +42 -0
- package/dist/react-shapes.d.ts.map +1 -0
- package/dist/react-shapes.js +149 -0
- package/dist/react-shapes.js.map +1 -0
- package/dist/server-version.d.ts +19 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +19 -0
- package/dist/server-version.js.map +1 -0
- package/dist/snapshot-borrow.d.ts +67 -0
- package/dist/snapshot-borrow.d.ts.map +1 -0
- package/dist/snapshot-borrow.js +113 -0
- package/dist/snapshot-borrow.js.map +1 -0
- package/dist/string-index.d.ts.map +1 -1
- package/dist/string-index.js +8 -0
- package/dist/string-index.js.map +1 -1
- package/dist/tools/analyze-run.d.ts.map +1 -1
- package/dist/tools/analyze-run.js +79 -18
- package/dist/tools/analyze-run.js.map +1 -1
- package/dist/tools/anonymize-snapshot.d.ts +12 -0
- package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
- package/dist/tools/anonymize-snapshot.js +159 -0
- package/dist/tools/anonymize-snapshot.js.map +1 -0
- package/dist/tools/app-config.d.ts +12 -0
- package/dist/tools/app-config.d.ts.map +1 -0
- package/dist/tools/app-config.js +217 -0
- package/dist/tools/app-config.js.map +1 -0
- package/dist/tools/app-heap.d.ts +18 -0
- package/dist/tools/app-heap.d.ts.map +1 -1
- package/dist/tools/app-heap.js +12 -46
- package/dist/tools/app-heap.js.map +1 -1
- package/dist/tools/artifact-budget.d.ts +12 -0
- package/dist/tools/artifact-budget.d.ts.map +1 -0
- package/dist/tools/artifact-budget.js +219 -0
- package/dist/tools/artifact-budget.js.map +1 -0
- package/dist/tools/async-census.d.ts +12 -0
- package/dist/tools/async-census.d.ts.map +1 -0
- package/dist/tools/async-census.js +243 -0
- package/dist/tools/async-census.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +54 -5
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts.map +1 -1
- package/dist/tools/batch.js +33 -5
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/cache-analysis.d.ts +15 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +85 -10
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/census-diff.d.ts +55 -0
- package/dist/tools/census-diff.d.ts.map +1 -0
- package/dist/tools/census-diff.js +228 -0
- package/dist/tools/census-diff.js.map +1 -0
- package/dist/tools/chain-walk.d.ts +12 -0
- package/dist/tools/chain-walk.d.ts.map +1 -0
- package/dist/tools/chain-walk.js +184 -0
- package/dist/tools/chain-walk.js.map +1 -0
- package/dist/tools/collection-diff.d.ts +44 -0
- package/dist/tools/collection-diff.d.ts.map +1 -0
- package/dist/tools/collection-diff.js +343 -0
- package/dist/tools/collection-diff.js.map +1 -0
- package/dist/tools/collection-trend.d.ts.map +1 -1
- package/dist/tools/collection-trend.js +2 -2
- package/dist/tools/collection-trend.js.map +1 -1
- package/dist/tools/detached-dom.d.ts +3 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +78 -3
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +221 -3
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +18 -2
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dom-audit.d.ts +37 -0
- package/dist/tools/dom-audit.d.ts.map +1 -0
- package/dist/tools/dom-audit.js +247 -0
- package/dist/tools/dom-audit.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +3 -2
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval-across.d.ts +12 -0
- package/dist/tools/eval-across.d.ts.map +1 -0
- package/dist/tools/eval-across.js +135 -0
- package/dist/tools/eval-across.js.map +1 -0
- package/dist/tools/eval.d.ts +78 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +2270 -701
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +42 -17
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts.map +1 -1
- package/dist/tools/event-registry.js +42 -8
- package/dist/tools/event-registry.js.map +1 -1
- package/dist/tools/explain-delta.d.ts.map +1 -1
- package/dist/tools/explain-delta.js +61 -10
- package/dist/tools/explain-delta.js.map +1 -1
- package/dist/tools/finding-index.d.ts +181 -0
- package/dist/tools/finding-index.d.ts.map +1 -1
- package/dist/tools/finding-index.js +343 -24
- package/dist/tools/finding-index.js.map +1 -1
- package/dist/tools/get-value.d.ts +16 -0
- package/dist/tools/get-value.d.ts.map +1 -1
- package/dist/tools/get-value.js +96 -2
- package/dist/tools/get-value.js.map +1 -1
- package/dist/tools/hypothesis.d.ts.map +1 -1
- package/dist/tools/hypothesis.js +117 -58
- package/dist/tools/hypothesis.js.map +1 -1
- package/dist/tools/id-space-audit.d.ts +12 -0
- package/dist/tools/id-space-audit.d.ts.map +1 -0
- package/dist/tools/id-space-audit.js +262 -0
- package/dist/tools/id-space-audit.js.map +1 -0
- package/dist/tools/identify.d.ts +12 -0
- package/dist/tools/identify.d.ts.map +1 -0
- package/dist/tools/identify.js +205 -0
- package/dist/tools/identify.js.map +1 -0
- package/dist/tools/identity-diff.d.ts +12 -0
- package/dist/tools/identity-diff.d.ts.map +1 -0
- package/dist/tools/identity-diff.js +188 -0
- package/dist/tools/identity-diff.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +4 -3
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder-probe.d.ts +65 -0
- package/dist/tools/ladder-probe.d.ts.map +1 -0
- package/dist/tools/ladder-probe.js +445 -0
- package/dist/tools/ladder-probe.js.map +1 -0
- package/dist/tools/ladder.d.ts.map +1 -1
- package/dist/tools/ladder.js +5 -5
- package/dist/tools/ladder.js.map +1 -1
- package/dist/tools/leak-report.d.ts +23 -0
- package/dist/tools/leak-report.d.ts.map +1 -1
- package/dist/tools/leak-report.js +153 -11
- package/dist/tools/leak-report.js.map +1 -1
- package/dist/tools/load-snapshot.d.ts +11 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +83 -10
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/metric.d.ts +13 -0
- package/dist/tools/metric.d.ts.map +1 -0
- package/dist/tools/metric.js +185 -0
- package/dist/tools/metric.js.map +1 -0
- package/dist/tools/module-attribution.d.ts +36 -0
- package/dist/tools/module-attribution.d.ts.map +1 -0
- package/dist/tools/module-attribution.js +235 -0
- package/dist/tools/module-attribution.js.map +1 -0
- package/dist/tools/next-measurement.d.ts +26 -0
- package/dist/tools/next-measurement.d.ts.map +1 -0
- package/dist/tools/next-measurement.js +149 -0
- package/dist/tools/next-measurement.js.map +1 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
- package/dist/tools/object-cost-breakdown.js +64 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -1
- package/dist/tools/population-vs-owners.d.ts +12 -0
- package/dist/tools/population-vs-owners.d.ts.map +1 -0
- package/dist/tools/population-vs-owners.js +183 -0
- package/dist/tools/population-vs-owners.js.map +1 -0
- package/dist/tools/property-names.d.ts +29 -0
- package/dist/tools/property-names.d.ts.map +1 -0
- package/dist/tools/property-names.js +131 -0
- package/dist/tools/property-names.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +7 -1
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/react-owners.d.ts +12 -0
- package/dist/tools/react-owners.d.ts.map +1 -0
- package/dist/tools/react-owners.js +167 -0
- package/dist/tools/react-owners.js.map +1 -0
- package/dist/tools/react-update-queues.d.ts +12 -0
- package/dist/tools/react-update-queues.d.ts.map +1 -0
- package/dist/tools/react-update-queues.js +173 -0
- package/dist/tools/react-update-queues.js.map +1 -0
- package/dist/tools/replicate.d.ts +49 -0
- package/dist/tools/replicate.d.ts.map +1 -0
- package/dist/tools/replicate.js +241 -0
- package/dist/tools/replicate.js.map +1 -0
- package/dist/tools/retainer-diff.d.ts +12 -0
- package/dist/tools/retainer-diff.d.ts.map +1 -0
- package/dist/tools/retainer-diff.js +168 -0
- package/dist/tools/retainer-diff.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +17 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +85 -22
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +11 -1
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/round-audit.d.ts +66 -0
- package/dist/tools/round-audit.d.ts.map +1 -0
- package/dist/tools/round-audit.js +258 -0
- package/dist/tools/round-audit.js.map +1 -0
- package/dist/tools/round-digest.d.ts +12 -0
- package/dist/tools/round-digest.d.ts.map +1 -0
- package/dist/tools/round-digest.js +190 -0
- package/dist/tools/round-digest.js.map +1 -0
- package/dist/tools/script-census.d.ts +12 -0
- package/dist/tools/script-census.d.ts.map +1 -0
- package/dist/tools/script-census.js +182 -0
- package/dist/tools/script-census.js.map +1 -0
- package/dist/tools/sequence-analysis.d.ts +4 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +53 -9
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/server-status.d.ts.map +1 -1
- package/dist/tools/server-status.js +4 -1
- package/dist/tools/server-status.js.map +1 -1
- package/dist/tools/settle-check.d.ts +12 -0
- package/dist/tools/settle-check.d.ts.map +1 -0
- package/dist/tools/settle-check.js +188 -0
- package/dist/tools/settle-check.js.map +1 -0
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +2 -1
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +24 -6
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/sparse-elements.d.ts +12 -0
- package/dist/tools/sparse-elements.d.ts.map +1 -0
- package/dist/tools/sparse-elements.js +215 -0
- package/dist/tools/sparse-elements.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +17 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +28 -0
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +2 -1
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts.map +1 -1
- package/dist/tools/tools-index.js +155 -5
- package/dist/tools/tools-index.js.map +1 -1
- package/dist/tools/trace-all.d.ts +42 -0
- package/dist/tools/trace-all.d.ts.map +1 -0
- package/dist/tools/trace-all.js +263 -0
- package/dist/tools/trace-all.js.map +1 -0
- package/dist/tools/unit-cost.d.ts +12 -0
- package/dist/tools/unit-cost.d.ts.map +1 -0
- package/dist/tools/unit-cost.js +219 -0
- package/dist/tools/unit-cost.js.map +1 -0
- package/dist/tools/verify-fix.d.ts.map +1 -1
- package/dist/tools/verify-fix.js +11 -3
- package/dist/tools/verify-fix.js.map +1 -1
- package/dist/tools/weakref-census.d.ts +15 -0
- package/dist/tools/weakref-census.d.ts.map +1 -0
- package/dist/tools/weakref-census.js +147 -0
- package/dist/tools/weakref-census.js.map +1 -0
- package/dist/tools/what-if.d.ts +12 -0
- package/dist/tools/what-if.d.ts.map +1 -0
- package/dist/tools/what-if.js +285 -0
- package/dist/tools/what-if.js.map +1 -0
- package/dist/utils.d.ts +92 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +172 -5
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-owners.js","sourceRoot":"","sources":["../../src/tools/react-owners.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
export declare function registerReactUpdateQueues(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=react-update-queues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-update-queues.d.ts","sourceRoot":"","sources":["../../src/tools/react-update-queues.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAsDvE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8KjE"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { getSnapshot } from '../heap-state.js';
|
|
12
|
+
import { nearestFiber, fiberComponentName, isUpdateRecord, } from '../react-shapes.js';
|
|
13
|
+
import { errorResult, toolResult, formatNumber, markdownTable, suggestionsSuppressed, } from '../utils.js';
|
|
14
|
+
/**
|
|
15
|
+
* Length of a `queue.pending` chain.
|
|
16
|
+
*
|
|
17
|
+
* React's update queue is CIRCULAR, which is the detail that makes a
|
|
18
|
+
* hand-written walk report its own hop cap as a measurement: a
|
|
19
|
+
* `while (next && next.id !== start)` guarded by `hops < 800` returned 800 for
|
|
20
|
+
* a chain of 2,066, and nothing in the output distinguished the two. The
|
|
21
|
+
* terminator is returned so a capped walk can never be quoted as a length.
|
|
22
|
+
*/
|
|
23
|
+
function chainLength(head, maxHops) {
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
let cur = head;
|
|
26
|
+
while (cur != null) {
|
|
27
|
+
if (seen.has(cur.id))
|
|
28
|
+
return { length: seen.size, terminated: 'cycle' };
|
|
29
|
+
if (seen.size >= maxHops)
|
|
30
|
+
return { length: seen.size, terminated: 'cap' };
|
|
31
|
+
seen.add(cur.id);
|
|
32
|
+
let next = null;
|
|
33
|
+
for (const edge of cur.references) {
|
|
34
|
+
if (String(edge.name_or_index) !== 'next')
|
|
35
|
+
continue;
|
|
36
|
+
next = edge.toNode.id > 3 ? edge.toNode : null;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
cur = next;
|
|
40
|
+
}
|
|
41
|
+
return { length: seen.size, terminated: 'end' };
|
|
42
|
+
}
|
|
43
|
+
export function registerReactUpdateQueues(server) {
|
|
44
|
+
server.tool('memlab_react_update_queues', 'The React eager-bailout leak family as one report. A `useState` update whose eager comparison bails out still leaves its record on `queue.pending`, which then never drains — four separate findings in this workstream have been that same shape, and each round re-derived the same three things by hand. This returns: how many queues hold a pending chain (BREADTH), how long each chain is (LENGTH), and which component owns it. The breadth-vs-length split is the part that decides the finding — a flat queue count with growing records is accumulation in existing queues, which is the leak; a rising queue count with one record each is just more hooks mounted, which is not. Getting that backwards is the difference between a filing and a retraction.', {
|
|
45
|
+
max_chain: z
|
|
46
|
+
.number()
|
|
47
|
+
.optional()
|
|
48
|
+
.default(100000)
|
|
49
|
+
.describe('Safety bound on links walked per chain (default 100000). A chain longer than this is itself the finding; the result says it was capped rather than reporting the cap as a length.'),
|
|
50
|
+
limit: z
|
|
51
|
+
.number()
|
|
52
|
+
.optional()
|
|
53
|
+
.default(20)
|
|
54
|
+
.describe('Maximum components to report (default 20).'),
|
|
55
|
+
max_hops: z
|
|
56
|
+
.number()
|
|
57
|
+
.optional()
|
|
58
|
+
.default(12)
|
|
59
|
+
.describe('Referrer hops allowed when looking for the owning fiber.'),
|
|
60
|
+
}, async ({ max_chain, limit, max_hops }) => {
|
|
61
|
+
try {
|
|
62
|
+
const snapshot = getSnapshot();
|
|
63
|
+
// A queue is recognised by holding a `pending` edge to an update
|
|
64
|
+
// record, rather than by name: `queue` is minified and the hook object
|
|
65
|
+
// it hangs off is a plain Object.
|
|
66
|
+
const queues = [];
|
|
67
|
+
let totalRecords = 0;
|
|
68
|
+
snapshot.nodes.forEach(node => {
|
|
69
|
+
if (node.type !== 'object')
|
|
70
|
+
return;
|
|
71
|
+
if (isUpdateRecord(node))
|
|
72
|
+
totalRecords++;
|
|
73
|
+
for (const edge of node.references) {
|
|
74
|
+
if (edge.type !== 'property')
|
|
75
|
+
continue;
|
|
76
|
+
if (String(edge.name_or_index) !== 'pending')
|
|
77
|
+
continue;
|
|
78
|
+
if (isUpdateRecord(edge.toNode))
|
|
79
|
+
queues.push(node);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (queues.length === 0) {
|
|
84
|
+
return toolResult('No React update queue in this snapshot holds a pending chain.\n\n' +
|
|
85
|
+
`${formatNumber(totalRecords)} update record(s) exist in total. If that number is large while no queue holds one, the records are retained by something OTHER than a live queue — which is a different (and usually more interesting) finding: trace one with \`memlab_retainer_trace\`.`);
|
|
86
|
+
}
|
|
87
|
+
const reports = [];
|
|
88
|
+
for (const queue of queues) {
|
|
89
|
+
let head = null;
|
|
90
|
+
for (const edge of queue.references) {
|
|
91
|
+
if (String(edge.name_or_index) === 'pending') {
|
|
92
|
+
head = edge.toNode;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (head == null)
|
|
97
|
+
continue;
|
|
98
|
+
const { length, terminated } = chainLength(head, max_chain);
|
|
99
|
+
const fiber = nearestFiber(queue, max_hops);
|
|
100
|
+
reports.push({
|
|
101
|
+
queueId: queue.id,
|
|
102
|
+
component: (fiber != null ? fiberComponentName(fiber) : null) ??
|
|
103
|
+
'(unattributed)',
|
|
104
|
+
length,
|
|
105
|
+
terminated,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const byComponent = new Map();
|
|
109
|
+
for (const r of reports) {
|
|
110
|
+
let b = byComponent.get(r.component);
|
|
111
|
+
if (!b) {
|
|
112
|
+
b = {
|
|
113
|
+
component: r.component,
|
|
114
|
+
queues: 0,
|
|
115
|
+
records: 0,
|
|
116
|
+
longest: 0,
|
|
117
|
+
capped: 0,
|
|
118
|
+
example: r.queueId,
|
|
119
|
+
};
|
|
120
|
+
byComponent.set(r.component, b);
|
|
121
|
+
}
|
|
122
|
+
b.queues++;
|
|
123
|
+
b.records += r.length;
|
|
124
|
+
if (r.length > b.longest) {
|
|
125
|
+
b.longest = r.length;
|
|
126
|
+
b.example = r.queueId;
|
|
127
|
+
}
|
|
128
|
+
if (r.terminated === 'cap')
|
|
129
|
+
b.capped++;
|
|
130
|
+
}
|
|
131
|
+
const ranked = [...byComponent.values()].sort((a, b) => b.records - a.records);
|
|
132
|
+
const shown = ranked.slice(0, limit);
|
|
133
|
+
const pendingRecords = reports.reduce((s, r) => s + r.length, 0);
|
|
134
|
+
const anyCapped = reports.some(r => r.terminated === 'cap');
|
|
135
|
+
const lines = [
|
|
136
|
+
'## React update queues holding a pending chain',
|
|
137
|
+
'',
|
|
138
|
+
`**Breadth: ${formatNumber(reports.length)} queue(s)** · **Length: ${formatNumber(pendingRecords)} pending record(s)** · ` +
|
|
139
|
+
`${formatNumber(totalRecords)} update record(s) exist in the heap in total.`,
|
|
140
|
+
'',
|
|
141
|
+
markdownTable([
|
|
142
|
+
'Component',
|
|
143
|
+
'Queues',
|
|
144
|
+
'Pending records',
|
|
145
|
+
'Longest chain',
|
|
146
|
+
'Example',
|
|
147
|
+
], shown.map(b => [
|
|
148
|
+
b.component + (b.capped > 0 ? ' ⚠' : ''),
|
|
149
|
+
formatNumber(b.queues),
|
|
150
|
+
formatNumber(b.records),
|
|
151
|
+
formatNumber(b.longest),
|
|
152
|
+
`@${b.example}`,
|
|
153
|
+
]), new Set([1, 2, 3])),
|
|
154
|
+
'',
|
|
155
|
+
];
|
|
156
|
+
if (ranked.length > shown.length) {
|
|
157
|
+
lines.push(`_${formatNumber(ranked.length - shown.length)} further component(s) not shown; raise \`limit\`._`, '');
|
|
158
|
+
}
|
|
159
|
+
if (anyCapped) {
|
|
160
|
+
lines.push(`⚠ ${formatNumber(reports.filter(r => r.terminated === 'cap').length)} chain(s) hit the ${formatNumber(max_chain)}-link cap — those lengths are FLOORS, not measurements. Raise \`max_chain\`.`, '');
|
|
161
|
+
}
|
|
162
|
+
lines.push('### How to read this across a ladder', '', '- **Queue count (breadth) FLAT, pending records rising** → existing queues are accumulating. This is the leak shape, and it is what to file.', '- **Queue count rising, records-per-queue ~1** → more components are mounted. Not a leak; the population scales with the UI.', '- **Both rising** → separate them before concluding, or the write-up will attribute mounting to leaking.', '', 'One measured round found `REPRODUCED` on record count and `NOT_REPRODUCED` on breadth across independent runs, which is exactly what proved the chains were lengthening rather than multiplying.');
|
|
163
|
+
if (!suggestionsSuppressed() && shown.length > 0) {
|
|
164
|
+
lines.push('', '**Suggested next steps**', `- \`memlab_ladder_probe\` on this tool's two numbers across the rungs — breadth and total pending records, separately.`, `- \`memlab_replicate\` before filing: this family has produced a retraction when a single run was trusted.`, `- \`memlab_verify_fix({metric_kind: "pending_chain", locator: "<Owner>.<property>"})\` once both arms are driven — no runtime gate needed, it takes two sets of snapshot files.`);
|
|
165
|
+
}
|
|
166
|
+
return toolResult(lines.join('\n'));
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
return errorResult(err);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=react-update-queues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-update-queues.js","sourceRoot":"","sources":["../../src/tools/react-update-queues.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,UAAU,EACV,YAAY,EACZ,aAAa,EACb,qBAAqB,GACtB,MAAM,aAAa,CAAC;AASrB;;;;;;;;GAQG;AACH,SAAS,WAAW,CAClB,IAAe,EACf,OAAe;IAEf,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,GAAG,GAAqB,IAAI,CAAC;IACjC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;QACnB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,EAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAC,CAAC;QACtE,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO;YAAE,OAAO,EAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAC,CAAC;QACxE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACjB,IAAI,IAAI,GAAqB,IAAI,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,MAAM;gBAAE,SAAS;YACpD,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/C,MAAM;QACR,CAAC;QACD,GAAG,GAAG,IAAI,CAAC;IACb,CAAC;IACD,OAAO,EAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,IAAI,CACT,4BAA4B,EAC5B,2uBAA2uB,EAC3uB;QACE,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,MAAM,CAAC;aACf,QAAQ,CACP,mLAAmL,CACpL;QACH,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,4CAA4C,CAAC;QACzD,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,0DAA0D,CAAC;KACxE,EACD,KAAK,EAAE,EAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAC,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAE/B,iEAAiE;YACjE,uEAAuE;YACvE,kCAAkC;YAClC,MAAM,MAAM,GAAgB,EAAE,CAAC;YAC/B,IAAI,YAAY,GAAG,CAAC,CAAC;YACrB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;oBAAE,OAAO;gBACnC,IAAI,cAAc,CAAC,IAAI,CAAC;oBAAE,YAAY,EAAE,CAAC;gBACzC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACnC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;wBAAE,SAAS;oBACvC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,SAAS;wBAAE,SAAS;oBACvD,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC;wBAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnD,MAAM;gBACR,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,UAAU,CACf,mEAAmE;oBACjE,GAAG,YAAY,CAAC,YAAY,CAAC,4PAA4P,CAC5R,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAkB,EAAE,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,IAAI,GAAqB,IAAI,CAAC;gBAClC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;wBAC7C,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;wBACnB,MAAM;oBACR,CAAC;gBACH,CAAC;gBACD,IAAI,IAAI,IAAI,IAAI;oBAAE,SAAS;gBAC3B,MAAM,EAAC,MAAM,EAAE,UAAU,EAAC,GAAG,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC1D,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC;oBACX,OAAO,EAAE,KAAK,CAAC,EAAE;oBACjB,SAAS,EACP,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAClD,gBAAgB;oBAClB,MAAM;oBACN,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;YAUD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;YAC9C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBACrC,IAAI,CAAC,CAAC,EAAE,CAAC;oBACP,CAAC,GAAG;wBACF,SAAS,EAAE,CAAC,CAAC,SAAS;wBACtB,MAAM,EAAE,CAAC;wBACT,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,CAAC;wBACV,MAAM,EAAE,CAAC;wBACT,OAAO,EAAE,CAAC,CAAC,OAAO;qBACnB,CAAC;oBACF,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;gBAClC,CAAC;gBACD,CAAC,CAAC,MAAM,EAAE,CAAC;gBACX,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC;gBACtB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;oBACzB,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;oBACrB,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;gBACxB,CAAC;gBACD,IAAI,CAAC,CAAC,UAAU,KAAK,KAAK;oBAAE,CAAC,CAAC,MAAM,EAAE,CAAC;YACzC,CAAC;YAED,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAChC,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACrC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YACjE,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC;YAE5D,MAAM,KAAK,GAAa;gBACtB,gDAAgD;gBAChD,EAAE;gBACF,cAAc,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,2BAA2B,YAAY,CAAC,cAAc,CAAC,yBAAyB;oBACxH,GAAG,YAAY,CAAC,YAAY,CAAC,+CAA+C;gBAC9E,EAAE;gBACF,aAAa,CACX;oBACE,WAAW;oBACX,QAAQ;oBACR,iBAAiB;oBACjB,eAAe;oBACf,SAAS;iBACV,EACD,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACb,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;oBACtB,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;oBACvB,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;oBACvB,IAAI,CAAC,CAAC,OAAO,EAAE;iBAChB,CAAC,EACF,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CACnB;gBACD,EAAE;aACH,CAAC;YACF,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CACR,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,oDAAoD,EAClG,EAAE,CACH,CAAC;YACJ,CAAC;YACD,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,CAAC,IAAI,CACR,KAAK,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,qBAAqB,YAAY,CAAC,SAAS,CAAC,8EAA8E,EAC/L,EAAE,CACH,CAAC;YACJ,CAAC;YAED,KAAK,CAAC,IAAI,CACR,sCAAsC,EACtC,EAAE,EACF,8IAA8I,EAC9I,8HAA8H,EAC9H,0GAA0G,EAC1G,EAAE,EACF,kMAAkM,CACnM,CAAC;YAEF,IAAI,CAAC,qBAAqB,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjD,KAAK,CAAC,IAAI,CACR,EAAE,EACF,0BAA0B,EAC1B,wHAAwH,EACxH,4GAA4G,EAC5G,iLAAiL,CAClL,CAAC;YACJ,CAAC;YAED,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
import { type LinearFit } from './ladder-probe.js';
|
|
12
|
+
export interface RunFit {
|
|
13
|
+
label: string;
|
|
14
|
+
values: number[];
|
|
15
|
+
xs: number[];
|
|
16
|
+
fit: LinearFit;
|
|
17
|
+
delta: number;
|
|
18
|
+
grows: boolean;
|
|
19
|
+
reason: string;
|
|
20
|
+
}
|
|
21
|
+
export type ReplicationVerdict = 'REPRODUCED' | 'REPRODUCED_UNSTABLE' | 'NOT_REPRODUCED' | 'INCONCLUSIVE';
|
|
22
|
+
/**
|
|
23
|
+
* Does this one run show the effect at all?
|
|
24
|
+
*
|
|
25
|
+
* Deliberately three conditions, not one. A slope alone is satisfied by noise;
|
|
26
|
+
* an r2 alone is satisfied by a dead-flat series (which fits a horizontal line
|
|
27
|
+
* perfectly); and a delta alone is satisfied by a single GC-band step. The
|
|
28
|
+
* effect has to be present, linear, and big enough to be worth a name.
|
|
29
|
+
*/
|
|
30
|
+
export declare function classifyRun(label: string, values: number[], xs: number[], minR2: number, minDelta: number): RunFit;
|
|
31
|
+
/**
|
|
32
|
+
* The whole point of the tool: a finding is not a finding until a SECOND,
|
|
33
|
+
* independently-driven run shows the same thing.
|
|
34
|
+
*
|
|
35
|
+
* A single run cannot distinguish an effect from a one-off, no matter how clean
|
|
36
|
+
* it looks — and "how clean it looks" is not a weak signal that can be tightened
|
|
37
|
+
* away. The finding that motivated this passed every gate the workstream had
|
|
38
|
+
* (r2 = 1.0000, permanent across nine minutes of idle with forced GC, 97%
|
|
39
|
+
* concentrated under one dominator, dominator-deduped sizing, an app-side
|
|
40
|
+
* retainer path with no dev-root hop) and did not reproduce on any of the next
|
|
41
|
+
* three runs. Replication is the only gate that would have caught it, and it is
|
|
42
|
+
* entirely mechanical, which is why it belongs in a tool rather than a habit.
|
|
43
|
+
*/
|
|
44
|
+
export declare function adjudicate(runs: RunFit[], slopeRatioTolerance: number): {
|
|
45
|
+
verdict: ReplicationVerdict;
|
|
46
|
+
summary: string;
|
|
47
|
+
};
|
|
48
|
+
export declare function registerReplicate(server: McpServer): void;
|
|
49
|
+
//# sourceMappingURL=replicate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replicate.d.ts","sourceRoot":"","sources":["../../src/tools/replicate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAcvE,OAAO,EAAuB,KAAK,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAGvE,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,kBAAkB,GAC5B,YAAY,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAE3E;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,EAChB,EAAE,EAAE,MAAM,EAAE,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,MAAM,CAgBR;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EAAE,EACd,mBAAmB,EAAE,MAAM,GAC1B;IAAC,OAAO,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CA6ChD;AAwBD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkMzD"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { armScanBudgetFor, resolveRungs, scaledTimeoutMs, } from '../snapshot-borrow.js';
|
|
12
|
+
import { errorResult, formatNumber, markdownTable, pathsHeader, toolResult, } from '../utils.js';
|
|
13
|
+
import { linearFit, probeRung } from './ladder-probe.js';
|
|
14
|
+
import { resolveLadderPaths } from './ladder.js';
|
|
15
|
+
/**
|
|
16
|
+
* Does this one run show the effect at all?
|
|
17
|
+
*
|
|
18
|
+
* Deliberately three conditions, not one. A slope alone is satisfied by noise;
|
|
19
|
+
* an r2 alone is satisfied by a dead-flat series (which fits a horizontal line
|
|
20
|
+
* perfectly); and a delta alone is satisfied by a single GC-band step. The
|
|
21
|
+
* effect has to be present, linear, and big enough to be worth a name.
|
|
22
|
+
*/
|
|
23
|
+
export function classifyRun(label, values, xs, minR2, minDelta) {
|
|
24
|
+
const fit = linearFit(xs, values);
|
|
25
|
+
const delta = values[values.length - 1] - values[0];
|
|
26
|
+
let grows = true;
|
|
27
|
+
let reason = 'grows, linear, and above the delta floor';
|
|
28
|
+
if (delta < minDelta) {
|
|
29
|
+
grows = false;
|
|
30
|
+
reason = `net delta ${formatNumber(delta)} is below the floor of ${formatNumber(minDelta)}`;
|
|
31
|
+
}
|
|
32
|
+
else if (fit.slope <= 0) {
|
|
33
|
+
grows = false;
|
|
34
|
+
reason = `slope ${fit.slope.toFixed(3)} is not positive`;
|
|
35
|
+
}
|
|
36
|
+
else if (fit.r2 < minR2) {
|
|
37
|
+
grows = false;
|
|
38
|
+
reason = `r2 ${fit.r2.toFixed(4)} is below ${minR2} — not a linear accumulation`;
|
|
39
|
+
}
|
|
40
|
+
return { label, values, xs, fit, delta, grows, reason };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The whole point of the tool: a finding is not a finding until a SECOND,
|
|
44
|
+
* independently-driven run shows the same thing.
|
|
45
|
+
*
|
|
46
|
+
* A single run cannot distinguish an effect from a one-off, no matter how clean
|
|
47
|
+
* it looks — and "how clean it looks" is not a weak signal that can be tightened
|
|
48
|
+
* away. The finding that motivated this passed every gate the workstream had
|
|
49
|
+
* (r2 = 1.0000, permanent across nine minutes of idle with forced GC, 97%
|
|
50
|
+
* concentrated under one dominator, dominator-deduped sizing, an app-side
|
|
51
|
+
* retainer path with no dev-root hop) and did not reproduce on any of the next
|
|
52
|
+
* three runs. Replication is the only gate that would have caught it, and it is
|
|
53
|
+
* entirely mechanical, which is why it belongs in a tool rather than a habit.
|
|
54
|
+
*/
|
|
55
|
+
export function adjudicate(runs, slopeRatioTolerance) {
|
|
56
|
+
if (runs.length < 2) {
|
|
57
|
+
return {
|
|
58
|
+
verdict: 'INCONCLUSIVE',
|
|
59
|
+
summary: 'Replication needs at least 2 independently-driven runs. One run cannot distinguish an effect from a one-off.',
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const growing = runs.filter(r => r.grows);
|
|
63
|
+
if (growing.length === 0) {
|
|
64
|
+
return {
|
|
65
|
+
verdict: 'NOT_REPRODUCED',
|
|
66
|
+
summary: `No run shows the effect (${runs.length}/${runs.length} flat or shrinking). There is nothing here to attribute.`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (growing.length < runs.length) {
|
|
70
|
+
const absent = runs.filter(r => !r.grows);
|
|
71
|
+
return {
|
|
72
|
+
verdict: 'NOT_REPRODUCED',
|
|
73
|
+
summary: `${growing.length} of ${runs.length} runs show the effect and ${absent.length} do not ` +
|
|
74
|
+
`(${absent.map(r => `${r.label}: ${r.reason}`).join('; ')}). ` +
|
|
75
|
+
'A finding that appears in some runs and not others is not yet a finding — it is an ' +
|
|
76
|
+
'unexplained difference between the runs. Find what differs before attributing it.',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const slopes = growing.map(r => r.fit.slope);
|
|
80
|
+
const ratio = Math.max(...slopes) / Math.min(...slopes);
|
|
81
|
+
if (ratio > slopeRatioTolerance) {
|
|
82
|
+
return {
|
|
83
|
+
verdict: 'REPRODUCED_UNSTABLE',
|
|
84
|
+
summary: `Every run shows the effect, but the magnitude is unstable: slopes range ` +
|
|
85
|
+
`${Math.min(...slopes).toFixed(3)} to ${Math.max(...slopes).toFixed(3)} per cycle ` +
|
|
86
|
+
`(${ratio.toFixed(1)}x, over the ${slopeRatioTolerance}x tolerance). ` +
|
|
87
|
+
'The effect is real; quote it as a range, and do not size a fix off one run.',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
verdict: 'REPRODUCED',
|
|
92
|
+
summary: `All ${runs.length} runs show the effect with consistent magnitude ` +
|
|
93
|
+
`(slopes ${Math.min(...slopes).toFixed(3)}–${Math.max(...slopes).toFixed(3)} per cycle, ` +
|
|
94
|
+
`${ratio.toFixed(1)}x spread). This is the evidence a filing needs.`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const RunSchema = z.object({
|
|
98
|
+
paths: z
|
|
99
|
+
.array(z.string())
|
|
100
|
+
.optional()
|
|
101
|
+
.describe('Ordered snapshot paths for this run, oldest first. Omit only if `series` is given.'),
|
|
102
|
+
series: z
|
|
103
|
+
.array(z.number())
|
|
104
|
+
.optional()
|
|
105
|
+
.describe('Pre-measured values per rung, when you already have the numbers (e.g. from an earlier `memlab_ladder_probe`, or from a round whose snapshots are gone). Skips loading entirely.'),
|
|
106
|
+
cycles_per_rung: z
|
|
107
|
+
.array(z.number())
|
|
108
|
+
.optional()
|
|
109
|
+
.describe('Cumulative cycle count at each rung. Needed to compare runs whose ladders are spaced differently — without it the fit is per RUNG, and two runs with different cycle spacing are not comparable.'),
|
|
110
|
+
label: z.string().optional().describe('Name for this run in the report.'),
|
|
111
|
+
});
|
|
112
|
+
export function registerReplicate(server) {
|
|
113
|
+
server.tool('memlab_replicate', 'Ask whether a measured effect REPRODUCES across two or more independently-driven runs, and refuse to call it real until it does. ' +
|
|
114
|
+
'This is the gate that separates a finding from a one-off, and it is the one gate that cannot be replaced by looking harder at a single run.\n\n' +
|
|
115
|
+
'Give it the same numeric probe and the ladders from N separate runs (or the pre-measured `series` if the snapshots are gone). ' +
|
|
116
|
+
'It fits each run independently and returns REPRODUCED / REPRODUCED_UNSTABLE / NOT_REPRODUCED / INCONCLUSIVE.\n\n' +
|
|
117
|
+
'Why it exists: a detached-DOM finding once passed every other gate — r2 = 1.0000, permanent across 9 minutes of idle with forced GC, ' +
|
|
118
|
+
'97% concentrated under a single dominator, dominator-deduped sizing, an app-side retainer path that `memlab_dev_artifacts` classified as production — ' +
|
|
119
|
+
'and failed to reproduce on all three follow-up runs. Every one of those checks was passed by a one-off. ' +
|
|
120
|
+
'Run this BEFORE writing a finding up, not after.', {
|
|
121
|
+
runs: z
|
|
122
|
+
.array(RunSchema)
|
|
123
|
+
.min(1)
|
|
124
|
+
.describe('Two or more INDEPENDENTLY-DRIVEN runs. Two ladders from the same browser session are not two runs — they share whatever one-off state produced the effect.'),
|
|
125
|
+
code: z
|
|
126
|
+
.string()
|
|
127
|
+
.optional()
|
|
128
|
+
.describe('The numeric probe, identical for every run, exactly as in memlab_ladder_probe. Required unless every run supplies `series`.'),
|
|
129
|
+
label: z
|
|
130
|
+
.string()
|
|
131
|
+
.optional()
|
|
132
|
+
.describe('Name for the measured population.'),
|
|
133
|
+
min_r2: z
|
|
134
|
+
.number()
|
|
135
|
+
.optional()
|
|
136
|
+
.default(0.9)
|
|
137
|
+
.describe('Minimum r2 for a run to count as showing a linear accumulation (default 0.9).'),
|
|
138
|
+
min_delta: z
|
|
139
|
+
.number()
|
|
140
|
+
.optional()
|
|
141
|
+
.default(1)
|
|
142
|
+
.describe('Minimum net growth for a run to count as showing the effect at all (default 1). Raise it to ignore single-object noise.'),
|
|
143
|
+
slope_ratio_tolerance: z
|
|
144
|
+
.number()
|
|
145
|
+
.optional()
|
|
146
|
+
.default(3)
|
|
147
|
+
.describe('How far the per-run slopes may differ and still count as consistent (default 3x). Beyond it the verdict is REPRODUCED_UNSTABLE — real, but do not size a fix off one run.'),
|
|
148
|
+
timeout_ms: z.number().optional().describe('Per-rung execution timeout.'),
|
|
149
|
+
max_nodes: z
|
|
150
|
+
.number()
|
|
151
|
+
.int()
|
|
152
|
+
.min(1)
|
|
153
|
+
.optional()
|
|
154
|
+
.default(20000000)
|
|
155
|
+
.describe('Per-rung node-visit budget for full-heap walks.'),
|
|
156
|
+
max_file_size_mb: z
|
|
157
|
+
.number()
|
|
158
|
+
.optional()
|
|
159
|
+
.describe('Per-file size ceiling, matching memlab_load_snapshot.'),
|
|
160
|
+
}, async ({ runs, code, label, min_r2, min_delta, slope_ratio_tolerance, timeout_ms, max_nodes, max_file_size_mb, }) => {
|
|
161
|
+
try {
|
|
162
|
+
const fits = [];
|
|
163
|
+
const allLabels = [];
|
|
164
|
+
for (let i = 0; i < runs.length; i++) {
|
|
165
|
+
const run = runs[i];
|
|
166
|
+
const runLabel = run.label ?? `run ${i + 1}`;
|
|
167
|
+
let values;
|
|
168
|
+
if (run.series != null && run.series.length > 0) {
|
|
169
|
+
values = run.series;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
if (run.paths == null || run.paths.length === 0) {
|
|
173
|
+
return errorResult(new Error(`${runLabel}: give it either \`paths\` or a pre-measured \`series\`.`));
|
|
174
|
+
}
|
|
175
|
+
if (code == null || code.trim() === '') {
|
|
176
|
+
return errorResult(new Error('Pass `code` — the probe has to be IDENTICAL across runs, otherwise the comparison is between two different questions.'));
|
|
177
|
+
}
|
|
178
|
+
const { paths: resolved } = resolveLadderPaths(run.paths);
|
|
179
|
+
const { rungs: locals, largestMB } = resolveRungs(resolved, max_file_size_mb);
|
|
180
|
+
allLabels.push(...locals.map(r => r.label));
|
|
181
|
+
const effectiveTimeout = scaledTimeoutMs(largestMB, timeout_ms);
|
|
182
|
+
const measured = [];
|
|
183
|
+
for (const { localPath } of locals) {
|
|
184
|
+
armScanBudgetFor(effectiveTimeout);
|
|
185
|
+
const out = await probeRung(localPath, [{ name: 'probe', code }], effectiveTimeout, max_nodes);
|
|
186
|
+
const o = out.get('probe');
|
|
187
|
+
if (o?.value == null) {
|
|
188
|
+
return errorResult(new Error(`${runLabel}: a rung produced no number (${o?.error ?? 'unknown'}). Every rung must yield a value, or the two runs are not comparable.`));
|
|
189
|
+
}
|
|
190
|
+
measured.push(o.value);
|
|
191
|
+
}
|
|
192
|
+
values = measured;
|
|
193
|
+
}
|
|
194
|
+
if (values.length < 2) {
|
|
195
|
+
return errorResult(new Error(`${runLabel} has ${values.length} rung(s); a rate needs at least 2.`));
|
|
196
|
+
}
|
|
197
|
+
const xs = run.cycles_per_rung != null &&
|
|
198
|
+
run.cycles_per_rung.length === values.length
|
|
199
|
+
? run.cycles_per_rung
|
|
200
|
+
: values.map((_, j) => j);
|
|
201
|
+
fits.push(classifyRun(runLabel, values, xs, min_r2, min_delta));
|
|
202
|
+
}
|
|
203
|
+
const { verdict, summary } = adjudicate(fits, slope_ratio_tolerance);
|
|
204
|
+
const lines = [
|
|
205
|
+
`## Replication — ${label != null ? `\`${label}\`` : 'probe'}`,
|
|
206
|
+
'',
|
|
207
|
+
markdownTable(['Run', 'Series', 'Net Δ', 'Slope', 'r2', 'Shows effect?'], fits.map(f => [
|
|
208
|
+
f.label,
|
|
209
|
+
f.values.map(v => formatNumber(v)).join(' → '),
|
|
210
|
+
`${f.delta >= 0 ? '+' : ''}${formatNumber(f.delta)}`,
|
|
211
|
+
f.fit.slope.toFixed(3),
|
|
212
|
+
f.fit.r2.toFixed(4),
|
|
213
|
+
f.grows ? 'yes' : `NO — ${f.reason}`,
|
|
214
|
+
]), new Set([2, 3, 4])),
|
|
215
|
+
'',
|
|
216
|
+
`**Verdict: ${verdict}**`,
|
|
217
|
+
'',
|
|
218
|
+
summary,
|
|
219
|
+
'',
|
|
220
|
+
];
|
|
221
|
+
if (verdict === 'REPRODUCED' || verdict === 'REPRODUCED_UNSTABLE') {
|
|
222
|
+
lines.push('_Replication establishes that the effect is real and repeatable. It does NOT establish the cause — ' +
|
|
223
|
+
'trace a sample with `memlab_retainer_trace` and rule out dev-only retention with `memlab_dev_artifacts` before attributing it._');
|
|
224
|
+
}
|
|
225
|
+
else if (verdict === 'NOT_REPRODUCED') {
|
|
226
|
+
lines.push('_Do not file this. If a previous round already reported it, the honest action is a retraction: ' +
|
|
227
|
+
'a one-off that passed every other gate is exactly what this tool exists to catch, and leaving it ' +
|
|
228
|
+
'on the record costs more than the round it took to find._');
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
lines.push('_Drive a second independent run and re-check. Two ladders from the same browser session do not count — ' +
|
|
232
|
+
'they share whatever one-off state produced the effect._');
|
|
233
|
+
}
|
|
234
|
+
return toolResult(lines.join('\n'), allLabels.length > 0 ? pathsHeader(allLabels) : null);
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
return errorResult(e instanceof Error ? e : new Error(String(e)));
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=replicate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replicate.js","sourceRoot":"","sources":["../../src/tools/replicate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
export declare function registerRetainerDiff(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=retainer-diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retainer-diff.d.ts","sourceRoot":"","sources":["../../src/tools/retainer-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA6BvE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuP5D"}
|