---
phase: 11-filterbuilder
plan: 02
type: execute
wave: 2
depends_on:
  - 11-01
files_modified:
  - src/filter/adapter.rs
  - src/parser/iterator.rs
  - src/lib.rs
  - examples/filter_builder.rs
  - tests/filter_builder.rs
autonomous: true
requirements:
  - FILTER-09
  - FILTER-10

must_haves:
  truths:
    - "src/filter/adapter.rs 新增 `apply_filter(iter, filter)` 与 `apply_filter_keep_errors(iter, filter)` 两个泛型 pub(crate) 函数（FILTER-09 / FILTER-10）"
    - "apply_filter 错误记录处理与现有 filter_by_exec_time 一致（Err 被丢弃），apply_filter_keep_errors 透传 Err"
    - "src/parser/iterator.rs 的 LogIterator 新增 `apply_filter(self, filter: Filter)` 与 `apply_filter_keep_errors(self, filter: Filter)` 两个 pub 方法，委托 adapter（FILTER-10）"
    - "src/lib.rs 顶层 `pub use filter::{Filter, FilterBuilder};` 让用户可写 `use dm_database_parser_sqllog::{FilterBuilder, Filter}`"
    - "examples/filter_builder.rs 新增，演示 FilterBuilder 多条件链式构造 + LogIterator::apply_filter 调用，cargo build --examples 通过"
    - "tests/filter_builder.rs 新增端到端集成测试：单条件、多条件 AND、apply_filter 与 apply_filter_keep_errors 错误记录行为差异、空 filter 匹配全部、Send/Sync 跨线程传递验证"
    - "Filter / FilterBuilder 上若 Plan 11-01 添加了 #[allow(dead_code)]，本 plan 全部删除（lib.rs 重导出后 Filter / FilterBuilder 不再 dead）"
    - "cargo test 全量通过；cargo clippy --all-targets -- -D warnings 零警告；cargo test --doc 通过；cargo llvm-cov --workspace --all-features --fail-under-lines 90 通过"
  artifacts:
    - path: "src/filter/adapter.rs"
      provides: "FILTER-09 AND 谓词执行 + 错误处理两种语义"
      contains: "pub(crate) fn apply_filter"
    - path: "src/parser/iterator.rs"
      provides: "LogIterator::apply_filter 公开方法 — FILTER-10 集成点"
      contains: "pub fn apply_filter"
    - path: "src/lib.rs"
      provides: "Filter 与 FilterBuilder 公开重导出"
      contains: "pub use filter::"
    - path: "examples/filter_builder.rs"
      provides: "FilterBuilder + LogParser 端到端使用示例（REFACTOR-07 跟进）"
      contains: "FilterBuilder::new"
    - path: "tests/filter_builder.rs"
      provides: "FilterBuilder 端到端集成测试（FILTER-09/10 行为验证）"
      contains: "apply_filter"
  key_links:
    - from: "src/parser/iterator.rs LogIterator::apply_filter"
      to: "src/filter/adapter.rs apply_filter"
      via: "adapter::apply_filter(self, filter)"
      pattern: "adapter::apply_filter"
    - from: "src/filter/adapter.rs apply_filter"
      to: "Filter::matches"
      via: "filter.matches(sqllog)"
      pattern: "filter\\.matches"
    - from: "src/lib.rs"
      to: "src/filter/builder.rs"
      via: "pub use filter::{Filter, FilterBuilder}"
      pattern: "pub use filter::\\{Filter, FilterBuilder\\}"
    - from: "tests/filter_builder.rs"
      to: "LogIterator::apply_filter"
      via: "parser.iter().apply_filter(filter).collect()"
      pattern: "apply_filter"
    - from: "examples/filter_builder.rs"
      to: "FilterBuilder + LogIterator::apply_filter"
      via: "FilterBuilder::new().<...>.build() + parser.iter().apply_filter(filter)"
      pattern: "FilterBuilder::new"
---

<objective>
完成 Phase 11 的集成与公开 API 暴露：

1. 扩展 `src/filter/adapter.rs`，新增 `apply_filter` / `apply_filter_keep_errors` 两个泛型函数（消费 11-01 的 `Filter` 类型）。
2. 在 `src/parser/iterator.rs` 的 `LogIterator` 上新增对应两个 pub 方法，委托 adapter。
3. 在 `src/lib.rs` 顶层 `pub use filter::{Filter, FilterBuilder};`，让用户可直接 `use dm_database_parser_sqllog::{FilterBuilder, Filter}`。
4. 新增 `examples/filter_builder.rs` 端到端示例（同步 REFACTOR-07 文档同步精神）。
5. 新增 `tests/filter_builder.rs` 端到端集成测试，验证 FILTER-09（AND 语义、空 filter）与 FILTER-10（LogIterator 集成）。
6. 通过 cargo test、cargo clippy --all-targets -- -D warnings、cargo test --doc、cargo llvm-cov ≥ 90% 全部验收。

Purpose: 实现 FILTER-09（AND 语义在迭代器中执行）+ FILTER-10（与 LogParser::iter() 无缝集成）；本 plan 完成后 Phase 11 全部需求收官。

Output: FilterBuilder 完整公开 API 链路打通；端到端集成测试覆盖；覆盖率 ≥ 90%；clippy 零警告。
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/ROADMAP.md
@.planning/REQUIREMENTS.md
@.planning/phases/11-filterbuilder/11-RESEARCH.md
@.planning/phases/11-filterbuilder/11-PATTERNS.md
@.planning/phases/11-filterbuilder/11-01-SUMMARY.md
@src/filter/adapter.rs
@src/filter/mod.rs
@src/filter/builder.rs
@src/parser/iterator.rs
@src/parser/mod.rs
@src/lib.rs
@tests/parser_filters.rs
@examples/filter_slow_queries.rs
@CLAUDE.md

<interfaces>
本计划开始时（Plan 11-01 完成后）：
- `src/filter/builder.rs` 提供：
  ```rust
  pub struct Filter { /* predicates 字段为 pub(crate) 或 super 可见 */ }
  impl Filter { pub fn matches(&self, record: &Sqllog) -> bool; }
  pub struct FilterBuilder { ... }
  impl FilterBuilder { pub fn new() -> Self; pub fn build(self) -> Filter; /* 约 50 个链式方法 */ }
  ```
- `src/filter/mod.rs` 当前为 3 行：`pub(crate) mod adapter;` + `pub mod builder;` + `pub use builder::{Filter, FilterBuilder};`
- `src/filter/adapter.rs` 现有两个函数：
  ```rust
  pub(crate) fn filter_by_exec_time<I>(iter: I, min_ms: u64) -> impl Iterator<Item = Result<Sqllog, ParseError>>
  where I: Iterator<Item = Result<Sqllog, ParseError>>
  pub(crate) fn filter_by_sql_contains<I>(iter: I, pattern: &str) -> impl Iterator<Item = Result<Sqllog, ParseError>>
  where I: Iterator<Item = Result<Sqllog, ParseError>>
  ```
- `src/parser/iterator.rs` 现有 `LogIterator<'a>` 与方法：`pub fn skip_errors(self) -> impl Iterator<Item = Sqllog> + 'a`、`pub fn filter_by_exec_time(self, min_ms: u64)`、`pub fn filter_by_sql_contains(self, pattern: &'a str)`
- `src/lib.rs` 顶层重导出：`pub use error::ParseError;`、`pub use parser::{ FileEncodingHint, LogIterator, LogParser, LogParserBuilder };`、`pub use record::Sqllog;`。**filter 模块声明为 `pub(crate) mod filter;`，不导出 Filter / FilterBuilder。**

本计划结束时输出（Phase 11 收尾）：
```rust
// src/filter/adapter.rs（追加）
use crate::filter::builder::Filter;
pub(crate) fn apply_filter<I>(iter: I, filter: Filter) -> impl Iterator<Item = Result<Sqllog, ParseError>>
where I: Iterator<Item = Result<Sqllog, ParseError>>;
pub(crate) fn apply_filter_keep_errors<I>(iter: I, filter: Filter) -> impl Iterator<Item = Result<Sqllog, ParseError>>
where I: Iterator<Item = Result<Sqllog, ParseError>>;
```
```rust
// src/parser/iterator.rs（impl LogIterator 追加）
use crate::filter::builder::Filter;
impl<'a> LogIterator<'a> {
    pub fn apply_filter(self, filter: Filter) -> impl Iterator<Item = Result<Sqllog, ParseError>> + 'a;
    pub fn apply_filter_keep_errors(self, filter: Filter) -> impl Iterator<Item = Result<Sqllog, ParseError>> + 'a;
}
```
```rust
// src/lib.rs 追加
pub use filter::{Filter, FilterBuilder};
```

错误记录行为决策（来自 RESEARCH.md Pitfall 3）：
- `apply_filter`：与现有 filter_by_exec_time 一致，`Err(_)` 被丢弃
- `apply_filter_keep_errors`：`Err(_)` 透传，Ok(_) 经 Filter 判定
</interfaces>
</context>

<tasks>

<task type="auto">
  <name>Task 1: 在 src/filter/adapter.rs 追加 apply_filter / apply_filter_keep_errors；在 src/parser/iterator.rs 的 LogIterator 上追加对应两个 pub 方法</name>
  <files>src/filter/adapter.rs, src/parser/iterator.rs</files>
  <read_first>
    - src/filter/adapter.rs（确认现有 `filter_by_exec_time` / `filter_by_sql_contains` 函数签名与 `Err(_) => false` 错误处理模式 — 新增 apply_filter 复用同一模式）
    - src/parser/iterator.rs（确认 LogIterator 已有 `use crate::filter::adapter;` 与 `pub fn filter_by_exec_time(self, ...) -> impl Iterator<...> + 'a { adapter::filter_by_exec_time(self, min_ms) }` 委托模式 — 直接照搬）
    - src/filter/builder.rs（确认 `pub struct Filter` 与 `pub fn matches(&self, record: &Sqllog) -> bool` 签名正确，Filter 满足 Send + Sync）
    - .planning/phases/11-filterbuilder/11-RESEARCH.md 第 305-372 行（adapter.rs 与 iterator.rs 集成代码骨架）
    - .planning/phases/11-filterbuilder/11-RESEARCH.md 第 568-579 行（Pitfall 3：错误记录处理两种语义决策）
  </read_first>
  <action>
    1. **修改 src/filter/adapter.rs**：
       a. 文件顶部追加 `use crate::filter::builder::Filter;`（已有 `use crate::error::ParseError;` 和 `use crate::record::Sqllog;` 保持不变）。
       b. 在现有两个函数下方追加两个新函数：
          ```rust
          /// 使用 Filter 过滤迭代器：Ok 记录通过 Filter::matches 判定，Err 记录被丢弃。
          ///
          /// 错误记录处理行为与 filter_by_exec_time / filter_by_sql_contains 一致。
          pub(crate) fn apply_filter<I>(
              iter: I,
              filter: Filter,
          ) -> impl Iterator<Item = Result<Sqllog, ParseError>>
          where
              I: Iterator<Item = Result<Sqllog, ParseError>>,
          {
              iter.filter(move |item| match item {
                  Ok(sqllog) => filter.matches(sqllog),
                  Err(_) => false,
              })
          }

          /// 与 apply_filter 相同，但保留错误记录（Err 透传，Ok 经过 Filter 判定）。
          pub(crate) fn apply_filter_keep_errors<I>(
              iter: I,
              filter: Filter,
          ) -> impl Iterator<Item = Result<Sqllog, ParseError>>
          where
              I: Iterator<Item = Result<Sqllog, ParseError>>,
          {
              iter.filter(move |item| match item {
                  Ok(sqllog) => filter.matches(sqllog),
                  Err(_) => true,
              })
          }
          ```
       c. 两个函数均为 `pub(crate)`（与现有约定一致）；通过 LogIterator 公开方法间接暴露给 crate 外用户。
       d. **每个函数 ≤ 12 行**（含 where 子句与文档），符合 CLAUDE.md < 40 行。

    2. **修改 src/parser/iterator.rs**：
       a. 顶部追加 `use crate::filter::builder::Filter;`（已有 `use crate::filter::adapter;` 保持不变）。
       b. 在 `impl<'a> LogIterator<'a>` 块内（现有 filter_by_sql_contains 方法之后）追加两个方法：
          ```rust
          /// 应用 FilterBuilder 产出的组合过滤器，错误记录被丢弃（与 filter_by_exec_time 一致）。
          pub fn apply_filter(
              self,
              filter: Filter,
          ) -> impl Iterator<Item = Result<Sqllog, ParseError>> + 'a {
              adapter::apply_filter(self, filter)
          }

          /// 应用 FilterBuilder 产出的组合过滤器，错误记录透传。
          pub fn apply_filter_keep_errors(
              self,
              filter: Filter,
          ) -> impl Iterator<Item = Result<Sqllog, ParseError>> + 'a {
              adapter::apply_filter_keep_errors(self, filter)
          }
          ```
       c. **不修改**现有 `skip_errors` / `filter_by_exec_time` / `filter_by_sql_contains`（保持向后兼容）。
       d. **不修改**现有 `impl<'a> Iterator for LogIterator<'a>` 块。
       e. **不修改**现有 #[cfg(test)] mod tests 块（time_stamp validation 测试）。

    3. **不修改**：src/filter/builder.rs、src/filter/mod.rs、src/lib.rs、Cargo.toml、tests/、examples/。
  </action>
  <verify>
    <automated>cd /Users/guang/Projects/dm-database-parser-sqllog && cargo build 2>&1 | tail -3 && cargo test --lib 2>&1 | tail -5 && cargo clippy --lib -- -D warnings 2>&1 | tail -3</automated>
  </verify>
  <acceptance_criteria>
    - src/filter/adapter.rs 新增导入：`grep -c '^use crate::filter::builder::Filter;' src/filter/adapter.rs` 返回 1
    - src/filter/adapter.rs 含 apply_filter 函数：`grep -c 'pub(crate) fn apply_filter\b' src/filter/adapter.rs` 返回 1
    - src/filter/adapter.rs 含 apply_filter_keep_errors 函数：`grep -c 'pub(crate) fn apply_filter_keep_errors\b' src/filter/adapter.rs` 返回 1
    - src/filter/adapter.rs 中 apply_filter 体使用 `filter.matches(sqllog)`：`grep -c 'filter\.matches(sqllog)' src/filter/adapter.rs` ≥ 2
    - src/filter/adapter.rs 中 apply_filter 错误丢弃语义：`grep -A1 'pub(crate) fn apply_filter\b' src/filter/adapter.rs | head -20 | grep -c 'Err(_) => false'` 至少 1
    - src/filter/adapter.rs 中 apply_filter_keep_errors 错误透传语义：`grep -A20 'pub(crate) fn apply_filter_keep_errors' src/filter/adapter.rs | grep -c 'Err(_) => true'` 至少 1
    - src/parser/iterator.rs 新增导入：`grep -c '^use crate::filter::builder::Filter;' src/parser/iterator.rs` 返回 1
    - src/parser/iterator.rs LogIterator::apply_filter 方法存在：`grep -c 'pub fn apply_filter\b' src/parser/iterator.rs` 返回 1
    - src/parser/iterator.rs LogIterator::apply_filter_keep_errors 方法存在：`grep -c 'pub fn apply_filter_keep_errors\b' src/parser/iterator.rs` 返回 1
    - 两个 LogIterator 方法均委托 adapter：`grep -cE 'adapter::apply_filter(_keep_errors)?\(' src/parser/iterator.rs` 返回 2
    - 现有方法未被破坏：`grep -c 'pub fn skip_errors\|pub fn filter_by_exec_time\|pub fn filter_by_sql_contains' src/parser/iterator.rs` 返回 3
    - `cargo build` 退出码 0
    - `cargo test --lib 2>&1 | grep 'test result' | tail -1` 含 `0 failed`
    - `cargo clippy --lib -- -D warnings` 退出码 0
  </acceptance_criteria>
  <done>
    src/filter/adapter.rs 含 apply_filter + apply_filter_keep_errors 两个 pub(crate) 函数；src/parser/iterator.rs 的 LogIterator 含两个 pub 委托方法；cargo build / cargo test --lib / cargo clippy --lib 全部通过。
  </done>
</task>

<task type="auto">
  <name>Task 2: 在 src/lib.rs 顶层 pub use filter::{Filter, FilterBuilder}；清理 Plan 11-01 可能添加的 #[allow(dead_code)]；新增 examples/filter_builder.rs 与 tests/filter_builder.rs 端到端集成测试；跑通 cargo test / clippy / cargo llvm-cov 验收</name>
  <files>src/lib.rs, src/filter/builder.rs, examples/filter_builder.rs, tests/filter_builder.rs</files>
  <read_first>
    - src/lib.rs（确认当前 `pub use error::ParseError;` / `pub use parser::{ ... };` / `pub use record::Sqllog;` 重导出顺序）
    - src/filter/builder.rs（检查是否含 `#[allow(dead_code)]` 临时标注；若有，Plan 11-01 SUMMARY 应已记录）
    - .planning/phases/11-filterbuilder/11-01-SUMMARY.md（确认 11-01 是否使用了 dead_code 临时标注）
    - tests/parser_filters.rs（参考端到端测试结构：tempfile 写日志 + LogParserBuilder + 链式调用 + assert_eq!，行 1-99）
    - examples/filter_slow_queries.rs（参考 example 风格：env::args 读取 path、main 返回 Result）
    - src/parser/iterator.rs（确认 Task 1 已加入 apply_filter / apply_filter_keep_errors）
    - src/filter/adapter.rs（确认 Task 1 已加入 apply_filter / apply_filter_keep_errors）
    - src/filter/mod.rs（确认 `pub mod builder` 与 `pub use builder::{Filter, FilterBuilder}`）
  </read_first>
  <action>
    1. **修改 src/lib.rs**：
       - 在 `pub use record::Sqllog;` 行**之后**追加一行：`pub use filter::{Filter, FilterBuilder};`
       - 注意：lib.rs lines 1-80 是 rustdoc，不动；只在 mod 声明与 pub use 区追加一行。
       - **lib.rs 的 `pub(crate) mod filter;` 模块声明保持不变**（与 D-15 风格一致：模块本身 crate 内可见，公开类型通过顶层 pub use 暴露）。

    2. **清理 src/filter/builder.rs 中的 #[allow(dead_code)]**（如有）：
       - 若 Plan 11-01 在 Filter / FilterBuilder 上添加了 `#[allow(dead_code)]` 临时标注，本任务**全部删除**（Filter / FilterBuilder 现在通过 lib.rs 顶层 pub use 公开，且通过 iterator::apply_filter 在 crate 内部消费，dead_code 不再适用）。
       - 验证方法：`grep -c '#\[allow(dead_code)\]' src/filter/builder.rs` 应返回 0。
       - 若 Plan 11-01 没有使用 #[allow(dead_code)]，本子任务不做修改。

    3. **新建 examples/filter_builder.rs**（演示 FilterBuilder 完整使用）：
       ```rust
       //! filter_builder — FilterBuilder 链式构造组合过滤器演示
       //!
       //! 用法：`cargo run --example filter_builder <path-to-sqllog>`

       use dm_database_parser_sqllog::{FilterBuilder, LogParserBuilder};
       use std::env;

       fn main() -> Result<(), Box<dyn std::error::Error>> {
           let path = env::args().nth(1).unwrap_or_else(|| {
               eprintln!("Usage: filter_builder <path-to-sqllog>");
               std::process::exit(1);
           });

           // 多字段 AND 组合：exec_time > 1ms AND sql 含 "SELECT" AND username 等于 "alice"
           let filter = FilterBuilder::new()
               .exec_time_gt(1.0)
               .sql_contains("SELECT")
               .username_eq("alice")
               .build();

           let parser = LogParserBuilder::new(&path).build()?;
           for result in parser.iter().apply_filter(filter) {
               let record = result?;
               println!(
                   "{} | ep={} | {}ms | {}",
                   record.ts, record.ep, record.exectime, record.sql
               );
           }
           Ok(())
       }
       ```
       - 文件总长 ~25 行；main 函数 < 40 行。

    4. **新建 tests/filter_builder.rs**（端到端集成测试，目标覆盖 FILTER-09 + FILTER-10）：
       使用 `tempfile::NamedTempFile` 写入合成日志，通过 `LogParserBuilder` 构建 parser，再链式调用 `.apply_filter(filter)`。**所有测试加 `#[cfg(not(miri))]`**（与 tests/parser_filters.rs 一致）。

       测试用例（每个 ≤ 30 行）：

       a. `test_apply_filter_single_condition_exec_time`：写 3 条记录（exectime=5/200/50），FilterBuilder 仅 exec_time_gt(100.0)，apply_filter 返回 1 条（200ms 那条）。

       b. `test_apply_filter_multiple_conditions_and_semantics`：写 3 条记录（变化 username 和 sql），FilterBuilder 链式 username_eq("alice") + sql_contains("SELECT")，验证只有同时满足两条件的记录返回。

       c. `test_apply_filter_empty_filter_matches_all`：写 2 条记录，`FilterBuilder::new().build()`（空 filter），验证返回 2 条记录。

       d. `test_apply_filter_no_match`：写 2 条记录，FilterBuilder 设置一个全部不满足的条件，验证返回 0 条。

       e. `test_apply_filter_drops_parse_errors`：第一行写无效内容（"this is not a valid log record\n"），第二行写有效记录，FilterBuilder 任意条件，验证 apply_filter 输出长度等于通过条件的有效记录数（不含 Err）。

       f. `test_apply_filter_keep_errors_propagates_parse_errors`：相同输入与 e，调用 apply_filter_keep_errors，验证输出长度 = 1（Err）+ N（通过 filter 的 Ok），且至少存在一个 `Err(ParseError::InvalidFormat { .. })`。

       g. `test_apply_filter_ts_starts_with`：写 2 条不同时间戳的记录，FilterBuilder 用 ts_starts_with("2025-11-17 16:09:41")，验证按前缀过滤生效。

       h. `test_apply_filter_ep_between`：写 3 条 ep 不同的记录，FilterBuilder 用 ep_between(1, 3)，验证范围闭区间。

       i. `test_filter_send_sync_across_threads`：构造 FilterBuilder 链式产出 Filter，使用 `std::thread::spawn(move || { filter.matches(&record) })` 验证 Filter 跨线程传递（这是 Send + Sync 边界测试，为 Phase 12 async 集成铺路）。**无需 tokio 依赖**，纯标准库即可。

       j. `test_apply_filter_with_skip_errors_pattern`：演示 `parser.iter().apply_filter(filter).filter_map(|r| r.ok())` 组合使用，验证返回 Vec<Sqllog>（type-only，确认链式可用）。

       **目标测试数 ≥ 10 个，覆盖 FILTER-09（AND + 空 filter）与 FILTER-10（与 LogParser::iter() 集成、错误记录两种语义、Send + Sync）。**

    5. **跑全套验收命令（每条退出码必须为 0）**：
       ```bash
       cargo build
       cargo build --tests
       cargo build --examples
       cargo test
       cargo test --doc
       cargo clippy --all-targets -- -D warnings
       cargo llvm-cov --workspace --all-features --fail-under-lines 90
       ```

    6. **覆盖率不达标处理**：
       - 若 cargo llvm-cov < 90%，定位是否 apply_filter_keep_errors / Filter::matches 某分支未被覆盖。
       - 缓解：在 tests/filter_builder.rs 内补充测试覆盖未覆盖的分支；**禁止降低 `--fail-under-lines` 阈值**。
       - 若仍不达标，在 src/filter/adapter.rs 末尾追加最小化 #[cfg(test)] mod tests 块（构造内存 Sqllog 与单元迭代器，验证 apply_filter / apply_filter_keep_errors 内部分支）。

    7. **clippy 警告处理**：若 clippy 报警告（unused import、needless_return、可读性提示等），立即修复；不允许 #[allow(...)] 绕过；不允许降低 -D warnings 等级。

    8. **不修改**：src/record.rs、src/error.rs、Cargo.toml、benches/、其他既有 tests/*.rs 文件、其他既有 examples/*.rs 文件、src/async_api/。
  </action>
  <verify>
    <automated>cd /Users/guang/Projects/dm-database-parser-sqllog && cargo build 2>&1 | tail -3 && cargo build --examples 2>&1 | tail -3 && cargo test 2>&1 | tail -10 && cargo test --doc 2>&1 | tail -5 && cargo clippy --all-targets -- -D warnings 2>&1 | tail -5 && cargo llvm-cov --workspace --all-features --fail-under-lines 90 2>&1 | tail -10</automated>
  </verify>
  <acceptance_criteria>
    - src/lib.rs 新增重导出：`grep -c '^pub use filter::{Filter, FilterBuilder};' src/lib.rs` 返回 1
    - src/lib.rs filter 模块声明保持 pub(crate)：`grep -c '^pub(crate) mod filter;' src/lib.rs` 返回 1
    - src/lib.rs 其他原有重导出未被破坏：`grep -c '^pub use error::ParseError;' src/lib.rs` 返回 1；`grep -c '^pub use parser::' src/lib.rs` 返回 1；`grep -c '^pub use record::Sqllog;' src/lib.rs` 返回 1
    - src/filter/builder.rs 已无 dead_code 标注：`grep -c '#\[allow(dead_code)\]' src/filter/builder.rs` 返回 0
    - 新文件 examples/filter_builder.rs 存在：`test -f examples/filter_builder.rs && echo OK` 输出 OK
    - examples/filter_builder.rs 调用 FilterBuilder：`grep -c 'FilterBuilder::new' examples/filter_builder.rs` 返回 1
    - examples/filter_builder.rs 调用 apply_filter：`grep -c 'apply_filter' examples/filter_builder.rs` 返回 1
    - 新文件 tests/filter_builder.rs 存在：`test -f tests/filter_builder.rs && echo OK` 输出 OK
    - tests/filter_builder.rs 含 ≥ 10 个 #[test]：`grep -c '^#\[test\]' tests/filter_builder.rs` ≥ 10
    - 所有集成测试都加 miri 跳过：`grep -c '#\[cfg(not(miri))\]' tests/filter_builder.rs` 应等于 #[test] 数量
    - 集成测试覆盖关键路径：
      - `grep -c 'apply_filter_keep_errors' tests/filter_builder.rs` ≥ 1（错误透传分支）
      - `grep -c 'std::thread::spawn' tests/filter_builder.rs` ≥ 1（Send + Sync 跨线程验证）
      - `grep -c 'FilterBuilder::new().build()' tests/filter_builder.rs` ≥ 1（空 filter 匹配全部）
    - `cargo build` 退出码 0
    - `cargo build --tests` 退出码 0
    - `cargo build --examples` 退出码 0
    - `cargo test` 退出码 0，且 `cargo test 2>&1 | grep 'test result' | tail -1` 含 `0 failed`
    - `cargo test --doc` 退出码 0
    - `cargo clippy --all-targets -- -D warnings` 退出码 0
    - `cargo llvm-cov --workspace --all-features --fail-under-lines 90` 退出码 0
    - tests/filter_builder.rs 集成测试至少 10 个通过：`cargo test --test filter_builder 2>&1 | grep 'test result' | tail -1` 含 `[0-9]+ passed; 0 failed` 且数 ≥ 10
    - 端到端公开路径有效（FILTER-10 验证）：tests/filter_builder.rs 文件顶部含 `use dm_database_parser_sqllog::{FilterBuilder, LogParserBuilder};` 且能编译运行（隐含在 cargo test 通过中）
  </acceptance_criteria>
  <done>
    src/lib.rs 顶层重导出 Filter + FilterBuilder；examples/filter_builder.rs 演示完整链路；tests/filter_builder.rs 集成测试 ≥10 个全部通过；cargo test / cargo test --doc / cargo clippy --all-targets -- -D warnings / cargo llvm-cov --fail-under-lines 90 全部通过；Phase 11 收官完成。
  </done>
</task>

</tasks>

<verification>
Plan 11-02 端到端验收（同时覆盖 Phase 11 整体收官）：

1. **公开 API 表面完整**（FILTER-10）：
   - 用户能写 `use dm_database_parser_sqllog::{FilterBuilder, Filter, LogParserBuilder};`
   - 用户能写 `parser.iter().apply_filter(filter).collect()`（apply_filter pub）
   - 用户能写 `parser.iter().apply_filter_keep_errors(filter).collect()`（apply_filter_keep_errors pub）

2. **AND 语义验证**（FILTER-09）：
   - tests/filter_builder.rs::test_apply_filter_multiple_conditions_and_semantics 通过
   - tests/filter_builder.rs::test_apply_filter_empty_filter_matches_all 通过

3. **错误处理两种语义**：
   - tests/filter_builder.rs::test_apply_filter_drops_parse_errors 通过
   - tests/filter_builder.rs::test_apply_filter_keep_errors_propagates_parse_errors 通过

4. **Send + Sync 跨线程**（为 Phase 12 async 集成铺路）：
   - tests/filter_builder.rs::test_filter_send_sync_across_threads 通过

5. **D-17 等价验收**（Phase 11 收尾质量门）：
   - `cargo test` 退出码 0
   - `cargo test --doc` 退出码 0
   - `cargo clippy --all-targets -- -D warnings` 退出码 0
   - `cargo llvm-cov --workspace --all-features --fail-under-lines 90` 退出码 0
   - `cargo build --examples` 退出码 0

6. **向后兼容**：
   - tests/parser_filters.rs 现有 6 个测试仍然通过（filter_by_exec_time / filter_by_sql_contains 未被破坏）
   - examples/filter_slow_queries.rs 仍然编译通过
</verification>

<success_criteria>
- FILTER-09：apply_filter 通过 Iterator::filter 链路一次性遍历完成多条件 AND，无中间 Vec
- FILTER-10：LogParser::iter() 返回的 LogIterator 上有 pub fn apply_filter(self, filter: Filter)；用户侧公开路径有效
- Filter / FilterBuilder 通过 src/lib.rs 顶层 pub use 暴露给 crate 外用户
- 错误记录两种处理语义（drop / keep_errors）均有专门方法和测试
- Filter 满足 Send + Sync（test_filter_send_sync_across_threads 验证）
- cargo test 全量通过，cargo clippy --all-targets -- -D warnings 零警告，cargo test --doc 通过，cargo llvm-cov --fail-under-lines 90 通过
- Phase 11 全部 10 个需求（FILTER-01 ~ FILTER-10）实现并验证
</success_criteria>

<output>
完成后创建 .planning/phases/11-filterbuilder/11-02-SUMMARY.md，记录：
- src/filter/adapter.rs 与 src/parser/iterator.rs 新增方法签名（apply_filter / apply_filter_keep_errors）
- src/lib.rs 最终重导出列表（确认 Filter + FilterBuilder 已暴露）
- examples/filter_builder.rs 文件结构
- tests/filter_builder.rs 测试函数清单（≥10 个）与通过情况
- 整体 cargo test 通过测试数（v1.1 基线 + Phase 11 新增）
- cargo llvm-cov 实际覆盖率数值
- cargo clippy --all-targets 输出（应零警告）
- Phase 11 总体收官：FILTER-01 ~ FILTER-10 全部实现位置一览
- 留给 Phase 12 AsyncAPI 的衔接点：Filter 已满足 Send + Sync（spawn_blocking 可直接传递）；FilterBuilder 链式方法可在 async fn 内同步构造；apply_filter 的同步迭代器可在 spawn_blocking 内 collect 为 Vec<Sqllog<'static>>（实际是 Vec<Sqllog>，已无生命周期）
</output>
</content>
</invoke>