From 8d2ef7df9ff22580f81e19301e5f735442ea6be0 Mon Sep 17 00:00:00 2001 From: mm Date: Mon, 5 Oct 2026 22:12:19 -0400 Subject: [PATCH 1/2] Clarify published startup and isolated tool configuration --- cli/bun/README.md | 72 ++++++++++++++++------------ cli/protocol/OWNERSHIP.md | 8 ++++ cli/rust/README.md | 58 ++++++++++++++--------- cli/shared/image/bundle/README.md | 30 +++++++++++- docs/kernel-startup.md | 78 ++++++++++++++++++++++++++++++- 5 files changed, 191 insertions(+), 55 deletions(-) diff --git a/cli/bun/README.md b/cli/bun/README.md index 49095adc..bda19036 100644 --- a/cli/bun/README.md +++ b/cli/bun/README.md @@ -16,44 +16,52 @@ Markdown remain owned by the separate language/image layer. `--output-contract native` accepts the actual native harness terminal and preserves final prose without requiring a model-authored JSON envelope. Semantic status is `not-applicable`: validate program artifacts independently. -`image-envelope` remains the default and requires the image-declared terminal -envelope in addition to native completion. `--output human|json|jsonl` controls +Ordinary published-kernel builds default to `native`; explicit image and test +builds default to `image-envelope`, which additionally requires the image-declared +terminal envelope. `--output human|json|jsonl` controls rendering separately. See [native output](../../docs/native-output.md) and [private native capture](../../docs/native-capture.md). -A build without image overrides still embeds the nonsemantic `echo-v0` image. -That is a packaging default, not a limit on the runner: production-shaped -builds can instead embed a verified language-owned image or minimal entry -pointer using the documented [image bundle configuration](../shared/image/bundle/README.md). -The configured image supplies instructions; choosing native output does not -replace an echo image with a language interpreter. No CLI source changes are -needed to swap image data. Native completion alone is not a release or -language-conformance claim. +A build without image overrides resolves and verifies the published kernel +when preparing a run through an installed harness. It also embeds `echo-v0` +for local diagnostics; that fixture is not a startup fallback. Help, version +and harness inventory do not retrieve the kernel. See +[kernel startup](../../docs/kernel-startup.md) for the acquisition policy and +[image bundle configuration](../shared/image/bundle/README.md) for fixed inputs. +Native completion alone does not establish contract fulfillment or language +conformance. ## Local development ```sh +cd cli/bun bun install --frozen-lockfile bun run check ./dist/prose --help ./dist/prose cli harness list -./dist/prose --harness codex --output json run fixture.prose.md +./dist/prose --harness codex --dry-run --output json run fixture.prose.md ``` +Start these commands at the repository root. The final command requires an +installed supported Codex and may retrieve the public kernel, but makes no +model call. Its readiness report is not proof of authentication or fulfillment. + `bun run check` performs strict TypeScript checking, unit/integration/shared- -schema tests, standalone compilation, and standalone smoke tests. The compile +schema tests and ordinary standalone compilation. Standalone smoke assertions +are exercised by the test suite. The compile command disables Bun's runtime `.env`, `bunfig.toml`, `tsconfig.json`, and `package.json` autoloading. A test places hostile `.env` and `bunfig.toml` files in the invoked working directory and proves that the standalone ignores them. -`bun run build` is the ordinary local build, matching Rust's default: it embeds -`echo-v0`, reports the `development` profile, and compiles with test seams off. +`bun run build` is the ordinary local build, matching Rust's default: it enables +published-kernel startup, reports the `development` profile, and compiles with test seams off. It writes `dist/prose`. `bun run build:test` is the explicit test-only build; it creates a private temporary `sentinel-v1` bundle, enables test seams, writes `dist/prose-test` by default, and removes the temporary bundle. The test-only -command refuses to overwrite `dist/prose`. `bun run build:release` embeds the -release-eligible `echo-v0` image with test seams off. +command refuses to overwrite `dist/prose`. `bun run build:release` reports the +release profile with published startup and test seams off. Its structural check +of the embedded diagnostic image does not qualify the kernel or authorize a release. ### Developer endpoint build (OpenProse developers only) @@ -71,11 +79,10 @@ the default `dist/prose` outfile. Public builds define the switch as false, so Bun removes the override code (`src/core/service/dev-endpoint.ts`) and the variable name from the binary; `test/dev-endpoint.test.ts` checks both builds. -Builds without image overrides embed the deliberately nonsemantic `echo-v0` image. They can -discover and run exactly admitted user-installed Prime, OMP, Codex, Claude, and Agents SDK +Ordinary builds can discover and run supported user-installed Prime, OMP, Codex, Claude, and Agents SDK harnesses through direct argument-array subprocesses. The adapters preserve the complete image/task boundary, use adapter-specific credential allowlists, -and, in the default output-contract mode, recover the image-owned terminal +and, when `image-envelope` is explicitly selected, recover the image-owned terminal envelope without a shell, outer PTY, or harness fallback. Codex and Claude can use their installed login state. Prime and OMP additionally require a fully qualified `provider/model` plus an @@ -104,9 +111,13 @@ native output, SDK support, image selection, and environment profiles. Functional-alpha admission is an exact audited allowlist: Prime `0.7.0` or `0.8.1`, OMP `18.0.9`, Codex `0.149.0-alpha.4.1`, Claude `2.1.243`, and the optional `prose-agents-sdk` harness `0.1.0` (currently macOS ARM64). -Nearby patches and prereleases are detected but refused, with the detected -identity, exact admitted set, and a copyable repair command in machine and -human doctor/run errors. The CLI build remains on its pinned Bun 1.3.5 +These are exact audited identities, not a claim of qualification for every +accepted version. Claude additionally permits stable versions at or above the +recipe minimum within its major version. Codex permits an explicit +`--codex-compatibility probe` attempt after required capabilities are observed; +the default `qualified` mode retains its exact qualified set. Other unknown +identities remain rejected with actionable diagnostics. See +[Codex compatibility](../../docs/codex-compatibility.md). The CLI build remains on its pinned Bun 1.3.5 toolchain; the separate upstream OMP package/source audit used Bun 1.3.14. Prime runs use one private per-run daemon socket. If its owned service cannot @@ -130,8 +141,8 @@ binary uses Bun's `baseline` runtime variant rather than the AVX2-oriented standard target; ARM64 binaries use their exact native target. Unsupported build hosts fail before producing a mislabeled artifact. -The exact same user journey is available in release-profile functional-alpha -builds. A completed `echo-v0` invocation proves transport completion only: it +Published startup also applies to ordinary release-profile builds. A completed +explicit `echo-v0` invocation proves transport completion only: it does not parse OpenProse, claim semantic success, or earn a strict-wrapper claim. The default `openprose` identity still fails closed with `HOSTED_UNAVAILABLE` until OpenProse-billed execution exists. @@ -139,7 +150,7 @@ claim. The default `openprose` identity still fails closed with The deterministic `mock` and `fake-process` transports remain test-only. They are admitted only by the explicit `bun run build:test` command, which carries the release-ineligible sentinel image and enables test seams. Without image overrides, ordinary -`bun run build` and release-profile builds carry `echo-v0` with test seams off +`bun run build` and release-profile builds use published startup with test seams off and refuse these transports before execution. Internal provider-free controls cannot be enabled in a release build and never become a harness, language, or billing fallback. @@ -162,8 +173,9 @@ successfully on native Windows and that evidence is retained. ## Packaging boundary -The default build produces `dist/prose`, a local Bun standalone carrying -`echo-v0`; explicit image arguments select a different verified bundle. Functional-alpha packaging creates platform-specific npm packages +The default build produces `dist/prose`, a local Bun standalone using published +startup with an embedded diagnostic fixture. Explicit image arguments disable +published acquisition and select the verified bundle. Packaging creates platform-specific npm packages and a small Node-compatible launcher in `@openprose/prose-cli`. Both products embed the same exact prerelease SemVer and source revision through `OPENPROSE_BUILD_VERSION` and `OPENPROSE_BUILD_COMMIT`. The launcher selects an @@ -172,9 +184,9 @@ and SHA-256, performs no download or postinstall work, forwards signals, and preserves the binary exit status. Isolated install, integrity, and foreground signal tests exercise the packed tarballs without a registry. -The functional alpha is explicitly transport-only. Its package evidence keeps -publication and full-release admission false; a semantic release remains -blocked on the canonical language-owned image and its external authorities. +Build and package checks establish mechanical transport and integrity facts. +Current publication gates and release evidence are maintained in the +[release guide](../release/README.md); none establish contract fulfillment. The Node interpreter used by installed-package conformance is deliberately not copied away from its dynamic libraries. Its resolved installed executable is diff --git a/cli/protocol/OWNERSHIP.md b/cli/protocol/OWNERSHIP.md index 031d4a5d..3ea443a1 100644 --- a/cli/protocol/OWNERSHIP.md +++ b/cli/protocol/OWNERSHIP.md @@ -777,3 +777,11 @@ IMP-086 lease extension: `cli/ci/test_rehearse_release.py` for exact current 64- IMP-086 lease extension: `cli/conformance/fixtures/adapter-host-expectations.json` and the existing leased host runner/tests for independently frozen inventory expectations across admitted POSIX hosts; keep all Codex blocked-state and full-inventory assertions. IMP-086 lease extension: `cli/ci/test_run_local.py` solely to make the interrupt-tree fixture reap its controlled descendant and publish readiness after signal-safe setup; supervisor behavior, 130/143 exits and PID-absence assertions remain unchanged. +## IMP-055 build documentation lane — October 5, 2026 + +Root authorized `/root/build_docs` on `codex/imp-055-build-docs` to edit exactly +`cli/bun/README.md`, `cli/rust/README.md`, `docs/kernel-startup.md`, and +`cli/shared/image/bundle/README.md`. Scope: published startup, fixed images, +diagnostic/test builds and explicit tool configuration; provider-free copied +example verification. No source, release documentation, model calls or new +Python. Root retains integration and publication ownership. diff --git a/cli/rust/README.md b/cli/rust/README.md index 0bba283d..ca62c97a 100644 --- a/cli/rust/README.md +++ b/cli/rust/README.md @@ -9,19 +9,20 @@ dependency on the repository's language or kernel packages. `--output-contract native` accepts the actual native harness terminal and preserves final prose without requiring a model-authored JSON envelope. Semantic status is `not-applicable`: validate program artifacts independently. -`image-envelope` remains the default and requires the image-declared terminal -envelope in addition to native completion. `--output human|json|jsonl` controls +Ordinary published-kernel builds default to `native`; explicit image and test +builds default to `image-envelope`, which additionally requires the image-declared +terminal envelope. `--output human|json|jsonl` controls rendering separately. See [native output](../../docs/native-output.md) and [private native capture](../../docs/native-capture.md). -A build without image overrides still embeds the nonsemantic `echo-v0` image. -That is a packaging default, not a limit on the runner: production-shaped -builds can instead embed a verified language-owned image or minimal entry -pointer using the documented [image bundle configuration](../shared/image/bundle/README.md). -The configured image supplies instructions; choosing native output does not -replace an echo image with a language interpreter. No CLI source changes are -needed to swap image data. Native completion alone is not a release or -language-conformance claim. +A build without image overrides resolves and verifies the published kernel +when preparing a run through an installed harness. It also embeds `echo-v0` +for local diagnostics; that fixture is not a startup fallback. Help, version +and harness inventory do not retrieve the kernel. See +[kernel startup](../../docs/kernel-startup.md) for the acquisition policy and +[image bundle configuration](../shared/image/bundle/README.md) for fixed inputs. +Native completion alone does not establish contract fulfillment or language +conformance. ## Local verification @@ -32,6 +33,10 @@ cargo clippy --workspace --all-targets --features prose-cli/test-seams --locked cargo fmt --all -- --check ``` +Start at the repository root. The remaining commands in this guide assume +`cli/rust` as the current directory. Use the pinned toolchain and install the +dependencies described in [contributing](../CONTRIBUTING.md) first. + Build and inspect an installed harness without starting a model run: ```sh @@ -40,6 +45,10 @@ cargo build --locked -p prose-cli ./target/debug/prose --harness codex --dry-run --output json run example.prose.md ``` +The dry run requires an installed supported Codex and may retrieve the public +kernel, but makes no model call. Readiness is not proof of authentication, +model availability or contract fulfillment. + The functional alpha can run installed `prime-agent`, `omp`, `codex`, and `claude` executables directly, plus the optional `prose-agents-sdk` harness, without a shell or outer PTY. Prime and OMP @@ -67,10 +76,13 @@ native output, SDK support, image selection, and environment profiles. Functional-alpha admission is an exact audited allowlist: Prime `0.7.0` or `0.8.1`, OMP `18.0.9`, Codex `0.149.0-alpha.4.1`, Claude `2.1.243`, and the optional `prose-agents-sdk` harness `0.1.0` (currently macOS ARM64). -Nearby patches and prereleases are detected but refused rather than admitted by -range extrapolation. Machine errors include the detected identity, exact -allowlist, and repair command; human doctor/run output prints the same copyable -repair command. +These are exact audited identities, not a claim of qualification for every +accepted version. Claude additionally permits stable versions at or above the +recipe minimum within its major version. Codex permits an explicit +`--codex-compatibility probe` attempt after required capabilities are observed; +the default `qualified` mode retains its exact qualified set. Other unknown +identities remain rejected with actionable diagnostics. See +[Codex compatibility](../../docs/codex-compatibility.md). Prime runs use one private per-run daemon socket. If its owned service cannot be settled, OpenProse recursively removes prompt, image, task, credential, and @@ -93,12 +105,11 @@ OpenProse-billed adapter exists, a language run fails with `HOSTED_UNAVAILABLE` and exit code 10. It never falls back to a third-party harness. -Builds without image overrides embed the release-eligible `echo-v0` Skill Runtime Image. It is -a functional-alpha placeholder: it asks the selected harness to echo the task -and produce a structurally verified terminal envelope, so successful runs have -semantic status `not-applicable`. It does not implement the OpenProse language. -Strict wrapper admission and a full semantic release still require the future -canonical, language-owned runtime image plus versioned real-harness evidence. +An explicit build selecting the committed `echo-v0` image exercises transport +only: the image asks the harness to echo the task and produce a terminal +envelope. It does not implement OpenProse. Ordinary builds instead acquire the +published kernel on run. Both routes leave artifact fulfillment to independent +assessment; see the [release guide](../release/README.md) for current release gates. An ordinary `cargo build` reports the development profile with test seams disabled. An ordinary `cargo build --release` reports the release profile with @@ -110,7 +121,7 @@ cargo build --locked -p prose-cli --features prose-cli/test-seams ``` The build rejects `--release` combined with `prose-cli/test-seams`. Release -workflows can set an exact validated prerelease version without editing Cargo +workflows can set an exact prerelease version without editing Cargo metadata: ```sh @@ -119,6 +130,11 @@ OPENPROSE_REQUIRE_RELEASE_IMAGE=1 \ cargo build --release --locked -p prose-cli ``` +This still selects published startup unless explicit image paths are supplied. +`OPENPROSE_REQUIRE_RELEASE_IMAGE=1` checks the embedded diagnostic image's +structural eligibility; it does not pin or qualify the remotely selected kernel +or authorize publication. + ## Developer endpoint build (OpenProse developers only) Public builds talk only to the production OpenProse service; the service diff --git a/cli/shared/image/bundle/README.md b/cli/shared/image/bundle/README.md index b989693e..b5980ee3 100644 --- a/cli/shared/image/bundle/README.md +++ b/cli/shared/image/bundle/README.md @@ -39,6 +39,30 @@ bun ../../../bun/scripts/image-bundle.ts build \ Neither path requires an adapter or runner source edit. The build first checks the source directory, exact staged bytes, and checksum; any drift fails closed. +Supply all three paths. This explicit selection disables published-kernel +acquisition and defaults to the image's terminal-envelope mode; select +`--output-contract native` explicitly when appropriate for the chosen image. +It pins the embedded instruction bytes, not the harness, model, toolchain, +dependencies or every other campaign input. + +To inspect the existing committed diagnostic bundle and build an offline, +fixed-image Bun executable from the repository root: + +```sh +bun cli/bun/scripts/image-bundle.ts check \ + --image-dir cli/shared/image/echo-v0 \ + --bundle cli/shared/image/embedded/current.bundle.bin \ + --checksum cli/shared/image/embedded/current.bundle.sha256 +bun cli/bun/scripts/image-bundle.ts build \ + --image-dir cli/shared/image/echo-v0 \ + --bundle cli/shared/image/embedded/current.bundle.bin \ + --checksum cli/shared/image/embedded/current.bundle.sha256 \ + --outfile cli/bun/dist/prose-echo +``` + +This selects the nonsemantic echo fixture, not OpenProse language execution. +The existing image staging/validation implementation still uses Python +internally; these commands do not introduce another implementation or dependency. The Rust runner's explicit provider-free test build is separate from the data-only replacement path: @@ -49,6 +73,8 @@ cargo build --manifest-path ../../../rust/Cargo.toml -p prose-cli \ ``` That development-only feature embeds `sentinel-v1` and enables the mock and -conformance seams. Ordinary development and release builds keep the committed -`echo-v0` image and report test seams as disabled. Combining `--release` with +conformance seams. Ordinary development and release builds without image +overrides acquire the verified published kernel for installed-harness runs; +they retain `echo-v0` only as a diagnostic fixture and keep test seams disabled. +See [published startup](../../../../docs/kernel-startup.md). Combining `--release` with the test-seams feature fails closed. diff --git a/docs/kernel-startup.md b/docs/kernel-startup.md index 5f483f24..3ce5150c 100644 --- a/docs/kernel-startup.md +++ b/docs/kernel-startup.md @@ -1,6 +1,9 @@ # Published kernel startup -Status: IMP-008 candidate, provider-free validation across Bun and Rust. Live provider/model checks and review remain outstanding. This does not qualify a release or establish model conformance. +Published startup is implemented in both Bun and Rust. The provider-free +startup checks described below establish acquisition and transport behavior; +they do not establish model conformance or contract fulfillment. See the +[release guide](../cli/release/README.md) for current distribution qualification. Ordinary compiled builds resolve `https://pkg.prose.md/kernel.md` before launching an installed harness. They accept only a redirect into the official origin's immutable `/releases//core/README.md` layout, fetch that release's descriptor and inventory, verify the inventory digest and kernel entry digest, and freeze the verified bytes for that invocation. They do not parse Markdown, install packages, create locks or implement Prose commands. @@ -35,12 +38,83 @@ Default harness selection is unchanged: an unconfigured hosted selection still r ## Fixed inputs and tests +| Build selection | Instructions used for an installed-harness run | Default output contract | Test seams | +| --- | --- | --- | --- | +| Ordinary development or release build | Verified published kernel acquired on run | `native` | Disabled | +| Explicit image directory, bundle and checksum | Verified embedded image | `image-envelope` | Disabled | +| Bun `build:test` or Rust `prose-cli/test-seams` | Embedded `sentinel-v1` transport fixture | `image-envelope` | Enabled; development only | + +Ordinary builds also embed `echo-v0` for diagnostics. Doctor describes that +fixture while `imageSource: published-on-run` identifies deferred startup; +neither means a failed kernel retrieval will execute the fixture. + Explicit image builds continue to consume a verified image directory, bundle and checksum; they do not contact the moving kernel entry. They preserve the image-envelope default unless the caller selects `--output-contract native`. Both ordinary compiled implementations append Codex instructions for explicit images too. Bun's earlier `--codex-instructions base|framed` remains an explicit-image experiment option; published startup rejects those modes. -Source-level test seams and dedicated test builds retain hermetic fixture behavior. They do not establish the ordinary compiled default; the shared compiled-process test separately checks Codex append delivery, task separation, model selection, child failure and timeout. Release-image qualification rejects moving published startup; select an explicitly qualified image for that gate. This candidate does not promote a published artifact. +Source-level test seams and dedicated test builds retain hermetic fixture behavior. They do not establish the ordinary compiled default; the shared compiled-process test separately checks Codex append delivery, task separation, model selection, child failure and timeout. The image eligibility check validates embedded image structure; it does not freeze a moving published kernel or establish language qualification. Current release policy and external authorities are recorded in the release guide. Runtime project-kernel lock selection is not implemented here. A fixed image build is the current deterministic pinning route. Initialization and package-lock semantics belong to the separately planned command interface. No company lock or installed dependency is changed by startup. +## Supplying tool configuration + +Installed adapters construct the child environment from a shared base allowlist +and the explicitly selected credential route. Arbitrary application variables +such as `MY_TOOL_PATH` are not forwarded. The CLI does not turn a custom +environment variable into an agent tool setting. Supply an ordinary configuration +file accessible from the selected working directory, and have the contract require +the agent to read it. A tool executable path, its arguments and its expected +digest can be explicit fields in that file; the executing agent remains +responsible for honoring those requirements. + +This provider-free POSIX example creates a deterministic tool and configuration +in a fresh directory, then independently checks the configured digest and output: + +```sh +tool_demo_root=$(mktemp -d) +cd "$tool_demo_root" +cat > tool.sh <<'EOF' +#!/bin/sh +printf '%s\n' 'tool-ready' +EOF +chmod 700 tool.sh +bun - <<'JS' +const executable = `${process.cwd()}/tool.sh`; +const hash = new Bun.CryptoHasher("sha256"); +hash.update(await Bun.file(executable).arrayBuffer()); +await Bun.write("tooling.json", JSON.stringify({ + executable, sha256: hash.digest("hex"), args: [], +}, null, 2)); +JS +bun - <<'JS' +const config = await Bun.file("tooling.json").json(); +const hash = new Bun.CryptoHasher("sha256"); +hash.update(await Bun.file(config.executable).arrayBuffer()); +if (hash.digest("hex") !== config.sha256) throw Error("Tool digest mismatch"); +const child = Bun.spawn([config.executable, ...config.args], { + env: {PATH: "/usr/bin:/bin"}, stdin: "ignore", stdout: "pipe", stderr: "inherit", +}); +const output = await new Response(child.stdout).text(); +if (await child.exited !== 0 || output !== "tool-ready\n") { + throw Error("Unexpected tool result"); +} +console.log(output.trim()); +JS +cat > check-tool.prose.md <<'EOF' +Read tooling.json from the supplied working directory. Verify the executable's +SHA-256 before invoking it with the supplied arguments. Report its observed +output. Do not infer tool configuration from ambient custom environment variables. +EOF +``` + +The last two Bun commands verify the fixture directly, without an agent or +model call. They do not prove the contract was executed. With a separately +authorized native run, pass `--cwd "$tool_demo_root"` and +`run check-tool.prose.md` to the exact chosen CLI, together with explicit harness, +model, authentication and native permissions. Use a fresh directory for each +attempt; retain observed tool effects and assess fulfillment independently. +This file supplies no permission grant, environment-forwarding extension or +filesystem isolation. Native permissions and filesystem access still have to +allow the configured path. Do not put credentials in the configuration. + ## Verification and limitations The two implementations use the same acquisition policy, image template and shared HTTP fixtures. Tests cover exact bytes and digests, origin/path rejection, malformed or modified metadata/content, size bounds, task separation and native argv limits. The selected release and content identity appear in ordinary image/result metadata. The public endpoint was also checked through dry runs of both compiled implementations, without a model. From 2880e190f64e4ef7a307c395a151ade05103419e Mon Sep 17 00:00:00 2001 From: mm Date: Mon, 5 Oct 2026 22:59:59 -0400 Subject: [PATCH 2/2] Match contributor CI version to existing Python workflow pin --- cli/CONTRIBUTING.md | 2 +- cli/protocol/OWNERSHIP.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cli/CONTRIBUTING.md b/cli/CONTRIBUTING.md index 8b244b01..062537d7 100644 --- a/cli/CONTRIBUTING.md +++ b/cli/CONTRIBUTING.md @@ -14,7 +14,7 @@ adapter should remain thin. Required development tools are Python 3.10, Rust 1.87.0 with Clippy and rustfmt, Bun 1.3.5, Node.js 22.22.3 or newer, and npm 10 or newer. CI uses -Python 3.10.18 and Node.js 24.20.0. Use those exact versions when you need to +Python 3.10.20 and Node.js 24.20.0. Use those exact versions when you need to reproduce CI or release behavior. The hash-locked test dependencies include Python 3.10 native wheels; use a Python 3.10 virtual environment for the install and test commands below. Newer Python versions may select wheels whose hashes diff --git a/cli/protocol/OWNERSHIP.md b/cli/protocol/OWNERSHIP.md index 3ea443a1..340d5704 100644 --- a/cli/protocol/OWNERSHIP.md +++ b/cli/protocol/OWNERSHIP.md @@ -785,3 +785,7 @@ Root authorized `/root/build_docs` on `codex/imp-055-build-docs` to edit exactly diagnostic/test builds and explicit tool configuration; provider-free copied example verification. No source, release documentation, model calls or new Python. Root retains integration and publication ownership. + +IMP-055 final documentation audit: root extends this branch's lease to +`cli/CONTRIBUTING.md` solely to align its stated CI Python patch version with +the existing workflow pin. No toolchain, workflow or Python source change.