litclaude-ai 0.2.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.
Files changed (156) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/LICENSE +21 -0
  3. package/README.md +369 -0
  4. package/README_ko-KR.md +374 -0
  5. package/RELEASE_CHECKLIST.md +165 -0
  6. package/bin/litclaude-ai.js +643 -0
  7. package/cover.png +0 -0
  8. package/docs/agents.md +67 -0
  9. package/docs/hooks.md +134 -0
  10. package/docs/lsp.md +40 -0
  11. package/docs/migration.md +209 -0
  12. package/docs/workflow-compatibility-audit.md +119 -0
  13. package/generate_cover.py +123 -0
  14. package/package.json +48 -0
  15. package/plugins/litclaude/.claude-plugin/plugin.json +25 -0
  16. package/plugins/litclaude/.lsp.json +13 -0
  17. package/plugins/litclaude/.mcp.json +9 -0
  18. package/plugins/litclaude/agents/boulder-executor.md +12 -0
  19. package/plugins/litclaude/agents/librarian-researcher.md +15 -0
  20. package/plugins/litclaude/agents/oracle-verifier.md +16 -0
  21. package/plugins/litclaude/agents/prometheus-planner.md +13 -0
  22. package/plugins/litclaude/agents/qa-runner.md +16 -0
  23. package/plugins/litclaude/agents/quality-reviewer.md +17 -0
  24. package/plugins/litclaude/bin/litclaude-hook.js +110 -0
  25. package/plugins/litclaude/bin/litclaude-hud.js +271 -0
  26. package/plugins/litclaude/bin/litclaude-lsp-doctor.js +15 -0
  27. package/plugins/litclaude/bin/litclaude-mcp.js +70 -0
  28. package/plugins/litclaude/commands/deep-interview.md +21 -0
  29. package/plugins/litclaude/commands/dynamic-workflow.md +36 -0
  30. package/plugins/litclaude/commands/lit-loop.md +40 -0
  31. package/plugins/litclaude/commands/lit-plan.md +35 -0
  32. package/plugins/litclaude/commands/litgoal.md +30 -0
  33. package/plugins/litclaude/commands/review-work.md +35 -0
  34. package/plugins/litclaude/commands/start-work.md +36 -0
  35. package/plugins/litclaude/hooks/hooks.json +54 -0
  36. package/plugins/litclaude/lib/context-pressure.mjs +25 -0
  37. package/plugins/litclaude/lib/hud-accent-palette.mjs +58 -0
  38. package/plugins/litclaude/lib/litgoal/cli.mjs +266 -0
  39. package/plugins/litclaude/lib/litgoal/ledger.mjs +16 -0
  40. package/plugins/litclaude/lib/litgoal/paths.mjs +7 -0
  41. package/plugins/litclaude/lib/litgoal/state.mjs +67 -0
  42. package/plugins/litclaude/lib/mutated-file-paths.mjs +63 -0
  43. package/plugins/litclaude/lib/start-work-continuation.mjs +99 -0
  44. package/plugins/litclaude/lib/workflow-check.mjs +83 -0
  45. package/plugins/litclaude/skills/ai-slop-remover/SKILL.md +142 -0
  46. package/plugins/litclaude/skills/comment-checker/SKILL.md +55 -0
  47. package/plugins/litclaude/skills/debugging/SKILL.md +70 -0
  48. package/plugins/litclaude/skills/debugging/references/methodology/00-setup.md +108 -0
  49. package/plugins/litclaude/skills/debugging/references/methodology/02-investigate.md +126 -0
  50. package/plugins/litclaude/skills/debugging/references/methodology/04-oracle-triple.md +106 -0
  51. package/plugins/litclaude/skills/debugging/references/methodology/05-escalate.md +69 -0
  52. package/plugins/litclaude/skills/debugging/references/methodology/06-fix.md +116 -0
  53. package/plugins/litclaude/skills/debugging/references/methodology/08-qa.md +94 -0
  54. package/plugins/litclaude/skills/debugging/references/methodology/09-cleanup.md +164 -0
  55. package/plugins/litclaude/skills/debugging/references/methodology/partial-runtime-evidence.md +228 -0
  56. package/plugins/litclaude/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
  57. package/plugins/litclaude/skills/debugging/references/runtimes/go.md +252 -0
  58. package/plugins/litclaude/skills/debugging/references/runtimes/native-binary.md +484 -0
  59. package/plugins/litclaude/skills/debugging/references/runtimes/node.md +260 -0
  60. package/plugins/litclaude/skills/debugging/references/runtimes/python.md +248 -0
  61. package/plugins/litclaude/skills/debugging/references/runtimes/rust.md +234 -0
  62. package/plugins/litclaude/skills/debugging/references/tools/ghidra.md +212 -0
  63. package/plugins/litclaude/skills/debugging/references/tools/playwright-cli.md +194 -0
  64. package/plugins/litclaude/skills/debugging/references/tools/pwndbg.md +263 -0
  65. package/plugins/litclaude/skills/debugging/references/tools/pwntools.md +265 -0
  66. package/plugins/litclaude/skills/deep-interview/SKILL.md +323 -0
  67. package/plugins/litclaude/skills/deep-interview/scripts/render_progress.py +193 -0
  68. package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +62 -0
  69. package/plugins/litclaude/skills/lit-loop/SKILL.md +144 -0
  70. package/plugins/litclaude/skills/lit-plan/SKILL.md +125 -0
  71. package/plugins/litclaude/skills/litgoal/SKILL.md +219 -0
  72. package/plugins/litclaude/skills/lsp/SKILL.md +63 -0
  73. package/plugins/litclaude/skills/programming/SKILL.md +106 -0
  74. package/plugins/litclaude/skills/programming/references/go/README.md +90 -0
  75. package/plugins/litclaude/skills/programming/references/go/backend-stack.md +641 -0
  76. package/plugins/litclaude/skills/programming/references/go/bootstrap.md +328 -0
  77. package/plugins/litclaude/skills/programming/references/go/bubbletea-v2.md +360 -0
  78. package/plugins/litclaude/skills/programming/references/go/cobra-stack.md +468 -0
  79. package/plugins/litclaude/skills/programming/references/go/concurrency.md +362 -0
  80. package/plugins/litclaude/skills/programming/references/go/data-modeling.md +329 -0
  81. package/plugins/litclaude/skills/programming/references/go/error-handling.md +359 -0
  82. package/plugins/litclaude/skills/programming/references/go/golangci-strict.md +236 -0
  83. package/plugins/litclaude/skills/programming/references/go/grpc-connect.md +375 -0
  84. package/plugins/litclaude/skills/programming/references/go/libraries.md +337 -0
  85. package/plugins/litclaude/skills/programming/references/go/one-liners.md +202 -0
  86. package/plugins/litclaude/skills/programming/references/go/sqlc-pgx.md +471 -0
  87. package/plugins/litclaude/skills/programming/references/go/testing.md +467 -0
  88. package/plugins/litclaude/skills/programming/references/go/type-patterns.md +298 -0
  89. package/plugins/litclaude/skills/programming/references/python/README.md +314 -0
  90. package/plugins/litclaude/skills/programming/references/python/async-anyio.md +442 -0
  91. package/plugins/litclaude/skills/programming/references/python/data-modeling.md +233 -0
  92. package/plugins/litclaude/skills/programming/references/python/data-processing.md +133 -0
  93. package/plugins/litclaude/skills/programming/references/python/error-handling.md +218 -0
  94. package/plugins/litclaude/skills/programming/references/python/fastapi-stack.md +316 -0
  95. package/plugins/litclaude/skills/programming/references/python/httpx2-optimization.md +360 -0
  96. package/plugins/litclaude/skills/programming/references/python/libraries.md +307 -0
  97. package/plugins/litclaude/skills/programming/references/python/one-liners.md +268 -0
  98. package/plugins/litclaude/skills/programming/references/python/orjson-stack.md +378 -0
  99. package/plugins/litclaude/skills/programming/references/python/pydantic-ai.md +285 -0
  100. package/plugins/litclaude/skills/programming/references/python/pyproject-strict.md +232 -0
  101. package/plugins/litclaude/skills/programming/references/python/textual-tui.md +201 -0
  102. package/plugins/litclaude/skills/programming/references/python/type-patterns.md +176 -0
  103. package/plugins/litclaude/skills/programming/references/rust/README.md +317 -0
  104. package/plugins/litclaude/skills/programming/references/rust/async-tokio.md +299 -0
  105. package/plugins/litclaude/skills/programming/references/rust/axum-stack.md +467 -0
  106. package/plugins/litclaude/skills/programming/references/rust/cargo-strict.md +317 -0
  107. package/plugins/litclaude/skills/programming/references/rust/clap-stack.md +409 -0
  108. package/plugins/litclaude/skills/programming/references/rust/concurrency.md +375 -0
  109. package/plugins/litclaude/skills/programming/references/rust/libraries.md +439 -0
  110. package/plugins/litclaude/skills/programming/references/rust/one-liners.md +291 -0
  111. package/plugins/litclaude/skills/programming/references/rust/proptest-insta.md +429 -0
  112. package/plugins/litclaude/skills/programming/references/rust/type-state.md +354 -0
  113. package/plugins/litclaude/skills/programming/references/rust/unsafe-discipline.md +250 -0
  114. package/plugins/litclaude/skills/programming/references/rust/zero-cost-safety.md +527 -0
  115. package/plugins/litclaude/skills/programming/references/rust-ub/README.md +289 -0
  116. package/plugins/litclaude/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
  117. package/plugins/litclaude/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
  118. package/plugins/litclaude/skills/programming/references/typescript/README.md +195 -0
  119. package/plugins/litclaude/skills/programming/references/typescript/backend-hono.md +672 -0
  120. package/plugins/litclaude/skills/programming/references/typescript/bootstrap.md +199 -0
  121. package/plugins/litclaude/skills/programming/references/typescript/data-modeling.md +202 -0
  122. package/plugins/litclaude/skills/programming/references/typescript/error-handling.md +169 -0
  123. package/plugins/litclaude/skills/programming/references/typescript/tsconfig-strict.md +152 -0
  124. package/plugins/litclaude/skills/programming/references/typescript/type-patterns.md +196 -0
  125. package/plugins/litclaude/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
  126. package/plugins/litclaude/skills/programming/scripts/go/new-project.py +138 -0
  127. package/plugins/litclaude/skills/programming/scripts/go/templates/.editorconfig +13 -0
  128. package/plugins/litclaude/skills/programming/scripts/go/templates/.golangci.yml +95 -0
  129. package/plugins/litclaude/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
  130. package/plugins/litclaude/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
  131. package/plugins/litclaude/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
  132. package/plugins/litclaude/skills/programming/scripts/go/templates/ci.yml +37 -0
  133. package/plugins/litclaude/skills/programming/scripts/go/templates/config.go +24 -0
  134. package/plugins/litclaude/skills/programming/scripts/go/templates/gitignore +15 -0
  135. package/plugins/litclaude/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
  136. package/plugins/litclaude/skills/programming/scripts/go/templates/run.go +15 -0
  137. package/plugins/litclaude/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
  138. package/plugins/litclaude/skills/programming/scripts/python/new-project.py +172 -0
  139. package/plugins/litclaude/skills/programming/scripts/python/new-script.py +116 -0
  140. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
  141. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
  142. package/plugins/litclaude/skills/programming/scripts/rust/new-project.py +175 -0
  143. package/plugins/litclaude/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
  144. package/plugins/litclaude/skills/programming/scripts/typescript/new-project.ts +177 -0
  145. package/plugins/litclaude/skills/refactor/SKILL.md +73 -0
  146. package/plugins/litclaude/skills/remove-ai-slops/SKILL.md +52 -0
  147. package/plugins/litclaude/skills/review-work/SKILL.md +331 -0
  148. package/plugins/litclaude/skills/rules/SKILL.md +66 -0
  149. package/plugins/litclaude/skills/start-work/SKILL.md +132 -0
  150. package/scripts/audit-plan-checkboxes.mjs +37 -0
  151. package/scripts/doctor.mjs +41 -0
  152. package/scripts/inspect-agent-tools.mjs +27 -0
  153. package/scripts/postinstall.mjs +50 -0
  154. package/scripts/qa-claude-plugin-smoke.sh +60 -0
  155. package/scripts/qa-portable-install.sh +136 -0
  156. package/scripts/validate-plugin.mjs +72 -0
@@ -0,0 +1,317 @@
1
+ # Cargo Strict Configuration
2
+
3
+ The exact knobs every new Rust project gets. Drop these in unmodified.
4
+
5
+ ## `rust-toolchain.toml`
6
+
7
+ ```toml
8
+ [toolchain]
9
+ channel = "stable"
10
+ components = ["rustfmt", "clippy", "rust-src"]
11
+ profile = "default"
12
+ ```
13
+
14
+ Pin nightly separately when miri runs:
15
+
16
+ ```bash
17
+ rustup install nightly
18
+ rustup component add miri rust-src --toolchain nightly
19
+ ```
20
+
21
+ ## `Cargo.toml` — `[lints]` section
22
+
23
+ ```toml
24
+ [lints.rust]
25
+ unsafe_op_in_unsafe_fn = "deny"
26
+ missing_docs = "warn"
27
+ missing_debug_implementations = "warn"
28
+ unreachable_pub = "warn"
29
+ unused_must_use = "deny"
30
+ elided_lifetimes_in_paths = "warn"
31
+ non_ascii_idents = "deny"
32
+ trivial_numeric_casts = "warn"
33
+ unused_lifetimes = "warn"
34
+ single_use_lifetimes = "warn"
35
+
36
+ [lints.clippy]
37
+ # Groups
38
+ all = { level = "deny", priority = -1 }
39
+ pedantic = { level = "warn", priority = -1 }
40
+ nursery = { level = "warn", priority = -1 }
41
+ cargo = { level = "warn", priority = -1 }
42
+
43
+ # Hard denies - turn warnings into errors for sharp tools
44
+ undocumented_unsafe_blocks = "deny"
45
+ multiple_unsafe_ops_per_block = "deny"
46
+ unwrap_used = "deny"
47
+ expect_used = "deny"
48
+ panic = "deny"
49
+ todo = "deny"
50
+ unimplemented = "deny"
51
+ unreachable = "deny"
52
+ indexing_slicing = "deny"
53
+ mem_forget = "deny"
54
+ arithmetic_side_effects = "warn"
55
+ cast_possible_truncation = "warn"
56
+ cast_possible_wrap = "warn"
57
+ cast_precision_loss = "warn"
58
+ cast_sign_loss = "warn"
59
+ as_underscore = "deny"
60
+ as_ptr_cast_mut = "deny"
61
+ ptr_as_ptr = "warn"
62
+ borrow_as_ptr = "warn"
63
+ fn_to_numeric_cast_any = "deny"
64
+ clone_on_ref_ptr = "warn"
65
+ mutex_atomic = "warn"
66
+ rc_buffer = "warn"
67
+ rc_mutex = "warn"
68
+ exit = "warn"
69
+ allow_attributes_without_reason = "warn"
70
+ dbg_macro = "warn"
71
+ print_stderr = "warn"
72
+ print_stdout = "warn"
73
+ use_debug = "warn"
74
+
75
+ # Stylistic relaxations (project-wide opinions only)
76
+ module_name_repetitions = "allow"
77
+ must_use_candidate = "allow"
78
+ missing_errors_doc = "allow" # we use anyhow::Result with .context() everywhere; doc rule is noisy
79
+
80
+ # Restriction lints - opt-in soundness rails
81
+ unreachable = "deny"
82
+ mod_module_files = "warn" # prefer foo.rs over foo/mod.rs
83
+ empty_drop = "warn"
84
+ empty_structs_with_brackets = "warn"
85
+ empty_enum = "warn"
86
+ exhaustive_enums = "warn" # public enums should consider #[non_exhaustive]
87
+ exhaustive_structs = "warn"
88
+ ```
89
+
90
+ The `priority = -1` trick: group-level levels are weak; specific lints below them win. This lets us deny `unwrap_used` while still allowing `pedantic` group warnings instead of denies.
91
+
92
+ ## `Cargo.toml` — release profile
93
+
94
+ ```toml
95
+ [profile.release]
96
+ opt-level = 3
97
+ lto = "fat"
98
+ codegen-units = 1
99
+ strip = "symbols"
100
+ panic = "abort" # smaller, faster - if you need unwinding (FFI catch), set "unwind"
101
+ debug = "line-tables-only"
102
+
103
+ [profile.dev]
104
+ opt-level = 0
105
+ debug = true
106
+ incremental = true
107
+ codegen-units = 256
108
+ split-debuginfo = "unpacked"
109
+
110
+ # A profile for miri - opt-level 1 keeps simulation bearable while still
111
+ # exercising real codegen patterns. miri ignores most profile keys but reads
112
+ # overflow-checks.
113
+ [profile.miri]
114
+ inherits = "test"
115
+ opt-level = 1
116
+ overflow-checks = true
117
+ ```
118
+
119
+ ## `Cargo.toml` — workspace level
120
+
121
+ ```toml
122
+ [workspace]
123
+ resolver = "3"
124
+
125
+ [workspace.package]
126
+ edition = "2024"
127
+ rust-version = "1.83" # bump only when a needed feature lands
128
+ license = "Apache-2.0 OR MIT"
129
+
130
+ [workspace.lints]
131
+ # Then in each member crate:
132
+ # [lints]
133
+ # workspace = true
134
+ ```
135
+
136
+ ## `rustfmt.toml`
137
+
138
+ ```toml
139
+ edition = "2024"
140
+ max_width = 100
141
+ imports_granularity = "Module"
142
+ group_imports = "StdExternalCrate"
143
+ reorder_imports = true
144
+ reorder_modules = true
145
+ newline_style = "Unix"
146
+ use_field_init_shorthand = true
147
+ use_try_shorthand = true
148
+ unstable_features = false
149
+ ```
150
+
151
+ Most options come from stable rustfmt. `imports_granularity` and `group_imports` are nightly-only but ignored cleanly on stable; CI runs `cargo +nightly fmt --check` for the import grouping.
152
+
153
+ ## `clippy.toml`
154
+
155
+ ```toml
156
+ # Reduce cognitive load thresholds.
157
+ cognitive-complexity-threshold = 25
158
+ type-complexity-threshold = 250
159
+ too-many-arguments-threshold = 6
160
+ too-many-lines-threshold = 100
161
+
162
+ # msrv - keeps clippy from suggesting features past our MSRV
163
+ msrv = "1.83"
164
+
165
+ # Avoid `panic` lint complaining about derived Debug impls calling unreachable_unchecked etc.
166
+ allow-unwrap-in-tests = true
167
+ allow-expect-in-tests = true
168
+ allow-panic-in-tests = true
169
+ allow-dbg-in-tests = true
170
+ allow-print-in-tests = true
171
+
172
+ # Force named arguments above N params
173
+ single-char-binding-names-threshold = 4
174
+ ```
175
+
176
+ ## `deny.toml` (cargo-deny)
177
+
178
+ ```toml
179
+ [advisories]
180
+ db-path = "~/.cargo/advisory-db"
181
+ db-urls = ["https://github.com/rustsec/advisory-db"]
182
+ yanked = "deny"
183
+ ignore = []
184
+
185
+ [licenses]
186
+ allow = [
187
+ "MIT",
188
+ "Apache-2.0",
189
+ "Apache-2.0 WITH LLVM-exception",
190
+ "BSD-2-Clause",
191
+ "BSD-3-Clause",
192
+ "ISC",
193
+ "Unicode-DFS-2016",
194
+ "Unicode-3.0",
195
+ "Zlib",
196
+ "MPL-2.0",
197
+ "CC0-1.0",
198
+ ]
199
+ confidence-threshold = 0.93
200
+ exceptions = []
201
+
202
+ [bans]
203
+ multiple-versions = "warn"
204
+ wildcards = "deny"
205
+ highlight = "all"
206
+ deny = [
207
+ # Pin out unmaintained alternatives
208
+ { name = "async-std", reason = "use tokio" },
209
+ { name = "actix-web", reason = "use axum" },
210
+ { name = "chrono", reason = "use jiff" },
211
+ ]
212
+
213
+ [sources]
214
+ unknown-registry = "deny"
215
+ unknown-git = "warn"
216
+ allow-registry = ["https://github.com/rust-lang/crates.io-index"]
217
+ ```
218
+
219
+ ## CI Workflow (`.github/workflows/ci.yml`)
220
+
221
+ ```yaml
222
+ name: ci
223
+ on:
224
+ push:
225
+ branches: [main]
226
+ pull_request:
227
+
228
+ env:
229
+ CARGO_TERM_COLOR: always
230
+ RUST_BACKTRACE: 1
231
+
232
+ jobs:
233
+ fmt:
234
+ runs-on: ubuntu-latest
235
+ steps:
236
+ - uses: actions/checkout@v4
237
+ - uses: dtolnay/rust-toolchain@nightly
238
+ with:
239
+ components: rustfmt
240
+ - run: cargo +nightly fmt --all -- --check
241
+
242
+ clippy:
243
+ runs-on: ubuntu-latest
244
+ steps:
245
+ - uses: actions/checkout@v4
246
+ - uses: dtolnay/rust-toolchain@stable
247
+ with:
248
+ components: clippy
249
+ - uses: Swatinem/rust-cache@v2
250
+ - run: cargo clippy --all-targets --all-features --workspace -- -D warnings
251
+
252
+ test:
253
+ runs-on: ubuntu-latest
254
+ steps:
255
+ - uses: actions/checkout@v4
256
+ - uses: dtolnay/rust-toolchain@stable
257
+ - uses: Swatinem/rust-cache@v2
258
+ - uses: taiki-e/install-action@nextest
259
+ - run: cargo nextest run --all-targets --all-features --workspace
260
+
261
+ miri:
262
+ runs-on: ubuntu-latest
263
+ steps:
264
+ - uses: actions/checkout@v4
265
+ - uses: dtolnay/rust-toolchain@nightly
266
+ with:
267
+ components: miri, rust-src
268
+ - uses: Swatinem/rust-cache@v2
269
+ - uses: taiki-e/install-action@nextest
270
+ - env:
271
+ MIRIFLAGS: "-Zmiri-strict-provenance -Zmiri-symbolic-alignment-check"
272
+ run: cargo +nightly miri nextest run --all-features --workspace
273
+
274
+ machete:
275
+ runs-on: ubuntu-latest
276
+ steps:
277
+ - uses: actions/checkout@v4
278
+ - uses: dtolnay/rust-toolchain@stable
279
+ - uses: bnjbvr/cargo-machete@main
280
+
281
+ deny:
282
+ runs-on: ubuntu-latest
283
+ steps:
284
+ - uses: actions/checkout@v4
285
+ - uses: EmbarkStudios/cargo-deny-action@v2
286
+ with:
287
+ command: check all
288
+
289
+ audit:
290
+ runs-on: ubuntu-latest
291
+ steps:
292
+ - uses: actions/checkout@v4
293
+ - uses: rustsec/audit-check@v1
294
+ with:
295
+ token: ${{ secrets.GITHUB_TOKEN }}
296
+ ```
297
+
298
+ ## Project bootstrap
299
+
300
+ ```bash
301
+ cargo new --bin my-app --edition 2024
302
+ cd my-app
303
+ cargo install cargo-nextest cargo-machete cargo-deny cargo-edit cargo-watch
304
+ rustup install nightly
305
+ rustup component add miri --toolchain nightly
306
+ # drop the configs above
307
+ git add . && git commit -m "chore: bootstrap strict toolchain"
308
+ ```
309
+
310
+ After every change:
311
+
312
+ ```bash
313
+ cargo fmt --all -- --check && \
314
+ cargo clippy --all-targets --all-features -- -D warnings && \
315
+ cargo nextest run && \
316
+ cargo +nightly miri nextest run # only if unsafe is involved
317
+ ```