Acceptance now names the discovery fact (console_fact_get fact key err,
returning the effective err channel name) so the clause is testable like
G-007's named facts. Detail file additions: "every -console site" is
satisfied at the module's documented resolution choke points
(console_spec_resolve, hybrid_console_spec, opt_console_* helpers,
spec_to_channelpair, shared PUNKARGS fragments) rather than by per-site
audit; the two consumer-shaped acceptance clauses' division of labour is
stated (internal diagnostics migration = first consumer, external consumer
= public emit form); G-001 backends wanting a distinct diagnostic stream
must set err explicitly (default merges into out); and
previous_stty_state_stderr stays as-is (stty-state restoration, orthogonal
to diagnostic routing).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
Goal: a console optionally carries an err channel as an attribute of its canonical {in out} identity - {in out err} specs accepted everywhere -console is, err resolving to process stderr for the default console and to the console's out channel elsewhere - so diagnostics and emit-to-err are first-class per-console operations instead of raw puts stderr.
Acceptance: console_spec_resolve and every -console site accept an {in out err} spec (err optional; existing pair/instance-name/object spec forms unchanged); opunk::Console exposes the err channel (nullable, additive base-class change); an unset err resolves to stderr for the default console and to the console's own out channel otherwise; punk::console's own warnings/diagnostics emitted while operating on a resolvable console go to that console's err (raw puts stderr remains only where no console is in play); an emit-to-err path exists and is exercised by at least one real consumer (e.g punk::repl); the effective err is discoverable from any thread/interp via console_fact_get; ownership/fact/mode-cache keys remain canonical {in out}; the existing console test suites pass unchanged.
Acceptance: console_spec_resolve and every -console site accept an {in out err} spec (err optional; existing pair/instance-name/object spec forms unchanged); opunk::Console exposes the err channel (nullable, additive base-class change); an unset err resolves to stderr for the default console and to the console's own out channel otherwise; punk::console's own warnings/diagnostics emitted while operating on a resolvable console go to that console's err (raw puts stderr remains only where no console is in play); an emit-to-err path exists and is exercised by at least one real consumer (e.g punk::repl); the effective err is discoverable from any thread/interp via console_fact_get (fact key err, returning the effective err channel name); ownership/fact/mode-cache keys remain canonical {in out}; the existing console test suites pass unchanged.
Acceptance: console_spec_resolve and every -console site accept an {in out err} spec (err optional; existing pair/instance-name/object spec forms unchanged); opunk::Console exposes the err channel (nullable, additive base-class change); an unset err resolves to stderr for the default console and to the console's own out channel otherwise; punk::console's own warnings/diagnostics emitted while operating on a resolvable console go to that console's err (raw puts stderr remains only where no console is in play); an emit-to-err path exists and is exercised by at least one real consumer (e.g punk::repl); the effective err is discoverable from any thread/interp via console_fact_get; ownership/fact/mode-cache keys remain canonical {in out}; the existing console test suites pass unchanged.
Acceptance: console_spec_resolve and every -console site accept an {in out err} spec (err optional; existing pair/instance-name/object spec forms unchanged); opunk::Console exposes the err channel (nullable, additive base-class change); an unset err resolves to stderr for the default console and to the console's own out channel otherwise; punk::console's own warnings/diagnostics emitted while operating on a resolvable console go to that console's err (raw puts stderr remains only where no console is in play); an emit-to-err path exists and is exercised by at least one real consumer (e.g punk::repl); the effective err is discoverable from any thread/interp via console_fact_get (fact key err, returning the effective err channel name); ownership/fact/mode-cache keys remain canonical {in out}; the existing console test suites pass unchanged.
## Context
@ -51,10 +51,14 @@ untouched.
only for contexts where no console is in play (e.g module-load-time warnings).
5. **Emit path.** A first-class emit-to-err form (shape decided at implementation time - e.g an
err-target variant of the opt_console_out convention) exercised by at least one real
consumer such as punk::repl, proving subshells can present stderr distinctly.
6. **Cross-thread discovery.** The effective err is exposed through console_fact_get so any
thread/interp of a session can answer "where do this console's diagnostics go" (G-007
location transparency extends to the err attribute).
consumer such as punk::repl. The two consumer-shaped clauses divide deliberately: the
internal diagnostics migration (item 4) proves the abstraction serves its own first
consumer and is self-contained; the external consumer proves the *public* emit form is
usable by subshells wanting to present stderr distinctly.
6. **Cross-thread discovery.** The effective err is exposed through console_fact_get under
fact key `err`, returning the effective err channel name, so any thread/interp of a
session can answer "where do this console's diagnostics go" (G-007 location transparency
extends to the err attribute).
## Alternatives considered
@ -74,13 +78,27 @@ untouched.
## Notes
- **The "-console surface" is the choke points, not per-site edits.** The module's documented
convention already funnels every -console site through a small resolution set: