Bounded I/O: UTF-8-safe truncation, bounded subprocess runner, line-framed JSON stream reader
| Tier | foundation |
| Role | unclassified (baselined) |
| Path | crates/foundation/bounded-io |
| Edition | 2021 |
| Targets | foundation_bounded_io |
| Public items | 20 across 2 modules |
| Tests | 47 |
What it is for
Bounded I/O sub-primitives (sprint 1.0.1 T-1.0.1a-0; HARVEST-BACKLOG rows 25/26/28).
Three fail-loud building blocks, each previously hand-rolled per site:
truncate_utf8_bounded— byte-cap without splitting a UTF-8 codepoint
(lifted from infrastructure-ai/src/claude_cli.rs).
exec(featureexec) — arg-vector subprocess with wall-clock timeout
and per-stream byte caps; PROCESS §17 invariants in one place.
jsonl(featurejsonl) — line-framed JSON reader with per-line byte
cap, read timeout, and a typed malformed-line error.
Capabilities
BoundedCommand
Bounded subprocess runner (HARVEST-BACKLOG row 25).
| Item |
|---|
pub struct BoundedCommand |
BoundedCommand :: fn new(bin : impl Into <PathBuf>, limits : ExecLimits) -> Self |
BoundedCommand :: fn arg(mut self, a : impl Into <String>) -> Self |
BoundedCommand :: fn stdin_bytes(mut self, b : Vec <u8>) -> Self |
BoundedCommand :: fn current_dir(mut self, dir : impl Into <PathBuf>) -> Self |
BoundedCommand :: fn env_clear(mut self) -> Self |
BoundedCommand :: fn env(mut self, key : impl Into <String>, value : impl Into <String>) -> Self |
BoundedCommand :: fn uid(mut self, uid : u32) -> Self |
BoundedCommand :: fn gid(mut self, gid : u32) -> Self |
BoundedCommand :: fn run_sync(self) -> Result <ExecOutput, ExecError> |
BoundedCommand :: async fn run(self) -> Result <ExecOutput, ExecError> |
ExecError
Bounded subprocess runner (HARVEST-BACKLOG row 25).
| Item |
|---|
pub enum ExecError |
ExecLimits
Bounded subprocess runner (HARVEST-BACKLOG row 25).
| Item |
|---|
pub struct ExecLimits |
ExecOutput
Bounded subprocess runner (HARVEST-BACKLOG row 25).
| Item |
|---|
pub struct ExecOutput |
JsonLines
Line-framed JSON stream reader (HARVEST-BACKLOG row 28).
| Item |
|---|
pub struct JsonLines<R> |
JsonLines<R>
Line-framed JSON stream reader (HARVEST-BACKLOG row 28).
| Item |
|---|
JsonLines<R> :: fn new(reader : R, max_line_bytes : usize, read_timeout : Duration) -> Self |
JsonLines<R> :: fn line_index(& self) -> usize |
JsonLines<R> :: async fn next_line(& mut self) -> Result <Option <Vec <u8>>, JsonlError> |
JsonLines<R> :: async fn next_value(& mut self) -> Result <Option <serde_json::Value>, JsonlError> |
JsonlError
Line-framed JSON stream reader (HARVEST-BACKLOG row 28).
| Item |
|---|
pub enum JsonlError |
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
foundation_bounded_io
execjsonl
flowchart TD n_foundation_bounded_io["foundation_bounded_io"] n_foundation_bounded_io --> n_exec["exec"] n_foundation_bounded_io --> n_jsonl["jsonl"]
Public surface
`exec`
| Item | What it is |
|---|---|
pub struct ExecLimits | Limits applied to a single run |
pub struct ExecOutput | Captured result of a bounded run that exited zero within its limits. |
pub enum ExecError | Every way a bounded run fails |
pub struct BoundedCommand | A bounded subprocess invocation: explicit binary, argument vector, limits. |
BoundedCommand :: fn new(bin : impl Into <PathBuf>, limits : ExecLimits) -> Self | — |
BoundedCommand :: fn arg(mut self, a : impl Into <String>) -> Self | — |
BoundedCommand :: fn stdin_bytes(mut self, b : Vec <u8>) -> Self | Bytes written to the child's stdin before reading output |
BoundedCommand :: fn current_dir(mut self, dir : impl Into <PathBuf>) -> Self | Working directory for the child |
BoundedCommand :: fn env_clear(mut self) -> Self | Drop the caller's own environment before applying .env() calls, so the child sees exactly what was configured — never an implicit inheritance a caller didn't ask for |
BoundedCommand :: fn env(mut self, key : impl Into <String>, value : impl Into <String>) -> Self | — |
BoundedCommand :: fn uid(mut self, uid : u32) -> Self | Run the child as this uid (std::os::unix::process::CommandExt — no unsafe code needed) |
BoundedCommand :: fn gid(mut self, gid : u32) -> Self | — |
BoundedCommand :: fn run_sync(self) -> Result <ExecOutput, ExecError> | run without a runtime: std threads drain the two pipes under the cap while the caller's thread polls the child against the wall clock |
BoundedCommand :: async fn run(self) -> Result <ExecOutput, ExecError> | Run to completion within the limits |
`jsonl`
| Item | What it is |
|---|---|
pub enum JsonlError | — |
pub struct JsonLines<R> | Bounded reader over newline-delimited JSON. |
JsonLines<R> :: fn new(reader : R, max_line_bytes : usize, read_timeout : Duration) -> Self | — |
JsonLines<R> :: fn line_index(& self) -> usize | Physical 0-based line number of the line most recently returned by Self::next_line/Self::next_value or reported in an error |
JsonLines<R> :: async fn next_line(& mut self) -> Result <Option <Vec <u8>>, JsonlError> | Next raw line as ORIGINAL bytes (terminator trimmed), bounded by the same content cap and timeout as Self::next_value |
JsonLines<R> :: async fn next_value(& mut self) -> Result <Option <serde_json::Value>, JsonlError> | Next parsed line: Ok(Some(value)), Ok(None) at clean EOF, or a typed error. |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
truncate_utf8_bounded | truncate::truncate_utf8_bounded |
{PathError,PathGuard,PathGuardSet} | pathguard::{PathError,PathGuard,PathGuardSet} |
Boundary
Depends on no other workspace tier.
Shares tier foundation with 27 other crates: foundation-audit-log, foundation-basemodels, foundation-conversation-closure, foundation-crypto-sign, foundation-decisioning, foundation-encounter-vocabulary, foundation-fs-metadata, foundation-i18n, … (27 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | foundation |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/foundation/bounded-io |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
serde_json | ^1 | — | yes | always |
thiserror | ^2 | — | no | always |
tokio | ^1 | process, io-util, time, rt, macros | yes | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
serde_json | ^1 | — | no | always |
tokio | ^1 | full | no | always |
Build. None.
Depended on by. 24 workspace crates.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_application_wiki["application-wiki"] -->|uses| SELF n_infrastructure_agent["infrastructure-agent"] -->|uses| SELF n_infrastructure_ai["infrastructure-ai"] -->|uses| SELF n_infrastructure_doc_ingest["infrastructure-doc-ingest"] -->|uses| SELF n_infrastructure_firmware_forensics["infrastructure-firmware-forensics"] -->|uses| SELF n_infrastructure_memory_forensics["infrastructure-memory-forensics"] -->|uses| SELF n_infrastructure_registry_forensics["infrastructure-registry-forensics"] -->|uses| SELF n_infrastructure_write_blocker["infrastructure-write-blocker"] -->|uses| SELF n_operations_block_imaging["operations-block-imaging"] -->|uses| SELF n_operations_boot_media["operations-boot-media"] -->|uses| SELF n_operations_control_plane["operations-control-plane"] -->|uses| SELF n_operations_net_scan["operations-net-scan"] -->|uses| SELF n_operations_net_trace["operations-net-trace"] -->|uses| SELF n_platform_disclosure_lab["platform-disclosure-lab"] -->|uses| SELF n_tools_book_report["tools-book-report"] -->|uses| SELF n_tools_corpus["tools-corpus"] -->|uses| SELF n_tools_fleet_reconnect["tools-fleet-reconnect"] -->|uses| SELF n_tools_githooks["tools-githooks"] -->|uses| SELF n_tools_imp["tools-imp"] -->|uses| SELF n_tools_local_model_import["tools-local-model-import"] -->|uses| SELF n_tools_manual["tools-manual"] -->|uses| SELF n_tools_prompt_shaper["tools-prompt-shaper"] -->|uses| SELF n_tools_research_sweep["tools-research-sweep"] -->|uses| SELF n_tools_target_sweep["tools-target-sweep"] -->|uses| SELF SELF["foundation-bounded-io"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
| Feature | Enables | On by default |
|---|---|---|
default | — | yes |
exec | dep:tokio | no |
exec-sync | — | no |
jsonl | dep:tokio, dep:serde_json | no |
flowchart LR n_default["default"] n_exec["exec"] --> n_dep_tokio["dep:tokio"] n_exec_sync["exec-sync"] n_jsonl["jsonl"] --> n_dep_tokio["dep:tokio"] n_jsonl["jsonl"] --> n_dep_serde_json["dep:serde_json"]
Targets
| Kind | Name | Source |
|---|---|---|
| lib | foundation_bounded_io | `src/lib.rs` |
Error model
| Error type | Named by |
|---|---|
ExecError | declared, no public signature returns it |
JsonlError | declared, no public signature returns it |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | yes |
| async runtime | yes |
| database access | none detected |
| network I/O | none detected |
| unsafe code | yes |
| environment variables | none detected |
Unsafe code.
| Site | Source |
|---|---|
unsafe block | src/exec.rs |
unsafe fn libc_getuid | src/exec.rs |
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
24 workspace crates depend on this one: application-wiki, infrastructure-agent, infrastructure-ai, infrastructure-doc-ingest, infrastructure-firmware-forensics, infrastructure-memory-forensics, infrastructure-registry-forensics, infrastructure-write-blocker, operations-block-imaging, operations-boot-media, operations-control-plane, operations-net-scan, … (24 total).
Verification
| Kind | Count |
|---|---|
| Unit tests | 47 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
exec | 4 | 0 | 45 |
jsonl | 2 | 0 | 4 |
What the tests establish, by name:
current_dir_is_respected—src/exec.rscurrent_dir_is_respected—src/exec.rsecho_within_limits_succeeds—src/exec.rsecho_within_limits_succeeds—src/exec.rsenv_clear_then_env_yields_exactly_the_configured_vars—src/exec.rsenv_clear_then_env_yields_exactly_the_configured_vars—src/exec.rsmissing_binary_is_spawn_error—src/exec.rsmissing_binary_is_spawn_error—src/exec.rsnonzero_exit_is_error_with_captured_stderr—src/exec.rsnonzero_exit_is_error_with_captured_stderr—src/exec.rsstdin_reaches_child—src/exec.rsstdin_reaches_child—src/exec.rsstdout_overflow_kills_and_types—src/exec.rsstdout_overflow_kills_and_types—src/exec.rstimeout_kills_and_types—src/exec.rstimeout_kills_and_types—src/exec.rsuid_matching_current_user_still_succeeds—src/exec.rswithout_env_clear_parent_env_still_inherited—src/exec.rscrlf_line_of_exactly_max_content_is_accepted—src/jsonl.rsline_index_tracks_physical_lines_including_blanks_and_over_cap—src/jsonl.rsmalformed_line_is_typed_error_with_bounded_snippet—src/jsonl.rsmalformed_snippet_is_bounded_even_after_lossy_expansion—src/jsonl.rsnext_line_returns_original_bytes_and_interleaves_with_next_value—src/jsonl.rsover_cap_final_line_without_newline_drains_to_eof—src/jsonl.rsover_cap_line_is_fully_drained_and_framing_recovers—src/jsonl.rsover_cap_line_is_typed_error—src/jsonl.rsover_cap_line_larger_than_one_drain_chunk_is_fully_consumed—src/jsonl.rsreads_values_then_clean_eof—src/jsonl.rsskips_empty_lines—src/jsonl.rsstalled_stream_times_out—src/jsonl.rs- _… 17 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 14 | 20 |
Public modules with a //! block | 2 | 2 |
pie showData
title Public items with rustdoc
"Documented" : 14
"No rustdoc detected" : 6
Metrics
| Metric | Value |
|---|---|
| Rust source files | 5 |
| Source lines | 1425 |
| Code lines | 1138 |
| Public API items | 20 |
| Public modules | 2 |
| Tests | 47 |
| Examples | 0 |
| Cargo features | 4 |
| Direct runtime dependencies | 3 |
| Workspace reverse dependencies | 24 |
pie showData
title Public API by kind
"enum" : 2
"method" : 14
"struct" : 4
pie showData
title Rust source composition
"Code" : 1138
"Blank or comment" : 287
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.