feat: install the product itself, not only configure it - #12
Conversation
This setup system now installs its harness. `software_install`, `software_update` and `software_remove` are declared, and the shape they take was agreed with the consumer on `ai-engineers-guild/ai_stp#414` rather than invented here: `--target` is the configuration directory and `--prefix` is the program directory, the plan carries an array `software_artifacts`, and `apply` receives one repeated `--software-artifact` per element in the plan's order. The provider never opens a socket. The contract gives software a download phase and gives a provider no command to run it in -- there is no `download` among the seven -- so `plan` names one url, one length and one digest while offline, whoever holds the network fetches exactly that, and `apply` re-checks it offline and installs. `setup-core::archive` reads the one shape every vendor ships: a gzip-compressed tar, or plain bytes. Both dialects that actually appear are accepted -- POSIX `ustar` and GNU tar with its long-name headers -- and exactly three entry types: a regular file, a directory, and that long name. Every other type flag is refused by name, because extraction that honours a symlink can be made to write through it. It streams, because one of these payloads inflates to 391 MB. DEFLATE comes from `miniz_oxide`; the gzip framing and the tar reading are here, where the refusals can be ours. The vendored provider kit moves to 0.2.1, which adds `unsupported_permission_profile`. A permission profile this build never advertised used to answer `projection_profile_mismatch` -- documented in place as a compromise, because the closed set had nothing better. It now answers what actually happened.
…e systems `rust / test (windows-latest)` failed here while ubuntu and macos passed. The test passed the literal `/tmp`, which on Windows is rooted but not absolute, so the argv parser refused it one step earlier and the test never reached its assertion. `std::env::temp_dir()` is absolute on all three. The product code was correct throughout: `Path::is_absolute` is platform-aware, and refusing a Windows path with no drive is what "both absolute" means there.
|
False positive: the variable is used through Rust's inline format-string capture.
The compiler is authoritative here and disagrees. Rewriting it as |
feat: install the product itself, not only configure it
This setup system now installs its harness.
software_install,software_updateandsoftware_removeare declared, and the shape they takewas agreed with the consumer on
ai-engineers-guild/ai_stp#414rather thaninvented here:
--targetis the configuration directory and--prefixis theprogram directory, the plan carries an array
software_artifacts, andapplyreceives one repeated
--software-artifactper element in the plan's order.The provider never opens a socket. The contract gives software a download phase
and gives a provider no command to run it in -- there is no
downloadamong theseven -- so
plannames one url, one length and one digest while offline,whoever holds the network fetches exactly that, and
applyre-checks it offlineand installs.
setup-core::archivereads the one shape every vendor ships: a gzip-compressedtar, or plain bytes. Both dialects that actually appear are accepted -- POSIX
ustarand GNU tar with its long-name headers -- and exactly three entry types:a regular file, a directory, and that long name. Every other type flag is
refused by name, because extraction that honours a symlink can be made to write
through it. It streams, because one of these payloads inflates to 391 MB.
DEFLATE comes from
miniz_oxide; the gzip framing and the tar reading are here,where the refusals can be ours.
The vendored provider kit moves to 0.2.1, which adds
unsupported_permission_profile. A permission profile this build neveradvertised used to answer
projection_profile_mismatch-- documented in place asa compromise, because the closed set had nothing better. It now answers what
actually happened.
Rendered from the private monorepo at
NDDev-it-com/setup-systems@fec6feb. Never hand-edit a public tree — the next render would overwrite it.https://claude.ai/code/session_011eFMKoUdWcc7Aw9vtMxH2A