Skip to content

release: gate every extension on its own component round - #49

Open
weilueluo wants to merge 2 commits into
mainfrom
agent-ext-smoke
Open

release: gate every extension on its own component round#49
weilueluo wants to merge 2 commits into
mainfrom
agent-ext-smoke

Conversation

@weilueluo

Copy link
Copy Markdown
Contributor

Every one of this release's extension defects was found in a full tagged deployment plus an eight-case live canary, and every one was reachable far earlier: a Model export threw a plain Error and reached the kernel as a bare Wasm backtrace, temperature: null was forwarded to the provider, the OpenAI dialect never read generation.system_prompt, and the SSE decoder rejected every chunk because a host list<u8> does not arrive as a Uint8Array. All four are only reachable when the real componentized Wasm runs against the real host ABI, which nothing here did — the package tests exercise provider.mjs and index.mjs as plain modules.

Per-extension end-to-end smoke

tools/component-smoke.mjs drives one package's actual built components through a realistic round on Brain's own component-host worker, at the immutable Brain revision packages/env-aws-microvm/runtime/Cargo.toml already pins. That worker is a complete JSON-lines host over stdio with a capability seam, so the smoke needs no second host implementation and no Rust in this repository — .github/actions/component-host builds and caches the binary by that revision.

kind round
Model startobserve with a 2xx first chunk, a second chunk whose status is absent, then doneacknowledge; then a 500 first chunk
Agentloop session_start with a hydration tail, then a message activation driving model_stream/journal_append/turn_finish; then a refused round
Environment resolvesubmit with a bundle → observe running → observe completed → acknowledgerelease; then a refused dispatch
Tool invoke under its declared grant against the package's own descriptor and bundle; then a refused grant

Each kind asserts that a failing export surfaces a typed extension-error carrying its reason, never a trap. @aexhq/model and @aexhq/agentloop publish no component, so their smoke compiles a fixture through the package's own public authoring path and drives that.

Reverting each of the four fixes and rebuilding shows the smoke catches all four, including the exact production symptom for the first:

temperature reached the provider
the sealed instructions never reached the provider
The input did not match /status 500/. Input: 'error while executing at wasm backtrace: ...'
Error: SSE chunks must be a byte sequence

Per-package staging and promotion

npm-publish.yml packed and published all nine workspaces as one lot. Now tools/npm-release.mjs records each package's intra-release edges in the manifest and derives the staging waves from them — no list to maintain, and a chain deeper than two waves fails closed rather than publishing a dependent before its dependency is visible. Staging fans out per package (@aexhq/model before @aexhq/model-openai, @aexhq/agentloop before the loops), each staged version is installed from the registry and smoked against its exact dist.integrity, and promotion moves each package on its own receipt for that exact archive, holding an unproven one on next instead of blocking the rest.

Every existing gate is unchanged: the release/sha-<40hex> tag and expected_commit check, the released-version integrity rule, the version-ownership source rule, the stage_run_id promotion consumes, and exact cross-release dependency verification. No package version changes and no file under packages/ is touched.

Extension defects only surfaced at the platform level because nothing in
this repository ever instantiated a built component: the package tests
exercise plain JS modules, so an opaque Wasm trap, a forwarded null
sampling field, a dropped sealed instruction and a `list<u8>` the guest
does not recognise were all reachable only from a tagged deployment.

Each package now drives its actual `.component.wasm` through a realistic
round on Brain's own `component-host` worker, at the immutable Brain
revision the AWS MicroVM runtime already pins, and asserts that a failing
export reaches the kernel as a typed `extension-error` carrying its reason.

Staging fans out per package in an order derived from the release itself,
each staged version is smoked from the registry rather than rebuilt, and
promotion moves each package on its own receipt for that exact archive.
@weilueluo

Copy link
Copy Markdown
Contributor Author

Run unchanged against the builds actually published to npm, the smoke rejects every one that shipped a defect and accepts only the current one:

published build smoke result
@aexhq/model-openai@0.1.0 temperature reached the provider
@aexhq/model-openai@0.1.1 temperature reached the provider
@aexhq/model-openai@0.1.2 SSE chunks must be Uint8Array values
@aexhq/model-openai@0.1.3 passes

Reverting the remaining two fixes in the working tree and rebuilding reproduces the other two, including the exact production symptom:

the sealed instructions never reached the provider
The input did not match /status 500/. Input: 'error while executing at wasm backtrace: ...'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant