Repository navigation
io-cli 0.34.0 - #87
Merged
Merged
Conversation
The pin forces no compile fix: io-harness 0.73.0 makes Skill non_exhaustive and gives it a root field, and this crate constructs none, only reads fields. Its real cost is a silent one, handled in the commits that follow.
A read_skill call is drawn as a loaded-skill row - the skill's displayed name and what became of it - from io-harness's own decision sentence rather than beside it, so the string that carried the separator is no longer drawn for that tool at all. A failed read still says the read failed. trim_result is repaired at the cause: a pending call keeps io-harness's wire target beside the displayed one, and both the said set and the trailing-target strip consult it. Translating the target in place is what stopped the repetition being recognised, and plain() keeps _ while dropping :, so the two sides differed by the separator itself. An MCP tool cell reads Call github:create_issue. The prefix is stripped before translating because the prefix itself ends with the separator, and the cell that carries a measured duration now matches on the wire name - the only event in the enum reporting how long a tool ran, lost silently otherwise. A slash-invoked skill echoes what was typed while the prompt stays the catalogue name. The echo is a field of the harness's own Started event, so it is carried from the driver rather than translated on the way past. And read_skill's target is no longer assumed to be a name: io-harness 0.73.0 announces a companion path in preference to it, and translating one draws a file that does not exist.
io-harness 0.73.0 parses a [[bin]], refuses one from a scope that may not contribute an executing thing, and offers it on an accessor it never calls itself; its contract says outright that placement is the host's decision. Appended and never prepended, so nothing a bundle ships can shadow a system command for the tool calls io-harness makes on the model's behalf, whose permission gate matches a binary name. No file is written on a stranger's behalf, so resolution is by the file's own name and a declaration that renames its program is reported at startup rather than staged. The plugin pane names the program and its path. Consenting to the bare word bin was free until this release put the program on PATH.
…ew gate A bundle contributes seven kinds now, not six - six sentences said otherwise across the guides, the capabilities index, the example configuration and two source files. The plugins guide gains a section on the executable a bundle ships: the append-not-prepend reason, that no file is written, and the downgrade hazard - a manifest carrying a [[bin]] is refused whole by an older io-cli reading the same home, which drops every skill, agent, hook and layer in that bundle rather than the one entry. The skills guide gains read_skill's optional path, and the naming rule now states the loaded-skill row and that the echoed line and the sent prompt deliberately differ.
Re-read, not version-bumped. The two trees were diffed first: of the eleven harness files cited, three changed, and four citations in adapt.rs shift by the lines inserted above them - each confirmed by landing on the target rather than by arithmetic. plugin.rs:311 still joins the plugin root, so the absolute-path argument holds; plugin.rs:841 still refuses substitutions in every scope and still takes the whole bundle. Every claim re-checked against the code rather than assumed: the three step and retry defaults, the five widening pairs, the three substitution forms, the two MCP transports, and that Act::Exec still matches a binary name alone. exec.rs also claimed 'Still true at 0.72.0'. That is a currency claim rather than a citation, so no gate would have caught it and a bump would have left it asserting currency for a version this crate no longer pins.
The placement went on the interactive session's startup, and io exec and io resume return from main hundreds of lines before that - so neither headless door placed anything. The two-entry-point asymmetry, again. Found by the live gate and only by it: the model reported that io-cli-probe was not on PATH, then found it by walking the workspace and ran it anyway. A check grepping for the program's own output would have said PASS over a placement that never happened. Four steps before the fix, two after. install_for lives in exec.rs rather than the driver because tests link the library and not main.rs, and f9_every_door_that_reaches_a_run_places_a_bundles _programs counts the sites - a contains is satisfied forever by whichever door was written first, which is exactly how this shipped. Also gates F5: set_echo is called at the two sites that submit a skill under its catalogue name, each beside the submission it belongs to.
Seven tests over what the transcript, the status line, the pickers and the plugin, skill and marketplace panes actually draw. The gate asserts an untranslated namespaced name - the literal <bundle id><NAMESPACE><contribution> for an id the fixture declared - and not the absence of the separator. A plugin id cannot contain __ (io-harness's check_id), so the first occurrence is always the join and everything after it is the contribution's own name: bundle__deep__nested is correctly drawn bundle:deep__nested and keeps one. Under the blanket spelling, writing display with replace instead of split_once reads as a fix, which is how 0.32.0 shipped its path defect. Every surface gets both halves - a contributed name translated, and a path or a doubly-separated name surviving intact - and the wire spelling is built from io_harness::NAMESPACE rather than from crate::naming, so the gate does not measure the translation against itself. AGENTS.md described the blanket rule and then contradicted it a sentence later; it now states what the gate actually asserts.
clippy::items_after_test_module refuses a test module with production items below it, and CI runs clippy with -D warnings.
Two reviewers split by area found the mid-session PATH defect independently, which is the strongest corroboration available. A bundle installed mid-session never reached PATH. refresh_holdings re-resolves at the /plugin door and at every turn boundary and placed nothing, so everything else a bundle contributes came into force at the next turn - the install says so in those words - and its program did not, until the operator restarted. appended()'s own doc justified its idempotence by a caller that did not exist. The echo outlived a turn that never started. io-harness validates the contract, discovers skills, opens the run, takes the store lease and sets the provider before it emits Started, and every one of those can fail - so Started's take() was not on its own a guarantee. Cleared in flush, beside awaiting and thinking. The echo dropped the leading slash. Command::Slash arrives stripped, so the one row the reader wrote came back as an ordinary prompt containing a colon - and the test hand-fed the slash it should have proved, so it could never see it. mismatched reported every correctly-authored Windows bundle: review.exe answers to review there, and the notice saying otherwise went to stderr on every io exec. answers_to reads PATHEXT rather than assuming. A switched-off bundle's programs and entries' sort and dedup were asserted by nothing - chaining disabled(), or dropping the BTreeSet, left the suite green. So was the whole executables disclosure block, on the surface an operator consents from. Also: a join_paths failure no longer wears the same value as nothing-to-add, a failed bundle listing no longer reads listed read error, and the bin path is shortened from the left so the file name survives.
…haviours
The changelog repeated the blanket rule ('fails if the separator appears') that
the gate is deliberately not written as - a path carries one legitimately, and
only the first separator is the join. Also records that a bundle installed
mid-session has its program placed at the next turn, and that a Windows bundle
shipping review.exe under the declared name review is correctly authored.
CI's clippy runs a newer toolchain than this machine's, and clippy::question_mark fires there on skill_and_file's else-if chain. My local clippy was the weaker gate, which this product has paid for before. And the appended-not-prepended test spelled a unix PATH by hand, so Windows - which splits on ';' - saw one entry whose name contained a colon and failed for a reason unrelated to the order under test. The production code was right and the fixture was not; it now joins with the platform's own separator. Four of five real defects in this product's history were platform-specific and invisible locally. This is the fifth and sixth.
io-cli 0.34.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release PR for 0.34.0.
Closes the three surfaces that still printed io-harness's
__to a person, puts a gate under the rule, and pins io-harness 0.73.0 so a capability bundle stops being half-installed: a skill reads its own bundle's files without a shell, and a bundle's declared executable is resolvable inside a run.Gates
cargo test --all-targets --no-fail-fast— 102 binaries, 1,824 passed, 0 failed, 37 ignoredcargo test --doc,cargo fmt --all -- --check,cargo clippy --all-targets -- -D warnings— exit 0What the gates caught that a green suite did not
The live gate found the release's own worst defect in words rather than in a failure: the model reported the bundle's program was not on
PATH, then ran it by walking the workspace. A check grepping for the program's output would have said PASS.Both adversarial reviewers independently found that a bundle installed mid-session never reached
PATH, while the install told the operator it was in force from the next turn.CI found two more that no local run could see: a clippy lint that only fires on its newer toolchain, and a test fixture that spelled a unix
PATHby hand and so failed on Windows for a reason unrelated to the property under test.The record is sealed and pinned at
sha256:39123dd9b09c9baa4553785bcd1ac031f6b0137d9a1f9f9f98143edf9394f868,ultraship validateexit 0 over 103 checks.