Last updated: 2026-05-24 — Cascade renumber to insert
PLAN_10_embedding.md(new) into the work-order queue, per ADR 0006. Mapping applied: old 10 (parser) → 11; old 11 (exec_phase_b) → 12; old 12 (traps_and_jobs) → 13; old 13 (line_editor) → 14; old 14 (prompt) → 15; old 15 (config) → 16; old 16 (nix) → 17; old 17 (ai) → 18; old 18 (milestones) → 19; old 19 (coproc) → 20; old 20 (gettext) → 21. PLAN_01–09 unchanged. New PLAN_10 = embedding (host contract from ADR 0006). "Renumbered from old PLAN_NN" annotations dropped from the planning table; cascade history lives only in this renumber log. Subtask IDs unchanged within each renamed doc. Historical Q-IDs preserved.Earlier on 2026-05-24: Work-order renumber of all PLAN documents to reflect actual execution sequence. Mapping applied: 06→06 (Phase A only); 07 spec_drafting (was 08); 08 fuzzer (was 09); 09 logging (NEW stub); 10 parser (NEW stub, absorbs old 06b.1 + 06b.2); 11 exec_phase_b (extracted from PLAN_06 §13 / temporary PLAN_06b); 12 traps_and_jobs (was 10); 13 line_editor (was 07); 14 prompt (was 11); 15 config (was 12); 16 nix (was 13); 17 ai (was 14); 18 milestones (was 15); 19 coproc (was 16); 20 gettext (NEW stub). PLAN_01–05 unchanged. Subtask IDs in PLAN_08 renumbered 09.N → 08.N; PLAN_11 retains
06b.N(continuity withtask-06b/branches); PLAN_12 renumbered 10.N → 12.N. Historical Q-IDs (Q06B.N, Q09.N, Q10.N) preserved across docs as immutable cross-references toQUESTIONS_for_review.md.Earlier on 2026-05-23: Full QUESTIONS_for_review.md question-walk complete: all 18 open questions resolved across Q-10-A..D, Q-08-A..D, Q-09-1..5, Q-06B-1..5. PLAN_19 stub added as the permanent owning document for
coproc(resolves Q-10-D / Q-06B-2); PLAN_12 §5.1 dispatch-asymmetry note (Q-10-B) and §6 notification-dispatch routing throughyield_terminal(Q-10-C / Q10.5) landed. PLAN_07 §2.2 addedutf8_localefeature category (~80 total sheets) covering UTF-8 correctness in v1; PLAN_18 row notes pending M-15-utf8-fuzz milestone scheduled between v1.0 and v1.1.Earlier on 2026-05-22: PLAN_11 (Phase B; then PLAN_06 §13) drafted: lexer/parser, executor pipeline,
ShellState, builtin inventory by owner, ADR 0004 two-stage sunset, 33-row subtask grid, five open questions Q06B.1–5. PLAN_13 scope augmented: ownshistory/fcbuiltins,yield_terminalprimitive (answers PLAN_12 Q10.5), and L4 PTY harness. PLAN_08 drafted (grammar-aware fuzzer + differential oracle, B-phase, gates PLAN_11 Phase B via 06b.0).Earlier on 2026-05-21: restructured PLAN numbering: PLAN_06a/06b collapsed into PLAN_06 (exec); old PLAN_13 narrowed to line editor; PLAN_07/09/10 introduced for spec drafting, fuzzer/differential, and traps+jobs; prompt/config/nix/ai/milestones shifted to 11/12/13/14/15. ADR 0004 (strict-default execution) added.
This is the top-level index of fredshell's planning documents. Read this first.
The actual design lives in the per-area PLAN_XX_*.md documents and the ADRs in
Documents/decisions/.
fredshell is an opinionated, batteries-included Rust shell intended as a daily-driver replacement for zsh on Linux and macOS. It is not a POSIX-only shell, not a "better bash," and not a structured-data shell in the nushell sense.
It aims to be:
- Bash-script compatible. Real-world bash scripts must run. Compatibility is
pursued via a native parser and in-process executor, not by shelling out to
/bin/sh. - Built-ins first. Common interactive commands (
ls,cat,du,df,which, plus all POSIX shell builtins) execute in-process. Fork/exec is reserved for genuinely external programs. - Pleasant by default. Starship-style prompt, fzf-style fuzzy history and
completion, lsd-style
ls, syntax highlighting, sensible keybindings — all baked in. No~/.zshrcarchaeology required. - Nix-native. First-class home-manager module; the shell, its config, and its plugins are managed declaratively.
- AI-augmented, optionally. Natural-language-to-command, error explanation, and command suggestion are available behind explicit opt-in with clear privacy boundaries.
It explicitly is not:
- A general-purpose programming language.
- A POSIX-conformant
/bin/sh. - A drop-in replacement for fish's syntax (we follow bash).
- A Windows shell.
See Documents/PLAN_01_philosophy.md for the full philosophy and non-goals.
Foundational decisions shape everything else and are recorded as ADRs:
- ADR 0001 — In-process execution and the builtin tier model. fredshell does
not shell out to
/bin/sh. Common externals are replaced by in-process builtins in a tiered model. SeeDocuments/decisions/0001-in-process-execution-and-builtin-tiers.md. - ADR 0002 — ANSI encoding crate strategy. fredshell ships its own
encoder-focused
fredshell-ansicrate rather than sharing freminal's decode- oriented escape-sequence types. Convergence is acknowledged as a future option. SeeDocuments/decisions/0002-ansi-encoding-crate-strategy.md. - ADR 0003 — Test-first compatibility methodology. Compatibility is
defined by an executable spec corpus, not prose. The harness lands before
the implementation and runs in CI from day one. Planning splits into
Phase A (corpus-independent docs) and Phase B (corpus-dependent docs).
See
Documents/decisions/0003-test-first-compatibility-methodology.md. - ADR 0004 — Strict-default execution.
ExecEnvdefaults to refusing to shell out to/bin/sh -cin both the binary REPL and the spec harness.FREDSHELL_ALLOW_SH_FALLBACK=1is a temporary escape hatch, removed before v1.0. SeeDocuments/decisions/0004-strict-default-execution.md.
| # | Document | Phase | Status | Summary |
|---|---|---|---|---|
| 01 | Documents/PLAN_01_philosophy.md |
A | draft | Goals, non-goals, target user, success criteria. |
| 02 | Documents/PLAN_02_architecture.md |
A | draft | Crate layout, module boundaries, key traits, dependency direction. |
| 03 | Documents/PLAN_03_ansi.md |
A | implemented | fredshell-ansi crate: encoder API, minimal decoder, Write-based contract, allocation budget. |
| 04 | Documents/PLAN_04_terminal_io.md |
A | implemented | Raw mode discipline, signals, process groups, terminal feature detection, kitty keyboard negotiation. |
| 05 | Documents/PLAN_05_testing.md |
A | implemented | Spec-test harness, corpus methodology, oils-spec integration, real-world script corpus, CI metrics. |
| 06 | Documents/PLAN_06_exec.md |
A | implemented | Execution pipeline, Phase A scaffold: public surface, dispatcher, ExecEnv, REPL/spec wiring. Phase B content extracted to PLAN_12. |
| 07 | Documents/PLAN_07_spec_drafting.md |
A | drafted | Spec sheet template (one per builtin + feature), batch-of-10 review cadence, lint extensions tying support rows to corpus cases. |
| 08 | Documents/PLAN_08_fuzzer.md |
B | drafted | Grammar-aware deterministic fuzzer + differential oracle against pinned bash 5.3p9. Five tiers (F1 PR → F5 release gate). Gates PLAN_12 Phase B via 06b.0 = "F1 green on main." |
| 09 | Documents/PLAN_09_logging.md |
A | stub | Structured logging via tracing + tracing-subscriber. Bans println!/eprintln!/dbg! in library crates and the fredshell binary. Defines log levels, target conventions, and the diagnostics sink contract. |
| 10 | Documents/PLAN_10_embedding.md |
A | stub | fredshell-core embeddability contract per ADR 0006: Shell handle, async Stream of typed ShellEvents, runtime-agnostic core, no fd writes from core. Owns PTY ownership model and the binary REPL refactor. |
| 11 | Documents/PLAN_11_parser.md |
B | stub | In-house recursive-descent bash parser (fredshell-parser). Owns lexer, AST/CST, error recovery for incremental parsing, refusal taxonomy. Absorbs old 06b.1 (ADR 0005) and 06b.2 (lexer/parser scaffold). |
| 12 | Documents/PLAN_12_exec_phase_b.md |
B | drafted | Execution pipeline Phase B: real semantics, ShellState, Tier-1 builtins, expansion family, ADR 0004 sunset. Extracted from PLAN_06 §13 / temporary PLAN_06b. Subtask grid retains 06b.N for task-06b/ continuity. |
| 13 | Documents/PLAN_13_traps_and_jobs.md |
B | drafted | Signal traps, job control, wait, kill, foreground/background. Corpus-dependent because trap semantics differ from POSIX in well-defined ways. |
| 14 | Documents/PLAN_14_line_editor.md |
A | drafted | Line editor: key-byte decoder, history, completion, fuzzy search, keybindings, syntax highlighting. Owns history/fc builtins, the yield_terminal primitive consumed by PLAN_13, and the L4 PTY harness. |
| 15 | Documents/PLAN_15_prompt.md |
A | draft | Starship-style prompt renderer, configuration model, performance budget. |
| 16 | Documents/PLAN_16_config.md |
A | draft pending | Config file format, layering, env vars, rc-file semantics. |
| 17 | Documents/PLAN_17_nix_integration.md |
A | draft pending | Home-manager module surface, flake outputs, default-shell story. |
| 18 | Documents/PLAN_18_ai_features.md |
A | draft pending | NL→command, error explanation, provider abstraction, privacy boundaries. |
| 19 | Documents/PLAN_19_milestones.md |
B | stub pending | Phased roadmap: MVP → daily-driver → bash-replacement. Corpus-dependent. Pending entries: M-15-utf8-fuzz — UTF-8 differential-fuzz tier (F2-utf8) scheduled between v1.0 and v1.1 per PLAN_08 §11 Q09.5. |
| 20 | Documents/PLAN_20_coproc.md |
post-v1 | stub | Coprocesses (coproc). Cuts across PLAN_11 parser, PLAN_12 executor, PLAN_13 jobs, PLAN_02 variables. v1 recognises and refuses; full implementation deferred. |
| 21 | Documents/PLAN_21_gettext.md |
A | stub | Internationalisation strategy: gettext-style message catalogues for diagnostic messages, error explanations, and AI-facing prompts. Locale negotiation, fallback chain, catalogue compilation in build. |
Planning proceeds in two phases:
-
Phase A drafts the docs whose content does not depend on knowing what bash scripts in the wild actually do. These are the architecture-shaped docs: testing methodology (PLAN_05), crate layout (PLAN_02), foundational subsystems (PLAN_03, PLAN_04), spec-drafting workflow (PLAN_07), logging (PLAN_09), embedding contract (PLAN_10), line editor (PLAN_14), prompt (PLAN_15), config (PLAN_16), nix integration (PLAN_17), AI features (PLAN_18), and gettext (PLAN_21). PLAN_05 (testing) is intentionally drafted before PLAN_02 (architecture) because the spec-test harness imposes hard constraints on the architecture (parser separable from executor, sandboxable execution environment, clean batch-mode entry point).
-
Phase B drafts the docs whose content is informed by the spec corpus once it exists: the fuzzer/differential (PLAN_08), the parser (PLAN_11), Phase B of the executor (PLAN_12), traps+jobs (PLAN_13), and the implementation roadmap (PLAN_19). These carry "stub pending" status during Phase A and receive full drafts only after the v1 corpus has been curated and the harness reports a baseline pass-rate. PLAN_06 (Phase A executor scaffold) is the foundation those Phase B docs build on.
The rationale and methodology are pinned in ADR 0003.
| ID | Title | Status |
|---|---|---|
| 0001 | In-process execution and the builtin tier model | accepted |
| 0002 | ANSI encoding crate strategy | accepted |
| 0003 | Test-first compatibility methodology | accepted |
| 0004 | Strict-default execution | accepted |
| 0006 | fredshell-core embeddable library contract |
accepted |
New ADRs are added as significant design questions are resolved. ADRs are immutable once accepted; superseding decisions get new ADRs that link back.
- Each planning document gets its own commit (or small set of commits) on a topic branch, reviewed iteratively.
- Implementation work for each plan section happens on its own task branch
(
task-NN/<topic>), perAGENTS.md. plan.mdis updated whenever a planning document changes status (draft → accepted → implementing → done) or a new document/ADR is added.
These are unresolved as of this draft and will be addressed by the relevant planning document or ADR:
- Choice of native bash parser: adopt
brush-parser, fork, or write our own. Resolved (2026-05-23): in-house recursive-descent. ADR 0005 to be authored in PLAN_12 subtask 06b.1; implementation owned byPLAN_11(parser). - Line-editor library: build on
reedline/rustyline, or roll our own on top ofcrossterm/termwiz(deferred toPLAN_14). - Async runtime: required for AI features and background jobs, optional
elsewhere — scope to be decided in
PLAN_02andPLAN_18. - Plugin/extension model: out of scope for v1, but the architecture must not preclude it.
Numbered cleanup entries for bugs surfaced during planning work that fall outside the surfacing subtask's scope. Each entry stays here until resolved or migrated to its owning PLAN doc.
- Surface point. Cascade-renumber commit on branch
docs/work-order-renumber(the commit that lands the PLAN_10 embedding insertion and cascades old PLAN_10..20 → new PLAN_11..21). - Impact. Two planning documents contain cross-references that point
to the wrong PLAN by name:
Documents/PLAN_14_line_editor.md— top-blockquote "Consumed by" line ends withPLAN_13 (config). Config is PLAN_16 post-cascade; the line should readPLAN_16 (config). The bug predates the cascade (pre-cascade saidPLAN_12 (config), also wrong — config was PLAN_15 at that time).Documents/PLAN_15_prompt.md— top-blockquote "Consumed by" line ends withPLAN_13 (config), PLAN_15 (AI segments, optional). Config is PLAN_16; AI is PLAN_18. The line should readPLAN_16 (config), PLAN_18 (AI segments, optional). Body prose (§3.2, §4.5, §10.1, §11.5, etc.) also referencesPLAN_15andPLAN_14in places where the intended target is the AI features doc (PLAN_18) or the line-editor doc (PLAN_14); a fuller audit is required to enumerate every site.
- Scope of fix. Two documents —
PLAN_14_line_editor.mdandPLAN_15_prompt.md. Cross-references only; no behavioural or structural changes. Audit everyPLAN_NNreference in the body of both docs and remap to the semantically intended target, using the parenthetical hint ((config),(AI segments), etc.) as the authority. - Suggested approach. Build a small inventory table mapping each
current
PLAN_NN (hint)reference to the intended PLAN number based on the current planning table inplan.md. Apply edits manually (the cascade-sweep tooling is by-number-only and cannot resolve semantic intent). Append a renumber-log entry to each doc noting the semantic-fix pass (distinct from the cascade pass). - Verification criteria.
rg -n '\bPLAN_(14|15|16|18)\b' Documents/PLAN_14_line_editor.md Documents/PLAN_15_prompt.mdreturns no stale references when paired with their parenthetical hints.- The audit table is recorded in the commit message or in a short note appended to each doc's renumber-log entry.
- No other PLAN doc is modified (single-purpose commit).
- Scheduling constraints. Independent — does not block any PLAN-XX task. Should be fixed before PLAN_14 (line editor) or PLAN_15 (prompt) implementation work starts, so implementers do not chase the wrong doc. No earlier task depends on this fix.