---
phase: 18-verification-and-integration
plan: 02
type: execute
wave: 2
depends_on: ["18-01"]
files_modified:
  - TECH-DEBT.md
autonomous: true
requirements: [BUILD-05]

must_haves:
  truths:
    - "Extension binary has C_STRUCT_UNSTABLE ABI footer"
    - "Extension binary exports only the entry point symbol (no ODR conflicts)"
    - "No CMakeLists.txt exists in the project (no CMake dependency)"
    - "TECH-DEBT.md documents all v0.5.0 decisions"
    - "Old branches (gsd/v0.1-milestone, feat/cpp-entry-point) are deleted"
  artifacts:
    - path: "TECH-DEBT.md"
      provides: "v0.5.0 tech debt decisions documented"
      contains: "v0.5.0"
    - path: "build/debug/semantic_views.duckdb_extension"
      provides: "Extension binary with correct ABI footer"
  key_links:
    - from: "Makefile"
      to: "build/debug/semantic_views.duckdb_extension"
      via: "cargo build + append_extension_metadata.py"
      pattern: "C_STRUCT_UNSTABLE"
---

<objective>
Verify the extension binary meets registry publication requirements (correct ABI footer, platform symbols, no CMake dependency), document all v0.5.0 technical decisions in TECH-DEBT.md, delete the old branches, and run the final test suite gate.

Purpose: Close out the v0.5.0 spike with a verified binary and documented decisions.
Output: Registry-ready binary verified, TECH-DEBT.md updated, old branches cleaned up, just test-all green.
</objective>

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

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/18-verification-and-integration/18-CONTEXT.md
@.planning/phases/18-verification-and-integration/18-RESEARCH.md
@.planning/phases/18-verification-and-integration/18-01-SUMMARY.md
@TECH-DEBT.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Verify binary format and evaluate ABI</name>
  <files></files>
  <action>
1. Ensure the extension binary is freshly built (it should be from Plan 01's test-all run, but verify):
   ```bash
   just build
   ```

2. Verify ABI footer type in the extension binary:
   ```bash
   strings build/debug/semantic_views.duckdb_extension | grep -E "C_STRUCT|CPP"
   ```
   Expected: `C_STRUCT_UNSTABLE` appears in the output.

3. Verify exported symbols (macOS):
   ```bash
   nm -gU build/debug/libsemantic_views.dylib | grep -i semantic
   ```
   Expected: Only `_semantic_views_init_c_api` exported (plus standard runtime symbols). No internal Rust symbols should be exported.

4. Verify no CMake dependency:
   ```bash
   ls CMakeLists.txt 2>/dev/null && echo "FAIL: CMake found" || echo "PASS: No CMake"
   ```
   Expected: "PASS: No CMake"

5. ABI evaluation (document findings for TECH-DEBT.md):
   - Current: `C_STRUCT_UNSTABLE` -- used because `duckdb-rs` crate relies on unstable C API functionality. The Makefile sets `UNSTABLE_C_API_FLAG=--abi-type C_STRUCT_UNSTABLE`.
   - Alternative: `CPP` ABI -- rejected in Phase 15 because `ExtensionLoader` referenced non-inlined C++ symbols not available under Python DuckDB's `-fvisibility=hidden`. CPP entry compiled but crashed at load time.
   - Recommendation: Keep `C_STRUCT_UNSTABLE`. It is functionally equivalent to CPP in version-pinning behavior, compatible with the community extension registry (rusty_quack uses the same approach), and the version pinning cost is mitigated by DuckDB Version Monitor CI.
   - Record evaluation result for use in Task 2.
  </action>
  <verify>
    <automated>strings build/debug/semantic_views.duckdb_extension | grep C_STRUCT_UNSTABLE && echo "ABI: OK" && test ! -f CMakeLists.txt && echo "CMake: OK"</automated>
  </verify>
  <done>Extension binary has C_STRUCT_UNSTABLE footer. Only entry point symbol exported. No CMake dependency. ABI evaluation complete: keep C_STRUCT_UNSTABLE.</done>
</task>

<task type="auto">
  <name>Task 2: Update TECH-DEBT.md, clean up branches, final gate</name>
  <files>TECH-DEBT.md</files>
  <action>
1. Update TECH-DEBT.md to add v0.5.0 decisions. Update the document title/date line to reflect v0.5.0. Add the following sections under "Accepted Design Decisions" (after the existing entries, continuing the numbering):

   **8. Statement rewrite approach for native DDL (not custom grammar)**
   - Origin: v0.5.0 Phase 16-17, parser extension spike
   - Decision: Native DDL (`CREATE SEMANTIC VIEW name (...)`) is implemented via DuckDB's parser hook fallback mechanism. The parse_function detects the `CREATE SEMANTIC VIEW` prefix, and the plan_function rewrites it to `SELECT * FROM create_semantic_view('name', ...)` which executes against the existing function-based DDL path. A custom SQL grammar parser was considered but deferred -- statement rewriting is simpler and reuses all existing catalog code.
   - Action: If a future milestone needs richer syntax (e.g., nested blocks, REFERENCES), a proper parser may be needed. For DDL-only statements, rewriting is sufficient.

   **9. DDL connection isolation pattern**
   - Origin: v0.5.0 Phase 17, DDL execution
   - Decision: The plan_function executes rewritten DDL SQL on a separate `duckdb_connection` created at extension init time and stored as a file-scope static in `shim.cpp`. This avoids deadlocking the main connection's ClientContext lock, which is held during the bind phase when plan_function is called.
   - Action: None needed. The pattern is safe as long as DDL is not executed concurrently (DuckDB is single-writer). If concurrent DDL becomes a requirement, a connection pool or mutex would be needed.

   **10. Amalgamation compilation via cc crate**
   - Origin: v0.5.0 Phase 15, C++ shim infrastructure
   - Decision: `duckdb.cpp` (the DuckDB amalgamation, ~23MB / ~300K lines) is compiled alongside `shim.cpp` via the `cc` crate. First build takes ~2.5 minutes; cached on subsequent builds. This provides ALL DuckDB C++ symbols (constructors, RTTI, vtables) without manual stubs. Symbol visibility restricts exports to the entry point only, preventing ODR conflicts with the host DuckDB process. The amalgamation must be version-pinned to match `TARGET_DUCKDB_VERSION`.
   - Action: The compilation cost is one-time per clean build. `build.rs` feature-gates the C++ compilation behind `CARGO_FEATURE_EXTENSION`, so `cargo test` (default features) is unaffected.

   **11. C_STRUCT_UNSTABLE ABI (evaluated, kept)**
   - Origin: v0.5.0 Phase 18, ABI evaluation
   - Decision: Evaluated switching from `C_STRUCT_UNSTABLE` to `CPP` ABI for community extension registry compatibility. Rejected: CPP entry point failed in Phase 15 because `ExtensionLoader` referenced non-inlined C++ symbols unavailable under Python DuckDB's `-fvisibility=hidden`. `C_STRUCT_UNSTABLE` pins the binary to an exact DuckDB version (same as CPP in practice). Compatible with the community extension registry (`rusty_quack` uses the same approach). The version-pinning cost is mitigated by the DuckDB Version Monitor CI workflow.
   - Action: No change. Re-evaluate if DuckDB stabilizes the C API or adds a new ABI type for mixed Rust+C++ extensions.

   Also update the document header date to 2026-03-08 and milestone reference to v0.5.0.

2. Commit TECH-DEBT.md:
   ```
   docs(18-02): document v0.5.0 technical decisions in TECH-DEBT.md
   ```

3. Delete old branches (per user decision):
   ```bash
   git branch -D gsd/v0.1-milestone
   git branch -D feat/cpp-entry-point
   ```
   Note: Do NOT delete remote branches -- only local. The user will handle remote cleanup.
   If either branch doesn't exist locally, that's fine (skip with error suppression).

4. Run the final test suite gate:
   ```bash
   just test-all
   ```
   This must pass for Phase 18 to be considered complete. All 4 test targets must succeed:
   - test-rust (cargo nextest run)
   - test-sql (sqllogictest including phase16_parser.test)
   - test-ducklake-ci (DuckLake integration)
   - test-vtab-crash (Python crash reproduction)

5. Verify `test_vtab_crash.py` specifically ran (it's now part of test-all):
   ```bash
   uv run test/integration/test_vtab_crash.py
   ```
   Expected: All 13 tests pass.
  </action>
  <verify>
    <automated>just test-all && echo "FINAL GATE: PASSED"</automated>
  </verify>
  <done>TECH-DEBT.md updated with 4 new v0.5.0 decision entries. Old branches deleted. just test-all passes (final gate). Phase 18 success criteria met.</done>
</task>

</tasks>

<verification>
- `strings build/debug/semantic_views.duckdb_extension | grep C_STRUCT_UNSTABLE` returns a match
- `nm -gU build/debug/libsemantic_views.dylib | grep semantic` shows only `_semantic_views_init_c_api`
- No `CMakeLists.txt` in project root
- TECH-DEBT.md contains sections 8-11 covering v0.5.0 decisions
- `git branch | grep -E "gsd/v0.1-milestone|feat/cpp-entry-point"` returns nothing (branches deleted)
- `just test-all` exits 0
</verification>

<success_criteria>
- BUILD-05: Extension binary has C_STRUCT_UNSTABLE footer, correct symbols, no CMake dependency
- TECH-DEBT.md documents statement rewrite, DDL connection isolation, amalgamation compilation, ABI evaluation
- Old branches deleted (gsd/v0.1-milestone, feat/cpp-entry-point)
- just test-all passes as final gate (VERIFY-01 reconfirmed)
</success_criteria>

<output>
After completion, create `.planning/phases/18-verification-and-integration/18-02-SUMMARY.md`
</output>
