Fix custom inspector action context and NSView sender; reproduce disabled controls and pass 1046 regressions

这个提交包含在:
dayu 于 2026-10-21 23:21:29 +08:00 提交
1 父节点 3bb33818ea
当前提交 53ce88dd15
15 个文件已更改
+149 -39

没有与搜索条件相匹配的文件

+1 -1
查看文件
@@ -1,6 +1,6 @@
# 大鱼人像美化 FCP 效果模板
版本:1.1.0。滤镜 UUID:`FB14B0E6-59B2-4836-916F-CD0C559E9241`。需配套同版大鱼人像美化 FxPlug APP。
版本:1.1.1。滤镜 UUID:`FB14B0E6-59B2-4836-916F-CD0C559E9241`。需配套同版大鱼人像美化 FxPlug APP。
## 三卡片与自动跟随
+12 -22
查看文件
@@ -1,6 +1,6 @@
{
"version": "1.1.0",
"sha256": "e1c0cff1dd3541ed97cab2cb39a76ad4f28dc659b3be7991cc7ac92dd8ea090b",
"version": "1.1.1",
"sha256": "7090c1fbe0d8310c0b092f7c56f72e9c3fe6503aa38753f3fd8d7adcbd9a27b3",
"filterUUID": "FB14B0E6-59B2-4836-916F-CD0C559E9241",
"publishedFunctionalControls": 1,
"informationalControls": 2,
@@ -58,10 +58,10 @@
"legacyValuesPreserved": true,
"publishOSC": 0,
"currentHostValidation": {
"version": "1.1.0",
"Motion": "pending user",
"FCP": "pending user",
"scope": "No Motion/FCP launch, quit, activation, UI operation or native save was performed. XML structure and standalone archive checks do not establish custom inspector loading."
"version": "1.1.1",
"Motion": "pending native retest",
"FCP": "1.1.0 reproduced: all parameter controls disabled and status waiting for host connection; 1.1.1 retest pending",
"scope": "User authorized Motion/FCP interaction for this regression investigation."
},
"customParameter": {
"id": 210,
@@ -156,14 +156,14 @@
},
"automatedInspectorValidation": {
"scope": "offscreen AppKit inspector, real production controller and mocked host callbacks; no Motion/FCP UI",
"fullChecks": 1039,
"fullChecks": 1046,
"counts": {
"beauty": 49,
"face": 116,
"thinChin": 394,
"hostAdapterASan": 248,
"oscASan": 98,
"inspectorASan": 134
"inspectorASan": 141
},
"nativeVisualQA": "pending user",
"manualAnalysisUI": "removed; legacy IDs hidden and buttons disabled",
@@ -188,19 +188,9 @@
"archives": "Own PGInspectorState secure payload; Foundation outer and inner decode and Motion alphabet roundtrip tested"
},
"installation": {
"version": "1.1.0",
"build": "9",
"status": "installed",
"appPath": "/Library/Plug-Ins/FxPlug/beatygril.app",
"templateAndSourceResourceByteVerified": true,
"signatureVerified": true,
"notarization": "Accepted",
"stapleValidated": true,
"gatekeeperAccepted": true,
"formalPluginKitPathVerified": true,
"UIOperated": false,
"hostTerminationPerformed": false,
"nativeLoadAndVisualQA": "pending user",
"receipt": "../../docs/verification/v1.1.0/installed-verification.json"
"version": "1.1.1",
"build": "10",
"status": "pending",
"previousInstalledVersion": "1.1.0"
}
}
@@ -46,7 +46,7 @@
<flags>1</flags>
</template>
<build />
<description>大鱼人像美化 1.1.0:磨皮、美白、瘦脸三卡片自定义面板,自动选择主体并实时跟随。模板局部磨皮默认为50%。</description>
<description>大鱼人像美化 1.1.1:磨皮、美白、瘦脸三卡片自定义面板,自动选择主体并实时跟随。模板局部磨皮默认为50%。</description>
<scene>
<sceneSettings>
<width>1920</width>
@@ -253,7 +253,7 @@
<parameter name="Width" id="313" flags="8589934610" default="1" value="1920" />
<parameter name="Height" id="314" flags="8589934610" default="1" value="1080" />
</parameter>
<filter name="大鱼人像美化" id="510000005" factoryID="6" pluginUUID="FB14B0E6-59B2-4836-916F-CD0C559E9241" pluginVersion="1.1.0" pluginName="大鱼人像美化" pluginDynamicParams="0">
<filter name="大鱼人像美化" id="510000005" factoryID="6" pluginUUID="FB14B0E6-59B2-4836-916F-CD0C559E9241" pluginVersion="1.1.1" pluginName="大鱼人像美化" pluginDynamicParams="0">
<timing in="0 1 1 0" out="299 30 1 0" offset="0 1 1 0" />
<baseFlags>8589934608</baseFlags>
<parameter name="" id="210" flags="12901679104">
+4 -4
查看文件
@@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.1.1</string>
<key>CFBundleVersion</key>
<string>9</string>
<string>10</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>PlugInKit</key>
@@ -72,7 +72,7 @@
<key>uuid</key>
<string>FB14B0E6-59B2-4836-916F-CD0C559E9241</string>
<key>version</key>
<string>1.1.0</string>
<string>1.1.1</string>
</dict>
<dict>
<key>className</key>
@@ -84,7 +84,7 @@
<key>uuid</key>
<string>E0E432C8-3D71-4ABA-B006-E7F519E06C87</string>
<key>version</key>
<string>1.1.0</string>
<string>1.1.1</string>
<key>protocolNames</key>
<array>
<string>FxOnScreenControl</string>
@@ -30,6 +30,8 @@ FOUNDATION_EXPORT PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings
@property (nonatomic, strong, readonly) PGInspectorState *state;
@property (nonatomic, readonly) BOOL available;
@property (nonatomic, copy, readonly) NSString *statusMessage;
/// The actual custom inspector view identifies the action to the native host.
@property (nonatomic, weak, nullable) NSView *actionSender;
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager;
- (void)refresh;
- (void)documentDidChange;
+30 -5
查看文件
@@ -1,6 +1,7 @@
#import "PGInspectorState.h"
#import <math.h>
#import <stddef.h>
#import <os/log.h>
NSArray<NSDictionary *> *PGInspectorControls(void) {
static NSArray *controls; static dispatch_once_t once;
@@ -129,6 +130,9 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
@property (nonatomic) BOOL interacting;
@property (nonatomic) NSTimeInterval pendingUntil;
@property (nonatomic) CMTime pendingTime;
@property (nonatomic, strong) id activeSender;
@property (nonatomic) BOOL reportedConnection;
@property (nonatomic) BOOL reportedMissingAction;
@end
@implementation PGInspectorController
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager {
@@ -138,13 +142,34 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
- (BOOL)start {
if(_interacting)return YES;
_action=[_manager apiForProtocol:@protocol(FxCustomParameterActionAPI_v4)];
if(!_action){
_available=NO;_statusMessage=@"等待宿主连接";
if(!_reportedMissingAction){os_log(OS_LOG_DEFAULT,"PGInspector action API unavailable manager=%{public}d viewSender=%{public}d onMain=%{public}d",_manager!=nil,_actionSender!=nil,NSThread.isMainThread);_reportedMissingAction=YES;}
return NO;
}
// A native host can expose parameter APIs only after the custom view's
// action has established its document context. Never gate startAction on
// those APIs being available before entering the action.
BOOL readBefore=NO,writeBefore=NO;
if(!_reportedConnection){
readBefore=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)]!=nil;
writeBefore=[_manager apiForProtocol:@protocol(FxParameterSettingAPI_v5)]!=nil;
}
_activeSender=_actionSender ?: self;
[_action startAction:_activeSender];_interacting=YES;
@try {
id retrieval=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)];
id setting=[_manager apiForProtocol:@protocol(FxParameterSettingAPI_v5)];
_available=_action && retrieval && setting;
if(!_available){_statusMessage=@"等待宿主连接";return NO;}
[_action startAction:self];_interacting=YES;return YES;
_available=retrieval && setting;
if(!_reportedConnection){
os_log(OS_LOG_DEFAULT,"PGInspector connection readBefore=%{public}d writeBefore=%{public}d readInAction=%{public}d writeInAction=%{public}d viewSender=%{public}d onMain=%{public}d",readBefore,writeBefore,retrieval!=nil,setting!=nil,[_activeSender isKindOfClass:NSView.class],NSThread.isMainThread);
_reportedConnection=YES;
}
if(!_available){_statusMessage=@"等待宿主连接";[self finish];return NO;}
} @catch(NSException *exception) {[self finish];@throw exception;}
return YES;
}
- (void)finish {if(_interacting){_interacting=NO;[_action endAction:self];_action=nil;}}
- (void)finish {if(_interacting){_interacting=NO;[_action endAction:_activeSender];_action=nil;_activeSender=nil;}}
- (void)readAtTime:(CMTime)time {
if(_pendingUntil && CMTimeCompare(time,_pendingTime)!=0)_pendingUntil=0;
id<FxParameterRetrievalAPI_v6> api=[_manager apiForProtocol:@protocol(FxParameterRetrievalAPI_v6)];
@@ -241,5 +266,5 @@ PGBeautySettings PGSettingsWithInspectorState(PGBeautySettings s,PGInspectorStat
ok=[self commit:[PGInspectorState stateWithValues:values disabledParameters:disabled hasEdits:YES]];
} @finally {if(owned)[self finish];}return ok;
}
- (void)dealloc {if(_interacting)[_action endAction:self];}
- (void)dealloc {if(_interacting)[_action endAction:_activeSender];}
@end
+1 -1
查看文件
@@ -293,7 +293,7 @@ static PGInspectorGlyphButton *PGUIButton(NSString *glyph, NSColor *accent, id t
- (instancetype)initWithAPIManager:(id<PROAPIAccessing>)manager { return [self initWithController:[[PGInspectorController alloc]initWithAPIManager:manager]]; }
- (instancetype)initWithController:(PGInspectorController *)controller {
if((self=[super initWithFrame:NSMakeRect(0,0,320,100)])){
_controller=controller;self.appearance=[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
_controller=controller;_controller.actionSender=self;self.appearance=[NSAppearance appearanceNamed:NSAppearanceNameDarkAqua];
NSArray *sections=@[@"smooth",@"color",@"shape",@"more"],*headings=@[@"磨皮",@"美白",@"瘦脸",@"更多设置"];
NSArray *colors=@[PGUIColor(.28,.83,.96,1),PGUIColor(.34,.89,.84,1),PGUIColor(.59,.69,.98,1),PGUIColor(.54,.64,.76,1)];
NSMutableArray *cards=[NSMutableArray new];
@@ -17,9 +17,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.1.1</string>
<key>CFBundleVersion</key>
<string>9</string>
<string>10</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSHumanReadableCopyright</key>
+5
查看文件
@@ -0,0 +1,5 @@
Beauty renderer: 49 checks, 0 failures (Metal).
2026-10-21 23:20:16.950 face-tests[22007:5696503] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
Face processing: 116 checks passed
2026-10-21 23:20:21.817 slim-tests[22045:5696731] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
PASS: 394 slim alignment checks; maximum UV oracle error 1.09828022e-05
+21
查看文件
@@ -0,0 +1,21 @@
2026-10-21 23:20:18.015 host-tests[22024:5696629] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
Default IOSurface maximum byte difference: 0
Alternate destination tag maximum byte difference: 0
Anatomy default 0/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
Anatomy default 0/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
Anatomy default 1/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
Anatomy default 1/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
Anatomy big-eye 0/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
Anatomy big-eye 0/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
Anatomy big-eye 1/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
Anatomy big-eye 1/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
Anatomy chin-positive 0/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
Anatomy chin-positive 0/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
Anatomy chin-positive 1/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
Anatomy chin-positive 1/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
Anatomy chin-negative 0/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
Anatomy chin-negative 0/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
Anatomy chin-negative 1/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
Anatomy chin-negative 1/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
Legacy fallback upright comparison: max=2 mean=0.0010357
Host adapter: 248 checks, 0 failures
@@ -0,0 +1,6 @@
FAIL: an action-scoped host connects and reads the actual template values
FAIL: custom parameter actions identify their actual inspector NSView
FAIL: action-scoped parameter APIs do not leave the whole native panel disabled
FAIL: a connected native control writes through the action-scoped setting API
FAIL: a later host connection restores controls after a transient API failure
Inspector: 141 checks, 5 failures
@@ -0,0 +1 @@
Inspector: 141 checks, 0 failures
+21
查看文件
@@ -0,0 +1,21 @@
2026-10-21 23:20:17.783 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
2026-10-21 23:20:17.791 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,180) surface=320x240 origin=0
2026-10-21 23:20:18.509 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.8,0.3) setter=(1152,-432) readback=(0.8,0.3) mode=centered-pixels verified=1
2026-10-21 23:20:18.509 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.7,0.4) objectBounds=(-1920,-1080,3840,2160) canvas=(152,78) surface=320x240 origin=0
2026-10-21 23:20:18.607 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.8,0.3) setter=(0.8,0.3) readback=(0.12345,0.87654) mode=normalized verified=0
2026-10-21 23:20:18.607 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.75,0.25) setter=(0.75,0.25) readback=(0.75,0.25) mode=normalized verified=1
2026-10-21 23:20:18.607 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.75,0.25) objectBounds=(-100,-50,200,100) canvas=(160,60) surface=320x240 origin=0
2026-10-21 23:20:18.684 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.625,0.375) setter=(0.625,0.375) readback=(0.625,0.375) mode=normalized verified=1
2026-10-21 23:20:18.684 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.625,0.375) objectBounds=(-100,-50,200,100) canvas=(240,60) surface=320x240 origin=0
2026-10-21 23:20:18.765 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
2026-10-21 23:20:18.765 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(144,180) surface=320x240 origin=0
2026-10-21 23:20:18.864 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
2026-10-21 23:20:18.864 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0,1) objectBounds=(-100,-50,200,100) canvas=(100,140) surface=320x240 origin=0
2026-10-21 23:20:18.947 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(nan,nan) surface=320x240 origin=0
2026-10-21 23:20:19.044 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
2026-10-21 23:20:19.044 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(inf,nan) surface=320x240 origin=0
2026-10-21 23:20:19.123 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
2026-10-21 23:20:19.123 osc-tests[22026:5696635] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,nan) surface=320x240 origin=0
2026-10-21 23:20:19.203 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
2026-10-21 23:20:19.203 osc-tests[22026:5696635] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
OSC adapter: 98 checks, 0 failures
+8
查看文件
@@ -101,3 +101,11 @@ Motion:独立普通视频项目,源PTS0、1920×1080/25fps/10秒,媒体通
配套卡片版模板和Drop Zone.tiff已在宿主关闭时同步并逐字节核对,moef SHA256为`e1c0cff1dd3541ed97cab2cb39a76ad4f28dc659b3be7991cc7ac92dd8ea090b`。FCP发布入口为面板210及两项版权信息;旧参数定义隐藏保留,手动分析不再显示,输出保持实时自动跟随。自定义面板的真实嵌入、滚动、键盘/VoiceOver、保存重开及视觉均待用户自测。
临时APP、旧APP备份、公证ZIP已清理。项目、Codex工作树、DerivedData、桌面、下载、Applications、系统/用户FxPlug及paintfcp临时目录的有界扫描仅发现正式外层APP,扫描错误0;不将该范围扩张为全部挂载卷搜索。完整回执和扫描范围见`verification/v1.1.0/installed-verification.json`。最终恢复标签`v1.1.0`包含交付文档,签名产品源码保持f79d24eb0185f31feaae58b83b632f92dcb3ca91。
## 1.1.1 面板交互修复(原生验收进行中)
用户报告1.1.0界面无法交互并授权接手Motion/FCP测试。FCP中“大鱼人像美化验收-20261021”独立测试时间线复现:所有PG参数控件被禁用,页脚“等待宿主连接”;“更多设置”可展开,说明视图事件仍正常,故不是整张面板无法命中。失败AX与截图保留本机build/native-111,不上传用户测试画面或资源库内容。
连接代码原先在开启自定义参数action之前就要求读写API存在,且action sender传NSObject控制器;现先用真实NSView sender开启action,再在其上下文里取得API,缺API时配对结束。新增action-scoped模拟宿主及sender校验用例:修改前141项中5项失败,修改后全通过,包含临时接口失败后重新连接。接口前后布尔日志保留为原生诊断,根因的实际宿主确认仍待新版加载。
1.1.1(10)完整1046项回归通过(49美化、116人脸、394瘦脸/下巴、248宿主、98 OSC、141检查器),后三套启用ASan。正式编译、公证与原生Motion/FCP交互验收进行中,尚未把自动检查等同于原生通过。
+33 -2
查看文件
@@ -9,10 +9,24 @@
@property NSUInteger scalarWrites;
@property (strong) NSDictionary *actionBefore;
@property (strong) NSDictionary *undoValues;
@property BOOL parameterAPIsRequireAction;
@property BOOL actionRequiresView;
@property NSUInteger invalidActionSenders;
@property (weak) id lastActionSender;
@end
@implementation PGInspectorTestAPI
- (id)apiForProtocol:(Protocol *)protocol {
NSString *name=NSStringFromProtocol(protocol);
if(_parameterAPIsRequireAction && !self.actionDepth &&
([name isEqual:@"FxParameterRetrievalAPI_v6"] || [name isEqual:@"FxParameterSettingAPI_v5"]))return nil;
return [super apiForProtocol:protocol];
}
- (void)guard {if(!self.actionDepth)_accessViolations++;}
- (void)startAction:(id)sender {if(!self.actionDepth)_actionBefore=[self.values copy];[super startAction:sender];}
- (void)startAction:(id)sender {
_lastActionSender=sender;
if(_actionRequiresView && ![sender isKindOfClass:NSView.class]){_invalidActionSenders++;return;}
if(!self.actionDepth)_actionBefore=[self.values copy];[super startAction:sender];
}
- (void)endAction:(id)sender {if(self.actionDepth==1 && ![self.values isEqual:_actionBefore])_undoValues=_actionBefore;[super endAction:sender];}
- (CMTime)currentTime {[self guard];return [super currentTime];}
- (BOOL)getCustomParameterValue:(NSObject **)v fromParameter:(UInt32)i atTime:(CMTime)t {[self guard];return [super getCustomParameterValue:v fromParameter:i atTime:t];}
@@ -143,9 +157,26 @@ static void ViewInteractionTests(void) {
for(NSView *card in view.subviews)if(!card.hidden)Check(NSMaxY(card.frame)<=NSHeight(view.bounds)+1 && NSMaxX(card.frame)<=NSWidth(view.bounds)+1,@"every visible card and footer remains inside the panel at all inspector widths");
}
}
static void HostHandshakeTests(void) {
PGInspectorTestAPI *api=[PGInspectorTestAPI new];beatygrilPlugIn *plugin=[[beatygrilPlugIn alloc]initWithAPIManager:api];[plugin addParametersWithError:nil];
api.values[@(PGMidtone)]=@.5;
api.parameterAPIsRequireAction=YES;api.actionRequiresView=YES;
PGInspectorView *view=(PGInspectorView *)[plugin createViewForParameterID:PGInspectorPanel];[view refreshFromHost];
Check(view.controller.available && Near([view.controller.state valueForParameter:PGMidtone],.5),@"an action-scoped host connects and reads the actual template values");
Check(api.lastActionSender==view && api.invalidActionSenders==0,@"custom parameter actions identify their actual inspector NSView");
NSSlider *brightness=(NSSlider *)FindControl(view,NSSlider.class,@"肤色亮度");
Check(brightness.enabled,@"action-scoped parameter APIs do not leave the whole native panel disabled");
brightness.doubleValue=.42;Fire(brightness);PGInspectorState *saved=api.values[@(PGInspectorPanel)];
Check(saved.hasEdits && Near([saved valueForParameter:PGBrightness],.42),@"a connected native control writes through the action-scoped setting API");
[api.disabledAPIs addObject:@"FxParameterSettingAPI_v5"];[view refreshFromHost];
Check(!view.controller.available && api.actionDepth==0 && api.actionStarts==api.actionEnds,@"a genuinely missing setting API closes the already-started host action");
[api.disabledAPIs removeObject:@"FxParameterSettingAPI_v5"];[view refreshFromHost];
Check(view.controller.available && brightness.enabled,@"a later host connection restores controls after a transient API failure");
Check(api.accessViolations==0 && api.actionDepth==0 && api.actionStarts==api.actionEnds,@"action-scoped connection, edits, failure and reconnection remain balanced");
}
int main(int argc,const char **argv) {@autoreleasepool {
[NSApplication sharedApplication];[NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];
RegistrationTests();ModelTests();ControllerTests();ViewInteractionTests();
RegistrationTests();ModelTests();ControllerTests();ViewInteractionTests();HostHandshakeTests();
if(argc>2) {
NSData *inner=[NSData dataWithContentsOfFile:@(argv[1])],*outer=[NSData dataWithContentsOfFile:@(argv[2])];NSError *error=nil;
NSKeyedUnarchiver *reader=[[NSKeyedUnarchiver alloc]initForReadingFromData:inner error:&error];reader.requiresSecureCoding=YES;