Skip to content

feat(engine): Trust-system Arc 6 (wave 2) — [portability] config + per-model pragma#186

Merged
hugocorreia90 merged 1 commit intomainfrom
feat/arc-6-portability-config
Apr 20, 2026
Merged

feat(engine): Trust-system Arc 6 (wave 2) — [portability] config + per-model pragma#186
hugocorreia90 merged 1 commit intomainfrom
feat/arc-6-portability-config

Conversation

@hugocorreia90
Copy link
Copy Markdown
Contributor

Summary

  • New [portability] block in rocky.toml with target_dialect + allow list, replacing the wave-1 flag-only UX with project-level configuration.
  • Per-model SQL pragma -- rocky-allow: NVL, QUALIFY (case-insensitive, comma-separated) for targeted exemptions.
  • Generic pragma parser in new rocky-sql/src/pragma.rs so a future [lints] block for P002 reuses it.
  • Dialect enum now Serialize/Deserialize/JsonSchema (lowercase variants) so target_dialect = "bigquery" parses naturally from TOML.

Precedence

  1. CLI --target-dialect flag (highest — useful for CI matrix runs / debugging)
  2. [portability] target_dialect in rocky.toml
  3. Unset → no lint runs (matches wave-1 default)

Allow-listing composes additively: project-wide [portability] allow = [...] ∪ per-model -- rocky-allow: pragma. Either suppresses the matching construct's P001 diagnostic before it hits the diagnostics vec.

What's deferred to wave 3

  • Sharper source spans (per-construct byte offsets) — same wave-3 line item Arc 6 wave 1 deferred.
  • Lint on expanded SQL when --expand-macros is set.
  • [lints] block driving per-model P002 toggles (lives in Arc 7's roadmap because it pairs with type-inference work).

Test plan

  • cargo test --workspace — full engine suite, all crates, 0 failures.
  • 12 unit tests in pragma::tests covering single/multi/case/indent/uppercase/string-literal/edge cases.
  • 6 new integration tests in commands::compile::tests: config-only, flag-overrides-config, project allow-list suppresses, per-model pragma suppresses, pragma-is-per-model-not-project-wide, missing-config falls through. Plus the 4 wave-1 tests still pass with the new signature.
  • pytest in integrations/dagster/ — 307/307 pass; fixtures unchanged because the playground default doesn't opt into portability config.
  • cargo fmt --check + cargo clippy --workspace --all-targets -- -D warnings.
  • just codegen — rocky-project.schema.json, dagster Pydantic, vscode TS all regenerated and committed (portability block now in the schema).
  • End-to-end CLI smoke test: 2-model project where m1's NVL fires P001 (project allow has QUALIFY but not NVL) and m2's NVL is suppressed by -- rocky-allow: NVL pragma. Compile bails with exactly 1 error on m1.

…r-model pragma

Replaces the wave-1 "flag-only" UX with a project-wide config block and
a per-model opt-out pragma. P001 now respects three layers, in order:

1. CLI `--target-dialect <dbx|sf|bq|duckdb>` flag (highest precedence;
   useful for CI matrix runs and ad-hoc debugging).
2. `[portability] target_dialect = "<dialect>"` in `rocky.toml`. Lives
   at top level because a Rocky project targets one warehouse — per-pipeline
   override is speculative; skipped until demand signal.
3. Unset → no lint runs (matches the wave-1 default).

Project-wide allow-listing via `[portability] allow = ["QUALIFY", "NVL"]`
suppresses matching constructs across every model. Per-model exemption
via the SQL line-comment pragma `-- rocky-allow: NVL, QUALIFY`,
case-insensitive comma-separated identifiers.

The pragma parser lives in a new `rocky-sql/src/pragma.rs` module,
deliberately generic: the `ModelPragmas { allowed_constructs }` API
returns a HashSet so a future `[lints]` block driving P002 toggles
reuses it without a second parser.

The `Dialect` enum gains `Serialize/Deserialize/JsonSchema` (lowercase
variants) so `target_dialect = "bigquery"` round-trips cleanly through
`rocky.toml` without a string-side parser. The CLI's short-form
`TargetDialect` (`dbx/sf/bq`) stays as ergonomics in the clap layer
and converts to `Dialect` at the boundary.

run_compile gains a leading `Option<&Path>` argument for the config
path. When present, config-load failures fall through silently — the
wave-1 `compile_without_target_dialect_does_not_run_lint` semantics
hold for projects without a `rocky.toml`.

Schema regen: rocky-project.schema.json + dagster + vscode generated
types updated via `just codegen`. No fixture changes (P002 message
unchanged; new code paths only fire when config opts in, which the
playground default doesn't).

Wave-3 backlog (carry-forward from `project_rocky_active_priority`):
sharper source spans (per-construct byte offsets), lint on expanded
SQL when `--expand-macros` is set.
@hugocorreia90 hugocorreia90 merged commit d6b157d into main Apr 20, 2026
15 checks passed
@hugocorreia90 hugocorreia90 deleted the feat/arc-6-portability-config branch April 20, 2026 16:22
@hugocorreia90 hugocorreia90 mentioned this pull request Apr 20, 2026
3 tasks
hugocorreia90 added a commit that referenced this pull request Apr 20, 2026
Closes the first wave of every trust-system arc (Arcs 1-7) plus the two
wave-2 follow-ups landed the same day. Nine feature PRs since v1.10.0.

- Arc 1 (#170): rocky lineage --downstream, rocky branch, rocky run --branch, rocky replay
- Arc 2 (#171): per-run cost attribution, [budget] block, budget_breach hook
- Arc 3 (#172): three-state CircuitBreaker, adapter consolidation
- Arc 4 (#173): rocky trace Gantt + feature-gated OTLP metrics export
- Arc 5 (#174): schema-grounded rocky ai prompt + project-aware validator
- Arc 6 wave 1 (#184): --target-dialect P001 portability lint (12 constructs)
- Arc 7 wave 1 (#185): blast-radius P002 SELECT * lint (semantic-graph aware)
- Arc 6 wave 2 (#186): [portability] config block + per-model rocky-allow pragma
- Arc 7 wave 2 wave-1 (#187): --with-seed source-schema inference

Plus #169 fix: install scripts pick latest engine version by semver.

Version bump: 20 Cargo.toml files (all workspace members except
rocky-bigquery, which tracks its own version).

Wave 2/3 work for every arc remains in the deferred backlog — see
the changelog Deferred section for the full carry-forward.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant