---
phase: 25.1-parser-robustness-security-hardening
plan: "01"
subsystem: testing
tags: [proptest, libfuzzer, security, parser, fuzz]

requires:
  - phase: 25-sql-body-parser
    provides: validate_and_rewrite, detect_semantic_view_ddl, detect_ddl_kind — the parser API under test

provides:
  - "TEST-07 proptest block: prefix_whitespace_detection and prefix_whitespace_rewrite_roundtrip (currently RED — will PASS after Plan 02)"
  - "TEST-08 adversarial unit tests: large input, null byte, semicolon injection, unicode homoglyph, control char (all PASS)"
  - "fuzz/fuzz_targets/fuzz_ddl_parse.rs: libFuzzer target for detect + validate_and_rewrite pipeline"
  - "fuzz/seeds/fuzz_ddl_parse/: 5 tracked corpus seeds"
  - "fuzz/Cargo.toml: fuzz_ddl_parse [[bin]] registered"

affects:
  - 25.1-02-PLAN (token-based detection fix that makes TEST-07 green)

tech-stack:
  added: []
  patterns:
    - "TDD RED state: proptest blocks in tests/parse_proptest.rs that document expected behavior before the fix"
    - "Fuzz target pattern: &[u8] input with early UTF-8 rejection, detect then validate pipeline"
    - "Seed tracking: fuzz/seeds/ (git-tracked) vs fuzz/corpus/ (gitignored, grows locally)"

key-files:
  created:
    - fuzz/fuzz_targets/fuzz_ddl_parse.rs
    - fuzz/seeds/fuzz_ddl_parse/seed_basic.txt
    - fuzz/seeds/fuzz_ddl_parse/seed_tab_ws.txt
    - fuzz/seeds/fuzz_ddl_parse/seed_null_byte.txt
    - fuzz/seeds/fuzz_ddl_parse/seed_long.txt
    - fuzz/seeds/fuzz_ddl_parse/seed_homoglyph.txt
  modified:
    - tests/parse_proptest.rs
    - fuzz/Cargo.toml

key-decisions:
  - "Corpus seeds placed in fuzz/seeds/fuzz_ddl_parse/ (git-tracked) not fuzz/corpus/ (gitignored by project .gitignore)"
  - "TEST-08 adversarial tests are standalone #[test] functions (not proptest blocks) because they test absolute invariants not probability-based properties"
  - "Fuzz target rejects invalid UTF-8 early (not a panic/crash — just out of scope for this target)"

patterns-established:
  - "RED state documentation: proptest blocks that FAIL against current impl and PASS after fix, with explicit comment explaining what will change"
  - "Adversarial test pattern: use std::panic::catch_unwind for tests that verify no-panic invariants on malformed input"

requirements-completed: []

duration: 6min
completed: 2026-03-12
---

# Phase 25.1 Plan 01: Failing Test Suite and Fuzz Target Summary

**Proptest RED suite + libFuzzer harness establishing test-first contracts for token-based whitespace-tolerant DDL detection**

## Performance

- **Duration:** ~6 min
- **Started:** 2026-03-12T14:01:43Z
- **Completed:** 2026-03-12T14:07:42Z
- **Tasks:** 2
- **Files modified:** 8 (2 modified, 6 created)

## Accomplishments
- TEST-07: Two proptest properties (`prefix_whitespace_detection`, `prefix_whitespace_rewrite_roundtrip`) that currently FAIL — confirming RED state for Plan 02's token-based fix
- TEST-08: Five adversarial unit tests covering large input (<50ms), null bytes, semicolon injection, unicode homoglyphs, and control characters — all PASS against the current implementation
- Created `fuzz/fuzz_targets/fuzz_ddl_parse.rs` exercising the full detect -> validate_and_rewrite pipeline on arbitrary byte sequences
- Added 5 corpus seed files to `fuzz/seeds/fuzz_ddl_parse/` tracking basic DDL, tab-separated keywords, null byte, 200-char name, and Cyrillic С homoglyph

## Task Commits

1. **Task 1: TEST-07 failing proptest (prefix whitespace variants)** - `4eb2867` (test)
2. **Task 2: TEST-08 adversarial unit tests + fuzz target** - `98d6ca2` (test)

## Files Created/Modified
- `tests/parse_proptest.rs` - Added TEST-07 proptest block + TEST-08 adversarial #[test] functions
- `fuzz/Cargo.toml` - Registered fuzz_ddl_parse [[bin]] entry
- `fuzz/fuzz_targets/fuzz_ddl_parse.rs` - libFuzzer target for parse pipeline
- `fuzz/seeds/fuzz_ddl_parse/seed_basic.txt` - Valid CREATE SEMANTIC VIEW DDL
- `fuzz/seeds/fuzz_ddl_parse/seed_tab_ws.txt` - Tab-separated keywords (CREATE\tSEMANTIC\tVIEW)
- `fuzz/seeds/fuzz_ddl_parse/seed_null_byte.txt` - Null byte (0x00) in view name
- `fuzz/seeds/fuzz_ddl_parse/seed_long.txt` - 200-char view name
- `fuzz/seeds/fuzz_ddl_parse/seed_homoglyph.txt` - Cyrillic С (0xD0 0xA1) prefix

## Decisions Made
- Seeds placed in `fuzz/seeds/fuzz_ddl_parse/` (git-tracked) rather than `fuzz/corpus/` (which is gitignored per project `.gitignore` convention)
- TEST-08 uses standalone `#[test]` functions with `catch_unwind` rather than proptest blocks, because they test absolute invariants
- Fuzz target rejects invalid UTF-8 early with early return, per the VALIDATION.md design spec

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] Seed files moved from fuzz/corpus/ to fuzz/seeds/**
- **Found during:** Task 2 (corpus seeds creation)
- **Issue:** Plan specified `fuzz/corpus/fuzz_ddl_parse/` but the root `.gitignore` excludes `fuzz/corpus/` (comment: "Fuzz corpus (grows locally, bootstraps from fuzz/seeds/ on fresh clone)"). Seeds would not be tracked in git.
- **Fix:** Created seeds in `fuzz/seeds/fuzz_ddl_parse/` following the project convention established by `fuzz/seeds/fuzz_json_parse/`, `fuzz/seeds/fuzz_query_names/`, etc.
- **Files modified:** Seeds in `fuzz/seeds/fuzz_ddl_parse/` (not `fuzz/corpus/`)
- **Verification:** `git status` confirms files are tracked; seeds exist locally in corpus for fuzzer use
- **Committed in:** `98d6ca2` (Task 2 commit)

---

**Total deviations:** 1 auto-fixed (1 blocking)
**Impact on plan:** Seed files are now properly tracked in git at the correct project location. The fuzz/corpus/ directory still holds the seeds locally (libFuzzer will use them). No functional change to the fuzz target or test behavior.

## Issues Encountered
- `prop_assert_eq!` format string with inline `{sep:?}` capture caused compile error — Rust's `format_args!` cannot capture variables when the format string is expanded from a macro. Fixed by passing `sep` as an explicit positional argument.
- Pre-commit hook (cargo fmt) reformatted the test file — required running `cargo fmt` before re-staging.

## RED State Confirmation

Running `cargo test prefix_whitespace` produces:

```
test prefix_whitespace_detection ... FAILED
test prefix_whitespace_rewrite_roundtrip ... FAILED
test result: FAILED. 0 passed; 2 failed
```

The failure root cause: `detect_ddl_kind` uses `starts_with_ci` which does byte-level prefix matching against literal single-space DDL prefixes like `b"create semantic view"`. Any tab, newline, or double-space between keywords fails the byte comparison. Plan 02 will replace this with token-based matching.

## Next Phase Readiness
- RED state established: Plan 02 can implement token-based detection and the proptest suite will turn green automatically
- Fuzz harness ready: once nightly toolchain is available, `cargo +nightly fuzz run fuzz_ddl_parse -- fuzz/seeds/fuzz_ddl_parse/` will exercise the pipeline
- No blockers for Plan 02

---
*Phase: 25.1-parser-robustness-security-hardening*
*Completed: 2026-03-12*
