Repository navigation
io-cli 0.37.0 - #96
Merged
Merged
Conversation
… for a turn /context drew the tool catalogue as one number, so an operator who wanted to know which of their bundles was expensive had no way to ask. It is now attributed: a row per MCP server named with the bundle that contributed it, and a skill catalogue row for the block io-harness writes into the system prompt — which until now was counted inside the system block, so a session's skills appeared to cost nothing at all. /plugin and /mcp draw the same figure on the row where the thing is switched on, from the same snapshot, so the two surfaces cannot disagree. The tiers are stated from a table keyed by io-harness's own wire names rather than from a hand-written list: of the seven kinds of thing a bundle contributes, only skills, agents and MCP servers reach the wire. /context withhold <tool> takes a tool away from the next turn and /context allow puts it back — verbs under an existing command, so COMMANDS.len() is still 36 and the last free group slot stays free. A mask does not make a turn cheaper, and the code says so everywhere it could be misread. io-harness offers a masked turn a byte-identical catalogue on purpose, because the tool array sits ahead of the provider's cache breakpoint and dropping a definition would pay a cache write on every later turn. Withholding in fact adds one sentence naming the withheld tools. The roadmap entry this version was planned from assumed the opposite; attribution is the cost feature and masking is a scoping one. Suite: 105 binaries, 1,924 passed, 0 failed, 37 ignored. fmt and clippy clean.
…n suite Two reviewers split by area found disjoint sets and both were load-bearing. A withheld name that answers to nothing was confirmed as refused. io-harness keeps an unknown mask entry rather than rejecting it, deliberately, so that a mask stays portable across builds with different cargo features — which means `mask_gate` matches on the exact string and a misspelling withholds nothing. `/context withhold Docx_Write` printed "calling it will be refused before anything starts", drew the name on the withheld row, and left the tool fully callable. The asymmetry was the tell: the allow arm already refused to be a silent no-op and was tested for it, so the guard existed only on the harmless direction. The name is still added — refusing it here would break the portability io-harness designed for — and the sentence now says it matches nothing on the wire. The skill catalogue swallowed io-harness's planning directive. `compose` appends the directive with `push_str` and `Skills::catalog()` ends with no trailing newline, so the final catalogue line on the wire carries the whole directive and still starts with "- ". The row over-reported by roughly 117 tokens and, worse, `bundle_cost` charged those tokens to whichever bundle owns the alphabetically last skill — so a bundle's figure moved when the operator toggled `/plan`, for a reason that had nothing to do with it. Reachable on every contained turn, and invisible to the partition test because the bytes are inside `request.system` either way. `/plugin` drew "0 tokens every request" for every bundle before any turn had run, while `/mcp` correctly drew "not yet on a request" for the very server one of them contributed. A zero on that column says the bundle is free, which is the one claim that stops an operator looking. The costs are now attached only when a request has actually gone out. `server_of` took the first prefix match rather than the longest, so a configured `github` absorbed every tool belonging to `github__enterprise` and the enterprise server read as unmeasured for the life of the session. Also: the docs taught `/context allow` as the inverse of a single withhold when bare allow clears the whole mask; CONTRACT.md still said all eleven mid-turn commands report; the verbs were absent from `/help`, the palette and the command guide; and every sentence said "the next turn" for what is a standing posture. Each fix has a regression test, and each test was verified to fail when its fix is reverted. Suite: 105 binaries, 1,929 passed, 0 failed, 38 ignored. Live 37/37 in 1152s, plus the new mask arm proved by a negative control — without the mask the model calls write_file immediately; with it, no write_file step ever commits and the run routes around.
io-cli 0.37.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.37.0.
/contextattributes the tool catalogue to what put it on the wire — a row per MCP server named with its bundle, and askill cataloguerow for the block io-harness writes into the system prompt, which four releases had counted insidesystem blockso a session's skills appeared to cost nothing./pluginand/mcpstate the same figure where the thing is switched on./context withhold <tool>withholds a tool until it is allowed again, as verbs under an existing command —COMMANDS.len()is still 36.The roadmap's premise was false and correcting it is most of the release. io-harness 0.76.0's
ToolMaskis availability, never membership: a masked run is offered a byte-identical catalogue, deliberately, because the tool array sits ahead of the provider's cache breakpoint. The mask adds a sentence rather than removing definitions. Attribution is the cost feature; masking is a scoping one, and a prose gate over every shipped page stops the original framing returning.The adversarial review found three High and four Medium behind a fully green suite — a withheld misspelling silently withholding nothing, the skill catalogue swallowing io-harness's planning directive on every contained turn,
/plugindrawing a real zero before any turn, andserver_oftaking the first prefix match. Each fixed with a regression test verified to fail when reverted.The live gate found the most useful thing: the mask arm failed against a working mask, because io-harness announces a withholding before the model acts so a compliant model never produces the refusal the criterion named. The arm now asserts the guarantee and is proved by a negative control.
ultraship validateexit 0 over 118 checks; record sealed and pinned before the merge