mustflow 2.116.1 → 2.116.2
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/package.json +1 -1
- package/templates/default/i18n.toml +72 -6
- package/templates/default/locales/en/.mustflow/skills/INDEX.md +37 -11
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/SKILL.md +477 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/compiler-diagnostics-abi-linker-checklist.md +778 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/compiler-generators-properties-checklist.md +501 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/compiler-test-strategy-differential-checklist.md +498 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/debug-symbol-symbolication-checklist.md +412 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/ir-design-ssa-pass-pipeline-checklist.md +759 -0
- package/templates/default/locales/en/.mustflow/skills/compiler-engineering-review/references/miscompile-reduction-ir-checklist.md +434 -0
- package/templates/default/locales/en/.mustflow/skills/cross-platform-filesystem-safety/SKILL.md +55 -36
- package/templates/default/locales/en/.mustflow/skills/cross-platform-filesystem-safety/references/path-containment-handle-checklist.md +251 -0
- package/templates/default/locales/en/.mustflow/skills/file-upload-security-review/SKILL.md +133 -32
- package/templates/default/locales/en/.mustflow/skills/file-upload-security-review/references/file-upload-parser-ssrf-resource-checklist.md +306 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/SKILL.md +310 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/references/formal-concurrency-model-checking-smt-checklist.md +457 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/references/formal-contracts-modeling-checklist.md +434 -0
- package/templates/default/locales/en/.mustflow/skills/formal-verification-review/references/formal-memory-bounds-ci-checklist.md +509 -0
- package/templates/default/locales/en/.mustflow/skills/fuzz-harness-review/SKILL.md +439 -0
- package/templates/default/locales/en/.mustflow/skills/fuzz-harness-review/references/fuzz-harness-campaign-checklist.md +379 -0
- package/templates/default/locales/en/.mustflow/skills/fuzz-harness-review/references/fuzz-oracle-triage-ci-checklist.md +307 -0
- package/templates/default/locales/en/.mustflow/skills/idempotency-integrity-review/SKILL.md +48 -28
- package/templates/default/locales/en/.mustflow/skills/idempotency-integrity-review/references/operation-ordering-stale-write-checklist.md +259 -0
- package/templates/default/locales/en/.mustflow/skills/input-boundary-validation-review/SKILL.md +329 -0
- package/templates/default/locales/en/.mustflow/skills/input-boundary-validation-review/references/input-boundary-security-checklist.md +319 -0
- package/templates/default/locales/en/.mustflow/skills/input-event-synchronization-review/SKILL.md +306 -0
- package/templates/default/locales/en/.mustflow/skills/input-event-synchronization-review/references/input-session-state-checklist.md +298 -0
- package/templates/default/locales/en/.mustflow/skills/input-event-synchronization-review/references/remote-input-transport-interaction-checklist.md +328 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/SKILL.md +353 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-diagnostics-recovery-checklist.md +267 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-execution-closure-performance-checklist.md +428 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-gc-verification-checklist.md +457 -0
- package/templates/default/locales/en/.mustflow/skills/interpreter-engineering-review/references/interpreter-semantics-runtime-checklist.md +391 -0
- package/templates/default/locales/en/.mustflow/skills/modal-loop-reentrancy-review/SKILL.md +294 -0
- package/templates/default/locales/en/.mustflow/skills/modal-loop-reentrancy-review/references/modal-loop-reentrancy-checklist.md +290 -0
- package/templates/default/locales/en/.mustflow/skills/modal-loop-reentrancy-review/references/nested-modal-state-lifetime-checklist.md +297 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/SKILL.md +252 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/references/dns-network-resolution-checklist.md +394 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/references/language-symbol-resolution-checklist.md +282 -0
- package/templates/default/locales/en/.mustflow/skills/name-resolution-integrity-review/references/module-package-loader-resolution-checklist.md +352 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/SKILL.md +103 -17
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/cst-ast-lowering-checklist.md +260 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/lexer-tokenization-checklist.md +397 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/tree-serialization-compatibility-checklist.md +164 -0
- package/templates/default/locales/en/.mustflow/skills/parser-engineering-review/references/tree-traversal-rewrite-checklist.md +209 -0
- package/templates/default/locales/en/.mustflow/skills/race-condition-review/SKILL.md +68 -11
- package/templates/default/locales/en/.mustflow/skills/race-condition-review/references/race-reproduction-memory-model-checklist.md +268 -0
- package/templates/default/locales/en/.mustflow/skills/routes.toml +151 -0
- package/templates/default/locales/en/.mustflow/skills/session-handoff-integrity-review/SKILL.md +343 -0
- package/templates/default/locales/en/.mustflow/skills/session-handoff-integrity-review/references/session-auth-stream-resume-checklist.md +413 -0
- package/templates/default/locales/en/.mustflow/skills/session-handoff-integrity-review/references/session-handoff-protocol-checklist.md +485 -0
- package/templates/default/locales/en/.mustflow/skills/two-phase-transition-integrity-review/SKILL.md +267 -0
- package/templates/default/locales/en/.mustflow/skills/two-phase-transition-integrity-review/references/admission-decision-recovery-checklist.md +308 -0
- package/templates/default/locales/en/.mustflow/skills/two-phase-transition-integrity-review/references/two-phase-transition-checklist.md +229 -0
- package/templates/default/locales/en/.mustflow/skills/ui-dispatch-lifecycle-review/SKILL.md +300 -0
- package/templates/default/locales/en/.mustflow/skills/ui-dispatch-lifecycle-review/references/ui-affinity-event-loop-checklist.md +277 -0
- package/templates/default/locales/en/.mustflow/skills/ui-dispatch-lifecycle-review/references/ui-dispatch-lifecycle-checklist.md +292 -0
- package/templates/default/manifest.toml +115 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
---
|
|
2
|
+
mustflow_doc: skill.modal-loop-reentrancy-review
|
|
3
|
+
locale: en
|
|
4
|
+
canonical: true
|
|
5
|
+
revision: 2
|
|
6
|
+
lifecycle: mustflow-owned
|
|
7
|
+
authority: procedure
|
|
8
|
+
name: modal-loop-reentrancy-review
|
|
9
|
+
description: Apply this skill when desktop or embedded UI code creates, changes, reviews, debugs, or reports modal dialogs, nested event loops, message pumping, synchronous UI waits, run-loop modes, dispatcher frames, local event loops, dialog exec APIs, synchronous cross-thread messages or RPC, file-picker portals, tracking loops, or callbacks that can reenter code before the outer handler returns and cause deadlock, livelock, starvation, stale-state mutation, or owner-lifecycle corruption.
|
|
10
|
+
metadata:
|
|
11
|
+
mustflow_schema: "1"
|
|
12
|
+
mustflow_kind: procedure
|
|
13
|
+
pack_id: mustflow.core
|
|
14
|
+
skill_id: mustflow.core.modal-loop-reentrancy-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
|
+
# Modal Loop Reentrancy Review
|
|
29
|
+
|
|
30
|
+
<!-- mustflow-section: purpose -->
|
|
31
|
+
## Purpose
|
|
32
|
+
|
|
33
|
+
Review modal and nested event-loop behavior as synchronous call-stack reentrancy, not as an
|
|
34
|
+
application pause.
|
|
35
|
+
|
|
36
|
+
A modal loop can keep an outer handler, lock, iterator, routed event, COM or IPC callback, and
|
|
37
|
+
partially updated model alive on the stack while dispatching another event inside it. The review
|
|
38
|
+
question is whether any reentered path can observe invalid intermediate state, wait on the outer
|
|
39
|
+
frame, starve the only exit source, or resume the outer frame against a changed owner.
|
|
40
|
+
|
|
41
|
+
<!-- mustflow-section: use-when -->
|
|
42
|
+
## Use When
|
|
43
|
+
|
|
44
|
+
- Code uses blocking dialog, modal window, nested dispatcher frame, local event loop, manual
|
|
45
|
+
`processEvents`, message pump, synchronous file picker, menu or drag tracking loop, COM or RPC
|
|
46
|
+
call that pumps messages, or cross-thread synchronous UI messaging.
|
|
47
|
+
- UI code waits synchronously for a task, future, worker, dispatcher callback, portal response,
|
|
48
|
+
network result, lock, event, thread, or another UI thread.
|
|
49
|
+
- A callback opens UI before returning to WebView, browser, accessibility, IPC, D-Bus, framework,
|
|
50
|
+
plugin, or native host code that may serialize or prohibit reentrancy.
|
|
51
|
+
- A bug reports frozen dialog, responsive-but-never-finishing UI, nested confirmations, stale event
|
|
52
|
+
continuation, callback starvation, wrong owner disable, lost capture, late completion, or
|
|
53
|
+
platform-specific modal behavior.
|
|
54
|
+
- Code or docs claim a modal dialog pauses the app, a recursive lock fixes reentrancy, pumping events
|
|
55
|
+
makes a wait safe, or one framework's nested-loop behavior applies to every platform.
|
|
56
|
+
|
|
57
|
+
<!-- mustflow-section: do-not-use-when -->
|
|
58
|
+
## Do Not Use When
|
|
59
|
+
|
|
60
|
+
- The task is dialog semantics, focus order, Escape behavior, accessible naming, or keyboard
|
|
61
|
+
navigation without nested-loop or reentrancy risk; use `frontend-accessibility-tree-review`.
|
|
62
|
+
- The task is only animation interruption or nonblocking overlay motion; use
|
|
63
|
+
`motion-system-contract-review`.
|
|
64
|
+
- The main problem is parallel shared-memory execution with no nested dispatch on one call stack;
|
|
65
|
+
use `race-condition-review` or `concurrency-invariant-review`.
|
|
66
|
+
- The main problem is fixed sleeps, readiness polling, or ordinary asynchronous timing without
|
|
67
|
+
nested pumping; use `async-timing-boundary-review`.
|
|
68
|
+
- The deadlock is primarily database locks or transaction isolation; use the database lock or
|
|
69
|
+
transaction integrity skill.
|
|
70
|
+
- The task merely styles a CSS modal or renders a dialog component whose result is already
|
|
71
|
+
nonblocking and lifecycle-safe.
|
|
72
|
+
|
|
73
|
+
<!-- mustflow-section: required-inputs -->
|
|
74
|
+
## Required Inputs
|
|
75
|
+
|
|
76
|
+
- Entry ledger: outer handler or callback, call stack, UI thread, owner, request, modal depth,
|
|
77
|
+
current state and locks, nested-loop API, and exact return or exit condition.
|
|
78
|
+
- Dispatch ledger: queued and synchronous messages, callbacks, timers, sockets, I/O sources,
|
|
79
|
+
accessibility or IPC sources, run-loop mode or main context, dispatcher priority, filters, and
|
|
80
|
+
source thread or affinity.
|
|
81
|
+
- Wait-for ledger: threads, tasks, locks, events, synchronous messages, RPC or COM calls, dispatcher
|
|
82
|
+
operations, portal requests, completion callbacks, and the context required to run each one.
|
|
83
|
+
- Reentrancy invariant: fields that must change together, transient state exposed across the nested
|
|
84
|
+
loop, stale iterators or object references, allowed nested callbacks, and forbidden reentry.
|
|
85
|
+
- Request lifecycle: stable request and owner IDs, state machine, generation, cancellation,
|
|
86
|
+
single-flight or queue policy, exactly-once result, late-completion behavior, and owner disposal.
|
|
87
|
+
- Modal session ledger: session-specific loop and exit token, nested depth and parent session,
|
|
88
|
+
completion and commit authority, owner-disable and capture ownership, input generation, hidden
|
|
89
|
+
versus closed state, deferred destruction, weak owner reference, and idempotent cleanup owner.
|
|
90
|
+
- Platform ledger: framework and version, backend, native versus portal dialog, process boundary,
|
|
91
|
+
apartment or thread-affinity model, event-loop modes, and current official or repository-owned
|
|
92
|
+
behavior evidence.
|
|
93
|
+
- Diagnostic and test evidence: modal spans, loop depth, call and wait graphs, source priority and
|
|
94
|
+
context, low-overhead event ring, stacks, CPU state, system trace correlation, deterministic
|
|
95
|
+
reentry fixtures, and configured command intents.
|
|
96
|
+
|
|
97
|
+
<!-- mustflow-section: preconditions -->
|
|
98
|
+
## Preconditions
|
|
99
|
+
|
|
100
|
+
- The task matches the Use When conditions and does not match the exclusions.
|
|
101
|
+
- Higher-priority instructions and `.mustflow/config/commands.toml` have been checked.
|
|
102
|
+
- The actual nested-loop or synchronous wait boundary is identified before changing dialog code.
|
|
103
|
+
- Platform behavior is matched to the repository's framework, backend, apartment and version.
|
|
104
|
+
External examples are evidence only and are not copied as universal rules.
|
|
105
|
+
- Existing async dialog, request state-machine, owner lifecycle, cancellation, dispatcher,
|
|
106
|
+
instrumentation and test patterns have been searched.
|
|
107
|
+
|
|
108
|
+
<!-- mustflow-section: allowed-edits -->
|
|
109
|
+
## Allowed Edits
|
|
110
|
+
|
|
111
|
+
- Replace blocking result APIs with future, task, callback or signal result APIs.
|
|
112
|
+
- Post presentation until the current callback has returned; add request state machines, owner-scoped
|
|
113
|
+
single-flight or queue policy, stable IDs and revisions, exactly-once completion, cancellation,
|
|
114
|
+
late-result guards, narrow window or document scope, and focused fixtures.
|
|
115
|
+
- Move locks, mutable iterators, partial model changes, synchronous I/O, remote validation, and
|
|
116
|
+
long-running work outside nested dispatch windows.
|
|
117
|
+
- Add modal-depth spans, dispatcher or source lifecycle records, wait-for edges, low-overhead event
|
|
118
|
+
rings, state hashes, and watchdog evidence collection.
|
|
119
|
+
- Add pre-pump admission guards, atomic pre-modal snapshots, session-scoped `TryComplete`, one
|
|
120
|
+
commit observer, weak-reference plus generation checks, nested owner-disable accounting,
|
|
121
|
+
session-specific exit tokens, stale-input invalidation, and idempotent finalization.
|
|
122
|
+
- Prefer inline confirmation, undo, soft delete, staged apply, sheets, or nonblocking overlays when
|
|
123
|
+
they preserve the product contract.
|
|
124
|
+
- Do not replace a nonrecursive lock with a recursive lock as proof of safety.
|
|
125
|
+
- Do not add manual event pumping, busy `processEvents` loops, sleeps, or global reentrancy booleans
|
|
126
|
+
as generic fixes.
|
|
127
|
+
|
|
128
|
+
<!-- mustflow-section: procedure -->
|
|
129
|
+
## Procedure
|
|
130
|
+
|
|
131
|
+
1. Find every nested dispatch and sync-over-async boundary.
|
|
132
|
+
- Search blocking dialog and file-picker calls, local loop execution, dispatcher frames, message
|
|
133
|
+
pumping, synchronous cross-thread messaging, task or future waits, joins, RPC, COM calls, and
|
|
134
|
+
callbacks that open UI before returning.
|
|
135
|
+
- Include menu, drag, resize and event-tracking loops even when no dialog is visible.
|
|
136
|
+
2. Capture the outer frame that stays alive.
|
|
137
|
+
- Record handler, event, owner, request, locks, iterators, mutable references, partial state,
|
|
138
|
+
transaction or callback contract, and code that resumes after the nested loop exits.
|
|
139
|
+
- State the invariant reentered code is forbidden to observe.
|
|
140
|
+
3. Close lock and partial-state windows before pumping.
|
|
141
|
+
- Release locks and finish or roll back multi-field mutation before entering any nested dispatch.
|
|
142
|
+
- A recursive lock removes self-wait while exposing intermediate state; it does not restore the
|
|
143
|
+
invariant.
|
|
144
|
+
4. Build a wait-for graph that includes delivery context.
|
|
145
|
+
- Add edges for thread waits, locks, synchronous sent messages, callbacks posted to the UI,
|
|
146
|
+
dispatcher operations, RPC or COM callbacks, portal responses and owner-close paths.
|
|
147
|
+
- Mark which run-loop mode, main context, priority, event class, thread affinity or message path
|
|
148
|
+
must execute each completion.
|
|
149
|
+
5. Classify the failure precisely.
|
|
150
|
+
- Deadlock has a closed wait cycle.
|
|
151
|
+
- Starvation has a required ready source that the active loop, filter, priority or context does
|
|
152
|
+
not dispatch.
|
|
153
|
+
- Livelock keeps dispatching or reposting without advancing the request state.
|
|
154
|
+
- Stale continuation resumes an old outer frame after owner, model, selection or visual tree
|
|
155
|
+
authority changed.
|
|
156
|
+
6. Review nested-loop admission and exit.
|
|
157
|
+
- Name the only APIs or signals that actually end the inner loop. General application quit,
|
|
158
|
+
cancellation request, owner disposal or transport close may not be that signal.
|
|
159
|
+
- Ensure filters, input disable, capture and owner selection do not remove the human or automated
|
|
160
|
+
path that creates exit.
|
|
161
|
+
7. Reject manual pumping as completion proof.
|
|
162
|
+
- A loop that repeatedly processes events can starve lower-priority work, mishandle deferred
|
|
163
|
+
destruction, admit more producers than it drains, or keep the request state unchanged.
|
|
164
|
+
- Replace it with an explicit asynchronous completion and a bounded owner lifecycle.
|
|
165
|
+
8. Treat platform behavior as a matrix.
|
|
166
|
+
- Distinguish queued messages from synchronous calls, broad message pumps from mode-filtered run
|
|
167
|
+
loops, framework dispatcher frames from native loops, recursive main contexts from portal
|
|
168
|
+
process boundaries, and blocking dialog APIs from callback or signal APIs.
|
|
169
|
+
- Read [Modal Loop and Reentrancy Checklist](references/modal-loop-reentrancy-checklist.md) for
|
|
170
|
+
the framework, design and diagnostic matrices.
|
|
171
|
+
- Distinguish synchronous return from thread sleep, input modality from state isolation, posted
|
|
172
|
+
work from synchronous or nonqueued dispatch, outer loop shutdown from inner session exit, and
|
|
173
|
+
deferred destruction from function-scope lifetime.
|
|
174
|
+
9. Break the current callback stack before presenting interactive UI.
|
|
175
|
+
- Copy stable request data, return from the host callback, then enqueue presentation on the
|
|
176
|
+
owning UI context.
|
|
177
|
+
- Do not hide the same nested loop behind a future immediately blocked by `.wait`, `.get`,
|
|
178
|
+
`.Result`, or equivalent synchronization.
|
|
179
|
+
10. Model each interactive request explicitly.
|
|
180
|
+
- Transition owner-scoped state through idle, presenting, awaiting result, applying or canceled,
|
|
181
|
+
and done. Enter presenting before any call that can reenter.
|
|
182
|
+
- Give every request and owner a generation. Coalesce equivalent requests, queue ordered work,
|
|
183
|
+
or return busy according to policy; do not create unbounded dialog stacks.
|
|
184
|
+
- Set the admission state before any call that may pump. Bind loop object, exit token, parent
|
|
185
|
+
session, owner-disable lease, capture state and input generation to that session.
|
|
186
|
+
- Route user close, cancellation and worker completion through one atomic
|
|
187
|
+
`TryComplete(sessionId, result)`. Choose one commit owner: completion signal or synchronous
|
|
188
|
+
return path, not both.
|
|
189
|
+
11. Revalidate state after user think time.
|
|
190
|
+
- Store stable entity IDs, capability tokens and expected revisions rather than indexes,
|
|
191
|
+
iterators, object pointers, transient paths or selected-object copies.
|
|
192
|
+
- Before applying the result, verify owner existence, generation, entity revision, permission
|
|
193
|
+
and destination. Recompute or reject stale results.
|
|
194
|
+
12. Tie cancellation to owner lifecycle.
|
|
195
|
+
- Owner close, document replacement, shutdown and explicit cancel complete the local request
|
|
196
|
+
exactly once. A provider or portal response is not required to arrive after cancellation.
|
|
197
|
+
- Late success, failure or response signals become idempotent no-ops after terminal completion.
|
|
198
|
+
- Treat hidden and closed as different lifecycles. A reusable dialog gets a new display
|
|
199
|
+
generation, fresh cancellation ownership and explicit subscription reset every time.
|
|
200
|
+
- Validate weak owner or dialog identity and session generation after the nested call returns;
|
|
201
|
+
return does not prove the caller object survived inner dispatch.
|
|
202
|
+
13. Keep long or failure-prone work outside the dialog callback.
|
|
203
|
+
- Return the user's choice, close presentation, then perform file I/O, parsing, network or remote
|
|
204
|
+
validation in owned asynchronous work. Report failures inline instead of recursively opening
|
|
205
|
+
another blocking dialog.
|
|
206
|
+
14. Preserve capability-bearing picker results.
|
|
207
|
+
- Do not collapse URI, access token, sandbox grant, remote object or provider handle into a
|
|
208
|
+
local path string when later access depends on that authority.
|
|
209
|
+
15. Instrument reentrancy without changing it.
|
|
210
|
+
- Record modal enter and exit, depth, owner, request, call site, mode or context, exit reason,
|
|
211
|
+
queued versus synchronous dispatch, callback start and end, wait edges and state hashes in a
|
|
212
|
+
bounded low-overhead ring.
|
|
213
|
+
- Correlate stacks, CPU state and system traces. A watchdog gathers evidence; it does not
|
|
214
|
+
forcibly dismiss destructive UI.
|
|
215
|
+
16. Read [Nested Modal State and Lifetime Checklist](references/nested-modal-state-lifetime-checklist.md) when nested sessions can mutate owners, collections, input generations, commit paths, deferred deletion, or shutdown state.
|
|
216
|
+
17. Require adversarial evidence.
|
|
217
|
+
- Force callback reentry before outer return, completion on an excluded mode or context,
|
|
218
|
+
high-priority source starvation, synchronous call cycles, repeated confirmation, owner close,
|
|
219
|
+
stale entity revision, cancellation without provider response, immediate provider response,
|
|
220
|
+
nested input capture and shutdown during presentation.
|
|
221
|
+
- Assert bounded modal depth, state progress, exactly-once completion, no held lock across nested
|
|
222
|
+
dispatch, no stale result application, no orphan owner disable or capture, and a replayable
|
|
223
|
+
wait or causal graph.
|
|
224
|
+
- Also force parent deletion, collection mutation during the nested call, double completion,
|
|
225
|
+
nested owner disable, wrong-session exit, deferred deletion, stale queued input after modal
|
|
226
|
+
exit, dialog reuse, continuation-before-return, and progress backlog.
|
|
227
|
+
- If configured proof is unavailable, report static reentrancy risk instead of approving the
|
|
228
|
+
path.
|
|
229
|
+
|
|
230
|
+
<!-- mustflow-section: postconditions -->
|
|
231
|
+
## Postconditions
|
|
232
|
+
|
|
233
|
+
- Nested dispatch, outer stack, modal depth, owner, request, invariants, dispatch contexts, wait
|
|
234
|
+
graph, exit condition, platform behavior, request state machine, cancellation, stale-result guard,
|
|
235
|
+
diagnostics and tests are explicit.
|
|
236
|
+
- Lock-held modal entry, sync-over-async UI wait, synchronous call cycles, wrong run-loop mode or
|
|
237
|
+
context, priority starvation, manual-pump livelock, recursive confirmation, wrong owner disable,
|
|
238
|
+
callback-hosted modal UI, stale routed event, quit-as-dialog-exit, late provider response and
|
|
239
|
+
capability loss are fixed or reported.
|
|
240
|
+
- Session admission after the pump starts, half-applied invariants, duplicated domain commands,
|
|
241
|
+
caller deletion, iterator invalidation, double commit, Boolean modal ownership, focus-triggered
|
|
242
|
+
mutation during construction, hidden-instance reuse, double cleanup, wrong-loop exit and
|
|
243
|
+
post-modal stale input are fixed or reported.
|
|
244
|
+
- Reentrancy safety claims are backed by configured tests, framework evidence matched to current
|
|
245
|
+
code, causal or wait traces, or labeled as static review risk.
|
|
246
|
+
|
|
247
|
+
<!-- mustflow-section: verification -->
|
|
248
|
+
## Verification
|
|
249
|
+
|
|
250
|
+
Use configured oneshot command intents when available:
|
|
251
|
+
|
|
252
|
+
- `changes_status`
|
|
253
|
+
- `changes_diff_summary`
|
|
254
|
+
- `lint`
|
|
255
|
+
- `build`
|
|
256
|
+
- `test_related`
|
|
257
|
+
- `test`
|
|
258
|
+
- `test_audit`
|
|
259
|
+
- `docs_validate_fast`
|
|
260
|
+
- `test_release`
|
|
261
|
+
- `mustflow_check`
|
|
262
|
+
|
|
263
|
+
Prefer the narrowest configured intent that covers the changed UI reentrancy boundary and template
|
|
264
|
+
surfaces. Do not infer raw profilers, message hooks, system traces, live dialogs, portal calls,
|
|
265
|
+
watchers, or platform diagnostics outside the command contract.
|
|
266
|
+
|
|
267
|
+
<!-- mustflow-section: failure-handling -->
|
|
268
|
+
## Failure Handling
|
|
269
|
+
|
|
270
|
+
- If the nested loop, outer frame, exit condition or required delivery context cannot be named,
|
|
271
|
+
report the path as unreviewable for reentrancy.
|
|
272
|
+
- If safe repair requires framework migration, async public API change, native instrumentation,
|
|
273
|
+
system tracing, portal integration or a deterministic harness outside scope, report that boundary.
|
|
274
|
+
- If diagnostics alter timing, allocate, block, acquire application locks or consume messages in the
|
|
275
|
+
hot hook, remove or redesign the observer before trusting its result.
|
|
276
|
+
- If configured tests cannot force nested dispatch, report the missing manual or integration
|
|
277
|
+
evidence and do not infer a raw command.
|
|
278
|
+
- If a configured command fails, preserve the failing invariant, request trace and first relevant
|
|
279
|
+
output before editing again.
|
|
280
|
+
|
|
281
|
+
<!-- mustflow-section: output-format -->
|
|
282
|
+
## Output Format
|
|
283
|
+
|
|
284
|
+
- Modal-loop reentrancy boundary reviewed
|
|
285
|
+
- Outer stack, modal depth, owner, request, invariant, dispatch context, wait graph, exit condition,
|
|
286
|
+
platform, modal session, completion and commit authority, owner-disable and capture ownership,
|
|
287
|
+
object lifetime, deferred deletion, input generation, request-state, cancellation, stale-result,
|
|
288
|
+
capability, diagnostic and test findings
|
|
289
|
+
- Reentrancy fixes made or recommended
|
|
290
|
+
- Evidence level: configured-test evidence, framework evidence, causal or wait trace, static review
|
|
291
|
+
risk, manual-only, missing, or not applicable
|
|
292
|
+
- Command intents run
|
|
293
|
+
- Skipped reentrancy diagnostics and reasons
|
|
294
|
+
- Remaining modal-loop reentrancy risk
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Modal Loop and Reentrancy Checklist
|
|
2
|
+
|
|
3
|
+
Use this checklist when one event-processing stack can dispatch another event before the outer
|
|
4
|
+
handler returns. Confirm framework and version behavior from current repository or official sources;
|
|
5
|
+
do not treat this matrix as a substitute for platform evidence.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
1. [Failure classification](#failure-classification)
|
|
10
|
+
2. [Outer-frame inventory](#outer-frame-inventory)
|
|
11
|
+
3. [Wait and delivery graph](#wait-and-delivery-graph)
|
|
12
|
+
4. [Framework behavior matrix](#framework-behavior-matrix)
|
|
13
|
+
5. [Unsafe patterns](#unsafe-patterns)
|
|
14
|
+
6. [Asynchronous interaction contract](#asynchronous-interaction-contract)
|
|
15
|
+
7. [State and owner revalidation](#state-and-owner-revalidation)
|
|
16
|
+
8. [File-picker authority](#file-picker-authority)
|
|
17
|
+
9. [Tracing without observer effects](#tracing-without-observer-effects)
|
|
18
|
+
10. [Platform diagnostic routing](#platform-diagnostic-routing)
|
|
19
|
+
11. [Fault matrix](#fault-matrix)
|
|
20
|
+
12. [Invariants](#invariants)
|
|
21
|
+
13. [Skill handoffs](#skill-handoffs)
|
|
22
|
+
|
|
23
|
+
## Failure classification
|
|
24
|
+
|
|
25
|
+
Distinguish these outcomes before changing code:
|
|
26
|
+
|
|
27
|
+
| Class | Observable structure |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| deadlock | a closed wait cycle prevents required progress |
|
|
30
|
+
| starvation | required work is ready or posted but the active mode, context, priority or filter never dispatches it |
|
|
31
|
+
| livelock | callbacks and messages run while the request state never advances |
|
|
32
|
+
| stale continuation | the outer handler resumes after owner or model authority changed |
|
|
33
|
+
| reentrant corruption | an inner callback observes or mutates a partially updated invariant |
|
|
34
|
+
| human-path starvation | wrong owner, capture or disable policy removes the only user exit |
|
|
35
|
+
|
|
36
|
+
A responsive window, nonzero CPU, or active message stream does not rule out livelock or starvation.
|
|
37
|
+
|
|
38
|
+
## Outer-frame inventory
|
|
39
|
+
|
|
40
|
+
At each nested-loop boundary record:
|
|
41
|
+
|
|
42
|
+
- outer handler and originating event;
|
|
43
|
+
- current thread and affinity;
|
|
44
|
+
- call site and modal depth;
|
|
45
|
+
- owner, document, surface and request identity;
|
|
46
|
+
- locks, transactions and guards still held;
|
|
47
|
+
- iterators, object pointers, visual elements and selected items still referenced;
|
|
48
|
+
- multi-field state currently between valid states;
|
|
49
|
+
- callbacks or host contracts waiting for the outer return;
|
|
50
|
+
- code that resumes after the inner loop exits;
|
|
51
|
+
- actual exit signal and terminal-result owner.
|
|
52
|
+
|
|
53
|
+
Attack the assumption that a local variable remains valid merely because its stack frame still
|
|
54
|
+
exists.
|
|
55
|
+
|
|
56
|
+
## Wait and delivery graph
|
|
57
|
+
|
|
58
|
+
Model both waits and the context needed to satisfy them.
|
|
59
|
+
|
|
60
|
+
Nodes can include:
|
|
61
|
+
|
|
62
|
+
- UI and worker threads;
|
|
63
|
+
- mutexes, events, semaphores and condition variables;
|
|
64
|
+
- tasks, futures and dispatcher operations;
|
|
65
|
+
- queued messages and synchronous sent messages;
|
|
66
|
+
- COM, RPC, IPC and plugin calls;
|
|
67
|
+
- run-loop modes, main contexts and source priorities;
|
|
68
|
+
- portal or provider request handles;
|
|
69
|
+
- dialog owner, capture and input-disable state;
|
|
70
|
+
- user action required to close the request.
|
|
71
|
+
|
|
72
|
+
For each completion edge, record:
|
|
73
|
+
|
|
74
|
+
- who is waiting;
|
|
75
|
+
- what must run;
|
|
76
|
+
- target thread or context;
|
|
77
|
+
- required mode and priority;
|
|
78
|
+
- whether it is queued, sent, invoked, signaled or polled;
|
|
79
|
+
- which filter can defer or consume it;
|
|
80
|
+
- whether owner shutdown removes the callback path.
|
|
81
|
+
|
|
82
|
+
A posted completion is not progress evidence when its context is not active.
|
|
83
|
+
|
|
84
|
+
## Framework behavior matrix
|
|
85
|
+
|
|
86
|
+
Use this as a question list, not a frozen compatibility promise:
|
|
87
|
+
|
|
88
|
+
| Family | Boundary to verify |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| native Windows dialog | owner disable, nested message dispatch, queued versus synchronous messages, actual dialog termination |
|
|
91
|
+
| dispatcher-based Windows UI | nested dispatcher frame, priorities, routed-event continuation, deferred operations |
|
|
92
|
+
| COM apartment UI | apartment type, outgoing-call pumping, callback delivery and synchronous call cycles |
|
|
93
|
+
| AppKit | modal versus sheet API, active run-loop mode, tracking modes and source registration |
|
|
94
|
+
| Qt | blocking dialog execution, local loop flags, deferred deletion, thread affinity and queued signals |
|
|
95
|
+
| GLib or GTK | recursive main loop, selected main context, source priority, recursion policy and portal boundary |
|
|
96
|
+
| desktop portal | process boundary, response subscription ordering, cancel semantics and capability result |
|
|
97
|
+
| embedded browser or WebView | callback serialization, host return requirement, UI posting and reentrancy restrictions |
|
|
98
|
+
|
|
99
|
+
Do not describe all platforms as one global message queue. Mode filters, recursive contexts,
|
|
100
|
+
synchronous calls, thread affinity and external portal processes create different failure shapes.
|
|
101
|
+
|
|
102
|
+
## Unsafe patterns
|
|
103
|
+
|
|
104
|
+
Reject or prove safe:
|
|
105
|
+
|
|
106
|
+
- lock held while opening a blocking dialog;
|
|
107
|
+
- partially updated model exposed across nested dispatch;
|
|
108
|
+
- UI thread waiting for a completion posted to the UI thread;
|
|
109
|
+
- two threads or components issuing synchronous calls back into each other;
|
|
110
|
+
- completion source attached only to a mode or context not run by the modal loop;
|
|
111
|
+
- always-ready high-priority source starving completion or cancel;
|
|
112
|
+
- loop flags excluding the only socket, input or close event;
|
|
113
|
+
- `while (!done) processEvents()` or equivalent busy pumping;
|
|
114
|
+
- confirmation handler opening another confirmation before changing state;
|
|
115
|
+
- wrong owner, capture or disable target;
|
|
116
|
+
- callback opening blocking UI before returning to a serialized host;
|
|
117
|
+
- general application quit treated as the nested dialog's exit;
|
|
118
|
+
- future-returning wrapper immediately blocked by the caller;
|
|
119
|
+
- global `isDialogOpen` or reentrancy boolean without owner and generation;
|
|
120
|
+
- iterator, selected index or object pointer retained across user think time;
|
|
121
|
+
- cancellation waiting forever for an optional provider response.
|
|
122
|
+
|
|
123
|
+
## Asynchronous interaction contract
|
|
124
|
+
|
|
125
|
+
Prefer a nonblocking request:
|
|
126
|
+
|
|
127
|
+
`Idle -> Presenting -> AwaitingResult -> Applying | Cancelled -> Done`
|
|
128
|
+
|
|
129
|
+
Required properties:
|
|
130
|
+
|
|
131
|
+
- enter `Presenting` before any call that can synchronously invoke callbacks;
|
|
132
|
+
- stable request, owner and generation identity;
|
|
133
|
+
- exactly one terminal result;
|
|
134
|
+
- explicit duplicate policy: coalesce, queue or busy;
|
|
135
|
+
- bounded queue and no recursive dialog stack;
|
|
136
|
+
- presentation posted after the current callback returns;
|
|
137
|
+
- result delivered by task, future, signal or callback without sync-over-async;
|
|
138
|
+
- owner close and explicit cancel complete locally;
|
|
139
|
+
- late result is an idempotent no-op;
|
|
140
|
+
- apply step revalidates target and authority;
|
|
141
|
+
- long work begins after presentation closes.
|
|
142
|
+
|
|
143
|
+
Scope modal behavior to the affected window or document when product semantics allow unrelated work
|
|
144
|
+
to continue.
|
|
145
|
+
|
|
146
|
+
Prefer reversal and recovery over confirmation theater: undo, soft delete, versioning, preview,
|
|
147
|
+
staged apply and atomic replace can remove the need for a blocking question.
|
|
148
|
+
|
|
149
|
+
## State and owner revalidation
|
|
150
|
+
|
|
151
|
+
Snapshot stable intent, not transient objects:
|
|
152
|
+
|
|
153
|
+
- entity or document ID;
|
|
154
|
+
- expected revision or generation;
|
|
155
|
+
- requested action and parameters;
|
|
156
|
+
- owner ID and lifecycle generation;
|
|
157
|
+
- permission or capability identity;
|
|
158
|
+
- request ID and creation context.
|
|
159
|
+
|
|
160
|
+
After completion verify:
|
|
161
|
+
|
|
162
|
+
- owner still exists and owns the request;
|
|
163
|
+
- target still exists;
|
|
164
|
+
- expected revision or precondition still holds;
|
|
165
|
+
- permission or capability remains valid;
|
|
166
|
+
- destination surface or document is current;
|
|
167
|
+
- result has not already completed or been canceled.
|
|
168
|
+
|
|
169
|
+
Recompute against current state or reject. Do not blindly continue the old routed event or mutate
|
|
170
|
+
the old selection.
|
|
171
|
+
|
|
172
|
+
## File-picker authority
|
|
173
|
+
|
|
174
|
+
A picker result can include authority beyond a path:
|
|
175
|
+
|
|
176
|
+
- URI or provider identifier;
|
|
177
|
+
- display name and metadata;
|
|
178
|
+
- sandbox grant, bookmark, token or file descriptor;
|
|
179
|
+
- remote object or lazy provider handle;
|
|
180
|
+
- capability lifetime and persistence rule.
|
|
181
|
+
|
|
182
|
+
Preserve the authority-bearing result type. A local path string may not remain accessible across
|
|
183
|
+
processes, sandbox boundaries, remote providers or later runs.
|
|
184
|
+
|
|
185
|
+
Portal-like flows need:
|
|
186
|
+
|
|
187
|
+
- response subscription before or atomically with request publication;
|
|
188
|
+
- stable request handle and owner;
|
|
189
|
+
- local cancel completion even when no later response arrives;
|
|
190
|
+
- late response suppression;
|
|
191
|
+
- capability cleanup;
|
|
192
|
+
- result schema and lifecycle evidence.
|
|
193
|
+
|
|
194
|
+
## Tracing without observer effects
|
|
195
|
+
|
|
196
|
+
Record a modal or interaction span with:
|
|
197
|
+
|
|
198
|
+
- monotonic time and global or thread-local sequence;
|
|
199
|
+
- request, owner, dialog and event identity;
|
|
200
|
+
- UI thread and source thread;
|
|
201
|
+
- call site and modal depth;
|
|
202
|
+
- current mode, main context or dispatcher priority;
|
|
203
|
+
- enter, callback, wait, wake, exit and completion events;
|
|
204
|
+
- exit or cancellation reason;
|
|
205
|
+
- state hash before and after reentrant callbacks;
|
|
206
|
+
- queued versus synchronous dispatch;
|
|
207
|
+
- target thread and wait edge.
|
|
208
|
+
|
|
209
|
+
Use fixed-size numeric records in a bounded memory ring on hot hooks. Avoid file I/O, formatting,
|
|
210
|
+
allocation, application locks and state mutation in the observer.
|
|
211
|
+
|
|
212
|
+
Capture full thread stacks and CPU state at the hang point. Busy repeated frames indicate a
|
|
213
|
+
different class than a low-CPU blocking wait.
|
|
214
|
+
|
|
215
|
+
Build a wait-for graph from both system objects and application-level tasks, dispatchers, RPCs and
|
|
216
|
+
request handles.
|
|
217
|
+
|
|
218
|
+
## Platform diagnostic routing
|
|
219
|
+
|
|
220
|
+
Select only diagnostics authorized by the command contract and current platform:
|
|
221
|
+
|
|
222
|
+
- Windows: queued-message, sent-message and modal-filter paths are distinct; correlate application
|
|
223
|
+
spans with thread waits and system traces.
|
|
224
|
+
- Dispatcher frameworks: record operation posted, started, completed or aborted, priority, nested
|
|
225
|
+
frame depth and resumed event age.
|
|
226
|
+
- AppKit: record run-loop activities, active mode, local event dispatch and signposted interaction
|
|
227
|
+
spans.
|
|
228
|
+
- Qt: record loop depth, dispatcher sleep and wake, filtered framework events and bounded native
|
|
229
|
+
events.
|
|
230
|
+
- GLib or GTK: name sources and record context, priority, recursion, callback duration and readiness.
|
|
231
|
+
- Portals: record request publication, response subscription, returned handle, cancellation and
|
|
232
|
+
terminal local task state.
|
|
233
|
+
|
|
234
|
+
Observers must forward or preserve events. A diagnostic hook that consumes an event or changes
|
|
235
|
+
priority invalidates the reproduction.
|
|
236
|
+
|
|
237
|
+
## Fault matrix
|
|
238
|
+
|
|
239
|
+
Cover relevant cases:
|
|
240
|
+
|
|
241
|
+
| Fault | Expected result |
|
|
242
|
+
| --- | --- |
|
|
243
|
+
| callback reenters before outer return | invariant remains valid or reentry is deferred |
|
|
244
|
+
| lock held at modal entry | assertion or structural prevention fires |
|
|
245
|
+
| UI waits on UI-posted completion | wait graph exposes and implementation avoids cycle |
|
|
246
|
+
| completion registered in inactive mode | request remains observable and design routes correctly |
|
|
247
|
+
| high-priority source reposts continuously | completion and cancellation have bounded progress |
|
|
248
|
+
| input or socket class excluded | exit path remains available |
|
|
249
|
+
| manual pump receives new work continuously | state still terminates or manual pump is absent |
|
|
250
|
+
| confirmation double click | one owner request is admitted |
|
|
251
|
+
| owner closes while awaiting result | request cancels exactly once |
|
|
252
|
+
| stale model revision after think time | result is recomputed or rejected |
|
|
253
|
+
| provider responds immediately | subscription or continuation does not miss response |
|
|
254
|
+
| provider omits response after cancel | local cancellation still completes |
|
|
255
|
+
| old completion arrives after new generation | new request state is unchanged |
|
|
256
|
+
| shutdown during presentation | no orphan disable, capture, task or callback remains |
|
|
257
|
+
| tracing enabled | failure class and timing remain representative |
|
|
258
|
+
|
|
259
|
+
Prefer deterministic reentry hooks and fake request providers over arbitrary sleeps.
|
|
260
|
+
|
|
261
|
+
## Invariants
|
|
262
|
+
|
|
263
|
+
Choose applicable executable invariants:
|
|
264
|
+
|
|
265
|
+
- modal depth is bounded by policy;
|
|
266
|
+
- no application lock or partial invariant crosses nested dispatch;
|
|
267
|
+
- every interactive request has one owner and one terminal completion;
|
|
268
|
+
- owner closure cannot leave an awaiting request alive;
|
|
269
|
+
- old generations cannot apply results;
|
|
270
|
+
- request state advances or reaches a bounded terminal state;
|
|
271
|
+
- the exit event's source remains dispatchable;
|
|
272
|
+
- cancellation does not depend on an optional remote response;
|
|
273
|
+
- presentation does not occur inside a host callback that forbids reentrancy;
|
|
274
|
+
- capability-bearing results retain required authority;
|
|
275
|
+
- tracing does not block, allocate unboundedly, consume events or acquire application locks.
|
|
276
|
+
|
|
277
|
+
## Skill handoffs
|
|
278
|
+
|
|
279
|
+
- Use `race-condition-review` for parallel interleavings, happens-before, atomics and data races.
|
|
280
|
+
- Use `concurrency-invariant-review` for lock order, condition variables, resource ownership and
|
|
281
|
+
shutdown outside the modal boundary.
|
|
282
|
+
- Use `async-timing-boundary-review` for readiness, polling and waits after nested-loop risk is
|
|
283
|
+
removed.
|
|
284
|
+
- Use `state-machine-pattern` to implement the interactive request lifecycle.
|
|
285
|
+
- Use `frontend-accessibility-tree-review` for dialog semantics, focus trap, announcements and
|
|
286
|
+
keyboard behavior.
|
|
287
|
+
- Use `file-path-handling` or the platform adapter skill for picker URI, capability and path
|
|
288
|
+
boundaries.
|
|
289
|
+
- Use `provenance-license-gate` before copying platform hook or diagnostic examples.
|
|
290
|
+
|