Skip to content

Commit ab2dfd5

Browse files
github-actions[bot]Liam0205
authored andcommitted
docs(llmdoc): complete operator input exclusion contract
1 parent 14ae712 commit ab2dfd5

4 files changed

Lines changed: 15 additions & 3 deletions

File tree

llmdoc/architecture/dag-engine.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,13 @@ Operator-visible input 排除集合(skip 控制字段 + `common_input_template
498498
- pine-go / pine-java:`BuildInput` 阶段构建 `common` map 时**直接丢弃**排除字段(materialize-time exclusion),`input.Common(field)` 在字段名不在 map 中时返回 nil。
499499
- pine-cpp:`OperatorInput` 是懒代理,`common(field)` 直查 frame——**必须在读路径显式 gate** 排除集合(`InputFieldSpec::excluded_common`),否则算子看到 raw frame 值。issue #174 首次暴露该差异:`reorder_shuffle_by_salt``metadata.common_input` 构 salt,pine-cpp 未 gate 时读到 skip 字段 `_skip_branch=false` 而 pine-go/pine-java 读到 nil,salt 分歧 → 排序分歧 → 下游整链 cascading。
500500

501-
**跨运行时不变量**:任何 op 通过 `input.common(field)` 访问排除集合内的字段名,都必须收到 nil。materialize 侧靠 build-time 剔除保证,proxy 侧靠 spec.excluded_common gate 保证。给 spec 加新的排除维度时(新增 skip 桶、template 桶等)需逐一核对每种实现是否都把该维度带进 excluded_common。
501+
**跨运行时不变量**:排除字段不得通过三个消费面向算子泄漏:
502+
503+
- 值访问:任何 op 通过 `input.common(field)` 访问排除集合内的字段名,都必须收到 nil。materialize 侧靠 build-time 剔除保证,proxy 侧靠 `spec.excluded_common` gate 保证。
504+
- 字段名元数据:传给算子 init 的 `metadata.common_input` 不得包含顶层 `skip` 控制字段。pine-cpp 在实例 init 前过滤字段名,但 DAG 依赖推导仍读取过滤前 metadata,避免改变调度边。
505+
- 观测快照:debug/trace 输入快照必须使用与算子值访问相同的三桶并集;`[pine-debug]``_return_trace` 不得显示算子本身不可见的 raw frame 字段。
506+
507+
给 spec 加新的排除维度时(新增 skip 桶、template 桶等),需逐一核对值访问、字段名元数据和观测快照,而非只验证 `OperatorInput` 的读取结果。
502508

503509
#### BuildInput 错误消息约定
504510

llmdoc/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
## architecture/
1414

15-
- `llmdoc/architecture/dag-engine.md` — 核心引擎架构:配置编译流水线、DAG 推导规则(三标记 + auto-inject 模型:ConsumesRowSet/MutatesRowSet/AdditiveWritesRowSet 标记与 item 字段自动注入)、调度模型、DataFrame 语义(含 InputFieldSpec 三态模型:Nullable/Strict/Defaulted)、算子类型约束、行集依赖行为,以及引擎级 option / 根级配置注入(含 debug nullable 三态继承)、Server struct 生命周期与 context 传播、服务端 reload 集成与 HTTP middleware 包装边界、双通道运行时观测、ExecutionError/PanicError 因果链(三运行时 cause chain parity)、资源数据型(snapshot 导出)/句柄型(borrow 借用,如 redis_connection)区分、Pine-Java 完整功能对等描述、接受的跨引擎设计差异归档(如 issue #91 Lua VM pool 上限/GC 回收语义不对等:指标层 5 元组对等 + 端到端 calibrated 持平 + 生产无 OOM 痛点 + 跨语言机制无可移植近似 → 接受差异,重启触发条件为生产 RSS 单调爬升数据;issue #169 Java routeHandler 抛/返回二分 vs Go 统一 err 传 Egress)、跨运行时 operator-visible input 排除集合契约(skip/template/common_input_skip 在 pine-go/pine-java 走 materialize-time 剔除、pine-cpp 走 proxy 读路径 gate,issue #174)。
15+
- `llmdoc/architecture/dag-engine.md` — 核心引擎架构:配置编译流水线、DAG 推导规则(三标记 + auto-inject 模型:ConsumesRowSet/MutatesRowSet/AdditiveWritesRowSet 标记与 item 字段自动注入)、调度模型、DataFrame 语义(含 InputFieldSpec 三态模型:Nullable/Strict/Defaulted)、算子类型约束、行集依赖行为,以及引擎级 option / 根级配置注入(含 debug nullable 三态继承)、Server struct 生命周期与 context 传播、服务端 reload 集成与 HTTP middleware 包装边界、双通道运行时观测、ExecutionError/PanicError 因果链(三运行时 cause chain parity)、资源数据型(snapshot 导出)/句柄型(borrow 借用,如 redis_connection)区分、Pine-Java 完整功能对等描述、接受的跨引擎设计差异归档(如 issue #91 Lua VM pool 上限/GC 回收语义不对等:指标层 5 元组对等 + 端到端 calibrated 持平 + 生产无 OOM 痛点 + 跨语言机制无可移植近似 → 接受差异,重启触发条件为生产 RSS 单调爬升数据;issue #169 Java routeHandler 抛/返回二分 vs Go 统一 err 传 Egress)、跨运行时 operator-visible input 排除集合契约(值访问、init 字段名元数据、debug/trace 快照三个消费面,issue #174)。
1616
- `llmdoc/architecture/apple-compiler.md` — Python DSL 架构:Flow 声明 API、SubFlow 契约声明与编译期强制(`common_input`/`common_output`/`item_input`/`item_output` 在 issue #78 落地为 subtree-scoped 字段覆盖 + 死代码校验,未声明契约的 SubFlow 自动继承外层;`required_resources` 沿用 issue #37 校验)、编译流水线(含 step 8b `_validate_subflow_contracts`)、校验规则(含 `validate_write_without_read``AdditiveWritesRowSet` 算子的同字段豁免,issue #72)、控制流降级(含 `_rename_field` Lua `_G[]` 语法处理)、资源声明处理、根级配置字段扩展路径(如 `storage_mode``log_prefix``debug`),以及 row-set 标记三元组(`consumes_row_set` / `mutates_row_set` / `additive_writes_row_set`)通过 `apple_generated/markers.py` 表填充 `OpCall`、True-OR widen 合并语义、`_apply``_add_op` 的刻意非对称(仅 `consumes_row_set` 暴露给 DSL 调用点)。
1717
- `llmdoc/architecture/pine-cpp-runtime.md` — Pine-C++ 运行时架构:作为标杆运行时的定位、错误/fixture parity 契约、CLI 与 HTTP 入口(含 HTTP/1.1 keep-alive / read-header-timeout / idle-timeout / max-body-size / middleware / graceful shutdown / 客户端断连取消 eventfd 零延迟唤醒 / custom Route 与 Watch 的"黑盒行为对等、实现结构自由"决策——不做 Go/Java 嵌入 API、可测校验逻辑抽 socket-free routes.cpp)、codegen 入口(`-schema-json` schema 导出 + `-output` 发射完整 Apple DSL 产物集与 Go/Java 字节级一致 + `-doc-dir` 发射算子文档 markdown 与 pine-go byte-equal、`OperatorSchema.metadata` 字段显式声明、`format_g` 对 |d| > LLONG_MAX 的 UB 守卫与 Ryu/Grisu 路由点、ResourceSchema 全局注册表与 `reset_resource_schema_registry`/`reset_all_resource_registries` 拆分语义)、`metrics::Provider` 与 `resource::Manager` 对等(`ResourceValue` 数据 `Variant` XOR 句柄 `shared_ptr<void>` 双通道,数据型走 `snapshot()`、句柄型走 `borrow()`,RAII 拆除)、Frame 多态基类 + ColumnFrame/RowFrame 双物理实现(C++23,per-call 锁形态与 Go/Java 对齐、`pine::SharedMutex` 备件)、Column 类型层级、`PINE_REGISTER_OPERATOR_T` 注册模型、ValidateOutput 类型约束、NaN/Inf 校验、PanicError stacktrace、外部 stop_token 取消、ready-queue DAG 调度器(双隔离线程池 + in-degree 原子追踪)、observe_log/pine-debug 日志、Redis client 失败收敛与 SIGPIPE 守卫(`MSG_NOSIGNAL` + AUTH/SELECT close fd)+ per-command 指标 `run_command<T>` 模板(错误类型分层 known follow-up)、`OperatorOutput` 缓冲区复用(`node_body` 用 `thread_local` 而非对象池——ready-queue 不迁移半完成节点故省掉 Get/Put 记账;acquire 与 node body 尾部**两侧都 reset**,承重的是尾部那次(在 `try/catch` 之外、成功与抛异常都覆盖),acquire 侧现为 defence in depth;`reset()` 用 `clear()` 保住 heap capacity 并对超 `kRetainLimit` 的容器释放;spine 上限不含元素 payload,issue #122)。
1818

llmdoc/memory/reflections/skip-field-lazy-input-and-pool-baseline-keys.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,9 @@
4141
- 由 recorder 把前三条 promotion 写进对应稳定文档并同步 `index.md`;lazy proxy 实现差异那条建议放在 `architecture/dag-engine.md` "BuildInput 语义"节,与现有 lazy proxy 描述并列一段"实现差异清单"。
4242
- 下次 nightly artifact 复现走弯路超过 30 分钟时,条件反射式切"从末端逐算子截断"策略,不要继续深挖末端错误路径。
4343
- pine-java `TransformByLua.java``is*()` 派发点现已全部为 type-tag 派发(table-key check / fromLua / snapshotKeys),三处闭环;下次再触碰该文件时不需要额外扫。若 pine-java 后续加新 Lua bridge 代码,仍需 grep 全部 `is*()` 调用逐个判定 coercion-or-tag(与 #175 反思同款要求)。
44+
45+
## Review Follow-up
46+
47+
- 后续 CI differential fuzz 再次命中同族分歧:只在 `OperatorInput::common` 隐藏排除字段的值还不够。算子若遍历 init 时收到的 `metadata.common_input`,仍会看到 skip 字段名并改变 salt/hash 形状。pine-cpp 因此在 `Engine` 构造、调用 `instance->init(op_cfg)` 前过滤顶层 `skip` 字段名;DAG 仍使用过滤前 metadata 推导依赖。
48+
- debug/trace 是第二个独立消费面。pine-cpp `snapshot_input` 必须使用 `skip ∪ common_input_skip ∪ common_input_template`,否则算子虽然读不到排除字段,`[pine-debug]``_return_trace` 仍会泄漏 raw frame 值。
49+
- 可复用教训:输入排除契约要沿“值访问、传给算子的字段名元数据、观测快照”三个消费面逐一验证;只修首个暴露分歧的读路径会留下同族旁路。

llmdoc/reference/operator-contract.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ C++ 侧 `OperatorInput`(`include/pine/operator_input.hpp`)是 Frame + InputF
526526
- **Sequence 检测严格性**(pine-go):`fromLua` 要求 `1..N` 严格连续才识别为 array,遇到 `nil` 中断即降级为 map(避免误判稀疏数组)。
527527
- **错误前缀去重**(pine-go):`fromLua` 的内部错误已带 `lua:` 前缀,外层 `executeForItem` / `executeForCommon` 不再二次包裹。
528528

529-
`fixtures/operators/transform_by_lua_tables.json``scripts/differential-fuzz.py``LUA_ITEM_FUNCTIONS` table-aware 用例(`#item_tags``for i=1,#item_vals`、return `{a, b}`)覆盖该转换路径,由 differential fuzz 与 cross-validate 持续验证。标量类型身份路径由 `fixtures/pipelines/lua_string_number_identity.json` 与 fuzzer 的 `LUA_IDENTITY_ITEM_FUNCTION` + flow_contract 投影(使字段值进入差分比对面)覆盖。issue #174 的 skip-field-in-common_input 契约由 `fixtures/pipelines/shuffle_salt_reads_skip_field.json` 钉住:`reorder_shuffle_by_salt``metadata.common_input` 构 salt 时,`skip` 列表中的字段必须对算子的 `input.common(field)` 不可见,三运行时(pine-go / pine-java / pine-cpp)字节级一致输出
529+
`fixtures/operators/transform_by_lua_tables.json``scripts/differential-fuzz.py``LUA_ITEM_FUNCTIONS` table-aware 用例(`#item_tags``for i=1,#item_vals`、return `{a, b}`)覆盖该转换路径,由 differential fuzz 与 cross-validate 持续验证。标量类型身份路径由 `fixtures/pipelines/lua_string_number_identity.json` 与 fuzzer 的 `LUA_IDENTITY_ITEM_FUNCTION` + flow_contract 投影(使字段值进入差分比对面)覆盖。issue #174 的排除契约由 `fixtures/pipelines/shuffle_salt_reads_skip_field.json` `fixtures/pipelines/shuffle_salt_reads_common_input_skip.json` 钉住:`reorder_shuffle_by_salt``metadata.common_input` 构 salt 时,排除字段的值和顶层 `skip` 字段名都不得进入算子可见输入;debug/trace 快照也不得泄漏同一排除集合
530530

531531
### Lua Pool Baseline 重置契约(仅覆盖字符串键 globals)
532532

0 commit comments

Comments
 (0)