Parent: #2129
Blocked by: #2135. Wave 2; gestures.ts is an importer owned by the snapshot scroll child and must be updated there first.
Scope — exact tracked files
Production:
src/utils/keyboard-actions.ts
src/utils/merge-flags.ts
src/utils/parse-timeout.ts
src/utils/payload-input.ts
src/utils/project-runtime.ts
src/utils/session-binding.ts
src/utils/string-enum.ts
src/utils/truncate-utf8.ts
src/utils/type-target-warning.ts
src/utils/validation.ts
Tests:
src/utils/__tests__/device.test.ts
src/utils/__tests__/interactors.test.ts
src/utils/__tests__/perf-args.test.ts
src/utils/__tests__/truncate-utf8.test.ts
Destination and importer edits
Move the modules to these exact owning locations:
keyboard-actions.ts -> src/daemon/keyboard-actions.ts
merge-flags.ts -> src/cli-schema/merge-flags.ts
parse-timeout.ts -> src/core/parse-timeout.ts
payload-input.ts -> src/core/payload-input.ts
project-runtime.ts -> src/core/project-runtime.ts
session-binding.ts -> src/cli/session-binding.ts
string-enum.ts -> src/commands/observability/string-enum.ts
truncate-utf8.ts -> src/commands/interaction/runtime/truncate-utf8.ts
type-target-warning.ts -> src/daemon/type-target-warning.ts
validation.ts -> src/core/validation.ts
Move tests to mirror their owning source:
src/core/__tests__/device.test.ts
src/core/__tests__/interactors.test.ts
src/cli/parser/__tests__/perf-args.test.ts
src/commands/interaction/runtime/truncate-utf8.test.ts
Update exact production importers:
src/commands/system/runtime/system.ts, src/daemon/keyboard-runtime.ts, src/daemon/session-event-action-presentation.ts -> keyboard actions
src/cli-schema/cli-config.ts, src/cli/parser/args.ts, src/cli/resolve-cli-options.ts, src/mcp/tool-input-config.ts -> merge flags
src/core/wait-positionals.ts, src/daemon/handlers/snapshot-alert.ts -> parse timeout
src/core/dispatch-payload.ts, src/daemon/handlers/session-app-deployment.ts -> payload input
src/daemon/handlers/session-doctor-options.ts, src/metro/client-metro.ts -> project runtime
src/cli.ts -> session binding
src/commands/observability/index.ts -> string enum
src/commands/interaction/runtime/resolution.ts -> UTF-8 truncation
src/daemon/type-text-runtime.ts -> type-target warning
src/commands/interaction/runtime/gestures.ts, src/commands/observability/runtime/diagnostics.ts, src/commands/recording/runtime/recording.ts, src/commands/system/runtime/system.ts, src/daemon/focus-runtime.ts, src/daemon/touch-runtime.ts, src/daemon/tv-remote-runtime.ts, src/daemon/type-text-runtime.ts -> validation
Update the direct test imports for parse-timeout and the moved modules. Do not add a commands/common, src/shared, or package utility replacement.
Behavior invariants
Preserve strict flag merge precedence, timeout numeric acceptance, payload inline-vs-file resolution and typed errors, project runtime detection, session/platform binding and lock refusal, strict enum membership, UTF-8 byte-safe truncation, mistargeted type-ref warning detection, integer/point validation, and keyboard action vocabulary. Preserve all command schemas, error codes/messages, and CLI/MCP input audience rules.
The destination must follow the existing layer spine: daemon may consume core, commands may consume core, and CLI schema owns flag merging. No new fallback or compatibility path.
Focused validation
Run:
pnpm vitest run src/core/__tests__/device.test.ts src/core/__tests__/interactors.test.ts src/cli/parser/__tests__/perf-args.test.ts src/commands/interaction/runtime/truncate-utf8.test.ts
- the existing CLI config, snapshot-alert, payload, Metro, observability, and runtime validation tests that exercise each importer
pnpm check:affected --run
Planted-red proof
No new structural rule is added. Temporarily make requireIntInRange accept an out-of-range value and observe the validation test fail; temporarily make mergeDefinedFlags overwrite a defined target and observe the CLI config test fail. Restore both before the green run. The test move must not turn an implementation self-comparison into proof.
Dependency order
Start only after #2135. The terminal child is blocked by this child. Surface-output and pure-facet children may proceed independently once their own dependencies are satisfied.
Shrink target
Delete all ten old production utility files and four old tests. Place each rule beside its owning command/core/daemon surface without a new shared layer; after discounting physical moves, production LOC must not grow and no old src/utils import may remain.
Parent: #2129
Blocked by: #2135. Wave 2;
gestures.tsis an importer owned by the snapshot scroll child and must be updated there first.Scope — exact tracked files
Production:
src/utils/keyboard-actions.tssrc/utils/merge-flags.tssrc/utils/parse-timeout.tssrc/utils/payload-input.tssrc/utils/project-runtime.tssrc/utils/session-binding.tssrc/utils/string-enum.tssrc/utils/truncate-utf8.tssrc/utils/type-target-warning.tssrc/utils/validation.tsTests:
src/utils/__tests__/device.test.tssrc/utils/__tests__/interactors.test.tssrc/utils/__tests__/perf-args.test.tssrc/utils/__tests__/truncate-utf8.test.tsDestination and importer edits
Move the modules to these exact owning locations:
keyboard-actions.ts->src/daemon/keyboard-actions.tsmerge-flags.ts->src/cli-schema/merge-flags.tsparse-timeout.ts->src/core/parse-timeout.tspayload-input.ts->src/core/payload-input.tsproject-runtime.ts->src/core/project-runtime.tssession-binding.ts->src/cli/session-binding.tsstring-enum.ts->src/commands/observability/string-enum.tstruncate-utf8.ts->src/commands/interaction/runtime/truncate-utf8.tstype-target-warning.ts->src/daemon/type-target-warning.tsvalidation.ts->src/core/validation.tsMove tests to mirror their owning source:
src/core/__tests__/device.test.tssrc/core/__tests__/interactors.test.tssrc/cli/parser/__tests__/perf-args.test.tssrc/commands/interaction/runtime/truncate-utf8.test.tsUpdate exact production importers:
src/commands/system/runtime/system.ts,src/daemon/keyboard-runtime.ts,src/daemon/session-event-action-presentation.ts-> keyboard actionssrc/cli-schema/cli-config.ts,src/cli/parser/args.ts,src/cli/resolve-cli-options.ts,src/mcp/tool-input-config.ts-> merge flagssrc/core/wait-positionals.ts,src/daemon/handlers/snapshot-alert.ts-> parse timeoutsrc/core/dispatch-payload.ts,src/daemon/handlers/session-app-deployment.ts-> payload inputsrc/daemon/handlers/session-doctor-options.ts,src/metro/client-metro.ts-> project runtimesrc/cli.ts-> session bindingsrc/commands/observability/index.ts-> string enumsrc/commands/interaction/runtime/resolution.ts-> UTF-8 truncationsrc/daemon/type-text-runtime.ts-> type-target warningsrc/commands/interaction/runtime/gestures.ts,src/commands/observability/runtime/diagnostics.ts,src/commands/recording/runtime/recording.ts,src/commands/system/runtime/system.ts,src/daemon/focus-runtime.ts,src/daemon/touch-runtime.ts,src/daemon/tv-remote-runtime.ts,src/daemon/type-text-runtime.ts-> validationUpdate the direct test imports for
parse-timeoutand the moved modules. Do not add acommands/common,src/shared, or package utility replacement.Behavior invariants
Preserve strict flag merge precedence, timeout numeric acceptance, payload inline-vs-file resolution and typed errors, project runtime detection, session/platform binding and lock refusal, strict enum membership, UTF-8 byte-safe truncation, mistargeted type-ref warning detection, integer/point validation, and keyboard action vocabulary. Preserve all command schemas, error codes/messages, and CLI/MCP input audience rules.
The destination must follow the existing layer spine: daemon may consume core, commands may consume core, and CLI schema owns flag merging. No new fallback or compatibility path.
Focused validation
Run:
pnpm vitest run src/core/__tests__/device.test.ts src/core/__tests__/interactors.test.ts src/cli/parser/__tests__/perf-args.test.ts src/commands/interaction/runtime/truncate-utf8.test.tspnpm check:affected --runPlanted-red proof
No new structural rule is added. Temporarily make
requireIntInRangeaccept an out-of-range value and observe the validation test fail; temporarily makemergeDefinedFlagsoverwrite a defined target and observe the CLI config test fail. Restore both before the green run. The test move must not turn an implementation self-comparison into proof.Dependency order
Start only after #2135. The terminal child is blocked by this child. Surface-output and pure-facet children may proceed independently once their own dependencies are satisfied.
Shrink target
Delete all ten old production utility files and four old tests. Place each rule beside its owning command/core/daemon surface without a new shared layer; after discounting physical moves, production LOC must not grow and no old
src/utilsimport may remain.