---
milestone: v0.5.2
audited: 2026-03-13T20:00:00Z
status: tech_debt
scores:
  requirements: 16/16 active satisfied (6 cancelled)
  phases: 5/5 active passed (1 cancelled)
  integration: 12/12 connections wired
  flows: 4/4 E2E flows complete
gaps:
  requirements: []
  integration: []
  flows: []
cancelled_requirements:
  - id: "DDL-06"
    status: "won't-do"
    phase: "Phase 24 (cancelled)"
    reason: "Function-based create_semantic_view() retired in Phase 28; native DDL is sole interface"
  - id: "MDL-01"
    status: "won't-do (delivered implicitly)"
    phase: "Phase 24 (cancelled)"
    reason: "TableRef.pk_columns exists in model.rs — delivered via Phase 25-01 but never formally tracked"
  - id: "MDL-02"
    status: "won't-do (delivered implicitly)"
    phase: "Phase 24 (cancelled)"
    reason: "Join.from_alias/fk_columns exist in model.rs — delivered via Phase 25-01"
  - id: "MDL-03"
    status: "won't-do (delivered implicitly)"
    phase: "Phase 24 (cancelled)"
    reason: "Dimension.source_table/Metric.source_table exist — delivered via Phase 25-01"
  - id: "MDL-04"
    status: "won't-do (delivered implicitly)"
    phase: "Phase 24 (cancelled)"
    reason: "Composite PKs work — parse_tables_clause handles multi-column PRIMARY KEY"
  - id: "MDL-05"
    status: "won't-do (delivered implicitly)"
    phase: "Phase 24 (cancelled)"
    reason: "Join.name field exists in model.rs — delivered via Phase 25-01"
tech_debt:
  - phase: 24-pk-fk-model
    items:
      - "REQUIREMENTS.md: DDL-06 + MDL-01-05 still show [ ] Pending — update to reflect cancelled/won't-do status"
  - phase: 26-pk-fk-join-resolution
    items:
      - "expand.rs line 313: stale doc comment says 'CTE-wrapped' but function emits flat SELECT/FROM/JOIN"
nyquist:
  compliant_phases: ["25"]
  partial_phases: ["25.1", "26", "27", "28"]
  missing_phases: []
  cancelled_phases: ["24"]
  overall: partial
---

# Milestone v0.5.2 Audit Report

**Milestone Goal:** Replace function-call DDL body syntax with proper SQL keyword clauses (TABLES, RELATIONSHIPS, DIMENSIONS, METRICS) and adopt Snowflake-style PK/FK relationship model with table aliases, eliminating ON-clause heuristics and enabling qualified column names.

**Audited:** 2026-03-13
**Status:** TECH DEBT (no blockers, accumulated cleanup items)

---

## Phase Summary

| Phase | Name | Status | Verification | Score |
|-------|------|--------|-------------|-------|
| 24 | PK/FK Model | CANCELLED | N/A | N/A |
| 25 | SQL Body Parser | PASSED | 2026-03-12 | 13/13 |
| 25.1 | Parser Robustness & Security | PASSED | 2026-03-13 | 9/9 |
| 26 | PK/FK Join Resolution | PASSED | 2026-03-13 | 4/4 |
| 27 | Alias-Based Query Expansion | PASSED | 2026-03-13 | 5/5 |
| 28 | Integration Testing & Docs | PASSED | 2026-03-13 | 9/9 |

All 5 active phases verified with PASSED status. Phase 24 cancelled — model work absorbed into Phase 25-01.

---

## Requirements Coverage (3-Source Cross-Reference)

### Active Requirements: 16/16 Satisfied

| REQ-ID | Description | VERIFICATION.md | SUMMARY Frontmatter | REQUIREMENTS.md | Final Status |
|--------|-------------|-----------------|---------------------|-----------------|--------------|
| DDL-01 | SQL keyword body syntax | Phase 25: SATISFIED | 25-01, 25-03, 25-04 | [x] | **satisfied** |
| DDL-02 | TABLES clause parsing | Phase 25: SATISFIED | 25-02, 25-04 | [x] | **satisfied** |
| DDL-03 | RELATIONSHIPS clause parsing | Phase 25: SATISFIED | 25-02, 25-04 | [x] | **satisfied** |
| DDL-04 | DIMENSIONS clause parsing | Phase 25: SATISFIED | 25-02, 25-04 | [x] | **satisfied** |
| DDL-05 | METRICS clause parsing | Phase 25: SATISFIED | 25-02, 25-04 | [x] | **satisfied** |
| DDL-07 | All 7 DDL verbs | Phase 25: SATISFIED | 25-01, 25-03, 25-04 | [x] | **satisfied** |
| EXP-01 | FROM+JOIN expansion (no CTE) | Phase 26+27: SATISFIED | 27-01, 27-03 | [x] | **satisfied** |
| EXP-02 | JOIN ON from PK/FK | Phase 26: SATISFIED | 26-02 | [x] | **satisfied** |
| EXP-03 | Topological sort ordering | Phase 26: SATISFIED | 26-01 | [x] | **satisfied** |
| EXP-04 | Transitive join inclusion | Phase 26: SATISFIED | 26-02 | [x] | **satisfied** |
| EXP-05 | Qualified column refs | Phase 27: SATISFIED | 27-01, 27-03 | [x] | **satisfied** |
| EXP-06 | Define-time graph validation | Phase 26: SATISFIED | 26-01 | [x] | **satisfied** |
| CLN-01 | Remove struct-literal DDL parsing | Phase 27: SATISFIED | 27-02, 27-03 | [x] | **satisfied** |
| CLN-02 | Remove CTE _base flattening | Phase 26+27: SATISFIED | 27-01, 27-03 | [x] | **satisfied** |
| CLN-03 | Remove ON-clause heuristic | Phase 27: SATISFIED | 27-01, 27-03 | [x] | **satisfied** |
| DOC-01 | README with PK/FK examples | Phase 28: SATISFIED | 28-03 | [x] | **satisfied** |

### Cancelled Requirements: 6 (Phase 24)

| REQ-ID | Description | Reason | Implicitly Delivered? |
|--------|-------------|--------|----------------------|
| DDL-06 | Function DDL PK/FK params | Function DDL retired in Phase 28 | No — intentionally removed |
| MDL-01 | TableRef stores alias, table, PKs | Phase 24 cancelled; work in 25-01 | Yes — `TableRef.pk_columns` exists |
| MDL-02 | Relationships store from/to/cols | Phase 24 cancelled; work in 25-01 | Yes — `Join.fk_columns` exists |
| MDL-03 | Dims/metrics store source alias | Phase 24 cancelled; work in 25-01 | Yes — `Dimension.source_table` exists |
| MDL-04 | Composite primary keys | Phase 24 cancelled; work in 25-01 | Yes — multi-col PK parsing works |
| MDL-05 | Relationship names stored | Phase 24 cancelled; work in 25-01 | Yes — `Join.name` field exists |

### Orphaned Requirements

None. All 22 requirements in the traceability table are accounted for — 16 satisfied, 6 explicitly cancelled with rationale.

---

## Integration Check

**Cross-phase wiring:** 12/12 connections verified
**Orphaned exports:** 0
**Missing connections:** 0
**E2E flows verified:** 4/4

### E2E Flow Summary

| Flow | Path | Status |
|------|------|--------|
| Native DDL CREATE | User SQL → C++ shim → parse.rs → body_parser.rs → DefineFromJsonVTab → catalog | COMPLETE |
| Query expansion | semantic_view() → expand → RelationshipGraph → toposort → LEFT JOIN emission | COMPLETE |
| Graph validation | RELATIONSHIPS with cycle → validate_graph → define-time error | COMPLETE |
| Error caret position | DDL typo → parse error with position → C++ caret rendering | COMPLETE |

### Cross-Phase Wiring

| From | Export | To | Status |
|------|--------|----|--------|
| Phase 25 body_parser.rs | parse_keyword_body | Phase 25 parse.rs | CONNECTED |
| Phase 25 model.rs | TableRef.pk_columns, Join.fk_columns | Phase 26 expand.rs | CONNECTED |
| Phase 25 model.rs | Dimension.source_table, Metric.source_table | Phase 26 expand.rs | CONNECTED |
| Phase 25.1 parse.rs | detect_ddl_prefix | All DDL paths (5 sites) | CONNECTED |
| Phase 26 graph.rs | validate_graph | Phase 26 define.rs (both bind paths) | CONNECTED |
| Phase 26 graph.rs | RelationshipGraph, toposort | Phase 26 expand.rs | CONNECTED |
| Phase 27 expand.rs | expand() (flat SQL) | Phase 28 tests | CONNECTED |
| Phase 28 define.rs | DefineFromJsonVTab (sole VTab) | Phase 28 lib.rs (3 registrations) | CONNECTED |

---

## Tech Debt

### Documentation Cleanup

1. **REQUIREMENTS.md stale checkboxes** — DDL-06 and MDL-01 through MDL-05 still show `[ ] Pending` status. Should be updated to reflect cancelled/won't-do status with rationale.

### Code Cleanup

2. **Stale doc comment** — `src/expand.rs` line 313: doc comment says "CTE-wrapped SQL query string" but function emits flat `SELECT/FROM/LEFT JOIN`. Cosmetic only, no functional impact.

**Total:** 2 items across 2 categories. No blockers.

---

## Nyquist Compliance

| Phase | VALIDATION.md | Compliant | Action |
|-------|---------------|-----------|--------|
| 24 | exists | N/A (cancelled) | — |
| 25 | exists | true | — |
| 25.1 | exists | false (draft) | `/gsd:validate-phase 25.1` |
| 26 | exists | false (draft) | `/gsd:validate-phase 26` |
| 27 | exists | false (draft) | `/gsd:validate-phase 27` |
| 28 | exists | false (draft) | `/gsd:validate-phase 28` |

**Overall:** PARTIAL — 1/5 active phases Nyquist-compliant. Phases 25.1, 26, 27, 28 have draft VALIDATION.md files but were not validated.

---

## Quality Gate

Per CLAUDE.md, `just test-all` must pass. Phase 28 verification (most recent) confirmed:

| Suite | Result | Count |
|-------|--------|-------|
| Rust unit + proptest | PASS | 282 tests |
| SQL logic tests | PASS | 7/7 files |
| DuckLake CI | PASS | 6/6 tests |
| Python crash repro | PASS | 13/13 |
| Python caret tests | PASS | 3/3 |

---

## Conclusion

Milestone v0.5.2 achieves its definition of done:
- SQL keyword clauses (TABLES, RELATIONSHIPS, DIMENSIONS, METRICS) fully implemented and tested
- PK/FK relationship model adopted with automatic JOIN ON synthesis
- Topological sort ordering and transitive join inclusion working
- Define-time graph validation (cycles, diamonds, orphans) in place
- Function DDL retired; native DDL is sole interface
- README rewritten with AS-body PK/FK examples
- Full test suite green

No critical blockers. 2 minor tech debt items (stale docs). 4 phases pending Nyquist validation.

---

_Audited: 2026-03-13_
_Auditor: Claude (gsd-audit-milestone)_
