fix(manifest): reject blank module names at parse - #96
Merged
Conversation
AI Assistance: Claude Fable 5 used for implementation and tests
AI Assistance: Claude Opus 5 used for red-team review and test hardening
This was referenced Aug 6, 2026
runtime: consolidate the post-train seams (builder tail, Role vocabulary, load-path convergence)
#94
Closed
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.
What
Reject a manifest
[module].namethat is missing, empty, or whitespace-only at parse time, instead of letting it fall through to a fallback namespace later.validate_module_namenow runs aname.trim().is_empty()check before the existing path-safety check, so the refusal fires before the component-digest parse and before the[capabilities]gate.Adds a new
ParseError::BlankModuleNamevariant, unit tests covering absence/empty/whitespace-only names (including tab and newline via TOML escapes), an integration test asserting the refusal happens before any component read for both the provider and worker boot roles, and two README lines documenting the requirement.Why
An empty manifest name never reached downstream validation: the supervisor substituted a fallback namespace (
"provider"or"module") before extensions ever saw it, so a blank-named adapter could silently install under an indistinguishable shared namespace, and a second blank-named adapter was refused as a duplicate rather than as a bad name.Closes #78
Testing
Independent gate on a fresh clone of nullislabs/nexum-runtime, detached at origin/seam/c1-reject-blank-names.
Provenance verified against the live remote: HEAD matches refs/heads/seam/c1-reject-blank-names, base origin/main is a strict ancestor, range is 2 commits, 4 files, +59/-3.
Full CI-parity battery, every step inside nix develop --command (rustc 1.94.0, nextest 0.9.127):
cargo fmt --all -- --check: clean.
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings: clean.
just build (engine + example + 3 example modules + 6 wasm fixtures): clean.
CI=1 cargo nextest run --workspace --all-features --locked: 649 run, 649 passed, 0 skipped, 0 failed.
cargo test --doc --workspace --all-features --locked: all doctest targets ok, 0 failed.
RUSTDOCFLAGS='-D warnings' cargo doc --workspace --no-deps --locked: clean.
just test-e2e: 11 run, 11 passed, 405 filtered out (expected: recipe filters to supervisor::tests::e2e + digest::e2e_).
Em-dash scan of added lines: zero hits.
AI Assistance
implement claude-fable-5, red-team claude-opus-5, PR claude-sonnet-5