ADR 0044 - Wire Namespace Use Imports
Adds explicit `use` imports for registry namespaces so standard Wire packs can be brought into source scope without weakening registry-based authority.
On this page
ADR 0044 - Wire Namespace Use Imports
Status
Proposed - this ADR defines explicit namespace imports for registry-backed Wire packs, initially
scoped to std.io.
Context
Wire already has file imports:
import { acceptedItem } from "./helpers.wire";
Those imports are about source files and exported let bindings. They are not the right mechanism
for names that come from a registered executor and contract catalog.
The standard IO pack needs a visible source dependency without turning standard host effects into CorePure builtins or globally ambient names. At the same time, ADR 0010’s closed-authority rule should remain intact: runtime authority is admitted by the host registry, not by syntax alone.
Decision
Wire gains a top-level registry-namespace import form:
use std.io.{@stdin, @stdout, @command, @readFile, @writeFile, CommandSpec, CommandResult};
Selectors are explicit. Executor leaves carry the @ marker; contracts do not:
use std.io.{@command as @shell, CommandSpec as Spec};
The imported local names may then be used in executor and port positions:
node run_check
<- spec: Spec;
-> result: CommandResult = @shell {} (spec);
The use form is a source-scope dependency, not a replacement for registry authority. It decides
which standard-pack names are referenceable in a Wire file. The host still decides whether
std.io.command exists, what effect class it has, and whether it is bound at runtime.
For v1:
std.iois the only implemented registry namespace.@std.io.stdin,@std.io.stdout,@std.io.command,@std.io.readFile, and@std.io.writeFilerequire an explicituse std.io.{...};in the same file before they can be referenced.- Bare
@stdin,@stdout,@command,@readFile, and@writeFileresolve only when imported byuse. - Imported aliases lower to canonical executor and contract IDs in compiled metadata.
usedoes not propagate across file imports; each source file declares its own registry namespace dependencies.- Wildcards are not admitted.
use std.io.*;is intentionally invalid in v1.
This keeps source dependencies auditable while preserving the registry as the runtime authority gate.
Alternatives Considered
- Make
std.ioglobally ambient - rejected because standard effects would become invisible dependencies in source. - Use file
importfor registry names - rejected because file imports and registry catalogs have different identity, authority, and loading rules. - Gate every registered executor through
useimmediately - deferred. Existing non-standard executor names remain fully qualified registry references so this change does not widen the migration blast radius. - Admit wildcard imports - rejected for v1. The standard pack is small, and explicit selectors make host-effect dependencies easier to review.
- Put
@on namespace roots - rejected. The authority marker belongs to executor leaves:std.io.{@command}, not@std.io.{command}.
Consequences
Positive
- Standard host effects are visible as source dependencies.
- Local aliases improve ergonomics without changing canonical compiled IDs.
- The pure core stays free of hidden IO names.
- File imports and registry namespace imports have separate syntax and separate semantics.
Negative
- Wire now has two top-level import-like forms.
- Standard-pack names have stricter source-scope rules than existing non-standard executor names.
- Aliased source names require compiled metadata and diagnostics to preserve canonical IDs.
Obligations
- Keep diagnostics clear when a
std.ioexecutor is referenced withoutuse. - Keep
useselector lists explicit until a later ADR admits wildcard semantics. - Keep canonical compiled executor IDs stable even when source uses aliases.
- Document std pack contracts and executor projections in Haskell library APIs so host authors do not copy string literals.