---
phase: 65.1-phase-65-code-review-remediation
plan: 10
type: execute
wave: 4
depends_on:
  - 65.1-02b
  - 65.1-08
files_modified:
  - cpp/src/shim.cpp
autonomous: true
requirements:
  - REM-WR-06

must_haves:
  truths:
    - "A file-scope `static_assert(sizeof(duckdb_connection) == sizeof(void*), ...)` exists near the top of `cpp/src/shim.cpp` with a message referencing the BORROW contract and 65-REVIEW.md WR-06"
    - "A runtime probe inside `sv_register_parser_hooks` (or its callee) constructs a `Connection probe(*wrapper->database->instance)`, reinterpret_casts to `duckdb_connection`, and round-trips `SELECT 1` via `duckdb_query`"
    - "Probe failure writes a clear `bridge contract broken — duckdb_connection layout assumption failed at load time...` message into the WR-02 `error_buf` and returns `false`"
    - "`sv_register_parser_hooks` signature carries the `error_buf` / `error_buf_len` pair (consistent with WR-02 Plan 02)"
  artifacts:
    - path: cpp/src/shim.cpp
      provides: "static_assert + load-time runtime probe in sv_register_parser_hooks"
      contains: "static_assert(sizeof(duckdb_connection)"
  key_links:
    - from: cpp/src/shim.cpp::sv_register_parser_hooks
      to: cpp/src/shim.cpp::error_buf surfacing (Plan 02)
      via: "probe-failure write_err using the same error_buf channel"
      pattern: "bridge contract broken"
---

<objective>
Pin the BORROW-contract bridge (`reinterpret_cast<duckdb_connection>(Connection*)` used at ~20 sites in `cpp/src/shim.cpp`) with two complementary guards per CONTEXT D-12:

1. **Compile-time `static_assert`** at file scope near the top of `cpp/src/shim.cpp`:
   ```
   static_assert(sizeof(duckdb_connection) == sizeof(void*),
       "duckdb_connection must be pointer-sized — bridge contract broken; "
       "see cpp/src/shim.cpp BORROW contract docs and 65-REVIEW.md WR-06");
   ```
   This catches DuckDB ABI drift that changes the size of `duckdb_connection`.

2. **Runtime probe at extension load** at the TOP of `sv_register_parser_hooks` (after the wrapper unwrap, before any user-visible state mutation). Construct a `Connection probe`, bridge-cast it, run `duckdb_query(handle, "SELECT 1", &r)`. On failure, write a clear error message into the WR-02 `error_buf` (which Plan 02 added to `sv_register_parser_hooks`'s signature) and return false. This catches representation drift that the static_assert would miss (e.g. `duckdb_connection->internal_ptr` wrapping).

Per CONTEXT D-13: probe failure surfaces through the WR-02 error-buffer mechanism (no separate channel).

Wave 3 because:
- Depends on Plan 02 (WR-02 error_buf in `sv_register_parser_hooks` is the surfacing channel)
- Depends on Plan 08 (CR-02 cleanup in shim.cpp lands first to minimise diff conflict)

Implements D-12, D-13 (WR-06).
</objective>

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

<context>
@.planning/PROJECT.md
@.planning/STATE.md
@.planning/phases/65.1-phase-65-code-review-remediation/65.1-CONTEXT.md
@.planning/phases/65.1-phase-65-code-review-remediation/65.1-RESEARCH.md
@.planning/phases/65.1-phase-65-code-review-remediation/65.1-PATTERNS.md
@cpp/src/shim.cpp
@cpp/include/duckdb.hpp
</context>

<interfaces>
Existing wrapper unwrap pattern (cpp/src/shim.cpp:2469-2471 — used by sv_register_parser_hooks):
```
auto *wrapper = reinterpret_cast<duckdb::DatabaseWrapper *>(db_handle->internal_ptr);
auto &db = *wrapper->database->instance;
```

Target runtime probe (PATTERNS.md lines 229-246):
```
{
    Connection probe(db);
    auto handle = reinterpret_cast<duckdb_connection>(&probe);
    duckdb_result r;
    auto rc = duckdb_query(handle, "SELECT 1", &r);
    if (rc != DuckDBSuccess) {
        snprintf(error_buf, error_buf_len,
            "bridge contract broken — duckdb_connection layout assumption failed at load time. "
            "DuckDB ABI may have changed; refusing to load semantic_views extension.");
        return false;
    }
    duckdb_destroy_result(&r);
}
```

The Connection class is defined at `cpp/include/duckdb.hpp:42284-42297` — `explicit Connection(DatabaseInstance &database)` is the ctor we use.
</interfaces>

<tasks>

<task type="auto">
  <name>Task 1: Add file-scope static_assert and load-time runtime probe</name>
  <read_first>
    - cpp/src/shim.cpp lines 1-100 (file header + namespace setup + extern "C" block — find a clean file-scope location for the static_assert)
    - cpp/src/shim.cpp lines 2460-2545 (sv_register_parser_hooks — entry point + wrapper unwrap pattern at ~2469-2471)
    - cpp/src/shim.cpp post-Plan-02 signature of sv_register_parser_hooks (must already carry `error_buf, error_buf_len` from WR-02 work)
    - .planning/phases/65.1-phase-65-code-review-remediation/65.1-PATTERNS.md lines 209-246 (target shape for both guards)
    - .planning/phases/65.1-phase-65-code-review-remediation/65.1-RESEARCH.md lines 483-531 (full WR-06 design + Connection class signature notes)
    - cpp/include/duckdb.hpp lines 42284-42297 (Connection ctor verification)
  </read_first>
  <files>cpp/src/shim.cpp</files>
  <action>
1. **Static_assert (compile-time guard)** — add at file scope, near the top of `cpp/src/shim.cpp` (just after the `using namespace duckdb;` directive OR just after the `extern "C"` block of FFI declarations — pick whichever location is clean and visible to the build):
   ```
   static_assert(sizeof(duckdb_connection) == sizeof(void*),
       "duckdb_connection must be pointer-sized — bridge contract broken; "
       "see cpp/src/shim.cpp BORROW contract docs and 65-REVIEW.md WR-06 / Phase 65.1 D-12");
   ```

2. **Runtime probe** — locate `sv_register_parser_hooks` (around line 2465-2544). Verify it now carries `char *error_buf, size_t error_buf_len` parameters from Plan 02. If not, halt and surface — this plan's design depends on Plan 02 having landed.

3. After the existing wrapper unwrap at lines ~2469-2471 (`auto *wrapper = ...; auto &db = *wrapper->database->instance;`), insert the runtime probe block from `<interfaces>` above. Use the unwrapped `db` reference for `Connection probe(db);`.

4. The probe must run BEFORE any user-visible state mutation (i.e. before the `ParserExtension::Register` call and before any catalog function registration). The point of failing fast: if the bridge is broken, no semantic_views state survives the failed LOAD.

5. Probe failure path:
   - `snprintf(error_buf, error_buf_len, "bridge contract broken — duckdb_connection layout assumption failed at load time. DuckDB ABI may have changed; refusing to load semantic_views extension.");`
   - Guard `error_buf == nullptr || error_buf_len == 0` before snprintf (defensive).
   - `return false;` — Plan 02's caller-side error_buf parser will surface this in the user's LOAD error message.

6. Probe success path:
   - `duckdb_destroy_result(&r);` to release the result.
   - The `Connection probe` destructor runs on scope exit; the bridged `handle` becomes invalid but is not touched again.
   - Execution continues into the existing parser-extension registration body.

7. DO NOT change any other part of `sv_register_parser_hooks`. WR-09 (parser-hook idempotence) is Plan 12; that work depends on this plan landing first.

8. Build + run all tests; this change should be transparent (the probe succeeds on every supported platform).
  </action>
  <verify>
    <automated>just build &gt; /tmp/claude/p10_t1_build.log 2>&amp;1; RC=$?; tail -50 /tmp/claude/p10_t1_build.log; test $RC -eq 0 &amp;&amp; grep -nE "static_assert\\(sizeof\\(duckdb_connection\\)" cpp/src/shim.cpp &amp;&amp; grep -nE "bridge contract broken" cpp/src/shim.cpp &amp;&amp; just test-sql &gt; /tmp/claude/p10_t1_sql.log 2>&amp;1; RC2=$?; tail -40 /tmp/claude/p10_t1_sql.log; test $RC2 -eq 0</automated>
  </verify>
  <acceptance_criteria>
    - `grep -nE "static_assert\\(sizeof\\(duckdb_connection\\)" cpp/src/shim.cpp` returns exactly one match at file scope
    - The static_assert message references both "BORROW contract" and "WR-06" or "Phase 65.1"
    - `grep -nE "bridge contract broken" cpp/src/shim.cpp` returns exactly one match (inside sv_register_parser_hooks)
    - The runtime probe creates a `Connection probe(...)`, reinterpret_casts to `duckdb_connection`, calls `duckdb_query(... "SELECT 1" ...)`, checks the return code, and destroys the result
    - `sv_register_parser_hooks` carries `(char *error_buf, size_t error_buf_len)` (verify Plan 02 dependency met)
    - `just build` exits 0
    - `just test-sql` exits 0 — extension still loads cleanly across all test scenarios
    - `just test-all` exits 0
  </acceptance_criteria>
  <done>WR-06 closed: bridge contract pinned by compile-time + runtime guards; probe failure surfaces via WR-02 error_buf.</done>
</task>

</tasks>

<threat_model>
## Trust Boundaries

| Boundary | Description |
|----------|-------------|
| DuckDB amalgamation ABI ↔ shim BORROW cast | `reinterpret_cast<duckdb_connection>(Connection*)` assumes layout equivalence |

## STRIDE Threat Register

| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-65.1-10-01 | Tampering | DuckDB minor-version bump changes `duckdb_connection` size | mitigate | `static_assert` catches at compile time (D-12 compile-time guard) |
| T-65.1-10-02 | Tampering | DuckDB minor-version bump changes representation (e.g. wrap pointer in struct) | mitigate | Runtime probe round-trips SELECT 1 via the cast handle; failure refuses extension load (D-12 runtime probe) |
| T-65.1-10-03 | Denial of service | Probe spuriously fails | accept | Probe is identical to the bind callbacks' bridge cast; if it fails, the entire extension's read path is unusable — failing LOAD is the right disposition (D-13) |
</threat_model>

<verification>
  <automated>just test-all &gt; /tmp/claude/p10_all.log 2>&amp;1; RC=$?; tail -100 /tmp/claude/p10_all.log; test $RC -eq 0 &amp;&amp; just ci &gt; /tmp/claude/p10_ci.log 2>&amp;1; RC2=$?; tail -40 /tmp/claude/p10_ci.log; test $RC2 -eq 0</automated>
</verification>

<success_criteria>
- File-scope `static_assert` on `sizeof(duckdb_connection)` present in shim.cpp
- Runtime probe at top of `sv_register_parser_hooks` (post wrapper unwrap, pre any state mutation)
- Probe failure writes "bridge contract broken — ..." into WR-02 error_buf and returns false
- `just test-all` AND `just ci` both green
</success_criteria>

<output>
Create `.planning/phases/65.1-phase-65-code-review-remediation/65.1-10-SUMMARY.md` when done.
</output>
