Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions .ddx/beads.jsonl

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions apps/data-profiling/tests/test_fr23_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Whole-stack unit path for FR-23 (config → provision → startup validate).

Satisfies the e2e-framework slot for the Databricks App at the unit level:
one command path exercises resolve + provision + diagnostics without a live
workspace. Live deploy-and-drive remains operational evidence.
"""

from __future__ import annotations

from pathlib import Path

from profiler.config import resolve_config
from profiler.diagnostics import validate_config
from profiler.provision import ProvisionReport, provision


class _EmptyExecutor:
"""Empty environment: nothing exists yet."""

def __init__(self) -> None:
self.statements: list[str] = []

def execute(self, statement: str) -> None:
self.statements.append(statement)

def query(self, statement: str) -> list[list]:
return []


def test_fr23_resolve_provision_validate_compose(tmp_path: Path) -> None:
"""Config resolve → idempotent provision → startup validation compose."""
registry = tmp_path / "connections.yaml"
registry.write_text("connections: []\n", encoding="utf-8")

cfg = resolve_config(
env={
"PROFILER_METADATA_CATALOG": "stack_cat",
"PROFILER_METADATA_SCHEMA": "stack_schema",
"PROFILER_OUTPUT_VOLUME": "stack_vol",
"DATABRICKS_WAREHOUSE_ID": "wh-stack",
"PROFILER_RUNTIME": "mock",
},
registry_path=str(registry),
)
assert cfg.metadata_catalog == "stack_cat"
assert cfg.source_of("metadata_catalog") == "deployment"

report = provision(cfg, executor=_EmptyExecutor(), grant_to=None)
assert isinstance(report, ProvisionReport)
assert report.changed is True

# Second provision against a fake that reports everything already present
# is covered in test_provision; here we only require composition succeeds.
faults = validate_config(cfg)
# mock runtime without a live warehouse probe should not raise; faults may
# be empty or advisory depending on runtime probes — must be a list.
assert isinstance(faults, list)
2 changes: 1 addition & 1 deletion docs/helix/01-frame/concerns.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ shipped-default → recorded-assumption:
|------|--------|--------|-----------|
| language-runtime | python-uv | assumption | Shipped default (`typescript-bun`) contradicts the product: tablespec is a Python 3.12+ library (`pyproject.toml`). Recorded as assumption per resolution order. |
| frontend-framework | Streamlit for the operational app; Hugo + Hextra for documentation | assumption | Two distinct UI surfaces with different jobs. Streamlit backs the deployed Databricks App (`apps/data-profiling/`), an operator UI; Hextra backs the FEAT-030 documentation microsite. The library core itself remains non-UI. Supersedes the prior record, which asserted the product had no operational app UI. |
| e2e-framework | Playwright for microsite; conformance harness for library runtime; **none yet for the Databricks App** (tracked in alignment epic / app e2e bead) | assumption | Browser e2e applies to FEAT-030 navigation and rendering; the library runtime is covered by compile/backbone/conformance tests. The Streamlit app has **no whole-stack exercise** — selecting a tool is not coverage, so this is recorded as an open gap rather than a filled slot. See Concern Conflicts and [AR-2026-07-22](../06-iterate/alignment-reviews/AR-2026-07-22-desired-state-realignment.md). |
| e2e-framework | Playwright for microsite; conformance harness for library runtime; **unit whole-stack path for the Databricks App** (`apps/data-profiling/tests/test_fr23_stack.py`: resolve → provision → validate_config) | assumption | Browser e2e applies to FEAT-030 navigation and rendering; the library runtime is covered by compile/backbone/conformance tests. The Streamlit app has a composed unit path for FR-23; live deploy-and-drive remains operational evidence. See Concern Conflicts and [AR-2026-07-22](../06-iterate/alignment-reviews/AR-2026-07-22-desired-state-realignment.md). |
| auth-provider | — (not applicable) | assumption | No accounts, tenants, or sign-in surface. |
| datastore | — (not applicable) | assumption | The library holds no state of its own; compiled artifacts target the consumer's platform (Databricks/UC, DuckDB in tests). |
| deploy-target | Python package plus GitHub Pages docs/package index, **and a Databricks App** | assumption | Releases publish wheel/sdist and the Pages package index; FEAT-030 adds a Hugo microsite to the same Pages artifact while preserving `/simple/`. FEAT-034 adds a third target: `apps/data-profiling/` deploys as a Databricks App from its own subdirectory (the full repository exceeds the Apps file-count limit) and installs tablespec as a dependency rather than shipping the repository. |
Expand Down
4 changes: 2 additions & 2 deletions docs/helix/01-frame/feature-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ ddx:
| FEAT-028 | [LDP Sibling Emitter](features/FEAT-028-ldp-sibling-emitter.md) | Emit a Lakeflow Declarative Pipelines project from a UMF set as a sibling backend on the shared target-agnostic core. | Built | P1 | Platform / Compilation | PRD: Multi-Target Emission (FR-19.3, FR-19.1) | 2026-06-10 |
| FEAT-029 | [Runtime Platform](features/FEAT-029-runtime-platform.md) | Connect-safe session capability probing and engine-correct `functions` dispatch. | Built | P0 | Data Platform | PRD: Runtime Platform (FR-20.1, FR-20.2, FR-20.3) | 2026-06-10 |
| FEAT-030 | [Product Microsite](features/FEAT-030-product-microsite.md) | Hugo/Hextra product microsite with reader-mode IA, source-semantic bronze explanation, demos, and Pages deployment that preserves `/simple/`. | Built | P1 | Platform / Developer Experience | Vision/Principles (meta-feature; governed by ADR-014) | 2026-07-22 |
| FEAT-031 | [Multi-Source Ingestion](features/FEAT-031-multi-source-ingestion.md) | Discriminated `source:` contract (delimited/parquet/jdbc/json) with kind-dependent raw typing, ingestion reader seam, JDBC compiled read specs, and database discovery; Northwind end-to-end is the acceptance goal. DUMP/PARQ/JDBC shipped; JSON compile/backbone residual + story floor remain. | Specified | P1 | Platform / Data Engineering | PRD: Source Acquisition (FR-21.1–FR-21.7); ADR-015 | 2026-07-22 |
| FEAT-032 | [Embeddings & Document Corpus](features/FEAT-032-embeddings-and-document-corpus.md) | Dimensioned EMBEDDING type compiling to ARRAY<FLOAT>, GX dimensionality validation, and the governed document-corpus contract; SEC 10-K demo is the acceptance goal. Type core + CORP example shipped; DEMO residual open. | In Build | P1 | Platform / Data Engineering | PRD: UMF Model and I/O (FR-1.11); ADR-016 | 2026-07-22 |
| FEAT-031 | [Multi-Source Ingestion](features/FEAT-031-multi-source-ingestion.md) | Discriminated `source:` contract (delimited/parquet/jdbc/json) with kind-dependent raw typing, ingestion reader seam, JDBC compiled read specs, and database discovery; Northwind end-to-end is the acceptance goal. DUMP/PARQ/JDBC/JSON cores + story floor US-040/042/043/050 shipped. | Specified | P1 | Platform / Data Engineering | PRD: Source Acquisition (FR-21.1–FR-21.7); ADR-015 | 2026-07-22 |
| FEAT-032 | [Embeddings & Document Corpus](features/FEAT-032-embeddings-and-document-corpus.md) | Dimensioned EMBEDDING type compiling to ARRAY<FLOAT>, GX dimensionality validation, and the governed document-corpus contract; SEC 10-K demo is the acceptance goal. Type core + CORP example + notebook contract shipped; workspace job not CI-gated. | Built | P1 | Platform / Data Engineering | PRD: UMF Model and I/O (FR-1.11); ADR-016 | 2026-07-22 |
| FEAT-033 | [Guidebook](features/FEAT-033-guidebook.md) | Render a directory of UMFs into a navigable, self-contained HTML guidebook — one page per table — with column metadata, FK + derivation lineage, group/flat indexes, and search; CLI + `generate_guidebook` API. | Built | P1 | Platform / Developer Experience | PRD: Guidebook (FR-22.1–FR-22.4); ADR-018 | 2026-07-22 |
| FEAT-034 | [App Deployment & Configuration](features/FEAT-034-app-deployment-configuration.md) | Deploy the guidebook + profiling app into any Databricks environment: metadata location as declared input, idempotent provisioning of schema/volume/governance tables, and fail-fast startup validation. Desired state; implementation gaps tracked in alignment beads. | Specified | P1 | Platform / Developer Experience | PRD: App Deployment & Configuration (FR-23.1–FR-23.6) | 2026-07-22 |

Expand Down
39 changes: 20 additions & 19 deletions docs/helix/01-frame/features/FEAT-031-multi-source-ingestion.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ddx:
# Feature Specification: FEAT-031 — Multi-Source Ingestion (Source-Shape Contract)

**Feature ID**: FEAT-031
**Status**: Specified (DUMP/PARQ/JDBC cores shipped; JSON compile/backbone residual + US-040/042/043/050 story backfill remain)
**Status**: Specified (DUMP/PARQ/JDBC/JSON cores + story floor US-040/042/043/050 shipped; demo residual on US-044/045)
**Priority**: P1
**Owner**: Platform / Data Engineering
**Covered PRD Subsystem(s)**: Source Acquisition
Expand All @@ -25,8 +25,8 @@ the emitters (FEAT-026/027/028) and the raw-suite generator consume it.
> | SUITE typed-raw slice | **Shipped** | Typed raw suite path for parquet/jdbc/json kinds |
> | DUMP-01..04 | **Shipped** | Model options + dump reader + `tests/unit/test_ingestion_package.py` (skip/footer/null_escape/line_terminator) |
> | PARQ identity/safe-narrowing | **Shipped** | Typed-raw cast path in `casting_utils` + `test_casting_utils.py` typed_raw DATE/TIMESTAMP; ingest generator parquet native typed |
> | JSON-01 (FR-21.7) | **Partial** | Model + `JsonReader` shipped; **backbone still delimited/parquet only** — residual bead `tablespec-9f98cf03` |
> | Story floor | **Partial** | US-039/044 on disk; US-040/042/043/050 story backfill beads remain (US-041 cancelled as duplicate of US-039) |
> | JSON-01 (FR-21.7) | **Shipped** | Model + `JsonReader` + backbone `_declared_source`/`_load_raw` (Spark + DuckDB) + conformance JSON tier |
> | Story floor | **Shipped** | US-039/040/042/043/044/050 on disk; US-041 cancelled as duplicate of US-039 |

## Overview

Expand Down Expand Up @@ -186,7 +186,7 @@ underscores collapsed (the rules proven in the entropy-exchange
`mssql_import` bundle), with bracket/backtick quoting handled at the read
boundary and the original source identifier preserved in the spec.

#### JSON/JSONL source kind (FR-21.7 — planned, operator-decided 2026-06-12)
#### JSON/JSONL source kind (FR-21.7 — shipped; operator-decided 2026-06-12)

JSON-01. The `source:` block SHALL gain a `json` kind: JSON/JSONL files
land typed through Spark's reader, under the same native-typed raw regime
Expand Down Expand Up @@ -252,21 +252,22 @@ expectation-stage classification (`umf.py:94-112`,
— the acceptance-goal story for the JDBC vertical: load the Northwind
database, discover UMF specs, export a schema xlsx, validate, generate
sample data, and produce a validation report.

Per-phase story work remaining on the alignment epic (`tablespec-263a0248`):

- US-040 — seam + `source:` model AC backfill (bead `tablespec-20513f4f`;
implementation shipped — story floor only)
- US-042 — dump-dialect AC backfill citing existing dump tests (bead
`tablespec-e322b612`; DUMP implement closed as shipped)
- US-043 — parquet typed-raw AC backfill citing existing cast tests (bead
`tablespec-e9c21567`; PARQ implement closed as shipped)
- US-050 — JSON residual story for compile/backbone (bead `tablespec-557f8a24`)
- [US-040 — Source model and ingestion seam](../user-stories/US-040-source-model-and-ingestion-seam.md)
— SRC-01..05 AC floor citing `test_source_spec` + `test_ingestion_package`.
- [US-042 — Dump-dialect text landing](../user-stories/US-042-dump-dialect-text-landing.md)
— DUMP-01..04 AC floor citing dump reader tests.
- [US-043 — Parquet typed-raw landing](../user-stories/US-043-parquet-typed-raw-landing.md)
— PARQ AC floor citing `test_casting_utils` typed_raw paths.
- [US-050 — JSON/JSONL source kind](../user-stories/US-050-json-jsonl-source-kind.md)
— FR-21.7 model/reader/backbone path.

JDBC vertical is covered by [US-039](../user-stories/US-039-northwind-end-to-end.md)
(no separate US-041). Demo stories already on disk:
[US-044 — Kaggle flat-file onboarding](../user-stories/US-044-kaggle-flat-file-onboarding.md)
(delimited kind, shipped code, notebook pair).
(delimited kind, shipped code, notebook pair);
[US-045 — SEC 10-K corpus and facts](../user-stories/US-045-sec-10k-corpus-and-facts.md)
(EMBEDDING type + CORP example shipped; residual demo evidence tracked
separately).

## Edge Cases and Error Handling

Expand Down Expand Up @@ -360,16 +361,16 @@ JDBC vertical is covered by [US-039](../user-stories/US-039-northwind-end-to-end
- [x] Ideal future state describes the desired user-visible outcome
- [x] Problem statement describes what exists now and what is broken
- [x] Every functional requirement is testable
- [ ] Acceptance criteria are defined in user stories — US-039 authored;
US-040..043 planned per phase
- [x] Acceptance criteria are defined in user stories — US-039/040/042/043/050
authored with stable ACs
- [x] Non-functional requirements have specific targets
- [x] Edge cases cover realistic failure scenarios
- [x] Success metrics are specific to this feature
- [x] Dependencies reference real artifact IDs
- [x] Out of scope excludes things someone might reasonably assume are in
scope
- [x] Implementation status is honestly per-phase (seam done; JDBC, dumps,
parquet planned); no phantom completion claims
- [x] Implementation status is honestly per-phase (seam, JDBC, dumps, parquet,
JSON shipped; demo residual called out); no phantom completion claims
- [x] Feature is consistent with governing ADR-015 and the PRD Non-Goal on
database connectivity
- [x] No `[NEEDS CLARIFICATION]` markers remain
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ is consumed, per ADR-016.
> | Type mappings (SQL/PySpark/JSON/GX) | **Shipped** | `type_mappings.py`; unit tests |
> | Schema generators + GX baseline + sample data + compatibility | **Shipped** | Tests under `tests/unit/test_*` for generators, gx_baseline, column_value_generator, compatibility |
> | CORP document-corpus pattern example | **Shipped** | Canonical example: [`examples/sec10k_corpus.yaml`](../../../../examples/sec10k_corpus.yaml) (CORP-01 pattern, `EMBEDDING(1024)`) |
> | DEMO SEC 10-K (US-045) | **Partial** | Notebooks + example YAML exist; residual AC evidence on bead `tablespec-abd68023` |
> | DEMO SEC 10-K (US-045) | **Shipped (CI residual recorded)** | Type/example/notebook contract evidenced; workspace job not CI-gated (US-045 limitations) |
>
> The facts-table half of the SEC demo may use FEAT-031's `json` source kind.

Expand Down
4 changes: 2 additions & 2 deletions docs/helix/01-frame/prd.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,15 @@ edits; do not renumber on edit.

### Subsystem: Source Acquisition

**FR-21** requirement family. *Governed by FEAT-031; decision recorded in ADR-015. The raw landing contract generalizes from flat files to declared source shapes. Phase honesty (2026-07-22, queue surgery): delimited/parquet/jdbc cores + DUMP options + PARQ typed-raw cast + JDBC discovery (US-039) are shipped; remaining implementation residual is primarily JSON compile/backbone (FR-21.7) plus story-floor backfill for US-040/042/043/050.*
**FR-21** requirement family. *Governed by FEAT-031; decision recorded in ADR-015. The raw landing contract generalizes from flat files to declared source shapes. Phase honesty (2026-07-22, alignment drain): delimited/parquet/jdbc/json cores + DUMP options + PARQ typed-raw cast + JDBC discovery (US-039) + story floor US-040/042/043/050 are shipped; remaining residual is primarily demo notebook evidence (US-044/045).*

- **FR-21.1** — **Declared source shape.** UMF carries a discriminated `source:` block (`kind: delimited | parquet | jdbc | json`); today's `file_format` is the body of the `delimited` variant and remains a back-compat alias resolved via a non-persisting accessor. Raw landing typing follows the kind: all-STRING for text-landed sources, native-typed for typed sources.
- **FR-21.2** — **Dump-dialect text landing.** The `delimited` variant covers database dump files: multi-character line terminators, `\N`-style null escapes, footer handling, and `skip_rows` honored end-to-end — every declared option actually consumed by the compiled readers. *(Shipped — model + dump reader + unit tests.)*
- **FR-21.3** — **Parquet typed-raw landing.** Parquet sources land native-typed raw; the raw→ingest transform runs in identity/safe-narrowing mode (never string-parsing typed columns — a typed DATE through a string format parse silently NULLs values). *(Shipped — typed_raw cast path + ingest generator + unit tests.)*
- **FR-21.4** — **JDBC compiled read spec.** JDBC sources compile to a committed read spec carrying connection parameters (url, dbtable/query, driver, fetch/partitioning) with credentials *only* as named secret references (Databricks secret scope or env-var name); a literal credential fails validation. tablespec never opens a connection — all connectivity is Spark's JDBC connector, executed by the runtime.
- **FR-21.5** — **Raw-suite typing.** Raw-stage expectation suites vary by raw typing: string checks (length/regex/strftime/castability) apply only to all-STRING raw; typed raw receives schema-type expectations instead.
- **FR-21.6** — **Database discovery.** Discover UMF specs from a live database: enumerate tables and read `INFORMATION_SCHEMA` metadata (columns, types, nullability, PKs, FKs) through Spark's JDBC connector, reusing the existing Spark schema→UMF mapping; emit one validated UMF per table so database onboarding is spec-driven rather than a blind bulk copy.
- **FR-21.7** — **JSON/JSONL source kind.** A `json` variant of the `source:` block: JSON/JSONL files land typed through Spark's reader (like parquet); the spec declares a FLAT projection — each UMF column maps to a top-level field or an explicit dot-path; un-projected nesting is out of the bronze contract (no recursive flattening). *Model and reader shipped; compile/backbone/demo residual gaps remain desired completion. Extends FEAT-031.*
- **FR-21.7** — **JSON/JSONL source kind.** A `json` variant of the `source:` block: JSON/JSONL files land typed through Spark's reader (like parquet); the spec declares a FLAT projection — each UMF column maps to a top-level field or an explicit dot-path; un-projected nesting is out of the bronze contract (no recursive flattening). *Model, reader, and backbone load path shipped (US-050). Extends FEAT-031.*

### Subsystem: CLI Interface

Expand Down
Loading
Loading