# Fresh — System Capability Analysis

This document answers the core design question: **what set of operations that actually touch the
operating system does Fresh need in order to be a sufficiently powerful build/install scripting
language — while staying simple?**

The approach is to (1) inventory what real build/install/deploy scripts *do* to the system, (2)
distill that into a minimal set of runtime primitives, (3) wrap each primitive in a "just works"
guarantee, and (4) assign each primitive to a release phase so v0.1 stays tiny.

---

## 1. What these scripts actually do to a system

Surveying typical `build.sh` / `install.sh` / `deploy.sh` scripts (including the Dtracker example),
every meaningful line falls into one of a small number of categories:

| # | Category | Real-world examples | Frequency |
|---|----------|---------------------|-----------|
| 1 | **Run a process** | `mvn package`, `npm ci`, `cargo build`, `rm target/*.jar` | Every script |
| 2 | **Move / copy files** | stage a jar, `scp` an artifact, back up a config | Most scripts |
| 3 | **Create directories** | `mkdir -p out/`, ensure a dest exists before writing | Most scripts |
| 4 | **Delete files / dirs** | `rm -rf build/`, clean stale artifacts | Most scripts |
| 5 | **Substitute values** | inject `$VERSION`, `$HOST`, `$NAME` into commands/paths | Most scripts |
| 6 | **Change directory** | run a build in a subproject folder | Common |
| 7 | **Read / set environment** | `MAVEN_OPTS`, `PATH`, `NODE_ENV` | Common |
| 8 | **Expand globs** | `*.jar`, `dist/**/*.js` | Common |
| 9 | **Branch on a condition** | `--fast` skips clean; skip step if file missing | Common |
| 10 | **Compose tasks** | `bd` = `build` then `deploy` | Common |
| 11 | **Parse arguments** | `--name`, `--debug`, `--host` | Common |
| 12 | **Operate on a remote host** | `ssh`, `scp`, `rsync` to a deploy target | Deploy scripts |
| 13 | **Fan out over a set** | build for {linux, mac} × {amd64, arm64} (matrix) | CI-style scripts |
| 14 | **Print / log** | status messages, tailing a log | Common |

That's the entire universe. Notably, categories 1–8 and 14 cover the overwhelming majority of
*lines* in real scripts; 9–13 are where complexity (and Bash pain) explodes.

---

## 2. The minimal runtime primitive set

Reduced to primitives the interpreter must implement, the surface is remarkably small. These are
the OS-facing capabilities — the "system layer" of Fresh.

### Tier A — the irreducible core (must exist to be useful at all)

- **P1. Process execution.** Spawn a child process from a command line, stream its stdout/stderr,
  wait for it, and capture the exit code. Tokenizing the command line into `argv` and applying
  variable substitution is part of this primitive.
- **P2. Filesystem write with auto-parenting.** Copy or move a source path to a destination,
  automatically creating any missing parent directories. This single guarantee eliminates the most
  common Bash boilerplate.
- **P3. Variable resolution.** A flat namespace of `KEY=value` strings, interpolated into commands
  and paths as `$KEY` / `${KEY}`.

With just P1–P3 you can express "run a predefined command and move a file" — the stated v0.1 goal.

### Tier B — the practical core (needed for real scripts)

- **P4. Directory creation** (`MKDIR`) — recursive, idempotent (never errors if it exists).
- **P5. Deletion** (`REMOVE`) — files and directories, idempotent, glob-aware.
- **P6. Glob expansion** — resolve `*`, `**`, `?` against the filesystem before an operation runs.
- **P7. Working-directory control** — run a task or a step from a chosen directory.
- **P8. Environment injection** — set/pass env vars to spawned processes.
- **P9. Structured output** — `PRINT`/`ECHO` and consistent, colorized status lines per step.

### Tier C — the power layer (opt-in, higher phases)

- **P10. Argument parsing** — declared parameters become `--flags` with defaults and validation.
- **P11. Conditionals** — run/skip a step or task based on a flag or a file's existence.
- **P12. Task composition** — one task invokes others (e.g. `bd` → `build` + `deploy`).
- **P13. Remote transport** — `ssh`-style command execution and `scp`/`rsync`-style transfer,
  with the same auto-parenting and substitution guarantees applied remotely.
- **P14. Set expansion (matrix) & parallelism** — cartesian product of value lists, executed
  serially or concurrently.

---

## 3. The "just works" guarantee layer

The differentiator is not the primitive list — it's the invariants the runtime enforces on top of
every primitive, so the script author never writes defensive code.

| Guarantee | What the runtime does | Bash equivalent it replaces |
|-----------|----------------------|-----------------------------|
| **No permission management** | Scripts run through the `fresh` interpreter; there is no exec bit. File ops use sane default modes (respecting umask) and never require `chmod`. | `chmod +x`, `chmod 644`, `chown` |
| **Destinations always exist** | Any write/copy/move creates parent directories first. | `mkdir -p "$(dirname "$dst")"` before every copy |
| **Fail-fast by default** | A non-zero exit stops the task and reports which step failed. | `set -euo pipefail` |
| **Predictable quoting** | Arguments are tokenized once by Fresh; no double-expansion surprises. | manual `"$var"` quoting everywhere |
| **Idempotent housekeeping** | `MKDIR` on an existing dir and `REMOVE` on a missing path succeed quietly. | `mkdir -p`, `rm -f`, existence guards |
| **Deterministic env** | Only declared variables and inherited env are visible; no accidental globals. | careful `unset` / subshell discipline |
| **Dry-run** | `--dry-run` prints the exact operations without executing them. | hand-rolled `echo` shims |
| **Self-documenting** | Every task auto-registers as a subcommand with generated `help`. | hand-written `case` + `usage()` |

---

## 4. How the runtime is structured

The interpreter is a thin layer over the OS, organized as small, independently testable modules:

```
                    ┌─────────────────────────────────────┐
   fresh script ──► │  Parser  (line-oriented, indented)   │
                    └───────────────────┬─────────────────┘
                                        ▼
                    ┌─────────────────────────────────────┐
                    │  Task registry + CLI dispatcher      │  ← auto help, subcommands
                    └───────────────────┬─────────────────┘
                                        ▼
                    ┌─────────────────────────────────────┐
                    │  Variable / interpolation resolver   │  (P3, P8, P10)
                    └───────────────────┬─────────────────┘
                                        ▼
          ┌──────────────── System Capability Layer ───────────────┐
          │  Process runner (P1)   Filesystem ops (P2,P4,P5)         │
          │  Glob engine (P6)      Workdir/env (P7,P8)               │
          │  Remote transport (P13)   Scheduler/matrix (P14)         │
          └─────────────────────────────────────────────────────────┘
                                        ▼
                              Operating System
```

Design notes:

- **Cross-platform from day one.** Filesystem and process primitives are implemented against a
  portable standard library (a Go or Rust binary is the recommended reference implementation), so
  the same script runs on Linux, macOS, and Windows without shell-specific quirks.
- **Single static binary.** `fresh` ships as one dependency-free executable — installing the
  language is copying one file onto `PATH`. This reinforces "just works."
- **The system layer is the contract.** Everything above it (parser, CLI, help) is convenience;
  everything below it is the OS. Keeping that boundary crisp is what lets the language stay small
  while the capability set grows.

---

## 5. Conclusion: the sufficient feature set

To be **sufficiently powerful** for build/install/clean/run/deploy work while staying **simple**,
Fresh needs exactly these system capabilities, and no more:

- **Absolute minimum (v0.1):** P1 (run a process), P2 (move/copy with auto-parenting), P3
  (variables). — *"run a command and move a file."*
- **Genuinely useful tool (v1.0):** add P4–P9 (mkdir, remove, globs, workdir, env, output) plus
  auto-subcommands and generated help.
- **Full-strength (v2+):** add P10–P14 (params, conditionals, composition, remote, matrix) —
  each opt-in, none taxing the simple case.

The remainder of the proposal ([LanguageSpecification.md](LanguageSpecification.md) and
[PhasedRoadmap.md](PhasedRoadmap.md)) turns this capability set into concrete syntax and a phased
delivery plan.
