bsl-semanticlisted
Install: claude install-skill petermcalister/shared-skills
# BSL — Boring Semantic Layer
The **Boring Semantic Layer** is a deliberately-restrictive way to describe a table
for LLM/analytics consumption: instead of letting an agent write arbitrary SQL, you
declare a table's **dimensions** (how you slice), **measures** (what you aggregate),
**time dimension** (the timestamp + its grain), **primary key / grain**, and **joins**.
The agent then issues *structured* `.query(dimensions=…, measures=…, filters=…)` calls
that compile to safe SQL. The tight constraint is what makes it correct for agents.
| Concept | What it is | Example |
|---|---|---|
| **Dimension** | A categorical / group-by field | `category`, `counterparty`, `direction` |
| **Measure** | An aggregation | `total_spend = SUM(...)`, `row_count = COUNT(*)` |
| **Time dimension** | A timestamp column + its grain | a date column at `TIME_GRAIN_DAY` |
| **Grain** | What one row represents | "one row per transaction" |
| **Join** | A declared relationship to another model | this table → `<fk_table>` via a key column |
---
## Workspace adapter — read this FIRST
This skill is **workspace-agnostic**. Everything project-specific — which schemas/tables
to model, where the JSON contract lives, and the commands that draft and apply comment
migrations — comes from an **optional** per-workspace config.
**On invocation, read `.claude/skill-workspace.json`.** If it exists and has a
`"bsl-semantic"` block, use those values (the *configured* path). If it is absent or
lacks that block, op