Skip to content

feat(build): add tiny profile and minimal runtime config - #1273

Closed
c2j wants to merge 1 commit into
1jehuang:masterfrom
c2j:tiny-build-profile
Closed

c2j wants to merge 1 commit into
1jehuang:masterfrom
c2j:tiny-build-profile

Conversation

@c2j

@c2j c2j commented Sep 15, 2026

Copy link
Copy Markdown

Closes #1272

What this changes

This is the first, profile-only step toward a minimal-footprint jcode. It adds no Rust code and restructures nothing.

  • Cargo.toml — a new [profile.tiny]: opt-level = "z", lto = "fat", codegen-units = 1, incremental = false, strip = "symbols", debug = 0, panic = "abort". The interactive hot-path crates (ratatui family, crossterm, unicode-*, jcode-tui-anim, jcode-fuzzy) are pinned back to opt-level = 3, matching the existing dev/selfdev/test pins, because at opt-level = "z" the render loop and fuzzy picker feel visibly laggy.
  • scripts/build_tiny.sh — one command that builds with the tiny profile plus the existing JCODE_DEV_FEATURE_PROFILE=minimal (i.e. --no-default-features) and reports the resulting size and version.
  • assets/config-templates/tiny.toml — a reduced runtime config that disables the background and optional work that is compiled in but unnecessary for basic coding: update checks, the memory subsystem and its LLM sidecar, swarm, Mermaid, decorative animations, LaTeX/image rendering, sleep inhibition, desktop notifications, autoreview/autojudge, integration discovery, and the non-essential tools (tools.profile = "minimal").
  • docs/TINY_BUILD.md — documents the recipe, the measured result, the panic = "abort" behavior tradeoff, what is deliberately left alone, and the later steps. Linked from docs/README.md.
  • scripts/dev_cargo.sh — treats tiny as non-incremental so the sccache decision matches the profile's incremental = false.

The minimal feature profile is not new; it already maps to --no-default-features and is the default for scripts/test_fast.sh, so the feature set built here is a known-compiling configuration.

Measured

Apple Silicon (aarch64) macOS, Rust stable. The baseline is the existing target/release/jcode, built with the default feature set and the release profile, so the numbers cover the feature-set reduction and the profile change together:

Metric release (default features) tiny + minimal Change
Binary size 136,489,952 B (136 MB) 24,613,488 B (23.5 MB) -82%
__text (code) 64,617,564 B 16,117,640 B -75%
__eh_frame 9,480,336 B 95,280 B -99%
__gcc_except_tab 5,947,100 B 9,188 B -99.8%

The __eh_frame / __gcc_except_tab collapse comes from panic = "abort" plus strip; the __text reduction from opt-level = "z" + fat LTO + dropping the embedding/AWS/PDF dependency stacks.

Build time was about 16 minutes on a 10-core host. scripts/dev_cargo.sh throttled it to a single rustc job because the host was under memory pressure, so an unloaded machine will be faster.

Validation

  • scripts/build_tiny.sh completes with exit code 0 and produces target/tiny/jcode (23.5 MB, jcode v0.84.54-dev).
  • target/tiny/jcode --version and --help work.
  • The config template parses and loads in the real binary: with a temporary JCODE_HOME containing it, jcode --no-update model list exits 0 and lists models.
  • scripts/check_dependency_boundaries.py passes.

Note: scripts/check_guardrails.sh --skip-slow reports 6 failing gates (fmt, warning budget, oversized-file/test ratchets, panic-prone and swallowed-error ratchets) on the base commit, all referencing Rust files this PR does not touch. This PR adds no Rust code, so it neither causes nor fixes those.

Tradeoffs / review notes

  • panic = "abort" removes unwind tables but disables the catch_unwind graceful-degradation paths in the TUI draw loop, the Mermaid renderer, and PDF extraction. Session state is persisted server-side, so a client abort is recoverable, but reviewers who consider those paths load-bearing should ask for the line to be dropped — the profile still yields most of the win without it.
  • The tiny profile deliberately does not touch install_release.sh, so it cannot accidentally become a release channel. The doc shows how to install it under a separate launcher name.
  • This PR intentionally does not feature-gate the unconditional dependency stacks (nine provider runtimes, Mermaid/resvg, image/terminal-image, syntect, macOS helpers) or #[cfg]-out subsystems such as memory/swarm. Those are the larger, separately reviewable follow-ups.

Introduce the first, profile-only step of the minimal-footprint build:

- `[profile.tiny]` in Cargo.toml: opt-level="z", fat LTO, one codegen unit,
  no incremental, stripped symbols, and panic="abort", with the interactive
  hot-path crates pinned back to opt-level=3 so the TUI stays responsive.
- `scripts/build_tiny.sh` wraps the build (`tiny` profile plus
  `JCODE_DEV_FEATURE_PROFILE=minimal`) and reports the resulting size.
- `assets/config-templates/tiny.toml` turns off runtime work that is compiled
  in but unnecessary for basic coding: update checks, the memory subsystem and
  its sidecar, swarm, mermaid, decorative animations, sleep inhibition, desktop
  notifications, autoreview/autojudge, integration discovery, and the
  non-essential tools.
- `docs/TINY_BUILD.md` documents the recipe, the `panic = "abort"` behavior
  tradeoff, what is deliberately left alone, and the measured result
  (136 MB -> 23.5 MB, -82%).
- `scripts/dev_cargo.sh` treats `tiny` as non-incremental so the sccache
  decision matches the profile's `incremental = false`.

No Rust code was restructured; subsystem removal is left to later steps.

Measured: binary 136,489,952 B -> 24,613,488 B; __text 64,617,564 B ->
16,117,640 B; build ~16 min on a 10-core host under memory pressure.
@c2j c2j closed this Sep 15, 2026
@greptile-apps

greptile-apps Bot commented Sep 15, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

Not safe to merge until the build wrapper uses Cargo’s effective executable path.

Findings

  1. P1 Use Cargo output path
Fix with agent prompt
### Issue 1
scripts/build_tiny.sh:53
The script constructs the executable path as `target/$profile/jcode` instead of using Cargo’s actual artifact location. With `JCODE_TINY_PROFILE=dev`, Cargo successfully creates `target/debug/jcode`, but the script checks `target/dev/jcode` and exits as if no binary was produced. When `CARGO_TARGET_DIR` is set, it can instead size and run a stale binary in the repository’s default target directory rather than the binary that was just built. This makes supported build configurations fail or report misleading footprint and version results.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

This PR adds a size-focused build profile, minimal runtime configuration, and documentation for producing a smaller JCode binary. The build wrapper currently assumes Cargo’s output directory, which can cause successful builds to fail verification or report a different executable’s size and version.

Reviews (1) · Last reviewed commit: "feat(build): add tiny profile and minima..."

Comment thread scripts/build_tiny.sh
profile="${JCODE_TINY_PROFILE:-tiny}"
feature_profile="${JCODE_TINY_FEATURES:-minimal}"

bin="$repo_root/target/$profile/jcode"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Use Cargo output path

The script constructs the executable path as target/$profile/jcode instead of using Cargo’s actual artifact location. With JCODE_TINY_PROFILE=dev, Cargo successfully creates target/debug/jcode, but the script checks target/dev/jcode and exits as if no binary was produced. When CARGO_TARGET_DIR is set, it can instead size and run a stale binary in the repository’s default target directory rather than the binary that was just built. This makes supported build configurations fail or report misleading footprint and version results.

Artifacts

Evidence from the check

  • A disposable-package harness copied and executes the changed build script with a real local Cargo pass-through for tiny, dev, and custom-target configurations, ending with the reproduced behavior.

Command output from the check

  • The command-captured authored harness source shows exactly how the disposable Cargo package and three execution cases were created, ending with the executable test definition.

Command output from the check

  • The first captured execution shows default tiny succeeds, dev builds but the script misses Cargo's debug output, and custom target uses a divergent artifact path, ending with a successful harness exit.

Command output from the check

  • The repeated execution changes the custom-target binary version, proving the script reports the old default-target version despite Cargo creating the distinct custom-target binary, ending with a successful harness exit.

Command output from the check

  • The command-captured numbered source identifies the hard-coded artifact path at line 53 and its validation, sizing, and version use at lines 69 through 80, ending with successful command completion.

Command output from the check

  • The captured shell syntax check validates both the changed script and the focused harness, ending with exit code 0.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/build_tiny.sh
Line: 53

Comment:
**Use Cargo output path**

The script constructs the executable path as `target/$profile/jcode` instead of using Cargo’s actual artifact location. With `JCODE_TINY_PROFILE=dev`, Cargo successfully creates `target/debug/jcode`, but the script checks `target/dev/jcode` and exits as if no binary was produced. When `CARGO_TARGET_DIR` is set, it can instead size and run a stale binary in the repository’s default target directory rather than the binary that was just built. This makes supported build configurations fail or report misleading footprint and version results.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

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.

Add a minimal-footprint build profile (tiny binary + reduced runtime config)

1 participant