prizmkit 1.1.53 → 1.1.55

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.
Files changed (29) hide show
  1. package/bin/create-prizmkit.js +2 -0
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/rules/_rules-metadata.json +6 -1
  4. package/bundled/rules/general/cohesive-modeling.md +27 -0
  5. package/bundled/skills/_metadata.json +1 -1
  6. package/bundled/skills/app-planner/SKILL.md +114 -4
  7. package/bundled/skills/app-planner/references/rules/backend/derivation-rules.md +609 -0
  8. package/bundled/skills/app-planner/references/rules/backend/fixed-rules.md +285 -0
  9. package/bundled/skills/app-planner/references/rules/backend/question-bank.md +249 -0
  10. package/bundled/skills/app-planner/references/rules/backend/template.md +173 -0
  11. package/bundled/skills/app-planner/references/rules/database/derivation-rules.md +373 -0
  12. package/bundled/skills/app-planner/references/rules/database/fixed-rules.md +211 -0
  13. package/bundled/skills/app-planner/references/rules/database/question-bank.md +184 -0
  14. package/bundled/skills/app-planner/references/rules/database/template.md +158 -0
  15. package/bundled/skills/app-planner/references/rules/frontend/derivation-rules.md +810 -0
  16. package/bundled/skills/app-planner/references/rules/frontend/fixed-rules.md +188 -0
  17. package/bundled/skills/app-planner/references/rules/frontend/question-bank.md +302 -0
  18. package/bundled/skills/app-planner/references/rules/frontend/template.md +320 -0
  19. package/bundled/skills/app-planner/references/rules/mobile/derivation-rules.md +639 -0
  20. package/bundled/skills/app-planner/references/rules/mobile/fixed-rules.md +290 -0
  21. package/bundled/skills/app-planner/references/rules/mobile/question-bank.md +232 -0
  22. package/bundled/skills/app-planner/references/rules/mobile/template.md +175 -0
  23. package/bundled/skills/prizm-kit/SKILL.md +1 -1
  24. package/bundled/skills/prizmkit-init/SKILL.md +47 -6
  25. package/bundled/skills/prizmkit-init/references/config-schema.md +7 -3
  26. package/bundled/skills/prizmkit-init/references/rules/layer-detection.md +41 -0
  27. package/package.json +1 -1
  28. package/src/index.js +10 -0
  29. package/src/scaffold.js +124 -7
@@ -0,0 +1,639 @@
1
+ # Derivation Rules — Mobile Auto-Derivation Rule Mapping
2
+
3
+ > This file defines the mapping "Phase 2 answers → rule blocks auto-injected into mobile-rules.md". The AI reads this file in Phase 3 — **do not ask the user again**.
4
+
5
+ ---
6
+
7
+ ## Phase 2 Answer Direct-Fill Table (copy user answer text directly into placeholders)
8
+
9
+ | Template Placeholder | Source | Example Fill |
10
+ |---------------------|--------|-------------|
11
+ | `{{ project_name }}` | Phase 0 auto-read | `my-mobile-app` |
12
+ | `{{ generated_at }}` | Phase 4, AI writes current date | `2026-05-24` |
13
+ | `{{ platform }}` | Q1 answer | `Flutter (Dart)` |
14
+ | `{{ min_os_version }}` | Q2 answer | `iOS 17+ / Android 14+` |
15
+ | `{{ architecture }}` | Q3 answer | `MVVM` |
16
+ | `{{ ui_framework }}` | Q4 answer | `Material Design 3` |
17
+ | `{{ navigation }}` | Q5 answer | `GoRouter` |
18
+ | `{{ state_management }}` | Q6 answer | `Riverpod` |
19
+ | `{{ networking }}` | Q7 answer | `Dio` |
20
+ | `{{ persistence }}` | Q8 answer | `Drift` |
21
+ | `{{ push_notifications }}` | Q9 answer | `FCM/APNs` |
22
+ | `{{ background_tasks }}` | Q10 answer | `WorkManager/BGTaskScheduler` |
23
+ | `{{ permissions_strategy }}` | Q11 answer | `Ask-on-use` |
24
+ | `{{ test_coverage }}` | Q12 answer | `Unit + Widget + Integration` |
25
+ | `{{ unit_test_framework }}` | Q13 answer | `flutter_test + mocktail` |
26
+ | `{{ e2e_framework }}` | Q14 answer | `Patrol` |
27
+ | `{{ distribution }}` | Q15 answer | `App Store + Google Play` |
28
+ | `{{ performance_target }}` | Q16 answer | `60fps, < 100MB` |
29
+ | `{{ a11y_target }}` | Q17 answer | `Platform defaults` |
30
+
31
+ ---
32
+
33
+ ## Trigger Map
34
+
35
+ **Coverage policy**: 【Recommended】options always have trigger entries with rule blocks. Non-recommended options may or may not have triggers. If a user selects a non-recommended option with no matching trigger, the corresponding rule placeholder is intentionally left empty — the TL;DR table still records the user's choice, but no pre-authored derived rules exist for that option. The AI may suggest the user switch to the recommended option for better rule coverage.
36
+
37
+ **Q13/Q14 note**: Q13 and Q14 are direct-fill only (no derivation rule blocks). The TL;DR table documents the chosen frameworks. Detailed framework-specific rules are not auto-generated — the AI should apply the framework's official best practices.
38
+
39
+ | Trigger (Phase 2 Answer) | Inject Rule Block ID | Inject Into Placeholder |
40
+ |--------------------------|---------------------|------------------------|
41
+ | Q1 = Flutter | `D-FLUTTER-01`, `D-FLUTTER-02` | `{{ tech_stack_rules }}` |
42
+ | Q1 = React Native | `D-RN-01`, `D-RN-02` | `{{ tech_stack_rules }}` |
43
+ | Q1 = iOS native | `D-IOS-01`, `D-IOS-02` | `{{ tech_stack_rules }}` |
44
+ | Q1 = Android native | `D-ANDROID-01`, `D-ANDROID-02` | `{{ tech_stack_rules }}` |
45
+ | Q1 = Both native | `D-BOTH-NATIVE-01` | `{{ tech_stack_rules }}` |
46
+ | Q2 = Latest - 1 | `D-OS-LATEST-1-01` | `{{ tech_stack_rules }}` |
47
+ | Q2 = Latest - 2 | `D-OS-LATEST-2-01` | `{{ tech_stack_rules }}` |
48
+ | Q2 = Latest - 3 | `D-OS-LATEST-3-01` | `{{ tech_stack_rules }}` |
49
+ | Q3 = MVVM | `D-MVVM-01` | `{{ arch_rules }}` |
50
+ | Q3 = Clean Architecture | `D-CLEAN-MOBILE-01` | `{{ arch_rules }}` |
51
+ | Q3 = Redux-style / MVI | `D-MVI-01` | `{{ arch_rules }}` |
52
+ | Q3 = Simple MVC | `D-MVC-MOBILE-01` | `{{ arch_rules }}` |
53
+ | Q4 = Material Design 3 | `D-MATERIAL3-01` | `{{ ui_rules }}` |
54
+ | Q4 = Cupertino | `D-CUPERTINO-01` | `{{ ui_rules }}` |
55
+ | Q4 = Adaptive | `D-ADAPTIVE-UI-01` | `{{ ui_rules }}` |
56
+ | Q4 = RN core + StyleSheet | `D-RN-CORE-01` | `{{ ui_rules }}` |
57
+ | Q4 = Tamagui / NativeWind | `D-NATIVEWIND-01` | `{{ ui_rules }}` |
58
+ | Q4 = SwiftUI | `D-SWIFTUI-01` | `{{ ui_rules }}` |
59
+ | Q4 = UIKit | `D-UIKIT-01` | `{{ ui_rules }}` |
60
+ | Q4 = Jetpack Compose | `D-COMPOSE-01` | `{{ ui_rules }}` |
61
+ | Q4 = XML + Material 3 | `D-XML-MATERIAL-01` | `{{ ui_rules }}` |
62
+ | Q5 = Platform-default | `D-DEEP-LINK-01` | `{{ navigation_rules }}` |
63
+ | Q5 = URL-based routing | `D-URL-ROUTING-01` | `{{ navigation_rules }}` |
64
+ | Q5 = Simple stack | `D-STACK-NAV-01` | `{{ navigation_rules }}` |
65
+ | Q6 = Riverpod | `D-RIVERPOD-01` | `{{ state_rules }}` |
66
+ | Q6 = Bloc | `D-BLOC-01` | `{{ state_rules }}` |
67
+ | Q6 = Provider | `D-PROVIDER-01` | `{{ state_rules }}` |
68
+ | Q6 = GetX | `D-GETX-01` | `{{ state_rules }}` |
69
+ | Q6 = Zustand | `D-ZUSTAND-MOBILE-01` | `{{ state_rules }}` |
70
+ | Q6 = Redux Toolkit | `D-REDUX-MOBILE-01` | `{{ state_rules }}` |
71
+ | Q6 = @Observable / @State | `D-SWIFT-STATE-01` | `{{ state_rules }}` |
72
+ | Q6 = Combine | `D-COMBINE-01` | `{{ state_rules }}` |
73
+ | Q6 = ViewModel + StateFlow | `D-VIEWMODEL-STATE-01` | `{{ state_rules }}` |
74
+ | Q6 = MutableState | `D-MUTABLESTATE-01` | `{{ state_rules }}` |
75
+ | Q7 = Dio | `D-DIO-01` | `{{ networking_rules }}` |
76
+ | Q7 = Axios | `D-AXIOS-MOBILE-01` | `{{ networking_rules }}` |
77
+ | Q7 = URLSession + async/await | `D-URLSESSION-01` | `{{ networking_rules }}` |
78
+ | Q7 = Retrofit + OkHttp | `D-RETROFIT-01` | `{{ networking_rules }}` |
79
+ | Q8 = Drift | `D-DRIFT-01` | `{{ persistence_rules }}` |
80
+ | Q8 = Hive | `D-HIVE-01` | `{{ persistence_rules }}` |
81
+ | Q8 = MMKV + WatermelonDB | `D-MMKV-01` | `{{ persistence_rules }}` |
82
+ | Q8 = SwiftData | `D-SWIFTDATA-01` | `{{ persistence_rules }}` |
83
+ | Q8 = CoreData | `D-COREDATA-01` | `{{ persistence_rules }}` |
84
+ | Q8 = Room | `D-ROOM-01` | `{{ persistence_rules }}` |
85
+ | Q8 = DataStore | `D-DATASTORE-01` | `{{ persistence_rules }}` |
86
+ | Q9 = Yes, needed | `D-PUSH-01` | `{{ platform_features_rules }}` |
87
+ | Q10 = Yes, needed | `D-BG-TASK-01` | `{{ platform_features_rules }}` |
88
+ | Q11 = Ask-on-use | `D-PERM-ASK-ON-USE-01` | `{{ platform_features_rules }}` |
89
+ | Q11 = Ask-on-launch | `D-PERM-ASK-LAUNCH-01` | `{{ platform_features_rules }}` |
90
+ | Q12 = All tiers | `D-MOBILE-TEST-01` | `{{ test_rules }}` |
91
+ | Q12 = Unit + Widget only | `D-MOBILE-TEST-02` | `{{ test_rules }}` |
92
+ | Q12 = Critical path only | `D-MOBILE-TEST-03` | `{{ test_rules }}` |
93
+ | Q15 = App Store + Google Play | `D-APP-STORE-01` | `{{ distribution_rules }}` |
94
+ | Q15 = Enterprise distribution | `D-ENTERPRISE-DIST-01` | `{{ distribution_rules }}` |
95
+ | Q16 = 60fps | `D-PERF-60FPS-01` | `{{ performance_rules }}` |
96
+ | Q16 = 120fps premium | `D-PERF-120FPS-01` | `{{ performance_rules }}` |
97
+ | Q17 = Platform defaults | `D-A11Y-PLATFORM-01` | `{{ a11y_rules }}` |
98
+ | Q17 = WCAG 2.1 AA equivalent | `D-A11Y-WCAG-01` | `{{ a11y_rules }}` |
99
+ | Q18 = Forbid | `D-AI-DEP-STRICT-MOBILE-01` | `{{ ai_dependency_rule }}` |
100
+ | Q18 = Allowed with declaration | `D-AI-DEP-ANNOUNCE-MOBILE-01` | `{{ ai_dependency_rule }}` |
101
+ | Q19 = Must list callers | `D-AI-BREAK-STRICT-MOBILE-01` | `{{ ai_breaking_change_rule }}` |
102
+ | Q20 = Must not mix paradigms | `D-AI-PLATFORM-STRICT-01` | `{{ ai_platform_rule }}` |
103
+
104
+ **Matching rule**: The AI should use substring match against the user's selected option text. The trigger text in the left column is a key phrase; the AI should check if all significant words in the trigger appear in the selected option text (keyword matching), not literal substring matching.
105
+
106
+ ---
107
+
108
+ ## Rule Block Definitions
109
+
110
+ ### D-FLUTTER-01
111
+ **Trigger**: Q1 = Flutter | **Inject into**: `{{ tech_stack_rules }}`
112
+
113
+ - Flutter SDK stable channel. `pubspec.yaml` locks dependency versions with caret constraints.
114
+ - Dart analysis: `flutter analyze` must pass with zero errors in CI. Use `dart fix --apply` for auto-fixes.
115
+ - Widget tree: prefer composition over inheritance. Forbid creating custom widget subclasses when composition works.
116
+ - `const` constructors everywhere possible (improves rebuild performance). CI should warn on missing `const`.
117
+ - StatefulWidget only when state is needed. Default to StatelessWidget.
118
+
119
+ ### D-FLUTTER-02
120
+ **Trigger**: Q1 = Flutter | **Inject into**: `{{ tech_stack_rules }}`
121
+
122
+ - Project structure: `lib/features/<domain>/` with `screens/`, `widgets/`, `models/`, `services/`.
123
+ - Assets declared in `pubspec.yaml` under `flutter: assets:`. Forbid hardcoded asset paths in code (use an `Assets` class or code-gen).
124
+ - Use `flutter_lints` or `very_good_analysis` for lint rules. Forbid disabling lint rules without a comment explaining why.
125
+ - Platform channels: isolate in a single `platform/` service layer. Forbid scattering `MethodChannel` calls across widgets.
126
+
127
+ ### D-RN-01
128
+ **Trigger**: Q1 = React Native | **Inject into**: `{{ tech_stack_rules }}`
129
+
130
+ - React Native with TypeScript strict mode. Forbid `any` in new code.
131
+ - Use Hermes JS engine (default in RN 0.70+). Test with Hermes enabled.
132
+ - Platform-specific code: use `Platform.OS` checks or `.ios.ts` / `.android.ts` file extensions. Forbid platform-specific imports leaking into shared code.
133
+ - Metro bundler config: commit `metro.config.js`. Custom resolvers documented.
134
+
135
+ ### D-RN-02
136
+ **Trigger**: Q1 = React Native | **Inject into**: `{{ tech_stack_rules }}`
137
+
138
+ - Project structure: `src/features/<domain>/` with `screens/`, `components/`, `hooks/`, `api/`.
139
+ - Native modules: wrap in a thin TypeScript adapter. Forbid using native module APIs directly in screens.
140
+ - Use `react-native-mmkv` for fast KV storage over AsyncStorage for performance-critical data.
141
+
142
+ ### D-IOS-01
143
+ **Trigger**: Q1 = iOS native | **Inject into**: `{{ tech_stack_rules }}`
144
+
145
+ - Swift 5.9+. Use Swift Concurrency (`async/await`) for all async work. Forbid completion-handler-based APIs for new code.
146
+ - Swift Package Manager for dependencies. Forbid Carthage. CocoaPods allowed only for legacy deps without SPM support.
147
+ - All public API must have documentation comments (`///`). CI validates with `swift-docc-plugin`.
148
+ - `swiftlint` must pass with zero errors. Config committed to repo root.
149
+
150
+ ### D-IOS-02
151
+ **Trigger**: Q1 = iOS native | **Inject into**: `{{ tech_stack_rules }}`
152
+
153
+ - Xcode project settings managed via `.xcconfig` files. Forbid hardcoding build settings in the project file.
154
+ - Version and build number managed by CI. Forbid manual increment.
155
+ - App delegate/scene delegate minimal. Use feature-based app initialization.
156
+
157
+ ### D-ANDROID-01
158
+ **Trigger**: Q1 = Android native | **Inject into**: `{{ tech_stack_rules }}`
159
+
160
+ - Kotlin 2.0+. Use Kotlin Coroutines + Flow for async. Forbid raw `Thread` / `AsyncTask` (deprecated).
161
+ - Gradle Version Catalog (`libs.versions.toml`) for dependency management. Forbid declaring versions directly in module `build.gradle`.
162
+ - `detekt` must pass with zero errors. Config committed to repo root.
163
+ - Min SDK, target SDK, compile SDK declared in a single `config.gradle` or convention plugin.
164
+
165
+ ### D-ANDROID-02
166
+ **Trigger**: Q1 = Android native | **Inject into**: `{{ tech_stack_rules }}`
167
+
168
+ - Project structure by feature: `app/src/main/java/<package>/<feature>/` with `ui/`, `data/`, `domain/`.
169
+ - Dependency injection via Hilt (recommended) or Koin. Forbid manual DI / service locator in application code.
170
+ - ProGuard/R8 rules committed. Add rules for each reflection-using library.
171
+
172
+ ### D-BOTH-NATIVE-01
173
+ **Trigger**: Q1 = Both native | **Inject into**: `{{ tech_stack_rules }}`
174
+
175
+ - Dual native codebases (Swift + Kotlin). iOS rules apply to the Swift codebase. Android rules apply to the Kotlin codebase.
176
+ - Shared business logic must be documented in a shared spec — no code-level sharing between the two platforms.
177
+ - Each platform follows its own native conventions independently.
178
+ - Both platform-specific rule sets (D-IOS-* and D-ANDROID-*) apply to their respective codebases.
179
+
180
+ ### D-OS-LATEST-1-01
181
+ **Trigger**: Q2 = Latest - 1 | **Inject into**: `{{ tech_stack_rules }}`
182
+
183
+ - Target API level: latest stable - 1. minSdk = latest - 3 (or latest - 2 for platforms with faster adoption).
184
+ - Forbid using APIs introduced in the latest OS version without `@available` / `@RequiresApi` guards.
185
+ - Deprecated APIs in target version must be migrated within one release cycle.
186
+
187
+ ### D-OS-LATEST-2-01
188
+ **Trigger**: Q2 = Latest - 2 | **Inject into**: `{{ tech_stack_rules }}`
189
+
190
+ - Target API level: latest stable - 2. Wider compatibility, more devices covered.
191
+ - `@available(iOS 16, *)` / `@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)` for latest APIs.
192
+ - Test on oldest supported OS version as part of CI or manual QA checklist.
193
+
194
+ ### D-OS-LATEST-3-01
195
+ **Trigger**: Q2 = Latest - 3 | **Inject into**: `{{ tech_stack_rules }}`
196
+
197
+ - Wide compatibility mode. Must test on oldest supported OS version for every release.
198
+ - More `@available` checks needed. Document which features degrade gracefully on older OS versions.
199
+
200
+ ### D-MVVM-01
201
+ **Trigger**: Q3 = MVVM | **Inject into**: `{{ arch_rules }}`
202
+
203
+ - ViewModel exposes UI state as observable streams (StateFlow / @Published / Stream). View observes and renders.
204
+ - ViewModel never holds a reference to View/Widget/ViewController. Use unidirectional data flow.
205
+ - One ViewModel per screen or major component. Forbid sharing ViewModel instances across unrelated screens.
206
+ - Business logic in ViewModel is testable without UI framework imports.
207
+
208
+ ### D-CLEAN-MOBILE-01
209
+ **Trigger**: Q3 = Clean Architecture | **Inject into**: `{{ arch_rules }}`
210
+
211
+ - Layers: Presentation → Domain (UseCase) → Data (Repository) → Data Source.
212
+ - Domain layer has zero platform/framework dependencies. Pure Dart/Kotlin/Swift.
213
+ - UseCases are single-responsibility. One UseCase = one business operation.
214
+ - Repository interfaces in Domain layer. Implementations in Data layer.
215
+
216
+ ### D-MVI-01
217
+ **Trigger**: Q3 = Redux-style / MVI | **Inject into**: `{{ arch_rules }}`
218
+
219
+ - Unidirectional data flow: Intent (user action) → Model (state mutation) → View (render).
220
+ - State is a single immutable object per screen. Mutations produce new state (never modify in-place).
221
+ - Side effects (network, DB) handled by middleware or dedicated effect handlers. Forbid side effects in reducers/mutation functions.
222
+
223
+ ### D-MVC-MOBILE-01
224
+ **Trigger**: Q3 = Simple MVC | **Inject into**: `{{ arch_rules }}`
225
+
226
+ - Simplified pattern for small apps (< 5 screens). Model holds data + business logic. Controller mediates. View renders.
227
+ - Forbid using MVC for projects expected to grow beyond 10 screens. Re-evaluate architecture before scaling.
228
+
229
+ ### D-MATERIAL3-01
230
+ **Trigger**: Q4 = Material Design 3 | **Inject into**: `{{ ui_rules }}`
231
+
232
+ - Use Material 3 design tokens: `MaterialTheme.colorScheme`, `MaterialTheme.typography`.
233
+ - Dynamic color (Material You) on Android 12+. Opt-in via `DynamicColorBuilder`.
234
+ - Theme configured via `ThemeData` using `ColorScheme.fromSeed()`. Forbid hardcoding colors outside theme.
235
+ - Component spacing follows Material 3 8dp grid.
236
+
237
+ ### D-CUPERTINO-01
238
+ **Trigger**: Q4 = Cupertino | **Inject into**: `{{ ui_rules }}`
239
+
240
+ - Use `CupertinoApp` + `CupertinoPageScaffold`. iOS-native look and feel throughout.
241
+ - Navigation uses `CupertinoPageRoute`. Forbid mixing with Material PageRoute for consistency.
242
+ - Cupertino widgets for forms, dialogs, and action sheets. Use `cupertino_icons` package.
243
+
244
+ ### D-ADAPTIVE-UI-01
245
+ **Trigger**: Q4 = Adaptive | **Inject into**: `{{ ui_rules }}`
246
+
247
+ - Platform-adaptive UI: `Platform.isIOS` → Cupertino, `Platform.isAndroid` → Material 3.
248
+ - Shared business logic. UI switches at the widget tree leaves, not at the app root.
249
+ - `adaptive_theme` or custom platform check helper. Forbid importing platform-specific widget libraries in shared code.
250
+
251
+ ### D-RN-CORE-01
252
+ **Trigger**: Q4 = RN core + StyleSheet | **Inject into**: `{{ ui_rules }}`
253
+
254
+ - Use React Native core components (View, Text, ScrollView, FlatList, TextInput). Forbid unnecessary UI libraries.
255
+ - StyleSheet.create() for all styles. Forbid inline style objects (causes re-render churn).
256
+ - Design tokens in `src/theme/tokens.ts`. All components reference tokens via `useTheme()` or import.
257
+
258
+ ### D-NATIVEWIND-01
259
+ **Trigger**: Q4 = Tamagui / NativeWind | **Inject into**: `{{ ui_rules }}`
260
+
261
+ - Use Tamagui or NativeWind as the UI foundation. Forbid mixing with raw StyleSheet.
262
+ - Design tokens in `tamagui.config.ts` or `tailwind.config.js`. Theme centralized.
263
+ - Optimizing compiler (Tamagui) or Tailwind JIT must be configured for production builds.
264
+
265
+ ### D-SWIFTUI-01
266
+ **Trigger**: Q4 = SwiftUI | **Inject into**: `{{ ui_rules }}`
267
+
268
+ - SwiftUI with `@Observable` macro (iOS 17+) or `@StateObject` / `@ObservedObject` (iOS 16-).
269
+ - View structs lean — extract subviews when body exceeds ~20 lines.
270
+ - Use `NavigationStack` (iOS 16+). Forbid `NavigationView` (deprecated).
271
+ - Preview providers for all screens. Forbid relying on simulator-only iteration.
272
+
273
+ ### D-UIKIT-01
274
+ **Trigger**: Q4 = UIKit | **Inject into**: `{{ ui_rules }}`
275
+
276
+ - UIKit with programmatic Auto Layout (NSLayoutConstraint or SnapKit). Forbid Storyboards for new screens.
277
+ - View code separated from ViewController: use UIView subclasses for rendering, ViewController for lifecycle + coordination.
278
+ - Use `UICollectionView` with `UICollectionViewDiffableDataSource` for lists. Forbid `UITableView` for new code.
279
+
280
+ ### D-COMPOSE-01
281
+ **Trigger**: Q4 = Jetpack Compose | **Inject into**: `{{ ui_rules }}`
282
+
283
+ - Jetpack Compose with Material 3. `setContent {}` as single entry point.
284
+ - State hoisting: state flows down, events flow up. Forbid Compose `remember` as global state substitute.
285
+ - Preview annotations (`@Preview`) with multiple configurations (light/dark, font scales).
286
+ - Use `Modifier` chaining. Forbid custom drawing when a Modifier exists.
287
+
288
+ ### D-XML-MATERIAL-01
289
+ **Trigger**: Q4 = XML + Material 3 | **Inject into**: `{{ ui_rules }}`
290
+
291
+ - XML layouts with Material 3 theme via `MaterialComponents` theme parent.
292
+ - Data Binding or ViewBinding for view references. Forbid `findViewById`.
293
+ - `ConstraintLayout` as the default layout. Forbid deeply nested `LinearLayout` chains.
294
+
295
+ ### D-DEEP-LINK-01
296
+ **Trigger**: Q5 = Platform-default | **Inject into**: `{{ navigation_rules }}`
297
+
298
+ - Navigation uses platform defaults with deep linking support:
299
+ - Flutter: GoRouter with `ShellRoute` for tab-based navigation.
300
+ - React Native: React Navigation with linking config.
301
+ - iOS: NavigationStack with `navigationDestination(for:)`.
302
+ - Android: Compose Navigation with NavDeepLink.
303
+ - Every screen must have a unique route path. Forbid ambiguous routes.
304
+
305
+ ### D-URL-ROUTING-01
306
+ **Trigger**: Q5 = URL-based routing | **Inject into**: `{{ navigation_rules }}`
307
+
308
+ - URL-based routing as first-class citizen. Every screen has a canonical URL pattern.
309
+ - Deep link URLs resolve to the same screen as in-app navigation.
310
+ - Route patterns documented in a centralized `routes.dart` / `routes.ts` / `Routes.swift` file.
311
+
312
+ ### D-STACK-NAV-01
313
+ **Trigger**: Q5 = Simple stack | **Inject into**: `{{ navigation_rules }}`
314
+
315
+ - Simple push/pop stack navigation. No deep linking.
316
+ - Forbid programmatic navigation to arbitrary stack positions (push-only from current top).
317
+ - Suitable for prototype/simple apps. Plan deep linking migration path for production.
318
+
319
+ ### D-RIVERPOD-01
320
+ **Trigger**: Q6 = Riverpod | **Inject into**: `{{ state_rules }}`
321
+
322
+ - State via Riverpod providers. `StateNotifierProvider` for complex state, `Provider` for derived/computed.
323
+ - Providers auto-disposed when no longer listened to (default behavior). Forbid manual dispose.
324
+ - Provider dependencies explicit. Forbid using `ref.read` inside build methods (use `ref.watch`).
325
+ - Testing: override providers in test with `ProviderScope.overrides`.
326
+
327
+ ### D-BLOC-01
328
+ **Trigger**: Q6 = Bloc | **Inject into**: `{{ state_rules }}`
329
+
330
+ - Bloc pattern: Event → Bloc → State. Events and States are sealed classes (or freezed unions).
331
+ - Bloc-to-Bloc communication via stream subscription in the presentation layer, not direct Bloc references.
332
+ - `BlocProvider` provides Bloc to widget subtree. Forbid creating Bloc instances directly in widgets.
333
+ - Testing: `blocTest` for unit-testing Bloc logic. Mock Blocs for widget tests.
334
+
335
+ ### D-PROVIDER-01
336
+ **Trigger**: Q6 = Provider | **Inject into**: `{{ state_rules }}`
337
+
338
+ - Provider pattern: `ChangeNotifierProvider` for mutable state, `Provider` for immutable/reactive values.
339
+ - Use `context.watch<T>()` in build, `context.read<T>()` in callbacks. Forbid `context.read` in build methods.
340
+ - For complex state (> 5 properties), prefer Riverpod or Bloc. Provider is designed for medium-complexity state.
341
+
342
+ ### D-GETX-01
343
+ **Trigger**: Q6 = GetX | **Inject into**: `{{ state_rules }}`
344
+
345
+ - GetX for state management + navigation + DI. Verify that all three features are needed before choosing GetX.
346
+ - `GetBuilder` for reactive UI. Forbid mixing GetX reactive state with other state management solutions.
347
+ - Warning: GetX is opinionated and couples navigation, state, and DI. Migration away from GetX is expensive. Document this decision.
348
+
349
+ ### D-ZUSTAND-MOBILE-01
350
+ **Trigger**: Q6 = Zustand | **Inject into**: `{{ state_rules }}`
351
+
352
+ - Zustand stores: one per domain. Forbid massive global store.
353
+ - Store selectors prevent unnecessary re-renders: `useStore(state => state.specificField)`.
354
+ - Async actions in store via `set`. Forbid calling `set` outside of store actions.
355
+ - Persist middleware for session state: `zustand/middleware persist` with MMKV storage adapter.
356
+
357
+ ### D-REDUX-MOBILE-01
358
+ **Trigger**: Q6 = Redux Toolkit | **Inject into**: `{{ state_rules }}`
359
+
360
+ - Redux Toolkit with `createSlice` + `createAsyncThunk`.
361
+ - Middleware: `redux-persist` with MMKV storage engine for session persistence.
362
+ - Forbid dispatching actions directly from components — use typed hooks (`useAppDispatch`, `useAppSelector`).
363
+
364
+ ### D-SWIFT-STATE-01
365
+ **Trigger**: Q6 = @Observable / @State | **Inject into**: `{{ state_rules }}`
366
+
367
+ - SwiftUI native state: `@State` for local UI state, `@Observable` (Observation framework) for shared model data.
368
+ - `@Environment` for dependency injection and theme. Forbid creating singletons for DI purposes — use Environment instead.
369
+ - `@Bindable` for two-way binding to Observable properties. Forbid hand-rolled KVO.
370
+
371
+ ### D-COMBINE-01
372
+ **Trigger**: Q6 = Combine | **Inject into**: `{{ state_rules }}`
373
+
374
+ - Combine publishers for reactive data streams. `@Published` for observable properties.
375
+ - `AnyCancellable` stored in a `Set<AnyCancellable>` for automatic cancellation on deinit.
376
+ - Forbid `.sink` without storing the cancellable (memory leak). Use `.store(in: &cancellables)`.
377
+
378
+ ### D-VIEWMODEL-STATE-01
379
+ **Trigger**: Q6 = ViewModel + StateFlow | **Inject into**: `{{ state_rules }}`
380
+
381
+ - ViewModel exposes `StateFlow<UiState>` (single sealed class per screen). View collects with `collectAsStateWithLifecycle()`.
382
+ - ViewModel scoped to navigation destination. Forbid ViewModels that outlive their screen.
383
+ - ViewModelFactory provided via Hilt or manual DI. Forbid instantiating ViewModels with `ViewModelProvider` directly in Activities.
384
+
385
+ ### D-MUTABLESTATE-01
386
+ **Trigger**: Q6 = MutableState | **Inject into**: `{{ state_rules }}`
387
+
388
+ - Compose `mutableStateOf` + `remember` for local UI state. Forbid as global state container.
389
+ - For cross-screen state, use ViewModel + StateFlow, not hoisted `mutableStateOf` at the Activity level.
390
+
391
+ ### D-DIO-01
392
+ **Trigger**: Q7 = Dio | **Inject into**: `{{ networking_rules }}`
393
+
394
+ - Dio instance singleton configured with base URL, interceptors, timeout (connect: 10s, receive: 30s).
395
+ - Interceptors: auth token injection, refresh token retry, logging (debug only).
396
+ - Response typed via `dio.withJson<T>()` or manual `fromJson` factories. Forbid `dynamic` response types.
397
+ - Certificate pinning via `HttpClientAdapter` with custom `SecurityContext` for release builds.
398
+
399
+ ### D-AXIOS-MOBILE-01
400
+ **Trigger**: Q7 = Axios | **Inject into**: `{{ networking_rules }}`
401
+
402
+ - Axios instance with base URL, interceptors, timeout (30s default).
403
+ - Request interceptor: attach auth token. Response interceptor: handle 401 refresh, global error normalization.
404
+ - API functions in `src/api/` return typed Promise. Forbid `axios.get<any>(...)`.
405
+
406
+ ### D-URLSESSION-01
407
+ **Trigger**: Q7 = URLSession + async/await | **Inject into**: `{{ networking_rules }}`
408
+
409
+ - `URLSession.shared` for simple requests. Custom `URLSession` with `URLSessionConfiguration.default` + custom headers for API.
410
+ - Async/await: `let (data, response) = try await session.data(for: request)`. Forbid completion handler style.
411
+ - Response decoding via `JSONDecoder` with `keyDecodingStrategy = .convertFromSnakeCase`.
412
+ - Unified API service protocol. Mock implementation for tests and SwiftUI previews.
413
+
414
+ ### D-RETROFIT-01
415
+ **Trigger**: Q7 = Retrofit + OkHttp | **Inject into**: `{{ networking_rules }}`
416
+
417
+ - Retrofit interfaces with `suspend` functions returning `Response<T>` or `Result<T>`.
418
+ - OkHttp client singleton with interceptors: auth token, logging (debug), caching.
419
+ - Moshi or kotlinx.serialization for JSON. Forbid Gson (unmaintained, slower).
420
+ - Timeout: connect 10s, read 30s, write 30s.
421
+
422
+ ### D-DRIFT-01
423
+ **Trigger**: Q8 = Drift | **Inject into**: `{{ persistence_rules }}`
424
+
425
+ - Drift (SQLite, type-safe). Table definitions via Dart classes extending `Table`.
426
+ - DAO (Data Access Object) classes for query logic. Forbid raw SQL in widgets/services.
427
+ - Migration strategy: `onUpgrade` with versioned migration callbacks. Test migrations.
428
+ - Database singleton provided via Riverpod/Provider. Forbid opening database directly.
429
+
430
+ ### D-HIVE-01
431
+ **Trigger**: Q8 = Hive | **Inject into**: `{{ persistence_rules }}`
432
+
433
+ - Hive for KV storage (settings, cache). Forbid using Hive for relational data.
434
+ - TypeAdapters registered at app startup. Forbid writing untyped data (`Hive.box('x').put('k', someDynamic)`).
435
+ - Boxes opened once at app start, closed on app teardown. Forbid opening/closing boxes per widget build.
436
+
437
+ ### D-MMKV-01
438
+ **Trigger**: Q8 = MMKV + WatermelonDB | **Inject into**: `{{ persistence_rules }}`
439
+
440
+ - MMKV for fast KV (tokens, settings, cache). WatermelonDB for relational data with lazy loading.
441
+ - WatermelonDB: `@text`, `@date`, `@children`, `@relation` decorators for schema definition.
442
+ - Database version managed via `schemaMigrations`. Forbid destructive migrations without backup.
443
+
444
+ ### D-SWIFTDATA-01
445
+ **Trigger**: Q8 = SwiftData | **Inject into**: `{{ persistence_rules }}`
446
+
447
+ - SwiftData with `@Model` macro. `.modelContainer` in WindowGroup or root view.
448
+ - `@Query` for reactive fetch in SwiftUI views. Forbid manual fetch requests in view code.
449
+ - Migration via `SchemaMigrationPlan` versions. Test migration from previous model version.
450
+
451
+ ### D-COREDATA-01
452
+ **Trigger**: Q8 = CoreData | **Inject into**: `{{ persistence_rules }}`
453
+
454
+ - CoreData with `NSPersistentContainer`. Background contexts for writes, view context for reads only.
455
+ - Forbid `viewContext.perform {}` for writes. Use `container.performBackgroundTask {}` for all mutations.
456
+ - Model versioning: add new model version for schema changes. Mapping model for lightweight migration.
457
+
458
+ ### D-ROOM-01
459
+ **Trigger**: Q8 = Room | **Inject into**: `{{ persistence_rules }}`
460
+
461
+ - Room with `@Entity`, `@Dao`, `@Database`. TypeConverters for custom types.
462
+ - DAO methods: `suspend` for writes, `Flow<List<T>>` for observable reads.
463
+ - Migration via `Migration(x, y) { ... }` with SQL strategies. Test migrations with `MigrationTestHelper`.
464
+ - Database singleton via Hilt `@Singleton`. Forbid multiple database instances.
465
+
466
+ ### D-DATASTORE-01
467
+ **Trigger**: Q8 = DataStore | **Inject into**: `{{ persistence_rules }}`
468
+
469
+ - Preferences DataStore (KV) for settings. Proto DataStore for typed structured data.
470
+ - `Flow`-based reads. Forbid using `runBlocking` with DataStore reads on the main thread.
471
+ - DataStore file migration from SharedPreferences must be tested.
472
+
473
+ ### D-PUSH-01
474
+ **Trigger**: Q9 = Yes, needed | **Inject into**: `{{ platform_features_rules }}`
475
+
476
+ - Push via FCM (Android) / APNs (iOS). Use a cross-platform wrapper (firebase_messaging / @react-native-firebase/messaging) for cross-platform projects.
477
+ - Notification channels (Android 8+): one channel per notification category with clear user-facing name.
478
+ - Token management: store token on server, retry on failure, invalidate on logout.
479
+ - Foreground notification display configurable. Forbid showing sensitive data in notification body.
480
+
481
+ ### D-BG-TASK-01
482
+ **Trigger**: Q10 = Yes, needed | **Inject into**: `{{ platform_features_rules }}`
483
+
484
+ - Flutter: `workmanager` plugin. React Native: `react-native-background-fetch`.
485
+ - iOS: BGAppRefreshTask (short) or BGProcessingTask (long). Android: WorkManager with constraints (network, charging).
486
+ - Background task ID registered in Info.plist (iOS) and AndroidManifest.xml.
487
+ - Forbid running UI updates from background tasks. Persist results, update UI on next foreground.
488
+
489
+ ### D-PERM-ASK-ON-USE-01
490
+ **Trigger**: Q11 = Ask-on-use | **Inject into**: `{{ platform_features_rules }}`
491
+
492
+ - Request permission at the moment of first use, preceded by a rationale dialog (optional but recommended).
493
+ - Handle "Don't ask again": detect permanent denial, show Settings redirect dialog with clear benefit statement.
494
+ - Permission status checked via platform API before attempting the protected operation. Forbid assuming permission is granted.
495
+
496
+ ### D-PERM-ASK-LAUNCH-01
497
+ **Trigger**: Q11 = Ask-on-launch | **Inject into**: `{{ platform_features_rules }}`
498
+
499
+ - Critical permissions only requested at launch. Must include a clear onboarding explanation BEFORE the system dialog.
500
+ - Forbid requesting non-critical permissions at launch. This reduces acceptance rate for all permissions.
501
+
502
+ ### D-MOBILE-TEST-01
503
+ **Trigger**: Q12 = All tiers | **Inject into**: `{{ test_rules }}`
504
+
505
+ - Three-tier testing: unit (ViewModel/Bloc/UseCase), widget/component (individual UI), integration (critical flows).
506
+ - Unit test coverage: ViewModel/Bloc layer ≥ 80%. Widget/component tests for shared components ≥ 60%.
507
+ - Integration tests cover: login, registration, core CRUD, payment (if applicable).
508
+
509
+ ### D-MOBILE-TEST-02
510
+ **Trigger**: Q12 = Unit + Widget | **Inject into**: `{{ test_rules }}`
511
+
512
+ - Unit tests + widget/component tests. No integration/E2E tests.
513
+ - Coverage: ViewModel/Bloc layer ≥ 80%. Shared widgets ≥ 60%.
514
+ - Recommend adding integration tests for critical flows before production.
515
+
516
+ ### D-MOBILE-TEST-03
517
+ **Trigger**: Q12 = Critical path only | **Inject into**: `{{ test_rules }}`
518
+
519
+ - Integration tests for critical flows only (login, core CRUD, payment).
520
+ - No coverage thresholds enforced project-wide. Critical paths must have ≥ 1 test each.
521
+
522
+ ### D-APP-STORE-01
523
+ **Trigger**: Q15 = App Store + Google Play | **Inject into**: `{{ distribution_rules }}`
524
+
525
+ - iOS: archive via Xcode Cloud or Fastlane. Upload to App Store Connect via `deliver` or Xcode.
526
+ - Android: signed app bundle via `./gradlew bundleRelease`. Upload to Google Play Console.
527
+ - Staged rollout default: 10% → 50% → 100% over 48 hours. Monitor crash-free rate at each stage.
528
+ - Code signing: iOS uses automatic signing (Xcode managed). Android uses `signingConfigs` in Gradle with keystore in CI secrets.
529
+
530
+ ### D-ENTERPRISE-DIST-01
531
+ **Trigger**: Q15 = Enterprise distribution | **Inject into**: `{{ distribution_rules }}`
532
+
533
+ - iOS: enterprise certificate + provisioning profile. OTA distribution via HTTPS server with manifest.plist.
534
+ - Android: signed APK distributed via private channel or MDM.
535
+ - No App Store Review process. Internal compliance review replaces it. Document compliance criteria.
536
+
537
+ ### D-PERF-60FPS-01
538
+ **Trigger**: Q16 = 60fps | **Inject into**: `{{ performance_rules }}`
539
+
540
+ - Frame budget: 16ms/frame. Profile with Flutter DevTools / Android Studio Profiler / Xcode Instruments.
541
+ - App download < 100MB. Use app bundle / app thinning. Defer large assets to on-demand download.
542
+ - Memory budget: < 150MB on most devices. Monitor with memory profiler. Release cached images on memory warning.
543
+ - List/scroll performance: use `ListView.builder` / `LazyColumn` / `FlatList` with `getItemLayout`.
544
+
545
+ ### D-PERF-120FPS-01
546
+ **Trigger**: Q16 = 120fps premium | **Inject into**: `{{ performance_rules }}`
547
+
548
+ - On top of 60fps rules: frame budget 8ms/frame. Profile on ProMotion (iOS) / 120Hz (Android) devices.
549
+ - App download < 50MB. Aggressive asset compression. AVIF/WebP images. SVG over PNG.
550
+ - Memory budget: < 100MB. Aggressive cache eviction. Lazy widget/component instantiation.
551
+ - Shader precompilation (Flutter). Warm-up complex Compose functions.
552
+
553
+ ### D-A11Y-PLATFORM-01
554
+ **Trigger**: Q17 = Platform defaults | **Inject into**: `{{ a11y_rules }}`
555
+
556
+ - iOS: VoiceOver support for all interactive elements via `.accessibilityLabel()`, `.accessibilityHint()`.
557
+ - Android: TalkBack support via `contentDescription`, `semantics {}` modifier (Compose).
558
+ - Dynamic Type: support up to 2x font scaling without layout breakage.
559
+ - Minimum touch target: 44x44pt (iOS), 48x48dp (Android).
560
+
561
+ ### D-A11Y-WCAG-01
562
+ **Trigger**: Q17 = WCAG 2.1 AA | **Inject into**: `{{ a11y_rules }}`
563
+
564
+ - On top of platform defaults: WCAG 2.1 AA contrast (4.5:1 normal, 3:1 large text).
565
+ - Screen reader audit: every screen navigable end-to-end with VoiceOver/TalkBack.
566
+ - Focus order: logical and predictable. Group related content with accessibility containers.
567
+ - Accessibility testing in CI: `accessibility_scanner` (Flutter), Accessibility Inspector (iOS), Accessibility Scanner (Android).
568
+
569
+ ### D-AI-DEP-STRICT-MOBILE-01
570
+ **Trigger**: Q18 = Forbid | **Inject into**: `{{ ai_dependency_rule }}`
571
+
572
+ - AI must not modify `pubspec.yaml` / `package.json` / `Podfile` / `build.gradle` on its own.
573
+ - If a new dependency is needed, AI must list: package name, version, reason, alternative comparison, platform support matrix, and bundle size impact. Human reviews before adding.
574
+
575
+ ### D-AI-DEP-ANNOUNCE-MOBILE-01
576
+ **Trigger**: Q18 = Allowed with declaration | **Inject into**: `{{ ai_dependency_rule }}`
577
+
578
+ - AI may introduce new dependencies, but must declare: package name, version, reason, and platform compatibility in the PR description.
579
+ - Forbid adding dependencies that support only one platform in a cross-platform project without explicit justification.
580
+
581
+ ### D-AI-BREAK-STRICT-MOBILE-01
582
+ **Trigger**: Q19 = Must list callers | **Inject into**: `{{ ai_breaking_change_rule }}`
583
+
584
+ - Before modifying a shared widget/component/utility/service, AI must list all callers and assess impact on: iOS behavior, Android behavior, navigation flow, state management integrity.
585
+ - Breaking changes must be prefixed with `[BREAKING]` and include a migration guide covering all target platforms.
586
+
587
+ ### D-AI-PLATFORM-STRICT-01
588
+ **Trigger**: Q20 = Must not mix paradigms | **Inject into**: `{{ ai_platform_rule }}`
589
+
590
+ - AI must not write iOS architecture patterns in Android code or vice versa.
591
+ - Flutter code must follow Flutter conventions (widget composition), not Android (Fragment/Activity) or iOS (ViewController) patterns.
592
+ - Cross-platform code must not contain platform-specific workarounds without a `// Platform: <reason>` comment.
593
+ - If a change introduces a pattern that is idiomatic on one platform but foreign on another, AI must flag it explicitly.
594
+
595
+ ---
596
+
597
+ ## Template Placeholder Coverage Self-Check
598
+
599
+ | Placeholder | Fill Source | Source Type |
600
+ |------------|-------------|-------------|
601
+ | `{{ project_name }}` | Phase 0 auto-read | Metadata |
602
+ | `{{ generated_at }}` | Phase 4 | Metadata |
603
+ | `{{ platform }}` | Q1 answer | Direct fill |
604
+ | `{{ min_os_version }}` | Q2 answer | Direct fill |
605
+ | `{{ architecture }}` | Q3 answer | Direct fill |
606
+ | `{{ ui_framework }}` | Q4 answer | Direct fill |
607
+ | `{{ navigation }}` | Q5 answer | Direct fill |
608
+ | `{{ state_management }}` | Q6 answer | Direct fill |
609
+ | `{{ networking }}` | Q7 answer | Direct fill |
610
+ | `{{ persistence }}` | Q8 answer | Direct fill |
611
+ | `{{ push_notifications }}` | Q9 answer | Direct fill |
612
+ | `{{ background_tasks }}` | Q10 answer | Direct fill |
613
+ | `{{ permissions_strategy }}` | Q11 answer | Direct fill |
614
+ | `{{ test_coverage }}` | Q12 answer | Direct fill |
615
+ | `{{ unit_test_framework }}` | Q13 answer (If Q12 not in (A, B) → fill with '*Not required at this stage*') | Direct fill |
616
+ | `{{ e2e_framework }}` | Q14 answer (If Q12 not in (A, C) → fill with '*Not required at this stage*') | Direct fill |
617
+ | `{{ distribution }}` | Q15 answer | Direct fill |
618
+ | `{{ performance_target }}` | Q16 answer | Direct fill |
619
+ | `{{ a11y_target }}` | Q17 answer | Direct fill |
620
+ | `{{ tech_stack_rules }}` | D-FLUTTER/RN/IOS/ANDROID + D-OS-LATEST | Derivation |
621
+ | `{{ arch_rules }}` | D-MVVM/D-CLEAN-MOBILE/D-MVI/D-MVC-MOBILE | Derivation |
622
+ | `{{ ui_rules }}` | D-MATERIAL3/CUPERTINO/ADAPTIVE/RN-CORE/NATIVEWIND/SWIFTUI/UIKIT/COMPOSE/XML-MATERIAL | Derivation |
623
+ | `{{ navigation_rules }}` | D-DEEP-LINK/D-URL-ROUTING/D-STACK-NAV | Derivation |
624
+ | `{{ state_rules }}` | D-RIVERPOD/BLOC/PROVIDER/GETX/ZUSTAND-MOBILE/REDUX-MOBILE/SWIFT-STATE/COMBINE/VIEWMODEL-STATE/MUTABLESTATE | Derivation |
625
+ | `{{ networking_rules }}` | D-DIO/AXIOS-MOBILE/URLSESSION/RETROFIT | Derivation |
626
+ | `{{ persistence_rules }}` | D-DRIFT/HIVE/MMKV/SWIFTDATA/COREDATA/ROOM/DATASTORE | Derivation |
627
+ | `{{ platform_features_rules }}` | D-PUSH/D-BG-TASK/D-PERM | Derivation |
628
+ | `{{ test_rules }}` | D-MOBILE-TEST-01/02/03 | Derivation |
629
+ | `{{ distribution_rules }}` | D-APP-STORE/D-ENTERPRISE-DIST | Derivation |
630
+ | `{{ performance_rules }}` | D-PERF-60FPS/D-PERF-120FPS | Derivation |
631
+ | `{{ a11y_rules }}` | D-A11Y-PLATFORM/D-A11Y-WCAG | Derivation |
632
+ | `{{ ai_dependency_rule }}` | D-AI-DEP-STRICT/ANNOUNCE-MOBILE | Derivation |
633
+ | `{{ ai_breaking_change_rule }}` | D-AI-BREAK-STRICT-MOBILE | Derivation |
634
+ | `{{ ai_platform_rule }}` | D-AI-PLATFORM-STRICT | Derivation |
635
+ | `{{ FIXED_RULES_* }}` | fixed-rules.md (14 chapters) | Fixed injection |
636
+ | `{{ deny_list_summary }}` | Phase 4 auto-extract | Auto-generated |
637
+ | `{{ recommended_libs }}` | Phase 4 platform+tools recommendation | Auto-generated |
638
+
639
+ **Self-check rule**: Before rendering, scan the output file. If any `{{ ... }}` string still remains, trace back to Phase 2/3 to fix.