feat(genbi): provision managed Wren runtime

This commit is contained in:
Jax Liu
2026-09-07 11:04:34 +08:00
parent ed4ebf30a9
commit a126dde42e
11 changed files with 713 additions and 8 deletions
+134
View File
@@ -0,0 +1,134 @@
name: Stage managed Wren runtime
on:
workflow_dispatch:
inputs:
runtime_tag:
description: Immutable managed-Wren release tag
required: true
type: string
license_approval:
description: Must be approved after legal review; protected environment is the authority
required: true
default: pending
type: choice
options: [pending, approved]
permissions:
contents: read
jobs:
stage:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Resolve and download the exact darwin-arm64 wheel closure
run: |
mkdir -p release/wheels
python -m pip download --only-binary=:all: --platform macosx_11_0_arm64 --python-version 3.11 --implementation cp --dest release/wheels 'wrenai==0.13.0'
python - <<'PY'
import hashlib, pathlib
target = pathlib.Path('release/wheels/wrenai-0.13.0-py3-none-any.whl')
assert target.is_file()
assert hashlib.sha256(target.read_bytes()).hexdigest() == '1cb14927c9a1e1925a7295c2772e5852254c6cc370db640ccc33b6cd04e95dae'
PY
- name: Verify and stage the exact CPython archive
run: |
python - <<'PY'
import hashlib, pathlib, urllib.request
target = pathlib.Path('release/cpython-3.11.16+20260901-aarch64-apple-darwin-install_only.tar.gz')
urllib.request.urlretrieve('https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-apple-darwin-install_only.tar.gz', target)
assert hashlib.sha256(target.read_bytes()).hexdigest() == '50424fa409e8ae84b82a3052522f64695b47dff2158b70bb7358e0ebd6c085c9'
PY
- name: Inventory every selected wheel licence and digest
run: |
python - <<'PY'
import hashlib, json, pathlib, urllib.request, zipfile
rows = []
for wheel in sorted(pathlib.Path('release/wheels').glob('*.whl')):
with zipfile.ZipFile(wheel) as archive:
metadata = next(name for name in archive.namelist() if name.endswith('.dist-info/METADATA'))
fields = {}
for line in archive.read(metadata).decode('utf-8', 'replace').splitlines():
if ': ' in line:
key, value = line.split(': ', 1)
if key in ('Name', 'Version', 'License'): fields[key] = value
if not fields.get('Name') or not fields.get('Version'):
raise SystemExit(f'missing wheel identity: {wheel.name}')
sha256 = hashlib.sha256(wheel.read_bytes()).hexdigest()
project = json.load(urllib.request.urlopen(f"https://pypi.org/pypi/{fields['Name']}/{fields['Version']}/json"))
match = next((item for item in project['urls'] if item['filename'] == wheel.name and item['digests']['sha256'] == sha256), None)
if match is None:
raise SystemExit(f'missing immutable source identity: {wheel.name}')
rows.append({'filename': wheel.name, 'sha256': sha256, 'distribution': fields['Name'].lower().replace('-', '_'), 'version': fields['Version'], 'license': fields.get('License', 'UNKNOWN'), 'sourceUrl': match['url']})
pathlib.Path('release/wheel-license-inventory.json').write_text(json.dumps({'schema': 1, 'platform': 'darwin-arm64', 'wheels': rows}, indent=2) + '\n')
pathlib.Path('release/wheel-inputs.json').write_text(json.dumps(rows, indent=2) + '\n')
PY
- name: Build the selected runtime without an index or dependency resolver
run: |
mkdir -p release/runtime
tar -xzf release/cpython-*.tar.gz -C release/runtime
release/runtime/python/install/bin/python3.11 -m venv release/runtime/venv
python - <<'PY'
import json, pathlib
wheels = json.loads(pathlib.Path('release/wheel-inputs.json').read_text())
pathlib.Path('release/requirements.txt').write_text(''.join(f"{wheel['distribution']}=={wheel['version']} --hash=sha256:{wheel['sha256']}\n" for wheel in wheels))
PY
release/runtime/venv/bin/python -m pip install --no-index --no-deps --require-hashes --find-links release/wheels -r release/requirements.txt
- name: Generate attested candidate manifest and preliminary licence inventory
run: node apps/genbi/scripts/managed-wren-release.mjs release "${{ inputs.runtime_tag }}"
- name: Upload review-only release evidence
uses: actions/upload-artifact@v4
with:
name: managed-wren-staged-evidence
path: release/
publish-approved-runtime:
needs: stage
if: ${{ inputs.license_approval == 'approved' }}
environment: managed-wren-license-approved
permissions:
contents: write
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
persist-credentials: false
- uses: actions/download-artifact@v4
with:
name: managed-wren-staged-evidence
path: release
- name: Require protected-environment approval evidence
run: |
test "${{ inputs.license_approval }}" = approved
test -s release/license-inventory.json
test -s release/wheel-license-inventory.json
test -s release/provenance.json
test -s release/managed-wren-manifest.candidate.json
- name: Emit the approval-bound immutable manifest
run: |
node - <<'NODE'
const fs = require('node:fs');
const manifest = JSON.parse(fs.readFileSync('release/managed-wren-manifest.candidate.json', 'utf8'));
manifest.activation = 'approved';
manifest.licenseApproval = { state: 'approved', evidence: `protected-environment:${process.env.RUNTIME_TAG}` };
fs.writeFileSync('release/managed-wren-manifest.json', JSON.stringify(manifest, null, 2) + '\n', { mode: 0o600 });
NODE
env:
RUNTIME_TAG: ${{ inputs.runtime_tag }}
- name: Publication is release-only and must be completed by the approved release job
run: |
gh release create "${{ inputs.runtime_tag }}" \
--title "Managed Wren runtime ${{ inputs.runtime_tag }}" \
release/cpython-*.tar.gz release/wheels/*.whl release/*.json
echo "The staging job cannot publish assets or activate a package manifest."
+44
View File
@@ -0,0 +1,44 @@
{
"schema": 1,
"activation": "staged",
"platform": "darwin-arm64",
"compatibility": {
"genbi": "0.0.4",
"profile": "genbi-native-v4",
"wren": "0.13.0"
},
"python": {
"implementation": "cpython",
"version": "3.11.16",
"upstream": {
"release": "20260901",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
"sha256": "50424fa409e8ae84b82a3052522f64695b47dff2158b70bb7358e0ebd6c085c9"
},
"mirror": {
"url": "https://github.com/Canner/WrenAI/releases/download/managed-wren-v0.0.4/cpython-3.11.16%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
"sha256": "50424fa409e8ae84b82a3052522f64695b47dff2158b70bb7358e0ebd6c085c9"
},
"interpreterPath": "python/install/bin/python3.11"
},
"wheels": [
{
"distribution": "wrenai",
"version": "0.13.0",
"filename": "wrenai-0.13.0-py3-none-any.whl",
"url": "https://github.com/Canner/WrenAI/releases/download/managed-wren-v0.0.4/wrenai-0.13.0-py3-none-any.whl",
"sourceUrl": "https://files.pythonhosted.org/packages/7f/40/2de81f1a3fe332ebfb8ec5db0161ce4b521dee5c1d0d4adf9c5693651b51/wrenai-0.13.0-py3-none-any.whl",
"sha256": "1cb14927c9a1e1925a7295c2772e5852254c6cc370db640ccc33b6cd04e95dae"
}
],
"runtime": {
"pythonArchivePath": "python.tar.gz",
"venvInterpreterPath": "venv/bin/python",
"launcherPath": "venv/bin/wren",
"module": "wren.cli:app",
"packagePath": "venv/lib/python3.11/site-packages/wren",
"packageTreeSha256": "staged",
"closureSha256": "staged"
},
"licenseApproval": { "state": "pending" }
}
@@ -0,0 +1,21 @@
{
"schema": 1,
"platform": "darwin-arm64",
"compatibility": {
"genbi": "0.0.4",
"profile": "genbi-native-v4"
},
"python": {
"version": "3.11.16",
"release": "20260901",
"filename": "cpython-3.11.16+20260901-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
"sha256": "50424fa409e8ae84b82a3052522f64695b47dff2158b70bb7358e0ebd6c085c9"
},
"wrenai": {
"version": "0.13.0",
"filename": "wrenai-0.13.0-py3-none-any.whl",
"url": "https://files.pythonhosted.org/packages/7f/40/2de81f1a3fe332ebfb8ec5db0161ce4b521dee5c1d0d4adf9c5693651b51/wrenai-0.13.0-py3-none-any.whl",
"sha256": "1cb14927c9a1e1925a7295c2772e5852254c6cc370db640ccc33b6cd04e95dae"
}
}
+2 -1
View File
@@ -89,7 +89,8 @@
"dist-server/server",
"dist-server/harness",
"dist-server/providers",
"profiles"
"profiles",
"managed-wren"
],
"publishConfig": {
"access": "public"
@@ -382,7 +382,7 @@ function assertPublishedFiles(files) {
const forbidden = /(^|\/)(scripts|test|tests|fixtures|examples|\.git)(\/|$)|(^|\/)node_modules(\/|$)/;
const unexpected = files.filter((file) => forbidden.test(file));
if (unexpected.length > 0) throw new Error(`package tarball contains repository-only files: ${JSON.stringify(unexpected)}`);
for (const required of ["package/bin/genbi.mjs", "package/dist/index.html", "package/dist-server/server/bin.js"]) {
for (const required of ["package/bin/genbi.mjs", "package/dist/index.html", "package/dist-server/server/bin.js", "package/managed-wren/manifest.json"]) {
if (!files.includes(required)) throw new Error(`package tarball is missing ${required}`);
}
}
@@ -0,0 +1,54 @@
#!/usr/bin/env node
/** Generate review-only managed-Wren release evidence; it never publishes. */
import { createHash } from "node:crypto";
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const [output, runtimeTag] = process.argv.slice(2);
if (!output || !runtimeTag || !/^[A-Za-z0-9._-]+$/.test(runtimeTag)) throw new Error("usage: managed-wren-release.mjs <output-directory> <runtime-tag>");
const inputs = JSON.parse(await readFile(path.join(packageRoot, "managed-wren", "release-inputs.json"), "utf8"));
const digest = (value) => createHash("sha256").update(value).digest("hex");
const fileDigest = async (target) => digest(await readFile(target));
const stableJson = (value) => Array.isArray(value) ? "[" + value.map(stableJson).join(",") + "]" : value && typeof value === "object" ? "{" + Object.keys(value).sort().map((key) => JSON.stringify(key) + ":" + stableJson(value[key])).join(",") + "}" : JSON.stringify(value);
const treeDigest = async (root) => {
const entries = [];
const visit = async (directory) => {
for (const name of (await readdir(directory)).sort()) {
if (name === "__pycache__") continue;
const target = path.join(directory, name); const metadata = await stat(target);
if (metadata.isDirectory()) await visit(target); else if (metadata.isFile()) entries.push(path.relative(root, target) + "\0" + await fileDigest(target)); else throw new Error("unsupported runtime entry: " + target);
}
};
await visit(root); return digest(entries.join("\n"));
};
for (const artifact of [inputs.python, inputs.wrenai]) {
if (!artifact || !/^https:/.test(artifact.url) || !/^[a-f0-9]{64}$/.test(artifact.sha256) || !/^[A-Za-z0-9._+%-]+$/.test(artifact.filename)) throw new Error("invalid exact release input");
}
const wheelInputs = JSON.parse(await readFile(path.join(output, "wheel-inputs.json"), "utf8"));
if (!Array.isArray(wheelInputs) || wheelInputs.length === 0) throw new Error("missing selected wheel closure");
const wheelLicenses = new Map(wheelInputs.map((wheel) => [wheel.filename, wheel.license]));
const wheels = wheelInputs.map((wheel) => {
if (!/^[a-z0-9][a-z0-9._-]*$/.test(wheel.distribution) || !/^[A-Za-z0-9!+._-]+$/.test(wheel.version) || !/^[A-Za-z0-9._+%-]+$/.test(wheel.filename) || !/^https:/.test(wheel.sourceUrl) || !/^[a-f0-9]{64}$/.test(wheel.sha256)) throw new Error("invalid selected wheel closure");
return { distribution: wheel.distribution, version: wheel.version, filename: wheel.filename, sourceUrl: wheel.sourceUrl, sha256: wheel.sha256, url: "https://github.com/Canner/WrenAI/releases/download/" + runtimeTag + "/" + wheel.filename };
}).sort((a, b) => a.filename.localeCompare(b.filename));
const wrenIndex = wheels.findIndex((wheel) => wheel.distribution === "wrenai" && wheel.version === inputs.wrenai.version);
if (wrenIndex < 0) throw new Error("wrenai is absent from the selected wheel closure");
const [wrenai] = wheels.splice(wrenIndex, 1); wheels.unshift(wrenai);
const packageTreeSha256 = await treeDigest(path.join(output, "runtime", "venv", "lib", "python3.11", "site-packages", "wren"));
const closureSha256 = digest(wheels.map((wheel) => wheel.filename + "\0" + wheel.sha256).sort().join("\n"));
const manifest = {
schema: 1, activation: "staged", platform: "darwin-arm64",
compatibility: { genbi: inputs.compatibility.genbi, profile: inputs.compatibility.profile, wren: inputs.wrenai.version },
python: { implementation: "cpython", version: inputs.python.version, upstream: { release: inputs.python.release, url: inputs.python.url, sha256: inputs.python.sha256 }, mirror: { url: "https://github.com/Canner/WrenAI/releases/download/" + runtimeTag + "/" + inputs.python.filename, sha256: inputs.python.sha256 }, interpreterPath: "python/install/bin/python3.11" },
wheels,
runtime: { pythonArchivePath: "python.tar.gz", venvInterpreterPath: "venv/bin/python", launcherPath: "venv/bin/wren", module: "wren.cli:app", packagePath: "venv/lib/python3.11/site-packages/wren", packageTreeSha256, closureSha256 },
licenseApproval: { state: "pending" },
};
const inventory = { schema: 1, status: "pending-explicit-approval", components: [{ name: "python-build-standalone", version: "cpython-" + inputs.python.release, declaredLicense: "MPL-2.0", artifact: inputs.python.filename }, { name: "CPython", version: inputs.python.version, declaredLicense: "PSF-2.0", artifact: inputs.python.filename }, ...wheels.map((wheel) => ({ name: wheel.distribution, version: wheel.version, declaredLicense: wheelLicenses.get(wheel.filename) ?? "UNKNOWN", artifact: wheel.filename }))], note: "The protected release environment must approve the completed expanded wheel and bundled-library inventory before public assets or an approved manifest can be emitted." };
const provenance = { schema: 1, inputs, selectedWheels: wheels, stagedManifestSha256: digest(stableJson(manifest)), generatedAt: new Date().toISOString() };
await mkdir(output, { recursive: true, mode: 0o700 });
await writeFile(path.join(output, "managed-wren-manifest.candidate.json"), JSON.stringify(manifest, null, 2) + "\n", { mode: 0o600 });
await writeFile(path.join(output, "license-inventory.json"), JSON.stringify(inventory, null, 2) + "\n", { mode: 0o600 });
await writeFile(path.join(output, "provenance.json"), JSON.stringify(provenance, null, 2) + "\n", { mode: 0o600 });
+23 -4
View File
@@ -42,9 +42,6 @@
* binding reads. Falls back to this repo's own Rust build; resolution
* loud-fails rather than degrading to Warble's built-in MDL adapter
* (see harness/compile/context-loader.ts)
* WREN_HARNESS_WREN_SHIM optional absolute server-owned Wren shim for
* native Codex runtime permissions; defaults to
* the fixed local installation when unset
* WREN_HARNESS_AGENT_SDK_BIN path to the agent-sdk CLI binary (dispatched)
* WREN_HARNESS_CODEX_LOCAL_BIN path to the warble-codex-local dispatcher CLI
* WREN_HARNESS_CODEX_BIN optional path to the Codex CLI used by that dispatcher
@@ -146,6 +143,8 @@ import { createProbedPtyFactory, ensureDarwinNodePtySpawnHelper } from "./node-p
import { NativeSessionService } from "./native-sessions.js";
import { NativeArtifactService } from "./native-artifacts.js";
import { RuntimeHost } from "./runtime-host/local.js";
import { runtimeNotReady } from "./runtime-host/policy.js";
import { ManagedWrenRuntimeError, provisionManagedWrenRuntime, resolveManagedWrenRuntime } from "./managed-wren-runtime.js";
import { assertNativeExecutableIdentity, assertNativeRuntimeSpec, attestNativeExecutable, buildNativeChildEnvironment, buildNativeRuntimeSpec, resolveNativeExecutable } from "./native-runtime-spec.js";
import type { NativeExecutableIdentity } from "./native-runtime-spec.js";
import { initializeNativeSessionStateBase, legacyInteractiveWorkspace, validateLegacyInteractiveWorkspace } from "./native-session-workspace.js";
@@ -581,10 +580,30 @@ async function main(): Promise<void> {
};
// This is the sole production composition of the Phase-1 policy. Browser
// requests never reach this selection or its executable/policy inputs.
const managedCodexRuntimeProbe = async () => {
try {
const record = await provisionManagedWrenRuntime({ packageRoot });
// Provisioning is only one Codex readiness input. This phase must not
// enable the local PTY as a production Codex adapter before the future
// app-server capability/identity contract is certified.
void record;
return {
readiness: runtimeNotReady("codex-app-server", "unprovisioned", "codex_app_server_unprovisioned"),
diagnostic: { phase: "provisioning" as const },
};
} catch (error) {
const code = error instanceof ManagedWrenRuntimeError ? error.code : "codex_wren_runtime_unprovisioned";
return {
readiness: runtimeNotReady("codex-app-server", "unprovisioned", code),
diagnostic: { phase: "provisioning" as const },
};
}
};
const nativeRuntimeHost = new RuntimeHost({
selected: "local",
deployment: process.env["NODE_ENV"] === "production" ? "production" : "development",
localAvailable: nativeTerminalHostAvailable,
vendorProbes: { "codex-app-server": managedCodexRuntimeProbe },
});
const nativeSessions = new NativeSessionService({
store,
@@ -612,9 +631,9 @@ async function main(): Promise<void> {
// The service's option is a required string; when resolution failed the bare
// name is what the preflight will report as unresolvable, with its reason.
warbleBin: producerExecutable?.executable ?? "warble",
...(process.env["WREN_HARNESS_WREN_SHIM"] !== undefined ? { wrenShim: process.env["WREN_HARNESS_WREN_SHIM"] } : {}),
terminalHostAvailable: nativeTerminalHostAvailable,
runtimeHost: nativeRuntimeHost,
resolveManagedCodexWrenRuntime: () => resolveManagedWrenRuntime({ packageRoot }),
nativeHome,
sourceWrenHome: nativeSourceWrenHome,
...(baseRouteOptions.codexHome ? { codexHome: baseRouteOptions.codexHome } : {}),
+229
View File
@@ -0,0 +1,229 @@
/**
* Immutable, release-managed Wren runtime for native Codex sessions.
*
* The packaged manifest is deliberately staged until the release workflow has
* mirrored every byte and passed its protected licence-approval environment.
* This module never substitutes a local checkout, PATH Python, user venv, or
* upstream URL for a missing approved record.
*/
import { execFileSync } from "node:child_process";
import { createHash } from "node:crypto";
import { chmodSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { z } from "zod";
import type { NativeWrenRuntime } from "./native-wren-runtime.js";
const SHA256 = z.string().regex(/^[a-f0-9]{64}$/);
const RELATIVE = z.string().min(1).refine((value) => !path.isAbsolute(value) && !value.split(/[\\/]/).includes(".."));
const URL = z.string().url().refine((value) => value.startsWith("https://github.com/Canner/WrenAI/releases/download/"));
const stagedDigest = z.union([SHA256, z.literal("staged")]);
const managedWrenManifestSchema = z.object({
schema: z.literal(1),
activation: z.enum(["staged", "approved"]),
platform: z.literal("darwin-arm64"),
compatibility: z.object({ genbi: z.string().regex(/^\d+\.\d+\.\d+$/), profile: z.literal("genbi-native-v4"), wren: z.string().regex(/^\d+\.\d+\.\d+$/) }).strict(),
python: z.object({
implementation: z.literal("cpython"), version: z.string().regex(/^3\.11\.\d+$/),
upstream: z.object({ release: z.string().regex(/^\d{8}$/), url: z.string().url(), sha256: SHA256 }).strict(),
mirror: z.object({ url: URL, sha256: SHA256 }).strict(), interpreterPath: RELATIVE,
}).strict(),
wheels: z.array(z.object({ distribution: z.string().regex(/^[a-z0-9][a-z0-9._-]*$/), version: z.string().regex(/^[A-Za-z0-9!+._-]+$/), filename: RELATIVE, url: URL, sourceUrl: z.string().url(), sha256: SHA256 }).strict()).min(1),
runtime: z.object({ pythonArchivePath: RELATIVE, venvInterpreterPath: RELATIVE, launcherPath: RELATIVE, module: z.literal("wren.cli:app"), packagePath: RELATIVE, packageTreeSha256: stagedDigest, closureSha256: stagedDigest }).strict(),
licenseApproval: z.object({ state: z.enum(["pending", "approved"]), evidence: z.string().min(1).optional() }).strict(),
}).strict().superRefine((value, context) => {
if (new Set(value.wheels.map((wheel) => wheel.filename)).size !== value.wheels.length) context.addIssue({ code: "custom", message: "duplicate wheel filename" });
if (value.wheels[0]?.distribution !== "wrenai" || value.wheels[0].version !== value.compatibility.wren) context.addIssue({ code: "custom", message: "wrenai must be the first exact wheel" });
const approved = value.activation === "approved";
if (approved !== (value.licenseApproval.state === "approved") || (approved && (!value.licenseApproval.evidence || value.runtime.packageTreeSha256 === "staged" || value.runtime.closureSha256 === "staged"))) {
context.addIssue({ code: "custom", message: "activation requires approved licence evidence and attested digests" });
}
});
export type ManagedWrenManifest = Readonly<z.infer<typeof managedWrenManifestSchema>>;
export class ManagedWrenRuntimeError extends Error { constructor(readonly code: ManagedWrenFailureCode, message = code) { super(message); } }
export type ManagedWrenFailureCode = "codex_wren_manifest_missing" | "codex_wren_manifest_invalid" | "codex_wren_platform_unsupported" | "codex_wren_runtime_unprovisioned" | "codex_wren_provision_failed" | "codex_wren_interpreter_mismatch" | "codex_wren_launcher_mismatch" | "codex_wren_package_mismatch" | "codex_wren_closure_mismatch";
export interface ManagedWrenRuntimeRecord extends NativeWrenRuntime {
readonly manifest_digest: string;
readonly generation_root: string;
readonly closure_digest: string;
readonly package_digest: string;
}
function failure(code: ManagedWrenFailureCode): never { throw new ManagedWrenRuntimeError(code); }
function sha256(value: Uint8Array | string): string { return createHash("sha256").update(value).digest("hex"); }
function contained(root: string, target: string): boolean { const relative = path.relative(root, target); return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative)); }
function platform(): "darwin-arm64" | undefined { return process.platform === "darwin" && process.arch === "arm64" ? "darwin-arm64" : undefined; }
function packageRoot(): string { return path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); }
export function defaultManagedWrenRoot(): string { return path.join(os.homedir(), "Library", "Application Support", "WrenAI", "genbi", "managed-wren"); }
export function managedWrenManifestPath(root = packageRoot()): string { return path.join(root, "managed-wren", "manifest.json"); }
export function readManagedWrenManifest(root = packageRoot()): ManagedWrenManifest {
let raw: unknown;
try { raw = JSON.parse(readFileSync(managedWrenManifestPath(root), "utf8")); } catch { return failure("codex_wren_manifest_missing"); }
const parsed = managedWrenManifestSchema.safeParse(raw);
if (!parsed.success) return failure("codex_wren_manifest_invalid");
if (platform() !== parsed.data.platform) return failure("codex_wren_platform_unsupported");
return Object.freeze(parsed.data);
}
function stableJson(value: unknown): string {
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
if (value && typeof value === "object") {
const object = value as Record<string, unknown>;
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${stableJson(object[key])}`).join(",")}}`;
}
return JSON.stringify(value);
}
export function manifestDigest(manifest: ManagedWrenManifest): string { return sha256(stableJson(manifest)); }
function immutableDirectory(root: string, digest: string): string { return path.join(root, digest); }
function assertPrivateDirectory(directory: string): void {
try { const entry = lstatSync(directory); if (!entry.isDirectory() || entry.isSymbolicLink() || realpathSync(directory) !== directory || (entry.mode & 0o777) !== 0o700) failure("codex_wren_runtime_unprovisioned"); } catch (error) { if (error instanceof ManagedWrenRuntimeError) throw error; failure("codex_wren_runtime_unprovisioned"); }
}
function assertContainedRealpath(root: string, target: string, code: ManagedWrenFailureCode): string {
try { const canonical = realpathSync(target); if (!contained(root, canonical)) failure(code); return canonical; } catch (error) { if (error instanceof ManagedWrenRuntimeError) throw error; return failure(code); }
}
function regularExecutable(root: string, target: string, code: ManagedWrenFailureCode): string {
const canonical = assertContainedRealpath(root, target, code); const metadata = statSync(canonical); if (!metadata.isFile() || (metadata.mode & 0o111) === 0) failure(code); return canonical;
}
function regularFile(root: string, target: string, code: ManagedWrenFailureCode): string {
const canonical = assertContainedRealpath(root, target, code); const metadata = statSync(canonical); if (!metadata.isFile()) failure(code); return canonical;
}
function assertSecureTree(root: string, code: ManagedWrenFailureCode): void {
try {
const visit = (directory: string) => {
for (const name of readdirSync(directory)) {
const target = path.join(directory, name); const entry = lstatSync(target);
if (entry.isSymbolicLink() || (entry.mode & 0o022) !== 0) failure(code);
if (entry.isDirectory()) visit(target); else if (!entry.isFile()) failure(code);
}
};
visit(root);
} catch (error) { if (error instanceof ManagedWrenRuntimeError) throw error; failure(code); }
}
function treeDigest(root: string): string {
const entries: string[] = [];
const visit = (directory: string) => { for (const name of readdirSync(directory).sort()) { if (name === "__pycache__") continue; const target = path.join(directory, name); const stat = lstatSync(target); if (stat.isSymbolicLink()) throw new Error("symlink"); if (stat.isDirectory()) visit(target); else if (stat.isFile()) entries.push(`${path.relative(root, target)}\0${sha256(readFileSync(target))}`); else throw new Error("special"); } };
visit(root); return sha256(entries.join("\n"));
}
function closureDigest(manifest: ManagedWrenManifest): string { return sha256(manifest.wheels.map((wheel) => `${wheel.filename}\0${wheel.sha256}`).sort().join("\n")); }
function ownershipMarker(root: string): string { return path.join(root, ".genbi-managed-wren.json"); }
function stagingMarker(root: string): string { return path.join(root, ".genbi-managed-wren-staging.json"); }
function actualClosureDigest(root: string, manifest: ManagedWrenManifest): string {
const hashes: string[] = [];
for (const wheel of manifest.wheels) {
const target = regularFile(root, path.join(root, "wheels", wheel.filename), "codex_wren_closure_mismatch");
const actual = sha256(readFileSync(target)); if (actual !== wheel.sha256) failure("codex_wren_closure_mismatch");
hashes.push(`${wheel.filename}\0${actual}`);
}
return sha256(hashes.sort().join("\n"));
}
function isRecognisedStaging(root: string, candidate: string, digest: string): boolean {
try {
const target = path.join(root, candidate); const entry = lstatSync(target);
if (!entry.isDirectory() || entry.isSymbolicLink() || !contained(root, target) || (entry.mode & 0o777) !== 0o700) return false;
const marker = stagingMarker(target); const markerEntry = lstatSync(marker);
if (!markerEntry.isFile() || markerEntry.isSymbolicLink() || (markerEntry.mode & 0o777) !== 0o600) return false;
return JSON.parse(readFileSync(marker, "utf8")).manifestDigest === digest;
} catch { return false; }
}
function cleanupRecognisedStaging(root: string, digest: string): void {
for (const candidate of readdirSync(root)) {
if (!candidate.startsWith(`.staging-${digest}-`) || !isRecognisedStaging(root, candidate, digest)) continue;
rmSync(path.join(root, candidate), { recursive: true, force: true });
}
}
/** Revalidate a record before every native Codex launch. */
export function resolveManagedWrenRuntime(options: { readonly packageRoot?: string; readonly runtimeRoot?: string } = {}): ManagedWrenRuntimeRecord {
const manifest = readManagedWrenManifest(options.packageRoot);
if (manifest.activation !== "approved") return failure("codex_wren_runtime_unprovisioned");
const digest = manifestDigest(manifest); const root = options.runtimeRoot ?? defaultManagedWrenRoot(); const generation = immutableDirectory(root, digest);
assertPrivateDirectory(root); assertPrivateDirectory(generation);
assertSecureTree(generation, "codex_wren_closure_mismatch");
let marker: { manifestDigest?: unknown; closureDigest?: unknown; packageDigest?: unknown; interpreterDigest?: unknown; launcherDigest?: unknown };
try { const markerPath = ownershipMarker(generation); const entry = lstatSync(markerPath); if (!entry.isFile() || entry.isSymbolicLink() || (entry.mode & 0o777) !== 0o600) return failure("codex_wren_runtime_unprovisioned"); marker = JSON.parse(readFileSync(markerPath, "utf8")); } catch { return failure("codex_wren_runtime_unprovisioned"); }
if (marker.manifestDigest !== digest) return failure("codex_wren_closure_mismatch");
const archive = regularFile(generation, path.join(generation, manifest.runtime.pythonArchivePath), "codex_wren_interpreter_mismatch");
if (sha256(readFileSync(archive)) !== manifest.python.mirror.sha256) return failure("codex_wren_interpreter_mismatch");
const interpreter = regularExecutable(generation, path.join(generation, manifest.runtime.venvInterpreterPath), "codex_wren_interpreter_mismatch");
const launcher = regularExecutable(generation, path.join(generation, manifest.runtime.launcherPath), "codex_wren_launcher_mismatch");
if (marker.interpreterDigest !== sha256(readFileSync(interpreter))) return failure("codex_wren_interpreter_mismatch");
if (marker.launcherDigest !== sha256(readFileSync(launcher))) return failure("codex_wren_launcher_mismatch");
let launcherText = ""; try { launcherText = readFileSync(launcher, "utf8"); } catch { return failure("codex_wren_launcher_mismatch"); }
if (!launcherText.startsWith(`#!${path.join(generation, manifest.runtime.venvInterpreterPath)}`) || !launcherText.includes("from wren.cli import app")) return failure("codex_wren_launcher_mismatch");
const packagePath = assertContainedRealpath(generation, path.join(generation, manifest.runtime.packagePath), "codex_wren_package_mismatch");
let actualPackage: string; try { actualPackage = treeDigest(packagePath); } catch { return failure("codex_wren_package_mismatch"); }
if (actualPackage !== manifest.runtime.packageTreeSha256 || marker.packageDigest !== actualPackage) return failure("codex_wren_package_mismatch");
const actualClosure = actualClosureDigest(generation, manifest); if (actualClosure !== manifest.runtime.closureSha256 || marker.closureDigest !== actualClosure) return failure("codex_wren_closure_mismatch");
const python = regularExecutable(generation, path.join(generation, manifest.python.interpreterPath), "codex_wren_interpreter_mismatch");
return Object.freeze({ version: "1", shim: launcher, launcher, venv_python: interpreter, tool_root: path.join(generation, "venv"), site_packages: path.dirname(packagePath), source_root: packagePath, interpreter: python, interpreter_root: path.dirname(path.dirname(python)), manifest_digest: digest, generation_root: generation, closure_digest: actualClosure, package_digest: actualPackage });
}
/**
* Provision is intentionally unavailable for a staged manifest. A release can
* only turn this on after the protected licence approval job writes an approved
* manifest with release-attested digests.
*/
export async function provisionManagedWrenRuntime(options: { readonly packageRoot?: string; readonly runtimeRoot?: string } = {}): Promise<ManagedWrenRuntimeRecord> {
const manifest = readManagedWrenManifest(options.packageRoot);
if (manifest.activation !== "approved") return failure("codex_wren_runtime_unprovisioned");
const root = options.runtimeRoot ?? defaultManagedWrenRoot();
mkdirSync(root, { recursive: true, mode: 0o700 }); chmodSync(root, 0o700); assertPrivateDirectory(root);
const digest = manifestDigest(manifest); const destination = immutableDirectory(root, digest);
try { return resolveManagedWrenRuntime({ ...(options.packageRoot ? { packageRoot: options.packageRoot } : {}), runtimeRoot: root }); } catch (error) { if (!(error instanceof ManagedWrenRuntimeError) || error.code !== "codex_wren_runtime_unprovisioned") throw error; }
const lock = path.join(root, ".provision.lock"); let descriptor: number | undefined;
try {
// A second first-use caller waits for the owner instead of falling through
// to a partial directory or declaring a separate runtime valid.
const deadline = Date.now() + 10_000;
while (descriptor === undefined && Date.now() < deadline) {
try { descriptor = openSync(lock, "wx", 0o600); } catch (error: unknown) {
if (!(error && typeof error === "object" && "code" in error && error.code === "EEXIST")) throw error;
await new Promise((resolve) => setTimeout(resolve, 25));
}
}
if (descriptor === undefined) return failure("codex_wren_provision_failed");
// A waiter must re-check after it owns the lock: the original owner may
// have completed while this caller was waiting.
try { return resolveManagedWrenRuntime({ ...(options.packageRoot ? { packageRoot: options.packageRoot } : {}), runtimeRoot: root }); } catch (error) { if (!(error instanceof ManagedWrenRuntimeError) || error.code !== "codex_wren_runtime_unprovisioned") throw error; }
// Only a marker written by this provisioner is eligible for interrupted-run
// recovery, after the exclusive lock prevents a live writer race.
cleanupRecognisedStaging(root, digest);
const staging = path.join(root, `.staging-${digest}-${process.pid}`); mkdirSync(staging, { mode: 0o700 }); chmodSync(staging, 0o700);
writeFileSync(stagingMarker(staging), JSON.stringify({ manifestDigest: digest }) + "\n", { mode: 0o600, flag: "wx" });
// The release workflow makes these assets available as a closed mirror.
// Fetching any other URL, index, or dependency resolver is intentionally absent.
const archive = path.join(staging, manifest.runtime.pythonArchivePath); const download = async (url: string, target: string, expected: string) => { const response = await fetch(url); if (!response.ok) throw new Error("download"); const bytes = Buffer.from(await response.arrayBuffer()); if (sha256(bytes) !== expected) throw new Error("digest"); writeFileSync(target, bytes, { mode: 0o600, flag: "wx" }); };
await download(manifest.python.mirror.url, archive, manifest.python.mirror.sha256);
execFileSync("tar", ["-xzf", archive, "-C", staging], { stdio: "ignore" });
const python = path.join(staging, manifest.python.interpreterPath); regularExecutable(staging, python, "codex_wren_interpreter_mismatch");
const wheels = path.join(staging, "wheels"); mkdirSync(wheels, { mode: 0o700 });
for (const wheel of manifest.wheels) await download(wheel.url, path.join(wheels, wheel.filename), wheel.sha256);
const requirements = manifest.wheels.map((wheel) => `${wheel.distribution}==${wheel.version} --hash=sha256:${wheel.sha256}`).join("\n") + "\n";
writeFileSync(path.join(staging, "requirements.txt"), requirements, { mode: 0o600, flag: "wx" });
const venv = path.join(staging, "venv"); execFileSync(python, ["-m", "venv", venv], { stdio: "ignore", env: { PATH: path.dirname(python), HOME: staging, PYTHONNOUSERSITE: "1" } });
execFileSync(path.join(venv, "bin", "python"), ["-m", "pip", "install", "--no-index", "--no-deps", "--require-hashes", "--find-links", wheels, "-r", path.join(staging, "requirements.txt")], { stdio: "ignore", env: { PATH: path.join(venv, "bin"), HOME: staging, PYTHONNOUSERSITE: "1" } });
const packagePath = path.join(staging, manifest.runtime.packagePath); const packageDigest = treeDigest(packagePath); const closure = actualClosureDigest(staging, manifest);
if (packageDigest !== manifest.runtime.packageTreeSha256 || closure !== manifest.runtime.closureSha256) throw new Error("attestation");
// `venv` console launchers contain an absolute interpreter shebang. The
// staging name must never escape into an active generation after rename.
const stagedInterpreter = path.join(staging, manifest.runtime.venvInterpreterPath);
const stagedLauncher = path.join(staging, manifest.runtime.launcherPath);
const launcherText = readFileSync(stagedLauncher, "utf8");
if (!launcherText.startsWith(`#!${stagedInterpreter}\n`) || !launcherText.includes("from wren.cli import app")) return failure("codex_wren_launcher_mismatch");
renameSync(staging, destination);
const finalInterpreter = path.join(destination, manifest.runtime.venvInterpreterPath);
const finalLauncher = path.join(destination, manifest.runtime.launcherPath);
writeFileSync(finalLauncher, `#!${finalInterpreter}\n${launcherText.slice(stagedInterpreter.length + 3)}`, { mode: 0o700 });
rmSync(stagingMarker(destination), { force: true });
writeFileSync(ownershipMarker(destination), JSON.stringify({ manifestDigest: digest, packageDigest, closureDigest: closure, interpreterDigest: sha256(readFileSync(finalInterpreter)), launcherDigest: sha256(readFileSync(finalLauncher)) }) + "\n", { mode: 0o600, flag: "wx" });
return resolveManagedWrenRuntime({ ...(options.packageRoot ? { packageRoot: options.packageRoot } : {}), runtimeRoot: root });
} catch (error) { if (descriptor !== undefined) cleanupRecognisedStaging(root, digest); if (error instanceof ManagedWrenRuntimeError) throw error; return failure("codex_wren_provision_failed");
} finally { if (descriptor !== undefined) { try { rmSync(lock, { force: true }); } catch { /* next run reports unavailable */ } } }
}
export function managedWrenClosureDigest(manifest: ManagedWrenManifest): string { return closureDigest(manifest); }
+13 -2
View File
@@ -19,6 +19,7 @@ import { createNativeSessionWorkspace, initializeNativeSessionStateBase, nativeS
import type { NativeSessionStateBase } from "./native-session-workspace.js";
import { NativeWrenRuntimeError, resolveNativeWrenRuntime } from "./native-wren-runtime.js";
import type { NativeWrenRuntime } from "./native-wren-runtime.js";
import { ManagedWrenRuntimeError } from "./managed-wren-runtime.js";
import { assertNativeExecutableIdentity, assertNativeRuntimeSpec, attestNativeExecutable, buildNativeChildEnvironment, buildNativeRuntimeSpec, nativeProcessEnvironment, resolveNativeExecutable } from "./native-runtime-spec.js";
import type { NativeChildEnvironment, NativeExecutableIdentity, NativeRuntimeSpec } from "./native-runtime-spec.js";
import { createEmptyCodexWrenHome, materializeCodexWrenHome } from "./native-wren-home.js";
@@ -674,6 +675,8 @@ export async function probeNativeSessionProducer(input: {
readonly warbleBin: string;
readonly irPaths: Readonly<Record<NativePurpose, string | undefined>>;
readonly wrenShim?: string;
/** Production Codex probes receive the same immutable-record resolver used at launch. */
readonly resolveManagedCodexWrenRuntime?: () => NativeWrenRuntime;
readonly nativeHome?: string;
readonly nodeExecutable?: NativeExecutableIdentity;
readonly childToolDirectories?: readonly string[];
@@ -725,7 +728,14 @@ export async function probeNativeSessionProducer(input: {
const scopeId = `preflight-${purpose}-${vendor}`;
const scopePath = path.join(root, "scope.json");
const mcpPath = path.join(root, "mcp.json");
const wrenRuntime = vendor === "codex" ? resolveNativeWrenRuntime(input.wrenShim) : undefined;
// Production passes the sealed managed record. The legacy resolver is a
// compatibility seam for deterministic fixture tests only; bin.ts does
// not provide a shim and so can never select an editable installation.
const wrenRuntime = vendor === "codex"
? input.resolveManagedCodexWrenRuntime
? input.resolveManagedCodexWrenRuntime()
: resolveNativeWrenRuntime(input.wrenShim)
: undefined;
const binding = NATIVE_DISPATCH_REGISTRY[purpose].scopeKind === "bound_project"
? { project_identity: "native-preflight-project", generation: "1", revision: "native-preflight-revision" }
: undefined;
@@ -742,7 +752,7 @@ export async function probeNativeSessionProducer(input: {
break;
}
} catch (error) {
outcome = error instanceof NativeWrenRuntimeError
outcome = error instanceof NativeWrenRuntimeError || error instanceof ManagedWrenRuntimeError
? fail(`result=wren_runtime_unavailable (${error.message})`, error.message)
: fail("result=preflight_workspace_unavailable", "the preflight could not create its temporary workspace");
break;
@@ -1010,6 +1020,7 @@ export class NativeSessionService {
nativeHome: this.nativeHome,
nodeExecutable: this.nodeExecutable,
childToolDirectories: this.childToolDirectories,
...(this.options.resolveManagedCodexWrenRuntime ? { resolveManagedCodexWrenRuntime: this.options.resolveManagedCodexWrenRuntime } : {}),
...(this.options.pathValue !== undefined ? { pathValue: this.options.pathValue } : {}),
wrenShim: this.wrenShim,
});
@@ -0,0 +1,175 @@
import { chmodSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
import { execFileSync } from "node:child_process";
import { createHash } from "node:crypto";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
import { ManagedWrenRuntimeError, managedWrenClosureDigest, manifestDigest, provisionManagedWrenRuntime, readManagedWrenManifest, resolveManagedWrenRuntime } from "../server/managed-wren-runtime.js";
const roots: string[] = [];
const digest = (value: string | Uint8Array) => createHash("sha256").update(value).digest("hex");
function fixture() {
const root = realpathSync(mkdtempSync(path.join(tmpdir(), "genbi-managed-wren-"))); roots.push(root);
const packageRoot = path.join(root, "package"); const runtimeRoot = path.join(root, "runtime");
mkdirSync(path.join(packageRoot, "managed-wren"), { recursive: true, mode: 0o700 }); mkdirSync(runtimeRoot, { mode: 0o700 }); chmodSync(runtimeRoot, 0o700);
const archiveDigest = digest("python-archive"); const wheelDigest = digest("wheel");
const manifest = {
schema: 1, activation: "approved", platform: "darwin-arm64",
compatibility: { genbi: "0.0.4", profile: "genbi-native-v4", wren: "0.13.0" },
python: { implementation: "cpython", version: "3.11.16", upstream: { release: "20260901", url: "https://example.invalid/upstream", sha256: archiveDigest }, mirror: { url: "https://github.com/Canner/WrenAI/releases/download/managed-wren-v0.0.4/python.tar.gz", sha256: archiveDigest }, interpreterPath: "python/install/bin/python3.11" },
wheels: [{ distribution: "wrenai", version: "0.13.0", filename: "wrenai-0.13.0-py3-none-any.whl", url: "https://github.com/Canner/WrenAI/releases/download/managed-wren-v0.0.4/wrenai-0.13.0-py3-none-any.whl", sourceUrl: "https://files.pythonhosted.org/wrenai-0.13.0-py3-none-any.whl", sha256: wheelDigest }],
runtime: { pythonArchivePath: "python.tar.gz", venvInterpreterPath: "venv/bin/python", launcherPath: "venv/bin/wren", module: "wren.cli:app", packagePath: "venv/lib/python3.11/site-packages/wren", packageTreeSha256: "staged", closureSha256: "staged" },
licenseApproval: { state: "approved", evidence: "release-evidence" },
} as const;
const closure = managedWrenClosureDigest(manifest as never);
const packageDigest = digest(`__init__.py\0${digest("__version__ = '0.13.0'\n")}`);
const approved = { ...manifest, runtime: { ...manifest.runtime, packageTreeSha256: packageDigest, closureSha256: closure } };
writeFileSync(path.join(packageRoot, "managed-wren", "manifest.json"), JSON.stringify(approved));
const parsed = readManagedWrenManifest(packageRoot); const generation = path.join(runtimeRoot, manifestDigest(parsed));
for (const directory of [path.join(generation, "python", "install", "bin"), path.join(generation, "venv", "bin"), path.join(generation, "venv", "lib", "python3.11", "site-packages", "wren"), path.join(generation, "wheels")]) mkdirSync(directory, { recursive: true, mode: 0o700 });
const python = path.join(generation, "python", "install", "bin", "python3.11"); const venvPython = path.join(generation, "venv", "bin", "python"); const launcher = path.join(generation, "venv", "bin", "wren");
writeFileSync(path.join(generation, "python.tar.gz"), "python-archive", { mode: 0o600 });
writeFileSync(path.join(generation, "wheels", manifest.wheels[0].filename), "wheel", { mode: 0o600 });
writeFileSync(python, "#!/bin/sh\nexit 0\n", { mode: 0o700 }); writeFileSync(venvPython, "#!/bin/sh\nexit 0\n", { mode: 0o700 }); writeFileSync(launcher, `#!${venvPython}\nfrom wren.cli import app\n`, { mode: 0o700 }); writeFileSync(path.join(generation, "venv", "lib", "python3.11", "site-packages", "wren", "__init__.py"), "__version__ = '0.13.0'\n", { mode: 0o600 });
writeFileSync(path.join(generation, ".genbi-managed-wren.json"), JSON.stringify({ manifestDigest: manifestDigest(parsed), packageDigest, closureDigest: closure, interpreterDigest: digest("#!/bin/sh\nexit 0\n"), launcherDigest: digest(`#!${venvPython}\nfrom wren.cli import app\n`) }), { mode: 0o600 }); chmodSync(generation, 0o700);
return { packageRoot, runtimeRoot, generation, launcher, manifest: approved };
}
afterEach(() => { vi.unstubAllGlobals(); while (roots.length) rmSync(roots.pop()!, { recursive: true, force: true }); });
function provisionFixture(version = "0.13.0") {
const root = realpathSync(mkdtempSync(path.join(tmpdir(), "genbi-managed-wren-provision-"))); roots.push(root);
const packageRoot = path.join(root, "installed-package"); const runtimeRoot = path.join(root, "runtime"); const source = path.join(root, "python-source");
mkdirSync(path.join(packageRoot, "managed-wren"), { recursive: true, mode: 0o700 }); mkdirSync(runtimeRoot, { mode: 0o700 }); mkdirSync(path.join(source, "python", "install", "bin"), { recursive: true, mode: 0o700 }); chmodSync(runtimeRoot, 0o700);
const python = path.join(source, "python", "install", "bin", "python3.11");
const fakePython = [
"#!/bin/sh",
"if [ \"$1\" = \"-m\" ] && [ \"$2\" = \"venv\" ]; then",
" target=\"$3\"",
" /bin/mkdir -p \"$target/bin\" \"$target/lib/python3.11/site-packages/wren\"",
" /bin/cp \"$0\" \"$target/bin/python\"",
" /bin/chmod 700 \"$target/bin/python\"",
" /usr/bin/printf '#!%s\\nfrom wren.cli import app\\n' \"$target/bin/python\" > \"$target/bin/wren\"",
" /bin/chmod 700 \"$target/bin/wren\"",
` /usr/bin/printf \"__version__ = '${version}'\\n\" > \"$target/lib/python3.11/site-packages/wren/__init__.py\"`,
" /bin/chmod 600 \"$target/lib/python3.11/site-packages/wren/__init__.py\"",
" exit 0",
"fi",
"if [ \"$1\" = \"-m\" ] && [ \"$2\" = \"pip\" ]; then",
" /usr/bin/printf '%s\\n' \"$*\" > \"$HOME/pip-args\"",
" exit 0",
"fi",
"exit 1",
"",
].join("\n");
writeFileSync(python, fakePython, { mode: 0o700 });
const archive = path.join(root, "python.tar.gz"); execFileSync("tar", ["-czf", archive, "-C", source, "."]);
const archiveBytes = readFileSync(archive); const wheelBytes = Buffer.from(`fixture wheel ${version}\n`);
const base = {
schema: 1, activation: "approved", platform: "darwin-arm64",
compatibility: { genbi: "0.0.4", profile: "genbi-native-v4", wren: version },
python: { implementation: "cpython", version: "3.11.16", upstream: { release: "20260901", url: "https://example.invalid/upstream", sha256: digest(archiveBytes) }, mirror: { url: `https://github.com/Canner/WrenAI/releases/download/fixture-${version}/python.tar.gz`, sha256: digest(archiveBytes) }, interpreterPath: "python/install/bin/python3.11" },
wheels: [{ distribution: "wrenai", version, filename: `wrenai-${version}-py3-none-any.whl`, url: `https://github.com/Canner/WrenAI/releases/download/fixture-${version}/wrenai-${version}-py3-none-any.whl`, sourceUrl: `https://files.pythonhosted.org/fixture/wrenai-${version}-py3-none-any.whl`, sha256: digest(wheelBytes) }],
runtime: { pythonArchivePath: "python.tar.gz", venvInterpreterPath: "venv/bin/python", launcherPath: "venv/bin/wren", module: "wren.cli:app", packagePath: "venv/lib/python3.11/site-packages/wren", packageTreeSha256: digest(`__init__.py\0${digest(`__version__ = '${version}'\n`)}`), closureSha256: "staged" },
licenseApproval: { state: "approved", evidence: "fixture" },
} as const;
const manifest = { ...base, runtime: { ...base.runtime, closureSha256: managedWrenClosureDigest(base as never) } };
writeFileSync(path.join(packageRoot, "managed-wren", "manifest.json"), JSON.stringify(manifest));
const requests: string[] = [];
const installFetch = (beforeResponse?: () => Promise<void>) => vi.stubGlobal("fetch", vi.fn(async (input: string | URL) => {
requests.push(String(input)); if (beforeResponse) await beforeResponse();
if (String(input) === manifest.python.mirror.url) return new Response(archiveBytes);
if (String(input) === manifest.wheels[0].url) return new Response(wheelBytes);
return new Response("not found", { status: 404 });
}));
return { packageRoot, runtimeRoot, manifest, requests, installFetch };
}
describe("managed Wren runtime", () => {
it("accepts only an approved, immutable record and rejects every tampered launch link", () => {
const value = fixture();
expect(resolveManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot })).toMatchObject({ generation_root: value.generation, launcher: value.launcher });
for (const mutation of ["interpreter", "launcher", "package", "marker"] as const) {
const next = fixture();
if (mutation === "interpreter") writeFileSync(path.join(next.generation, "venv", "bin", "python"), "not executable");
if (mutation === "launcher") writeFileSync(next.launcher, "#!/wrong/python\n");
if (mutation === "package") writeFileSync(path.join(next.generation, "venv", "lib", "python3.11", "site-packages", "wren", "__init__.py"), "tampered\n");
if (mutation === "marker") writeFileSync(path.join(next.generation, ".genbi-managed-wren.json"), "{}", { mode: 0o600 });
expect(() => resolveManagedWrenRuntime({ packageRoot: next.packageRoot, runtimeRoot: next.runtimeRoot })).toThrow(ManagedWrenRuntimeError);
}
});
it("rejects mutable, unapproved, or non-mirror manifest input before provisioning", () => {
const value = fixture();
const manifestPath = path.join(value.packageRoot, "managed-wren", "manifest.json");
const original = JSON.parse(JSON.stringify(value.manifest));
for (const mutate of [
(m: any) => { m.activation = "staged"; m.licenseApproval.state = "pending"; },
(m: any) => { m.python.mirror.url = "https://example.com/python.tar.gz"; },
(m: any) => { m.wheels[0].filename = "../escape.whl"; },
]) {
const changed = JSON.parse(JSON.stringify(original)); mutate(changed); writeFileSync(manifestPath, JSON.stringify(changed));
expect(() => resolveManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot })).toThrow(ManagedWrenRuntimeError);
}
});
it("provisions deterministic fixture assets offline and then reuses the immutable generation", async () => {
const value = provisionFixture(); value.installFetch();
const first = await provisionManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot });
expect(first.generation_root).toContain(first.manifest_digest);
expect(value.requests).toEqual([value.manifest.python.mirror.url, value.manifest.wheels[0].url]);
expect(readFileSync(path.join(first.generation_root, "pip-args"), "utf8")).toContain("--no-index --no-deps --require-hashes");
const requestCount = value.requests.length;
await expect(provisionManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot })).resolves.toMatchObject({ generation_root: first.generation_root });
expect(value.requests).toHaveLength(requestCount);
}, 20_000);
it("waits for a concurrent first-use owner and both callers receive the same generation", async () => {
const value = provisionFixture(); let release!: () => void; const paused = new Promise<void>((resolve) => { release = resolve; }); let firstFetch = true;
value.installFetch(async () => { if (firstFetch) { firstFetch = false; await paused; } });
const owner = provisionManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot });
await new Promise((resolve) => setTimeout(resolve, 30));
const waiter = provisionManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot });
release();
const [a, b] = await Promise.all([owner, waiter]);
expect(a.generation_root).toBe(b.generation_root);
expect(value.requests).toHaveLength(2);
}, 20_000);
it("recovers only marked stale staging and preserves untrusted or rollback state", async () => {
const value = provisionFixture(); const digestValue = manifestDigest(readManagedWrenManifest(value.packageRoot));
const stale = path.join(value.runtimeRoot, `.staging-${digestValue}-stale`); mkdirSync(stale, { mode: 0o700 }); chmodSync(stale, 0o700); writeFileSync(path.join(stale, ".genbi-managed-wren-staging.json"), JSON.stringify({ manifestDigest: digestValue }), { mode: 0o600 });
const untrusted = path.join(value.runtimeRoot, `.staging-${digestValue}-untrusted`); mkdirSync(untrusted, { mode: 0o700 }); chmodSync(untrusted, 0o700); writeFileSync(path.join(untrusted, "keep"), "keep");
const rollback = path.join(value.runtimeRoot, "previous-generation"); mkdirSync(rollback, { mode: 0o700 }); chmodSync(rollback, 0o700); writeFileSync(path.join(rollback, "keep"), "keep");
value.installFetch(); await provisionManagedWrenRuntime({ packageRoot: value.packageRoot, runtimeRoot: value.runtimeRoot });
expect(existsSync(stale)).toBe(false); expect(readFileSync(path.join(untrusted, "keep"), "utf8")).toBe("keep"); expect(readFileSync(path.join(rollback, "keep"), "utf8")).toBe("keep");
});
it("retains older generations and keeps an active record pinned across an update", async () => {
const old = provisionFixture("0.13.0"); old.installFetch(); const active = await provisionManagedWrenRuntime({ packageRoot: old.packageRoot, runtimeRoot: old.runtimeRoot });
const next = provisionFixture("0.13.1"); next.installFetch(); const updated = await provisionManagedWrenRuntime({ packageRoot: next.packageRoot, runtimeRoot: old.runtimeRoot });
expect(updated.generation_root).not.toBe(active.generation_root);
expect(lstatSync(active.generation_root).isDirectory()).toBe(true);
expect(resolveManagedWrenRuntime({ packageRoot: old.packageRoot, runtimeRoot: old.runtimeRoot }).launcher).toBe(active.launcher);
});
it("rejects retained archive and wheel tampering after a successful provision", async () => {
for (const target of ["python.tar.gz", "wheel"] as const) {
const next = provisionFixture(); next.installFetch(); const nextRecord = await provisionManagedWrenRuntime({ packageRoot: next.packageRoot, runtimeRoot: next.runtimeRoot });
writeFileSync(target === "python.tar.gz" ? path.join(nextRecord.generation_root, target) : path.join(nextRecord.generation_root, "wheels", next.manifest.wheels[0].filename), "tampered");
expect(() => resolveManagedWrenRuntime({ packageRoot: next.packageRoot, runtimeRoot: next.runtimeRoot })).toThrow(ManagedWrenRuntimeError);
}
});
it("derives a closed staged candidate manifest from the selected release closure", () => {
const root = realpathSync(mkdtempSync(path.join(tmpdir(), "genbi-managed-wren-release-"))); roots.push(root);
const packagePath = path.join(root, "runtime", "venv", "lib", "python3.11", "site-packages", "wren"); mkdirSync(packagePath, { recursive: true, mode: 0o700 }); writeFileSync(path.join(packagePath, "__init__.py"), "__version__ = '0.13.0'\n", { mode: 0o600 });
const wheel = { distribution: "wrenai", version: "0.13.0", filename: "wrenai-0.13.0-py3-none-any.whl", sourceUrl: "https://files.pythonhosted.org/fixture/wrenai-0.13.0-py3-none-any.whl", sha256: "b".repeat(64), license: "Apache-2.0" };
writeFileSync(path.join(root, "wheel-inputs.json"), JSON.stringify([wheel]));
execFileSync(process.execPath, [path.resolve("scripts", "managed-wren-release.mjs"), root, "managed-wren-fixture"], { cwd: path.resolve("."), stdio: "pipe" });
const candidate = JSON.parse(readFileSync(path.join(root, "managed-wren-manifest.candidate.json"), "utf8"));
expect(candidate).toMatchObject({ activation: "staged", wheels: [{ distribution: wheel.distribution, version: wheel.version, filename: wheel.filename, url: "https://github.com/Canner/WrenAI/releases/download/managed-wren-fixture/wrenai-0.13.0-py3-none-any.whl" }] });
expect(candidate.runtime.packageTreeSha256).not.toBe("staged"); expect(candidate.runtime.closureSha256).not.toBe("staged");
});
});
@@ -17,6 +17,23 @@ describe("installed-package and vendor-contract CI wiring", () => {
expect(packageJson.scripts["check:installed-package"]).toBe("node scripts/installed-package-acceptance.mjs");
});
it("ships the staged managed-Wren manifest but never treats its release input as an active runtime", () => {
expect(packageJson.files).toContain("managed-wren");
const manifest = JSON.parse(readFileSync(path.join(packageRoot, "managed-wren", "manifest.json"), "utf8"));
expect(manifest).toMatchObject({ schema: 1, platform: "darwin-arm64", activation: "staged", licenseApproval: { state: "pending" } });
expect(manifest.python.mirror.url).toMatch(/^https:\/\/github\.com\/Canner\/WrenAI\/releases\/download\//);
expect(manifest.wheels[0]).toMatchObject({ distribution: "wrenai", version: "0.13.0" });
});
it("keeps managed-Wren publication and manifest activation behind the protected approval job", () => {
const workflow = readFileSync(path.join(repositoryRoot, ".github", "workflows", "managed-wren-runtime.yml"), "utf8");
expect(workflow).toContain("managed-wren-license-approved");
expect(workflow).toContain("if: ${{ inputs.license_approval == 'approved' }}");
expect(workflow).toContain("managed-wren-manifest.candidate.json");
expect(workflow).toContain("--no-index --no-deps --require-hashes");
expect(workflow).toContain("gh release create");
});
it("pins the context loader exactly and runs its no-checkout acceptance on the certified macOS target", () => {
expect(packageJson.dependencies["@wrenai/context-loader"]).toBe("0.1.0");
const workflow = readFileSync(path.join(repositoryRoot, ".github", "workflows", "genbi-ci.yml"), "utf8");