Skip to content

[core-shrink] add TinyBox native shell client helper - #61

Merged
senamakel merged 36 commits into
epic/8369-security-migrationfrom
sec-6-tinybox-native-shell
Oct 26, 2026
Merged

senamakel merged 36 commits into
epic/8369-security-migrationfrom
sec-6-tinybox-native-shell

Conversation

@senamakel

@senamakel senamakel commented Oct 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

Add runtime-neutral run_native_shell orchestration over a caller-supplied transport, including resource/process reservation, create/start, cursor-based output collection, timeout and caller cancellation, cleanup, and a yield handoff for still-running processes. Add stable detected backend naming and Landlock availability detection, and derive JsonSchema for LocalGrantConfig.

Related issue

Closes #6
Part of tinyhumansai/openhuman#8369

API or behavior changes

Adds the NativeShellClient adapter trait and run_native_shell API. A running outcome retains its resource, process, cursor, and partial streams for host supervision. This adds no TinyBus connection or runtime dependency. LocalGrantConfig now implements JsonSchema; jail detection exposes stable backend and Landlock capability helpers. No wire contract members changed.

Validation

Commands actually run, with their outcome:

  • cargo fmt --all -- --check
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo build --all-targets --all-features
  • cargo test --all-features

Tests

Added coverage for output streaming, cursor advancement, cancellation and cleanup, resource cleanup on create failure, module-reported timeout output, running-process yield state, schema generation, backend naming, and Landlock detection. The existing module E2E tests requiring a built cdylib or live Docker/SSH fixtures remain ignored by their existing environment gates.

Documentation

Updated the tinybox-bus crate overview and public API rustdocs.

Checklist

  • The change is focused on one logical change
  • No new #[allow(...)], #[ignore], or relaxed lints
  • No secrets, tokens, or .env contents in the diff or the description

senamakel and others added 30 commits October 26, 2026 06:26
LocalGrantConfig now derives JsonSchema so OpenHuman config operations can
generate a schema from the shared contract type, with a test asserting the
schema is produced. The jail crate also gains helpers exposing the detected
backend name and whether Landlock is available.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…g test

The schema test now serializes the generated schema to JSON and checks for a
properties key instead of inspecting the schemars object directly, and returns
a Result so serialization failures surface as test errors.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a runtime-neutral native shell client that runs commands and polls
bounded output, exposed alongside the existing bus types. The helper
depends on futures-util and futures-timer so it works without pulling in
a specific async runtime.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The timeout was read from request.shell after the shell had been moved into
start_native_shell_exec, so the deadline now uses a value captured up front.
This keeps the timeout clamping behaviour unchanged while avoiding the
use-after-move.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The timed_out flag was previously derived from cancellation_requested, so
caller-initiated cancellations were reported as timeouts; a dedicated flag now
tracks only deadline expiry. Read errors and failed executions also release the
output stream before returning, and the Failed state no longer leaks it.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reworked the NativeShellClient trait to return boxed futures instead of
using async fn, so it can be used as a trait object, and added a Sync
bound. Also fixed the timeout flag being set on cancellation rather than
on the delay branch, and documented the Transport error fields.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Replace the tokio test attribute with a plain test that drives the async
body through futures_executor::block_on, adding futures-executor as a
dev-dependency. This removes the tokio runtime requirement from the
native shell test.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Output batches containing chunks but reporting a next sequence at or
before the current cursor are now treated as an error, with the process
cancelled and its output released before returning. Cleanup failures are
also preserved instead of being dropped when another operation is
already failing, so the original error is no longer lost.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reworked the select arms and the running-state branch to use unit patterns and an empty block, and added an allow attribute for the long run_native_shell function so the process lifecycle stays in one auditable scope. The mock client methods now await a ready future to keep them genuinely async, and a missing semicolon in the test closure was fixed.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Extend the mock client with failure and cancellation switches so the
native shell tests can exercise two cleanup paths. One test asserts that
cancellation reaps the process before releasing and closing, and the
other asserts that a failed create still releases the resource
reservation.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reformatted the mock client's cancel check and the transport error
assertion so they fit within the configured line width. No test
behaviour changed.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Handle the ExecutionState::Failed variant carrying ExecutionFailure::TimedOut
separately so a timed out command releases its output and returns a result with
timed_out set, instead of falling through to the generic failure arm and
surfacing as an execution error.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a yield_after option to the native shell request and return a
NativeShellRunOutcome that either reports a finished process or hands back a
running one with its resource, process reference, cursor, and output collected
so far. This lets callers take over the cleanup lifecycle of long-running
shells instead of always waiting for exit.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The native shell runner now returns a Running outcome carrying the process,
cursor, and captured output when a configured yield_after duration elapses,
instead of blocking until the command exits. This lets callers poll or resume
long-running commands without holding the request open indefinitely.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add tests for the module timeout path returning collected output as a
finished result and for yielding preserving the process resource, cursor
and partial output. The mock client gains timed-out and stays-running
states, and existing tests now unwrap the new run outcome type.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add the ExecutionFailure import to the native shell test module so the
tests can reference the failure type.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Wrap the TinyBox product name in backticks within the NativeShellRunOutcome
doc comment so rustdoc renders it as code.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The mock client's four independent boolean flags are collapsed into a single
MockBehavior enum, so each test now selects one named scenario instead of
setting every flag explicitly. This makes the intended state of each test
obvious and prevents contradictory combinations.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The yield deadline is now dropped when it is not shorter than the shell
timeout, and the elapsed clock starts before the process is created so
early setup time counts toward the yield. Output batches that arrive
alongside a terminal state are skipped before the yield check, and
cancellation takes precedence over yielding so a cancelled run is never
reported as still running.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The crate-level doc comment now notes that the crate also provides runtime-neutral native-shell lifecycle orchestration over a caller-supplied client, so the summary matches what the module actually offers.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The function no longer trips the too_many_lines lint, so the attribute and its
explanatory comment were removed to keep the code free of unnecessary
suppressions.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…achine

The native shell run loop was restructured into a dedicated state machine
that tracks the process lifecycle across polling, cancellation, and
timeout transitions. This makes the control flow easier to follow and
keeps the cleanup paths consistent when a run is interrupted or resumed.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…bility

Capture the process handle returned by start_native_shell so it can be
passed to collect_native_shell, and make the fused cancellation future
mutable where it is polled. The previous bindings left the process
unused and the cancellation stream immutable, which prevented the shell
from being collected and the cancellation branch from being polled.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The terminal-state match arms in the poll loop were folded into a new
finish_native_shell helper that releases output and returns the finished
capture, leaving the loop to handle only the running and yield cases. The
redundant continue statements after cancellation and timeout are gone since
those branches now fall through to the same yield check.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Extend the mock client with failure behaviors for reserve, start, read, cancel, release, and close, plus failed-execution and invalid-cursor cases, and add tests asserting these errors are reported and resources cleaned up.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a mock behavior that reports a failed execution and also fails on
close, and use it in the cleanup test so the primary error is checked
when both the execution and the subsequent close fail. The cancelled
state check no longer depends on a prior cancel call, since the mock
behavior alone determines the reported state.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
…anup failures

Extend the mock client with timed-out and invalid-cursor cleanup failure
behaviors so the read path can block until a cancel arrives. Add tests
asserting that a timeout cancels the process and returns the collected
output, and that cancel and release failures after an invalid cursor are
surfaced as cleanup errors.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The mock client now returns Running instead of Cancelled when a cancelled or timed out behavior is polled without a cancellation flag, so tests can distinguish a pending execution from a cancelled one.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a RunningStderr mock behavior that emits stderr chunks and reports
cancellation, then use it in a new test asserting that a poll loop which
never yields still accumulates stderr until the timeout fires.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The mock client's read counter now increments with wrapping_add instead of a plain addition, avoiding a potential overflow panic in long-running tests.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
senamakel and others added 6 commits October 26, 2026 06:56
… tests

Replace the inline `std::future::pending()`/`std::future::ready(())` and
`|_| {}` arguments in the native shell tests with the `never_cancel`,
`cancel_now`, and `ignore_chunk` helpers. This makes the intent of each
call site explicit and keeps the cancellation and output handling
consistent across the suite.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a never_cancel future that stays pending forever and a cancel_now
future that resolves immediately, giving tests deterministic control over
cancellation timing.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Convert several native shell tests to return Result instead of panicking
on unexpected outcomes, so failures surface as test errors rather than
aborts. The mock client's stderr stream selection now also covers the
invalid cursor behaviors, and poisoned call locks are handled explicitly.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The async blocks in the native shell tests now return a result and use the
question mark operator so that assertion failures inside them surface as test
errors instead of being silently discarded. The stdout emptiness check was
rewritten to compare the length against zero, which avoids a type inference
issue with the empty array literal.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The closure passed to the assertion helper now returns an explicit Result so its error type is inferred correctly, and the trailing semicolon was replaced with a `?` to propagate the result. This keeps the test compiling under the stricter type inference.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The cancellation test asserted an exact sequence of client calls, which
broke whenever unrelated calls were added around the reads. It now checks
the fixed prefix and only requires cancel to precede release and close.

Auto-committed-on: cuttlefish
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel merged commit 8a6ef31 into epic/8369-security-migration Oct 26, 2026
15 checks passed
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.

1 participant