Completed Suggestions
Items from suggestions.md that have been implemented.
Completed Features
- Remote caching — See Remote Caching. Share build artifacts across machines via S3, HTTP, or filesystem.
- Lua plugin system — built, then removed on 2026-10-17: no repository ever declared a
[processor.lua.*]stanza, and the host could not take part in cache versioning or field validation. Custom commands go through the config-driven processors (script,generic) instead. - Tool version locking —
rsconstruct tool locklocks and verifies external tool versions. Tool versions are included in cache keys. - JSON output mode —
--jsonflag for machine-readable JSON Lines output (build_start, product_start, product_complete, build_summary events). - Native C/C++ include scanner — Default
include_scanner = "native"uses regex-based scanning. Falls back toinclude_scanner = "compiler"(gcc -MM). --processorflag —rsconstruct build -p processor.generator.tera,processor.checker.ruffandrsconstruct watch -p processor.generator.terafilter which processors run.- Colored diff on config changes — When processor config changes trigger rebuilds, rsconstruct shows what changed with colored diff output.
- Batch processing — ruff, pylint, shellcheck, zspell, mypy, and rumdl all support batch execution via
execute_batch(). - Progress bar — Uses
indicatifcrate. Progress bar sized to actual work (excludes instant skips), hidden in verbose/JSON mode. - Emit
ProductStartJSON events — Emitted before each product starts executing, pairs withProductCompletefor per-product timing. - mypy processor — Python type checking with mypy. Batch-capable. Auto-detects
mypy.inias extra input. - Explain commands —
--explainflag shows skip/restore/rebuild reasons for each product during build. -ppulls in the producers of its inputs —-p Bruns B and the processors that generate B’s inputs, transitively, as--targetdoes for products; every processor is discovered and the selection is made on the full graph (select_processors).-xexcludes a processor and everything downstream of it, and an excluded processor is never pulled back in.- Unchanged-output pruning — When a product rebuilds to identical bytes, the products reading it are skipped with their outputs untouched: no rerun, no restore. Each product is decided at dispatch from the inputs it will read (R1), and its stale outputs are removed only right before it actually restores or rebuilds — no longer for every predicted change before the run. Products predicted to change that never run (a failed dependency, an error, Ctrl+C) have their stale outputs removed at the end of the run, so a failed build still leaves none behind. Processors whose one tool run writes many products’ outputs (mass generators) replace them themselves (
Processor::replaces_own_outputs). - Ready-queue scheduler — Products run the moment their own dependencies finish, from a pool of exactly
-jworkers, instead of level by level. Batch chunks run in parallel and count against-j;max_jobsis enforced by the queue instead of semaphores. See R6/R7 in Architecture Observations.
Completed Code Consolidation
- Collapsed
checker_config!macro variants — Merged@basic,@with_auto_inputs, and@with_linterinto two internal variants (@no_linterand@with_linter). - Added
batchfield to all manually-defined processor configs — All processor configs now supportbatch = falseto disable batching per-project. - Replaced trivial checker files with
simple_checker!macro — 25 trivial checkers reduced from ~35 lines each to 3-5 lines (~800 lines eliminated). - Unified
lint_files/check_filesnaming — All checkers now usecheck_filesconsistently. - Moved
should_processguard into macro — Addedguard: scan_rootbuilt-in toimpl_checker!, removed boilerplateshould_process()from 7 processors. - Simplified
KnownFields— Scan config fields auto-appended by validation layer viaSCAN_CONFIG_FIELDSconstant;KnownFieldsimpls only list their own fields. - Extracted
WordManagerfor spellcheck/aspell — Shared word-file management (loading, collecting, flushing, execute/batch patterns) inword_manager.rs.
Completed New Processors
- mypy — Python type checking using
mypy. Batch-capable. Config:checker,args,dep_inputs,scan. - yamllint — Lint YAML files using
yamllint.src/processor/checker/yamllint.rs. - jsonlint — Validate JSON files for syntax errors.
src/processor/checker/jsonlint.rs. - taplo (toml-lint) — Validate TOML files using
taplo.src/processor/checker/taplo.rs. - markdownlint — Lint Markdown files for structural issues. Uses
mdlormarkdownlint-cli. - pandoc — Convert Markdown to other formats (PDF, HTML, EPUB). Generator processor.
- jinja2 — Render Jinja2 templates (
.j2) via Python jinja2 library.src/processor/generator/jinja2.rs. - black — Python formatting verification using
black --check.src/processor/checker/black.rs. - rust_single_file — Compile single-file Rust programs to executables.
src/processor/generator/rust_single_file.rs. - sass — Compile SCSS/SASS files to CSS.
src/processor/generator/sass.rs. - protobuf — Compile
.protofiles to generated code usingprotoc.src/processor/generator/protobuf.rs. - pytest — Run Python test files with pytest.
src/processor/checker/pytest.rs. - doctest — Run Python doctests via
python3 -m doctest.src/processor/checker/doctest.rs.
Completed Test Coverage
- Ruff/pylint processor tests —
tests/processor/ruff.rsandtests/processor/pylint.rswith integration tests. - Make processor tests —
tests/processor/make.rswith Makefile discovery and execution tests. - All generator processor tests — Integration tests for all 14 previously untested generators: a2x, drawio, gem, libreoffice, markdown, marp, mermaid, npm, pandoc, pdflatex, pdfunite, pip, sphinx.
- All checker processor tests — Integration tests for all 5 previously untested checkers: ascii, aspell, markdownlint, mdbook, mdl.
Completed Caching & Performance
- Lazy file hashing (mtime-based) —
mtime_checkconfig (defaulttrue),fast_checksum()with MTIME_TABLE. Stores(path, mtime, checksum)tuples. Disable with--no-mtime. - Compressed cache objects — Optional zstd compression for
.rsconstruct/objects/. Config:compression = truein[cache]. Incompatible with hardlink restore (must userestore_method = "copy"). Checksums computed on original content for stable cache keys.
Completed Developer Experience
--quietflag —-q/--quietsuppresses all output except errors. Useful for CI scripts that only care about exit code.- Flaky product detection / retry —
--retry=Nretries failed products up to N times. Reports FLAKY (passed on retry) vs FAILED status in build summary. - Actionable error messages —
rsconstruct tool checkshows install hints for missing tools (e.g., “install with: pip install ruff”). - Build profiling / tracing —
--trace=file.jsongenerates Chrome trace format output viewable inchrome://tracingor Perfetto UI. rsconstruct build <target>— Build specific targets by name or pattern via--targetglob patterns and-d/--dirflags.rsconstruct why <file>/ Explain rebuilds —--explainflag shows why each product is skipped, restored, or rebuilt.rsconstruct doctor— Diagnose build environment: checks config, tools, and versions. Full implementation insrc/builder/doctor.rs.rsconstruct sloc— Source lines of code statistics with COCOMO effort/cost estimation.src/builder/sloc.rs.
Completed Quick Wins
- Batch processing for more processors — All checker processors that support multiple file arguments now use batching.
- Progress bar for long builds — Implemented with
indicatif, shows[elapsed] [bar] pos/len message. --processorflag for build and watch — Filter processors with-pflag.- Emit
ProductStartJSON events — Wired up and emitted before execution. - Colored diff on config changes — Shows colored JSON diff when processor config changes.
Completed Features (v0.3.7)
RSCONSTRUCT_THREADSenv var — Set parallelism via environment variable instead of-j. Priority: CLI-j>RSCONSTRUCT_THREADS> configparallel.- Global
output_dirin[build]— Global output directory prefix (default:"out"). Processor defaults likeout/processor.generator.marpare remapped when the global is changed (e.g.,output_dir = "build"makes marp output tobuild/marp). Individual processors can still override theiroutput_direxplicitly. - Named processor instance output directories — When multiple instances of the same processor are declared (e.g.,
[processor.generator.marp.slides]and[processor.generator.marp.docs]), each instance defaults toout/{instance_name}(e.g.,out/marp.slides,out/marp.docs) instead of sharing the same output directory. - Named processor instance names in error reporting — When multiple instances of the same processor exist, error messages, build progress, and statistics use the full instance name (e.g.,
[pylint.core],[pylint.tests]). Single instances continue to use just the processor type name. processor configwithout config file —rsconstruct processor config <name>now works without anrsconstruct.toml, showing the default configuration (same asdefconfig).tag collectcommand —rsconstruct tag collectscans the tags database for tags that are not in the tag collection (tags_dir) and adds them to the appropriate.txtfiles. Key:value tags go to{key}.txt, bare tags go totags.txt.rsconstruct statusshows 0-file processors — Processors declared in the config that match no files are now shown instatusoutput and the--breakdownsummary, making it easy to spot misconfigured or unnecessary processors.smart remove-no-file-processors— New commandrsconstruct smart remove-no-file-processorsremoves[processor.*]sections fromrsconstruct.tomlfor processors that don’t match any files. Handles both single and named instances.cc_single_fileoutput_dir from config — Thecc_single_fileprocessor now reads its output directory from the configoutput_dirfield instead of hardcodingout/processor.generator.cc_single_file. This fixes named instances (e.g.,cc_single_file.gccandcc_single_file.clang) which previously collided on the same output directory.clean unknownrespects .gitignore —rsconstruct clean unknownnow skips gitignored files. Previously it disabled .gitignore handling, causing intentionally ignored files (IDE configs, virtualenvs,*.pyc, etc.) to be flagged as unknown. RSConstruct outputs are still correctly identified via the build graph, so nothing is missed. Use--no-gitignoreto include gitignored files.- Cross-processor dependencies (fixed-point discovery) — Generator outputs are now visible to downstream processors on the first build. Discovery runs in a fixed-point loop: after each pass, declared outputs are injected as virtual files into the FileIndex, and discovery re-runs until no new products are found. This means a generator that creates
.mdfiles can feed pandoc/tags/spell-checkers in a single build, without needing a second build.
Completed Architecture Refactors
- Config provenance tracking — Every config field now carries
FieldProvenance(UserToml with line number, ProcessorDefault, ScanDefault, OutputDirDefault, SerdeDefault).rsconstruct config showannotates every field with its source. Usestoml_edit::Documentfor span capture. BuildContextreplacing process globals — All mutable process globals moved intoBuildContext: the three processor globals (INTERRUPTED,RUNTIME,INTERRUPT_SENDER) and the three checksum globals (CACHE,MTIME_DB,MTIME_ENABLED). Threaded through theProcessortrait, executor, analyzers, remote cache, checksum functions, and deps cache. Signal handler usesArc<BuildContext>.BuildPolicytrait — Extracted from the executor.classify_productsdelegates per-product skip/restore/rebuild decisions to a&dyn BuildPolicy.IncrementalPolicyimplements the current logic. Future policies (dry-run, always-rebuild, time-windowed) are a single trait impl.ObjectStoredecomposition —mod.rssplit from 664 → 223 lines into focused submodules:blobs.rs(content-addressed storage),descriptors.rs(cache descriptor CRUD),restore.rs(restore/needs_rebuild/can_restore/explain).
Completed Features (latest)
rsconstruct status --json— JSON output with per-processor counts (up_to_date,restorable,stale,new,total,native) and totals. Activated by--jsonflag.- Selective processor cleaning —
rsconstruct clean outputs -p processor.checker.ruff,processor.checker.pylintcleans only those processors’ outputs. Without-p, cleans everything. - Prettier processor — Checker using
prettier --check. Batch-capable. Scans.js/.jsx/.ts/.tsx/.mjs/.cjs/.css/.scss/.less/.html/.json/.md/.yaml/.yml.src/processor/checker/prettier.rs. - Bare
cleanrequires subcommand —rsconstruct cleannow errors with usage hint instead of silently defaulting toclean outputs. - Nondeterministic test race fix — Fixed TOCTOU race in
store_descriptorwhere parallel writers could getPermission denied. Now retries after forcing writable on first failure. - Suppress status line for non-build commands — The
Exited with SUCCESS/ERRORfooter only shows forbuild,watch, andclean. - Configurable graph validation — Four checks run after
resolve_dependencies(): (1) reject empty inputs (default on), (2) validate dep references (default on), (3) detect duplicate inputs within same processor (default off), (4) early cycle detection (default off). Config:[graph]section fieldsvalidate_empty_inputs,validate_dep_references,validate_duplicate_inputs,validate_early_cycles. - Checksum globals moved to BuildContext —
CACHE,MTIME_DB,MTIME_ENABLEDmoved fromsrc/checksum.rsstatics intoBuildContext.combined_input_checksum,checksum_fast,file_checksumall take&BuildContext. Completes the isolated-build-context story. rsconstruct fixcommand — Runs fixers (auto-format, auto-fix) on source files. Checkers declare fix capability viafix_subcommand/fix_prepend_argsonSimpleCheckerParams.processor listshows aFixcolumn. Supports-pfiltering, batch execution, and--json. Fix-capable processors: ruff, black, prettier, eslint, stylelint, standard, taplo, rumdl, markdownlint. (Partly reverted 2026-08-04: fix capability was unused, so all ninecan_fixflags were set tofalse; today onlyscriptinstances with afix_commandare fix-capable, and processors are named as positional arguments torsconstruct fix runrather than with-p. Removed entirely on 2026-10-17: the one fleet use was ascriptinstance, and nothing else ever declared a fixer.)processor search—rsconstruct processor search <query>searches by name, description, and keywords. All 91 processors have keywords covering language, tool category, file extensions, and ecosystem terms. Supports--jsonoutput.