@aletheia-works/vivarium-mcp 0.0.1
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/LICENSE +202 -0
- package/README.md +118 -0
- package/dist/bundled/recipes.json +217 -0
- package/dist/catalogue.d.ts +7 -0
- package/dist/catalogue.d.ts.map +1 -0
- package/dist/catalogue.js +63 -0
- package/dist/catalogue.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +114 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/get_recipe.d.ts +28 -0
- package/dist/tools/get_recipe.d.ts.map +1 -0
- package/dist/tools/get_recipe.js +29 -0
- package/dist/tools/get_recipe.js.map +1 -0
- package/dist/tools/list_recipes.d.ts +34 -0
- package/dist/tools/list_recipes.d.ts.map +1 -0
- package/dist/tools/list_recipes.js +43 -0
- package/dist/tools/list_recipes.js.map +1 -0
- package/dist/tools/lookup_verdict.d.ts +39 -0
- package/dist/tools/lookup_verdict.d.ts.map +1 -0
- package/dist/tools/lookup_verdict.js +60 -0
- package/dist/tools/lookup_verdict.js.map +1 -0
- package/dist/tools/match_error.d.ts +62 -0
- package/dist/tools/match_error.d.ts.map +1 -0
- package/dist/tools/match_error.js +282 -0
- package/dist/tools/match_error.js.map +1 -0
- package/dist/tools/prepare_new_recipe.d.ts +92 -0
- package/dist/tools/prepare_new_recipe.d.ts.map +1 -0
- package/dist/tools/prepare_new_recipe.js +193 -0
- package/dist/tools/prepare_new_recipe.js.map +1 -0
- package/dist/tools/verify_branch_fix.d.ts +49 -0
- package/dist/tools/verify_branch_fix.d.ts.map +1 -0
- package/dist/tools/verify_branch_fix.js +207 -0
- package/dist/tools/verify_branch_fix.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
- package/src/bundled/recipes.json +217 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// Phase 7 B3 — verify_branch_fix tool (5th MCP tool, ADR-0030).
|
|
2
|
+
//
|
|
3
|
+
// A scaffolding helper, NOT an execution engine. Stdio TypeScript can't
|
|
4
|
+
// run php-wasm / pyodide (ADR-0019 §F rejected the headless-browser
|
|
5
|
+
// dependency). The tool's job is to give the agent a deep-link URL plus
|
|
6
|
+
// instructions, leaving execution to the visitor's browser (or to a
|
|
7
|
+
// browser MCP the agent separately drives).
|
|
8
|
+
//
|
|
9
|
+
// Layer dispatch:
|
|
10
|
+
// - Layer 1 → path A. compare_url is the recipe page itself with
|
|
11
|
+
// `?fix_url=` or `?fix=<base64url>` so the visitor's browser does
|
|
12
|
+
// the run. Path A produces a verdict bundle the visitor drops on
|
|
13
|
+
// /repro/compare.
|
|
14
|
+
// - Layer 2/3 → path B. compare_url is /repro/compare with `?slug=`
|
|
15
|
+
// and `?branch_url=` placeholders; gh_command is the
|
|
16
|
+
// `branch-fix-verdict.yml` workflow_dispatch line the agent runs.
|
|
17
|
+
import { getCatalogue } from '../catalogue.js';
|
|
18
|
+
const FIX_INLINE_LIMIT_BYTES = 4 * 1024;
|
|
19
|
+
const PIPELINE_DOC_URL = 'https://aletheia-works.github.io/vivarium/spec/branch-fix-pipeline';
|
|
20
|
+
const D5_DOC_URL_EN = 'https://aletheia-works.github.io/vivarium/guide/compare-branch-fix';
|
|
21
|
+
const D5_DOC_URL_JA = 'https://aletheia-works.github.io/vivarium/ja/guide/compare-branch-fix';
|
|
22
|
+
/* ------------------------------------------------------------------------ */
|
|
23
|
+
/* base64url (encode is sync; decode in Path A's panel) */
|
|
24
|
+
/* ------------------------------------------------------------------------ */
|
|
25
|
+
function base64UrlEncode(text) {
|
|
26
|
+
// Use TextEncoder + manual base64 to preserve UTF-8 semantics; Node's
|
|
27
|
+
// Buffer is available but the package targets a portable ES surface.
|
|
28
|
+
const bytes = new TextEncoder().encode(text);
|
|
29
|
+
let bin = '';
|
|
30
|
+
for (const b of bytes)
|
|
31
|
+
bin += String.fromCharCode(b);
|
|
32
|
+
// Bun and Node both expose `btoa` globally; the package's `engines`
|
|
33
|
+
// pins them.
|
|
34
|
+
const b64 = typeof btoa === 'function'
|
|
35
|
+
? btoa(bin)
|
|
36
|
+
: Buffer.from(bytes).toString('base64');
|
|
37
|
+
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
38
|
+
}
|
|
39
|
+
function pathACompareUrl(inputs) {
|
|
40
|
+
const u = new URL(inputs.pageUrl);
|
|
41
|
+
if (inputs.fix_url)
|
|
42
|
+
u.searchParams.set('fix_url', inputs.fix_url);
|
|
43
|
+
else if (inputs.fix_source)
|
|
44
|
+
u.searchParams.set('fix', base64UrlEncode(inputs.fix_source));
|
|
45
|
+
return u.toString();
|
|
46
|
+
}
|
|
47
|
+
function pathBCompareUrl(inputs) {
|
|
48
|
+
const u = new URL(inputs.compareBaseUrl);
|
|
49
|
+
u.searchParams.set('slug', inputs.slug);
|
|
50
|
+
return u.toString();
|
|
51
|
+
}
|
|
52
|
+
function deriveCompareBaseFromPageUrl(pageUrl) {
|
|
53
|
+
// page_url is e.g. https://aletheia-works.github.io/vivarium/repro/<slug>/.
|
|
54
|
+
// The compare page sits at /repro/compare under both /en and /ja chrome.
|
|
55
|
+
// Default to no-locale (legacy /repro/compare) — R.3 mounts the same
|
|
56
|
+
// component in both locales.
|
|
57
|
+
try {
|
|
58
|
+
const u = new URL(pageUrl);
|
|
59
|
+
return `${u.origin}/vivarium/repro/compare`;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return 'https://aletheia-works.github.io/vivarium/repro/compare';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function buildInstructions(inputs) {
|
|
66
|
+
if (inputs.path === 'A') {
|
|
67
|
+
const headline = inputs.fixSupplied
|
|
68
|
+
? `Open ${inputs.compareUrl} in a browser. The fix is pre-loaded — the page will run it through php-wasm/ruby.wasm/pyodide and capture a Contract v1 verdict.`
|
|
69
|
+
: `Open ${inputs.compareUrl} in a browser, paste the candidate fix into the "Try a fix" panel, and click Run. The page will run it through the recipe's WASM runtime and capture a verdict.`;
|
|
70
|
+
return [
|
|
71
|
+
`**${inputs.recipe.title}** — Layer 1 (Path A: in-browser source substitution).`,
|
|
72
|
+
'',
|
|
73
|
+
headline,
|
|
74
|
+
'',
|
|
75
|
+
'After the run completes:',
|
|
76
|
+
`1. Download \`branch-fix-verdict.json\` and \`original-verdict.json\` from the panel.`,
|
|
77
|
+
`2. Drop both onto ${deriveCompareBaseFromPageUrl(inputs.recipe.page_url)} for side-by-side review.`,
|
|
78
|
+
'',
|
|
79
|
+
`**Verdict semantics.** \`reproduced\` = bug still triggers (fix is slop). \`unreproduced\` = bug avoided (fix steers around the broken code path). See [the walkthrough](${D5_DOC_URL_EN}) ([日本語版](${D5_DOC_URL_JA})) for the full loop.`,
|
|
80
|
+
].join('\n');
|
|
81
|
+
}
|
|
82
|
+
// Path B
|
|
83
|
+
return [
|
|
84
|
+
`**${inputs.recipe.title}** — Layer ${inputs.recipe.layer} (Path B: Docker image-based).`,
|
|
85
|
+
'',
|
|
86
|
+
`Build and push your branch-fix Docker image to a public registry the GitHub Actions runner can pull. Then run:`,
|
|
87
|
+
'',
|
|
88
|
+
'```bash',
|
|
89
|
+
inputs.ghCommand ?? '(gh command unavailable)',
|
|
90
|
+
'```',
|
|
91
|
+
'',
|
|
92
|
+
`Once the workflow finishes:`,
|
|
93
|
+
`1. Download the \`branch-fix-verdict-${inputs.recipe.slug}-<run_id>\` artefact from the workflow run.`,
|
|
94
|
+
`2. Drop the zip onto ${inputs.compareUrl} for side-by-side review (or pass \`?branch_url=\` with a publicly fetchable URL of the verdict JSON).`,
|
|
95
|
+
'',
|
|
96
|
+
`**Verdict semantics.** A working fix flips the verdict from \`reproduced\` to \`unreproduced\`. Pipeline spec: ${PIPELINE_DOC_URL}. Walkthrough: [English](${D5_DOC_URL_EN}) · [日本語](${D5_DOC_URL_JA}).`,
|
|
97
|
+
].join('\n');
|
|
98
|
+
}
|
|
99
|
+
/* ------------------------------------------------------------------------ */
|
|
100
|
+
/* Tool */
|
|
101
|
+
/* ------------------------------------------------------------------------ */
|
|
102
|
+
export async function verifyBranchFix(args) {
|
|
103
|
+
const slug = args.slug?.trim();
|
|
104
|
+
if (!slug) {
|
|
105
|
+
return { ok: false, error: 'missing required argument: slug' };
|
|
106
|
+
}
|
|
107
|
+
if (args.fix_url && args.fix_source) {
|
|
108
|
+
return {
|
|
109
|
+
ok: false,
|
|
110
|
+
error: 'fix_url and fix_source are mutually exclusive — supply at most one',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (args.fix_source && args.fix_source.length > FIX_INLINE_LIMIT_BYTES) {
|
|
114
|
+
return {
|
|
115
|
+
ok: false,
|
|
116
|
+
error: `fix_source exceeds the ${FIX_INLINE_LIMIT_BYTES}-byte inline limit; use fix_url with a publicly fetchable URL instead`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const { recipes } = await getCatalogue();
|
|
120
|
+
const recipe = recipes.find((r) => r.slug === slug);
|
|
121
|
+
if (!recipe) {
|
|
122
|
+
return { ok: false, error: `recipe not found: ${slug}` };
|
|
123
|
+
}
|
|
124
|
+
const notes = [];
|
|
125
|
+
if (recipe.layer === 1) {
|
|
126
|
+
if (args.fix_url || args.fix_source) {
|
|
127
|
+
// Path A inputs are valid; pre-load.
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
notes.push('no fix_url or fix_source supplied — compare_url opens the recipe page; the user pastes manually into the "Try a fix" panel');
|
|
131
|
+
}
|
|
132
|
+
const compareUrl = pathACompareUrl({
|
|
133
|
+
pageUrl: recipe.page_url,
|
|
134
|
+
fix_url: args.fix_url,
|
|
135
|
+
fix_source: args.fix_source,
|
|
136
|
+
});
|
|
137
|
+
const instructions = buildInstructions({
|
|
138
|
+
recipe,
|
|
139
|
+
path: 'A',
|
|
140
|
+
compareUrl,
|
|
141
|
+
fixSupplied: Boolean(args.fix_url || args.fix_source),
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
ok: true,
|
|
145
|
+
slug: recipe.slug,
|
|
146
|
+
layer: recipe.layer,
|
|
147
|
+
path: 'A',
|
|
148
|
+
page_url: recipe.page_url,
|
|
149
|
+
compare_url: compareUrl,
|
|
150
|
+
instructions,
|
|
151
|
+
notes,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// Layer 2 / 3 → Path B.
|
|
155
|
+
if (args.fix_url || args.fix_source) {
|
|
156
|
+
notes.push('fix_url and fix_source are ignored for Layer 2/3 recipes — the contributor builds and pushes a Docker image themselves; see ADR-0020 §1 for the image-as-input boundary');
|
|
157
|
+
}
|
|
158
|
+
const compareBase = deriveCompareBaseFromPageUrl(recipe.page_url);
|
|
159
|
+
const compareUrl = pathBCompareUrl({
|
|
160
|
+
slug: recipe.slug,
|
|
161
|
+
compareBaseUrl: compareBase,
|
|
162
|
+
});
|
|
163
|
+
const ghCommand = `gh workflow run branch-fix-verdict.yml --repo aletheia-works/vivarium -f slug=${recipe.slug} -f branch_image=<your-image-ref>`;
|
|
164
|
+
const instructions = buildInstructions({
|
|
165
|
+
recipe,
|
|
166
|
+
path: 'B',
|
|
167
|
+
compareUrl,
|
|
168
|
+
ghCommand,
|
|
169
|
+
fixSupplied: false,
|
|
170
|
+
});
|
|
171
|
+
return {
|
|
172
|
+
ok: true,
|
|
173
|
+
slug: recipe.slug,
|
|
174
|
+
layer: recipe.layer,
|
|
175
|
+
path: 'B',
|
|
176
|
+
page_url: recipe.page_url,
|
|
177
|
+
compare_url: compareUrl,
|
|
178
|
+
gh_command: ghCommand,
|
|
179
|
+
instructions,
|
|
180
|
+
notes,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
export const VERIFY_BRANCH_FIX_TOOL = {
|
|
184
|
+
name: 'verify_branch_fix',
|
|
185
|
+
description: "Generate a deep-link URL and instructions for verifying a candidate branch-fix against a Vivarium recipe. SCAFFOLDING HELPER, not an execution engine — actual reproduction runs in the visitor's browser (Layer 1) or in GitHub Actions (Layer 2/3). Layer dispatch is automatic from the recipe's catalogue layer. Layer 1 returns Path A: a recipe-page URL with the fix pre-loaded via `?fix_url=` or `?fix=<base64url>`. Layer 2/3 returns Path B: a `/repro/compare` URL plus the `gh workflow run branch-fix-verdict.yml` command the contributor runs to capture a verdict against their pushed Docker image. Use after `match_error` or `list_recipes` has narrowed to a specific slug. Pair with the D-5 walkthrough page (https://aletheia-works.github.io/vivarium/guide/compare-branch-fix) for the full AI-slop verification loop.",
|
|
186
|
+
inputSchema: {
|
|
187
|
+
type: 'object',
|
|
188
|
+
properties: {
|
|
189
|
+
slug: {
|
|
190
|
+
type: 'string',
|
|
191
|
+
pattern: '^[a-z0-9]+(-[a-z0-9]+)*$',
|
|
192
|
+
description: "Kebab-case recipe slug (e.g. 'php-12167', 'bash-local-shadows-exit'). Same convention as Manifest v1's `slug`.",
|
|
193
|
+
},
|
|
194
|
+
fix_url: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
description: "Public URL of the candidate fix source (raw.githubusercontent.com / gist.githubusercontent.com). Layer 1 only — embedded in the returned compare_url as `?fix_url=`. Mutually exclusive with fix_source.",
|
|
197
|
+
},
|
|
198
|
+
fix_source: {
|
|
199
|
+
type: 'string',
|
|
200
|
+
maxLength: FIX_INLINE_LIMIT_BYTES,
|
|
201
|
+
description: "Inline candidate fix source (max 4096 bytes). Layer 1 only — embedded in the returned compare_url as `?fix=<base64url>`. Mutually exclusive with fix_url. Long fixes should use fix_url instead.",
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
required: ['slug'],
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=verify_branch_fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify_branch_fix.js","sourceRoot":"","sources":["../../src/tools/verify_branch_fix.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type Layer = 1 | 2 | 3;
|
|
2
|
+
export interface RecipeEntry {
|
|
3
|
+
slug: string;
|
|
4
|
+
layer: Layer;
|
|
5
|
+
project: string;
|
|
6
|
+
issue: number;
|
|
7
|
+
title: string;
|
|
8
|
+
page_url: string;
|
|
9
|
+
verdict_url?: string;
|
|
10
|
+
source_url: string;
|
|
11
|
+
language?: string;
|
|
12
|
+
symptom?: string;
|
|
13
|
+
severity?: string;
|
|
14
|
+
tags?: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface RecipesIndex {
|
|
17
|
+
index: 'v1';
|
|
18
|
+
contract: 'v1';
|
|
19
|
+
recipes: RecipeEntry[];
|
|
20
|
+
}
|
|
21
|
+
export type Verdict = 'reproduced' | 'unreproduced';
|
|
22
|
+
export interface VerdictSnapshot {
|
|
23
|
+
contract: 'v1';
|
|
24
|
+
verdict: Verdict;
|
|
25
|
+
exit_code: number;
|
|
26
|
+
image_tag: string;
|
|
27
|
+
image_digest: string;
|
|
28
|
+
captured_at: string;
|
|
29
|
+
stdout: string;
|
|
30
|
+
stderr_tail: string;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE9B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IAInB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,EAAE,IAAI,CAAC;IACf,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,cAAc,CAAC;AAKpD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,IAAI,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Type definitions for the Vivarium recipes index (locked at v1 by
|
|
2
|
+
// ADR-0019, private memo) and the per-recipe verdict snapshot (Contract
|
|
3
|
+
// v1, ADR-0014, with the optional revision-2 evidence surface from
|
|
4
|
+
// ADR-0018). Kept structural and surface-only — the canonical schemas
|
|
5
|
+
// live at:
|
|
6
|
+
//
|
|
7
|
+
// https://aletheia-works.github.io/vivarium/api/recipes.schema.json
|
|
8
|
+
// https://aletheia-works.github.io/vivarium/spec/verdict.schema.json
|
|
9
|
+
//
|
|
10
|
+
// Consumers who need runtime validation should fetch and validate against
|
|
11
|
+
// those JSON Schemas; this module's types are an ergonomic façade for
|
|
12
|
+
// the in-process tool implementations.
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,wEAAwE;AACxE,mEAAmE;AACnE,sEAAsE;AACtE,WAAW;AACX,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,EAAE;AACF,0EAA0E;AAC1E,sEAAsE;AACtE,uCAAuC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aletheia-works/vivarium-mcp",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "MCP server exposing the Vivarium reproduction catalogue (list_recipes, get_recipe, lookup_verdict, match_error, verify_branch_fix) to AI agent clients (Claude Code, Cline, Cursor, Continue, etc.).",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://github.com/aletheia-works/vivarium/tree/main/packages/mcp-server",
|
|
7
|
+
"bugs": {
|
|
8
|
+
"url": "https://github.com/aletheia-works/vivarium/issues"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/aletheia-works/vivarium.git",
|
|
13
|
+
"directory": "packages/mcp-server"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"bin": {
|
|
19
|
+
"vivarium-mcp": "dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"src/bundled",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"test": "bun test",
|
|
30
|
+
"prepublishOnly": "bun run build"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/bun": "^1.3.13",
|
|
37
|
+
"@types/node": "^25.6.0",
|
|
38
|
+
"typescript": "^6.0.3"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=24",
|
|
42
|
+
"bun": ">=1.2.0"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"mcp",
|
|
46
|
+
"model-context-protocol",
|
|
47
|
+
"vivarium",
|
|
48
|
+
"bug-reproduction",
|
|
49
|
+
"catalogue",
|
|
50
|
+
"ai-tools"
|
|
51
|
+
],
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"provenance": true
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
{
|
|
2
|
+
"index": "v1",
|
|
3
|
+
"contract": "v1",
|
|
4
|
+
"recipes": [
|
|
5
|
+
{
|
|
6
|
+
"slug": "cpython-137205",
|
|
7
|
+
"layer": 1,
|
|
8
|
+
"project": "cpython",
|
|
9
|
+
"issue": 137205,
|
|
10
|
+
"title": "python/cpython#137205",
|
|
11
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/cpython/137205/",
|
|
12
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer1_wasm/cpython-137205",
|
|
13
|
+
"language": "python",
|
|
14
|
+
"tags": [
|
|
15
|
+
"sqlite3",
|
|
16
|
+
"pragma",
|
|
17
|
+
"foreign-keys",
|
|
18
|
+
"autocommit"
|
|
19
|
+
],
|
|
20
|
+
"symptom": "fk-pragma-silently-dropped",
|
|
21
|
+
"severity": "spec-violation"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"slug": "numpy-28287",
|
|
25
|
+
"layer": 1,
|
|
26
|
+
"project": "numpy",
|
|
27
|
+
"issue": 28287,
|
|
28
|
+
"title": "numpy/numpy#28287",
|
|
29
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/numpy/28287/",
|
|
30
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer1_wasm/numpy-28287",
|
|
31
|
+
"language": "python",
|
|
32
|
+
"tags": [
|
|
33
|
+
"timedelta64",
|
|
34
|
+
"comparison",
|
|
35
|
+
"datetime-units"
|
|
36
|
+
],
|
|
37
|
+
"symptom": "ordering-non-transitive",
|
|
38
|
+
"severity": "bug"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"slug": "pandas-56679",
|
|
42
|
+
"layer": 1,
|
|
43
|
+
"project": "pandas",
|
|
44
|
+
"issue": 56679,
|
|
45
|
+
"title": "pandas-dev/pandas#56679",
|
|
46
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/pandas/56679/",
|
|
47
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer1_wasm/pandas-56679",
|
|
48
|
+
"language": "python",
|
|
49
|
+
"tags": [
|
|
50
|
+
"empty-series",
|
|
51
|
+
"empty-dataframe",
|
|
52
|
+
"type-inference"
|
|
53
|
+
],
|
|
54
|
+
"symptom": "dtype-mismatch",
|
|
55
|
+
"severity": "regression"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"slug": "php-12167",
|
|
59
|
+
"layer": 1,
|
|
60
|
+
"project": "php",
|
|
61
|
+
"issue": 12167,
|
|
62
|
+
"title": "php/php-src#12167",
|
|
63
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/php/12167/",
|
|
64
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer1_wasm/php-12167",
|
|
65
|
+
"language": "php",
|
|
66
|
+
"tags": [
|
|
67
|
+
"json_encode",
|
|
68
|
+
"recursion-depth"
|
|
69
|
+
],
|
|
70
|
+
"symptom": "json-encode-recursion",
|
|
71
|
+
"severity": "bug"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"slug": "regex-779",
|
|
75
|
+
"layer": 1,
|
|
76
|
+
"project": "regex",
|
|
77
|
+
"issue": 779,
|
|
78
|
+
"title": "rust-lang/regex#779",
|
|
79
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/regex/779/",
|
|
80
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer1_wasm/regex-779",
|
|
81
|
+
"language": "rust",
|
|
82
|
+
"tags": [
|
|
83
|
+
"regex",
|
|
84
|
+
"wasm32-wasip1"
|
|
85
|
+
],
|
|
86
|
+
"symptom": "regex-engine-edge-case",
|
|
87
|
+
"severity": "bug"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"slug": "ruby-21709",
|
|
91
|
+
"layer": 1,
|
|
92
|
+
"project": "ruby",
|
|
93
|
+
"issue": 21709,
|
|
94
|
+
"title": "ruby/ruby#21709",
|
|
95
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/ruby/21709/",
|
|
96
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer1_wasm/ruby-21709",
|
|
97
|
+
"language": "ruby",
|
|
98
|
+
"tags": [
|
|
99
|
+
"string",
|
|
100
|
+
"unicode",
|
|
101
|
+
"combining-diacritics"
|
|
102
|
+
],
|
|
103
|
+
"symptom": "unicode-normalize-nfd",
|
|
104
|
+
"severity": "bug"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"slug": "bash-local-shadows-exit",
|
|
108
|
+
"layer": 2,
|
|
109
|
+
"project": "bash",
|
|
110
|
+
"issue": 0,
|
|
111
|
+
"title": "bash `local` shadows command-substitution exit code",
|
|
112
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/bash/local-shadows-exit/",
|
|
113
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer2_docker/bash-local-shadows-exit",
|
|
114
|
+
"language": "shell",
|
|
115
|
+
"tags": [
|
|
116
|
+
"bash",
|
|
117
|
+
"command-substitution",
|
|
118
|
+
"exit-code"
|
|
119
|
+
],
|
|
120
|
+
"symptom": "local-shadows-exit-status",
|
|
121
|
+
"severity": "footgun",
|
|
122
|
+
"verdict_url": "https://aletheia-works.github.io/vivarium/repro/bash/local-shadows-exit/verdict.json"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"slug": "find-xargs-whitespace",
|
|
126
|
+
"layer": 2,
|
|
127
|
+
"project": "find",
|
|
128
|
+
"issue": 0,
|
|
129
|
+
"title": "`find … | xargs cmd` is unsafe for whitespace in filenames",
|
|
130
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/find/xargs-whitespace/",
|
|
131
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer2_docker/find-xargs-whitespace",
|
|
132
|
+
"language": "shell",
|
|
133
|
+
"tags": [
|
|
134
|
+
"find",
|
|
135
|
+
"xargs",
|
|
136
|
+
"whitespace",
|
|
137
|
+
"filenames"
|
|
138
|
+
],
|
|
139
|
+
"symptom": "whitespace-unsafe-pipeline",
|
|
140
|
+
"severity": "footgun",
|
|
141
|
+
"verdict_url": "https://aletheia-works.github.io/vivarium/repro/find/xargs-whitespace/verdict.json"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"slug": "flock-is-advisory",
|
|
145
|
+
"layer": 2,
|
|
146
|
+
"project": "flock",
|
|
147
|
+
"issue": 0,
|
|
148
|
+
"title": "`flock(2)` is advisory only",
|
|
149
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/flock/is-advisory/",
|
|
150
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer2_docker/flock-is-advisory",
|
|
151
|
+
"language": "shell",
|
|
152
|
+
"tags": [
|
|
153
|
+
"flock",
|
|
154
|
+
"filesystem",
|
|
155
|
+
"concurrency"
|
|
156
|
+
],
|
|
157
|
+
"symptom": "advisory-lock-bypass",
|
|
158
|
+
"severity": "spec-violation",
|
|
159
|
+
"verdict_url": "https://aletheia-works.github.io/vivarium/repro/flock/is-advisory/verdict.json"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"slug": "node-63041",
|
|
163
|
+
"layer": 2,
|
|
164
|
+
"project": "node",
|
|
165
|
+
"issue": 63041,
|
|
166
|
+
"title": "Node.js `Intl.DateTimeFormat` drops month with `calendar: 'iso8601'`",
|
|
167
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/node/63041/",
|
|
168
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer2_docker/node-63041",
|
|
169
|
+
"language": "javascript",
|
|
170
|
+
"tags": [
|
|
171
|
+
"intl",
|
|
172
|
+
"datetimeformat",
|
|
173
|
+
"iso8601-calendar",
|
|
174
|
+
"icu"
|
|
175
|
+
],
|
|
176
|
+
"symptom": "intl-month-dropped",
|
|
177
|
+
"severity": "regression",
|
|
178
|
+
"verdict_url": "https://aletheia-works.github.io/vivarium/repro/node/63041/verdict.json"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"slug": "postgres-lost-update",
|
|
182
|
+
"layer": 2,
|
|
183
|
+
"project": "postgres",
|
|
184
|
+
"issue": 0,
|
|
185
|
+
"title": "PostgreSQL lost update under READ COMMITTED",
|
|
186
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/postgres/lost-update/",
|
|
187
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer2_docker/postgres-lost-update",
|
|
188
|
+
"language": "sql",
|
|
189
|
+
"tags": [
|
|
190
|
+
"postgresql",
|
|
191
|
+
"isolation-level",
|
|
192
|
+
"concurrency"
|
|
193
|
+
],
|
|
194
|
+
"symptom": "lost-update-read-committed",
|
|
195
|
+
"severity": "datarace",
|
|
196
|
+
"verdict_url": "https://aletheia-works.github.io/vivarium/repro/postgres/lost-update/verdict.json"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"slug": "lost-update",
|
|
200
|
+
"layer": 3,
|
|
201
|
+
"project": "pthread",
|
|
202
|
+
"issue": 0,
|
|
203
|
+
"title": "pthread lost-update data race (canonical)",
|
|
204
|
+
"page_url": "https://aletheia-works.github.io/vivarium/repro/pthread/lost-update/",
|
|
205
|
+
"source_url": "https://github.com/aletheia-works/vivarium/tree/main/src/layer3_thirdway/lost-update",
|
|
206
|
+
"language": "c",
|
|
207
|
+
"tags": [
|
|
208
|
+
"pthread",
|
|
209
|
+
"rr-replay",
|
|
210
|
+
"deterministic"
|
|
211
|
+
],
|
|
212
|
+
"symptom": "lost-update-data-race",
|
|
213
|
+
"severity": "datarace",
|
|
214
|
+
"verdict_url": "https://aletheia-works.github.io/vivarium/repro/pthread/lost-update/verdict.json"
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|