@malloy-publisher/skills 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/skills/malloy/SKILL.md +1 -1
  3. package/skills/malloy-analysis/SKILL.md +1 -1
  4. package/skills/malloy-analysis-pitfalls/SKILL.md +1 -1
  5. package/skills/malloy-analysis-report/SKILL.md +2 -2
  6. package/skills/malloy-analyze/SKILL.md +1 -1
  7. package/skills/malloy-charts/SKILL.md +1 -1
  8. package/skills/malloy-dashboards/SKILL.md +1 -1
  9. package/skills/malloy-debug/SKILL.md +9 -6
  10. package/skills/malloy-define/SKILL.md +1 -1
  11. package/skills/malloy-discover/SKILL.md +1 -1
  12. package/skills/malloy-document/SKILL.md +1 -1
  13. package/skills/malloy-getting-started/SKILL.md +51 -1
  14. package/skills/malloy-gotchas-modeling/SKILL.md +42 -2
  15. package/skills/malloy-gotchas-queries/SKILL.md +1 -1
  16. package/skills/malloy-gotchas-rendering/SKILL.md +1 -1
  17. package/skills/malloy-html-data-app-embedding/SKILL.md +1 -1
  18. package/skills/malloy-html-data-app-runtime/SKILL.md +1 -1
  19. package/skills/malloy-html-data-apps/SKILL.md +1 -1
  20. package/skills/malloy-lookml-review/SKILL.md +1 -1
  21. package/skills/malloy-lookml-review/reference/_concepts.md +1 -1
  22. package/skills/malloy-lookml-review/reference/build-derived-tables.md +5 -3
  23. package/skills/malloy-materialization/SKILL.md +19 -4
  24. package/skills/malloy-materialization-tuning/SKILL.md +1 -1
  25. package/skills/malloy-model/SKILL.md +4 -2
  26. package/skills/malloy-model-as-you-go/SKILL.md +1 -1
  27. package/skills/malloy-modeling/SKILL.md +1 -1
  28. package/skills/malloy-notebook-chat/SKILL.md +2 -2
  29. package/skills/malloy-notebooks/SKILL.md +1 -1
  30. package/skills/malloy-patterns/SKILL.md +1 -1
  31. package/skills/malloy-phrase-detection/SKILL.md +1 -1
  32. package/skills/malloy-publish/SKILL.md +1 -1
  33. package/skills/malloy-queries/SKILL.md +1 -1
  34. package/skills/malloy-review/SKILL.md +1 -1
  35. package/skills/malloy-review/reference/rubric-structure.md +1 -1
  36. package/skills/malloy-scope/SKILL.md +1 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/skills",
3
3
  "description": "Agent skills for Malloy and the Malloy Publisher",
4
- "version": "0.1.10",
4
+ "version": "0.1.12",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy
3
3
  description: Index of all Malloy skills. Use when user asks "malloy help", "what malloy skills are available", "how do I use malloy", or needs guidance on which Malloy skill to use.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-analysis
3
3
  description: Workflow for answering data questions against Malloy semantic models over MCP - structured discovery with get_context, query construction with execute_query, verification, and answer delivery. Use whenever the user asks a data question, wants a metric, a breakdown, a trend, or a chart over a model.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-analysis-pitfalls
3
3
  description: Common data analysis pitfalls to watch for during query construction and result interpretation. Reference this checklist when verifying queries and results to catch errors before presenting an answer.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-analysis-report
3
3
  description: Combine validated Malloy queries into a notebook report or dashboard. Use when the user asks to "create a report", "build a dashboard", "combine these into a report", or wants a persistent multi-query artifact.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -24,7 +24,7 @@ Do NOT build the notebook in the same turn as `execute_query`. Explain first, th
24
24
 
25
25
  ## Filters are inherited from the model, don't declare them in the report
26
26
 
27
- Reports do not (and cannot) define their own filters. If the source declares `given:` parameters (or legacy `#(filter)` annotations), Publisher renders the controls, parses caller parameters, and applies them server-side automatically: the report inherits and displays them with no extra work. If the analysis needs a knob the source doesn't expose, the right move is to add a `given:` to the source itself, not to wedge a filter widget into the report. `#(filter)` is deprecated in favour of native Malloy `given:` parameters. Do not add new `#(filter)` annotations; the two exceptions are `required` and `implicit`, which `given:` cannot cover yet. See `skill:malloy-model` § Legacy: Parameterizable Filters. For curated notebooks with their own per-notebook filter UI on top of the model, see `skill:malloy-notebooks` instead.
27
+ Reports do not (and cannot) define their own filters. If the source declares `given:` parameters (or legacy `#(filter)` annotations), Publisher renders the controls, parses caller parameters, and applies them server-side automatically: the report inherits and displays them with no extra work. If the analysis needs a knob the source doesn't expose, the right move is to add a `given:` to the source itself, not to wedge a filter widget into the report. `#(filter)` is deprecated in favour of native Malloy `given:` parameters. Do not add new `#(filter)` annotations; the two exceptions are `required` and `implicit`, which `given:` cannot cover yet. The `malloy-model` skill covers this under § Legacy: Parameterizable Filters. For curated notebooks with their own per-notebook filter UI on top of the model, see `skill:malloy-notebooks` instead.
28
28
 
29
29
  ## What goes in the report
30
30
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-analyze
3
3
  description: Open-ended exploration with no specific question to answer, and building views/dashboards/notebooks on an existing model. Use when the user asks "what's interesting?", "explore this data", "find insights", "look for patterns", "build a dashboard", or "create views". Not for a specific data question - answering one is `malloy-analysis`, and writing down what the answer assumed is `malloy-model-as-you-go`. For exploration start at Step 1; for views on an existing model jump to View Patterns.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-charts
3
3
  description: Chart selection guidance and renderer reference for Malloy views. Use when choosing visualization types, adding chart annotations, user asks "what chart should I use", "how should I visualize this", or when deciding between bar_chart, line_chart, scatter_chart, etc.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-dashboards
3
3
  description: "Build or modify a Malloy Publisher dashboard, a tagged .malloy file in a package's dashboards/ directory, with auto-rendered filter controls, a grid layout, and # drill click-through. Use when the user asks for a dashboard, a filterable operational view, or drill-through between views, and no code is wanted."
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-debug
3
3
  description: Fix Malloy compile errors and understand error messages. Use when encountering errors in .malloy files, user says "fix this error", "malloy error", "compile error", "syntax error", or sees 20+ cascading errors.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -14,11 +14,12 @@ SPDX-License-Identifier: MIT
14
14
 
15
15
  ## Get Diagnostics
16
16
 
17
- **Claude Code (in VS Code terminal):** Call `mcp__ide__getDiagnostics` with the file URI.
17
+ Hosts expose errors differently, so take the best path you actually have:
18
18
 
19
- **VS Code Copilot / Cursor:** Use the `ReadLints` tool on the file path, or open the file and check lints in the editor.
19
+ 1. **An editor-diagnostics tool**, if your host offers one - call it on the file and read the errors straight out.
20
+ 2. **Otherwise, compile by running.** Run any query against the source with your query tool and read the error it returns. Every host that can run Malloy can do this, including chat surfaces with no editor.
20
21
 
21
- **Claude Code (standalone terminal):** No IDE diagnostics available. Ask the user to open the file in VS Code with the Malloy extension and report the errors.
22
+ Only ask the user to open the file in an editor when you know they have the model open in one. On a hosted chat surface there is no local checkout to open, and the query path above is the one that works.
22
23
 
23
24
  ## Strategy
24
25
 
@@ -38,8 +39,10 @@ SPDX-License-Identifier: MIT
38
39
  | "Aggregate not allowed in where" | Use `having:` instead |
39
40
  | 20+ random errors | Backtick reserved word (`` `Date` ``, `` `Hour` ``, `` `number` ``) |
40
41
  | `Can't find field 'X' to set access modifier` | An `include {}` sits before the `extend { rename: }`. Rename first, then `include {}` naming the field by its new name (see `skill:malloy-gotchas-modeling` § Field Management) |
42
+ | `IO Error: No files found that match the pattern "data/x.csv"` | Data-file path, not the model. Relative `duckdb.table()` paths resolve against the DuckDB `workingDirectory`; Publisher sets it to the package root, but a relative `workingDirectory` in `malloy-config.json` resolves against the process cwd. Make it absolute (see `skill:malloy-gotchas-modeling` § Relative Data-File Paths). The "not defined" errors under it are cascade, not real |
41
43
  | Import path errors | Check paths: `import "orders.malloy"`. All files should be in the same directory (flat layout) |
42
- | `from()` errors | Verify the source query returns the expected columns, check that imported sources are defined |
44
+ | `unexpected 'from'` | `from()` was removed from the language. Use the query directly: `source: x is q extend {...}`, or `source: x is (q -> {...}) extend {...}` |
45
+ | Query-based source errors | Verify the source query returns the expected columns, check that imported sources are defined |
43
46
  | "Cannot redefine 'X'" | Field already exists from query-based source (`-> { group_by, aggregate }`). Remove the dimension, add only NEW derived fields in `extend {}`. Use `include {}` to add `#(doc)` tags to existing fields. |
44
47
 
45
48
  ## Gotchas Checklist
@@ -123,4 +126,4 @@ a / b a / nullif(b, 0)
123
126
  | "Can't find source X" | Add `import "X.malloy"` at top of file (all files in same directory) |
124
127
  | Wrong import path | All `.malloy` files should be in the package root (flat layout). Use `import "orders.malloy"`, not `import "../sources/orders.malloy"` |
125
128
  | Circular imports | Source A imports Source B which imports Source A. Restructure to break the cycle |
126
- | `from()` "Can't find field" | Verify the source query's GROUP BY and aggregate fields match what you reference in `extend {}` |
129
+ | Query-based source "Can't find field" | Verify the source query's GROUP BY and aggregate fields match what you reference in `extend {}` |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-define
3
3
  description: Propose a source plan and field definitions for a Malloy semantic model. Covers picking which sources to model and at what grain, then proposing the specific renames, dimensions, and measures per source, every proposal backed by querying the data.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-discover
3
3
  description: Silent data discovery for Malloy modeling. Used at Step 1 of the modeling workflow. Scans tables, columns, distributions, and relationships without user interaction. The agent builds an internal picture before presenting anything.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-document
3
3
  description: 'Add documentation with #(doc) tags to Malloy models so fields and sources are described in plain language. Use when user asks to "add documentation", "add doc tags", "document the model", or wants fields and sources described for natural-language search and discovery. For declaring parameterizable filters with #(filter), see the malloy-model skill. Filters are a runtime/modeling construct (governance, latency, correctness), not a documentation tag.'
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-getting-started
3
3
  description: First steps for using a Malloy Publisher deployment through its MCP tools. Use when connecting to Publisher for the first time, when you do not yet know the available environments, packages, or models, or when a user asks what data they can explore. Covers verifying the server, discovering data with malloy_getContext, and running a first grounded query.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -29,6 +29,56 @@ Two escape hatches worth knowing:
29
29
 
30
30
  When a user is present, do not route around it by calling the REST API with curl. It appears to work, so the user never learns their session is missing the tools, and you lose what they are for: grounded discovery instead of guessed names, `malloy_compile` instead of throwaway queries, and `malloy_reloadPackage` instead of a restart. Say the tools are missing and let the user fix it in five seconds. Running unattended, with nobody who can reconnect you, is different: there the REST API is the supported interface, not a workaround. Discovery, query, compile, and reload all have REST equivalents (`malloy_searchDocs` and `malloy_getContext`'s plain-English ranking do not; read the bundled skills for syntax and ground from model metadata instead); the running server serves the full spec at `http://localhost:4000/api-doc.yaml`, and AGENTS.md carries the endpoint map.
31
31
 
32
+ ## 0.5 Ask whether they also use the CLI or the VS Code extension
33
+
34
+ Publisher is often not the only thing reading the model. The Malloy CLI (`malloy-cli`) and the VS
35
+ Code extension compile the same files, and they do **not** get their connections from
36
+ `publisher.config.json` - they read `malloy-config.json`, found by walking up from the file being
37
+ compiled. So a package that Publisher serves correctly can fail to compile in the editor, on the
38
+ same machine, from the same files.
39
+
40
+ Ask before the user finds out the hard way:
41
+
42
+ > Are you also using the Malloy CLI or the VS Code extension on this package?
43
+
44
+ If yes, and the package reads **local data files**, it needs a `malloy-config.json`. Publisher
45
+ resolves a relative `duckdb.table('data/x.csv')` against the package root on its own, so nothing is
46
+ configured for it; the other two hosts resolve it against the DuckDB connection's
47
+ `workingDirectory`, which has to be set.
48
+
49
+ **Make that path absolute.** A relative `workingDirectory` is resolved against the process's current
50
+ directory, not the config file's directory and not the VS Code workspace root, so the same config
51
+ compiles from one directory and fails from another:
52
+
53
+ ```json
54
+ // malloy-config.json, beside the model
55
+ {
56
+ "connections": {
57
+ "duckdb": {
58
+ "is": "duckdb",
59
+ "workingDirectory": "/abs/path/to/package",
60
+ "securityPolicy": "none"
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ Point it at the directory the model's table paths are written relative to - the one holding `data/`.
67
+ Leave the model's own paths relative so Publisher still serves it; only the config carries the
68
+ absolute path. When this is wrong the editor reports `IO Error: No files found that match the
69
+ pattern "data/x.csv"` on the `source:` line, followed by a "not defined" error for every field of
70
+ that source; those are cascade, not real. The `malloy-gotchas-modeling` skill covers the mechanism
71
+ under § Relative Data-File Paths.
72
+
73
+ **Remote Credible connections are a different case.** With the Credible extension running and signed
74
+ in, the data is reached through a `publisher` proxy connection - the connection type that forwards
75
+ SQL to a remote Publisher dataplane, and the same type the CLI and the VS Code extensions use - and
76
+ the extension supplies it, so there is nothing to hand-write and no `workingDirectory` involved.
77
+ `workingDirectory` only ever matters for local files that DuckDB opens itself. Worth knowing: those
78
+ access tokens are user-scoped and short-lived, and nothing refreshes them mid-session, so queries
79
+ that start failing auth after a long session mean the token expired, not that the model broke. See
80
+ `docs/connections.md` § Publisher proxy connections.
81
+
32
82
  ## 1. Discover what exists (never guess names)
33
83
 
34
84
  `malloy_getContext` is progressive. Call it with as much as you know:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-gotchas-modeling
3
3
  description: Common Malloy modeling mistakes and how to avoid them. Read BEFORE writing source definitions, dimensions, measures, or joins. Covers reserved words, NULL checks, date functions, type casts, field management (extend except/accept/rename vs include public/internal/private), and query-based source gotchas.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -282,6 +282,46 @@ source: facts is conn.table('orders') -> { group_by: user_id, aggregate: total i
282
282
 
283
283
  If a project's standards file specifies a stricter policy (e.g., a `search_malloy_docs` rationale comment requirement above every `conn.sql()` block), defer to that.
284
284
 
285
+ ## Relative Data-File Paths: Set an Absolute `workingDirectory`
286
+
287
+ `duckdb.table('data/x.csv')` is resolved against the DuckDB connection's `workingDirectory`, not
288
+ against the model file. Publisher sets that to the package root, so relative paths work there with
289
+ no config at all. Every other host reads it from `malloy-config.json`, and **a relative value there
290
+ is resolved against the process's current directory** - not the config file's directory, and not the
291
+ VS Code workspace root. `canonicalizeConfigPath` in `malloy-db-duckdb/src/duckdb_config.ts` calls
292
+ `canonicalizePath` with no `baseDirectory`, which is a bare `path.resolve(input)`.
293
+
294
+ So the same config works or fails depending on which directory the editor or shell was launched
295
+ from. That is why this breaks intermittently and appears to be a model bug.
296
+
297
+ ```json
298
+ // WRONG: resolved against the process cwd, so it works from the repo root and
299
+ // fails from anywhere else - including however your editor happened to launch
300
+ {"connections": {"duckdb": {"is": "duckdb", "workingDirectory": "malloy"}}}
301
+
302
+ // RIGHT: absolute, so the cwd cannot change the answer
303
+ {"connections": {"duckdb": {"is": "duckdb", "workingDirectory": "/abs/path/to/pkg"}}}
304
+ ```
305
+
306
+ Point it at the directory the model's table paths are written relative to - the package root, the
307
+ one holding `data/`. Keep the model's paths relative (`data/x.csv`) so Publisher still serves it;
308
+ only the config carries the absolute path.
309
+
310
+ **The symptom, and the cascade.** One `IO Error` at the `source:` line, then a "not defined" error
311
+ for every field of that source:
312
+
313
+ ```
314
+ line 87: IO Error: No files found that match the pattern "data/product_usage.csv"
315
+ line 91: 'org_slug' is not defined
316
+ line 93: Reference to undefined value active_users
317
+ ```
318
+
319
+ Those field errors are not real. Fix the first error and they all go. Do not start renaming
320
+ columns.
321
+
322
+ **Check the config before the model** when a source that Publisher queries fine fails in the editor
323
+ or CLI with a missing-file error. The model is the same file; the resolution base is not.
324
+
285
325
  ## JSON Files: Read Them In Place Like CSV
286
326
 
287
327
  ```malloy
@@ -407,5 +447,5 @@ Call `search_malloy_docs` BEFORE first use of any of these. Don't guess the synt
407
447
  - Window functions (`calculate`)
408
448
  - `percentile` or statistical functions: but see the hard limit above, raw-SQL aggregates (`sql_number` / `is_aggregate` / `percentile_cont!`) do **not** compile as measures in this build; there is no scalar median (`stddev` is the exception and does work as a measure)
409
449
  - Time interval functions (`days()`, `months()`): always `unit(start to end)`, and calendar units need date operands (see above)
410
- - Query-based sources (`from()`)
450
+ - Query-based sources (`source: x is (q -> {...}) extend {...}`; `from()` was removed and no longer parses)
411
451
  - `!` operator / `sql_number()`
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-gotchas-queries
3
3
  description: Common Malloy query and view mistakes. Read BEFORE writing views, queries, or notebooks. Covers chart constraints, aggregate filters, joined field aliasing, method syntax, and time truncation vs extraction.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-gotchas-rendering
3
3
  description: Common Malloy renderer annotation mistakes. Read BEFORE adding chart annotations, formatting tags, or building dashboards. Covers tag syntax, scale rules, sparkline setup, and big_value patterns.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-html-data-app-embedding
3
3
  description: Embed an in-package HTML data app into a host page or another application, including auto-sizing and auth. Read when embedding a Publisher page via Publisher.embed.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-html-data-app-runtime
3
3
  description: Write the JavaScript that drives an in-package HTML data app, calling Publisher.query, building queries from filter state, and handling results and errors. Read before writing the page's data code.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-html-data-apps
3
3
  description: Build or modify an in-package HTML data app for a Malloy Publisher package (a public/ directory the package serves). Use when the user wants a hand-authored HTML dashboard or web page backed by a package's Malloy models, with no build step.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-lookml-review
3
3
  description: Analyze LookML files as prior art for Malloy modeling. Used during Step 1 (DISCOVER) when .lkml files are present. Coordinates reference files that extract business logic, relationships, and curation decisions. Works with or without a database connection.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -41,7 +41,7 @@ Reference table for translating LookML constructs to Malloy. Referenced by multi
41
41
  | `+view:` (refinement) | User decides: consolidate or `extend` | Malloy `extend` serves the same purpose |
42
42
  | `derived_table: { sql: ... }` (perf-only) | Use base table directly | PDT optimization is Looker-specific |
43
43
  | `derived_table: { sql: ... }` (transformation) | Flag for user | Recommend base table + dims or upstream dbt |
44
- | `derived_table: { explore_source: ... }` (NDT) | `from(source -> { group_by:, aggregate: }) extend { }` | Computed source pattern |
44
+ | `derived_table: { explore_source: ... }` (NDT) | `(source -> { group_by:, aggregate: }) extend { }` | Computed source pattern |
45
45
  | `value_format: "$#,##0.00"` | `# currency` | Map to Malloy render tags |
46
46
  | `value_format: "0.00%"` | `# percent` | Map to Malloy render tags |
47
47
  | `value_format_name: decimal_2` | `# number="0.00"` | Map to Malloy render tags |
@@ -12,7 +12,7 @@ SPDX-License-Identifier: MIT
12
12
  ```
13
13
  derived_table:
14
14
  ├── explore_source: → NDT path
15
- │ ├── Simple aggregation → Malloy from() extend {}
15
+ │ ├── Simple aggregation → Malloy (query) extend {}
16
16
  │ ├── With derived_column: (window functions) → Malloy window function patterns
17
17
  │ ├── Chained NDTs → dependency ordering, multi-stage computed source
18
18
  │ └── With bind_filters → flag, no direct Malloy equivalent
@@ -25,10 +25,12 @@ derived_table:
25
25
 
26
26
  ### Simple Aggregation NDT
27
27
 
28
- Express the aggregation as a Malloy query, then build a source from it:
28
+ Express the aggregation as a Malloy query, then build a source from it by
29
+ wrapping the query in parentheses and extending it (`from(...)` was removed from
30
+ the language and no longer parses):
29
31
 
30
32
  ```malloy
31
- source: source_name is from(
33
+ source: source_name is (
32
34
  base_source -> {
33
35
  group_by: group_field
34
36
  aggregate:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-materialization
3
3
  description: Add and debug Malloy Persistence materializations in a package - persist an expensive source so queries read a pre-built table. Read this whenever the user wants to materialize a source, add a persist annotation, speed up a slow source, or asks why a persist source isn't building.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -124,13 +124,28 @@ bound, only the first is:
124
124
 
125
125
  - **`materialization.freshness` `{ "window": "24h", "fallback": "live" }` is the bound.** The serve path
126
126
  re-checks freshness per query, so once the artifact ages past the window it drops out of the serving set
127
- and the query recomputes live, correctly filtered - whether or not a rebuild ever lands. Two details
127
+ and the query recomputes live, correctly filtered - whether or not a rebuild ever lands. Three details
128
128
  decide whether you actually get that. **`fallback` must be `live`**: under `stale_ok` a stale artifact
129
129
  keeps being served, which voids the bound, and window and fallback resolve *independently* per layer,
130
- so a package-level `stale_ok` silently defeats a window you set on the source. And prefer the
130
+ so a package-level `stale_ok` silently defeats a window you set on the source. That is a statement about
131
+ **layers**, which do not combine - not about siblings, below. Prefer the
131
132
  **per-source** spelling `#@ persist name="..." freshness.window="24h" freshness.fallback="live"` over
132
133
  the package-wide `materialization.freshness` key: the gated source is what needs the bound, and setting
133
- it package-wide forces every other persisted source to recompute once stale too.
134
+ it package-wide forces every other persisted source to recompute once stale too. And **a
135
+ content-identical sibling shares the artifact, so it shares the window**: reuse is keyed on the
136
+ content-addressed `sourceEntityId`, which folds the connection and the SQL but *not* the source name, so
137
+ two persist sources whose bodies compute the same SQL resolve to one table carrying one freshness
138
+ policy. The tightest window any of them declares governs all of them - a sibling declaring nothing
139
+ cannot loosen yours, and yours pulls that sibling's reads off the table once it lapses. A sibling's
140
+ `stale_ok` cannot void your bound either: the fold keeps whichever fallback bounds staleness, so the
141
+ layer rule above does not carry over here. If two sources need genuinely different windows, give them
142
+ genuinely different SQL.
143
+
144
+ Both of those are properties of the **host** that assembles the manifest, not of the annotation. Where
145
+ the host does not fold, which sibling's policy reaches the wire is unspecified; and a host that folds at
146
+ manifest-assembly time typically applies it when a version's manifest is next published rather than
147
+ retroactively to manifests already distributed - so you can declare the window correctly and not have it
148
+ in force yet.
134
149
  - **A cron alone is not a bound.** A failed build or a stopped scheduler leaves the source serving its old
135
150
  decisions indefinitely. `freshness` and `schedule` are mutually exclusive; for a gated source, take the
136
151
  window.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-materialization-tuning
3
3
  description: Optimize a package's Malloy Persistence materializations for cost and performance using the malloy-pub CLI and the materialization history. Recommend what to persist, what to stop persisting, and how to schedule/scope it. Use when the user asks to make a package cheaper or faster, tune persistence, decide what to materialize, or review persist/schedule choices.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-model
3
3
  description: Build Malloy semantic models with base source and joined source files. Use when creating or modifying .malloy files, user asks to "create a malloy model", "add dimensions", "add measures", "create a source", or any Malloy model authoring task.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -112,10 +112,12 @@ extend {
112
112
 
113
113
  ### Computed Source (from Query)
114
114
 
115
+ Wrap the query in parentheses and extend it. `from(...)` was removed from the language and no longer parses (`unexpected 'from'`).
116
+
115
117
  ```malloy
116
118
  import "orders.malloy"
117
119
 
118
- source: user_order_facts is from(
120
+ source: user_order_facts is (
119
121
  orders -> {
120
122
  group_by: customer_id
121
123
  aggregate:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-model-as-you-go
3
3
  description: After answering a data question, write down what the answer assumed so the next reader can trust the number. A field with a #(doc) in the model when you can edit it, an extend in the notebook when you can only author reports, or a stated assumption plus a Malloy snippet when you can only chat. Use after every answered question that rested on a judgment call, and whenever a question is asked against tables that have no model yet.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
 
7
7
  <!--
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-modeling
3
3
  description: Build semantic models with Malloy for the Malloy Publisher. Read this skill whenever the user asks about modeling data or specifically mentions Malloy.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-notebook-chat
3
3
  description: Steps to follow when the chat is bound to a notebook or saved report. The notebook's cells are the agent's primary context, answer from it, run its queries, and only reach for get_context when the user asks about something outside it.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -21,5 +21,5 @@ Steps to follow when the user asks a question:
21
21
  - If the question can be answered by a query already in the notebook, run that cell's query via `execute_query` (exact code, or a minor variation like adding a filter or changing a group_by).
22
22
  - If the question asks for an analysis that is clearly NOT in the notebook (new source, different package, different domain), then, and only then, call `get_context` to explore.
23
23
  - Do NOT call `get_context` as a default first step. The notebook already tells you what's available.
24
- 4. Before writing or modifying a query, read the `malloy-queries` skill for syntax patterns. When you tweak a query (add a `where:` clause, change a `group_by`, etc.), do NOT add `#(filter)` annotations: filters live on the source's model file and are inherited by this notebook automatically. Query-level `where:` filtering inside a cell is fine; declaring new filter UI is a model change, not a chat-time change.
24
+ 4. Before writing or modifying a query, read the `malloy-queries` skill for syntax patterns. When you tweak a query (add a `where:` clause, change a `group_by`, etc.), do NOT add `#(filter)` annotations or `given:` declarations: both live on the source's model file and are inherited by this notebook automatically. Query-level `where:` filtering inside a cell is fine; declaring a new runtime parameter is a model change, not a chat-time change.
25
25
  5. Summarize insights from query results. Do not echo raw rows: the user sees them rendered.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-notebooks
3
3
  description: Create Malloy notebooks (.malloynb) for interactive dashboards and data stories. Use when user asks to "create a notebook", "make a dashboard notebook", "write a malloynb", "data story", or needs to build reports/visualizations.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-patterns
3
3
  description: Index of Malloy documentation topics. Use to discover what's available in search_malloy_docs. Covers language reference (sources, queries, views, fields, aggregates, joins, filters, expressions, functions), common patterns (YoY, cohorts, percent of total), rendering, and experimental features.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-phrase-detection
3
3
  description: How to construct search targets for the get_context tool. Covers target-type classification and non-obvious decomposition patterns. Read the tool description for field definitions and the end-to-end workflow.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-publish
3
3
  description: Package Malloy models for serving by Malloy Publisher. Use when user asks to "publish", "package", "deploy", or wants to share models with others.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-queries
3
3
  description: Malloy query patterns, syntax rules, and chart annotation reference. Consult before writing or debugging any query. Covers dates, aggregates vs dimensions, join paths, filters, string matching, and common error patterns.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-review
3
3
  description: Malloy semantic-model code review. Invoke when the user asks to review, audit, or critique a `.malloy` file, a folder of Malloy models, or a GitHub PR that touches Malloy. Enforces project modeling standards and emits a navigable review file.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.
@@ -29,7 +29,7 @@ For every rule, the linked instruction-skill section is the canonical source for
29
29
  - **Why this isn't a correctness rule.** The Malloy compiler auto-synthesizes a UUID-based `__distinct_key` for any `join_one:` target without a declared PK (`packages/malloy/src/model/field_instance.ts:644-670`, `query_query.ts:946-951`), so symmetric aggregation is correct either way, see the C-07 entry in `rubric-correctness.md`'s "Rules we dropped" section. The `with` shortcut, which DOES require a declared PK, errors at compile time and surfaces as a diagnostic. The actual silent-correctness hazard ("declared PK isn't actually unique in the data") is `rubric-correctness.md` § C-12.
30
30
  - **What this rule catches.** A discoverability / hygiene gap: when a source has a natural primary key, declaring it lets downstream code use the `with` shortcut, makes grain explicit in the model, and gives tooling a stable identifier per row. Treat as a recommendation, not a merge gate.
31
31
  - **Detection:** for every `source:` declaration, check whether its body contains a `primary_key:` clause. Skip flagging when:
32
- - The source is a query-based / computed source (`source: x is t -> {...}` or `source: x is from(...)`) where grain is determined by the `group_by` columns, declaring a `primary_key:` on the result is fine but not required.
32
+ - The source is a query-based / computed source (`source: x is t -> {...}` or `source: x is (t -> {...}) extend {...}`) where grain is determined by the `group_by` columns, declaring a `primary_key:` on the result is fine but not required.
33
33
  - The source represents an event/log table or a denormalized analytical source where no natural PK exists. Both situations are legitimate; the LLM should recognize them and skip the finding.
34
34
  - **Fix (when the source does have a natural PK):** declare it, `primary_key: <col>` inside `extend {}`. When there isn't a natural PK, leave it undeclared; if the absence is non-obvious, a one-line `#(doc)` on the source explaining the grain helps future readers.
35
35
  - **See:** `skill:malloy-model` § Key Rules · `rubric-correctness.md` § C-12 (the related correctness rule that checks whether a declared PK is actually unique in the data) · `rubric-style.md` § Y-03 (`join_one:` style consistency, which is the other consequence of declared-vs-undeclared PKs)
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: malloy-scope
3
3
  description: Present discovery findings and propose an analytical scope before modeling. Use after inspecting a package's model and data, to classify tables and recommend an analytical focus the user can pick from.
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  ---
6
6
  <!--
7
7
  Copyright (c) Credible Data Inc.