Browse Source

G-011: review-driven refinements - testable fact key, choke-point surface, backend default, stty-state disposition

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
master
Julian Noble 2 weeks ago
parent
commit
4501c37723
  1. 2
      GOALS.md
  2. 30
      goals/G-011-console-stderr-semantics.md

2
GOALS.md

@ -114,4 +114,4 @@ Acceptance: from a grandchild subshell a single switch command reaches the grand
Scope: src/modules/punk/console-999999.0a1.0.tm, src/modules/opunk/console-999999.0a1.0.tm, src/modules/punk/repl-999999.0a1.0.tm Scope: src/modules/punk/console-999999.0a1.0.tm, src/modules/opunk/console-999999.0a1.0.tm, src/modules/punk/repl-999999.0a1.0.tm
Detail: goals/G-011-console-stderr-semantics.md Detail: goals/G-011-console-stderr-semantics.md
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. 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.

30
goals/G-011-console-stderr-semantics.md

@ -2,7 +2,7 @@
Status: proposed Status: proposed
Scope: src/modules/punk/console-999999.0a1.0.tm, src/modules/opunk/console-999999.0a1.0.tm, src/modules/punk/repl-999999.0a1.0.tm Scope: src/modules/punk/console-999999.0a1.0.tm, src/modules/opunk/console-999999.0a1.0.tm, src/modules/punk/repl-999999.0a1.0.tm
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 ## Context
@ -51,10 +51,14 @@ untouched.
only for contexts where no console is in play (e.g module-load-time warnings). 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 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 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. consumer such as punk::repl. The two consumer-shaped clauses divide deliberately: the
6. **Cross-thread discovery.** The effective err is exposed through console_fact_get so any internal diagnostics migration (item 4) proves the abstraction serves its own first
thread/interp of a session can answer "where do this console's diagnostics go" (G-007 consumer and is self-contained; the external consumer proves the *public* emit form is
location transparency extends to the err attribute). 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 ## Alternatives considered
@ -74,13 +78,27 @@ untouched.
## Notes ## 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:
console_spec_resolve, internal::hybrid_console_spec, internal::opt_console_out /
opt_console_channels (+_var variants), internal::spec_to_channelpair, and the shared PUNKARGS
fragments ::punk::console::argdoc::console_opts / console_emit_opts. Accepting the 3-element
form there satisfies "every -console site" by construction; a site that bypasses these
helpers is already a convention violation to be fixed on discovery, not a reason to audit
the whole module up front.
- **Channel-name locality.** Like in/out, an err channel name is thread-local for non-std - **Channel-name locality.** Like in/out, an err channel name is thread-local for non-std
channels; the fact-store exposure inherits the owner-qualified keying that already handles channels; the fact-store exposure inherits the owner-qualified keying that already handles
this for other facts. What is discoverable cross-thread is the owner-context name (and the this for other facts. What is discoverable cross-thread is the owner-context name (and the
default-console case, where std names are process-wide). default-console case, where std names are process-wide).
- **G-001 interaction.** G-001's acceptance requires the base class unchanged *by G-001's own - **G-001 interaction.** G-001's acceptance requires the base class unchanged *by G-001's own
work*; the nullable err field is an additive change made by this goal. If G-011 lands first, work*; the nullable err field is an additive change made by this goal. If G-011 lands first,
G-001 subclasses simply inherit the field; sequencing either way is safe. G-001 subclasses simply inherit the field; sequencing either way is safe. Backend authors
should note the default is "merge into out": a backend with a genuinely distinct diagnostic
stream (e.g a separate ssh extended-data channel or a dedicated tk widget pane) must set err
explicitly at construction to get separation.
- **previous_stty_state_stderr stays as-is.** It preserves stty state of the process stderr fd
across raw-mode cycling - terminal-mode restoration, orthogonal to diagnostic output routing.
This goal adds nothing to it and removes nothing from it.
- **G-008/G-009 interaction.** Once err exists, a per-subshell re-route of diagnostics is - **G-008/G-009 interaction.** Once err exists, a per-subshell re-route of diagnostics is
console state that a G-008 state set could capture; that is enrichment for those goals, not console state that a G-008 state set could capture; that is enrichment for those goals, not
part of this goal's acceptance. part of this goal's acceptance.

Loading…
Cancel
Save