# Nucleic fork of brush Vendored copy of [reubeno/brush](https://github.com/reubeno/brush), pinned at tag **`brush-shell-v0.4.0`** (upstream commit `96a26d0`), consumed by the `shell/` workspace to build **hash**, the Hydrangea agent shell ([docs/HYDRASHELL.md](../../docs/HYDRASHELL.md)). Every fork change is marked with a `// hydrashell:` comment. Current patches: | File | Change | | --- | --- | | `brush-shell/src/productinfo.rs` | `PRODUCT_NAME` → `hydrashell`; display string identifies the fork | | `brush-shell/src/args.rs` | usage/version strings rebranded | | `brush-core/src/prompt.rs` | `\$` (`PromptPiece::DollarOrPound`) renders the atom sign `⚛` (U+269B) for non-root instead of `$`; root still shows `#` | | `brush-core/src/expansion.rs` | corpus divergence D1: added `ExpansionPiece::LiteralText` — literal unquoted text is never field-split (bash splits only expansion results) but keeps glob characters active. Parameter-expansion substitutions (`${v:-word}` etc.) convert back to splittable at the expansion boundary; `ExpanderOptions.field_split_literal_text` lets data-string callers opt in. Upstream candidate. | | `brush-core/src/completion.rs` | `compgen -W` word list opts into `field_split_literal_text` (the -W string is data) | | `brush-shell/tests/cases/compat/ifs.yaml` | removed `known_failure` from 3 IFS tests the D1 fix repairs | | `brush-builtins/src/dot.rs` + `brush-shell/tests/cases/compat/builtins/dot.yaml` | the `.` / `source` builtin searches `PATH` for slashless operands when `sourcepath` is enabled, as Bash/POSIX require; fixes `git-subtree` sourcing `git-sh-setup` | | `brush-core/src/gate.rs` (new) + `lib.rs` | the `Gate` trait (docs/HYDRASHELL.md §4.2): process-global, verdict-shaped hook; allow-all default so an unconfigured shell behaves exactly like upstream | | `brush-core/src/commands.rs` | `SimpleCommand::execute` split into gate wrapper + `execute_inner`: `on_exec` before dispatch (Deny short-circuits), completion correlated through all three spawn-result variants | | `brush-core/src/processes.rs` | `ChildProcess.gate_token` + `on_exit` reporting from `wait()`/`poll()` (128+signal for signal deaths) | | `brush-shell/src/entry.rs` | `set_exit_hook` seam so hash can flush its event buffer before `process::exit` | | `brush-core/src/gate.rs` | M2 (docs/HYDRASHELL.md §5.2–5.3): `RedirectRecord`/`RedirectReadback` + `ExecStart.redirects` + `Gate::on_cmdsub` default hook | | `brush-core/src/interp.rs` | `ExecutionParameters.hydrashell_redirects` accumulator; `setup_redirect` records file (`>`,`>>`,`<`,`2>`,`&>`,`<>`), heredoc, and here-string redirects | | `brush-core/src/commands.rs` | gate wrapper drains `hydrashell_redirects` into `ExecStart` for post-run read-back | | `brush-core/src/expansion.rs` | command-substitution arm calls `gate().on_cmdsub` with the trimmed output | | `brush-core/src/gate.rs` | pipe tap (docs/HYDRASHELL.md §5.3): `PipeEvent` + `Gate::on_pipe` default hook + `is_active()`/`next_pipeline_id()` gating | | `brush-core/src/interp.rs` | `spawn_pipeline_processes` interposes a tee on each `a \| b` link when observation is active (`hydrashell_spawn_pipe_tee`): a copier thread mirrors a bounded prefix, preserving backpressure and SIGPIPE, reports before closing the write end. No tee on the unobserved fast path. | Verification (this container): brush compat suite `2067 ran: 1684 succeeded, 6 failed, 377 known to fail, 38 skipped` — the 6 failures are identical to a pristine `brush-shell-v0.4.0` baseline run (environmental: ANSI-C quote and `echo -e` oracle differences, syntax-error formatting, missing `hexdump`), i.e. zero fork-caused regressions; +3 successes vs baseline are the repaired IFS tests. hash corpus: 94/94. Planned (M3, per docs/HYDRASHELL.md / HYDRANGEAOS.md): image-side delivery — hash baked and forced on every Linux surface via hydrangeaOS. No further brush-core patches expected for M3; enforcement (`Hold`/`Deny` verdicts) remains post-M6. Updating: diff against the upstream tag, re-vendor, re-apply `// hydrashell:` patches (grep for the marker), then re-run `shell/corpus/replay.py` and the brush compat suite (`cargo test -p brush-shell --test brush-compat-tests`).