Roadmap
v0.1.0-beta4 is a useful preview for early adopters, not a declaration that Netsuke is finished. This page tracks what shipped, what is honestly still rough, and the order of the work ahead.
Shipped in v0.1.0-beta4
The core build-system compiler is implemented and packaged for Linux, macOS, and Windows. The public beta releases so far cover the following; items marked beta4 are new in this release.
Manifest language
- YAML 1.2 parsing with duplicate-key and schema validation
- Jinja variables, macros,
foreach,when, and globbing - Rules, targets, actions, defaults, and explicit, implicit, and order-only dependencies
- Ordered
commandlists with fail-fast&&chaining, anddescriptionmetadata on rules, targets, and actions - Dependency-only aggregates: an action or target with a non-empty
depslist may omit its recipe - Ordinary shell dollars: write
$PATHas-is; Netsuke escapes it for Ninja after lowering the{{ ins }}and{{ outs }}markers -
$inand$outare plain shell variables inscript:recipes too, as they already were incommand:recipes beta4
Compiler & execution
- A deterministic build graph with duplicate-output, missing-rule, and cycle checks
- Ninja generation and execution, plus
cleanand standalone manifest generation - Dependency graphs as Graphviz DOT or self-contained, accessible HTML
- Serial dependency ordering with
dependency_order: serial, backed by Ninja dyndep - Windows legacy recipes run in Windows PowerShell by default, with an explicit Git Bash or MSYS2 compatibility route
- Budgets on manifest evaluation — instructions, value and output sizes, template source, and
foreachexpansion — that a project can lower but not raise beta4 - Target names are passed to Ninja after
--, so a target called-fstays a target beta4
Safety boundary
- UTF-8 build-file and working-directory paths are required, with a clear diagnostic otherwise
-
whichandcommand_availablesearch onlyPATHunless a manifest opts in withcwd_mode="workspace-recursive"beta4 - Exact-name allow and block lists for what
env()may read beta4 -
fetch()revalidates every redirect against the network policy, and project configuration can only narrow that policy unless the operator trusts it beta4 - File-reading filters are bounded to 8 MiB by default and refuse symlinks and non-regular files unless asked beta4
- Manifest content no longer reaches verbose or debug logs beta4
Operator experience
- Layered configuration, localized output, and accessibility preferences
- Progress reporting, stage timings, and versioned JSON results or diagnostics
- A
netsuke help targetscatalogue of targets and actions, listing conditional entries without rendering recipe bodies - Configuration-selection diagnostics, cached configuration discovery, and bounded metrics under
--verbose - Thirty-five locale catalogues, with a published localization style guide and glossary
- Progress parsing reads at most 512 bytes of a Ninja status line; longer lines still reach the terminal unchanged beta4
Confidence & packaging
- Unit, behavioural, integration, property, snapshot, and Kani verification coverage
- Kani harnesses for command interpolation, and the command placeholder contract documented in the README beta4
- Packages for Linux (
.deb,.rpm), macOS (.pkg), and Windows (.msi) - A later beta or the final release replaces an installed beta MSI in place beta4
- Each Linux release binary reports the oldest glibc it runs on beta4
- Jinja
glob()rejects matched filenames that cannot be inserted as one portable unquoted shell word
Upgrading from beta3
Four changes in v0.1.0-beta4 can alter what an existing manifest does. Each one closes a way for a checkout or a project file to widen what a build may reach; the migration guide has the detail.
which and command_available no longer search the workspace when PATH has no match. A manifest that deliberately runs an executable from its own checkout must now say so with cwd_mode="workspace-recursive"; see the standard library.
A project’s .netsuke.toml can narrow the network policy but no longer widen it: its allowed schemes and hosts are ignored unless the operator trusts project fetch policy. See the security model.
contents, linecount, hash, and digest read at most 8 MiB by default, refuse a symlink unless the call passes follow_symlinks=true, and refuse anything that is not a regular file.
In script: recipes, $in and $out are now ordinary shell variables. Use {{ ins }} and {{ outs }} for a target’s paths.
Building from a source checkout on Linux now also needs the mold linker; Install has the details. Registry installs and packages are unaffected.
Known limitations
The compiler pipeline and ordinary local-build workflow are substantial; the command-line interface, configuration vocabulary, and advanced recipe model remain pre-stable. Pin the Netsuke version in automation and expect some command names, flags, diagnostic schemas, and manifest details to change before 1.0. The following limitations apply to v0.1.0-beta4.
Recipes remain shell strings: Unix scripts use /bin/sh -e, Windows legacy recipes use Windows PowerShell by default, and the Windows Bash compatibility route is an explicit opt-in. Values templated into a recipe are not quoted for you. Argv-safe commands and recipe environment mappings are designed but not implemented; see the structured commands preview.
A manifest cannot yet ask which operating system or architecture it is on without reading environment variables; an opt-in host descriptor is proposed in RFC 0029, intended for v0.1.1.
Compiler-generated dependency imports, such as GCC depfiles, are planned but not yet part of the manifest model.
A build is one Netsukefile: there are no includes or bundles yet, and reuse means Jinja macros within the file. Reusable modules are designed.
--json emits exactly one versioned result or diagnostic document per command, but the schema may still change before 1.0.
Accessibility still needs assistive-technology verification, and terminal rendering needs regression coverage.
Colour rendering is not implemented: --color affects mode selection but does not add coloured terminal text.
A Netsukefile can execute commands and use impure template helpers. Treat it with the same care
as a Makefile: review untrusted manifests before running them. Netsuke quotes supported path
substitutions, but it is not a sandbox.
The road ahead
Work after the first release is organized around a few near-term priorities and a set of larger capability tracks, each validating one hypothesis. The upstream plans — the detailed roadmap, the composition roadmap, and the progressive-enhancement roadmap — track the task-level sequence; the bracketed numbers below link to the step that owns each item. Every capability track has a preview page, and every item on it links to the section that explains it.
Near-term priorities
Work on the current command surface and the compiler’s guarantees.
Stabilize the command-line contract
Keep a pleasant, accessible local experience while making every command predictable for CI, editors, and agents.
- To do: Canonical command and flag names replacing the pre-0.1.0 surface [3.15]
- To do: Non-interactive and mutation-safety guarantees (
--no-input,--force,--dry-run) [3.15] - To do: Canonical structured
--jsonoutput with stable exit codes and enumerable errors [3.15] - To do: Bounded output for every large response [3.15]
- To do: Assistive-technology verification of accessible output [3.8]
- Done: Precedence-ladder regression coverage for configuration selection and discovery; the profile layer waits on profiles [3.11]
- To do: Regression coverage for terminal rendering and colour policy [3.12]
Make shell recipes safer and clearer
Tighten today’s shell-string recipes while the structured recipe model is built beside them.
- Done: Backend dollar escaping after placeholder lowering [3.14.7]
- Done: Dependency-only aggregates in place of no-op recipes [3.14.3]
- To do:
env(name, default=...),compact, and shell-quoting helpers for deliberate shell recipes [3.14.8] - To do: Rule-level
deps_fromfor compiler dependency imports (GCC depfiles) [3.14.6] - To do: Reporting which conditional actions were selected, without a recipe
echo[3.14.11] - To do: Recipe environment mappings, deferred until structured commands settle the shape [3.14.9]
Strengthen confidence
State and check the core compiler invariants strongly enough that future features cannot erode deterministic builds.
- Done: Kani tooling, a CI smoke job, and harnesses for manifest-to-IR safety and cycle canonicalization [4.2]
- Done: Kani harnesses for command interpolation [4.2.3]
- Done: The command placeholder contract, documented in the README [4.4.1]
- To do: Property tests for deterministic Ninja emission, expansion invariants, and render stability [4.3]
- To do: A documented cycle-detection contract, and an evaluation of a minimal Verus proof kernel [4.4]
Capability tracks
Each track has a preview page. Every item links to the preview section that explains it, and to the task that tracks it upstream.
System facts
An opt-in, immutable description of the host, collected once per run, so a manifest can choose a convention without probing the environment.
- To do: Accept RFC 0029 and settle the snapshot, grant, and diagnostic types [30.1]
- To do: An explicit
host_factsopt-in under an operator authority ceiling [30.2.1] - To do: Platform facts collected once into an immutable
host: operating system, family, architecture, executable suffix, and path separators [30.2.2] - To do: A facts digest in plan identity, so a changed host invalidates stale Ninja work [30.2.3]
- To do: Non-disclosing target discovery and a standalone
factsinspection command [30.2.4–30.2.5] - To do: Separately authorized distribution and kernel observations [30.3]
- To do: Typed host fixtures for manifest tests, and one snapshot shared across includes and bundles [30.4]
- To do: Query-gated filesystem probes:
exists,link_exists,same_file,mount, andexpandvars[6.7]
Template standard-library expansion
Absorb common manifest operations into the standard library without weakening determinism or the capability boundary.
- To do: Settle the helper contract and split RFC 0006 into focused child RFCs [6.1]
- To do: Structured data readers without a subprocess [6.2]
- To do: Configuration layering and build matrices with stable ordering [6.3–6.4]
- To do: Text and version conditions, and path text for another platform [6.5–6.6]
- To do: Generated file text, stable identities, and timestamp conversion without the clock [6.8–6.9]
- To do: Proportionate quality-gate selection from a deterministic Git changeset [6.11]
Structured commands
Close the gap between shell-string recipes and an argv-safe recipe model in which a value can never become syntax.
- Done: The named-shell contract, settled in ADR-019 [11.1]
- To do: Trusted shell resolution and an allow-list of named shells [11.2–11.3]
- To do: Argv-safe
invokeblocks, compiled before any template value is rendered [12.1] - To do: Isolated environment overlays and capability-scoped working directories [12.2]
- To do: Shell-free streams, tee, and fail-fast pipelines [13]
- To do: Runtime bindings and owner-private temporary directories [14]
- To do: Migration examples and downstream canaries [14.3]
Reusable modules
Compose a build from reviewed parts: local includes first, then versioned bundles, then pinned external ones.
Netsukefile testing framework
Manifest-time tests that run through the same compiler as the build: deterministic, mock-friendly, and reported like any other command.
- Done: An injectable clock for the standard library’s time functions [7.1.1]
- To do: A YAML test dialect beside the manifest, with discovery [7.2]
- To do: Mock and fixture engines so tests never touch the real host [7.3–7.4]
- To do: Assertions over the expanded manifest, the graph, and the generated Ninja [7.5]
- To do: The
netsuke testcommand, localized and reported like any other [7.6]
Netsukefile linter under netsuke check
Deterministic manifest linting inspired by mbake: named rules over the compiler’s own stages, and findings that never mutate the manifest.
Property testing
Test what should hold for every action a manifest generates, not just the cases someone thought to write down.
States and probes
Say what must be ready before a command runs, check it honestly, and prepare it at most once.
Typed inputs
Give the values a manifest takes a contract, checked before anything runs.
Owned artefacts
Declare what a build owns, then clean exactly that.
Underpinning the rest
Commitments that constrain every track above.
Keep the shallow end
Every contract above is optional. These steps prove that a plain manifest never pays for features it does not use.
- To do: Compatibility fixtures: the unchanged basic workflow starts no probes, installs nothing, and makes no new network requests [20.1]
- To do: Opt-in maturity policies, so strictness is chosen per project rather than imposed [25]
- To do: An end-to-end proof that each enhancement can be adopted on its own [25.3]
Compounding features for humans and agents
Make repeated human, CI, editor, and agent usage improve through introspection, memory, and delivery.
- To do: Machine-readable context:
netsuke context --jsonandskill-path[5.1] - To do: A run ledger:
runs list,runs get, andruns prune[5.2] - To do: Named profiles with redaction and secret handling [5.3]
- To do: Structured delivery of Netsuke-owned artefacts, and local-first feedback [5.4]