# 最小 Native Shadow 采集设计（仅设计，未实施）

## 依据与最小范围

历史缺口位于“全部ModelAction已有解析缓存”到“按策略使用随机代表”之间：当前只输出模型数量及最后一个选中控件，未输出所有动作的匹配节点、资格新鲜度和策略实际触达。既有input/注入/transition足够证明已尝试事实，应复用，不复制一套执行器/数据库/身份系统。

最小新增是**一次决策的被动模型/解析缓存快照 + 实际选择关联**。它能补足控件机会证据，但不声称穷举所有输入字符串、动态对象或业务结果。先采Shadow，不改变排序、预算、阈值或禁用规则。

## 采集点与数据来源

|点|真实函数/位置|记录内容|不得做的事|
|---|---|---|---|
|S0 当前缓存快照|`StatefulAgent.resolveNewAction:840–856`中`adjustActionsByGUITree`之后、首次选择之前；State/tree/timestamp需一致|`newState.getActions()`全部ID/type/Name/valid/enabled/priority/visited/saturation；`getResolvedNodes/Node/Tree`缓存、GUI与Naming/version|不重跑resolveAction/validateNewAction、不消费RNG、不重新Naming、不抓新树|
|S1 选择实际触达|`SataAgent.returnSelectedAction:304–318`、`StatefulAgent.validateNewAction:813–830`原有结果返回处|本轮真实尝试的策略、动作、代表、已有validate结果，最终selected；未触达策略记NOT_EVALUATED|不为了记录全部候选重新跑策略或validator；不把未选都标disabled|
|S2 输入实例|既有`JevEvidenceAudit.beforeInput:203–216`/`MonkeySourceApe.generateEventsForAction:548–565`|snapshot_id→input_id、最终代表与参数、绑定是否变化，复用生成/注入记录|不把S0的代表当最终输入；不新增输入计划|
|S3 真实结果|既有`JevRuntime.inputSummary:764–793`与NATIVE_TRANSITION、transition receipt|确认/失败/丢弃，target GUI/version/State与输入实例关联|不以markVisited/生成输入替代确认执行，不推定业务成功|

S0只是当前随机代表资格的被动真值。每个resolvedNodes成员只有命名匹配；代表之外`native_validation=NOT_EVALUATED`。若某动作缓存tree/timestamp过期，记录STALE，而不是调用resolver刷新。需在后续设计验证已有缓存是否足够完整；不能保证单个快照等于所有潜在Concrete随机结果的已验证集合。

## 字段 Schema

可机器读取的 [shadow-capture.schema.json](analysis/shadow-capture.schema.json) 与 [example](analysis/shadow-capture.example.json) 是**提案示例，非采集结果**。主要字段：

- envelope：schema_version、run/attempt、process_epoch、snapshot_id、step/decision_round、monotonic_ns与wall_time、event_kind。
- observation：sourceState/model_version、Activity、GUI id/timestamp、Naming id、tree observation时间、snapshot freeze/写出时间、坐标/root bounds；区分观察时刻和日志到达时刻。
- inventory coverage：完整State动作枚举是否完成、当前tree缓存成员覆盖是否完整、逐成员Native验证是否完整、策略是否仅实际触达、丢弃/截断/未知原因。没有足够证据不设complete=true。
- 每ModelAction：ID、type、targetName引用、enabled/valid、priority、visitedCount、unvisited、resolvedSaturation、resolvedTree/timestamp、selected representative node_ref、全部已缓存member_refs（不构造新`GUITreeAction`）。
- 每节点：快照局部node_ref、parent_ref/index/path、class/resource、原始Native text/desc与generated_image_text标记、enabled/checkable/checked/clickable/longclick/scrollType、focus、bounds、inputText是否已计划；祖先与兄弟行上下文保留。现有Native文本会截断，不能假定其是完整对象业务键。
- identity：复用已存在的Concrete identity缓存；若要新计算`JevIdentity.fullName`，放在冻结的必要字段副本上离线完成并做同版等价测试，不在热路径额外调用全局Name intern。无证据则identity=null，不能伪造精确身份。
- execution：chosen action/node/input_id、已有confirmed history引用、注入结果、transition_id/target；source与target abstraction version分别保存。历史“已执行”由输入确认事实派生，不直接复制Native visit计数。
- mode/object/input：可靠已有上下文才记来源与值；无业务object键时UNKNOWN；Add/Edit和Save/Delete保留模式、对象指纹/来源及参数。入口组/功能ID可离线关联，Native不得新增语义推断或Prompt。

## 完整库存与策略资格如何解释

S0可完整列出State.actions与**缓存当前tree匹配成员**；不等于所有GUI元素，也不等于所有成员已验证。当前Native的bounds validator本身简单，但`validateNewAction`包含随机解析，不能为Shadow重调它。可在离线冻结bounds上计算非空/相交派生条件，必须标DERIVED，不冒充逐成员Native执行结果。

S1只记录实际评估/拒绝、缓存复用与最终分支；未走到的动作是NOT_EVALUATED。策略先后、路径缓存、随机数与相邻State差异不允许被重新执行来“补理由”。完全枚举潜在策略选择空间不是最小Shadow目标。

## 开销、频率与失败

历史23971决策的ModelAction中位数9、P95=25、P99=31、最大43；选中动作成员中位1、P95=4、最大50。抽样树flag操作对中位20/P95=49，**不是全State匹配成员总数**。因此不能从选中成员数量精确估计全快照体积。

建议每次正常State决策冻结一个快照，内容hash/字典去重节点与长identity，仅状态/计数/代表变化记增量；保留序号和可恢复基线。示例预算假设每点10–60KiB，则约2400点/run为24–144MiB未压缩，输入结果复用既有日志；这只是容量预算，非实测。极端别名/长文本可超出，不能截断后仍声称完整。

冻结后有界队列异步序列化写本地JSONL即可，无服务/DB。队列满记drop范围、原因和completeness=false；不阻塞、不重试改变动作选择，也不能静默丢完整性。观察新增必有CPU/内存/写盘成本，**不能承诺零耗时或完全不影响固定wall-clock预算内吞吐**；下阶段需对照测试RNG/选择序列未被采集调用改变，并测P50/P95采集耗时、队列峰值、drop率、字节/决策与动作吞吐。这里没有启动该测试。

原始敏感字段避免采密码/认证内容；公开副本另做脱敏。对象身份无法可靠获取时保留UNKNOWN，不用文本相同猜业务对象相同。

## 下一阶段最小可证伪假设

“在已给定Ⅰ入口的连续发生中，完整记录当前缓存控件成员与代表资格，再与精确模式/对象/参数下的确认操作及结果关联，能比State计数更早暴露尚未尝试的机会，并区分重复GUI操作和新结果。”

先检查Shadow完整性与留出新增解释能力，特别重测ODK晚期Checkbox、AD跨模式Save、Scarlet块操作和Wiki查询；只有证据充足才讨论充分性阈值。本轮没有修改Native或实施SUPPRESS。
