fix(amico-run): bundle-build CI gate + upgrade-path dist rebuild — no more stale verb router (#643) - #647
Open
aarontrowbridge wants to merge 4 commits into
Open
fix(amico-run): bundle-build CI gate + upgrade-path dist rebuild — no more stale verb router (#643)#647aarontrowbridge wants to merge 4 commits into
aarontrowbridge wants to merge 4 commits into
Conversation
…smoke-runs the verb router (#643) The CLI bundles (packages/amico-run/dist/*.js) are gitignored build artifacts; the deployed verb-router bundle sat 46 days stale because nothing gated the build — a broken entry or unresolvable import only failed on whichever machine last tried to build. New bundle-build-gate job (mirrors app-bundle-gate's shape): install + the package's own build + scripts/assert_built_bundles.mjs, which re-reads the package's bin map (single source of truth, same map the extension staging and assert_packaged_cli.mjs re-read) and asserts every declared bundle is built non-empty, plus a verb-router smoke (amico --help exits 0 with the usage surface) — the vitest suite transpiles and never executes the shipped artifact, so a builds-but-dies bundle reds here. Both directions pinned in test/bundle_gate.test.ts (real build green; fabricated missing-bundle and dead-router red).
…r dists, with receipt evidence (#643) The incident: the deployed amico bundle sat 46 days stale while server-binary upgrades ran — the ledger verbs existed in source, were absent from the deployed binary, and every ledger call silently degraded for weeks. Deployed router freshness must not depend on whoever last ran a local build. The server-binary verb (the deployed-code lane) now rebuilds the CLI bundles from the amicode checkout's current source and refreshes BOTH copies — the build output (packages/amico-run/dist) and the extension-side byte-copy the PATH-first launcher execs (packages/extension/bin/dist) — between the artifact smoke (5) and the freeze (6). Fail-closed by placement: a failed or incomplete rebuild aborts BEFORE any server surface is touched, so the receipt never lies about a half-deployed state. - the declared bundle set comes from the amico-run package's bin map + shadowBins (the single source of truth the extension staging and CI's bundle-build-gate re-read); a build that drops a declared bundle is the stale-bundle signature and aborts - receipt evidence: amicode_head (the commit the dists were built from), verb_router_sha256 + verb_router_staged_sha256 (the router's bytes on both sides) - --dist-build-command is the hermetic stub seam (mirrors --package-command); the default is 'pnpm run build' in the package dir with a pnpm environment check - fixture worlds carry the real amico-run bin map; the server-binary suite stubs the dist build through the shared verbArgs helper
…le — no MODULE_TYPELESS reparse (#643) The ESM CLI bundles staged under packages/extension/bin sit inside the VS Code extension manifest's package.json — which MUST stay typeless (adding "type": "module" would flip the CJS extension-host entry dist/extension.js and break vsce packaging). Without a scoped marker, node reparse-warns (MODULE_TYPELESS_PACKAGE_JSON) on every invocation — the deployed live machine paid exactly this, because its bin/ was staged before the marker existed and refreshed by hand. The dist-rebuild hook now writes the bin/-scoped {"type":"module"} marker alongside the refreshed bundles — byte-identical to the one the extension build's staging writes (esbuild.config.mjs), so both refresh paths converge. Blast radius: zero changes to the extension manifest, no .mjs rename (which would churn the staging convention, the launcher exec path, and the packaging gates for no additional benefit). Pinned from both sides: the upgrade test spawns the refreshed extension-side bundle and asserts no MODULE_TYPELESS warning on stderr; the VSIX packaging list pins extension/bin/package.json as a required runtime asset (the packaged side of the contract).
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
aarontrowbridge
marked this pull request as ready for review
August 30, 2026 12:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #643
What
The deployed
amicoverb-router bundle sat 46 days stale because nothing rebuilt it: no CI lane built the bundles, and the upgrade path deployed new code while the dist stayed months old. This closes both holes and fixes the cosmetic that made every invocation noisy.bundle-build-gatelane — builds every declared bundle from current source on every push/PR (mirroringapp-bundle-gate's shape), then asserts the full declared set exists and smoke-runs the built verb-router (--helpmust exit 0). A broken entry or unresolvable import fails the build step; a build that silently drops a bundle reds the assert. The vitest suite never executes the shipped artifact — this lane is where a builds-but-dies bundle is caught.amicode_head,verb_router_sha256,verb_router_staged_sha256). A deployed upgrade can no longer leave a stale verb router behind.{"type": "module"}marker beside it, killing the per-invocationMODULE_TYPELESS_PACKAGE_JSONreparse warning. The VS Code extension manifest was deliberately not touched (adding"type": "module"there would flip the CJS extension-host entry); the marker is byte-identical to what the extension build's staging already writes, so both refresh paths converge.Acceptance criteria — evidence
ERROR: Could not resolve(the exact incident class, re-created and caught).Director gates (run independently on this branch)
pnpm --filter @amicode/amico-run build— clean, all five entriesnode packages/amico-run/scripts/assert_built_bundles.mjs— all PASS, exit 0pnpm --filter amico-run typecheck— cleanDesign choices worth review
--dist-build-commandis the hermetic test seam, mirroring the extension verb's--package-command.Ops follow-through (not repo work)
The live server's extension-side copies still hold the ops-refreshed bundles from 2026-08-30 minus the marker; the next
amico upgrade server-binaryrun on that machine refreshes all five bundles and writes the marker under the new receipt. Trivial, but it's the closing step of the original incident.Merge
Draft until CI runs the new lane on this very PR (its own first execution). Ready-for-review once green; merge is human-only.