fix: improve debug mode output and exit behavior#12
Merged
Conversation
- Remove clear_screen on exit so Docker errors remain visible - Skip intro/outro animations in debug mode (--debug implies --no-intro) - Fix spinner and debug log overlap during DinD wait - Add newline after interactive docker run to separate cleanup logs - Disable all clear_screen calls in debug mode via global flag Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Speeds up CI runs by caching compiled dependencies between builds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bump actions/checkout v4 → v5 across all workflows - Bump actions/upload-pages-artifact v3 → v4 - Add Swatinem/rust-cache to release test and build jobs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
donbeave
added a commit
that referenced
this pull request
Apr 20, 2026
…ovements fix: improve debug mode output and exit behavior
donbeave
added a commit
that referenced
this pull request
Apr 21, 2026
…ovements fix: improve debug mode output and exit behavior
donbeave
added a commit
that referenced
this pull request
Apr 21, 2026
fix: improve debug mode output and exit behavior
donbeave
added a commit
that referenced
this pull request
Apr 21, 2026
fix: improve debug mode output and exit behavior
donbeave
added a commit
that referenced
this pull request
Apr 21, 2026
fix: improve debug mode output and exit behavior
donbeave
added a commit
that referenced
this pull request
May 7, 2026
fix: improve debug mode output and exit behavior Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Codex <codex@openai.com>
donbeave
added a commit
that referenced
this pull request
May 7, 2026
fix: improve debug mode output and exit behavior Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Codex <codex@openai.com>
donbeave
added a commit
that referenced
this pull request
May 7, 2026
- Remove clear_screen on exit so Docker errors remain visible - Skip intro/outro animations in debug mode (--debug implies --no-intro) - Fix spinner and debug log overlap during DinD wait - Add newline after interactive docker run to separate cleanup logs - Disable all clear_screen calls in debug mode via global flag Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Claude <noreply@anthropic.com>
donbeave
added a commit
that referenced
this pull request
May 7, 2026
Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Claude <noreply@anthropic.com>
donbeave
added a commit
that referenced
this pull request
May 7, 2026
Speeds up CI runs by caching compiled dependencies between builds. Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Claude <noreply@anthropic.com>
donbeave
added a commit
that referenced
this pull request
May 7, 2026
- Bump actions/checkout v4 → v5 across all workflows - Bump actions/upload-pages-artifact v3 → v4 - Add Swatinem/rust-cache to release test and build jobs Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Claude <noreply@anthropic.com>
donbeave
added a commit
that referenced
this pull request
May 7, 2026
fix: improve debug mode output and exit behavior Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Codex <codex@openai.com>
donbeave
added a commit
that referenced
this pull request
May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report that followed the parallel-agent capture commit. Splits cleanly from the in-flight env-config refactor by touching only the host-side session-inventory and snapshot-fanout paths plus the capsule socket layer; parallel-agent territory (main.rs, daemon.rs, session.rs, launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays untouched. Findings addressed: * `src/console/manager/state.rs` — fan-out worker panics now surface through the existing `debug_log` path: `h.join()` failures are downcast to a string and re-routed as `Err(anyhow!)` so the slot is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host with dozens of active containers does not spawn dozens of OS threads per 500 ms refresh tick; each chunk's wall-clock cost is still bounded by the slowest fetch in that chunk. The fan-out body moves into a free `fetch_snapshots_parallel` helper so `refresh_instances` stays under the clippy line-count gate. * `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on `test -S /jackin/run/jackin.sock` so the early-bring-up window (between container start and the daemon binding its socket, plus any pre-`setup-once` time) does not leak operator-visible stderr from a binary that exists but cannot serve yet. `test -S` exits silently with status 1 if the socket is absent; `||` short- circuits at the first failure only — no `|| true` masking the second command's errors once the socket exists. `parse_jackin_sessions` drops the strict `len() != expected` equality in favour of `take(expected)` so trailing footer lines or labels that `Display`-emit a non-`[` continuation line no longer flip the parse to Unavailable; the count check is now a lower-bound (`< expected`), which still catches real format drift but tolerates harmless decoration. The header search lifts a shared `parse_session_count` helper used by both `inspect_agent_sessions` here and `isolation::finalize::has_jackin_sessions`, replacing the duplicate parser that was warned about in finding #3. * `src/isolation/finalize.rs` — `parse_session_count` is now `runtime::attach::parse_session_count`; the local copy is gone. One header parser, one definition of malformed, no silent divergence on edge cases. * `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection log now fires exactly once on the saturation transition + once on the recovery transition, with per-drop messages demoted to `cdebug!` so a flood attacker (the exact threat `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the compact-tier log. Per-backoff line also demoted to `cdebug!` — the accept-error clog above already names the failure, so the 1-line-per-failure compact-log invariant holds. `start_listener_at` splits behind a new `start_listener_at_with_limiter` test-only helper that returns the inner `Arc<Semaphore>`. The cap regression test now reads `limiter.available_permits()` directly instead of racing `rx.recv()` against a 300 ms wall-clock deadline — cap-sensitive, not timing-sensitive. Wall-clock `timeout()` windows widen to 2 s for the remaining positive assertions so a slow CI runner does not produce spurious failures. * `crates/jackin-capsule/src/protocol/attach.rs` — new `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload` variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1` real entries so the per-entry boundary is verified after the read loop, not just at the count declaration. The earlier test only exercised the front-of-loop guard; a regression that moved the cap check below the per-entry loop would slip past it silently. Deferred (parallel-agent territory or out-of-scope for this pass): * `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push asymmetry (finding #6) and `focus_swap_reset_*` test-name overpromises (finding #12) — `session.rs` is mid-rebase by the parallel agent. * `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by alt-screen swap (finding #8) — `main.rs` mid-rebase. * `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit` fixture ordering (finding #14) — `launch.rs` mid-rebase under the env-config migration. Setup-once gating left untouched: `docker/runtime/entrypoint.sh` already gates on `/jackin/state/hooks/setup-once.done` (line 78, runs only if marker absent; line 88 writes the marker on success). The new `test -S` socket gate on the host-side status query is the orthogonal half of the "don't query during early bring-up" rule. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
donbeave
added a commit
that referenced
this pull request
May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report that followed the parallel-agent capture commit. Splits cleanly from the in-flight env-config refactor by touching only the host-side session-inventory and snapshot-fanout paths plus the capsule socket layer; parallel-agent territory (main.rs, daemon.rs, session.rs, launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays untouched. Findings addressed: * `src/console/manager/state.rs` — fan-out worker panics now surface through the existing `debug_log` path: `h.join()` failures are downcast to a string and re-routed as `Err(anyhow!)` so the slot is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host with dozens of active containers does not spawn dozens of OS threads per 500 ms refresh tick; each chunk's wall-clock cost is still bounded by the slowest fetch in that chunk. The fan-out body moves into a free `fetch_snapshots_parallel` helper so `refresh_instances` stays under the clippy line-count gate. * `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on `test -S /jackin/run/jackin.sock` so the early-bring-up window (between container start and the daemon binding its socket, plus any pre-`setup-once` time) does not leak operator-visible stderr from a binary that exists but cannot serve yet. `test -S` exits silently with status 1 if the socket is absent; `||` short- circuits at the first failure only — no `|| true` masking the second command's errors once the socket exists. `parse_jackin_sessions` drops the strict `len() != expected` equality in favour of `take(expected)` so trailing footer lines or labels that `Display`-emit a non-`[` continuation line no longer flip the parse to Unavailable; the count check is now a lower-bound (`< expected`), which still catches real format drift but tolerates harmless decoration. The header search lifts a shared `parse_session_count` helper used by both `inspect_agent_sessions` here and `isolation::finalize::has_jackin_sessions`, replacing the duplicate parser that was warned about in finding #3. * `src/isolation/finalize.rs` — `parse_session_count` is now `runtime::attach::parse_session_count`; the local copy is gone. One header parser, one definition of malformed, no silent divergence on edge cases. * `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection log now fires exactly once on the saturation transition + once on the recovery transition, with per-drop messages demoted to `cdebug!` so a flood attacker (the exact threat `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the compact-tier log. Per-backoff line also demoted to `cdebug!` — the accept-error clog above already names the failure, so the 1-line-per-failure compact-log invariant holds. `start_listener_at` splits behind a new `start_listener_at_with_limiter` test-only helper that returns the inner `Arc<Semaphore>`. The cap regression test now reads `limiter.available_permits()` directly instead of racing `rx.recv()` against a 300 ms wall-clock deadline — cap-sensitive, not timing-sensitive. Wall-clock `timeout()` windows widen to 2 s for the remaining positive assertions so a slow CI runner does not produce spurious failures. * `crates/jackin-capsule/src/protocol/attach.rs` — new `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload` variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1` real entries so the per-entry boundary is verified after the read loop, not just at the count declaration. The earlier test only exercised the front-of-loop guard; a regression that moved the cap check below the per-entry loop would slip past it silently. Deferred (parallel-agent territory or out-of-scope for this pass): * `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push asymmetry (finding #6) and `focus_swap_reset_*` test-name overpromises (finding #12) — `session.rs` is mid-rebase by the parallel agent. * `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by alt-screen swap (finding #8) — `main.rs` mid-rebase. * `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit` fixture ordering (finding #14) — `launch.rs` mid-rebase under the env-config migration. Setup-once gating left untouched: `docker/runtime/entrypoint.sh` already gates on `/jackin/state/hooks/setup-once.done` (line 78, runs only if marker absent; line 88 writes the marker on success). The new `test -S` socket gate on the host-side status query is the orthogonal half of the "don't query during early bring-up" rule. Co-authored-by: Codex <codex@openai.com> Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
donbeave
added a commit
that referenced
this pull request
May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report that followed the parallel-agent capture commit. Splits cleanly from the in-flight env-config refactor by touching only the host-side session-inventory and snapshot-fanout paths plus the capsule socket layer; parallel-agent territory (main.rs, daemon.rs, session.rs, launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays untouched. Findings addressed: * `src/console/manager/state.rs` — fan-out worker panics now surface through the existing `debug_log` path: `h.join()` failures are downcast to a string and re-routed as `Err(anyhow!)` so the slot is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host with dozens of active containers does not spawn dozens of OS threads per 500 ms refresh tick; each chunk's wall-clock cost is still bounded by the slowest fetch in that chunk. The fan-out body moves into a free `fetch_snapshots_parallel` helper so `refresh_instances` stays under the clippy line-count gate. * `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on `test -S /jackin/run/jackin.sock` so the early-bring-up window (between container start and the daemon binding its socket, plus any pre-`setup-once` time) does not leak operator-visible stderr from a binary that exists but cannot serve yet. `test -S` exits silently with status 1 if the socket is absent; `||` short- circuits at the first failure only — no `|| true` masking the second command's errors once the socket exists. `parse_jackin_sessions` drops the strict `len() != expected` equality in favour of `take(expected)` so trailing footer lines or labels that `Display`-emit a non-`[` continuation line no longer flip the parse to Unavailable; the count check is now a lower-bound (`< expected`), which still catches real format drift but tolerates harmless decoration. The header search lifts a shared `parse_session_count` helper used by both `inspect_agent_sessions` here and `isolation::finalize::has_jackin_sessions`, replacing the duplicate parser that was warned about in finding #3. * `src/isolation/finalize.rs` — `parse_session_count` is now `runtime::attach::parse_session_count`; the local copy is gone. One header parser, one definition of malformed, no silent divergence on edge cases. * `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection log now fires exactly once on the saturation transition + once on the recovery transition, with per-drop messages demoted to `cdebug!` so a flood attacker (the exact threat `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the compact-tier log. Per-backoff line also demoted to `cdebug!` — the accept-error clog above already names the failure, so the 1-line-per-failure compact-log invariant holds. `start_listener_at` splits behind a new `start_listener_at_with_limiter` test-only helper that returns the inner `Arc<Semaphore>`. The cap regression test now reads `limiter.available_permits()` directly instead of racing `rx.recv()` against a 300 ms wall-clock deadline — cap-sensitive, not timing-sensitive. Wall-clock `timeout()` windows widen to 2 s for the remaining positive assertions so a slow CI runner does not produce spurious failures. * `crates/jackin-capsule/src/protocol/attach.rs` — new `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload` variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1` real entries so the per-entry boundary is verified after the read loop, not just at the count declaration. The earlier test only exercised the front-of-loop guard; a regression that moved the cap check below the per-entry loop would slip past it silently. Deferred (parallel-agent territory or out-of-scope for this pass): * `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push asymmetry (finding #6) and `focus_swap_reset_*` test-name overpromises (finding #12) — `session.rs` is mid-rebase by the parallel agent. * `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by alt-screen swap (finding #8) — `main.rs` mid-rebase. * `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit` fixture ordering (finding #14) — `launch.rs` mid-rebase under the env-config migration. Setup-once gating left untouched: `docker/runtime/entrypoint.sh` already gates on `/jackin/state/hooks/setup-once.done` (line 78, runs only if marker absent; line 88 writes the marker on success). The new `test -S` socket gate on the host-side status query is the orthogonal half of the "don't query during early bring-up" rule. Co-authored-by: Codex <codex@openai.com> Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com>
donbeave
added a commit
that referenced
this pull request
May 23, 2026
Trust-but-verify pass on the 15-item /code-review max-effort report that followed the parallel-agent capture commit. Splits cleanly from the in-flight env-config refactor by touching only the host-side session-inventory and snapshot-fanout paths plus the capsule socket layer; parallel-agent territory (main.rs, daemon.rs, session.rs, launch.rs, env_model.rs, derived_image.rs, entrypoint.sh) stays untouched. Findings addressed: * `src/console/manager/state.rs` — fan-out worker panics now surface through the existing `debug_log` path: `h.join()` failures are downcast to a string and re-routed as `Err(anyhow!)` so the slot is no longer dropped by `filter_map(|h| h.join().ok())`. Snapshot fan-out is also bounded by `SNAPSHOT_FANOUT_CHUNK = 8` so a host with dozens of active containers does not spawn dozens of OS threads per 500 ms refresh tick; each chunk's wall-clock cost is still bounded by the slowest fetch in that chunk. The fan-out body moves into a free `fetch_snapshots_parallel` helper so `refresh_instances` stays under the clippy line-count gate. * `src/runtime/attach.rs` — `JACKIN_STATUS_CMD` now gates on `test -S /jackin/run/jackin.sock` so the early-bring-up window (between container start and the daemon binding its socket, plus any pre-`setup-once` time) does not leak operator-visible stderr from a binary that exists but cannot serve yet. `test -S` exits silently with status 1 if the socket is absent; `||` short- circuits at the first failure only — no `|| true` masking the second command's errors once the socket exists. `parse_jackin_sessions` drops the strict `len() != expected` equality in favour of `take(expected)` so trailing footer lines or labels that `Display`-emit a non-`[` continuation line no longer flip the parse to Unavailable; the count check is now a lower-bound (`< expected`), which still catches real format drift but tolerates harmless decoration. The header search lifts a shared `parse_session_count` helper used by both `inspect_agent_sessions` here and `isolation::finalize::has_jackin_sessions`, replacing the duplicate parser that was warned about in finding #3. * `src/isolation/finalize.rs` — `parse_session_count` is now `runtime::attach::parse_session_count`; the local copy is gone. One header parser, one definition of malformed, no silent divergence on edge cases. * `crates/jackin-capsule/src/socket.rs` — accept-loop cap-rejection log now fires exactly once on the saturation transition + once on the recovery transition, with per-drop messages demoted to `cdebug!` so a flood attacker (the exact threat `MAX_CONCURRENT_CLIENTS` defends against) cannot drown the compact-tier log. Per-backoff line also demoted to `cdebug!` — the accept-error clog above already names the failure, so the 1-line-per-failure compact-log invariant holds. `start_listener_at` splits behind a new `start_listener_at_with_limiter` test-only helper that returns the inner `Arc<Semaphore>`. The cap regression test now reads `limiter.available_permits()` directly instead of racing `rx.recv()` against a 300 ms wall-clock deadline — cap-sensitive, not timing-sensitive. Wall-clock `timeout()` windows widen to 2 s for the remaining positive assertions so a slow CI runner does not produce spurious failures. * `crates/jackin-capsule/src/protocol/attach.rs` — new `hello_env_count_over_cap_is_rejected_by_decoder_with_full_payload` variant supplies a fully-populated payload of `MAX_HELLO_ENV + 1` real entries so the per-entry boundary is verified after the read loop, not just at the count declaration. The earlier test only exercised the front-of-loop guard; a regression that moved the cap check below the per-entry loop would slip past it silently. Deferred (parallel-agent territory or out-of-scope for this pass): * `crates/jackin-capsule/src/session.rs` kitty single-pop vs N-push asymmetry (finding #6) and `focus_swap_reset_*` test-name overpromises (finding #12) — `session.rs` is mid-rebase by the parallel agent. * `crates/jackin-capsule/src/main.rs` `--focus` eprintln eaten by alt-screen swap (finding #8) — `main.rs` mid-rebase. * `src/runtime/launch.rs` `fake_docker_for_clean_attached_exit` fixture ordering (finding #14) — `launch.rs` mid-rebase under the env-config migration. Setup-once gating left untouched: `docker/runtime/entrypoint.sh` already gates on `/jackin/state/hooks/setup-once.done` (line 78, runs only if marker absent; line 88 writes the marker on success). The new `test -S` socket gate on the host-side status query is the orthogonal half of the "don't query during early bring-up" rule. Signed-off-by: Alexey Zhokhov <alexey@zhokhov.com> Co-authored-by: Codex <codex@openai.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.
Summary
clear_screenon exit so Docker errors remain visible in the terminal--debugimplies--no-intro)[debug]log overlap during Docker-in-Docker waitdocker runto prevent cleanup logs from overlapping with Claude Code's TUIclear_screencalls in debug mode via a globalAtomicBoolflagTest plan
jackin load --debugand verify no screen clears happenjackin load --debugand verify spinner + debug logs don't overlap during DinD waitjackin load(no debug) and verify intro/outro animations still workjackin load --debugwith a failing container and verify the Docker error is visible🤖 Generated with Claude Code