typedJSONValue marshaled a typed value and then routed the result through
rawJSONValue, which runs json.Valid before decoding. On that path the input is
whatever json.Marshal has just produced, so the validation scan can only ever
succeed: it re-read every marshaled document for nothing.
The decode step is now shared by both entry points. rawJSONValue keeps its
json.Valid check, because it still accepts untrusted input, while typedJSONValue
decodes what it marshaled directly. Across the 1121-tool set this removes about a
third of the Schema Catalog projection work: the internal/app schema suite goes
from 26.0s to 17.2s uninstrumented, and from 291.1s to 241.0s under -race.
The delivered Catalog is byte-for-byte unchanged. check-generated-drift,
check-schema-catalog and check-schema-binary each regenerate the same
source_hash sha256:93b8d44eb163bd2898c78397d22af92d378e3dc4e20f56b33277b51e4342e2e6,
and the two error contracts are preserved: typedJSONValue still rejects a value
json.Marshal cannot encode, and rawJSONValue still rejects invalid JSON.
Completes the wait capability per review guidance ("add corresponding
execution hooks and fallback tests for the modes"):
- contract.WaitSpec restores event/auto modes with event_key,
match_field, and a new resource_query (dotted path into the accepted
result data yielding the identifier events correlate against);
per-mode validation of required fields
- internal/wait adds EventStream (leaf-owned transport) and RunEvent:
correlated-event filtering, the same terminal/pending/unknown mapping
as polling, timed-out pending on deadline during consumption, and an
ErrEventStreamEnded sentinel distinguishing stream termination from
fail-closed status errors
- Spec.WaitEvents hook; validateWaitDecl pairs mode with hooks
(poll<->WaitPoll, event<->WaitEvents, auto<->both; surplus hooks
rejected too)
- the wait phase runs event-first in auto mode and falls back to polling
when the stream ends or the subscription fails, under one deadline
spanning both phases; strict event mode surfaces stream errors
- output.CommandResult gains Data() (deep copy) so the framework can
resolve the resource identifier without exposing mutable state
Changed-code coverage re-verified at 100% (CI cross-package recipe).
Addresses the three P1 findings from review 4942891040:
1. event/auto modes were declared but always executed polls. WaitSpec now
accepts poll only (event/auto fail validation with a not-implemented
message); event_key/match_field dead fields removed. Event waiting will
land with its own execution path and mode constant.
2. a deadline reached during the between-poll sleep re-polled with a
cancelled context, so a context-aware poller surfaced its error as a poll
failure instead of the contracted timed-out pending. The wait between
polls now uses a timer + select on ctx.Done(), the deadline is checked
before each poll, and a poll error on a cancelled context closes as
timed-out pending with the last observed status.
3. legacy Invoke/Orchestrate/RunE commands declaring Wait observed a failure
terminal while still exiting 0. validateWaitDecl now requires the
ResultInvoke dispatcher (the only path whose unified envelope can be
closed); the wait phase no longer wraps legacy paths.
Also: dropped the unreachable nonPendingTerminal branch, simplified
waitTimeoutSecs to the flag value (registration always seeds the reviewed
default), and raised changed-code coverage to 100% (new wait-engine edge
tests, output With* unit tests, contractfinal deep-copy coverage,
AttachContract invalid-Wait panic path).
Every neighbouring string in the root help listing — service
descriptions, utility descriptions, global flag usage — is hardcoded
Chinese. Routing only the feedback label through i18n therefore rendered
it in English on any host whose LANG is not zh_*, leaving a lone English
line inside an otherwise Chinese screen.
Hardcode the label and drop the two locale entries it needed. A test
assertion now pins the Chinese label so the indirection cannot return
unnoticed.
`dws --help` now closes with a Feedback section that links the
user-experience survey form, tagged with source=dws-cli so submissions
arriving through the CLI can be told apart from other channels.
The entry is deliberately root-only: this CLI is driven mostly by AI
agents, and repeating a survey link in every subcommand help would be
pure context noise. A guard test pins that boundary.
The URL is printed on its own unwrapped line — it is longer than the
help rule width, and breaking it would stop terminals from recognizing
it as a clickable hyperlink.