Repository navigation
fix(sandbox): build the guest image from the office bundle's proven versions - #242
Merged
Merged
Conversation
…ersions install-office.sh was a loose re-interpretation of codev-office-ubuntu-setup.sh rather than a translation of it. It apt-installed pandoc and LibreOffice, took whatever the dotnet 8.0 channel currently served, and pip-installed the Python set from PyPI — so the guest ran pandoc 2.17.1.1 against the bundle's 3.10.1, LibreOffice 7.4.7.2 against 26.2.5, SDK 8.0.424 against 8.0.423, and unpinned Python packages. It also ignored two bundle components outright: the offline NuGet feed, which the docx skill's CLI restores DocumentFormat.OpenXml from and which a sealed guest cannot reach nuget.org to replace, and Playwright's Chromium, without which the pdf skill has no browser to render covers with. Versions now come off the bundle's own filenames, so refreshing the bundle moves the image with it. The bundle's x86_64 binaries are used verbatim on amd64; arm64 fetches the same version arch-correct (LibreOffice's aarch64 deb set, pandoc's arm64 deb, dotnet-install --version, and PyPI under a constraints file generated from the bundle's own cp311 wheels). A version the bundle pins that cannot be matched on an arch is a hard failure, never a substitution. Two defects found by verifying the built image rather than the script: LibreOffice was installed but could not execute. The TDF debs declare almost no dependencies, so `dpkg -i` succeeds and the `-f` fallback never fires, leaving system libraries absent — and LibreOffice dlopens several of them (libnss3's libssl3.so, libcairo.so.2), so they are invisible to ldd and surface only as "error while loading shared libraries" at first use. It appeared to work only because Playwright's install-deps happened to pull the same libraries in later. Debian packages the same software, so its libreoffice-core dependencies are now taken as the authoritative list. The build additionally converts a document and fails if no PDF comes out: the previous gate was `command -v soffice`, which passes happily on a binary that cannot load. Skills unzipped a directory too deep, because the zips carry their own top-level <skill>/ dir. Discovery survived it (its glob is recursive and these skills name themselves in frontmatter), but a skill without a frontmatter name would silently fail to load. Staged and moved as the setup script does, and the check is now for SKILL.md at the skill root rather than the directory existing. The bundle is bind-mounted rather than COPYed, since committing 1.2 GB to a layer that the install step then cannot delete is pure waste. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The sandbox guest image installed the office skills, but not the things they need to actually run. This makes the image build a translation of
codev-office-ubuntu-setup.shinstead of a loose re-interpretation of it.Version drift
install-office.shapt-installed pandoc and LibreOffice, took whatever the dotnet8.0channel currently served, and pip-installed the Python set unpinned from PyPI. Against the bundle the skills are tested with:Versions are now read off the bundle's own filenames, so refreshing the bundle moves the image with it rather than requiring a second edit here.
Two components were missing entirely
Worse than drift, and both fatal offline:
DocumentFormat.OpenXmland friends from it; a sealed guest has no route to nuget.org, so that skill could not run at all. The setup scriptfails outright when this feed is absent — the image silently shipped without it.Both now ship, with the NuGet config seeded through
/etc/skel(nuget.org cleared, offline feed only) so every fresh sandbox home gets it.Cross-arch rule
The bundle's binaries are x86_64-only, but every version it pins is obtainable for arm64: LibreOffice's
aarch64deb set, pandoc'sarm64deb,dotnet-install --version 8.0.423 --architecture arm64, and PyPI under a constraints file generated from the bundle's own cp311 wheels. So amd64 uses the bundle's bits verbatim, arm64 fetches the same versions arch-correct, and a version that cannot be matched on an arch is a hard build failure, never a silent substitution.Both wheel paths were verified before building: the fully-offline amd64 install resolves all 36 packages from the bundle alone, and the constrained arm64 install produces an identical version set. Generating those constraints caught a real drift —
magikaships apy3-none-manylinux_x86_64wheel, so a naive cp311/none-any filter missed it and arm64 resolved 0.6.3 against the bundle's 0.6.2.Two defects found by verifying the built image
LibreOffice was installed but could not execute. The TDF debs declare almost no dependencies, so
dpkg -isucceeds and the|| apt-get install -ffallback never fires. Several of the missing libraries aredlopened (libnss3'slibssl3.so,libcairo.so.2), solddreports nothing and the failure surfaces only aserror while loading shared librariesthe first time a document is converted. It appeared to work in testing only because Playwright'sinstall-depspulled the same libraries in at a later step — LibreOffice was silently depending on Playwright.Fixed by taking Debian's own
libreoffice-coredependencies as the authoritative list rather than hand-maintaining a guess (my hand-written list was wrong twice). Verified on a clean base stage with no Playwright present:probe.txt→probe.pdf.The build gate was checking the wrong thing. It was
command -v soffice— presence, which passes happily on a binary that cannot load. It now converts a document and fails the build if no PDF appears. That check is what caught the second missing library, and it is the part of this PR most likely to save someone later.Skills unzipped one directory too deep, because the zips carry their own top-level
<skill>/dir. Discovery survived it — the loader globs**/SKILL.mdrecursively and all four skills declarename:in frontmatter — but a skill without a frontmatter name would silently fail to load, since the filename fallback only applies to a SKILL.md directly in the configured directory. Now staged and moved as the setup script does, and the check is forSKILL.mdat the skill root rather than for the directory existing.Also
The bundle is bind-mounted rather than
COPYed: committing 1.2 GB to a layer the install step then cannot delete is pure waste.stageOfficeBundlenow stages the whole bundle (minus macOS artifacts, useless in a Linux guest) since the installer needs the artifacts themselves, not just the arch-independent zips.Verification
Offline NuGet restore — the component this PR adds — verified end to end in a sealed container (
--network none, arm64 guest image):With
<clear/>the restore had nowhere to go but the offline feed, so this proves the feed genuinely substitutes for nuget.org. This is precisely what failed before: the feed was not in the image and a sandbox cannot reach nuget.org, so the docx skill was unusable in every sandbox the old pipeline built.Also verified:
probe.txt→probe.pdfviawriter_pdf_Export, no missing-library error — the defect that broke the two previous build attempts.A full two-arch build is running at the time of writing; sizes and hashes to follow. Expect a substantially larger download — the full TDF LibreOffice suite, the .NET SDK and Chromium replace a trimmed Debian subset — so the changelog entry tells users to expect that and to hit Reset to pick the new image up.
packages/codev-sandboxis fork-only, so no DIVERGENCES rows apply.🤖 Generated with Claude Code