Repository navigation
Toolchain Profiles
ADR 0009. The graph names what it needs; a profile says how for one stack.
scio.toolchain.Toolchain covers, for one stack:
- files: source suffixes, test-path rules, cache excludes (also the
.git/info/excludetext), dependency files, a syntax check - commands: the test command and the meaning of its exit codes (passed, failed, no tests collected, runner broken), failure-only filtering of test output, path-selector semantics (
path::nameversus a filter expression), the lint command and how to read its exit codes, the script runner - parsers: the error signature (which failure is "the same" as last time) and the removed-public-symbol detector used by the high-impact flag
- prompt phrases: how a model should name tests (
selector_help) and filters (filter_help)
Profiles are frozen dataclasses; the protocol exposes read-only properties. Data lives in configs/profiles/<name>.yaml, parsers in scio/toolchain/<name>.py. Settings.toolchain (SCIO_TOOLCHAIN) picks the profile for a run; RunContext.toolchain carries it to every node and tool.
Reproduces the pre-M6 behaviour byte for byte: python -m pytest -q --tb=short -p no:cacheprovider -rfE --no-header, ruff check --no-cache --select E9,F63,F7,F82,F821 --output-format concise, __pycache__, *.pyc, .pytest_cache, .ruff_cache, .mypy_cache, test paths under tests/ or named test_*, pytest exit codes 0, 5 and 2 to 4, Python tracebacks for signatures, def/class removals for the public-API flag. tests/unit/test_toolchain.py asserts the equality against the old literals copied into the test.
test_no_stack_specific_command_outside_the_toolchain_package scans scio/ for command tokens ("pytest",, "ruff",, "npm", ...) and cache literals outside scio/toolchain/ and fails on any hit. The only Python facts left elsewhere are about SCIO's own runtime, not the target stack: the local sandbox rewrites argv python to its own interpreter and sets PYTHONUTF8=1 and PIP_NO_INDEX=1 offline.
-
configs/profiles/<name>.yaml: test argv and filter flag, exit codes, lint argv and exit codes, source suffixes, test dirs and prefix, cache excludes, dependency files, environment, script runner, the two prompt phrases. -
scio/toolchain/<name>.py: the failure-only filter, the error-signature parser, the removed-public-symbol detector, loaded from the YAML into a frozen dataclass that satisfies the protocol. - Register it in
scio/toolchain/__init__.py::get_toolchain. - A scaffold for product mode in
scio/product/scaffold.py(package, smoke test, CI running the profile's commands). - Tests mirroring
test_toolchain.pyfor the new profile; the regression suite stays at pass^5 = 1.00 for python.
Detection of an existing repository's stack is also M10; until then python is the only accepted value.