Score: 67.2% (β +0.1 vs prior)
Per-shard breakdown
| Shard |
Score |
Killed |
Survived |
No cov |
Timeout |
Errors |
Total |
| mutation-report-db |
β |
β |
β |
β |
β |
β |
(missing) |
| hardware-lib |
67.5% |
1619 |
591 |
180 |
7 |
969 |
3391 |
| homekit |
62.6% |
290 |
164 |
9 |
0 |
201 |
689 |
| hooks |
73.5% |
886 |
296 |
23 |
1 |
483 |
1707 |
| server |
59.5% |
1421 |
595 |
371 |
2 |
1682 |
5117 |
| services-scheduler |
73.2% |
561 |
186 |
16 |
3 |
251 |
1019 |
| streaming |
73.1% |
890 |
252 |
63 |
13 |
411 |
1638 |
- HTML reports: attached as
mutation-report-<shard> artifacts on run 29145443368.
- Hit list artifact:
mutation-hitlist on the same run.
- Last updated: 2026-07-11T09:31:49.682Z (commit
cf895d7, trigger: schedule).
This issue is updated automatically by .github/workflows/mutation.yml on each scheduled / manual mutation run. Do not edit the body β it will be overwritten. Comment freely to track work on surviving mutants.
Mutation testing β hit list
Score: 67.2% Β· Total mutants: 13561
| Status |
Count |
| Killed |
5667 |
| Survived |
2084 |
| NoCoverage |
662 |
| Timeout |
26 |
| CompileError |
3996 |
| RuntimeError |
1 |
| Ignored |
1125 |
Surviving mutants by file (80 files, top 50 mutants shown)
For each entry below: the mutator type tells you what Stryker changed, the snippet shows where, and "expected test" is the most likely location to add a killing assertion. A killing test must fail when the mutation is applied.
src/streaming/piezoStream.ts β 151 surviving
Expected test file: src/streaming/tests/piezoStream.test.ts
LogicalOperator at line 47
46 |
> 47 | const WS_PORT = Number(process.env.PIEZO_WS_PORT ?? 3001)
48 | const RAW_DATA_DIR = process.env.RAW_DATA_DIR ?? '/persistent'
+ (mutation): process.env.PIEZO_WS_PORT && 3001
StringLiteral at line 48
47 | const WS_PORT = Number(process.env.PIEZO_WS_PORT ?? 3001)
> 48 | const RAW_DATA_DIR = process.env.RAW_DATA_DIR ?? '/persistent'
49 | // Fallback subdirectory probed when RAW_DATA_DIR holds no usable .RAW files.
+ (mutation): ""
ArithmeticOperator at line 57
56 | // index stays bounded on long-running streams (24h at 50fps was ~70MB).
> 57 | const FRAME_INDEX_RETENTION_S = SEEK_MAX_DURATION_S + 10
58 | // Drop outbound frames for a client whose send buffer exceeds this many bytes.
+ (mutation): SEEK_MAX_DURATION_S - 10
ArithmeticOperator at line 60
59 | // Prevents a slow/stalled client from pinning unbounded server memory.
> 60 | const MAX_BUFFERED_BYTES = 1024 * 1024 // 1 MB
61 | // Cap inbound client messages. All clientβserver messages are tiny JSON
+ (mutation): 1024 / 1024
ObjectLiteral at line 317
316 |
> 317 | const cborDecoder = new Decoder({ mapsAsObjects: true, useRecords: false })
318 |
+ (mutation): {}
BooleanLiteral at line 317
316 |
> 317 | const cborDecoder = new Decoder({ mapsAsObjects: true, useRecords: false })
318 |
+ (mutation): false
BooleanLiteral at line 317
316 |
> 317 | const cborDecoder = new Decoder({ mapsAsObjects: true, useRecords: false })
318 |
+ (mutation): true
StringLiteral at line 52
51 | // (and the SEQNO.RAW tmpfs symlink) sits at the /persistent root.
> 52 | const RAW_DATA_FALLBACK_SUBDIR = 'biometrics'
53 | const FILE_POLL_INTERVAL_MS = 10 // match Python's 10 ms poll for new data
+ (mutation): ""
ConditionalExpression at line 127
126 | // slice is correct. Batch the splice to avoid O(n) shift per push.
> 127 | if (frameIndex.length > 0 && frameIndex[0].ts < cutoff) {
128 | let drop = 0
+ (mutation): true
LogicalOperator at line 127
126 | // slice is correct. Batch the splice to avoid O(n) shift per push.
> 127 | if (frameIndex.length > 0 && frameIndex[0].ts < cutoff) {
128 | let drop = 0
+ (mutation): frameIndex.length > 0 || frameIndex[0].ts < cutoff
ConditionalExpression at line 127
126 | // slice is correct. Batch the splice to avoid O(n) shift per push.
> 127 | if (frameIndex.length > 0 && frameIndex[0].ts < cutoff) {
128 | let drop = 0
+ (mutation): true
EqualityOperator at line 127
126 | // slice is correct. Batch the splice to avoid O(n) shift per push.
> 127 | if (frameIndex.length > 0 && frameIndex[0].ts < cutoff) {
128 | let drop = 0
+ (mutation): frameIndex.length >= 0
ConditionalExpression at line 127
126 | // slice is correct. Batch the splice to avoid O(n) shift per push.
> 127 | if (frameIndex.length > 0 && frameIndex[0].ts < cutoff) {
128 | let drop = 0
+ (mutation): true
EqualityOperator at line 127
126 | // slice is correct. Batch the splice to avoid O(n) shift per push.
> 127 | if (frameIndex.length > 0 && frameIndex[0].ts < cutoff) {
128 | let drop = 0
+ (mutation): frameIndex[0].ts <= cutoff
ConditionalExpression at line 129
128 | let drop = 0
> 129 | while (drop < frameIndex.length && frameIndex[drop].ts < cutoff) drop += 1
130 | if (drop > 0) frameIndex.splice(0, drop)
+ (mutation): true
EqualityOperator at line 129
128 | let drop = 0
> 129 | while (drop < frameIndex.length && frameIndex[drop].ts < cutoff) drop += 1
130 | if (drop > 0) frameIndex.splice(0, drop)
+ (mutation): drop <= frameIndex.length
EqualityOperator at line 129
128 | let drop = 0
> 129 | while (drop < frameIndex.length && frameIndex[drop].ts < cutoff) drop += 1
130 | if (drop > 0) frameIndex.splice(0, drop)
+ (mutation): frameIndex[drop].ts <= cutoff
ConditionalExpression at line 130
129 | while (drop < frameIndex.length && frameIndex[drop].ts < cutoff) drop += 1
> 130 | if (drop > 0) frameIndex.splice(0, drop)
131 | }
+ (mutation): true
EqualityOperator at line 130
129 | while (drop < frameIndex.length && frameIndex[drop].ts < cutoff) drop += 1
> 130 | if (drop > 0) frameIndex.splice(0, drop)
131 | }
+ (mutation): drop >= 0
StringLiteral at line 154
153 | function need(n: number): void {
> 154 | if (pos + n > end) throw new RangeError('Incomplete record')
155 | }
+ (mutation): ""
ConditionalExpression at line 159
158 | need(1)
> 159 | if (buf[pos] !== 0xa2) {
160 | throw new Error(`Expected outer map 0xa2, got 0x${buf[pos].toString(16)}`)
+ (mutation): false
BlockStatement at line 159
158 | need(1)
> 159 | if (buf[pos] !== 0xa2) {
160 | throw new Error(`Expected outer map 0xa2, got 0x${buf[pos].toString(16)}`)
161 | }
162 | pos += 1
+ (mutation): {}
StringLiteral at line 160
159 | if (buf[pos] !== 0xa2) {
> 160 | throw new Error(`Expected outer map 0xa2, got 0x${buf[pos].toString(16)}`)
161 | }
+ (mutation): ``
ConditionalExpression at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
170 | || buf[pos + 3] !== 0x71
171 | ) {
+ (mutation): false
LogicalOperator at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
170 | || buf[pos + 3] !== 0x71
171 | ) {
+ (mutation): (buf[pos] !== 0x63 || buf[pos + 1] !== 0x73 || buf[pos + 2] !== 0x65) && buf[pos + 3] !== 0x71
ConditionalExpression at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
170 | || buf[pos + 3] !== 0x71
+ (mutation): false
LogicalOperator at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
170 | || buf[pos + 3] !== 0x71
+ (mutation): (buf[pos] !== 0x63 || buf[pos + 1] !== 0x73) && buf[pos + 2] !== 0x65
ConditionalExpression at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
+ (mutation): false
LogicalOperator at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
+ (mutation): buf[pos] !== 0x63 && buf[pos + 1] !== 0x73
ConditionalExpression at line 167
166 | if (
> 167 | buf[pos] !== 0x63
168 | || buf[pos + 1] !== 0x73
+ (mutation): false
ConditionalExpression at line 168
167 | buf[pos] !== 0x63
> 168 | || buf[pos + 1] !== 0x73
169 | || buf[pos + 2] !== 0x65
+ (mutation): false
ConditionalExpression at line 169
168 | || buf[pos + 1] !== 0x73
> 169 | || buf[pos + 2] !== 0x65
170 | || buf[pos + 3] !== 0x71
+ (mutation): false
ConditionalExpression at line 170
169 | || buf[pos + 2] !== 0x65
> 170 | || buf[pos + 3] !== 0x71
171 | ) {
+ (mutation): false
ConditionalExpression at line 182
181 | const seqMt = seqHdr >> 5
> 182 | if (seqMt !== 0) {
183 | throw new Error(`seq must be unsigned int, got major type ${seqMt}`)
+ (mutation): false
ConditionalExpression at line 188
187 | }
> 188 | else if (seqAi === 24) {
189 | need(1)
+ (mutation): true
ConditionalExpression at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
215 | || buf[pos + 4] !== 0x61
216 | ) {
+ (mutation): false
LogicalOperator at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
215 | || buf[pos + 4] !== 0x61
216 | ) {
+ (mutation): (buf[pos] !== 0x64 || buf[pos + 1] !== 0x64 || buf[pos + 2] !== 0x61 || buf[pos + 3] !== 0x74) && buf[pos + 4] !== 0x61
ConditionalExpression at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
215 | || buf[pos + 4] !== 0x61
+ (mutation): false
LogicalOperator at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
215 | || buf[pos + 4] !== 0x61
+ (mutation): (buf[pos] !== 0x64 || buf[pos + 1] !== 0x64 || buf[pos + 2] !== 0x61) && buf[pos + 3] !== 0x74
ConditionalExpression at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
+ (mutation): false
LogicalOperator at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
+ (mutation): (buf[pos] !== 0x64 || buf[pos + 1] !== 0x64) && buf[pos + 2] !== 0x61
ConditionalExpression at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
+ (mutation): false
LogicalOperator at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
+ (mutation): buf[pos] !== 0x64 && buf[pos + 1] !== 0x64
ConditionalExpression at line 211
210 | if (
> 211 | buf[pos] !== 0x64
212 | || buf[pos + 1] !== 0x64
+ (mutation): false
ConditionalExpression at line 212
211 | buf[pos] !== 0x64
> 212 | || buf[pos + 1] !== 0x64
213 | || buf[pos + 2] !== 0x61
+ (mutation): false
ConditionalExpression at line 213
212 | || buf[pos + 1] !== 0x64
> 213 | || buf[pos + 2] !== 0x61
214 | || buf[pos + 3] !== 0x74
+ (mutation): false
ConditionalExpression at line 214
213 | || buf[pos + 2] !== 0x61
> 214 | || buf[pos + 3] !== 0x74
215 | || buf[pos + 4] !== 0x61
+ (mutation): false
ConditionalExpression at line 215
214 | || buf[pos + 3] !== 0x74
> 215 | || buf[pos + 4] !== 0x61
216 | ) {
+ (mutation): false
ConditionalExpression at line 227
226 | let length: number
> 227 | if (ai <= 23) {
228 | length = ai
+ (mutation): false
EqualityOperator at line 227
226 | let length: number
> 227 | if (ai <= 23) {
228 | length = ai
+ (mutation): ai < 23
β¦and 2034 more surviving mutants not shown. See the HTML report for the full list.
Score: 67.2% (β +0.1 vs prior)
Per-shard breakdown
mutation-report-<shard>artifacts on run 29145443368.mutation-hitliston the same run.cf895d7, trigger:schedule).Mutation testing β hit list
Score: 67.2% Β· Total mutants: 13561
Surviving mutants by file (80 files, top 50 mutants shown)
For each entry below: the mutator type tells you what Stryker changed, the snippet shows where, and "expected test" is the most likely location to add a killing assertion. A killing test must fail when the mutation is applied.
src/streaming/piezoStream.tsβ 151 survivingExpected test file:
src/streaming/tests/piezoStream.test.tsLogicalOperatorat line 47StringLiteralat line 48ArithmeticOperatorat line 57ArithmeticOperatorat line 60ObjectLiteralat line 317BooleanLiteralat line 317BooleanLiteralat line 317StringLiteralat line 52ConditionalExpressionat line 127LogicalOperatorat line 127ConditionalExpressionat line 127EqualityOperatorat line 127ConditionalExpressionat line 127EqualityOperatorat line 127ConditionalExpressionat line 129EqualityOperatorat line 129EqualityOperatorat line 129ConditionalExpressionat line 130EqualityOperatorat line 130StringLiteralat line 154153 | function need(n: number): void { > 154 | if (pos + n > end) throw new RangeError('Incomplete record') 155 | } + (mutation): ""ConditionalExpressionat line 159BlockStatementat line 159StringLiteralat line 160159 | if (buf[pos] !== 0xa2) { > 160 | throw new Error(`Expected outer map 0xa2, got 0x${buf[pos].toString(16)}`) 161 | } + (mutation): ``ConditionalExpressionat line 167LogicalOperatorat line 167ConditionalExpressionat line 167LogicalOperatorat line 167ConditionalExpressionat line 167LogicalOperatorat line 167ConditionalExpressionat line 167ConditionalExpressionat line 168ConditionalExpressionat line 169ConditionalExpressionat line 170ConditionalExpressionat line 182ConditionalExpressionat line 188ConditionalExpressionat line 211LogicalOperatorat line 211ConditionalExpressionat line 211LogicalOperatorat line 211ConditionalExpressionat line 211LogicalOperatorat line 211ConditionalExpressionat line 211LogicalOperatorat line 211ConditionalExpressionat line 211ConditionalExpressionat line 212ConditionalExpressionat line 213ConditionalExpressionat line 214ConditionalExpressionat line 215ConditionalExpressionat line 227EqualityOperatorat line 227β¦and 2034 more surviving mutants not shown. See the HTML report for the full list.