-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdetekt.yml
More file actions
146 lines (138 loc) · 6.05 KB
/
Copy pathdetekt.yml
File metadata and controls
146 lines (138 loc) · 6.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# ────────────────────────────────────────────────────────────────────────
# VeriSphere Detekt configuration (Story 1.3, AR11)
# ────────────────────────────────────────────────────────────────────────
# This file overlays the Detekt default configuration (loaded because
# `buildUponDefaultConfig = true` in app/build.gradle.kts).
#
# Architecture-mandated rules (architecture.md line 526) — ONLY THESE:
# 1. GlobalScope usage → `coroutines > GlobalCoroutineUsage`
# 2. println / print instead of Log → `style > ForbiddenMethodCall`
# 3. Missing @Serializable on repository-consumed types → CUSTOM RULE
# scoped to Story 1.10 (placeholder below).
#
# Every other Detekt ruleset is DISABLED. Detekt is a focused enforcement
# tool here, not a full-spectrum lint pass — Android Lint already covers
# the broader catalogue. Stories that want stricter Detekt enforcement
# must amend this file with explicit rationale.
build:
maxIssues: 0 # CI hard-fails on any violation (Story 1.3 AC #2).
config:
validation: true
warningsAsErrors: false
# `excludes:` intentionally omitted — Detekt's schema validates
# config.excludes as a string; we have no patterns to exclude from
# validation today. Add as a comma-separated glob string when needed.
# ─── Rulesets explicitly disabled ───────────────────────────────────────
# Default-on rules that fire on Story 1.1's clean code but lie outside
# the architecture's three mandated checks. Re-enable per-rule only with
# explicit story scope and architecture amendment.
comments:
active: false
complexity:
active: false
empty-blocks:
active: false
exceptions:
active: false
naming:
active: false # FunctionNaming flags @Composable PascalCase nouns;
# MatchingDeclarationName flags Color.kt / Spacing.kt
# which group thematic tokens (intentional pattern).
performance:
active: false
potential-bugs:
active: false # UnusedPrivateProperty flags AppContainer's deliberate
# constructor param (Story 1.1 dismissed-review-finding).
# ─── Rulesets selectively active ────────────────────────────────────────
coroutines:
active: true
GlobalCoroutineUsage:
active: true
severity: error
# Architecture pattern: every coroutine launches from a scoped owner
# (Application, Service, viewModelScope). GlobalScope leaks coroutines
# past their natural owner's lifecycle.
#
# Coverage gap (deferred-work): only flags direct `GlobalScope.launch`;
# ad-hoc `CoroutineScope(Dispatchers.IO).launch { }` is NOT caught.
# Story 1.10 decides on a custom rule alongside the @Serializable
# placeholder.
style:
active: true
# Disable everything in the style ruleset by default; cherry-pick the
# one rule the architecture mandates.
MaxLineLength:
active: false
WildcardImport:
active: false
NewLineAtEndOfFile:
active: false
MagicNumber:
active: false
ReturnCount:
active: false
ThrowsCount:
active: false
UnusedPrivateMember:
active: false
UnusedPrivateProperty:
active: false # AppContainer's `applicationContext` is intentional
# (constructor contract for future stories — Story
# 1.1 dismissed-review-finding).
ForbiddenComment:
active: false
UseDataClass:
active: false
LoopWithTooManyJumpStatements:
active: false
SerialVersionUIDInSerializableClass:
active: false
ProtectedMemberInFinalClass:
active: false
EqualsOnSignatureLine:
active: false
FunctionOnlyReturningConstant:
active: false
ExplicitItLambdaParameter:
active: false
UseCheckOrError:
active: false
UnnecessaryAbstractClass:
active: false
UseRequire:
active: false
ForbiddenMethodCall:
active: true
severity: error
excludes:
- '**/test/**'
- '**/androidTest/**'
methods:
- reason: 'Use Logger.tag(name) — D2.7. println bypasses the VS.<Component> tag pattern and survives R8 minification.'
value: 'kotlin.io.println'
- reason: 'Use Logger.tag(name) — D2.7. print bypasses the VS.<Component> tag pattern.'
value: 'kotlin.io.print'
- reason: 'Use Logger.tag(name) — D2.7. System.out.println bypasses the VS.<Component> tag pattern and survives R8 minification.'
value: 'java.io.PrintStream.println'
- reason: 'Use Logger.tag(name) — D2.7. System.out.print bypasses the VS.<Component> tag pattern.'
value: 'java.io.PrintStream.print'
- reason: 'Use Logger.tag(name) — D2.7. System.err.println bypasses the VS.<Component> tag pattern.'
value: 'java.io.PrintStream.println'
# ─── Custom rule placeholder (TODO Story 1.10) ──────────────────────────
#
# The third architecture-mandated rule — "missing @Serializable on classes
# consumed by repositories" — is a CUSTOM rule that does not ship with
# Detekt out-of-the-box. Decision (Story 1.3): defer to Story 1.10.
#
# When Story 1.10 lands HistoryRepository (the first concrete repository
# that consumes a serialised type, SessionRecord), the implementer either:
# (a) ships a custom Detekt rule via dependencies { detektPlugins(...) },
# (b) relies on kotlinx.serialization's compile-time @Serializable check
# (it already fails the build with a clear error at the use site).
#
# Until then, the missing-@Serializable case is caught by:
# - kotlinx.serialization compile-time check (build fails)
# - Code review (PR template line for repository-consumed types)
#
# Do NOT remove this comment block until Story 1.10's implementer makes
# the explicit call.