* docs: add npm managed python runtime design * build: add bundled python runtime wheel builder * build: make local embedding dependencies optional * build: bundle python runtime wheel in cli artifacts * build: track bundled python runtime release artifact * test: verify bundled python runtime wheel * docs: add plan for bundled python runtime wheel * test: cover managed python runtime lifecycle * feat: add managed python runtime installer * feat: add runtime command runner * feat: expose runtime management commands * test: verify managed python runtime commands * docs: add plan for managed python runtime installer * feat: add managed python command helper * feat: use managed runtime for sl query compute * feat: route sl query managed runtime policy * docs: add plan for managed runtime sl query integration * feat: add managed runtime daemon metadata * feat: manage python daemon lifecycle * feat: add runtime daemon start stop commands * fix: verify managed runtime daemon lifecycle * docs: add plan for managed runtime daemon lifecycle * feat: add managed local embeddings config marker * feat: add managed local embeddings daemon helper * feat: use managed runtime for local embedding setup * feat: pass managed runtime policy through setup * docs: add plan for managed local embeddings runtime * feat: read CLI package metadata dynamically * feat: assemble public kaelio ktx npm package * feat: release one public kaelio ktx npm artifact * test: cover public kaelio ktx package invocations * chore: verify public kaelio ktx package artifacts * docs: add plan for public kaelio ktx npm package * test: verify managed runtime in public package smoke * test: finalize managed runtime release smoke * docs: add plan for managed runtime release smoke * test: specify local embeddings release smoke * feat: add local embeddings runtime smoke * chore: register local embeddings smoke * fix: verify local embeddings smoke * fix: restore artifact smoke python env helper * docs: add plan for managed local embeddings release smoke * refactor: share managed runtime install policy parsing * feat: use managed runtime for agent semantic queries * feat: use managed runtime for MCP semantic compute * docs: add plan for managed agent and MCP semantic runtime * feat(cli): add managed daemon HTTP helpers * feat(cli): route local adapters through managed daemon * feat(cli): use managed daemon for ingest helpers * feat(cli): pass managed daemon options to scan * feat(context): pass MCP ingest pull config options * feat(cli): pass managed daemon options to serve ingest * test: verify managed local ingest daemon runtime * docs: add plan for managed local ingest daemon runtime * docs: align managed runtime examples * docs: add plan for managed runtime docs cleanup * test: cover published package runtime smoke commands * test: validate published package smoke outputs * docs: add plan for published package runtime smoke * build: stamp public npm package version * release: add npm public release policy * release: add guarded npm publish script * release: document public npm release handoff * docs: add plan for public npm release handoff * test: cover managed runtime prune in package smoke * docs: document managed runtime prune * docs: add plan for managed runtime prune smoke and docs * chore: encode uv runtime prerequisite policy * fix: clarify missing uv runtime error * docs: document uv runtime prerequisite * docs: add plan for uv runtime prerequisite contract * refactor: limit release artifacts to public package runtime * chore: align release policy with bundled runtime wheel * docs: describe single public runtime artifact surface * test: verify single public runtime artifact contract * docs: add plan for single public runtime artifact cleanup * fix: align local embeddings smoke with public version * docs: add plan for local embeddings smoke public version * release: soft-launch as @kaelio/ktx@0.1.0-rc.0 on next tag Publish target moves to the pre-release version 0.1.0-rc.0 under the next dist-tag so npm install @kaelio/ktx (which resolves to latest) does not pick up the soft-launch build. Users opt in via @kaelio/ktx@next. * Fix release script boundary checks * Remove PostHog from public package bundle
21 KiB
Managed Runtime uv Prerequisite Contract Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Close the remaining npm-managed Python runtime open decision by
making uv a documented, release-policy-checked prerequisite.
Architecture: Keep the runtime installer behavior simple: the CLI locates
uv on PATH and prints a focused error when it is missing. Encode that
decision in release-policy.json, validate it during release readiness, use one
shared runtime error message, and document the prerequisite in public docs.
Tech Stack: Node 22 ESM scripts, node:test, TypeScript, Vitest, JSON
release policy, Markdown.
Existing status
This plan is based on
docs/superpowers/specs/2026-05-11-npm-managed-python-runtime-design.md.
The following plan files are based on that spec and are already implemented in this worktree:
docs/superpowers/plans/2026-05-11-bundled-python-runtime-wheel.mddocs/superpowers/plans/2026-05-11-managed-python-runtime-installer.mddocs/superpowers/plans/2026-05-11-managed-python-runtime-command-integration.mddocs/superpowers/plans/2026-05-11-managed-python-runtime-daemon-lifecycle.mddocs/superpowers/plans/2026-05-11-managed-local-embeddings-runtime.mddocs/superpowers/plans/2026-05-11-public-kaelio-ktx-npm-package.mddocs/superpowers/plans/2026-05-11-managed-python-runtime-release-smoke.mddocs/superpowers/plans/2026-05-11-managed-local-embeddings-release-smoke.mddocs/superpowers/plans/2026-05-11-managed-agent-mcp-semantic-runtime.mddocs/superpowers/plans/2026-05-11-managed-local-ingest-daemon-runtime.mddocs/superpowers/plans/2026-05-11-managed-runtime-docs-and-postgres-smoke-cleanup.mddocs/superpowers/plans/2026-05-11-published-package-managed-runtime-smoke.mddocs/superpowers/plans/2026-05-11-public-npm-release-handoff.mddocs/superpowers/plans/2026-05-11-managed-runtime-prune-smoke-and-docs.md
Implementation evidence found before writing this plan includes:
packages/cli/assets/python/manifest.jsonand the bundledkaelio_ktx-0.1.0-py3-none-any.whl.packages/cli/src/managed-python-runtime.ts, including runtime roots, bundled wheel verification, install, status, doctor, and prune behavior.packages/cli/src/managed-python-command.ts,packages/cli/src/managed-python-daemon.ts,packages/cli/src/managed-local-embeddings.ts, andpackages/cli/src/managed-python-http.ts.scripts/build-public-npm-package.mjs,scripts/package-artifacts.mjs,scripts/published-package-smoke.mjs,scripts/local-embeddings-runtime-smoke.mjs, andscripts/publish-public-npm-package.mjs.release-policy.jsonis already innpm-public-release-readymode for@kaelio/ktx0.1.0and keeps Python package publishing disabled.README.mdandexamples/package-artifacts/README.mddocument the managed runtime command family, includingruntime prune.
The remaining spec gap is the open decision in
docs/superpowers/specs/2026-05-11-npm-managed-python-runtime-design.md:
KTX still needs a final decision on whether uv is a hard prerequisite or a
bootstrap dependency that KTX downloads automatically.
This plan chooses the hard-prerequisite path for the first public release. KTX
will not download uv automatically in this release.
File structure
- Modify
release-policy.json: add aruntimeInstallerpolicy section that records the harduvprerequisite decision. - Modify
scripts/release-readiness.mjs: validate the runtime installer policy, include it in readiness reports, and print it in text output. - Modify
scripts/release-readiness.test.mjs: cover the accepted policy and rejection paths for missing or bootstrap-styleuvpolicies. - Modify
packages/cli/src/managed-python-runtime.ts: export one shared missing-uvmessage and use it for install and doctor output. - Modify
packages/cli/src/managed-python-runtime.test.ts: cover install and doctor behavior whenuvis missing. - Modify
scripts/examples-docs.test.mjs: require public docs to state the harduvprerequisite. - Modify
README.md: document thatuvmust be onPATHand KTX does not download it automatically. - Modify
examples/package-artifacts/README.md: document the artifact smokeuvprerequisite.
Task 1: Encode the runtime installer policy
Files:
-
Modify:
release-policy.json -
Modify:
scripts/release-readiness.test.mjs -
Modify:
scripts/release-readiness.mjs -
Test:
scripts/release-readiness.test.mjs -
Step 1: Add failing release policy tests
In scripts/release-readiness.test.mjs, inside the releasePolicy() helper
return value, add the runtimeInstaller object immediately after
publishedPackageSmoke:
runtimeInstaller: {
uvStrategy: 'path-prerequisite',
bootstrapUv: false,
missingUvBehavior: 'focused-error',
},
In the three assert.deepEqual(report, { ... }) expectations, add this field
immediately after publishedPackageSmokeGate:
runtimeInstaller: {
uvStrategy: 'path-prerequisite',
bootstrapUv: false,
missingUvBehavior: 'focused-error',
},
Add these tests immediately after the
it('accepts the npm public release ready policy', async () => { ... }) block:
it('rejects npm public release ready mode without a runtime installer policy', async () => {
const root = await mkdtemp(join(tmpdir(), 'ktx-runtime-policy-missing-test-'));
try {
await writeReadyFixture(root, {
policy: releasePolicy({
releaseMode: 'npm-public-release-ready',
npm: {
publish: true,
registry: null,
access: 'public',
tag: 'latest',
},
publishedPackageSmoke: {
packageName: '@kaelio/ktx',
version: PUBLIC_NPM_PACKAGE_VERSION,
registry: null,
},
runtimeInstaller: undefined,
requiredBeforePublishing: [],
}),
});
await assert.rejects(
() => releaseReadinessReport(root),
/Release policy runtimeInstaller must be a JSON object/,
);
} finally {
await rm(root, { recursive: true, force: true });
}
});
it('rejects uv bootstrap download policy for the first public npm release', async () => {
const root = await mkdtemp(join(tmpdir(), 'ktx-runtime-policy-bootstrap-test-'));
try {
await writeReadyFixture(root, {
policy: releasePolicy({
releaseMode: 'npm-public-release-ready',
npm: {
publish: true,
registry: null,
access: 'public',
tag: 'latest',
},
publishedPackageSmoke: {
packageName: '@kaelio/ktx',
version: PUBLIC_NPM_PACKAGE_VERSION,
registry: null,
},
runtimeInstaller: {
uvStrategy: 'bootstrap-download',
bootstrapUv: true,
missingUvBehavior: 'download',
},
requiredBeforePublishing: [],
}),
});
await assert.rejects(
() => releaseReadinessReport(root),
/Release policy runtimeInstaller\.uvStrategy must be path-prerequisite/,
);
} finally {
await rm(root, { recursive: true, force: true });
}
});
- Step 2: Run the release readiness tests and verify failure
Run:
node --test scripts/release-readiness.test.mjs
Expected: FAIL because releaseReadinessReport() does not include
runtimeInstaller, and validateReleasePolicy() does not validate the new
policy section.
- Step 3: Validate the runtime installer policy
In scripts/release-readiness.mjs, add this function immediately after the
assertRequiredBeforePublishing(policy) function definition:
function assertRuntimeInstallerPolicy(policy) {
assertPlainObject(policy.runtimeInstaller, 'Release policy runtimeInstaller');
assertString(policy.runtimeInstaller.uvStrategy, 'Release policy runtimeInstaller.uvStrategy');
assertBoolean(policy.runtimeInstaller.bootstrapUv, 'Release policy runtimeInstaller.bootstrapUv');
assertString(
policy.runtimeInstaller.missingUvBehavior,
'Release policy runtimeInstaller.missingUvBehavior',
);
if (policy.runtimeInstaller.uvStrategy !== 'path-prerequisite') {
throw new Error('Release policy runtimeInstaller.uvStrategy must be path-prerequisite');
}
if (policy.runtimeInstaller.bootstrapUv !== false) {
throw new Error('Release policy runtimeInstaller.bootstrapUv must be false');
}
if (policy.runtimeInstaller.missingUvBehavior !== 'focused-error') {
throw new Error('Release policy runtimeInstaller.missingUvBehavior must be focused-error');
}
}
In validateReleasePolicy(policy), add this call immediately after
assertRequiredBeforePublishing(policy);:
assertRuntimeInstallerPolicy(policy);
In releaseReadinessReport(rootDir = scriptRootDir()), add
runtimeInstaller to the returned object immediately after
publishedPackageSmokeGate:
runtimeInstaller: policy.runtimeInstaller,
In main(), add these lines immediately after the published package smoke
registry line:
process.stdout.write(`Runtime uv strategy: ${report.runtimeInstaller.uvStrategy}\n`);
process.stdout.write(
`Runtime uv bootstrap: ${report.runtimeInstaller.bootstrapUv ? 'enabled' : 'disabled'}\n`,
);
- Step 4: Encode the policy in
release-policy.json
Replace release-policy.json with this exact content:
{
"schemaVersion": 1,
"releaseMode": "npm-public-release-ready",
"npm": {
"publish": true,
"registry": null,
"access": "public",
"tag": "latest",
"packages": ["@kaelio/ktx"]
},
"python": {
"publish": false,
"repository": null,
"packages": ["ktx-sl", "ktx-daemon", "kaelio-ktx"]
},
"publishedPackageSmoke": {
"packageName": "@kaelio/ktx",
"version": "0.1.0",
"registry": null
},
"runtimeInstaller": {
"uvStrategy": "path-prerequisite",
"bootstrapUv": false,
"missingUvBehavior": "focused-error"
},
"requiredBeforePublishing": []
}
- Step 5: Run the release readiness tests and verify success
Run:
node --test scripts/release-readiness.test.mjs
Expected: PASS.
- Step 6: Commit the release policy contract
git add release-policy.json scripts/release-readiness.mjs scripts/release-readiness.test.mjs
git commit -m "chore: encode uv runtime prerequisite policy"
Task 2: Centralize missing-uv runtime output
Files:
-
Modify:
packages/cli/src/managed-python-runtime.test.ts -
Modify:
packages/cli/src/managed-python-runtime.ts -
Test:
packages/cli/src/managed-python-runtime.test.ts -
Step 1: Add failing missing-uv runtime tests
In packages/cli/src/managed-python-runtime.test.ts, add
MISSING_UV_RUNTIME_INSTALL_MESSAGE to the import from
./managed-python-runtime.js:
import {
MISSING_UV_RUNTIME_INSTALL_MESSAGE,
doctorManagedPythonRuntime,
installManagedPythonRuntime,
managedPythonRuntimeLayout,
pruneManagedPythonRuntimes,
readManagedPythonRuntimeStatus,
verifyRuntimeAsset,
type ManagedPythonRuntimeExec,
} from './managed-python-runtime.js';
Inside describe('installManagedPythonRuntime', () => { ... }), add this test
after the local embeddings test:
it('fails with the hard-prerequisite message when uv is missing', async () => {
const { assetDir } = await writeAsset(tempDir, 'core-wheel');
const commands: Array<{ command: string; args: string[] }> = [];
const exec: ManagedPythonRuntimeExec = vi.fn(async (command, args) => {
commands.push({ command, args });
throw new Error('spawn uv ENOENT');
});
await expect(
installManagedPythonRuntime({
cliVersion: '0.2.0',
runtimeRoot: join(tempDir, 'runtime'),
assetDir,
features: ['core'],
exec,
}),
).rejects.toThrow(MISSING_UV_RUNTIME_INSTALL_MESSAGE);
expect(commands).toEqual([{ command: 'uv', args: ['--version'] }]);
});
Inside describe('doctorManagedPythonRuntime', () => { ... }), add this test
after the existing doctor test:
it('reports uv as a hard prerequisite when uv is missing', async () => {
const { assetDir } = await writeAsset(tempDir, 'core-wheel');
const exec: ManagedPythonRuntimeExec = vi.fn(async () => {
throw new Error('spawn uv ENOENT');
});
const checks = await doctorManagedPythonRuntime({
cliVersion: '0.2.0',
runtimeRoot: join(tempDir, 'runtime'),
assetDir,
exec,
});
expect(checks[0]).toEqual({
id: 'uv',
label: 'uv',
status: 'fail',
detail: MISSING_UV_RUNTIME_INSTALL_MESSAGE,
fix: 'Install uv, make sure it is on PATH, and run: ktx runtime install --yes',
});
});
- Step 2: Run the runtime tests and verify failure
Run:
pnpm --filter @ktx/cli run test -- src/managed-python-runtime.test.ts
Expected: FAIL because the shared message constant does not exist and the doctor fix text still uses the older message.
- Step 3: Add the shared missing-uv message
In packages/cli/src/managed-python-runtime.ts, add this export immediately
after the ManagedPythonRuntimePruneResult interface:
export const MISSING_UV_RUNTIME_INSTALL_MESSAGE =
'uv is required to install the KTX Python runtime. KTX does not download uv automatically. Install uv, make sure it is on PATH, and retry: ktx runtime install --yes';
Replace the body of the catch block in ensureUv() with:
throw new Error(MISSING_UV_RUNTIME_INSTALL_MESSAGE);
In doctorManagedPythonRuntime(), replace the fix value for the uv check
with:
fix: 'Install uv, make sure it is on PATH, and run: ktx runtime install --yes',
- Step 4: Run the runtime tests and verify success
Run:
pnpm --filter @ktx/cli run test -- src/managed-python-runtime.test.ts
Expected: PASS.
- Step 5: Commit the runtime output contract
git add packages/cli/src/managed-python-runtime.ts packages/cli/src/managed-python-runtime.test.ts
git commit -m "fix: clarify missing uv runtime error"
Task 3: Document the hard uv prerequisite
Files:
-
Modify:
scripts/examples-docs.test.mjs -
Modify:
README.md -
Modify:
examples/package-artifacts/README.md -
Test:
scripts/examples-docs.test.mjs -
Step 1: Add failing docs assertions
In scripts/examples-docs.test.mjs, inside
it('documents public npm and managed runtime usage in the README', ... ), add
these assertions immediately after the existing ktx runtime prune --yes
assertion:
assert.match(rootReadme, /KTX requires `uv` on `PATH`/);
assert.match(rootReadme, /KTX doesn't download `uv` automatically/);
Inside it('documents the public package artifact smoke shape', ... ), add
this assertion immediately after the managed Python runtime assertion:
assert.match(readme, /requires `uv` on `PATH`/);
- Step 2: Run the docs test and verify failure
Run:
node --test scripts/examples-docs.test.mjs
Expected: FAIL because the README files do not state the hard uv
prerequisite.
- Step 3: Update the root README runtime section
In README.md, in the ## Managed Python runtime section, replace this
paragraph:
KTX installs its Python runtime only when a Python-backed command needs it.
The runtime lives outside the npm cache, is versioned by the installed CLI
version, and is managed by `ktx runtime` commands:
With:
KTX installs its Python runtime only when a Python-backed command needs it.
The runtime lives outside the npm cache, is versioned by the installed CLI
version, and is managed by `ktx runtime` commands.
KTX requires `uv` on `PATH` to create the managed runtime. Install `uv` with
your system package manager or the official installer before running Python-
backed KTX commands. KTX doesn't download `uv` automatically; run
`ktx runtime doctor` if runtime installation fails:
- Step 4: Update the package artifact smoke README
In examples/package-artifacts/README.md, replace this paragraph:
The managed Python runtime smoke isolates `KTX_RUNTIME_ROOT`, verifies
`ktx runtime status`, runs `ktx sl query --yes` to install the core runtime from
the bundled wheel, checks `ktx runtime doctor`, starts and reuses the managed
daemon, stops it, previews a stale runtime with `ktx runtime prune --dry-run`,
verifies confirmation is required, and removes the stale runtime with
`ktx runtime prune --yes`.
With:
The managed Python runtime smoke requires `uv` on `PATH`, isolates
`KTX_RUNTIME_ROOT`, verifies `ktx runtime status`, runs `ktx sl query --yes` to
install the core runtime from the bundled wheel, checks `ktx runtime doctor`,
starts and reuses the managed daemon, stops it, previews a stale runtime with
`ktx runtime prune --dry-run`, verifies confirmation is required, and removes
the stale runtime with `ktx runtime prune --yes`.
- Step 5: Run the docs test and verify success
Run:
node --test scripts/examples-docs.test.mjs
Expected: PASS.
- Step 6: Commit the public docs update
git add README.md examples/package-artifacts/README.md scripts/examples-docs.test.mjs
git commit -m "docs: document uv runtime prerequisite"
Task 4: Verify the completed contract
Files:
-
Verify:
release-policy.json -
Verify:
scripts/release-readiness.mjs -
Verify:
scripts/release-readiness.test.mjs -
Verify:
packages/cli/src/managed-python-runtime.ts -
Verify:
packages/cli/src/managed-python-runtime.test.ts -
Verify:
scripts/examples-docs.test.mjs -
Verify:
README.md -
Verify:
examples/package-artifacts/README.md -
Step 1: Run focused verification
Run:
node --test scripts/release-readiness.test.mjs scripts/examples-docs.test.mjs
pnpm --filter @ktx/cli run test -- src/managed-python-runtime.test.ts
Expected: PASS.
- Step 2: Verify release readiness text output
Run:
pnpm run release:readiness
Expected output includes:
KTX release mode: npm-public-release-ready
Runtime uv strategy: path-prerequisite
Runtime uv bootstrap: disabled
NPM publish target: @kaelio/ktx@0.1.0 (latest)
- Step 3: Verify no pre-commit config is required
Run:
rg --files -g '.pre-commit-config.yaml' -g 'pre-commit-config.yaml'
Expected: no output and exit code 1. No Python files changed, so the repository Python pre-commit requirement does not apply.
- Step 4: Review the final diff
Run:
git diff --stat
git diff -- release-policy.json scripts/release-readiness.mjs scripts/release-readiness.test.mjs packages/cli/src/managed-python-runtime.ts packages/cli/src/managed-python-runtime.test.ts scripts/examples-docs.test.mjs README.md examples/package-artifacts/README.md
Expected: only the runtime installer policy, missing-uv message/tests, and
public docs changed.
- Step 5: Commit final verification notes if needed
If Task 4 produces only verification output and no file changes, skip this step. If a correction was made during verification, commit it:
git add release-policy.json scripts/release-readiness.mjs scripts/release-readiness.test.mjs packages/cli/src/managed-python-runtime.ts packages/cli/src/managed-python-runtime.test.ts scripts/examples-docs.test.mjs README.md examples/package-artifacts/README.md
git commit -m "chore: finish uv prerequisite release contract"
Self-review
Spec coverage:
- The earlier implemented plans cover the single public npm package, bundled Python wheel, managed runtime installer, runtime commands, daemon lifecycle, local embeddings, Python-backed command integration, release smoke, published smoke, docs cleanup, release handoff, and prune coverage.
- This plan closes the spec's remaining
uvopen decision by choosingpath-prerequisite, recording that decision in release policy, validating it in release readiness, using one CLI error message, and documenting it. - The plan keeps Python package publication disabled and keeps KTX-owned Python code bundled in the npm package.
Placeholder scan:
- No task contains deferred implementation markers.
- Each code-changing step names exact files and includes the concrete code to add or replace.
Type consistency:
- The release policy field is consistently named
runtimeInstaller. - The chosen strategy is consistently
path-prerequisite. - The shared CLI message constant is consistently
MISSING_UV_RUNTIME_INSTALL_MESSAGE.