Skip to content

Commit 50dee29

Browse files
committed
F4-F7: operator quality, survivor actionability, Apple support matrix, release-gate hardening
Summary of what changed since the last publish (private/main e497c7f .. c7eba5d): - F4: core operator quality (expanded default/experimental operator coverage, schemata lowerers for the newer operators, compile-viability fixes). - F5 + F5.1: survivor actionability reporting -- clustering, coverage-aware reason codes (mutationSiteNotCovered / coveredButNotCaught), a code-review-driven hardening pass (deterministic tiebreaking, per-cluster evidence, corrected coverage semantics). - F6: Apple platform support matrix, documented honestly including what remains real-simulator-unverified (tvOS/watchOS/visionOS). - F7: feature freeze and full release gate -- T2 (unit/regression) and a real-simulator acceptance suite, both green; a release-artifact gate verifying the actual packaged tarball end-to-end; a paired before/after benchmark harness. Two real product bugs found and fixed along the way: WorkspaceManager.cloneProducts breaking on a symlinked products directory (SwiftPM's own .build/debug), and HostResourcePreflight hanging past its own timeout under concurrent process load (now routed through ProcessSupervisor like every other production process spawn). - Public package hygiene: trimmed research/probe-only executable targets out of the public projection via the overlay mechanism. - A behavior-preserving decomposition of MutationRunner into MutationConfirmationCoordinator and MutationEvidenceAssembler. - A new `mutantkit trust` command and a small Trust Corpus of regression fixtures pinning correctness properties (cross-file cache invalidation, schemata neutral-path equivalence) that were previously undertested. - A standalone (not yet wired into execution) mutant-conflict-graph component researched as a future safe-batching mechanism, with an adversarially-reviewed design document naming its own real, unresolved correctness risks rather than glossing over them. - CodeQL: scan all four languages GitHub's own code-scanning detection finds for this repo (actions, c-cpp, python, swift), not just swift -- the previous single-language config is what surfaced as a code-scanning configuration error.
1 parent 5a6fc1a commit 50dee29

134 files changed

Lines changed: 14867 additions & 5210 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/action-smoke-test.yml

Lines changed: 22 additions & 1033 deletions
Large diffs are not rendered by default.

.github/workflows/ci.yml

Lines changed: 168 additions & 705 deletions
Large diffs are not rendered by default.

.github/workflows/codeql.yml

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,28 @@ name: CodeQL
66
# every PR like ci.yml, plus a weekly schedule so newly-disclosed query-pack
77
# findings surface even on a week with no code changes.
88
#
9+
# Four languages, not one: GitHub's own code-scanning default-setup
10+
# auto-detection (repos/.../code-scanning/default-setup) reports this repo
11+
# as containing actions, c-cpp, python, and swift — scanning only swift, as
12+
# an earlier version of this workflow did, left the other three undetected,
13+
# which is what a "code scanning configuration error" surfaces as (the
14+
# advanced setup this workflow represents not covering everything GitHub's
15+
# own detection found). c-cpp is Sources/MutantKitSchemataRuntimeC (a real,
16+
# plain-C target the SwiftPM package builds); python is Scripts/
17+
# compare-wave-reports.py; actions is this directory's own workflow YAML.
18+
#
919
# `build-mode: manual` rather than `autobuild`: this is a multi-target
1020
# SwiftPM package with a plain-C target (MutantKitSchemataRuntimeC) wrapped
1121
# in a product with an explicit `type: .static`, not a single generic
1222
# executable — exactly the shape autobuild's build-system heuristics are
1323
# least reliable on. A manual `swift build` step (the same invocation
1424
# ci.yml's `unit` job already trusts to build the whole package, including
1525
# the C target) is both simpler to reason about and guaranteed to match how
16-
# this package actually builds.
26+
# this package actually builds. `build-mode` only governs the two compiled
27+
# languages (swift, c-cpp) — one `swift build` invocation traces both, since
28+
# the C target compiles as part of the same package build. python and
29+
# actions are interpreted/config languages CodeQL scans directly with no
30+
# build step, unaffected by build-mode.
1731
#
1832
# macos-15, matching ci.yml/release.yml: this needs the real Xcode/Swift
1933
# toolchain, not a Linux runner — CodeQL's Swift extractor only runs on
@@ -39,42 +53,22 @@ concurrency:
3953

4054
jobs:
4155
analyze:
42-
name: Analyze (swift)
56+
name: Analyze
4357
runs-on: macos-15
4458
steps:
4559
- uses: actions/checkout@v4
4660

47-
# Same rationale as ci.yml's identical step: SwiftPM independently
48-
# re-clones swift-argument-parser/swift-syntax/Yams and re-runs version
49-
# resolution on every run today, with zero caching -- this is the same
50-
# cost class, not a CodeQL-specific restriction (CodeQL's own build
51-
# tracing has no documented issue with pre-populated dependency
52-
# checkouts; it only observes the compiler invocations `swift build`
53-
# below actually makes).
54-
- name: Cache SwiftPM dependencies
55-
uses: actions/cache@v4
56-
with:
57-
path: |
58-
.build/checkouts
59-
.build/repositories
60-
~/Library/Caches/org.swift.swiftpm
61-
key: ${{ runner.os }}-spm-${{ hashFiles('Package.resolved') }}
62-
restore-keys: |
63-
${{ runner.os }}-spm-
64-
6561
- name: Toolchain
6662
run: swift --version && xcodebuild -version
6763

6864
- name: Initialize CodeQL
6965
uses: github/codeql-action/init@v4
7066
with:
71-
languages: swift
67+
languages: actions, c-cpp, python, swift
7268
build-mode: manual
7369

7470
- name: Build
7571
run: swift build
7672

7773
- name: Perform CodeQL analysis
7874
uses: github/codeql-action/analyze@v4
79-
with:
80-
category: "/language:swift"

.swiftlint-baseline.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// swift-tools-version:6.0
2+
import PackageDescription
3+
4+
// Schemata supported-matrix fixture: SwiftPM macOS with ONE test target
5+
// containing both an XCTestCase class and a Swift Testing @Suite —
6+
// deliberately mixed, not two separate test targets, since the question
7+
// this fixture answers is whether schemata mode's own test-result parsing
8+
// (a single .xctest bundle report) handles both frameworks' results
9+
// correctly when they coexist in the same bundle. See
10+
// Fixtures/SchemataMatrixXCTest/Package.swift's own comment for why this
11+
// fixture is fully covered rather than deliberately partial.
12+
let package = Package(
13+
name: "MatrixWidget",
14+
platforms: [.macOS(.v14)],
15+
targets: [
16+
.target(name: "MatrixWidget"),
17+
.testTarget(name: "MatrixWidgetTests", dependencies: ["MatrixWidget"])
18+
]
19+
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/// One candidate per default-enabled, schemata-eligible operator — see
2+
/// this fixture's own Package.swift comment. Every function here is
3+
/// exercised by a dedicated test that kills every mutant a schemata run
4+
/// could produce from it.
5+
public enum MatrixWidget {
6+
/// bool-literal-inversion candidate.
7+
public static func isFeatureEnabled() -> Bool {
8+
true
9+
}
10+
11+
/// relational-operator-replacement candidate.
12+
public static func isAdult(age: Int) -> Bool {
13+
age >= 18
14+
}
15+
16+
/// logical-connector-replacement candidate.
17+
public static func bothRequired(a: Bool, b: Bool) -> Bool {
18+
a && b
19+
}
20+
21+
/// unary-not-removal candidate.
22+
public static func isInvalid(flag: Bool) -> Bool {
23+
!flag
24+
}
25+
26+
/// return-value-replacement candidate.
27+
public static func greeting() -> String {
28+
"hello"
29+
}
30+
31+
/// ternary-branch-swap candidate.
32+
public static func label(flag: Bool) -> String {
33+
flag ? "yes" : "no"
34+
}
35+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Testing
2+
import MatrixWidget
3+
4+
/// Other half of the coverage — see MatrixWidgetXCTestTests.swift's own
5+
/// doc comment.
6+
@Suite("MatrixWidget (Swift Testing half)")
7+
struct MatrixWidgetSwiftTestingTests {
8+
@Test
9+
func isInvalid() {
10+
#expect(MatrixWidget.isInvalid(flag: false))
11+
#expect(!MatrixWidget.isInvalid(flag: true))
12+
}
13+
14+
@Test
15+
func greeting() {
16+
#expect(MatrixWidget.greeting() == "hello")
17+
}
18+
19+
@Test
20+
func label() {
21+
#expect(MatrixWidget.label(flag: true) == "yes")
22+
#expect(MatrixWidget.label(flag: false) == "no")
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import XCTest
2+
import MatrixWidget
3+
4+
/// Half the coverage lives here (XCTest), half in
5+
/// MatrixWidgetSwiftTestingTests.swift (Swift Testing) — same test bundle,
6+
/// both frameworks, deliberately.
7+
final class MatrixWidgetXCTestTests: XCTestCase {
8+
func testIsFeatureEnabled() {
9+
XCTAssertTrue(MatrixWidget.isFeatureEnabled())
10+
}
11+
12+
func testIsAdultBoundary() {
13+
XCTAssertFalse(MatrixWidget.isAdult(age: 17))
14+
XCTAssertTrue(MatrixWidget.isAdult(age: 18))
15+
XCTAssertTrue(MatrixWidget.isAdult(age: 19))
16+
}
17+
18+
func testBothRequired() {
19+
XCTAssertTrue(MatrixWidget.bothRequired(a: true, b: true))
20+
XCTAssertFalse(MatrixWidget.bothRequired(a: true, b: false))
21+
XCTAssertFalse(MatrixWidget.bothRequired(a: false, b: true))
22+
XCTAssertFalse(MatrixWidget.bothRequired(a: false, b: false))
23+
}
24+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// swift-tools-version:6.0
2+
import PackageDescription
3+
4+
// Schemata supported-matrix fixture: SwiftPM macOS + Swift Testing. See
5+
// Fixtures/SchemataMatrixXCTest/Package.swift's own comment for why this
6+
// fixture is fully covered (zero uncovered candidates) rather than
7+
// deliberately partial like Fixtures/SchemataSwiftPackageMacOS.
8+
let package = Package(
9+
name: "MatrixWidget",
10+
platforms: [.macOS(.v14)],
11+
targets: [
12+
.target(name: "MatrixWidget"),
13+
.testTarget(name: "MatrixWidgetTests", dependencies: ["MatrixWidget"])
14+
]
15+
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/// One candidate per default-enabled, schemata-eligible operator — see
2+
/// this fixture's own Package.swift comment. Every function here is
3+
/// exercised by a dedicated test that kills every mutant a schemata run
4+
/// could produce from it.
5+
public enum MatrixWidget {
6+
/// bool-literal-inversion candidate.
7+
public static func isFeatureEnabled() -> Bool {
8+
true
9+
}
10+
11+
/// relational-operator-replacement candidate.
12+
public static func isAdult(age: Int) -> Bool {
13+
age >= 18
14+
}
15+
16+
/// logical-connector-replacement candidate.
17+
public static func bothRequired(a: Bool, b: Bool) -> Bool {
18+
a && b
19+
}
20+
21+
/// unary-not-removal candidate.
22+
public static func isInvalid(flag: Bool) -> Bool {
23+
!flag
24+
}
25+
26+
/// return-value-replacement candidate.
27+
public static func greeting() -> String {
28+
"hello"
29+
}
30+
31+
/// ternary-branch-swap candidate.
32+
public static func label(flag: Bool) -> String {
33+
flag ? "yes" : "no"
34+
}
35+
}

0 commit comments

Comments
 (0)