@orkestrel/scaffold 0.0.48 → 0.0.50

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.
@@ -95,6 +95,15 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
95
95
  global: "export function setup(): void {}\n";
96
96
  entry: "import * as entry from {{specifier}}\nimport { describe, expect, it } from 'vitest'\n\ndescribe({{label}}, () => {\n\tit('has no starter exports', () => {\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
97
97
  bin: "import { describe, expect, it } from 'vitest'\n\ndescribe('bin entry', () => {\n\tit('has no starter exports', async () => {\n{{import}}\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
98
+ distribution: Readonly<{
99
+ proof: "// The artifact a consumer installs, measured rather than described. This workspace\n// is packed and installed into a throwaway consumer, and every following claim is read\n// off that installed tree: the exports map it publishes, the declarations it ships,\n// and the module objects a real runtime hands a consumer. Nothing here names this\n// package, one of its exports, or how many there are, so the proof stays true as\n// the published surface moves.\n{{types}}import type { SpawnSyncReturns } from 'node:child_process'\nimport type { TestContext } from 'vitest'\nimport { spawnSync } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\tmkdtempSync,\n\treaddirSync,\n\treadFileSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\n{{transport}}import { tmpdir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n{{launcher}}import ts from 'typescript'\nimport { afterAll, describe, expect, it } from 'vitest'\n\nconst ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')\nconst NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'\n// Windows needs a shell to launch a `.cmd`: Node refuses one directly since the\n// batch-argument hardening, and `spawnSync` returns `EINVAL` with a null status\n// rather than an exit code a caller can read. Every following argument is a literal or\n// a path this file built, so the shell has nothing to escape.\nconst SHELL = process.platform === 'win32'\n// `prepublishOnly` runs this proof as `npm run test:distribution -- --mode release`.\n// Release is the publish gate, so evidence it cannot obtain fails there and skips\n// everywhere else: a gate that passes on missing evidence proves nothing.\nconst RELEASE = import.meta.env.MODE === 'release'\n// The built output directory a browser face is published from. Every selection here\n// reads this prefix off the export TARGET and never off the subpath name. A\n// workspace whose only published face is the browser one publishes that face at the\n// root subpath, so a rule keyed on the subpath name drives a browser bundle through\n// Node and the miss is silent.\nconst BROWSER_OUTPUT = './dist/src/browser/'\nconst ABSENT_SUBPATH = '/no-subpath-is-published-under-this-name'\nconst PING = ['ping', '--fetch-retries=0', '--fetch-timeout=5000', '--loglevel=silent']\nconst ESM_DRIVER = 'drive.mjs'\nconst CJS_DRIVER = 'drive.cjs'\nconst CONSUMER_MANIFEST = `{ \"name\": \"distribution-consumer\", \"private\": true, \"type\": \"module\" }\\n`\nconst ESM_DRIVER_SOURCE = `const entry = await import(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\nconst CJS_DRIVER_SOURCE = `const entry = require(process.argv[2])\nprocess.stdout.write(JSON.stringify(Object.keys(entry).sort()))\n`\n\n// The extensions a JavaScript handler loads as modules. Node loads a native addon\n// through its addon handler instead, so that extension is named separately.\nconst MODULE_EXTENSIONS = ['.js', '.mjs', '.cjs']\nconst ADDON_EXTENSION = '.node'\n// The extensions a declaration file carries. A `require` condition declares\n// `.d.cts` and an ESM-only one `.d.mts`, so the `.d.ts` spelling alone does not\n// name them.\nconst DECLARATION_EXTENSIONS = ['.d.ts', '.d.cts', '.d.mts']\ntype Format = 'module' | 'commonjs'\n\n// The Node import target is resolved with the conditions that driver supplies. The\n// CommonJS compile probe is selected from its declaration's format, and its runtime\n// drive loads the same subpath through Node's require resolver. Vite's production\n// client build enables its module and browser conditions.\nconst RUNTIME_CONDITIONS = Object.freeze({\n\tmodule: Object.freeze(['node-addons', 'node', 'import', 'module-sync']),\n\tcommonjs: Object.freeze(['node-addons', 'node', 'require', 'module-sync']),\n\tbrowser: Object.freeze(['module', 'browser', 'production', 'import']),\n})\n// TypeScript's Node resolutions add `node` to the format condition. Its bundler\n// resolution does not, so a browser drive compares against the declaration a bundler\n// consumer reads rather than borrowing the Node declaration.\nconst BUNDLER_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'import'],\n\tcommonjs: ['types', 'require'],\n})\nconst DECLARATION_CONDITIONS = Object.freeze({\n\tmodule: ['types', 'node', 'import'],\n\tcommonjs: ['types', 'node', 'require'],\n\tbrowser: BUNDLER_CONDITIONS.module,\n})\n\ninterface Resolution {\n\treadonly label: string\n\treadonly resolution: ts.ModuleResolutionKind\n\treadonly module: ts.ModuleKind\n\treadonly conditions: Readonly<Record<Format, readonly string[]>>\n}\n\ninterface TargetResolution {\n\treadonly target: string\n}\n\n// Each compile driver carries the conditions TypeScript applies for its resolution\n// and importing format. A `require`-only subpath therefore stays in each CommonJS\n// probe that can resolve it.\nconst RESOLUTIONS: readonly Resolution[] = [\n\t{\n\t\tlabel: 'node16',\n\t\tresolution: ts.ModuleResolutionKind.Node16,\n\t\tmodule: ts.ModuleKind.Node16,\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'nodenext',\n\t\tresolution: ts.ModuleResolutionKind.NodeNext,\n\t\tmodule: ts.ModuleKind.NodeNext,\n\t\tconditions: DECLARATION_CONDITIONS,\n\t},\n\t{\n\t\tlabel: 'bundler',\n\t\tresolution: ts.ModuleResolutionKind.Bundler,\n\t\tmodule: ts.ModuleKind.ESNext,\n\t\tconditions: BUNDLER_CONDITIONS,\n\t},\n]\n\nconst FORMATS: ReadonlyArray<readonly [extension: string, format: Format]> = [\n\t['ts', 'module'],\n\t['cts', 'commonjs'],\n]\n\n// One published subpath, resolved to what this proof can drive: the specifier a\n// consumer writes, the declarations its consumer formats name, whether its target\n// is a browser bundle, and whether it answers `import` and `require` at all.\ninterface Entry {\n\treadonly subpath: string\n\treadonly specifier: string\n\treadonly mapping: unknown\n\treadonly declaration: {\n\t\treadonly module: string | undefined\n\t\treadonly commonjs: string | undefined\n\t\treadonly browser: string | undefined\n\t}\n\treadonly browser: boolean\n\treadonly module: boolean\n\treadonly commonjs: boolean\n\treadonly required: boolean\n}\n\n// The installed tree every claim is read from. Every subpath the exports map names\n// lands in exactly one of `entries`, `undeclared`, and `excluded`, so a subpath this\n// proof cannot drive is reported rather than dropped.\ninterface Stage {\n\treadonly consumer: string\n\treadonly installed: string\n\treadonly archives: readonly string[]\n\treadonly entries: readonly Entry[]\n\treadonly subpaths: readonly string[]\n\treadonly undeclared: readonly string[]\n\treadonly excluded: readonly string[]\n\treadonly targets: readonly string[]\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction isNames(value: unknown): value is readonly string[] {\n\treturn Array.isArray(value) && value.every((name) => typeof name === 'string')\n}\n\n// A fallback list, which is what Node reads an array in an exports entry as. The\n// narrowing is what the following walkers need: `Array.isArray` widens an `unknown`\n// member to `any`, and an entry read that way is not read at all.\nfunction isList(value: unknown): value is readonly unknown[] {\n\treturn Array.isArray(value)\n}\n\n// Whether a string is a valid package target. Node rejects a target outside the\n// package and a target containing a dot, parent, or node_modules segment during\n// package-target resolution. A later module-resolution failure is not the same\n// thing: an array falls through the former and keeps the latter.\nfunction isPackageTarget(target: string): boolean {\n\tif (!target.startsWith('./')) return false\n\tfor (const segment of target.slice(2).split(/[\\\\/]/u)) {\n\t\tlet decoded = segment\n\t\ttry {\n\t\t\tdecoded = decodeURIComponent(segment)\n\t\t} catch {}\n\t\tconst normalized = decoded.toLowerCase()\n\t\tif (normalized === '.' || normalized === '..' || normalized === 'node_modules') return false\n\t}\n\treturn true\n}\n\nfunction readJson(path: string): unknown {\n\tconst parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n\treturn parsed\n}\n\nfunction readManifestName(path: string): string {\n\tconst manifest = readJson(path)\n\tif (!isRecord(manifest) || typeof manifest.name !== 'string') {\n\t\tthrow new Error(`The manifest at ${path} declares no package name`)\n\t}\n\treturn manifest.name\n}\n\nfunction writeFile(path: string, content: string): void {\n\tmkdirSync(dirname(path), { recursive: true })\n\twriteFileSync(path, content)\n}\n\nfunction readOutput(result: SpawnSyncReturns<string>): string {\n\treturn `${result.stdout ?? ''}${result.stderr ?? ''}`.trim()\n}\n\nfunction runNpm(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(NPM, [...args], {\n\t\tcwd,\n\t\tencoding: 'utf8',\n\t\tenv: { ...process.env, npm_config_cache: CACHE },\n\t\tshell: SHELL,\n\t\twindowsHide: true,\n\t})\n}\n\nfunction runNode(args: readonly string[], cwd: string): SpawnSyncReturns<string> {\n\treturn spawnSync(process.execPath, [...args], { cwd, encoding: 'utf8', windowsHide: true })\n}\n\n// Node's own condition matching, read in declaration order.\nfunction resolvePackageTarget(\n\tentry: unknown,\n\tconditions: readonly string[],\n): TargetResolution | undefined {\n\tif (typeof entry === 'string') return { target: entry }\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolvePackageTarget(member, conditions)\n\t\t\tif (resolved !== undefined && isPackageTarget(resolved.target)) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolvePackageTarget(nested, conditions)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// A flat entry, a condition-nested entry, and a fallback list all resolve through\n// one walker. An entry may declare `types` beside `default` at its top level\n// rather than inside `import`, so a fixed `entry.import.types` lookup is not\n// equivalent to condition resolution.\nfunction resolveTarget(entry: unknown, conditions: readonly string[]): string | undefined {\n\treturn resolvePackageTarget(entry, conditions)?.target\n}\n\n// Whether a path is a physical file. TypeScript's file-existence check refuses a\n// directory at the same spelling and continues to the outer package scope.\nfunction matchesFile(path: string): boolean {\n\ttry {\n\t\treturn statSync(path).isFile()\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// TypeScript resolves a declaration target by accepting an existing declaration\n// directly or by substituting beside a JavaScript target. A missing target leaves\n// the containing condition or fallback list unresolved, so the walk continues.\nfunction targetToDeclaration(target: string, installed: string): string | undefined {\n\tif (!isPackageTarget(target)) return undefined\n\tlet declaration = target\n\tif (target.endsWith('.cjs')) declaration = `${target.slice(0, -4)}.d.cts`\n\telse if (target.endsWith('.mjs')) declaration = `${target.slice(0, -4)}.d.mts`\n\telse if (target.endsWith('.js')) declaration = `${target.slice(0, -3)}.d.ts`\n\telse if (!isDeclaration(target)) return undefined\n\treturn matchesFile(join(installed, declaration)) ? declaration : undefined\n}\n\n// The declaration TypeScript resolves through one importing format's conditions.\n// Condition objects keep manifest order, and arrays keep fallback order.\nfunction resolveDeclaration(\n\tentry: unknown,\n\tconditions: readonly string[],\n\tinstalled: string,\n): string | undefined {\n\tif (typeof entry === 'string') return targetToDeclaration(entry, installed)\n\tif (isList(entry)) {\n\t\tfor (const member of entry) {\n\t\t\tconst resolved = resolveDeclaration(member, conditions, installed)\n\t\t\tif (resolved !== undefined) return resolved\n\t\t}\n\t\treturn undefined\n\t}\n\tif (!isRecord(entry)) return undefined\n\tfor (const [condition, nested] of Object.entries(entry)) {\n\t\tif (condition !== 'default' && !conditions.includes(condition)) continue\n\t\tconst resolved = resolveDeclaration(nested, conditions, installed)\n\t\tif (resolved !== undefined) return resolved\n\t}\n\treturn undefined\n}\n\n// The nearest package scope that decides a `.d.ts` declaration's module format. A\n// physical nested manifest starts a scope even when it omits `type` or cannot be\n// parsed. A directory at that spelling is not a manifest, so the walk continues.\nfunction readPackageType(installed: string, target: string): unknown {\n\tlet directory = dirname(join(installed, target))\n\twhile (true) {\n\t\tconst path = join(directory, 'package.json')\n\t\tif (matchesFile(path)) {\n\t\t\ttry {\n\t\t\t\tconst manifest = readJson(path)\n\t\t\t\treturn isRecord(manifest) ? manifest.type : undefined\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t}\n\t\tif (directory === installed) return undefined\n\t\tconst parent = dirname(directory)\n\t\tif (parent === directory) return undefined\n\t\tdirectory = parent\n\t}\n}\n\n// Whether the declaration selected by a typed CommonJS consumer admits that entry\n// to its compile probe. A `.d.cts` declaration admits and a `.d.mts`\n// declaration refuses. A `.d.ts` declaration takes its own nearest package scope.\n// Runtime target format remains the runtime drive's separate question.\nfunction resolvesCommonJS(entry: unknown, installed: string): boolean {\n\tconst declaration = resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed)\n\tif (declaration === undefined) return false\n\tif (declaration.endsWith('.d.cts')) return true\n\tif (declaration.endsWith('.d.mts')) return false\n\treturn declaration.endsWith('.d.ts') && readPackageType(installed, declaration) !== 'module'\n}\n\n// Every target an entry names under any condition. A fallback list omits members\n// Node rejects during package-target validation, because no reader can take them.\nfunction collectTargets(entry: unknown): readonly string[] {\n\tif (typeof entry === 'string') return [entry]\n\tif (isList(entry)) return entry.flatMap(collectTargets).filter(isPackageTarget)\n\tif (!isRecord(entry)) return []\n\treturn Object.values(entry).flatMap((nested) => collectTargets(nested))\n}\n\n// Whether a target is a file a runtime loads for its names, which is what a\n// declaration is owed for. The extension on the target's own file name decides it,\n// and a name carrying no extension is code: `require` reads such a file through its\n// JavaScript handler, so an extensionless target loads and publishes names. Node\n// loads `.node` through its native-addon handler. Every other extension is an asset\n// a consumer reads rather than imports — a stylesheet, a WebAssembly binary, the\n// `\"./package.json\"` manifest pointer, and a declaration alike.\n// The cost is an extensionless file published for a reader, such as a `LICENSE`:\n// that target reports undeclared until it is given an extension or a declaration.\nfunction isModule(target: string): boolean {\n\tconst name = target.slice(target.lastIndexOf('/') + 1)\n\tconst dot = name.lastIndexOf('.')\n\tif (name.endsWith(ADDON_EXTENSION)) return true\n\treturn dot === -1 || MODULE_EXTENSIONS.includes(name.slice(dot))\n}\n\n// Whether a resolved target is a declaration rather than the JavaScript a\n// `default` branch answers with when the entry declares no `types` condition.\nfunction isDeclaration(target: string): boolean {\n\treturn DECLARATION_EXTENSIONS.some((extension) => target.endsWith(extension))\n}\n\n// The declarations the Node module, Node CommonJS, and browser drives compare\n// against. Each field uses the conditions of the TypeScript consumer paired with\n// that runtime. A JavaScript target resolves through TypeScript's adjacent\n// declaration substitution rather than standing in for the declaration itself.\nfunction readDeclaration(entry: unknown, installed: string): Entry['declaration'] {\n\treturn {\n\t\tmodule: resolveDeclaration(entry, DECLARATION_CONDITIONS.module, installed),\n\t\tcommonjs: resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed),\n\t\tbrowser: resolveDeclaration(entry, DECLARATION_CONDITIONS.browser, installed),\n\t}\n}\n\n// The entries one compile driver can resolve under its own conditions.\nfunction selectEntries(entries: readonly Entry[], conditions: readonly string[]): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tresolveTarget(entry.mapping, conditions) !== undefined &&\n\t\t\t(!conditions.includes('require') || entry.commonjs),\n\t)\n}\n\n// Require-loadable entries that declare CommonJS support but a typed CommonJS\n// consumer cannot compile against. A default branch resolving under the require\n// condition set makes no CommonJS claim.\nfunction selectUntypable(entries: readonly Entry[]): readonly Entry[] {\n\treturn entries.filter(\n\t\t(entry) =>\n\t\t\tentry.required &&\n\t\t\tisRecord(entry.mapping) &&\n\t\t\tObject.hasOwn(entry.mapping, 'require') &&\n\t\t\t!entry.commonjs,\n\t)\n}\n\n// The value exports a declaration publishes, read through the compiler's checker\n// over the module symbol rather than off the declaration text. An alias resolves to\n// what it names, so a re-export counts as the thing it re-exports, and a type-only\n// symbol is dropped because no runtime publishes one.\nfunction readDeclaredExports(declaration: string): readonly string[] {\n\tconst program = ts.createProgram([declaration], {\n\t\tmodule: ts.ModuleKind.ESNext,\n\t\tmoduleResolution: ts.ModuleResolutionKind.Bundler,\n\t\tnoEmit: true,\n\t\tskipLibCheck: true,\n\t\ttarget: ts.ScriptTarget.ESNext,\n\t})\n\tconst source = program.getSourceFile(declaration)\n\tif (source === undefined) throw new Error(`The declaration ${declaration} was not read`)\n\tconst checker = program.getTypeChecker()\n\tconst symbol = checker.getSymbolAtLocation(source)\n\tif (symbol === undefined) throw new Error(`${declaration} declares no module symbol`)\n\tconst values: string[] = []\n\tfor (const exported of checker.getExportsOfModule(symbol)) {\n\t\tconst direct = (exported.flags & ts.SymbolFlags.Alias) === 0\n\t\tconst resolved = direct ? exported : checker.getAliasedSymbol(exported)\n\t\tif ((resolved.flags & ts.SymbolFlags.Value) !== 0) values.push(exported.getName())\n\t}\n\treturn [...values].sort()\n}\n\n// The diagnostics a consumer compiling against the installed declarations reports,\n// flattened to their messages so a failure names what the consumer could not do.\nfunction compileConsumer(\n\tentry: string,\n\tresolution: ts.ModuleResolutionKind,\n\tmodule: ts.ModuleKind,\n): readonly string[] {\n\tconst program = ts.createProgram([entry], {\n\t\tmodule,\n\t\tmoduleResolution: resolution,\n\t\tnoEmit: true,\n\t\tskipLibCheck: true,\n\t\tstrict: true,\n\t\ttarget: ts.ScriptTarget.ESNext,\n\t})\n\treturn ts\n\t\t.getPreEmitDiagnostics(program)\n\t\t.map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, ' '))\n}\n\n// One consumer module importing every installed entry, written where its own\n// resolution finds the installed package.\nfunction writeConsumerProbe(stage: Stage, path: string, specifiers: readonly string[]): string {\n\tconst names: string[] = []\n\tconst bindings: string[] = []\n\tfor (const [index, specifier] of specifiers.entries()) {\n\t\tconst binding = `entry${String(index)}`\n\t\tnames.push(binding)\n\t\tbindings.push(`import * as ${binding} from ${JSON.stringify(specifier)}`)\n\t}\n\tconst target = join(stage.consumer, path)\n\twriteFile(target, `${bindings.join('\\n')}\\nexport const surface = [${names.join(', ')}]\\n`)\n\treturn target\n}\n\n// The runtime key set a real process reads off one installed entry under one\n// condition. The driver is a file rather than an `--eval` string, so the specifier\n// travels as an argument and nothing needs escaping.\nfunction driveRuntime(stage: Stage, specifier: string, driver: string): readonly string[] {\n\tconst result = runNode([join(stage.consumer, driver), specifier], stage.consumer)\n\tif (result.status !== 0) {\n\t\tthrow new Error(`Loading ${specifier} from the consumer failed: ${readOutput(result)}`)\n\t}\n\tconst published: unknown = JSON.parse(result.stdout)\n\tif (!isNames(published)) throw new Error(`The driver printed no name list for ${specifier}`)\n\treturn published\n}\n{{helpers}}\n// Pack this workspace, install the archive into an isolated consumer, and read the\n// published surface back off the installed tree. Every later claim reads this\n// result, so a failure here is raised where it happens rather than once per entry.\nfunction buildStage(): Stage {\n\tconst packed = join(SCRATCH, 'packed')\n\tconst consumer = join(SCRATCH, 'consumer')\n\tmkdirSync(packed, { recursive: true })\n\tconst pack = runNpm(['pack', '--ignore-scripts', '--pack-destination', packed], ROOT)\n\tif (pack.status !== 0) throw new Error(`npm pack refused this workspace: ${readOutput(pack)}`)\n\tconst archives = readdirSync(packed).filter((name) => name.endsWith('.tgz'))\n\tconst archive = archives[0]\n\tif (archives.length !== 1 || archive === undefined) {\n\t\tthrow new Error(`npm pack wrote no single archive: ${archives.join(', ')}`)\n\t}\n\twriteFile(join(consumer, 'package.json'), CONSUMER_MANIFEST)\n\twriteFile(join(consumer, ESM_DRIVER), ESM_DRIVER_SOURCE)\n\twriteFile(join(consumer, CJS_DRIVER), CJS_DRIVER_SOURCE)\n\tconst install = runNpm(\n\t\t['install', '--ignore-scripts', '--no-audit', '--no-fund', join(packed, archive)],\n\t\tconsumer,\n\t)\n\tif (install.status !== 0) {\n\t\tthrow new Error(`Installing the packed archive failed: ${readOutput(install)}`)\n\t}\n\tconst name = readManifestName(join(ROOT, 'package.json'))\n\tconst installed = join(consumer, 'node_modules', ...name.split('/'))\n\tconst manifest = readJson(join(installed, 'package.json'))\n\tif (!isRecord(manifest) || !isRecord(manifest.exports)) {\n\t\tthrow new Error('The installed manifest publishes no exports map')\n\t}\n\tconst entries: Entry[] = []\n\tconst targets: string[] = []\n\tconst subpaths: string[] = []\n\tconst undeclared: string[] = []\n\tconst excluded: string[] = []\n\tfor (const [subpath, entry] of Object.entries(manifest.exports)) {\n\t\tconst files = collectTargets(entry)\n\t\ttargets.push(...files)\n\t\tsubpaths.push(subpath)\n\t\tconst declaration = readDeclaration(entry, installed)\n\t\t// A subpath resolving no declaration is partitioned rather than dropped. It is a\n\t\t// defect when a runtime loads one of its targets for names, because a consumer\n\t\t// importing it compiles against nothing under `node16`. It is an excluded\n\t\t// publication otherwise: the `\"./package.json\"` manifest pointer and a stylesheet\n\t\t// are published for a reader rather than an importer.\n\t\tif (\n\t\t\tdeclaration.module === undefined &&\n\t\t\tdeclaration.commonjs === undefined &&\n\t\t\tdeclaration.browser === undefined\n\t\t) {\n\t\t\tif (files.some(isModule)) undeclared.push(subpath)\n\t\t\telse excluded.push(subpath)\n\t\t\tcontinue\n\t\t}\n\t\tconst imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)\n\t\tconst commonjs = resolvesCommonJS(entry, installed)\n\t\tconst required = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs) !== undefined\n\t\tconst module = resolveTarget(entry, RUNTIME_CONDITIONS.browser)\n\t\tentries.push({\n\t\t\tsubpath,\n\t\t\tspecifier: subpath === '.' ? name : `${name}${subpath.slice(1)}`,\n\t\t\tmapping: entry,\n\t\t\tdeclaration: {\n\t\t\t\tmodule: declaration.module === undefined ? undefined : join(installed, declaration.module),\n\t\t\t\tcommonjs:\n\t\t\t\t\tdeclaration.commonjs === undefined ? undefined : join(installed, declaration.commonjs),\n\t\t\t\tbrowser:\n\t\t\t\t\tdeclaration.browser === undefined ? undefined : join(installed, declaration.browser),\n\t\t\t},\n\t\t\tbrowser: module !== undefined && module.startsWith(BROWSER_OUTPUT),\n\t\t\tmodule: imported !== undefined,\n\t\t\tcommonjs,\n\t\t\trequired,\n\t\t})\n\t}\n\treturn { consumer, installed, archives, entries, subpaths, undeclared, excluded, targets }\n}\n\nconst SCRATCH = mkdtempSync(join(tmpdir(), 'distribution-'))\nconst CACHE = join(SCRATCH, 'cache')\nmkdirSync(CACHE, { recursive: true })\n// The scratch tree holds the npm cache, the packed archive, and the installed\n// consumer, so its removal is registered before the first thing that can throw.\nafterAll(() => {\n\trmSync(SCRATCH, { force: true, recursive: true })\n})\n\n// Installing the packed archive resolves its own runtime dependencies, so an\n// unreachable registry leaves nothing to measure. Under release that is the gate\n// failing; anywhere else the suite skips and names the mechanism it wanted.\n//\n// A module that throws while loading never reaches the `afterAll` it registered,\n// so every throw here removes the scratch tree on its way out.\nfunction openStage(): Stage | undefined {\n\ttry {\n\t\tif (runNpm(PING, ROOT).status !== 0) {\n\t\t\tif (!RELEASE) return undefined\n\t\t\tthrow new Error(\n\t\t\t\t'The release gate requires a reachable npm registry, and npm ping did not answer',\n\t\t\t)\n\t\t}\n\t\treturn buildStage()\n\t} catch (error) {\n\t\trmSync(SCRATCH, { force: true, recursive: true })\n\t\tthrow error\n\t}\n}\n\nconst STAGE = openStage()\nconst STAGED = STAGE !== undefined\n\n// The staged consumer, or a skip naming what the run could not reach. `it.skipIf`\n// carries no reason, so the gate sits here where the test context can state one.\nfunction requireStage(context: TestContext): Stage {\n\tif (!STAGED) {\n\t\treturn context.skip('`npm ping` did not answer, so nothing was packed or installed')\n\t}\n\treturn STAGE\n}\n\ndescribe('installed package consumer', () => {\n\tit('packs one archive and installs it in isolation [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\texpect(stage.archives).toHaveLength(1)\n\t\texpect(existsSync(join(stage.installed, 'package.json'))).toBe(true)\n\t\texpect(stage.entries.length).toBeGreaterThan(0)\n\t})\n\n\tit('ships every relative target its exports map names [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst relative = stage.targets.filter((target) => target.startsWith('./'))\n\t\texpect(relative).not.toStrictEqual([])\n\t\texpect(relative.filter((target) => !existsSync(join(stage.installed, target)))).toStrictEqual(\n\t\t\t[],\n\t\t)\n\t})\n\n\t// Every published subpath is driven, excluded by name, or reported here. A dropped\n\t// one leaves no trace: no runtime test, no declaration comparison, and no place in\n\t// the resolution compile, so the run reports success for a subpath it never\n\t// measured.\n\tit('declares types for every module it publishes [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst partitioned = [\n\t\t\t...stage.entries.map((entry) => entry.subpath),\n\t\t\t...stage.undeclared,\n\t\t\t...stage.excluded,\n\t\t]\n\t\texpect(stage.undeclared).toStrictEqual([])\n\t\texpect(partitioned.sort()).toStrictEqual([...stage.subpaths].sort())\n\t\t// A driven subpath answers a runtime condition. One resolving a declaration and\n\t\t// no Node or browser target compiles for a consumer and throws when that consumer\n\t\t// loads it. Each later drive retires itself for that entry, so this assertion names\n\t\t// the subpath rather than counting it as driven.\n\t\tconst unreachable = stage.entries.filter(\n\t\t\t(entry) => !entry.module && !entry.required && !entry.browser,\n\t\t)\n\t\texpect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])\n\t\tconst untypable = selectUntypable(stage.entries)\n\t\texpect(untypable.map((entry) => entry.subpath)).toStrictEqual([])\n\t})\n\n\tit('refuses a subpath its exports map does not name [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst driver = join(stage.consumer, ESM_DRIVER)\n\t\tconst result = runNode([driver, `${name}${ABSENT_SUBPATH}`], stage.consumer)\n\t\texpect(result.status).not.toBe(0)\n\t\texpect(readOutput(result)).toContain('ERR_PACKAGE_PATH_NOT_EXPORTED')\n\t})\n\n\t// The absent subpath is the firing control: a resolution that reports nothing\n\t// for every published entry has not been shown to resolve anything at all. Each\n\t// module format carries its own control, because a format that resolves nothing\n\t// is silent for the same reason a resolution that resolves nothing is.\n\tit('compiles a consumer under every module resolution [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst name = readManifestName(join(stage.installed, 'package.json'))\n\t\tconst reported: string[] = []\n\t\tconst silent: string[] = []\n\t\tfor (const driver of RESOLUTIONS) {\n\t\t\tfor (const [extension, format] of FORMATS) {\n\t\t\t\tconst written = selectEntries(stage.entries, driver.conditions[format])\n\t\t\t\tif (written.length === 0) continue\n\t\t\t\tconst specifiers = written.map((entry) => entry.specifier)\n\t\t\t\tconst probe = writeConsumerProbe(stage, `probe.${driver.label}.${extension}`, specifiers)\n\t\t\t\tfor (const message of compileConsumer(probe, driver.resolution, driver.module)) {\n\t\t\t\t\treported.push(`${driver.label}.${extension}: ${message}`)\n\t\t\t\t}\n\t\t\t\tconst absent = [`${name}${ABSENT_SUBPATH}`]\n\t\t\t\tconst control = writeConsumerProbe(stage, `control.${driver.label}.${extension}`, absent)\n\t\t\t\tif (compileConsumer(control, driver.resolution, driver.module).length === 0) {\n\t\t\t\t\tsilent.push(`${driver.label}.${extension}`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\texpect(reported).toStrictEqual([])\n\t\texpect(silent).toStrictEqual([])\n\t})\n{{guard}}})\n\nfor (const entry of STAGE?.entries ?? []) {\n\tdescribe(`installed entry ${entry.subpath}`, () => {\n\t\tit.runIf(entry.module && !entry.browser)(\n\t\t\t'publishes what it declares to a Node import, and no more',\n\t\t\t(context) => {\n\t\t\t\tconst declaration = entry.declaration.module\n\t\t\t\tif (declaration === undefined) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no import declaration`)\n\t\t\t\t}\n\t\t\t\tconst published = driveRuntime(requireStage(context), entry.specifier, ESM_DRIVER)\n\t\t\t\texpect(published).toStrictEqual(readDeclaredExports(declaration))\n\t\t\t},\n\t\t)\n\n\t\tit.runIf(!entry.browser && entry.required)(\n\t\t\t'publishes what it declares to a Node require, and no more',\n\t\t\t(context) => {\n\t\t\t\tconst declaration = entry.declaration.commonjs\n\t\t\t\tif (declaration === undefined) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no require declaration`)\n\t\t\t\t}\n\t\t\t\tconst published = driveRuntime(requireStage(context), entry.specifier, CJS_DRIVER)\n\t\t\t\texpect(published).toStrictEqual(readDeclaredExports(declaration))\n\t\t\t},\n\t\t)\n{{drive}}\t})\n}\n";
100
+ transport: "import { createServer } from 'node:http'\n";
101
+ types: "import type { PlaywrightProviderOptions } from '@vitest/browser-playwright'\nimport type { Browser } from 'playwright'\n";
102
+ launcher: "import { chromium } from 'playwright'\nimport { build } from 'vite'\nimport { resolveBrowser, resolvePinnedBrowser } from '../configs/browsers.js'\n";
103
+ helpers: "\nconst BROWSER_PAGE = `<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<title>Distribution</title>\n\t</head>\n\t<body>\n\t\t<script type=\"module\" src=\"./main.js\"></script>\n\t</body>\n</html>\n`\n\nfunction readContentType(path: string): string {\n\tif (path.endsWith('.html')) return 'text/html'\n\tif (path.endsWith('.js')) return 'text/javascript'\n\tif (path.endsWith('.css')) return 'text/css'\n\tif (path.endsWith('.json') || path.endsWith('.map')) return 'application/json'\n\treturn 'application/octet-stream'\n}\n\n// `resolveBrowser` answers with provider options and never reports absence: its\n// last resort is a channel nothing verified. So the launch is attempted and its\n// rejection classified, rather than probed for and ruled on.\nfunction describeBrowser(options: PlaywrightProviderOptions): string {\n\tconst endpoint = options.connectOptions?.wsEndpoint\n\tif (endpoint !== undefined) return `the browser server at ${endpoint}`\n\tconst executable = options.launchOptions?.executablePath\n\tif (executable !== undefined) return `the executable at ${executable}`\n\tconst channel = options.launchOptions?.channel\n\tif (channel !== undefined) return `the ${channel} channel`\n\treturn 'the Chromium Playwright installed for itself'\n}\n\nasync function launchBrowser(options: PlaywrightProviderOptions): Promise<Browser> {\n\tconst endpoint = options.connectOptions?.wsEndpoint\n\tif (endpoint !== undefined) return chromium.connect(endpoint)\n\treturn chromium.launch({ ...options.launchOptions, headless: true })\n}\n\n// A consumer of one installed browser entry, bundled by the Vite toolchain this\n// workspace already declares. Nothing is stubbed: the bundle resolves the installed\n// package and its whole transitive graph as an application consuming it would.\nasync function bundleEntry(stage: Stage, entry: Entry): Promise<string> {\n\tconst page = join(stage.consumer, 'pages', entry.subpath.replaceAll(/[^\\w]+/gu, '-'))\n\tconst specifier = JSON.stringify(entry.specifier)\n\twriteFile(join(page, 'index.html'), BROWSER_PAGE)\n\twriteFile(\n\t\tjoin(page, 'main.js'),\n\t\t`import * as entry from ${specifier}\\nglobalThis.subject = Object.keys(entry).sort()\\n`,\n\t)\n\tawait build({\n\t\tbase: './',\n\t\tbuild: { emptyOutDir: true, outDir: 'bundle' },\n\t\tconfigFile: false,\n\t\tlogLevel: 'error',\n\t\troot: page,\n\t})\n\treturn join(page, 'bundle')\n}\n\n// The key set the bundled module publishes in a real browser, read off the page\n// once it has loaded over a loopback server. A module that never evaluated\n// publishes nothing, and a page error is raised rather than compared away.\nasync function readBrowserExports(browser: Browser, bundle: string): Promise<readonly string[]> {\n\tconst server = createServer((request, response) => {\n\t\tconst asked = request.url === undefined || request.url === '/' ? '/index.html' : request.url\n\t\tconst path = join(bundle, decodeURIComponent(asked))\n\t\tif (!path.startsWith(bundle) || !existsSync(path)) {\n\t\t\tresponse.writeHead(404)\n\t\t\tresponse.end()\n\t\t\treturn\n\t\t}\n\t\tresponse.writeHead(200, { 'content-type': readContentType(path) })\n\t\tresponse.end(readFileSync(path))\n\t})\n\ttry {\n\t\tawait new Promise<void>((settle) => {\n\t\t\tserver.listen(0, '127.0.0.1', settle)\n\t\t})\n\t\tconst address = server.address()\n\t\tif (address === null || typeof address === 'string') {\n\t\t\tthrow new Error('The bundle server bound no port')\n\t\t}\n\t\tconst page = await browser.newPage()\n\t\tconst failures: string[] = []\n\t\tpage.on('pageerror', (error) => failures.push(String(error)))\n\t\tawait page.goto(`http://127.0.0.1:${String(address.port)}/`, { waitUntil: 'load' })\n\t\tconst published: unknown = await page.evaluate('globalThis.subject')\n\t\tif (failures.length > 0) throw new Error(`The bundle raised ${failures.join(' | ')}`)\n\t\tif (!isNames(published)) throw new Error('The bundled module published no name list')\n\t\treturn published\n\t} finally {\n\t\tserver.close()\n\t}\n}\n";
104
+ drive: "\n\t\tit.runIf(entry.browser)(\n\t\t\t'publishes what it declares to a real browser, and no more [requires a browser]',\n\t\t\tasync (context) => {\n\t\t\t\tconst stage = requireStage(context)\n\t\t\t\tconst declaration = entry.declaration.browser\n\t\t\t\tif (declaration === undefined) {\n\t\t\t\t\tthrow new Error(`${entry.subpath} publishes no browser declaration`)\n\t\t\t\t}\n\t\t\t\tconst options = resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)\n\t\t\t\tconst browser = await launchBrowser(options).catch((error: unknown) => {\n\t\t\t\t\tconst cause = `${describeBrowser(options)} was rejected: ${String(error)}`\n\t\t\t\t\tif (RELEASE) throw new Error(`The release gate requires a browser, and ${cause}`)\n\t\t\t\t\treturn context.skip(`No browser launched. ${cause}`)\n\t\t\t\t})\n\t\t\t\ttry {\n\t\t\t\t\tconst bundle = await bundleEntry(stage, entry)\n\t\t\t\t\texpect(await readBrowserExports(browser, bundle)).toStrictEqual(\n\t\t\t\t\t\treadDeclaredExports(declaration),\n\t\t\t\t\t)\n\t\t\t\t} finally {\n\t\t\t\t\tawait browser.close()\n\t\t\t\t}\n\t\t\t},\n\t\t)\n";
105
+ guard: "\n\t// This proof drives a Node import and a Node require and carries no browser\n\t// branch: the workspace published no browser face when it was written, and the\n\t// browser drive measures the packed artifact, so only a published face is owed\n\t// one. A private browser application does not select this branch. It declares the\n\t// browser launcher and its Vitest browser provider and gets the generated browser\n\t// configuration module beside it, but installed browser tooling does not stand for\n\t// a published browser face. `vite` selects nothing either, though the branch\n\t// imports it: scaffold puts `vite` in every workspace's base development\n\t// dependencies, whatever that workspace publishes. The later Node\n\t// `it.runIf` predicates retire each matching Node drive for a face published\n\t// later, which leaves nothing measuring it. So it reddens here and names the\n\t// subpath a browser branch is owed for. A workspace that gains one deletes this\n\t// file and runs the `repair` verb, which writes the variant carrying that branch.\n\tit('publishes no browser face this proof cannot drive [requires the registry]', (context) => {\n\t\tconst stage = requireStage(context)\n\t\tconst faces = stage.entries.filter((entry) => entry.browser)\n\t\texpect(faces.map((entry) => entry.subpath)).toStrictEqual([])\n\t})\n";
106
+ }>;
98
107
  integration: "{{imports}}import { describe, expect, it } from 'vitest'\n\ndescribe('workspace integration', () => {\n\tit('loads every selected public barrel together as a composition seed', () => {\n\t\t// Replace this empty-barrel seed with one observable flow that passes one\n\t\t// environment's public result into another.\n\t\t{{actual}}{{expected}})\n\t})\n})\n";
99
108
  }>;
100
109
  docs: Readonly<{
@@ -236,8 +245,8 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
236
245
  * are runtime `@orkestrel/*` packages. A peer in the `@orkestrel` scope is a
237
246
  * fleet pin; every other peer is a floor. `extras` are package-specific
238
247
  * development dependencies and may carry any valid npm name.
239
- * `bin`, `setup`, `guides`, `distribution`, `integration`, `conformance`,
240
- * `service`, `vendors`, `global`, and `showcase` are structural facts: each is
248
+ * `bin`, `setup`, `guides`, `integration`, `conformance`, `service`,
249
+ * `vendors`, `global`, and `showcase` are structural facts: each is
241
250
  * set only when the workspace physically ships the directory or exact-case file
242
251
  * that defines it, never because of the workspace's name and never because a
243
252
  * sibling fact is set.
@@ -267,7 +276,6 @@ export declare interface Blueprint {
267
276
  readonly bin: boolean;
268
277
  readonly setup: boolean;
269
278
  readonly guides: boolean;
270
- readonly distribution: boolean;
271
279
  readonly integration: boolean;
272
280
  readonly conformance: boolean;
273
281
  readonly service: boolean;
@@ -524,13 +532,15 @@ export declare function blueprintToRootVite(blueprint: Blueprint): string;
524
532
  * proofs every workspace can pass before it has a public API, and one build per
525
533
  * target that actually builds.
526
534
  *
527
- * A publishing workspace isolates distribution and live-service proofs from
528
- * `test` and runs them from `prepublishOnly` instead. A private workspace has
529
- * no publish lifecycle, so it omits distribution and runs a live-service proof
530
- * from `test`. Integration and conformance stay in `test` because they neither
531
- * pack nor install the workspace and drive no external service. A conformance
532
- * run may start a server, but it starts its own and reaches it over loopback,
533
- * so the run stays hermetic.
535
+ * A publishing workspace isolates its distribution and live-service proofs from
536
+ * `test` and runs them from `prepublishOnly` instead. Publishing is what selects
537
+ * the distribution proof: what that proof measures is the packed tarball, so a
538
+ * workspace that packs no published source has nothing for it to read. A private
539
+ * workspace therefore omits it and runs a live-service proof from `test`.
540
+ * Integration and conformance stay in `test` because they neither pack nor
541
+ * install the workspace and drive no external service. A conformance run may
542
+ * start a server, but it starts its own and reaches it over loopback, so the run
543
+ * stays hermetic.
534
544
  *
535
545
  * The configuration paths interpolated here are the same ones `SRC_MATRIX` and
536
546
  * `APP_MATRIX` list as each environment's configuration files, so a rename in
@@ -591,6 +601,13 @@ export declare function blueprintToSourceArtifacts(blueprint: Blueprint): readon
591
601
  * readiness setup alone, because the root configuration names that module by
592
602
  * path.
593
603
  *
604
+ * The distribution proof is emitted, and the same test separates it from those
605
+ * two: its subject is the packed tarball rather than anything only the package
606
+ * knows, so every assertion derives from the installed tree at run time and
607
+ * nothing has to be named. It follows the published source it packs, and it is
608
+ * the one artifact here claimed by presence: a target lacking it reports as
609
+ * drift, and a package that replaced it with a better proof keeps that proof.
610
+ *
594
611
  * @example
595
612
  * ```ts
596
613
  * import { blueprintToTestArtifacts, createBlueprint } from '@orkestrel/scaffold'
@@ -602,6 +619,35 @@ export declare function blueprintToSourceArtifacts(blueprint: Blueprint): readon
602
619
  */
603
620
  export declare function blueprintToTestArtifacts(blueprint: Blueprint): readonly ContentArtifact[];
604
621
 
622
+ /**
623
+ * Project a blueprint into the manifest scripts a region write may replace.
624
+ *
625
+ * @param blueprint - The workspace specification.
626
+ * @returns One entry per writable script, or none when the workspace publishes
627
+ * nothing and therefore declares neither script.
628
+ *
629
+ * @remarks
630
+ * Publishing is what selects these scripts, so a private workspace answers an
631
+ * empty region and the write leaves its manifest alone.
632
+ *
633
+ * `accepted` carries the predecessor a target can hold before this package
634
+ * generated the packed-package proof: the same gate chain without
635
+ * {@link RELEASE_PROOF_COMMAND}. The value being written is always writable, so
636
+ * it is not repeated there. Any other value is a chain the workspace author
637
+ * customized, and {@link replaceManifestScripts} refuses the whole region
638
+ * rather than taking it.
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * import { blueprintToWritableScripts, createBlueprint } from '@orkestrel/scaffold'
643
+ *
644
+ * const blueprint = createBlueprint('router', { src: ['core'] })
645
+ *
646
+ * blueprintToWritableScripts(blueprint)[0]?.name // 'test:distribution'
647
+ * ```
648
+ */
649
+ export declare function blueprintToWritableScripts(blueprint: Blueprint): readonly ManifestScript[];
650
+
605
651
  /** One module format a published library environment builds. */
606
652
  export declare type BuildFormat = 'es' | 'cjs';
607
653
 
@@ -661,7 +707,7 @@ export declare type CatalogEntry = {
661
707
  readonly note?: never;
662
708
  } | {
663
709
  readonly name: string;
664
- readonly lookup: 'missing' | 'failed';
710
+ readonly lookup: 'missing' | 'unmatched' | 'failed';
665
711
  readonly note: string;
666
712
  readonly version?: never;
667
713
  readonly dependencies?: never;
@@ -1050,7 +1096,7 @@ export declare class Compiler implements CompilerInterface {
1050
1096
  }>;
1051
1097
  app: Readonly<{
1052
1098
  core: "export const appCore = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\tpublicDir: false,\n\t\t\tplugins: [environmentBoundary('app/core')],\n\t\t\ttest: {\n\t\t\t\tname: { label: 'app:core', color: 'cyan' },\n\t\t\t\tinclude: ['tests/app/core/**/*.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
1053
- browser: "function applicationBrowser(showcase: boolean): UserConfig {\n\tconst output = showcase ? 'dist/showcase' : 'dist/app/browser'\n{{showcasePlugins}}\treturn {\n\t\tresolve,\n{{plugins}}\t\troot: resolveWorkspacePath('app/browser'),\n\t\tpublicDir: false,\n\t\tbuild: {\n{{showcaseBuild}}\t\t\temptyOutDir: true,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tinput: resolveWorkspacePath('app/browser/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'app:browser', color: 'blue' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tdir: resolveWorkspacePath('.'),\n\t\t\tinclude: ['tests/app/browser/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n}\n\nexport function appBrowser(): UserConfig {\n\treturn applicationBrowser(false)\n}\n{{showcaseFactory}}";
1099
+ browser: "function applicationBrowser(showcase: boolean): UserConfig {\n\tconst output = showcase ? 'dist/showcase' : 'dist/app/browser'\n{{showcasePlugins}}\treturn {\n\t\tresolve,\n{{plugins}}\t\troot: resolveWorkspacePath('app/browser'),\n\t\tpublicDir: false,\n\t\tbuild: {\n{{showcaseBuild}}\t\t\temptyOutDir: true,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tinput: resolveWorkspacePath('app/browser/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'app:browser', color: 'blue' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tdir: resolveWorkspacePath('.'),\n\t\t\tinclude: ['tests/app/browser/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n}\n\nexport function appBrowser(options?: UserConfig): UserConfig {\n\treturn mergeConfig(applicationBrowser(false), options ?? {})\n}\n{{showcaseFactory}}";
1054
1100
  server: "export const appServer = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\tpublicDir: false,\n\t\t\tplugins: [outputBoundary('dist/app/server'), environmentBoundary('app/server')],\n\t\t\tbuild: {\n\t\t\t\temptyOutDir: true,\n\t\t\t\tlib: {\n\t\t\t\t\tentry: resolveWorkspacePath('app/server/main.ts'),\n\t\t\t\t\tformats: ['cjs'],\n\t\t\t\t\tfileName: () => 'main.cjs',\n\t\t\t\t},\n\t\t\t\toutDir: resolveWorkspacePath('dist/app/server'),\n\t\t\t\ttarget: 'node22',\n\t\t\t\trolldownOptions: {\n\t\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\t\texternal: (id: string) => id.startsWith('node:'),\n\t\t\t\t},\n\t\t\t},\n\t\t\ttest: {\n\t\t\t\tname: { label: 'app:server', color: 'green' },\n\t\t\t\tinclude: ['tests/app/server/**/*.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
1055
1101
  }>;
1056
1102
  policy: "export const policy = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'policy', color: 'white' },\n\t\t\t\tinclude: ['tests/policy.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
@@ -1235,7 +1281,13 @@ export declare class Compiler implements CompilerInterface {
1235
1281
  */
1236
1282
  export declare const DEPENDENCY_NAME_PATTERN: RegExp;
1237
1283
 
1238
- /** The packed-package proof whose presence makes a workspace `distribution`. */
1284
+ /** The dependency sections a range-writing operation may change. */
1285
+ export declare interface DependencyPinSet {
1286
+ readonly runtime: readonly Dependency[];
1287
+ readonly development: readonly Dependency[];
1288
+ }
1289
+
1290
+ /** The generated packed-package proof every publishing workspace is planned at. */
1239
1291
  export declare const DISTRIBUTION_TEST_PATH = "tests/distribution.test.ts";
1240
1292
 
1241
1293
  /**
@@ -1427,6 +1479,9 @@ export declare class Compiler implements CompilerInterface {
1427
1479
  /** Exact lowercase hexadecimal bytes: two digits per byte, and empty content is valid. */
1428
1480
  export declare const HEX_PATTERN: RegExp;
1429
1481
 
1482
+ /** The repository-relative path where the committed vendored-file inventory is served. */
1483
+ export declare const HOST_INVENTORY_PATH = "host.json";
1484
+
1430
1485
  /**
1431
1486
  * The paths byte-copied from the vendored data root, frozen.
1432
1487
  *
@@ -1464,6 +1519,36 @@ export declare class Compiler implements CompilerInterface {
1464
1519
  readonly content?: never;
1465
1520
  }
1466
1521
 
1522
+ /**
1523
+ * One vendored file read from the repository, beside the target bytes it answers for.
1524
+ *
1525
+ * @remarks
1526
+ * `path` is the target-relative path, which is also the checkout-relative path
1527
+ * the repository serves, so the file read and the file answered for cannot
1528
+ * drift apart. A found lookup carries the file's exact bytes as hexadecimal;
1529
+ * one that produced no answer carries the cause and no bytes. `observed` is the target's
1530
+ * file as exact bytes when the read was made, and is absent when the target
1531
+ * holds no such file; it is the precondition the write is held to, exactly as
1532
+ * {@link Finding.observed} is.
1533
+ *
1534
+ * A found row may carry the target's own bytes rather than read ones, where
1535
+ * those bytes already satisfy the claim the read was going to check. They are
1536
+ * the same bytes either way, so the row does not record which it holds.
1537
+ */
1538
+ export declare type HostFile = {
1539
+ readonly path: string;
1540
+ readonly lookup: 'found';
1541
+ readonly hex: string;
1542
+ readonly observed?: string;
1543
+ readonly note?: never;
1544
+ } | {
1545
+ readonly path: string;
1546
+ readonly lookup: 'missing' | 'unmatched' | 'failed';
1547
+ readonly note: string;
1548
+ readonly observed?: string;
1549
+ readonly hex?: never;
1550
+ };
1551
+
1467
1552
  /**
1468
1553
  * A vendored file whose exact bytes have been read, so its content can be compared.
1469
1554
  *
@@ -1664,6 +1749,28 @@ export declare class Compiler implements CompilerInterface {
1664
1749
  */
1665
1750
  export declare const isContent: Guard<string>;
1666
1751
 
1752
+ /**
1753
+ * Checks whether another surface owns the vendored bytes at a path.
1754
+ *
1755
+ * @param path - The target-relative vendored path to test.
1756
+ * @returns `true` for the catalog agent file and for a Markdown guide mirror;
1757
+ * `false` otherwise.
1758
+ *
1759
+ * @remarks
1760
+ * The materializer keeps these paths presence-owned because the catalog or
1761
+ * mirror surface writes their bytes. A live host fill therefore keeps the
1762
+ * installed floor's bytes for them and requests only the host-owned paths.
1763
+ *
1764
+ * @example
1765
+ * ```ts
1766
+ * import { isDeferredPath } from '@orkestrel/scaffold'
1767
+ *
1768
+ * isDeferredPath('guides/router.md') // true
1769
+ * isDeferredPath('AGENTS.md') // false
1770
+ * ```
1771
+ */
1772
+ export declare function isDeferredPath(path: string): boolean;
1773
+
1667
1774
  /**
1668
1775
  * Narrow a value to a {@link Dependency}.
1669
1776
  *
@@ -1765,6 +1872,25 @@ export declare class Compiler implements CompilerInterface {
1765
1872
  */
1766
1873
  export declare const isHex: Guard<string>;
1767
1874
 
1875
+ /**
1876
+ * Narrow a value to a {@link ManifestScript}.
1877
+ *
1878
+ * @remarks
1879
+ * Structural and bounded, exactly as {@link isDependency} is: a script name
1880
+ * and a script command are free text a manifest may carry, and which values a
1881
+ * region writer is willing to overwrite is the caller's decision rather than
1882
+ * this guard's.
1883
+ *
1884
+ * @example
1885
+ * ```ts
1886
+ * import { isManifestScript } from '@orkestrel/scaffold'
1887
+ *
1888
+ * isManifestScript({ name: 'test', command: 'vitest run', accepted: [] }) // true
1889
+ * isManifestScript({ name: 'test', command: 'vitest run' }) // false
1890
+ * ```
1891
+ */
1892
+ export declare const isManifestScript: Guard<ManifestScript>;
1893
+
1768
1894
  /**
1769
1895
  * Narrow a value to a {@link Mirror}.
1770
1896
  *
@@ -1823,7 +1949,9 @@ export declare class Compiler implements CompilerInterface {
1823
1949
  * @remarks
1824
1950
  * A plan reaches the writer, and the writer has no question channel, so this
1825
1951
  * carries the whole law of the value: every artifact path, every claimed byte,
1826
- * and the blueprint it was compiled from.
1952
+ * and the blueprint it was compiled from. An artifact at {@link MANIFEST_PATH}
1953
+ * must carry `birth` ownership. A plan claiming `content` or `presence` there
1954
+ * is refused because the compiler emits the manifest only as birth-owned.
1827
1955
  */
1828
1956
  export declare const isPlan: Guard<Plan>;
1829
1957
 
@@ -1883,27 +2011,65 @@ export declare class Compiler implements CompilerInterface {
1883
2011
  *
1884
2012
  * @remarks
1885
2013
  * `found` carries the answer. `missing` is an upstream `404`, which is a
1886
- * definite answer that the package is not published there. `failed` is a
1887
- * transport fault, which is no answer at all and may succeed on a later run.
1888
- * Holding these apart from how a local copy compares is what lets a verdict
1889
- * omit the value it never received instead of inventing an empty one.
2014
+ * definite answer that the package is not published there. `unmatched` means
2015
+ * the answer was read but no version admits under the declared range. `failed`
2016
+ * means the read did not complete because of a transport fault, timeout, byte
2017
+ * bound, redirect, or refused response shape. Holding these apart from how a
2018
+ * local copy compares is what lets a verdict omit the value it never received
2019
+ * instead of inventing an empty one.
2020
+ */
2021
+ export declare type Lookup = 'found' | 'missing' | 'unmatched' | 'failed';
2022
+
2023
+ /** The manifest path every compiler plan emits with birth ownership. */
2024
+ export declare const MANIFEST_PATH = "package.json";
2025
+
2026
+ /** The dependency sections read from an existing package manifest. */
2027
+ export declare interface ManifestDependencySet {
2028
+ readonly runtime: readonly Dependency[];
2029
+ readonly development: readonly Dependency[];
2030
+ readonly peer: readonly Dependency[];
2031
+ }
2032
+
2033
+ /**
2034
+ * The manifest regions a writing operation may change.
2035
+ *
2036
+ * @remarks
2037
+ * Each region is written in place, so every byte outside the named ranges
2038
+ * survives. `pins` names the declared ranges and `scripts` the declared script
2039
+ * values; a region given nothing to write leaves its section untouched.
1890
2040
  */
1891
- export declare type Lookup = 'found' | 'missing' | 'failed';
2041
+ export declare interface ManifestRegionSet {
2042
+ readonly pins: DependencyPinSet;
2043
+ readonly scripts: readonly ManifestScript[];
2044
+ }
1892
2045
 
1893
2046
  /**
1894
- * Project a package manifest's text to the `@orkestrel/*` packages it declares.
2047
+ * One manifest script a region-writing operation may replace.
2048
+ *
2049
+ * @remarks
2050
+ * `command` is the value the write lands. `accepted` is the closed set of
2051
+ * values the write is willing to overwrite, so a script holding anything else
2052
+ * is a chain its author customized and the write refuses rather than takes it.
2053
+ * An absent script is always writable and needs no entry in `accepted`.
2054
+ */
2055
+ export declare interface ManifestScript {
2056
+ readonly name: string;
2057
+ readonly command: string;
2058
+ readonly accepted: readonly string[];
2059
+ }
2060
+
2061
+ /**
2062
+ * Project a package manifest's text to the `@orkestrel/*` packages each dependency section declares.
1895
2063
  *
1896
2064
  * @param manifest - The `package.json` text.
1897
- * @returns One dependency per declared `@orkestrel` package, in section order,
1898
- * with the first declaration of a repeated name winning.
2065
+ * @returns The runtime, development, and peer declarations as separate lists.
1899
2066
  *
1900
2067
  * @remarks
1901
- * Runtime, development, and peer sections are read in that order, because a
1902
- * package the fleet publishes is upstream of this workspace wherever it is
1903
- * declared. Every other name is skipped rather than refused: a workspace's
1904
- * unrelated dependencies are not this package's to report on.
2068
+ * Every other name is skipped rather than refused: a workspace's unrelated
2069
+ * dependencies are not this package's to report on. Keeping the sections
2070
+ * separate prevents a caller from treating a peer as a writable floor.
1905
2071
  *
1906
- * Never throws, and every row it returns satisfies `isDependency` while the
2072
+ * Never throws, and every row it returns satisfies `isDependency` while each
1907
2073
  * list satisfies `isCollection`, so the result crosses the compiler's own
1908
2074
  * boundary without a second cleaning.
1909
2075
  *
@@ -1912,10 +2078,10 @@ export declare class Compiler implements CompilerInterface {
1912
2078
  * import { manifestToDependencies } from '@orkestrel/scaffold'
1913
2079
  *
1914
2080
  * manifestToDependencies('{"dependencies":{"@orkestrel/emitter":"^0.0.5","vite":"~8.2.0"}}')
1915
- * // [{ name: '@orkestrel/emitter', range: '^0.0.5' }]
2081
+ * // { runtime: [{ name: '@orkestrel/emitter', range: '^0.0.5' }], development: [], peer: [] }
1916
2082
  * ```
1917
2083
  */
1918
- export declare function manifestToDependencies(manifest: string): readonly Dependency[];
2084
+ export declare function manifestToDependencies(manifest: string): ManifestDependencySet;
1919
2085
 
1920
2086
  /**
1921
2087
  * Project a package manifest's text to its own name.
@@ -2112,6 +2278,9 @@ export declare class Compiler implements CompilerInterface {
2112
2278
  */
2113
2279
  export declare const MAX_REGISTRY_BYTES = 33554432;
2114
2280
 
2281
+ /** Maximum length of one manifest script name or command. */
2282
+ export declare const MAX_SCRIPT_LENGTH = 4096;
2283
+
2115
2284
  /** Maximum bytes retained across one whole plan or audit. */
2116
2285
  export declare const MAX_TOTAL_ARTIFACT_BYTES = 104857600;
2117
2286
 
@@ -2151,7 +2320,7 @@ export declare class Compiler implements CompilerInterface {
2151
2320
  } | {
2152
2321
  readonly name: string;
2153
2322
  readonly path: string;
2154
- readonly lookup: 'missing' | 'failed';
2323
+ readonly lookup: 'missing' | 'unmatched' | 'failed';
2155
2324
  readonly note: string;
2156
2325
  readonly observed?: string;
2157
2326
  readonly content?: never;
@@ -2451,7 +2620,9 @@ export declare class Compiler implements CompilerInterface {
2451
2620
  *
2452
2621
  * @remarks
2453
2622
  * `hash` is the plan's content identity and is absent until the pin stage
2454
- * fills it.
2623
+ * fills it. An artifact at `package.json` carries `birth` ownership because the
2624
+ * compiler emits the manifest that way. A plan claiming another ownership at
2625
+ * that path contradicts the compiler and is outside this contract.
2455
2626
  */
2456
2627
  export declare interface Plan {
2457
2628
  readonly blueprint: Blueprint;
@@ -2588,44 +2759,94 @@ export declare class Compiler implements CompilerInterface {
2588
2759
  } | {
2589
2760
  readonly name: string;
2590
2761
  readonly range: string;
2591
- readonly lookup: 'missing' | 'failed';
2762
+ readonly lookup: 'missing' | 'unmatched' | 'failed';
2592
2763
  readonly note: string;
2593
2764
  readonly major?: number;
2594
2765
  readonly latest?: never;
2595
2766
  };
2596
2767
 
2768
+ /**
2769
+ * The `prepublishOnly` row that runs the packed-package proof against a real registry.
2770
+ *
2771
+ * @remarks
2772
+ * The proof reads `import.meta.env.MODE`, so without `--mode release` it passes
2773
+ * on an unreachable registry instead of failing. The row therefore has one home
2774
+ * and both the script compiler and the manifest region writer read it from here.
2775
+ */
2776
+ export declare const RELEASE_PROOF_COMMAND = "npm run test:distribution -- --mode release";
2777
+
2597
2778
  /**
2598
2779
  * Replace declared dependency ranges in package manifest text.
2599
2780
  *
2600
2781
  * @param manifest - The manifest text to compile.
2601
- * @param dependencies - The declared names and replacement ranges.
2602
- * @returns The manifest with every matching dependency-section value replaced,
2603
- * or `undefined` when any name has no quoted declaration in those sections.
2782
+ * @param pins - The runtime and development names and replacement ranges.
2783
+ * @returns The manifest with every matching writable value replaced, or
2784
+ * `undefined` when a name has no quoted declaration in its named section.
2604
2785
  *
2605
2786
  * @remarks
2606
2787
  * The compiler replaces values in place instead of serializing the manifest,
2607
2788
  * so description, keywords, scripts, key order, indentation, and every byte
2608
- * outside the named ranges survive. Every occurrence in `dependencies`,
2609
- * `devDependencies`, and `peerDependencies` moves, which keeps duplicate
2610
- * declarations aligned until the manifest's own validation reports the
2611
- * duplicate. An override or resolution with the same name stays untouched.
2789
+ * outside the named ranges survive. Runtime pins apply only to `dependencies`,
2790
+ * and development pins apply only to `devDependencies`. The compiler never
2791
+ * reads or writes `peerDependencies` or `peerDependenciesMeta`. An override or
2792
+ * resolution with the same name stays untouched.
2612
2793
  *
2613
2794
  * @example
2614
2795
  * ```ts
2615
2796
  * import { replaceManifestRanges } from '@orkestrel/scaffold'
2616
2797
  *
2617
2798
  * const manifest = '{"devDependencies":{"typescript":"^6"}}\n'
2618
- * replaceManifestRanges(manifest, [{ name: 'typescript', range: '^7' }])
2799
+ * replaceManifestRanges(manifest, {
2800
+ * runtime: [],
2801
+ * development: [{ name: 'typescript', range: '^7' }],
2802
+ * })
2619
2803
  * // the manifest with the declared range replaced
2620
2804
  * ```
2621
2805
  */
2622
- export declare function replaceManifestRanges(manifest: string, dependencies: readonly Dependency[]): string | undefined;
2806
+ export declare function replaceManifestRanges(manifest: string, pins: DependencyPinSet): string | undefined;
2807
+
2808
+ /**
2809
+ * Replace named script values in package manifest text.
2810
+ *
2811
+ * @param manifest - The manifest text to compile.
2812
+ * @param scripts - The scripts to write, each with the predecessors it accepts.
2813
+ * @returns The manifest carrying every named script, or `undefined` when a
2814
+ * named script holds a value outside what it accepts, or when the text carries
2815
+ * no readable `scripts` object to write into.
2816
+ *
2817
+ * @remarks
2818
+ * The compiler replaces values in place instead of serializing the manifest, so
2819
+ * description, keywords, dependencies, key order, indentation, and every byte
2820
+ * outside the replaced ranges survive. A named script the manifest already
2821
+ * declares is overwritten only when its value is the one being written or one
2822
+ * of its {@link ManifestScript.accepted} predecessors; anything else is a chain
2823
+ * the workspace author customized, and the whole region is refused without a
2824
+ * byte moving. A named script the manifest does not declare is appended after
2825
+ * the last declared script, copying that section's indentation. A region
2826
+ * declaring nothing takes every named script as its first entries, indented
2827
+ * from the line its own opening brace sits on.
2828
+ *
2829
+ * The refusal is whole rather than per script, so a manifest never ends up
2830
+ * holding one written script beside one refused one.
2831
+ *
2832
+ * @example
2833
+ * ```ts
2834
+ * import { replaceManifestScripts } from '@orkestrel/scaffold'
2835
+ *
2836
+ * const manifest = '{\n\t"scripts": {\n\t\t"test": "vitest run"\n\t}\n}\n'
2837
+ * replaceManifestScripts(manifest, [
2838
+ * { name: 'test', command: 'vitest run --no-cache', accepted: ['vitest run'] },
2839
+ * ])
2840
+ * // the manifest with the declared script replaced
2841
+ * ```
2842
+ */
2843
+ export declare function replaceManifestScripts(manifest: string, scripts: readonly ManifestScript[]): string | undefined;
2623
2844
 
2624
2845
  /**
2625
2846
  * Replace dependency ranges in a plan's manifest and recompute its identity.
2626
2847
  *
2627
2848
  * @param plan - The plan carrying the manifest artifact to compile.
2628
- * @param dependencies - The declared names and replacement ranges.
2849
+ * @param pins - The runtime and development names and replacement ranges.
2629
2850
  * @returns A plan with replaced manifest ranges and a matching hash, or
2630
2851
  * `undefined` when the manifest or its identity cannot be compiled.
2631
2852
  *
@@ -2639,10 +2860,10 @@ export declare class Compiler implements CompilerInterface {
2639
2860
  * ```ts
2640
2861
  * import { replacePlanRanges } from '@orkestrel/scaffold'
2641
2862
  *
2642
- * replacePlanRanges(plan, releases) // the plan carrying the resolved manifest ranges
2863
+ * replacePlanRanges(plan, pins) // the plan carrying the resolved writable ranges
2643
2864
  * ```
2644
2865
  */
2645
- export declare function replacePlanRanges(plan: Plan, dependencies: readonly Dependency[]): Plan | undefined;
2866
+ export declare function replacePlanRanges(plan: Plan, pins: DependencyPinSet): Plan | undefined;
2646
2867
 
2647
2868
  /**
2648
2869
  * The one error this package throws, carrying the coded reason it was raised.