# Fresh — Phased Roadmap

Fresh is delivered in phases that each add a coherent slice of capability *without* adding weight
to the simple case. Every phase is independently useful and shippable. The primitives referenced
(P1–P14) are defined in [SystemCapabilityAnalysis.md](SystemCapabilityAnalysis.md).

The guiding rule: **the "run one command and move a file" script must look identical in v0.1 and in
v5.** New power is always opt-in.

---

## Phase 0 — v0.1 "Spark" (Minimum Viable Fresh)

*Goal: prove the model with the smallest thing that is genuinely useful.*

**Capabilities:** P1 (run a process), P2 (copy/move with auto-parenting), P3 (variables).

**Language surface:**
- `#!` shebang, `#` comments
- `NAME`, `HELP_DESCRIPTION` metadata
- `KEY = value` variables + `$VAR` / `${VAR}` interpolation
- `DEF <task>` blocks → auto-exposed subcommands
- `RUN <command>` — run a predefined system command
- `COPY <src> <dst>` and `MOVE <src> <dst>` — parents auto-created
- Auto-generated `help` listing all tasks

**Explicitly out of scope:** flags/params, conditionals, globs, composition, remote, matrix.

**Example that fully exercises v0.1:**

```fresh
#!/usr/bin/env fresh
NAME Tiny Deployer
VERSION = 1.4.0

DEF release
    RUN mvn package
    MOVE target/app-$VERSION.jar dist/app.jar
```

**Definition of done:** `fresh release` builds and moves the artifact; `fresh help` lists
`release`; no `chmod`, no `mkdir` needed. Single static binary installs by copy.

---

## Phase 1 — v1.0 "Toolbelt" (a real, everyday tool)

*Goal: cover the full common case of local build/clean/install scripts.*

**Adds:** P4 `MKDIR`, P5 `REMOVE`, P6 glob expansion, P7 `CD`, P9 `PRINT`, plus the polished CLI.

**Language surface (new):**
- `MKDIR`, `REMOVE` (idempotent, recursive)
- Glob expansion (`*.jar`, `dist/**`) in `COPY`/`MOVE`/`REMOVE`
- `CD` working-directory control per task
- `PRINT` status messages
- `HELP <text>` per-task descriptions
- Multi-source `COPY a b c dest/`
- Global flags: `--dry-run`, `--verbose`, `--help`

**Milestone:** the Dtracker tool's `clean`/`build`/`deploy`/`watchlogs` all express cleanly (see
[LanguageSpecification.md §9](LanguageSpecification.md)). This is the first "recommend it to a
friend" release.

---

## Phase 2 — v1.5 "Dials" (parameters & flags)

*Goal: kill the hand-written argument parser — the single biggest source of Bash boilerplate.*

**Adds:** P10 argument parsing, P8 environment control.

**Language surface (new):**
- `PARAM name = default` — declares a `--name` option with an optional default; reference as `$name`
- `FLAG debug` — declares a boolean `--debug`; reference as `$debug` (true/false)
- `REQUIRE name` — marks a param mandatory with a clean error if missing
- `ENV KEY = value` — set environment for spawned processes
- Auto-generated per-task help now lists each param/flag and its default

```fresh
DEF build
    PARAM name = dtracker
    FLAG  fast
    HELP  Build the extension.
    REMOVE $name/target/*.jar
    RUN mvn package
```

```bash
$ fresh build --name widgets --fast
$ fresh build help      # lists --name (default dtracker) and --fast
```

---

## Phase 3 — v2.0 "Assembly" (composition, conditionals, remote)

*Goal: express multi-step and deploy workflows without dropping to Bash.*

**Adds:** P11 conditionals, P12 task composition, P13 remote transport.

**Language surface (new):**
- `CALL <task>` — invoke another task (incl. private `_tasks`), sharing params
- `IF <cond>` / `UNLESS <cond>` / `ELSE` — branch on a flag or file existence
  (`IF $fast`, `IF EXISTS build/`, `UNLESS $skip_tests`)
- `ALLOW_FAIL` / `ONFAIL <task>` — controlled exceptions to fail-fast
- `SSH <user>@<host> <command>` — run a remote command
- `UPLOAD <local> <user>@<host>:<remote>` / `DOWNLOAD ...` — transfer with remote auto-parenting

```fresh
DEF bd
    HELP Build then deploy.
    CALL build
    CALL deploy

DEF deploy
    PARAM host = 192.168.1.234
    PARAM user = dedrone
    UPLOAD target/*.jar $user@$host:extensions/
```

---

## Phase 4 — v2.5 "Fan-out" (matrix & parallelism)

*Goal: the Jenkins-style perpendicular-list expansion, made trivial.*

**Adds:** P14 set expansion + concurrency.

**Language surface (new):**
- `MATRIX name = a b c` — declares an axis; multiple `MATRIX` lines form a cartesian product
- The task body runs once per combination, with each axis bound as `$name`
- `PARALLEL <n>` — run up to `n` combinations concurrently (default: serial)
- `FOREACH item IN <list>` — simple iteration for non-matrix loops

```fresh
DEF release
    MATRIX os   = linux mac windows
    MATRIX arch = amd64 arm64
    PARALLEL 3
    RUN ./package.sh --os $os --arch $arch      # 6 combinations, 3 at a time
```

---

## Phase 5 — v3.0 "Ecosystem" (scale & reuse)

*Goal: share and compose Fresh across projects and teams.*

**Adds (beyond the OS layer — tooling & DX):**
- `INCLUDE <file>` / importable task libraries (shared `clean`/`deploy` recipes)
- A small standard library of vetted tasks (archive, checksum, template-render)
- `fresh init` scaffolding, `fresh fmt` formatter, `fresh check` linter
- Editor support (LSP): completion, hover help, go-to-task
- Shell completion generation for the auto-CLI
- Structured/JSON output mode for CI integration and `--dry-run` plans

---

## At-a-glance capability matrix

| Capability | v0.1 | v1.0 | v1.5 | v2.0 | v2.5 | v3.0 |
|-----------|:----:|:----:|:----:|:----:|:----:|:----:|
| Run system command (`RUN`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Copy/move + auto-parent dirs | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Variables + interpolation | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Auto subcommands + help | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `MKDIR` / `REMOVE` / globs | | ✅ | ✅ | ✅ | ✅ | ✅ |
| `CD` / `PRINT` / dry-run | | ✅ | ✅ | ✅ | ✅ | ✅ |
| Params & flags (`--name`) | | | ✅ | ✅ | ✅ | ✅ |
| Env control (`ENV`) | | | ✅ | ✅ | ✅ | ✅ |
| Composition (`CALL`) | | | | ✅ | ✅ | ✅ |
| Conditionals (`IF`/`UNLESS`) | | | | ✅ | ✅ | ✅ |
| Remote (`SSH`/`UPLOAD`) | | | | ✅ | ✅ | ✅ |
| Matrix + parallel | | | | | ✅ | ✅ |
| Includes / stdlib / LSP | | | | | | ✅ |

---

## Sequencing rationale

- **P1–P3 first** because they are irreducible: without process execution, file staging, and
  substitution, nothing else matters. They also happen to be exactly the user's stated v1 target.
- **File housekeeping (P4–P6) before flags** because scripts hit "ensure this dir / delete these
  artifacts / glob these jars" far more often than they need argument parsing.
- **Flags (P10) before composition** because a single parameterized task delivers more value than
  chaining un-parameterized ones.
- **Remote and matrix last among core features** because they are the smallest slice of real usage
  and the easiest to shell out to (`RUN ssh ...`) in the meantime.
- **Ecosystem last** because language ergonomics only pay off once the core is stable and adopted.

Every phase preserves the invariants from day one: no permission management, destinations always
exist, fail-fast by default, and self-documenting subcommands.
