---
phase: 65.1-phase-65-code-review-remediation
plan: 06
type: execute
wave: 6
depends_on:
  - 65.1-02a
  - 65.1-02b
  - 65.1-03a
  - 65.1-03b
  - 65.1-04
  - 65.1-05
  - 65.1-07
  - 65.1-08
  - 65.1-09
  - 65.1-10
  - 65.1-11
  - 65.1-12
files_modified:
  - CHANGELOG.md
autonomous: true
requirements:
  - REM-CHG

must_haves:
  truths:
    - "`CHANGELOG.md` `## [Unreleased]` section contains entries categorised per Keep-a-Changelog 1.1.0: Security, Changed, Fixed, Removed"
    - "CR-01 entry under `### Security` (SQL-injection elimination via FileSystem API)"
    - "WR-07 + WR-08 entries under `### Changed` (silent fallback → hard error — user-visible behaviour change)"
    - "WR-03, WR-02, WR-09, CR-02 entries under `### Fixed`"
    - "IN-02 + IN-03 entries under `### Removed`"
    - "No `Phase 65 …` or workstream/chronology subheadings — bullets land under the standard categories only (per CLAUDE.md Format rules)"
  artifacts:
    - path: CHANGELOG.md
      provides: "Updated `## [Unreleased]` section with 5 categorised entries"
      contains: "### Security"
  key_links:
    - from: CHANGELOG.md
      to: docs/changelog.md
      via: "MyST include — Unreleased renders verbatim on docs site Release Notes"
      pattern: "Unreleased"
---

<objective>
Populate the `## [Unreleased]` section of `CHANGELOG.md` with categorised entries covering every behaviour-affecting finding remediated in Phase 65.1. Per CONTEXT D-27 + CLAUDE.md milestone rules + Keep-a-Changelog 1.1.0:
- `### Security` — CR-01 SQL-injection elimination
- `### Changed` — WR-07 + WR-08 silent-fallback → hard error (user-visible)
- `### Fixed` — WR-03 wording, WR-02 surfacing, WR-09 idempotence, CR-02 emit-fallback removal
- `### Removed` — IN-02 + IN-03 dead-code purge

This plan owns CHANGELOG entries for THE SET of findings that touch user-visible surface area. Pure internal cleanups with no behaviour change (IN-04 helper-TF arg trim, IN-05 sqllogictest additions, IN-06 dedup, the BorrowedConnection newtype) do NOT get CHANGELOG entries — they ship silently.

**B-08 fix per plan-checker:** This plan now runs in the LAST wave (Wave 6, after every implementing plan). Writing CHANGELOG entries before the implementation lands risks documenting a behaviour change that diverges from what shipped — the plan-checker flagged this as B-08. Moving Plan 06 to the final wave means the entries describe the actually-committed state. The plan still touches only `CHANGELOG.md` and is a single-task plan, just sequenced after all implementing plans (02a/02b/03a/03b/04/05/07/08/09/10/11/12) have landed.

Per CLAUDE.md: keep `## [Unreleased]` separate from the most recent tagged version. Phase 66 milestone-finisher will fold these entries into `## [0.10.0]` at tag time.

Implements D-27 (CHANGELOG strategy).
</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
@CHANGELOG.md
@CLAUDE.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Populate CHANGELOG.md ## [Unreleased] with categorised Phase 65.1 entries</name>
  <read_first>
    - CHANGELOG.md (current state of the `## [Unreleased]` section AND the most recent tagged version `## [0.9.0]` for tone/audience reference)
    - CLAUDE.md (Milestone Completion section — exact Keep-a-Changelog 1.1.0 format rules; allowed subheadings; "Audience" guidance to avoid GSD/phase-internal vocabulary)
    - .planning/phases/65.1-phase-65-code-review-remediation/65.1-RESEARCH.md lines 770-789 (the exact wording template for each entry)
    - .planning/phases/65.1-phase-65-code-review-remediation/65.1-PATTERNS.md lines 766-783 (subheading-order summary + wording template repeated)
    - .planning/phases/65.1-phase-65-code-review-remediation/65.1-CONTEXT.md (D-27 + the finding-by-finding decision text — source of truth for what each entry should say)
  </read_first>
  <files>CHANGELOG.md</files>
  <action>
1. Open `CHANGELOG.md`. Locate the `## [Unreleased]` section near the top (CLAUDE.md confirms it always exists between milestones).

2. If the current state reads `_No unreleased changes yet._` (or any similar placeholder), replace it with the new structured content. If `## [Unreleased]` already has entries from earlier in v0.10.0 work (e.g. from Phase 65), preserve them and ADD the new Phase 65.1 entries to the appropriate subheadings — do not clobber.

3. The target shape (subheadings in Keep-a-Changelog order: Added / Changed / Deprecated / Removed / Fixed / Security — only emit subheadings that have content):

```markdown
## [Unreleased]

### Changed
- `semantic_view(...)` and the `SHOW`/`DESCRIBE` family now raise a clear `Binder Error` when DuckDB's column-type inference fails at bind time (previously fell back to `VARCHAR` or `DECIMAL(18,3)` silently). If your query was previously succeeding with the wrong column type, it will now fail with the underlying error message — typically a missing table or permissions issue in the expanded SQL.

### Removed
- Internal `type_cache` module and `type_id_to_display_name` helper — both were unused after the read-side rebuild in v0.10.0 Phase 65.

### Fixed
- `DROP SEMANTIC VIEW` and `ALTER SEMANTIC VIEW` on a read-only database that was never bootstrapped now report `semantic view 'X' does not exist` (previously surfaced the lower-level `Catalog Error: Table _definitions does not exist`).
- Extension-load registration failures now surface the underlying DuckDB exception message in the user-visible error (previously dropped on the floor with a generic "Failed to register X" message).
- `LOAD semantic_views` is now idempotent — repeat loads no longer accumulate parser-extension hooks in `DBConfig`.
- Removed defensive single-shot fallback branches in four table-function exec callbacks that would have produced unbounded row streams if local state was ever absent. Registration now refuses table-function callbacks without an `init_local`.

### Security
- Eliminated SQL-injection surface in the `CREATE SEMANTIC VIEW v FROM YAML FILE '<path>'` helper. The path argument is now read via DuckDB's `FileSystem` API directly, removing the `SELECT content FROM read_text('...')` indirection that relied on quote-doubling.
```

4. **Wording discipline (per CLAUDE.md):**
   - User-facing terms only — no "WR-02", "Plan 12", "Phase 65.1", or "STRIDE" jargon in the bullets
   - Avoid `Phase 65 — ...` subheadings entirely (CLAUDE.md explicitly bans these)
   - If a future revision must add an entry, append it to the relevant subheading, never reorder

5. **Preserve the bottom-of-file link references.** Do not modify the `[Unreleased]: ...compare/...HEAD` reference link — Phase 66 milestone-finisher updates that to point at v0.10.0 at tag time.

6. **Sanity grep checks before commit** (run after editing):
   - `grep -c "^### Security" CHANGELOG.md` — at least 1 (Phase 65.1 contributes one)
   - `grep -c "^### Changed" CHANGELOG.md` — at least 1
   - `grep -c "^### Fixed" CHANGELOG.md` — at least 1
   - `grep -c "^### Removed" CHANGELOG.md` — at least 1
   - `grep -E "(Phase 65|WR-0|CR-0|IN-0|D-2)" CHANGELOG.md | grep -v "^\\[" | head -5` should return zero matches in the bullets (the link-reference block at the bottom may contain version names, but bullet text must be clean)
  </action>
  <verify>
    <automated>grep -n "^## \\[Unreleased\\]" CHANGELOG.md &amp;&amp; grep -n "^### Security" CHANGELOG.md &amp;&amp; grep -n "^### Changed" CHANGELOG.md &amp;&amp; grep -n "^### Fixed" CHANGELOG.md &amp;&amp; grep -n "^### Removed" CHANGELOG.md &amp;&amp; ! grep -E "(WR-0|CR-0|IN-0|Phase 65)" CHANGELOG.md | grep -v "^\\["</automated>
  </verify>
  <acceptance_criteria>
    - `## [Unreleased]` section exists at the top of CHANGELOG.md (above any tagged version section)
    - Section contains `### Security`, `### Changed`, `### Fixed`, `### Removed` subheadings (in Keep-a-Changelog order)
    - Bullets contain no GSD vocabulary (`WR-02`, `Phase 65`, `D-21`, etc.) — verify with grep
    - Bottom-of-file link reference `[Unreleased]: ...compare/<latest-tag>...HEAD` unchanged
    - The Security entry mentions `FileSystem` API and the `FROM YAML FILE` helper
    - The Changed entry mentions both `Binder Error` and the silent-fallback behaviour shift (VARCHAR / DECIMAL(18,3))
    - All four Fixed entries map 1:1 to the findings (WR-03 wording, WR-02 surfacing, WR-09 idempotence, CR-02 emit-fallback)
    - Removed entry names `type_cache` and `type_id_to_display_name`
  </acceptance_criteria>
  <done>CHANGELOG `## [Unreleased]` carries 5 user-visible entries for Phase 65.1 in Keep-a-Changelog format; no GSD vocabulary leaked.</done>
</task>

</tasks>

<verification>
  <automated>grep -q "FileSystem" CHANGELOG.md &amp;&amp; grep -q "Binder Error" CHANGELOG.md &amp;&amp; grep -q "type_cache" CHANGELOG.md &amp;&amp; grep -q "idempotent" CHANGELOG.md</automated>
</verification>

<success_criteria>
- `## [Unreleased]` populated with 5 user-visible entries categorised correctly
- No GSD/phase vocabulary in bullets
- Bottom link references unchanged
- File is well-formed Keep-a-Changelog 1.1.0 markdown
</success_criteria>

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