feat(engine): rocky compliance governance rollup (Wave B)#242
Merged
hugocorreia90 merged 3 commits intomainfrom Apr 23, 2026
Merged
feat(engine): rocky compliance governance rollup (Wave B)#242hugocorreia90 merged 3 commits intomainfrom
hugocorreia90 merged 3 commits intomainfrom
Conversation
Adds a top-level CLI verb that answers "are all classified columns masked wherever policy says they should be?" Pure resolver over `rocky.toml` + model sidecars — no warehouse I/O. - New `commands/compliance.rs` with `run_compliance` + `build_report` pure resolver + 10 unit tests covering the all-masked / some-exceptions / all-allow-listed / --env scoping / --exceptions-only branches. - New `ComplianceOutput` + supporting structs in `output.rs`. Derives `Serialize + Deserialize + JsonSchema + Debug + Clone` per Wave B spec (the other *Output structs only derive Serialize + JsonSchema; spec is authoritative here). - `CompactFailOn` clap enum for `--fail-on exception` CI gate. - Registered `ComplianceOutput` in `export_schemas.rs` so `just codegen` emits `schemas/compliance.schema.json`. CLI surface: rocky compliance rocky compliance --env prod rocky compliance --exceptions-only rocky compliance --fail-on exception # exits 1 on any exception
Output of `just codegen` for the new `rocky compliance` JSON schema: - `schemas/compliance.schema.json` (the source of truth for this command) - `integrations/dagster/.../compliance_schema.py` (Pydantic v2 model) - `editors/vscode/src/types/generated/compliance.ts` (TypeScript interface) Also updates the two curated barrel files that `just codegen` restores via `git checkout HEAD --` so the new types stay re-exported after future codegen runs: - `integrations/dagster/.../types_generated/__init__.py` - `editors/vscode/src/types/generated/index.ts`
Wire `rocky compliance` JSON output into the dagster-rocky package: - Re-export `ComplianceOutput` + its five supporting types from `types.py` (the round-9 soft-swap re-export pattern). - Extend `RockyOutput` union with `ComplianceOutput`. - Route `command == "compliance"` to `ComplianceOutput` in `parse_rocky_output()`. A `RockyResource.compliance(...)` helper can follow once a consumer asks for it — the parser side is enough to unblock ad-hoc `parse_rocky_output(...)` callers today.
This was referenced Apr 23, 2026
hugocorreia90
added a commit
that referenced
this pull request
Apr 23, 2026
* chore: release engine-v1.16.0 + dagster-v1.12.0 + vscode-v1.8.0 Bundles the governance waveplan — five merged PRs (#240 audit trail, #241 classification + masking, #242 rocky compliance, #243 role-graph, #244 retention) on top of three FR-004 / state-path follow-ups (#237 error-path idempotency, #238 state-path unification, #239 success-path idempotency finalize). Version bumps: engine 1.15.0 → 1.16.0, dagster-rocky 1.11.0 → 1.12.0, vscode extension 1.7.0 → 1.8.0. CHANGELOGs updated for all three artifacts. * chore(dagster): regen test fixtures for 1.16.0 Fixture drift flagged by CI (`codegen-drift.yml`). Fixtures are captured from the live engine binary — the version-string bump to 1.16.0 ripples through every `version` field, and the Wave A audit-trail work (#240) adds the 8 `RunRecord` fields to `rocky history` output, which the playground POC now emits. Regenerated via `just regen-fixtures` against `examples/playground/pocs/00-foundations/00-playground-default`. * chore(scripts): sentinel top-level version field in fixture normaliser Every CLI output's top-level `version` is `env!("CARGO_PKG_VERSION")` at emit time, so every engine version bump rippled through all 38 captured fixtures — every release PR fought `codegen-drift.yml` until `just regen-fixtures` was re-run. Extend the existing `AUDIT_FIELD_SENTINELS` set (Wave A already sentineled the audit-trail `rocky_version` field + hostname / git commit / etc.) with the top-level `version` key → `"0.0.0-SENTINEL"`. After this, version bumps only touch Cargo.toml / pyproject.toml / package.json / CHANGELOGs — never fixtures. Regen captured all 38 fixtures; top-level `version` now uniformly renders as `"0.0.0-SENTINEL"`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wave B of the governance waveplan — a new top-level
rocky complianceverb that reports on column classification + masking coverage across a project. Thin rollup over what Wave A (#240/#241) shipped.Answers the question: Are all classified columns masked wherever policy says they should be?
CLI surface
Output (typed + codegen-backed)
ComplianceOutputwithsummary/per_column/exceptions.EnvMaskingStatusreports strategy + enforced per (model, column, env). DerivesJsonSchema; Pydantic + TypeScript bindings regenerated and re-exported.Resolver semantics (design decisions from the PR body)
total_maskedis counted over(model, column, env)triples — same granularity astotal_exceptions.MaskStrategy::Nonecounts as masked (explicit-identity is a policy decision, not a gap).[classifications.allow_unmasked]suppressesComplianceExceptionemission;per_columnrows still report the truth (enforced: false,masking_strategy: "unresolved").--env, iteratesNone(labeled"default") ∪ every[mask.<env>]override key. With--env X, a singleSome(X)pass — defaults fallback if[mask.X]is absent.--exceptions-onlyfiltersper_columnto columns that triggered an exception;exceptionslist itself is unfiltered.--fail-on exceptionexit = 1 if!exceptions.is_empty(), else 0. Default run never fails on report content.Files touched
engine/crates/rocky-cli/src/commands/compliance.rs(new, ~491 LOC incl. 10 unit tests)engine/crates/rocky-cli/src/output.rs— 5 new output typesengine/crates/rocky-cli/src/commands/{mod.rs,export_schemas.rs}engine/rocky/src/main.rs— clapCompliancevariant +ComplianceFailOnenumschemas/compliance.schema.json(codegen)integrations/dagster/src/dagster_rocky/types_generated/compliance_schema.py(codegen)integrations/dagster/src/dagster_rocky/types_generated/__init__.py+types.py— re-exports +parse_rocky_outputrouteeditors/vscode/src/types/generated/{compliance.ts,index.ts}(codegen)Test plan
cargo test --workspace— 2481 passed, 0 failedcargo clippy --workspace --all-targets -- -D warnings— greencargo fmt --check— greenuv run pytest tests/test_types.py(dagster) — 23 passednpm run test:unit(vscode) — 20 passedjust codegenidempotent (no drift on re-run)--fail-on exceptionexit-1 semantics