sandbox tests, dependency hygiene, and the last audit items (plan 0.11 and follow-ups) - #93
Merged
Merged
Conversation
The WASM sandbox built fuel, memory and epoch limits but no test ran a
guest that breached any of them: the existing coverage stopped at engine
creation, the StoreLimits struct, and hash verification. A regression
that dropped a limiter would have shipped green.
wasm/tests/limits.rs runs real WAT guests against each limit — an
infinite loop under a 10k fuel budget, a memory.grow one page past the
cap, and an infinite loop under a one-second epoch deadline with fuel set
to u64::MAX so nothing but the deadline can stop it — plus the two
under-the-limit cases that prove the limits are not simply failing
everything.
Fuel exhaustion and epoch interruption were both mapped to
ConnectorError::Sandbox(String) by substring-matching the trap message,
which no caller could branch on. They are now classified from
wasmtime::Trap into ConnectorError::FuelExhausted (already present) and a
new ConnectorError::Timeout, and the fuel error reports what the guest
actually burned.
template_resolve gains the payload re-expansion test: a trigger value
that looks like ${trigger.secret} is substituted verbatim, never
re-expanded (finding 84).
Findings 81, 84.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8
chitchat 0.10 pinned lru 0.13.0, which carries RUSTSEC-2026-0002 (IterMut Stacked Borrows unsoundness, fixed in 0.18.2). No 0.10.x release moved off it, so the advisory sat in both ignore lists with a VEX note instead of being fixed. chitchat 0.13.0 depends on lru 0.18.4, and the workspace now resolves a single patched lru. Two API changes in the major bump, both in awareness/store/chitchat.rs: ChitchatId::node_id is now Arc<str>, and ChitchatConfig gained an explicit protocol_version. V0 is chitchat's own default and the wire format 0.10 spoke, so the bump changes no bytes on the wire. The RUSTSEC-2026-0002 ignore is removed from .cargo/audit.toml and deny.toml and the VEX record deleted — the advisory no longer matches any crate in the graph. Neither audit configuration was relaxed. cargo audit and cargo deny check advisories both pass without it. Finding 125. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8
`cargo test -p springtale-cooperation` re-runs the ts-rs exporters, which write tauri/packages/types/src/generated/*.ts in ts-rs's own style. What was committed there had been through Biome, so every Rust test run left the working tree dirty, and the reformat-vs-regenerate difference has been committed and reverted repeatedly. Fixed at the cause by making the committed bytes the generator's bytes: the directory joins the OpenAPI-generated `api.ts` in biome.json's files.includes exclusions, and the three drifted files are re-committed as ts-rs emits them. The alternative — shelling out to Biome from the export — was rejected: it would put node and a pnpm install on the critical path of `cargo test`, in a workspace whose Rust CI job has neither, to gain nothing but line breaks in files nobody reads by hand. `cargo test` now leaves `git status` clean, and `pnpm lint` passes (141 files checked). index.ts stays hand-written and says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8
Three places still named `tauri::api::dialog`, a Tauri 1 path. The desktop is on Tauri 2 and depends on `tauri-plugin-dialog`; both ARCHITECTURE.md copies now say `tauri_plugin_dialog`, and the AUDIT-NOTES item that tracked the drift is closed. The CSP `connect-src http://127.0.0.1:*` stays, with the reason written down rather than left as an open item. The desktop frontend is a real HTTP client of the sidecar (`apps/desktop/src/provider.ts` points the API base at `http://127.0.0.1:${port}`), and the sidecar binds `127.0.0.1:0`, so the port is not known until unlock — after the CSP has already been baked into the build. Tauri offers no runtime CSP override, and CSP source expressions cannot express a port range, so the only way to name the port is a fixed port chosen at install, which trades a loopback wildcard for a collision. Findings 22, 83. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8
…count `springtale-cli vault unset` and `springtale-cli connector setup` appear in the tutorials but in no command tree: VaultAction has one variant (DuressSetup) and ConnectorAction has list/enable/disable/remove/install/ sign. Tutorial 01's cleanup step is removed — `connector remove` on the line above it is the real cleanup, and the next line already revokes the token at BotFather. Tutorial 02 now points at the connector setup flow it already described two paragraphs later (the dashboard card or the setup API) instead of a CLI verb. Still unfixed and out of this scope: `springtale-cli new <template>` (tutorials 01 and 03) scaffolds a whole project directory and does not exist either, and `springtale-cli auth print` appears in tutorial 03 and four reference pages with no `auth` command behind it. Both need a decision — build the verb or rewrite the step — not a one-line edit. catalog/snapshot.rs claimed "≈60 built-ins". Rather than swap in another figure that will go stale (the plan's register says 68; `fn .. -> Recipe` greps 78 in this tree, so the two do not agree), the comment now names `list_recipes` as the source of truth and carries no number. Findings 98, 100, 122. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8
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.
The last group of plan work: five pieces, one branch.
The sandbox limits have tests (0.11, findings 81 and 84). The WASM sandbox built fuel, memory and wall-clock limits, and nothing proved any of them fired. Five tests now do: a guest that exhausts fuel traps, one under budget returns, growth past the cap is refused and memory stays at the cap, growth within it succeeds, and a spinning guest trips the wall-clock deadline with fuel deliberately unlimited so only the clock can stop it. Trap classification moved off matching the error message text onto the runtime's own trap type, with a dedicated timeout variant. The placeholder re-expansion test the plan named is included.
One deviation: growth past the cap is asserted as refused rather than trapping, because trapping on growth failure would change behaviour for real connectors.
Dependency hygiene (finding 125). The gossip crate pulled a cache crate carrying an unsoundness advisory. Bumping it to the current release collapses that to a single patched version. The advisory ignore is removed from both the audit and the deny configuration rather than kept, and both pass without it. The wire format is unchanged: the new protocol version option is set to the one the old release spoke.
The generated TypeScript stops going stale. Running the Rust tests rewrote the generated type files in a different style from the committed ones, so the working tree went dirty after every test run and the difference was committed and reverted repeatedly. The raw generator output is now what is committed, and the formatter ignores that directory, following the precedent already there for the other generated file. Running the tests now leaves the tree clean. The alternative, running the formatter from the export, would have put a node install on the critical path of
cargo test, which the Rust job does not have.Two audit items. The three references to a first-generation Tauri API in the documents are corrected to the plugin that replaced it. The content-security policy still allows any loopback port, and that is now a recorded decision rather than an open item: the desktop is a real client of the sidecar, the sidecar binds an ephemeral port that only exists after unlock, the policy is baked at build time with no runtime override, and the policy language has no port range. The only alternative is a fixed install-time port.
Documentation verbs that never existed. Two tutorial steps called commands that are in no command tree; one is removed because the step above it already does the cleanup, and the other points at the flow the same page describes. A comment claiming about sixty builtin recipes now names the listing function instead of a number, because the count in this tree is 78 rather than the 68 the register records.
Two more invented verbs are flagged but deliberately left: a scaffolding command in two tutorials and a credential-printing command across five pages. Both need a decision to build or rewrite, not a one-line edit.
Verification: clippy
-D warningsclean across the crates touched; connector, cooperation and runtime suites green;cargo fmt --checkclean; the dependency tree shows one patched version; frontend typecheck, lint and build pass; and the working tree is clean after a test run.🤖 Generated with Claude Code
https://claude.ai/code/session_018M415coMKAv5V2xJQsaSf8