mustflow 2.108.2 → 2.108.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cli/commands/script-pack.js +3 -0
- package/dist/cli/i18n/en.js +37 -0
- package/dist/cli/i18n/es.js +37 -0
- package/dist/cli/i18n/fr.js +37 -0
- package/dist/cli/i18n/hi.js +37 -0
- package/dist/cli/i18n/ko.js +37 -0
- package/dist/cli/i18n/zh.js +37 -0
- package/dist/cli/lib/command-registry.js +3 -0
- package/dist/cli/lib/script-pack-registry.js +84 -0
- package/dist/cli/script-packs/repo-automation-surface.js +88 -0
- package/dist/cli/script-packs/repo-dependency-surface.js +87 -0
- package/dist/cli/script-packs/repo-toolchain-provenance.js +90 -0
- package/dist/core/public-json-contracts.js +27 -0
- package/dist/core/repo-automation-surface.js +376 -0
- package/dist/core/repo-dependency-surface.js +282 -0
- package/dist/core/repo-toolchain-provenance.js +421 -0
- package/dist/core/script-pack-suggestions.js +33 -1
- package/package.json +1 -1
- package/schemas/README.md +10 -0
- package/schemas/repo-automation-surface-report.schema.json +148 -0
- package/schemas/repo-dependency-surface-report.schema.json +121 -0
- package/schemas/repo-toolchain-provenance-report.schema.json +124 -0
- package/templates/default/i18n.toml +18 -6
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +15 -5
- package/templates/default/locales/en/.mustflow/skills/go-code-change/SKILL.md +98 -22
- package/templates/default/locales/en/.mustflow/skills/python-code-change/SKILL.md +86 -27
- package/templates/default/locales/en/.mustflow/skills/routes.toml +16 -4
- package/templates/default/locales/en/.mustflow/skills/rust-code-change/SKILL.md +51 -32
- package/templates/default/locales/en/.mustflow/skills/split-refactor-residual-path-review/SKILL.md +176 -0
- package/templates/default/locales/en/.mustflow/skills/typescript-code-change/SKILL.md +47 -29
- package/templates/default/locales/en/.mustflow/skills/ui-state-resurrection-review/SKILL.md +218 -0
- package/templates/default/locales/en/.mustflow/skills/version-freshness-check/SKILL.md +14 -13
- package/templates/default/manifest.toml +15 -1
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
mustflow_doc: skill.rust-code-change
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 7
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: rust-code-change
|
|
9
|
-
description: Apply this skill when Rust source, Cargo metadata, features, traits, errors, ownership, async
|
|
9
|
+
description: Apply this skill when Rust source, Cargo metadata, features, traits, errors, ownership, borrowing, lifetimes, Clone/Rc/Arc/Mutex/RefCell use, async tasks, channels, cancellation, unsafe code, allocation, zero-copy, tests, examples, benchmarks, release profiles, MSRV, toolchain declarations, standard-library APIs, or public crate APIs are created or changed.
|
|
10
10
|
metadata:
|
|
11
11
|
mustflow_schema: "1"
|
|
12
12
|
mustflow_kind: procedure
|
|
@@ -28,7 +28,7 @@ metadata:
|
|
|
28
28
|
<!-- mustflow-section: purpose -->
|
|
29
29
|
## Purpose
|
|
30
30
|
|
|
31
|
-
Preserve Rust ownership, error, trait, feature, async runtime, unsafe, and public crate boundaries while making a focused change. A Rust change is successful only when it clarifies
|
|
31
|
+
Preserve Rust ownership, error, trait, feature, async runtime, unsafe, performance, and public crate boundaries while making a focused change. A Rust change is successful only when it clarifies owners, state, failure contracts, and allocation behavior, not when it merely silences the borrow checker.
|
|
32
32
|
|
|
33
33
|
Rust's compiler feedback can be especially useful for AI-assisted work because it rejects many
|
|
34
34
|
invalid states with concrete errors. That benefit has a real cost: compile time, target-directory
|
|
@@ -38,8 +38,8 @@ instead of treated as incidental.
|
|
|
38
38
|
<!-- mustflow-section: use-when -->
|
|
39
39
|
## Use When
|
|
40
40
|
|
|
41
|
-
- `.rs`, `Cargo.toml`, `Cargo.lock`, workspace config, feature flags, public exports, traits, error types, tests, examples, benches, FFI, async runtime, or unsafe code change.
|
|
42
|
-
- The task touches ownership, borrowing, lifetimes, `Clone`, `Arc`, `Mutex`, `unwrap`, or public crate compatibility.
|
|
41
|
+
- `.rs`, `Cargo.toml`, `Cargo.lock`, workspace config, feature flags, public exports, traits, error types, tests, examples, benches, FFI, async runtime, allocation-sensitive code, or unsafe code change.
|
|
42
|
+
- The task touches ownership, borrowing, lifetimes, `Clone`, `Rc`, `Arc`, `Mutex`, `RefCell`, `unwrap`, `anyhow`, `thiserror`, `Box<dyn Error>`, channels, cancellation, zero-copy buffers, or public crate compatibility.
|
|
43
43
|
- The task introduces or reviews Rust-version-gated APIs or language behavior such as `let else`, let chains, match `if let` guards, `cfg_select!`, `assert_matches!`, `core::range`, `Vec::push_mut`, `HashMap::get_disjoint_mut`, `Option::take_if`, `LazyLock`, `OnceLock`, `workspace.lints`, `rust-version`, Rust 2024 lints, or release-profile tuning.
|
|
44
44
|
|
|
45
45
|
<!-- mustflow-section: do-not-use-when -->
|
|
@@ -53,7 +53,7 @@ instead of treated as incidental.
|
|
|
53
53
|
|
|
54
54
|
- `Cargo.toml`, workspace manifests, lockfile policy, toolchain config, rustfmt, clippy, feature flags, docs.rs metadata, optional dependencies, build profiles, target directory or cache policy, and CI hints.
|
|
55
55
|
- Relevant `src/lib.rs`, `src/main.rs`, modules, public re-exports, tests, examples, and docs examples.
|
|
56
|
-
- Existing error handling convention and
|
|
56
|
+
- Existing ownership map, error handling convention, async runtime, task ownership model, channel/backpressure policy, and shutdown or cancellation boundary.
|
|
57
57
|
- Public crate status, minimum supported Rust version, feature support policy, and downstream compatibility expectations when available.
|
|
58
58
|
- `rust-version`, edition, `rust-toolchain.toml`, CI toolchain matrix, target triples, Cargo resolver, workspace inheritance policy, and whether newer standard-library APIs require a raised MSRV.
|
|
59
59
|
- Host and build-loop constraints: OS, shell, native toolchain prerequisites, VM or remote-builder use, release profile, LTO, workspace size, disk budget, and configured smoke or focused-check intents.
|
|
@@ -62,9 +62,9 @@ instead of treated as incidental.
|
|
|
62
62
|
<!-- mustflow-section: preconditions -->
|
|
63
63
|
## Preconditions
|
|
64
64
|
|
|
65
|
-
- Determine whether the change affects ownership flow, public API, feature gates, optional dependencies, error contract, async runtime, or unsafe invariants.
|
|
66
|
-
- Read local patterns before adding traits, lifetimes, clones, locks, boxed errors, feature bounds, or `Send + Sync + 'static` constraints.
|
|
67
|
-
- Treat `clone`, `Arc
|
|
65
|
+
- Determine whether the change affects ownership flow, borrow duration, shared-state meaning, public API, feature gates, optional dependencies, error contract, async runtime, performance hot paths, or unsafe invariants.
|
|
66
|
+
- Read local patterns before adding traits, lifetimes, clones, locks, `Rc<RefCell<_>>`, boxed errors, feature bounds, owned buffers, or `Send + Sync + 'static` constraints.
|
|
67
|
+
- Treat `clone`, `Rc`, `Arc`, `Mutex`, `RefCell`, explicit lifetimes, `'static`, `Box<dyn Error>`, `anyhow`, `unwrap`, feature changes, zero-copy lifetime spread, and `unsafe` as suspicious until their contract impact is justified.
|
|
68
68
|
- Identify the intended edit-check-test loop before choosing a broad build. Treat whole-workspace
|
|
69
69
|
checks, release builds, fat LTO, cross-compiles, and sanitizer-style runs as expensive evidence
|
|
70
70
|
unless the command contract declares them as the normal focused path.
|
|
@@ -73,7 +73,7 @@ instead of treated as incidental.
|
|
|
73
73
|
<!-- mustflow-section: allowed-edits -->
|
|
74
74
|
## Allowed Edits
|
|
75
75
|
|
|
76
|
-
- Prefer truthful ownership and borrowing over broad cloning.
|
|
76
|
+
- Prefer truthful ownership and borrowing over broad cloning, shared mutable bags, or lifetime puzzles.
|
|
77
77
|
- Follow the crate's existing application-versus-library error convention.
|
|
78
78
|
- Keep feature-gated code and public re-exports synchronized.
|
|
79
79
|
- Touch unsafe code only with explicit invariants preserved in nearby comments.
|
|
@@ -86,7 +86,7 @@ instead of treated as incidental.
|
|
|
86
86
|
## Procedure
|
|
87
87
|
|
|
88
88
|
1. Read Cargo metadata, features, optional dependencies, docs.rs metadata, toolchain config, build profiles, public exports, relevant modules, and tests.
|
|
89
|
-
2. Classify the change as ownership, API, error, feature, async, unsafe, dependency, or test-only.
|
|
89
|
+
2. Classify the change as ownership, API, error, feature, async, concurrency, allocation, unsafe, dependency, or test-only.
|
|
90
90
|
3. Model the build loop before broad edits:
|
|
91
91
|
- identify the smallest package, crate, feature set, smoke target, or test that covers the risk;
|
|
92
92
|
- check whether `target/` or an equivalent cache may grow enough to affect local disk budget;
|
|
@@ -108,29 +108,38 @@ instead of treated as incidental.
|
|
|
108
108
|
- treat automatic edition rewrites as candidate diffs that still need human review of unsafe, macro, pattern, temporary lifetime, docs, and examples.
|
|
109
109
|
6. Prefer flatter control flow when the MSRV supports it: use `let else` for early validation, let chains for related optional/result guards, and match `if let` guards for state-machine refinements. Remember that guard patterns do not satisfy match exhaustiveness; keep the fallback arm meaningful.
|
|
110
110
|
7. In tests, prefer `assert_matches!` over `assert!(matches!(...))` when the MSRV supports it and the failed value has useful `Debug` output. Import it explicitly from `std` or `core`; do not assume it is in the prelude.
|
|
111
|
-
8.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
111
|
+
8. Build an ownership ledger before reshaping modules:
|
|
112
|
+
- name the value owner, mutation owner, drop owner, and long-lived storage owner;
|
|
113
|
+
- keep `&T` as short observation, `&mut T` as short exclusive mutation, and `T` as transfer;
|
|
114
|
+
- prefer owned values, ids, handles, indexes, ranges, or offsets for long-lived structs;
|
|
115
|
+
- add explicit lifetimes only when the type is truly a view tied to source data.
|
|
116
|
+
9. Resolve ownership problems in this order: identify the real owner, shrink borrow scopes, fix function signatures to accept references or slices when ownership is unnecessary, distinguish transfer from sharing, then consider clone or shared ownership only when the semantics require it.
|
|
117
|
+
10. Before adding `clone`, verify it is a cheap handle clone such as `Arc`, `Rc`, or `Bytes`, a small intentional value clone, or a true independent ownership split. Reject derived `Clone` that hides shared mutable state, large collection clones, loop clones, clone-then-borrow code, and whole-state clones made only to satisfy `spawn`.
|
|
118
|
+
11. Before adding `Rc`, `Arc`, `Mutex`, or `RefCell`, identify whether the code needs shared ownership, thread crossing, interior mutability, or true shared mutable state. Prefer one owner plus messages or commands when possible; use `Weak` for back edges or cycles; keep `RefCell` and mutex guards short, and do not hold a guard across `.await`, I/O, callbacks, logging hooks, observer calls, or user code.
|
|
119
|
+
12. Before adding `Arc<Mutex<_>>`, verify multiple owners truly need shared mutable state. For read-mostly snapshots, prefer ownership-preserving choices such as `Arc::make_mut`, immutable swaps, atomics, sharded owners, or explicit reload boundaries. Keep critical sections short, document lock order when more than one lock exists, and decide whether poisoning is crash policy, recovery policy, or state-discard policy.
|
|
120
|
+
13. Choose initialization primitives by input and failure semantics: use `LazyLock` for no-argument static lazy values that may poison permanently on panic, and `OnceLock` when boot-time or test-time code supplies the value or panic poisoning must not become the recovery policy.
|
|
121
|
+
14. Avoid hidden allocation when cheaper type contracts fit: use `Cow<'_, str>` or borrowed slices for mostly-borrowed results, query `HashMap<String, V>` with `&str` when `Borrow` supports it, use `Option::take`, `take_if`, or `as_slice` for state transitions and 0-or-1 iteration, and use `ControlFlow`, `try_for_each`, or `try_fold` when visitor or iterator APIs need explicit short-circuiting.
|
|
122
|
+
15. Treat collection and string capacity as part of performance correctness. Use `with_capacity`, `reserve`, `spare_capacity_mut`, or `push_mut` only when the safety and MSRV contract are clear; keep `set_len` inside a small proven unsafe boundary; avoid repeated `String::insert`, front insertion loops, per-item `format!`, unnecessary `collect()`, and temporary `Vec` or `String` construction in hot paths.
|
|
123
|
+
16. Use zero-copy only when the lifetime cost is lower than the copy cost. Prefer borrowed slices for same-call observation, owned values for queue/task/cache/domain storage, and reference-counted buffers such as `Bytes` only when retaining the larger backing allocation is acceptable.
|
|
124
|
+
17. Use explicit lifetimes only to describe real borrow relationships. Do not add `'static` or `T: 'static` to public APIs merely because an internal task boundary requires it. If a self-referential shape appears, first replace internal references with offsets, ranges, ids, or arenas before considering `Pin`, macros, or unsafe.
|
|
125
|
+
18. Use concrete error enums for library APIs when callers need to classify failures. Separate recoverable errors from internal bugs; shape error variants around caller action, not merely dependency type names. Use `thiserror` to implement typed errors, `map_err` to translate lower-level failures, and `source()` to preserve diagnostic cause.
|
|
126
|
+
19. Keep `anyhow` mostly at application, CLI, worker, migration, or top-level orchestration boundaries where errors are logged, enriched with context, and not matched by downstream callers. Use `.context()` or `.with_context()` where `?` would otherwise erase the operation that failed.
|
|
127
|
+
20. Avoid `unwrap`, vague `expect`, and unbounded `panic!` in production paths. They are allowed only for tests, examples, startup policy, panic-boundary adapters, or invariants already proven by nearby code. Do not parse `Display` strings for control flow; match typed variants, error kinds, or stable error codes.
|
|
128
|
+
21. Review public API shape before adding `impl Trait`, `Deref`, or trait/lifetime machinery:
|
|
121
129
|
- argument-position `impl Trait` removes caller turbofish control and can be a public breaking change when converted from named generics;
|
|
122
130
|
- return-position `impl Trait` hides one concrete type, so divergent iterator or future branches need an enum, boxed trait object, or different API boundary;
|
|
123
131
|
- implement `Deref` only for pointer-like wrappers, not domain inheritance or method forwarding;
|
|
124
132
|
- use GATs for borrowing iterator/view traits when they remove a real allocation or boxed lifetime escape, not as decorative complexity.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
22. If feature flags or Cargo workspace metadata change, treat default features, no-default builds, all-features builds, optional dependency implicit features, resolver behavior, target-specific dependencies, `workspace.package`, `workspace.dependencies`, `workspace.lints`, public re-exports, docs examples, and feature-gated trait impls as compatibility surfaces. Features should be additive, and `resolver = "2"` or a newer resolver decision must match the crate's edition/MSRV policy.
|
|
134
|
+
23. Treat public re-exports, public dependency types, generic bounds, trait item sets, error enum variants, `#[non_exhaustive]`, sealed versus externally implementable traits, and MSRV as public API. Tightened bounds, added required trait methods, removed re-exports, changed error variants, public dependency upgrades, or raised `rust-version` require compatibility review.
|
|
135
|
+
24. Do not mix async runtimes. A Tokio crate should not casually gain `async-std` or runtime-specific APIs in library core. Do not call blocking I/O or CPU-heavy work in async paths without an established boundary such as async-native APIs, bounded `spawn_blocking`, a semaphore, a dedicated worker, or a caller-owned runtime decision.
|
|
136
|
+
25. For async spawning, avoid leaking internal `Send + Sync + 'static` requirements into public APIs. Prefer owned task state, smaller spawn boundaries, local task structures, or caller-owned runtime decisions. Track every spawned task's owner, join/abort policy, panic handling, cancellation signal, and shutdown wait point.
|
|
137
|
+
26. Review async channels and cancellation as reliability contracts: prefer bounded channels unless unbounded memory growth is explicitly acceptable; define full-queue behavior, `send` failure handling, `recv None` shutdown behavior, sender clone lifecycle, timeout target, and whether `select!` branches are cancel-safe.
|
|
138
|
+
27. Touch `unsafe` only when a safe design cannot express the required behavior. Every unsafe block needs a nearby `SAFETY:` explanation; every public `unsafe fn` needs `# Safety` docs. In Rust 2024 or when `unsafe_op_in_unsafe_fn` is enabled, unsafe operations inside `unsafe fn` still need explicit unsafe blocks. Keep unsafe scopes small and wrap them in safe abstractions only when callers have no hidden safety obligations.
|
|
139
|
+
28. For FFI, keep Rust ABI types out of C boundaries. Use explicit ownership, `#[repr(C)]` where required, raw pointer plus length pairs, `CStr`/`CString`, RAII wrappers, null handling, panic boundaries, and documented thread-safety evidence before manual `Send` or `Sync`.
|
|
140
|
+
29. Review release profiles when the task changes binary delivery, CLI startup, embedded, wasm, or performance behavior. Treat `opt-level`, LTO, `panic`, `codegen-units`, and `strip` as product tradeoffs that must be measured or reported, not decorative Cargo knobs.
|
|
141
|
+
30. Calibrate performance claims. Do not claim Rust made a system faster from compile success, empty-database timings, warm-cache microbenchmarks, local-only runs, or debug versus release confusion. Require representative data size, concurrency, target hardware, profile, and measurement method before reporting speed claims. Prefer Criterion-style or macrobenchmark evidence when adding benchmark-backed claims, and state whether allocation count, copy count, lock contention, syscall count, p95/p99 latency, or throughput changed.
|
|
142
|
+
31. Choose configured verification intents that cover format, lint, build, tests, feature combinations, docs, public API, unsafe, FFI, smoke targets, package artifact, benchmark evidence, and release-profile risk when available.
|
|
134
143
|
|
|
135
144
|
<!-- mustflow-section: rejection-criteria -->
|
|
136
145
|
## Review Rejection Criteria
|
|
@@ -138,7 +147,11 @@ instead of treated as incidental.
|
|
|
138
147
|
Reject or revise the patch when any of these appear without strong local justification:
|
|
139
148
|
|
|
140
149
|
- New large `clone()` calls, clone-then-borrow code, loop clones, or state clones used only to appease ownership errors.
|
|
141
|
-
- New `
|
|
150
|
+
- New `#[derive(Clone)]` on types that contain shared mutable state without an explicit handle-versus-snapshot decision.
|
|
151
|
+
- New long-lived `struct Foo<'a>` fields, self-referential shapes, or public `'static` bounds that export an internal borrow or task workaround.
|
|
152
|
+
- New `Rc<RefCell<_>>` object graphs, `Rc` cycles without `Weak`, `RefCell` guards held across callbacks, or runtime borrow panics treated as normal control flow.
|
|
153
|
+
- New `Arc<Mutex<AppState>>`-style shared bags, locks held across `.await`, I/O, callbacks, logging hooks, or user code, or async I/O resources shared mainly by mutex.
|
|
154
|
+
- New unbounded channels, detached `tokio::spawn` work, timeout wrappers that only stop waiting, blocking work on an async executor, or shutdown paths that signal without waiting.
|
|
142
155
|
- New version-gated Rust API usage without API-specific MSRV, `rust-version`, edition, toolchain, CI, or fallback evidence.
|
|
143
156
|
- Rust 2024 edition changes accepted without reviewing unsafe extern blocks, unsafe attributes, `unsafe_op_in_unsafe_fn`, temporary drop scopes, and macro fragment behavior where those surfaces exist.
|
|
144
157
|
- New `LazyLock` initialization for recoverable runtime configuration where permanent panic poisoning would be the wrong failure policy.
|
|
@@ -146,7 +159,11 @@ Reject or revise the patch when any of these appear without strong local justifi
|
|
|
146
159
|
- New public `impl Trait`, `Deref`, GAT, workspace resolver, feature, or `rust-version` change without public API and compatibility review.
|
|
147
160
|
- New public `'static`, `Send`, or `Sync` bounds that exist only because an internal task was spawned.
|
|
148
161
|
- New public `Box<dyn Error>` in a library where callers need typed failures.
|
|
162
|
+
- New library `anyhow::Result` where downstream callers need stable classification, transparent dependency errors that leak implementation, or error variants named only after dependency crates.
|
|
149
163
|
- New production `unwrap` or vague `expect` on I/O, parse, environment, network, FFI, lock, or user input paths.
|
|
164
|
+
- New string-parsed error control flow instead of typed error variants, error kinds, or stable codes.
|
|
165
|
+
- New zero-copy lifetime spread that makes queues, tasks, caches, or domain objects borrow input buffers longer than the source owner can guarantee.
|
|
166
|
+
- New hot-path `format!`, `.to_string()`, unnecessary `collect()`, temporary `Vec`, repeated allocation, or debug-build performance claim without measurement evidence.
|
|
150
167
|
- New unbounded `panic!` paths, index assumptions, or unchecked slicing in production paths without a documented invariant or panic boundary.
|
|
151
168
|
- Feature changes that remove APIs, change type meaning, rename features, expose internal optional dependency names, or fail default/no-default/all-features reasoning.
|
|
152
169
|
- Public dependency types, re-exports, trait bounds, trait methods, or error enum variants changed without semver review.
|
|
@@ -162,8 +179,9 @@ Reject or revise the patch when any of these appear without strong local justifi
|
|
|
162
179
|
- Rust-version-gated syntax, standard-library APIs, Cargo behavior, and lint assumptions match the declared MSRV or have explicit fallbacks.
|
|
163
180
|
- Public API, features, optional dependencies, and error contracts are synchronized.
|
|
164
181
|
- Async runtime ownership is preserved and blocking work is isolated.
|
|
182
|
+
- Task ownership, channel capacity, cancellation, timeout, and shutdown wait points are explicit when async code changes.
|
|
165
183
|
- Unsafe, `unsafe_op_in_unsafe_fn`, and FFI invariants are preserved or no unsafe code was touched.
|
|
166
|
-
- Allocation, initialization, Cargo workspace, and release-profile choices are intentional and reported when they affect public or delivery behavior.
|
|
184
|
+
- Allocation, zero-copy, initialization, Cargo workspace, and release-profile choices are intentional and reported when they affect public, hot-path, or delivery behavior.
|
|
167
185
|
- Build-loop cost, target/cache impact, smoke-target coverage, and native toolchain prerequisites
|
|
168
186
|
are handled or reported.
|
|
169
187
|
- Missing feature, semver, docs, unsafe, FFI, smoke, package, or performance verification is reported.
|
|
@@ -215,6 +233,7 @@ When configured intents exist for these risks, prefer coverage equivalent to:
|
|
|
215
233
|
- Boundary checked
|
|
216
234
|
- Build-loop, cache, smoke target, and toolchain notes
|
|
217
235
|
- Ownership, feature, async, or unsafe impact
|
|
236
|
+
- Allocation, zero-copy, channel, cancellation, or benchmark impact
|
|
218
237
|
- Public API or error impact
|
|
219
238
|
- Files changed
|
|
220
239
|
- Command intents run
|
package/templates/default/locales/en/.mustflow/skills/split-refactor-residual-path-review/SKILL.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
mustflow_doc: skill.split-refactor-residual-path-review
|
|
3
|
+
locale: en
|
|
4
|
+
canonical: true
|
|
5
|
+
revision: 1
|
|
6
|
+
lifecycle: mustflow-owned
|
|
7
|
+
authority: procedure
|
|
8
|
+
name: split-refactor-residual-path-review
|
|
9
|
+
description: Apply this skill when a refactor splits files, extracts handlers, moves event ownership, relocates state mutations, or claims a responsibility moved, and the review must prove old execution paths, listeners, effects, dispatches, imports, feature-flag fallbacks, tests, and lifecycle cleanup no longer keep the previous behavior alive.
|
|
10
|
+
metadata:
|
|
11
|
+
mustflow_schema: "1"
|
|
12
|
+
mustflow_kind: procedure
|
|
13
|
+
pack_id: mustflow.core
|
|
14
|
+
skill_id: mustflow.core.split-refactor-residual-path-review
|
|
15
|
+
command_intents:
|
|
16
|
+
- changes_status
|
|
17
|
+
- changes_diff_summary
|
|
18
|
+
- lint
|
|
19
|
+
- build
|
|
20
|
+
- test_related
|
|
21
|
+
- test
|
|
22
|
+
- test_audit
|
|
23
|
+
- docs_validate_fast
|
|
24
|
+
- test_release
|
|
25
|
+
- mustflow_check
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Split Refactor Residual Path Review
|
|
29
|
+
|
|
30
|
+
<!-- mustflow-section: purpose -->
|
|
31
|
+
## Purpose
|
|
32
|
+
|
|
33
|
+
Review file-splitting and responsibility-moving refactors by proving the old path lost authority.
|
|
34
|
+
|
|
35
|
+
The main question is not "was a nicer new module added?" It is "can the old file, handler, listener, effect, dispatch, mutation, route, middleware, consumer, or fallback still process the same event or state change?"
|
|
36
|
+
|
|
37
|
+
<!-- mustflow-section: use-when -->
|
|
38
|
+
## Use When
|
|
39
|
+
|
|
40
|
+
- A PR or local diff splits a file, extracts a component, handler, reducer, service, route, listener, worker, middleware, controller, or event processor.
|
|
41
|
+
- A responsibility is claimed to move from one owner to another, especially event receive, event interpretation, state mutation, side effect, API request, cache update, analytics emission, or cleanup ownership.
|
|
42
|
+
- A previous bug may reappear because old conditions, callbacks, effects, subscriptions, imports, feature flags, fallbacks, or tests still exercise the old path.
|
|
43
|
+
- Review needs to distinguish a true move from code duplication, partial extraction, or a new module that is not connected to the real entrypoint.
|
|
44
|
+
|
|
45
|
+
<!-- mustflow-section: do-not-use-when -->
|
|
46
|
+
## Do Not Use When
|
|
47
|
+
|
|
48
|
+
- The task is a broad behavior-preserving refactor with no file split, handler relocation, state mutation relocation, or old-path risk; use `behavior-preserving-refactor`.
|
|
49
|
+
- The main concern is general module ownership, import direction, DTO leakage, or policy owner placement; use `module-boundary-review`.
|
|
50
|
+
- The task only asks for changed-file risk classification and verification selection; use `diff-risk-review`.
|
|
51
|
+
- The change is a pure rename or formatting-only move with no runtime entrypoint, listener, state, side effect, feature flag, or test routing impact.
|
|
52
|
+
|
|
53
|
+
<!-- mustflow-section: required-inputs -->
|
|
54
|
+
## Required Inputs
|
|
55
|
+
|
|
56
|
+
- Refactor claim: what responsibility moved, from where, to where, and what behavior should remain unchanged.
|
|
57
|
+
- Current diff shape: added files, deleted lines, moved code, old files that remain, imports changed, and tests changed.
|
|
58
|
+
- Residual keyword ledger: old bug keywords, event names, action types, handler names, API calls, state field names, feature flag names, selector names, cache keys, analytics names, route names, job names, and middleware names.
|
|
59
|
+
- Entry and ownership ledger: event receiver, interpreter, state mutator, side-effect owner, external request owner, cleanup owner, and public entrypoints before and after the split.
|
|
60
|
+
- Lifecycle ledger: mount, unmount, remount, route change, modal close, tab switch, reconnect, retry, worker restart, consumer rebalance, or job replay behavior when relevant.
|
|
61
|
+
- Test ledger: existing regression tests, new module unit tests, real-entrypoint integration tests, duplicate-execution tests, cleanup tests, ordering tests, and static boundary rules.
|
|
62
|
+
|
|
63
|
+
<!-- mustflow-section: preconditions -->
|
|
64
|
+
## Preconditions
|
|
65
|
+
|
|
66
|
+
- The task matches the Use When conditions and does not match the Do Not Use When exclusions.
|
|
67
|
+
- Higher-priority instructions and `.mustflow/config/commands.toml` have been checked for the current scope.
|
|
68
|
+
- Existing local patterns for file moves, handler ownership, event routing, state mutations, lifecycle cleanup, feature flags, and tests have been searched before recommending a new pattern.
|
|
69
|
+
- If the residual path affects payments, auth, notifications, persistence, cache truth, concurrency, or UI resurrection, also apply the narrower matching skill for that boundary.
|
|
70
|
+
|
|
71
|
+
<!-- mustflow-section: allowed-edits -->
|
|
72
|
+
## Allowed Edits
|
|
73
|
+
|
|
74
|
+
- Remove old handlers, conditions, effects, subscriptions, dispatches, emits, mutations, imports, fallback branches, direct API calls, cache updates, analytics calls, or cleanup logic that still own the moved responsibility.
|
|
75
|
+
- Convert the old owner into a pure adapter, delegator, or view when the new owner should interpret and mutate state.
|
|
76
|
+
- Add or tighten boundary guards such as import restrictions, module boundary rules, lint rules, dependency rules, or package exports that prevent the old owner from importing moved event types or handlers.
|
|
77
|
+
- Add focused tests for real entrypoint routing, old-path non-execution, single execution, lifecycle cleanup, ordering, feature-flag fallbacks, and regression scenarios tied to the moved responsibility.
|
|
78
|
+
- Do not keep duplicate old and new paths "for safety" unless the product contract explicitly requires parallel behavior and the diff names the compatibility sunset.
|
|
79
|
+
|
|
80
|
+
<!-- mustflow-section: procedure -->
|
|
81
|
+
## Procedure
|
|
82
|
+
|
|
83
|
+
1. Start with the diff shape.
|
|
84
|
+
- Compare added files with deleted old responsibility.
|
|
85
|
+
- Treat a refactor that mostly adds new code while barely deleting old conditions, effects, handlers, cleanup, or side effects as suspected duplication.
|
|
86
|
+
- Separate mechanical moves from semantic changes before judging correctness.
|
|
87
|
+
2. Name the moved responsibility.
|
|
88
|
+
- State exactly what moved: receive event, interpret event, update state, perform external request, emit analytics, update cache, route command, validate input, cleanup listener, or publish event.
|
|
89
|
+
- If the responsibility cannot be named, use `behavior-preserving-refactor` or `module-boundary-review` before editing.
|
|
90
|
+
3. Search residual paths.
|
|
91
|
+
- Search old bug keywords, event names, action types, handler names, API calls, state fields, feature flags, selectors, cache keys, analytics names, route names, job names, middleware names, and callback names.
|
|
92
|
+
- Inspect neighborhoods around `onClick`, `onChange`, `addEventListener`, `subscribe`, `dispatch`, `emit`, `useEffect`, `watch`, `listener`, `handler`, `middleware`, `controller`, `route`, `consumer`, `job`, and `callback`.
|
|
93
|
+
- Treat old imports of moved event types, handlers, mutation helpers, or state fields as evidence that the move may be incomplete.
|
|
94
|
+
4. Check single ownership of the event path.
|
|
95
|
+
- The old location may pass data through or render output, but it should not still decide what the event means.
|
|
96
|
+
- Event receiving, event interpretation, state mutation, and external side effects should not be split halfway between old and new owners unless a named compatibility adapter explains why.
|
|
97
|
+
- If both old and new owners listen to the same event, identify whether one is dead, delegated, compatibility-only, or a duplicate-execution bug.
|
|
98
|
+
5. Trace state mutation authority.
|
|
99
|
+
- Follow reducers, store mutations, local setters, optimistic updates, query-cache writes, form sync, repository writes, job state, and side-effect acknowledgements.
|
|
100
|
+
- Reject designs where the new owner changes state and the old owner later recomputes, overwrites, or replays the old value.
|
|
101
|
+
6. Check feature flags and fallback paths.
|
|
102
|
+
- Review flag on, flag off, legacy mode, mobile, SSR, permission-denied, empty data, error retry, offline, reconnect, old route, and tenant or partner branches.
|
|
103
|
+
- All supported branches should route the responsibility to the same owner, or the diff should explicitly classify the divergence.
|
|
104
|
+
7. Check dependency direction.
|
|
105
|
+
- A new event owner should not import old UI internals, container-only constants, private helpers, or test-only wiring from the old location.
|
|
106
|
+
- Move stable contracts to a shared domain, type, adapter, or public module surface only when that reduces ownership ambiguity.
|
|
107
|
+
8. Review tests for real routing, not only new module correctness.
|
|
108
|
+
- A unit test that calls the new module directly is not enough when the real user or system event may still enter the old path.
|
|
109
|
+
- Prefer tests where the real click, route, message, API request, worker event, queue message, or dispatch enters the app and reaches the new owner.
|
|
110
|
+
- Keep or add the old bug reproduction as a regression guard when the refactor is meant to prevent recurrence.
|
|
111
|
+
9. Add duplicate-execution tests when side effects matter.
|
|
112
|
+
- Assert one click, request, dispatch, event, analytics call, notification, charge, save, cache update, or job replay is handled once.
|
|
113
|
+
- Check counts, idempotency keys, emitted events, persistence writes, and external calls rather than only final visible state.
|
|
114
|
+
10. Add lifecycle and cleanup evidence.
|
|
115
|
+
- Test or inspect mount, unmount, remount, route change, modal close, tab switch, reconnect, consumer restart, and job replay when listeners or subscriptions moved.
|
|
116
|
+
- Ensure the subscription and cleanup moved together; a split subscription and old cleanup is usually unstable.
|
|
117
|
+
11. Check ordering.
|
|
118
|
+
- Preserve important sequences such as validate, normalize, update, persist, notify, cleanup, ack, and publish.
|
|
119
|
+
- If swapping two steps would break correctness, encode that sequence in one owner or a test that observes the ordering.
|
|
120
|
+
12. Add structural guardrails when the old path is easy to reintroduce.
|
|
121
|
+
- Prefer `no-restricted-imports`, dependency-cruiser, module boundary rules, package exports, or local lint rules over a comment that asks humans to remember.
|
|
122
|
+
- Guard only the moved responsibility; do not create broad architecture rules unrelated to the current refactor.
|
|
123
|
+
13. Decide the outcome.
|
|
124
|
+
- If old and new paths both execute, fix the residual path when in scope.
|
|
125
|
+
- If the residual path is intentional compatibility, document the sunset and tests.
|
|
126
|
+
- If evidence is insufficient, report the missing entrypoint, lifecycle, flag, ordering, or static-boundary proof.
|
|
127
|
+
|
|
128
|
+
<!-- mustflow-section: postconditions -->
|
|
129
|
+
## Postconditions
|
|
130
|
+
|
|
131
|
+
- The old location either no longer owns the moved responsibility, is a pure delegator, or has a documented compatibility role.
|
|
132
|
+
- Real entrypoints route through the new owner.
|
|
133
|
+
- Duplicate listeners, dispatches, state mutations, external requests, cache writes, analytics calls, and cleanup ownership are removed or reported.
|
|
134
|
+
- Feature flags, fallback branches, lifecycle cleanup, ordering, and tests prove the old path cannot silently revive the previous behavior.
|
|
135
|
+
|
|
136
|
+
<!-- mustflow-section: verification -->
|
|
137
|
+
## Verification
|
|
138
|
+
|
|
139
|
+
Use configured oneshot command intents when available:
|
|
140
|
+
|
|
141
|
+
- `changes_status`
|
|
142
|
+
- `changes_diff_summary`
|
|
143
|
+
- `lint`
|
|
144
|
+
- `build`
|
|
145
|
+
- `test_related`
|
|
146
|
+
- `test`
|
|
147
|
+
- `test_audit`
|
|
148
|
+
- `docs_validate_fast`
|
|
149
|
+
- `test_release`
|
|
150
|
+
- `mustflow_check`
|
|
151
|
+
|
|
152
|
+
Use the narrowest configured test, lint, build, docs, release, or mustflow intent that covers the moved responsibility, static boundary guard, template surface, or public contract.
|
|
153
|
+
|
|
154
|
+
<!-- mustflow-section: failure-handling -->
|
|
155
|
+
## Failure Handling
|
|
156
|
+
|
|
157
|
+
- If the old responsibility cannot be located, stop and report the missing residual keyword, entrypoint, or ownership evidence.
|
|
158
|
+
- If tests only call the new module directly, report the real-entrypoint gap before claiming the refactor prevents regression.
|
|
159
|
+
- If removing the old path changes behavior, split the work into a behavior-preserving refactor and a separate behavior change or bug fix.
|
|
160
|
+
- If a boundary rule would block valid callers, narrow the rule to the moved responsibility instead of weakening the review.
|
|
161
|
+
- If a configured command fails, preserve the failing intent and use `failure-triage` before unrelated edits.
|
|
162
|
+
|
|
163
|
+
<!-- mustflow-section: output-format -->
|
|
164
|
+
## Output Format
|
|
165
|
+
|
|
166
|
+
- Split refactor surface reviewed
|
|
167
|
+
- Moved responsibility and old versus new owner
|
|
168
|
+
- Diff-shape evidence: additions, deletions, moved code, old imports, and old conditions
|
|
169
|
+
- Residual path search terms and findings
|
|
170
|
+
- Event, state mutation, side-effect, feature-flag, lifecycle, cleanup, and ordering evidence
|
|
171
|
+
- Tests added, updated, missing, or intentionally deferred
|
|
172
|
+
- Static boundary guard added or intentionally avoided
|
|
173
|
+
- Fixes made or recommendation
|
|
174
|
+
- Command intents run
|
|
175
|
+
- Skipped checks and reasons
|
|
176
|
+
- Remaining residual-path risk
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
mustflow_doc: skill.typescript-code-change
|
|
3
3
|
locale: en
|
|
4
4
|
canonical: true
|
|
5
|
-
revision:
|
|
5
|
+
revision: 7
|
|
6
6
|
lifecycle: mustflow-owned
|
|
7
7
|
authority: procedure
|
|
8
8
|
name: typescript-code-change
|
|
9
|
-
description: Apply this skill when TypeScript source, declarations, tsconfig, package exports, module resolution, compiler-version behavior, TypeScript 6-to-7 migration surfaces, TypeScript 7 RC or nightly tooling, type safety, or TypeScript tests are created or changed.
|
|
9
|
+
description: Apply this skill when TypeScript source, declarations, tsconfig, package exports, module resolution, project references, type-check performance, compiler-version behavior, TypeScript 6-to-7 migration surfaces, TypeScript 7 RC or nightly tooling, runtime data validation, type safety, or TypeScript tests are created or changed.
|
|
10
10
|
metadata:
|
|
11
11
|
mustflow_schema: "1"
|
|
12
12
|
mustflow_kind: procedure
|
|
@@ -35,6 +35,7 @@ Preserve TypeScript's type, runtime validation, module, build, and public API bo
|
|
|
35
35
|
|
|
36
36
|
- `.ts`, `.tsx`, `.mts`, `.cts`, `*.d.ts`, `tsconfig*.json`, package entry metadata, exports, declarations, runtime validators, or TypeScript tests change.
|
|
37
37
|
- The task touches module resolution, ESM/CJS interop, public package API, path aliases, generated declarations, or strict type errors.
|
|
38
|
+
- The task touches project references, monorepo package boundaries, type-check speed, declaration emit speed, ambient type scope, large unions, generated types, or TypeScript build graph shape.
|
|
38
39
|
- The task touches TypeScript compiler major-version behavior, TypeScript 6 transition deprecations, TypeScript 7 RC comparison, TypeScript 7 nightly comparison, `@typescript/typescript6`, `tsc6`, `typescript@rc`, `@typescript/native-preview`, `tsgo`, compiler API use, declaration emit comparison, or editor language-service behavior.
|
|
39
40
|
- The task touches external inputs such as JSON, HTTP responses, environment variables, config files, form data, URL params, local storage, message events, queue payloads, or user-provided objects.
|
|
40
41
|
- A framework component written in TypeScript changes its props, events, routes, loader data, or exported types.
|
|
@@ -52,6 +53,7 @@ Preserve TypeScript's type, runtime validation, module, build, and public API bo
|
|
|
52
53
|
- Relevant `package.json`, `tsconfig*.json`, lockfile, build config, test config, and package entry files.
|
|
53
54
|
- Existing source entrypoints, public exports, declaration files, validators, schemas, type tests, and nearby tests.
|
|
54
55
|
- The target runtime and module system: Node, browser, worker, Bun, edge, ESM, CJS, or mixed boundary.
|
|
56
|
+
- Workspace package dependency graph, `tsconfig` references graph, public package entrypoints, path alias policy, generated-type locations, and current import-boundary evidence when the repository is a monorepo or large TypeScript project.
|
|
55
57
|
- TypeScript compiler track and tooling entrypoint when relevant: TS6 stable API track through `@typescript/typescript6` and `tsc6`, TS7 RC compiler track through `typescript@rc` and `tsc`, TS7 nightly track through `@typescript/native-preview` and `tsgo`, future TS7 stable track through the stable `typescript` package, framework typecheck wrappers, editor extension settings, and any compiler API consumers.
|
|
56
58
|
- Package API metadata when relevant: `type`, `main`, `module`, `browser`, `exports`, `types`, `typings`, `typesVersions`, `files`, `bin`, `sideEffects`, and documented import paths.
|
|
57
59
|
- Existing verification intents from the repository command contract.
|
|
@@ -78,39 +80,47 @@ Preserve TypeScript's type, runtime validation, module, build, and public API bo
|
|
|
78
80
|
<!-- mustflow-section: procedure -->
|
|
79
81
|
## Procedure
|
|
80
82
|
|
|
81
|
-
1. Read `package.json`, `tsconfig*.json`, package exports, build config, and nearby tests before editing.
|
|
83
|
+
1. Read `package.json`, `tsconfig*.json`, package exports, build config, project references, and nearby tests before editing.
|
|
82
84
|
2. Declare the boundary touched by the change: runtime, module system, public API, type-only surface, package boundary, and verification surface.
|
|
83
|
-
3. Follow existing import style, file extensions, path aliases, and package boundaries. Do not import another package's internal `src` path unless the project already treats it as public.
|
|
85
|
+
3. Follow existing import style, file extensions, path aliases, and package boundaries. Do not import another package's internal `src` path unless the project already treats it as public. Treat `paths` aliases as type-resolution hints, not runtime aliases or package-boundary substitutes.
|
|
84
86
|
4. Fix type errors at the narrowest truthful point. Prefer `unknown` plus runtime validation over new `any`.
|
|
85
|
-
5. Treat external data as `unknown` until validated. This includes JSON parsing, HTTP bodies, environment variables, config files, form data, URL params, local storage, message events, queue payloads,
|
|
86
|
-
6. Pick the validation shape before assigning the domain type. Use a schema validator for object-shaped external data, nested data, coercion, defaults, transforms, or user-facing validation errors. Use a type guard for small branching checks. Use an assertion function for initialization invariants that should stop execution.
|
|
87
|
+
5. Treat external data as `unknown` until validated. This includes JSON parsing, HTTP bodies, environment variables, config files, form data, URL params, local storage, message events, queue payloads, framework request data, database raw rows, third-party SDK results, and generated client payloads.
|
|
88
|
+
6. Pick the validation shape before assigning the domain type. Use a schema validator for object-shaped external data, nested data, coercion, defaults, transforms, dates, money, decimal, bigint, optional-or-null normalization, or user-facing validation errors. Use a type guard for small branching checks. Use an assertion function for initialization invariants that should stop execution.
|
|
87
89
|
7. Keep validator and type definitions from drifting. When a schema is the source of truth, infer static types from it. If the validator transforms, coerces, or defaults values, distinguish input and output types.
|
|
88
|
-
8.
|
|
89
|
-
9.
|
|
90
|
-
10.
|
|
91
|
-
11.
|
|
92
|
-
12.
|
|
93
|
-
13.
|
|
94
|
-
14.
|
|
95
|
-
15.
|
|
96
|
-
16.
|
|
97
|
-
17.
|
|
98
|
-
18. For
|
|
99
|
-
19.
|
|
100
|
-
20. Use
|
|
101
|
-
21.
|
|
102
|
-
22.
|
|
103
|
-
23. For
|
|
104
|
-
24. Treat
|
|
105
|
-
25. For
|
|
90
|
+
8. Separate DTOs, persistence rows, provider payloads, and internal domain types when runtime shape differs. Do not cast a DTO into a domain model when fields need casing changes, `Date` construction, amount branding, null stripping, enum normalization, class rehydration, or policy snapshots.
|
|
91
|
+
9. Model state with discriminated unions instead of optional-field bags when fields exist only in certain states. Use stable internal discriminator strings, not UI copy or translated text. Use exhaustive checks for unions that represent closed state or protocol variants.
|
|
92
|
+
10. Choose type constructs by contract shape. Use `interface` for extendable object contracts, `type` for unions, mapped types, conditional types, primitive aliases, and branded primitives. Brand IDs, currencies, cents, and other same-primitive values when accidental mixing is costly.
|
|
93
|
+
11. Use generics only to preserve a real relationship between inputs, outputs, keys, callbacks, or container members. Add constraints such as `extends`, `keyof`, `const` type parameters, or `NoInfer` when needed. Remove unused or single-position generics that only decorate `unknown` behavior.
|
|
94
|
+
12. Use function-property syntax for callback members when parameter variance matters. Avoid method-shaped callback contracts in listeners, middleware, validators, adapters, or event buses unless the repository intentionally accepts the looser method variance.
|
|
95
|
+
13. Use `as` only for narrow runtime facts the compiler cannot infer. Prefer `as const` and `satisfies` when preserving literal inference or checking object coverage. Do not add broad `as Type`, `as any`, `as unknown as`, `as never`, broad non-null assertions, `@ts-ignore`, `skipLibCheck`, `strict: false`, `noCheck`, or equivalent safety downgrades.
|
|
96
|
+
14. Allow `!` only immediately after a same-scope runtime check that proves presence, such as a `has` check for the same key before `get`. Do not use `!` across `await`, callbacks, mutation, lifecycle boundaries, class async initialization gaps, or property chains.
|
|
97
|
+
15. For type tests, prefer `@ts-expect-error` with a short reason. Do not use `@ts-ignore` in implementation code. Implementation `@ts-expect-error` needs an owner, removal condition, and risk report.
|
|
98
|
+
16. If a public API changes, trace every consumer-visible import specifier, runtime export, type export, declaration output, docs example, type-only export, overload, generic default, interface field, enum or literal member, class member, and package entry condition.
|
|
99
|
+
17. Treat `exports`, `types`, `typings`, `typesVersions`, package `type`, file extensions, path aliases, declaration import paths, and barrel exports as public API surfaces. Adding or tightening `exports` can break existing deep imports.
|
|
100
|
+
18. For TypeScript that emits code for native Node ESM, prefer `.ts` source plus package `"type": "module"` and `module`/`moduleResolution` set to `NodeNext` or the repository's fixed Node mode. Do not rename every source file to `.mts` just to mean ESM; reserve `.mts` and `.cts` for explicit per-file module overrides or mixed-package boundaries.
|
|
101
|
+
19. In TypeScript source that targets native Node ESM, write relative imports using the emitted runtime specifier, usually `.js`, such as `import { createApp } from "./app.js"` from `app.ts`. Do not write extensionless relative imports or `.ts` runtime specifiers unless a declared loader, bundler, or runtime explicitly owns that behavior.
|
|
102
|
+
20. Use `moduleResolution: "Bundler"` only when a bundler such as Vite, esbuild, Rollup, or a framework build system owns final module resolution. Do not use bundler resolution to model code that Node will execute directly without that bundler.
|
|
103
|
+
21. If ESM/CJS behavior changes, verify package `type`, `main`, `module`, `browser`, `exports`, condition order, extension rules, generated JS, generated declarations, and supported consumer resolver modes together. Remember that `exports.import` and `exports.require` select the condition used by the caller; file extension and package `type` still decide whether a target is ESM or CJS.
|
|
104
|
+
22. For dual ESM/CJS packages, check whether runtime entries and declaration entries are separate where needed. Do not assume one `.d.ts` safely describes both `.mjs` and `.cjs`; use `.d.mts` and `.d.cts` when the package shape requires distinct module declarations.
|
|
105
|
+
23. For `tsconfig` updates, make defaults explicit when they affect emitted shape, ambient types, or module semantics. Check `rootDir`, `include`, `exclude`, `files`, `references`, `types`, `lib`, `target`, `module`, `moduleResolution`, `verbatimModuleSyntax`, `noUncheckedSideEffectImports`, `strict`, `noImplicitAny`, `strictNullChecks`, `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `useUnknownInCatchVariables`, `strictFunctionTypes`, `noImplicitOverride`, `noPropertyAccessFromIndexSignature`, `noImplicitReturns`, `noFallthroughCasesInSwitch`, declaration output, and framework wrapper defaults together instead of relying on a compiler-major default.
|
|
106
|
+
24. Treat `types` as an ambient-global allowlist. Add only the runtime or test environment globals the project actually uses, such as Node, Bun, DOM, Vitest, Jest, or Playwright. Do not restore broad ambient discovery just to hide missing imports or environment drift.
|
|
107
|
+
25. For large repositories, check whether the root `tsconfig` is a solution file with `files: []`, whether referenced projects use `composite`, declaration output, and narrow `include`, and whether package dependency graph and `references` graph agree. Do not solve slow type-checking by widening `skipLibCheck`, `noCheck`, broad `exclude`, or path aliases that bypass public package entries.
|
|
108
|
+
26. For type-check performance changes, prefer named exported return types, named conditional aliases, interface extension over repeated intersections when practical, smaller unions, bounded generated type inputs, and explicit public export annotations. Treat large anonymous public return types, massive unions, recursive mapped types, and all-visible `@types` globals as graph-size risks.
|
|
109
|
+
27. When a change is boundary-sensitive, use available read-only script-pack suggestions such as `repo/config-chain`, `code/dependency-graph`, `code/import-cycle`, `repo/related-files`, `code/export-diff`, or `repo/manifest-lock-drift` only as orientation or review evidence. Script-pack output does not replace source reading, command intents, or declaration/package verification.
|
|
110
|
+
28. Use import attributes, subpath imports, and deferred module evaluation only when the runtime, bundler, and compiler track all support the exact syntax. `import defer` is a side-effect and startup-order choice, not a generic lazy-loading trick; use it only for namespace imports whose module evaluation can safely wait until first export access.
|
|
111
|
+
29. Use `using` or `await using` only when the target runtime or transform path supports explicit resource management and the object really owns a disposable resource. Do not replace visible `try/finally`, context-manager, or framework cleanup contracts with `using` if the surrounding lifecycle, error propagation, or generated JS cannot be verified.
|
|
112
|
+
30. Inspect generated declarations when package surfaces change. Declaration files must not leak source-only aliases, private paths, workspace-only package names, unpublished internal paths, accidental public re-exports, stale `paths` aliases, or wrong ESM/CJS declaration shapes.
|
|
113
|
+
31. For TypeScript 6 migration work, treat deprecation warnings as future TypeScript 7 removal risk. `ignoreDeprecations` is a temporary compatibility valve, not proof that the project is ready for 7.0. Prefer removing deprecated options and updating resolver or module choices to match the project runtime.
|
|
114
|
+
32. Treat TypeScript 6 `--stableTypeOrdering` as a migration comparison tool for declaration and error-order differences, not as a permanent performance-neutral default. If it changes errors or declaration output, look for inference or declaration-stability issues instead of snapshotting noise.
|
|
115
|
+
33. For TypeScript 7 migration work, keep the tracks separate:
|
|
106
116
|
- TS6 stable API track: `@typescript/typescript6` and `tsc6` for compiler API, transformer, ESLint, framework wrapper, and peer-dependency compatibility.
|
|
107
117
|
- TS7 RC compiler track: `typescript@rc` and `tsc` for RC compiler verification.
|
|
108
118
|
- TS7 nightly track: `@typescript/native-preview` and `tsgo` for nightly diagnostics only.
|
|
109
119
|
- Future TS7 stable track: stable `typescript` once upstream publishes TypeScript 7 on the normal stable path.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
34. Keep compiler API consumers, language-service plugins, custom transformers, and framework typecheck wrappers on the TS6 API track until their owners explicitly support the TS7 API surface. Treat TS7 RC `tsc` as compiler verification, not proof that JavaScript compiler API consumers can migrate.
|
|
121
|
+
35. When comparing TS6 `tsc6`, TS7 RC `tsc`, and optional TS7 nightly `tsgo`, classify differences before editing code: real type error, declaration emit order or printback noise, unsupported option, unsupported API, watch or incremental behavior gap, language-service gap, generated-output drift, or framework wrapper mismatch.
|
|
122
|
+
36. Do not treat faster TS7 RC or nightly results as sufficient verification. Keep the repository's existing `tsc`, `tsc6`, or framework typecheck as the compatibility baseline until repository policy explicitly adopts a different compiler track.
|
|
123
|
+
37. Choose the narrowest configured verification intents that cover typecheck, lint, tests, build output, declarations, package contract risk, downstream-style consumer risk, and type-check performance risk.
|
|
114
124
|
|
|
115
125
|
<!-- mustflow-section: assertion-policy -->
|
|
116
126
|
## Assertion Policy
|
|
@@ -129,6 +139,7 @@ Rejected by default:
|
|
|
129
139
|
- `JSON.parse(...) as T`, `response.json() as T`, `process.env as Env`, `Object.fromEntries(formData) as T`, or any external input cast directly to a domain type.
|
|
130
140
|
- `as any`, `as unknown as T`, `as never`, or a broad object-wide `as T` used to bypass incompatible shapes.
|
|
131
141
|
- `user!.profile!.field!`-style property chains or non-null assertions after async, callbacks, mutation, or lifecycle transitions.
|
|
142
|
+
- Fake generic parsers such as `parseJson<T>()` that do not accept a real runtime parser or validator.
|
|
132
143
|
- Implementation `@ts-ignore`.
|
|
133
144
|
- Compiler setting downgrades such as disabling strictness, null checking, indexed access safety, or declaration checking to make the patch pass.
|
|
134
145
|
- Treating TypeScript 6 deprecation suppression as a long-term fix.
|
|
@@ -143,6 +154,7 @@ When package or declaration surfaces change:
|
|
|
143
154
|
|
|
144
155
|
- Compare runtime exports and type exports.
|
|
145
156
|
- Check root imports, subpath imports, type-only imports, ESM imports, CJS requires, and documented deep imports when those targets are supported.
|
|
157
|
+
- Check conditional export order, `"types"` condition placement, package `type`, `.mjs`, `.cjs`, `.d.mts`, `.d.cts`, and whether ESM and CJS consumers receive matching runtime and declaration shapes.
|
|
146
158
|
- Treat removed exports, renamed exports, narrowed parameters, changed defaults, changed overload order, widened or narrowed return contracts, required field additions, optional field meaning changes, generic bound changes, and declaration path changes as compatibility-sensitive.
|
|
147
159
|
- Treat path aliases in emitted JS or declarations as release risks unless the consumer environment is guaranteed to resolve them.
|
|
148
160
|
- If a previously importable deep path becomes blocked by `exports`, report it as a breaking-change risk unless a compatibility export remains.
|
|
@@ -154,9 +166,12 @@ Reject or revise the patch when any of these appear without explicit evidence an
|
|
|
154
166
|
|
|
155
167
|
- A type error is fixed by adding `any`, broad `as`, double assertion, non-null assertion, `@ts-ignore`, or compiler setting downgrades.
|
|
156
168
|
- External data is trusted as a domain type without schema validation, a type guard, or an assertion function.
|
|
169
|
+
- DTOs, raw rows, environment variables, JSON values, form values, or provider payloads are reused as internal domain types without conversion where runtime shape differs.
|
|
157
170
|
- A state object uses optional fields where a discriminated union would encode the lifecycle correctly.
|
|
171
|
+
- A generic parameter, callback method syntax, `Record<string, T>` lookup, optional property, or `Array.find()` result creates a false guarantee that runtime code does not prove.
|
|
158
172
|
- Validator schemas and exported types are duplicated without a single source of truth.
|
|
159
173
|
- Generated declarations expose source-only aliases, internal module paths, workspace-only packages, or accidental barrel exports.
|
|
174
|
+
- Project references, package dependencies, path aliases, root solution config, generated type inputs, ambient `types`, or internal `src` imports enlarge the type graph or bypass public package boundaries without evidence.
|
|
160
175
|
- Package entry metadata changes without checking runtime entry, type entry, declaration output, and supported resolver modes.
|
|
161
176
|
- `tsconfig` defaults, ambient `types`, import attributes, `import defer`, or explicit resource management syntax are adopted without runtime, bundler, compiler-track, and generated-output evidence.
|
|
162
177
|
- `skipLibCheck` or weakened strictness is used as release validation for a library/package.
|
|
@@ -171,6 +186,8 @@ Reject or revise the patch when any of these appear without explicit evidence an
|
|
|
171
186
|
- Runtime input boundaries are validated before values receive domain types.
|
|
172
187
|
- Runtime exports, type exports, and declaration output agree.
|
|
173
188
|
- Assertions are narrow, justified, and contained.
|
|
189
|
+
- DTO/domain, external input, optional property, index access, and generic relationship boundaries are honest about runtime behavior.
|
|
190
|
+
- Large-repository build graph, project references, path alias, generated-type, ambient global, and type-performance risks are checked when relevant.
|
|
174
191
|
- Any public API or module-system risk is reported.
|
|
175
192
|
- TypeScript 6/7 migration, RC, nightly, stable, and compiler-entrypoint risks are classified when relevant.
|
|
176
193
|
- No type-checking or test guard was weakened without an explicit user request and risk report.
|
|
@@ -207,8 +224,9 @@ Report whether configured verification exists for declaration output, package ar
|
|
|
207
224
|
|
|
208
225
|
- Boundary checked
|
|
209
226
|
- Files changed
|
|
210
|
-
- Type
|
|
227
|
+
- Type, runtime validation, module, and type-graph safety notes
|
|
211
228
|
- Public API or declaration impact
|
|
229
|
+
- Project reference, monorepo boundary, or type-check performance impact
|
|
212
230
|
- Compiler-version, RC, nightly, or API-track notes
|
|
213
231
|
- Command intents run
|
|
214
232
|
- Skipped checks and reasons
|