From 307fda7ac8063f0ae6d8718577a75c6f6e36d378 Mon Sep 17 00:00:00 2001 From: Maria Jose Ferreira Fernandes <171664470+MariaJoseFF@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:51:44 +0200 Subject: [PATCH 1/3] Update CLI docs to reflect TE3 PR 3254 bpa run resolution chain - Rename two remaining TE_BPA_PATH references to TE_BPA_RULES in te-cli-limitations.md (env var was renamed in CLI commit 138136976). - Note te bpa run alongside the deploy/save gate as a consumer of every bpa.rules entry in te-cli-config.md. - Clarify te bpa run --rules description (replaces user-rule layer, not "additional") and add a "Rule sources and resolution" subsection covering the priority chain --rules > TE_BPA_RULES > bpa.rules config and the layered model used by the Rules loaded: output line. --- content/features/te-cli/te-cli-commands.md | 21 ++++++++++++++++++- content/features/te-cli/te-cli-config.md | 2 +- content/features/te-cli/te-cli-limitations.md | 4 ++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/content/features/te-cli/te-cli-commands.md b/content/features/te-cli/te-cli-commands.md index 50eb3f17..4dce3987 100644 --- a/content/features/te-cli/te-cli-commands.md +++ b/content/features/te-cli/te-cli-commands.md @@ -407,7 +407,7 @@ Run Best Practice Analyzer rules against a model. `te bpa run` accepts: - `` - positional argument: path to model (alternative to the `--model` global flag). -- `-r, --rules ` - path(s) or URL(s) to additional BPA rule file(s) in JSON format. Repeatable. +- `-r, --rules ` - path(s) or URL(s) to BPA rule file(s) in JSON format. Repeatable. Replaces the user-rule layer for this invocation: see [Rule sources and resolution](#rule-sources-and-resolution) below. - `--no-model-rules` - exclude BPA rules embedded in the model's annotations. - `--no-defaults` - exclude built-in default BPA rules. - `--vpax ` - load VertiPaq Analyzer stats from a `.vpax` file to enable VPA-aware rules. @@ -433,6 +433,25 @@ te bpa run --path 'Sa*' # Wildcard - every table starting with Sa te bpa run --path Sales/Measures # Path filter applied to the matched tables ``` +#### Rule sources and resolution + +Each `te bpa run` invocation assembles rules from three independent layers: + +1. **User rules** - exactly one source wins, in priority order: + - `-r, --rules ` flag (highest) + - `TE_BPA_RULES` environment variable + - `bpa.rules` array from CLI config (`~/.config/te/config.json`) +2. **Built-in defaults** - loaded unless `--no-defaults` is passed or [`bpa.builtInRules`](xref:te-cli-config#bpa-gate-keys) is `false` in config. Individual built-ins listed in `bpa.disabledBuiltInRuleIds` are skipped. +3. **Model-embedded rules** - rules in the model's `BestPracticeAnalyzer_Rules` annotation, loaded unless `--no-model-rules` is passed. External URL annotations are skipped unless `--allow-external-rules` is also passed. + +Duplicate rule IDs are de-duplicated (user rules win over built-ins). Rule IDs in the model's `BestPracticeAnalyzer_IgnoreRules` annotation are then removed. + +The `Rules loaded:` line in the output attributes each contributing layer, for example: + +``` +Rules loaded: 41 from 1 file(s) from bpa.rules config + built-in defaults + model annotations +``` + ### bpa rules Manage BPA rule collections — list, inspect, initialize, and toggle rules in your local rules file or in model annotations. Built-in rules are read-only - to skip one without losing the rest, use `te bpa rules disable` (do not edit the built-in set directly). diff --git a/content/features/te-cli/te-cli-config.md b/content/features/te-cli/te-cli-config.md index 95c442a4..647ff232 100644 --- a/content/features/te-cli/te-cli-config.md +++ b/content/features/te-cli/te-cli-config.md @@ -121,7 +121,7 @@ Set these in your config to avoid passing the same paths on every command. Per-c | Key | Meaning | | -- | -- | | `macros` | Explicit path to a macros JSON file (typically `MacroActions.json`). Resolved by every `te macro` command. Point at a shared file (network share, repo-local, or even the TE3 desktop file) to reuse the same set of macros across machines and between the CLI and TE3 Desktop. | -| `bpa.rules` | Ordered list of paths or URLs to BPA rule files. The deploy/save gate loads **every** existing entry; `te bpa rules list` and `te config paths` use the first existing entry. Comma-separated values on `te config set bpa.rules ...` are split into the array. | +| `bpa.rules` | Ordered list of paths or URLs to BPA rule files. `te bpa run` and the deploy/save gate load **every** existing entry; `te bpa rules list` and `te config paths` use the first existing entry. Comma-separated values on `te config set bpa.rules ...` are split into the array. | | `te3ExePath` | Explicit path to the Tabular Editor 3 Desktop executable (`TabularEditor.exe`). Used **only** by `te open` to launch the desktop app; safe to leave unset on Linux/macOS or when you don't use `te open`. If unset, `te open` falls back to a `PATH` lookup. | | `queryLog` | Path to a log file where every `te query` invocation appends its query text and execution metadata. Useful for audit trails or analyzing query patterns over time. Supports `~` for the home directory (e.g., `~/.config/te/queries.log`). | diff --git a/content/features/te-cli/te-cli-limitations.md b/content/features/te-cli/te-cli-limitations.md index 1e52055d..09371a14 100644 --- a/content/features/te-cli/te-cli-limitations.md +++ b/content/features/te-cli/te-cli-limitations.md @@ -44,8 +44,8 @@ The CLI runs C# scripts (`te script`) against the same `Model` object you use in | -- | -- | | **BPA rule sources must be HTTPS URLs or local file paths** | Only `https://` URLs and bare local file paths are accepted. `http://` is recognized but deliberately rejected at load time with a clear error - BPA rules are executable rule expressions, and fetching them over an unauthenticated channel would be a tampering risk. Other URL schemes (`file://`, `ftp://`, …) are not supported. Applies to both `te bpa run --rules` and the rule list configured via [`te config set`](xref:te-cli-commands#config-show--paths--init--set). | | **Rule-URL validation runs at gate time, not on `te config set`** | A typo such as `http://` is accepted by `te config set` and only surfaces when BPA actually runs. After editing the configured rule sources, run `te bpa run` (or `te validate`) once to verify each URL loads. | -| **`--rules` does not suppress built-in rules** | When `te bpa run --rules ` is passed, the supplied rules replace the entries in [`bpa.rules`](xref:te-cli-commands#config-show--paths--init--set) and `TE_BPA_PATH` for that invocation, but the built-in defaults still load alongside. To run only the explicit rule file, also pass `--no-defaults`. | -| **No per-invocation flag to skip `bpa.rules` config** | Once `bpa.rules` is configured, every `te bpa run` loads those rules in addition to the built-ins. There is currently no flag to skip the configured rule files for a single run. Workaround: pass `--rules ` explicitly - the flag fully replaces `bpa.rules` and `TE_BPA_PATH` for that invocation. | +| **`--rules` does not suppress built-in rules** | When `te bpa run --rules ` is passed, the supplied rules replace the entries in [`bpa.rules`](xref:te-cli-commands#config-show--paths--init--set) and `TE_BPA_RULES` for that invocation, but the built-in defaults still load alongside. To run only the explicit rule file, also pass `--no-defaults`. | +| **No per-invocation flag to skip `bpa.rules` config** | Once `bpa.rules` is configured, every `te bpa run` loads those rules in addition to the built-ins. There is currently no flag to skip the configured rule files for a single run. Workaround: pass `--rules ` explicitly - the flag fully replaces `bpa.rules` and `TE_BPA_RULES` for that invocation. | ## Validation From 408bd46397a54d9a9603feffed7daf183a4cccbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maria=20Jos=C3=A9=20Ferreira?= <171664470+MariaJoseFF@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:57:22 +0200 Subject: [PATCH 2/3] Potential fix for pull request finding The xref anchor #bpa-gate-keys does not correspond to any heading in te-cli-config.md (the closest relevant section is ### Built-in BPA rules). Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- content/features/te-cli/te-cli-commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/features/te-cli/te-cli-commands.md b/content/features/te-cli/te-cli-commands.md index 4dce3987..609e1805 100644 --- a/content/features/te-cli/te-cli-commands.md +++ b/content/features/te-cli/te-cli-commands.md @@ -441,7 +441,7 @@ Each `te bpa run` invocation assembles rules from three independent layers: - `-r, --rules ` flag (highest) - `TE_BPA_RULES` environment variable - `bpa.rules` array from CLI config (`~/.config/te/config.json`) -2. **Built-in defaults** - loaded unless `--no-defaults` is passed or [`bpa.builtInRules`](xref:te-cli-config#bpa-gate-keys) is `false` in config. Individual built-ins listed in `bpa.disabledBuiltInRuleIds` are skipped. +2. **Built-in defaults** - loaded unless `--no-defaults` is passed or [`bpa.builtInRules`](xref:te-cli-config#built-in-bpa-rules) is `false` in config. Individual built-ins listed in `bpa.disabledBuiltInRuleIds` are skipped. 3. **Model-embedded rules** - rules in the model's `BestPracticeAnalyzer_Rules` annotation, loaded unless `--no-model-rules` is passed. External URL annotations are skipped unless `--allow-external-rules` is also passed. Duplicate rule IDs are de-duplicated (user rules win over built-ins). Rule IDs in the model's `BestPracticeAnalyzer_IgnoreRules` annotation are then removed. From 19c25231876702b0844c813b93b1ba64d67d2ad8 Mon Sep 17 00:00:00 2001 From: Maria Jose Ferreira Fernandes <171664470+MariaJoseFF@users.noreply.github.com> Date: Wed, 3 Jun 2026 12:35:29 +0200 Subject: [PATCH 3/3] Align --rules placeholder in te bpa run docs with CLI help output - Change (line 410) and (line 441) to , matching what te bpa run --help prints. The placeholder is auto-derived from the option name in TabularEditor3.CLI/Commands/BpaCommand.cs and no HelpName override is set, so is the canonical label users see. - Preserve the path-or-URL clarification: line 410's description already reads "path(s) or URL(s) to BPA rule file(s) in JSON format"; line 441's priority-list entry now reads "flag, accepts a file path or URL (highest)" so the clarification is retained without duplicating it in the placeholder. --- content/features/te-cli/te-cli-commands.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/features/te-cli/te-cli-commands.md b/content/features/te-cli/te-cli-commands.md index 609e1805..57c8f503 100644 --- a/content/features/te-cli/te-cli-commands.md +++ b/content/features/te-cli/te-cli-commands.md @@ -407,7 +407,7 @@ Run Best Practice Analyzer rules against a model. `te bpa run` accepts: - `` - positional argument: path to model (alternative to the `--model` global flag). -- `-r, --rules ` - path(s) or URL(s) to BPA rule file(s) in JSON format. Repeatable. Replaces the user-rule layer for this invocation: see [Rule sources and resolution](#rule-sources-and-resolution) below. +- `-r, --rules ` - path(s) or URL(s) to BPA rule file(s) in JSON format. Repeatable. Replaces the user-rule layer for this invocation: see [Rule sources and resolution](#rule-sources-and-resolution) below. - `--no-model-rules` - exclude BPA rules embedded in the model's annotations. - `--no-defaults` - exclude built-in default BPA rules. - `--vpax ` - load VertiPaq Analyzer stats from a `.vpax` file to enable VPA-aware rules. @@ -438,7 +438,7 @@ te bpa run --path Sales/Measures # Path filter applied to the matched tables Each `te bpa run` invocation assembles rules from three independent layers: 1. **User rules** - exactly one source wins, in priority order: - - `-r, --rules ` flag (highest) + - `-r, --rules ` flag, accepts a file path or URL (highest) - `TE_BPA_RULES` environment variable - `bpa.rules` array from CLI config (`~/.config/te/config.json`) 2. **Built-in defaults** - loaded unless `--no-defaults` is passed or [`bpa.builtInRules`](xref:te-cli-config#built-in-bpa-rules) is `false` in config. Individual built-ins listed in `bpa.disabledBuiltInRuleIds` are skipped.