Skip to content

fix(tangle-cli): add opt-in Jinja-safe bz2/Base85 bundling - #73

Open
Jflick58 wants to merge 3 commits into
TangleML:masterfrom
Jflick58:jflick/bundle-bz2-base85
Open

Jflick58 wants to merge 3 commits into
TangleML:masterfrom
Jflick58:jflick/bundle-bz2-base85

Conversation

@Jflick58

@Jflick58 Jflick58 commented Sep 30, 2026 •

Copy link
Copy Markdown

Why this change?

Large bundled Python components can exceed Linux's per-argument size limit and fail with argument list too long before Python starts. Keep the more compact format opt-in so existing callers retain zlib/Base64 behavior. Base85 can also contain Jinja delimiters, which need escaping before hydration.

Summary of changes

  • Keep bundle on zlib/Base64 and add opt-in bundle-bz2 for bz2/Base85. The new mode works through component generation, @task, hydration, and version regeneration.
  • Escape encoded opening braces as Python hex escapes so {{, {%, and {# remain inert during Jinja hydration, including repeated rendering.
  • Document the runtime requirement for Python's _bz2 extension. Both modes still use one command-line argument, so this reduces payload size rather than removing the size limit.

Testing

Automated Testing

  • 2,093 tests passed on each of Python 3.12 and 3.13. The final focused check passed all 411 tests.
  • Regression tests use real delimiter-bearing encoded payloads, pass generated YAML through the actual hydrator twice, then execute the generated shell and Python wrapper without the original source files.
  • Compatibility coverage checks the original zlib/Base64 format. The size regression includes brace-escaping overhead and stays at least 15% smaller on this package's source fixture.
  • Both packages built as source distributions and wheels. Lockfile and whitespace checks passed.

Tophatting

Offline CLI generation, hydration, and generated-wrapper execution passed for both modes using a synthetic helper. Both printed manual:value-510 as expected. No remote pipeline runs were submitted.

Bundle mode embeds every local module in one container command-line
argument. Linux rejects any single argument longer than MAX_ARG_STRLEN
(128 KiB) with E2BIG, so a component whose bundle crosses that size
fails at exec before any Python runs, and nothing warns at generation
time.

Encode the payload with bz2 instead of zlib, and Base85 instead of
Base64. Both are in the standard library, so generated components gain
no dependency. On a real 32-module, ~400 KB bundle, the argument drops
from 132,638 bytes (over the limit) to 94,952 bytes, with identical
module sources that decode and execute.

Base85 contains no quotes or backslashes, so the blob stays safe inside
the emitted Python string literal, and the program reaches the shell
only as $0 written out by printf, so it is never shell-interpreted.
Every generated component embeds its own decoder, so previously
generated components keep working unchanged. Very small bundles grow by
a few dozen bytes of bz2 header, which does not matter for the limit.

The bundled_modules_b64 keyword keeps its name because callers pass it
by keyword; only its documentation changes.
@Jflick58
Jflick58 marked this pull request as ready for review September 30, 2026 19:28
@Volv-G

Volv-G commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

I suggest not modifying an existing bundling mode, but adding a new one. Base85 allows things like {{ and {%, which might break jinja templates used during hydration. So the choice of this highly efficient bundling should be optional.

alternatively you might look into escaping these symbols safely, so that jinja doesn't break

@Volv-G Volv-G left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the comment about jinja templates

@Jflick58 Jflick58 changed the title fix(tangle-cli): shrink bundle-mode payload with bz2 and Base85 fix(tangle-cli): add opt-in Jinja-safe bz2/Base85 bundling Oct 1, 2026
@Jflick58

Jflick58 commented Oct 1, 2026

Copy link
Copy Markdown
Author

Fixed. bundle stays unchanged; bundle-bz2 is opt-in and safe through repeated Jinja hydration. We have downstream adoption planned: roll this into tangle-deploy, then update our pinned version and opt in the affected components.

@Jflick58
Jflick58 requested a review from Volv-G October 1, 2026 19:45

This branch has not been deployed

No deployments
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.

2 participants