Skip to content

Commit 5db6f1c

Browse files
committed
fix: gate runtime with package debug flag
1 parent e054ecb commit 5db6f1c

14 files changed

Lines changed: 361 additions & 51 deletions

File tree

.agents/tritonkit-skills/public/tritonkit-dev-feedback/SKILL.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -238,20 +238,16 @@ SwiftPM:
238238
https://github.com/NeptuneKit/TritonKit.git
239239
```
240240

241-
Add the `TritonKit` product to the iOS app target. Keep every app-side source file that imports or starts TritonKit behind `#if DEBUG`; do not rely only on the library's Release no-op behavior.
241+
Add only the `TritonKit` product to the iOS app target. `TritonKitShared` is an internal shared-contract target pulled in transitively; app integrations should not select or import it directly. Keep every app-side source file that imports or starts TritonKit behind `#if DEBUG`; do not rely only on the package runtime guard.
242242

243-
SwiftPM / Xcode package product dependencies do not have a CocoaPods-style `:configurations => ['Debug']` switch. The supported SwiftPM path is source-level Debug isolation with the dedicated bootstrap file below, plus TritonKit's Release no-op runtime. If the production Release target must not link TritonKit at all, create a separate Debug-only app target or scheme and attach the `TritonKit` product only to that target.
243+
SwiftPM supports configuration-scoped build settings, so TritonKit defines `TRITONKIT_RUNTIME_ENABLED` only for Debug package builds and keeps the embedded runtime no-op in Release. SwiftPM / Xcode package product dependencies still do not have a CocoaPods-style `:configurations => ['Debug']` switch: the package product may remain attached to the target even though the runtime is disabled. If the production Release target must not link TritonKit at all, create a separate Debug-only app target or scheme and attach the `TritonKit` product only to that target.
244244

245-
CocoaPods during development, restricted to Debug configurations:
245+
CocoaPods during development, restricted to Debug configurations. Do not add `TritonKitShared` explicitly; `TritonKit` resolves it transitively.
246246

247247
```ruby
248248
target 'YourApp' do
249249
use_frameworks!
250250

251-
pod 'TritonKitShared',
252-
:git => 'https://github.com/NeptuneKit/TritonKit.git',
253-
:branch => 'main',
254-
:configurations => ['Debug']
255251
pod 'TritonKit',
256252
:git => 'https://github.com/NeptuneKit/TritonKit.git',
257253
:branch => 'main',
@@ -476,7 +472,7 @@ If more than one iOS Simulator app connects to the same `triton serve`, use `tri
476472

477473
- For physical devices or local-network testing, add `NSLocalNetworkUsageDescription` to the app target if iOS prompts for local network access.
478474
- If App Transport Security blocks cleartext local development traffic, use a debug-only ATS exception. Do not ship broad ATS exceptions in production.
479-
- Release builds should compile, but `TritonKit.isRuntimeEnabled` is false and the embedded runtime does not connect, collect hierarchy, upload data, or respond to control messages. App-side integration files should still be explicitly wrapped in `#if DEBUG` so production entry points do not import or start TritonKit.
475+
- Release package builds should compile, but `TritonKit.isRuntimeEnabled` is false because `TRITONKIT_RUNTIME_ENABLED` is not defined; the embedded runtime does not connect, collect hierarchy, upload data, or respond to control messages. App-side integration files should still be explicitly wrapped in `#if DEBUG` so production entry points do not import or start TritonKit.
480476

481477
## Harmony App Integration Guide
482478

.agents/tritonkit-skills/public/tritonkit-real-project-regression/SKILL.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Real-project validation is not the same as demo smoke. Treat the business app as
2727
- If the task needs iOS embedded runtime access, use the iOS package path below.
2828
- If the task needs Harmony embedded runtime access, use the Harmony package/source path below and keep provider semantics opt-in.
2929
- SwiftPM or CocoaPods as requested; CocoaPods examples must use `:configurations => ['Debug']`.
30-
- For SwiftPM, do not claim configuration-scoped package dependencies exist. Use source-level `#if DEBUG` isolation, or create a separate Debug-only app target/scheme if Release must not link TritonKit at all.
30+
- For SwiftPM, distinguish build settings from product dependencies: TritonKit uses the package `TRITONKIT_RUNTIME_ENABLED` Debug compile flag, but SwiftPM still does not provide CocoaPods-style configuration-scoped product dependencies. Keep source-level `#if DEBUG` isolation, or create a separate Debug-only app target/scheme if Release must not link TritonKit at all.
3131
- Put all app-side TritonKit code in a dedicated iOS file such as `TritonKitDebugBootstrap.swift`.
3232
- Wrap the entire file in `#if DEBUG`, including `import TritonKit` and `TritonKit.shared.start(...)`.
3333
- Call the bootstrap only from a `#if DEBUG` branch in AppDelegate, SceneDelegate, or SwiftUI `onAppear`.
@@ -257,20 +257,16 @@ SwiftPM:
257257
https://github.com/NeptuneKit/TritonKit.git
258258
```
259259

260-
Add the `TritonKit` product to the iOS app target. Keep every app-side source file that imports or starts TritonKit behind `#if DEBUG`; do not rely only on the library's Release no-op behavior.
260+
Add only the `TritonKit` product to the iOS app target. `TritonKitShared` is an internal shared-contract target pulled in transitively; app integrations should not select or import it directly. Keep every app-side source file that imports or starts TritonKit behind `#if DEBUG`; do not rely only on the package runtime guard.
261261

262-
SwiftPM / Xcode package product dependencies do not have a CocoaPods-style `:configurations => ['Debug']` switch. The supported SwiftPM path is source-level Debug isolation with the dedicated bootstrap file below, plus TritonKit's Release no-op runtime. If the production Release target must not link TritonKit at all, create a separate Debug-only app target or scheme and attach the `TritonKit` product only to that target.
262+
SwiftPM supports configuration-scoped build settings, so TritonKit defines `TRITONKIT_RUNTIME_ENABLED` only for Debug package builds and keeps the embedded runtime no-op in Release. SwiftPM / Xcode package product dependencies still do not have a CocoaPods-style `:configurations => ['Debug']` switch: the package product may remain attached to the target even though the runtime is disabled. If the production Release target must not link TritonKit at all, create a separate Debug-only app target or scheme and attach the `TritonKit` product only to that target.
263263

264-
CocoaPods during development:
264+
CocoaPods during development. Do not add `TritonKitShared` explicitly; `TritonKit` resolves it transitively:
265265

266266
```ruby
267267
target 'YourApp' do
268268
use_frameworks!
269269

270-
pod 'TritonKitShared',
271-
:git => 'https://github.com/NeptuneKit/TritonKit.git',
272-
:branch => 'main',
273-
:configurations => ['Debug']
274270
pod 'TritonKit',
275271
:git => 'https://github.com/NeptuneKit/TritonKit.git',
276272
:branch => 'main',

Package.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ let package = Package(
1717
.target(
1818
name: "TritonKit",
1919
dependencies: ["TritonKitShared"],
20-
path: "Sources/TritonKit"
20+
path: "Sources/TritonKit",
21+
swiftSettings: [
22+
.define("TRITONKIT_RUNTIME_ENABLED", .when(configuration: .debug))
23+
]
2124
),
2225
.testTarget(
2326
name: "TritonKitSharedTests",
@@ -27,7 +30,10 @@ let package = Package(
2730
.testTarget(
2831
name: "TritonKitTests",
2932
dependencies: ["TritonKit"],
30-
path: "Tests/TritonKitTests"
33+
path: "Tests/TritonKitTests",
34+
swiftSettings: [
35+
.define("TRITONKIT_RUNTIME_ENABLED", .when(configuration: .debug))
36+
]
3137
),
3238
]
3339
)

README.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ In Xcode, add this package URL:
3030
https://github.com/NeptuneKit/TritonKit.git
3131
```
3232

33-
Add the `TritonKit` product to the iOS app target. `TritonKitShared` is pulled in as a package target dependency. Keep every app-side source file that imports or starts TritonKit behind `#if DEBUG`; do not rely only on the library's Release no-op behavior.
33+
Add only the `TritonKit` product to the iOS app target. `TritonKitShared` is an internal shared-contract target pulled in transitively; app integrations should not select or import it directly. Keep every app-side source file that imports or starts TritonKit behind `#if DEBUG`; do not rely only on the package runtime guard.
3434

35-
SwiftPM / Xcode package product dependencies do not have a CocoaPods-style `:configurations => ['Debug']` switch. The supported SwiftPM path is source-level Debug isolation with the dedicated bootstrap file below, plus TritonKit's Release no-op runtime. If your production Release target must not link TritonKit at all, create a separate Debug-only app target or scheme and attach the `TritonKit` product only to that target.
35+
SwiftPM supports configuration-scoped build settings, so TritonKit defines `TRITONKIT_RUNTIME_ENABLED` only for Debug package builds and keeps the embedded runtime no-op in Release. SwiftPM / Xcode package product dependencies still do not have a CocoaPods-style `:configurations => ['Debug']` switch: the package product may remain attached to the target even though the runtime is disabled. If the production Release target must not link TritonKit at all, create a separate Debug-only app target or scheme and attach the `TritonKit` product only to that target.
3636

3737
For command-line package manifests:
3838

@@ -42,16 +42,12 @@ For command-line package manifests:
4242

4343
#### CocoaPods
4444

45-
During development, point CocoaPods at the repository and restrict both pods to Debug configurations:
45+
During development, point CocoaPods at the repository and restrict the TritonKit pod to Debug configurations. Do not add `TritonKitShared` explicitly; the `TritonKit` podspec resolves the matching shared-contract pod transitively.
4646

4747
```ruby
4848
target 'YourApp' do
4949
use_frameworks!
5050

51-
pod 'TritonKitShared',
52-
:git => 'https://github.com/NeptuneKit/TritonKit.git',
53-
:branch => 'main',
54-
:configurations => ['Debug']
5551
pod 'TritonKit',
5652
:git => 'https://github.com/NeptuneKit/TritonKit.git',
5753
:branch => 'main',
@@ -207,7 +203,7 @@ If your app blocks cleartext development traffic through App Transport Security,
207203

208204
### 4. iOS Runtime Boundary
209205

210-
`TritonKit.isRuntimeEnabled` is `true` only in `DEBUG` builds. In Release builds the public API remains compileable, but the embedded runtime does not connect, collect hierarchy, upload data, or respond to control messages. App-side integration files should still be explicitly wrapped in `#if DEBUG` so production entry points do not import or start TritonKit.
206+
`TritonKit.isRuntimeEnabled` is `true` only when the package build defines `TRITONKIT_RUNTIME_ENABLED` (the default Debug package configuration). In Release package builds the public API remains compileable, but the embedded runtime does not connect, collect hierarchy, upload data, or respond to control messages. App-side integration files should still be explicitly wrapped in `#if DEBUG` so production entry points do not import or start TritonKit.
211207

212208
### 5. WebView Observation
213209

Sources/TritonKit/TritonKit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public class TritonKit {
167167
}
168168

169169
public static var isRuntimeEnabled: Bool {
170-
#if DEBUG
170+
#if TRITONKIT_RUNTIME_ENABLED
171171
true
172172
#else
173173
false

Tests/TritonKitTests/TKPlatformFallbackTests.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import Darwin
77

88
@Suite
99
struct TKPlatformFallbackTests {
10-
@Test("runtime is enabled only in DEBUG builds")
10+
@Test("runtime is enabled only when the package debug flag is defined")
1111
func runtimeEnabledFlagMatchesBuildConfiguration() {
12-
#if DEBUG
12+
#if TRITONKIT_RUNTIME_ENABLED
1313
#expect(TritonKit.isRuntimeEnabled)
1414
#else
1515
#expect(!TritonKit.isRuntimeEnabled)
@@ -126,8 +126,12 @@ struct TKPlatformFallbackTests {
126126
config.autoReconnect = false
127127
})
128128

129+
#if TRITONKIT_RUNTIME_ENABLED
129130
#expect(started)
130131
try await Task.sleep(nanoseconds: 500_000_000)
132+
#else
133+
#expect(!started)
134+
#endif
131135
#expect(kit.state == .disconnected)
132136
#expect(observedErrors.isEmpty)
133137
}

docs-linhay/dev/20260519-cocoapods-support.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ TritonKit 需要支持业务 App 通过 CocoaPods 引入 embedded runtime,同
1010

1111
- Given 业务 App 的 Podfile 引入 `pod 'TritonKit'`
1212
- When CocoaPods 解析依赖
13-
- Then `TritonKit` 会依赖同版本 `TritonKitShared`
14-
- And Swift module 边界与 SwiftPM 一致,`import TritonKitShared` 可解析
13+
- Then 业务 Podfile 只需要显式引入 `pod 'TritonKit'`
14+
- And `TritonKit` podspec 会传递依赖同版本 `TritonKitShared`
15+
- And 内部 Swift module 边界与 SwiftPM 一致,CLI / runtime 仍可解析 `import TritonKitShared`
1516
- And 对外示例必须使用 `:configurations => ['Debug']`,避免 Release 配置安装 embedded runtime
1617

1718
### 场景 2:CocoaPods 集成遵守 Debug-only runtime
@@ -34,7 +35,7 @@ TritonKit 需要支持业务 App 通过 CocoaPods 引入 embedded runtime,同
3435
1. `TritonKitShared.podspec` 只包含 `Sources/TritonKitShared/**/*.swift`
3536
2. `TritonKit.podspec` 只包含 `Sources/TritonKit/**/*.swift`,并依赖同版本 `TritonKitShared`
3637
3. CocoaPods 不打包 `Sources/TritonKitCLI`;SwiftPM 根 `Package.swift` 也不声明 CLI executable 与 CLI-only package dependencies,避免把 macOS CLI / Hummingbird / ArgumentParser 依赖带入业务 App。
37-
4. README 与 public skill 中的 Podfile 示例必须给 `TritonKitShared``TritonKit` 同时加 `:configurations => ['Debug']`
38+
4. README 与 public skill 中的用户 Podfile 示例只允许显式添加 `pod 'TritonKit'`,并加 `:configurations => ['Debug']`;不得要求用户手写 `pod 'TritonKitShared'`,该依赖由 `TritonKit.podspec` 传递解析
3839
5. 业务 App 侧推荐将全部 TritonKit 启动代码放入独立 `TritonKitDebugBootstrap.swift`,并用文件级 `#if DEBUG` 包住 `import TritonKit``TritonKit.shared.start()` / `start { config in ... }` 调用。
3940
6. podspec 版本暂与当前 CLI 版本保持一致:`0.1.0`。正式发布 CocoaPods 前,需要先创建对应 `v0.1.0` tag,或在发布时同步调整版本。
4041
7. 当前项目仍处开发阶段,podspec license metadata 使用 `Custom`,正式发布前应补齐稳定 license 文件与发布策略。

docs-linhay/dev/20260519-debug-only-pm-runtime.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@
22

33
## 背景
44

5-
TritonKit 作为 Package Manager 依赖提供给业务 App 时,embedded runtime 不应在 Release 构建中实际连接、采集或响应控制。该约束只跟编译配置有关,不跟 iOS/macOS、UIKit 是否可导入等端类型绑定。同时,业务 App 侧接入文件必须显式使用 `#if DEBUG`不能只依赖库内部 Release no-op。
5+
TritonKit 作为 Package Manager 依赖提供给业务 App 时,embedded runtime 不应在 Release 构建中实际连接、采集或响应控制。该约束由 SwiftPM package target 的 Debug-only compile flag `TRITONKIT_RUNTIME_ENABLED` 表达,不跟 iOS/macOS、UIKit 是否可导入等端类型绑定。同时,业务 App 侧接入文件必须显式使用 `#if DEBUG`不能只依赖包内部 Release no-op。
66

77
## 验收场景
88

99
### 场景 1:Debug 构建启用 embedded runtime
1010

1111
- Given App 通过 Package Manager 引入 TritonKit
12-
- When 使用 `DEBUG` 编译配置构建
13-
- Then `TritonKit.isRuntimeEnabled == true`
12+
- When 使用 Debug 编译配置构建
13+
- Then `TRITONKIT_RUNTIME_ENABLED` 被定义
14+
- And `TritonKit.isRuntimeEnabled == true`
1415
- And `connect`、消息处理、hierarchy 采集和 data upload 按现有逻辑执行
1516

1617
### 场景 2:Release 构建禁用 embedded runtime
1718

1819
- Given App 通过 Package Manager 引入 TritonKit
1920
- When 使用 Release 编译配置构建
2021
- Then package 仍可编译通过
22+
- And `TRITONKIT_RUNTIME_ENABLED` 不被定义
2123
- And `TritonKit.isRuntimeEnabled == false`
2224
- And runtime 不连接、不采集、不上传、不响应控制
2325

@@ -40,13 +42,15 @@ TritonKit 作为 Package Manager 依赖提供给业务 App 时,embedded runtim
4042

4143
- Given README 或 public skill 提供 SwiftPM 接入说明
4244
- When 用户要求 Debug-only 接入
43-
- Then 文档必须说明 SwiftPM / Xcode package product dependency 没有 CocoaPods-style `:configurations => ['Debug']`
44-
- And 默认推荐源码级 `#if DEBUG` bootstrap + Release no-op runtime
45+
- Then 文档必须说明 SwiftPM 支持 configuration-scoped build settings / compile conditions
46+
- And TritonKit package 内部使用 `TRITONKIT_RUNTIME_ENABLED` 在 Debug package build 启用 runtime
47+
- And 文档必须说明 SwiftPM / Xcode package product dependency 没有 CocoaPods-style `:configurations => ['Debug']`
48+
- And 默认推荐 package Debug compile flag + 源码级 `#if DEBUG` bootstrap + Release no-op runtime
4549
- And 若 Release target 必须完全不链接 TritonKit,则推荐独立 Debug-only app target / scheme
4650

4751
## 实现约定
4852

49-
1. `#if DEBUG` 定义 `TritonKit.isRuntimeEnabled`,作为 runtime 是否生效的唯一配置边界
53+
1. `Package.swift``TritonKit` target 通过 `.define("TRITONKIT_RUNTIME_ENABLED", .when(configuration: .debug))` 定义 package 内部 runtime 启用边界;`TritonKit.isRuntimeEnabled` 只读取该宏,不直接绑定裸 `#if DEBUG`
5054
2. Release 下保留 public API,避免业务 App 仅因依赖存在而编译失败。
5155
3. Release 下 runtime 行为采用 no-op 或明确错误:`connect` / `send` / reconnect / ping no-op,hierarchy 返回空数组,data upload 抛出 `TritonKitRuntimeError.disabledOutsideDebug`,request handler 返回 disabled 错误。
5256
4. `canImport(UIKit)` 仍只用于保护 UIKit 符号可编译性,不用于决定 runtime 是否启用。
@@ -56,9 +60,9 @@ TritonKit 作为 Package Manager 依赖提供给业务 App 时,embedded runtim
5660

5761
## 验证
5862

59-
- `swift test` 覆盖 Debug 分支,确认 `TritonKit.isRuntimeEnabled == true`
60-
- `swift test -c release` 覆盖 Release 分支,确认 `TritonKit.isRuntimeEnabled == false`
63+
- `swift test` 覆盖 Debug package 分支,确认 `TRITONKIT_RUNTIME_ENABLED` 生效且 `TritonKit.isRuntimeEnabled == true`
64+
- `swift test -c release` 覆盖 Release package 分支,确认 `TRITONKIT_RUNTIME_ENABLED` 不生效且 `TritonKit.isRuntimeEnabled == false`
6165
- `swift build -c release --target TritonKit` 确认 Package Manager 的 Release library target 可编译。
6266
- `swift build --package-path CLI --scratch-path .build/cli -c release --product triton` 确认 CLI release 产物不受影响。
63-
- `docs-linhay/scripts/verify-ios-debug-isolation.sh` 校验 `Examples/TritonKitDemo` 的 app-side 接入示例采用文件级 `#if DEBUG`,并确认 runtime 内部 Release no-op 防线存在。
67+
- `docs-linhay/scripts/verify-ios-debug-isolation.sh` 校验 `Examples/TritonKitDemo` 的 app-side 接入示例采用文件级 `#if DEBUG`,并确认 package 内部 `TRITONKIT_RUNTIME_ENABLED` Release no-op 防线存在。
6468
- 文档、skill 与 `Examples/TritonKitDemo` 自检确认所有 app-side 接入示例都采用文件级 `#if DEBUG`、CocoaPods Debug-only 配置、推荐显式 opt-in 开关,并明确 SwiftPM 的 Debug-only target / source-level fallback 策略。

0 commit comments

Comments
 (0)