Skip to content

feat: add persisted top-K categorical lumping - #2596

Open
Rana Singh (ranadeepsingh) wants to merge 5 commits into
microsoft:masterfrom
ranadeepsingh:copilot/ancient-1941-lump-features
Open

feat: add persisted top-K categorical lumping#2596
Rana Singh (ranadeepsingh) wants to merge 5 commits into
microsoft:masterfrom
ranadeepsingh:copilot/ancient-1941-lump-features

Conversation

@ranadeepsingh

Copy link
Copy Markdown
Collaborator

Summary

Recreates the valuable categorical-lumping proposal from #1941 for the current SynapseML codebase and addresses #1891.

  • implements LumpFeatures as a Spark ML Estimator plus persisted LumpFeaturesModel
  • preserves the multi-column lumpRules API, including Scala map, Java map, legacy JSON, and generated Python dict bindings
  • learns top-K values once during fit; transform never refits
  • ranks deterministically by count descending and value ascending
  • retains learned values, maps rare and unseen non-null values to an explicit otherValue, and makes null handling configurable
  • rejects real-data collisions with the other bucket
  • validates StringType-only v1 schemas and handles literal dotted, backtick, and count column names safely
  • persists learned state and supports estimator/model/pipeline serialization and copy behavior

This is a new implementation; it does not alter the ancient PR branch.

Validation

  • core/compile
  • core/testOnly com.microsoft.azure.synapse.ml.stages.LumpFeaturesSuite — 18 tests passed
  • core/scalastyle; core/Test/scalastyle
  • codegen
  • generated LumpFeatures.py and LumpFeaturesModel.py syntax-compiled with py_compile
  • final SynapseML code review: no concrete issues

Design notes

The initial API intentionally supports string columns only so the explicit other bucket cannot silently change numeric or boolean column types. Nulls are excluded from frequency counts and preserved by default; unseen non-null values always use the other bucket. Fitting fails if otherValue already occurs in any configured column, avoiding ambiguous category merges.

Related: #1941, #1891

Copilot AI lite review requested due to automatic review settings August 1, 2026 15:02
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Hey Rana Singh (@ranadeepsingh) 👋!
Thank you so much for contributing to our repository 🙌.
Someone from SynapseML Team will be reviewing this pull request soon.

We use semantic commit messages to streamline the release process.
Before your pull request can be merged, you should make sure your first commit and PR title start with a semantic prefix.
This helps us to create release messages and credit you for your hard work!

Examples of commit messages with semantic prefixes:

  • fix: Fix LightGBM crashes with empty partitions
  • feat: Make HTTP on Spark back-offs configurable
  • docs: Update Spark Serving usage
  • build: Add codecov support
  • perf: improve LightGBM memory usage
  • refactor: make python code generation rely on classes
  • style: Remove nulls from CNTKModel
  • test: Add test coverage for CNTKModel

To test your commit locally, please follow our guild on building from source.
Check out the developer guide for additional guidance on testing your change.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new core Spark ML stage to address high-cardinality categorical features by learning per-column top‑K string values at fit time and applying deterministic lumping at transform time, with full persistence/serialization support consistent with SynapseML’s Estimator/Model patterns.

Changes:

  • Introduces LumpFeatures (Estimator) and LumpFeaturesModel (Model) with multi-column lumpRules, deterministic top‑K selection, configurable null handling, and otherValue collision validation.
  • Implements persisted learned state via keptValuesJson and supports load/save, copy, and schema transformation behavior.
  • Adds a comprehensive Scala test suite covering ranking, null handling, collisions, schema/metadata behavior, special column names, and persistence round-trips.
Show a summary per file
File Description
core/src/main/scala/com/microsoft/azure/synapse/ml/stages/LumpFeatures.scala New Estimator/Model implementation for persisted top‑K categorical lumping with deterministic ranking, schema validation, and serialization.
core/src/test/scala/com/microsoft/azure/synapse/ml/stages/LumpFeaturesSuite.scala New unit tests validating behavior, edge cases, schema expectations, and persistence round-trip.

Review details

Suppressed comments (1)

core/src/main/scala/com/microsoft/azure/synapse/ml/stages/LumpFeatures.scala:227

  • handleNull='keep' currently only preserves nulls when the input schema marks the column as nullable; otherwise the expression coalesces nulls to otherValue. This makes runtime behavior depend on schema nullability and can violate the documented semantics that 'keep' preserves null. Refactor lumpExpr to preserve nulls whenever keepNulls is true, independent of schema nullability, and drop the inputNullable parameter.
      transformSchema(dataset.schema)
      val other = getOtherValue
      val keepNulls = getHandleNull == "keep"
      getKeptValues.foldLeft(dataset.toDF()) { case (acc, (name, values)) =>
        acc.withColumn(name, lumpExpr(name, values, other, keepNulls, acc.schema(name).nullable))
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread core/src/main/scala/com/microsoft/azure/synapse/ml/stages/LumpFeatures.scala Outdated
@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.89552% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.47%. Comparing base (0dfddd3) to head (8560216).

Files with missing lines Patch % Lines
...crosoft/azure/synapse/ml/stages/LumpFeatures.scala 95.89% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2596      +/-   ##
==========================================
+ Coverage   86.33%   86.47%   +0.14%     
==========================================
  Files         335      336       +1     
  Lines       18007    18275     +268     
  Branches     1658     1673      +15     
==========================================
+ Hits        15546    15803     +257     
- Misses       2461     2472      +11     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Rana Singh (ranadeepsingh) added a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 1, 2026
## Summary
Add dedicated transformer fuzzing coverage for LumpFeaturesModel so global experiment, serialization, Python, and R coverage gates recognize the persisted model.

## Prompting Intent
Repair the concrete UnitTests core failure from PR microsoft#2596 after Azure build 229219360 reported that LumpFeaturesModel had no directly registered fuzzers, while preserving all estimator tests.

## Linked Sources
- Pull request: microsoft#2596
- Failed Azure build: https://msdata.visualstudio.com/b9b2accc-2d1c-45b3-9d24-0eb5d78cc47f/_build/results?buildId=229219360
- Original proposal: microsoft#1941
- Feature request: microsoft#1891

## Rationale
Register a real TransformerFuzzing test object instead of exempting the model. This exercises deterministic transforms and model persistence while generating Python and R correspondence coverage expected by the repository-wide FuzzingTest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Rana Singh (ranadeepsingh) added a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 1, 2026
## Summary
Persist each fitted top-K alongside retained values and reject incompatible LumpFeaturesModel lumpRules mutations across direct setters, generic generated-binding transfer, copy overrides, and loaded models.

## Prompting Intent
Address the independent medium-severity API review finding on PR microsoft#2596 without removing API-compatible params. Ensure a fitted model can never silently score with learned values that disagree with a post-fit K, and cover persistence, copy, Scala, Java, JSON, and generated-binding paths.

## Linked Sources
- Pull request: microsoft#2596
- Original proposal: microsoft#1941
- Feature request: microsoft#1891
- Independent review finding supplied in the PR follow-up request
- No Azure DevOps work item was supplied; tracking is through the linked GitHub issue.

## Rationale
Encode the fitted top-K inside the existing model-only keptValuesJson state instead of adding another generated mutable parameter. Direct model setters fail immediately, while transform-time state validation protects generic Param paths used by generated bindings. Exact no-op rule assignment remains allowed, and incompatible copy overrides fail before returning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

Addressed the independent API review finding in 5443214:

  • fitted top-K is now persisted with retained values
  • Scala, Java, and JSON setLumpRules overloads reject incompatible post-fit changes immediately
  • generated-binding/generic Param mutations are rejected by model-state validation before scoring
  • incompatible copy(extra) overrides are rejected
  • persistence, loaded-model copy, no-op assignment, and mutation paths have regression coverage

Validation: 24 estimator tests, 4 model tests, 10 repository fuzzing checks, core compile/scalastyle, codegen, and generated-wrapper py_compile all passed.

copilot-pull-request-reviewer please re-review the updated head.

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

Follow-up API fix is now fully green on head 54432143d3:

  • all 76 GitHub/Azure checks passed
  • Azure build 229247329 succeeded
  • targeted estimator/model/fuzzing tests, scalastyle, codegen, and generated-wrapper syntax checks passed locally

Re-review requested for the fitted lumpRules immutability change.

Rana Singh (ranadeepsingh) added a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 4, 2026
## Summary
Add dedicated transformer fuzzing coverage for LumpFeaturesModel so global experiment, serialization, Python, and R coverage gates recognize the persisted model.

## Prompting Intent
Repair the concrete UnitTests core failure from PR microsoft#2596 after Azure build 229219360 reported that LumpFeaturesModel had no directly registered fuzzers, while preserving all estimator tests.

## Linked Sources
- Pull request: microsoft#2596
- Failed Azure build: https://msdata.visualstudio.com/b9b2accc-2d1c-45b3-9d24-0eb5d78cc47f/_build/results?buildId=229219360
- Original proposal: microsoft#1941
- Feature request: microsoft#1891

## Rationale
Register a real TransformerFuzzing test object instead of exempting the model. This exercises deterministic transforms and model persistence while generating Python and R correspondence coverage expected by the repository-wide FuzzingTest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ranadeepsingh
Rana Singh (ranadeepsingh) force-pushed the copilot/ancient-1941-lump-features branch from 5443214 to a676184 Compare August 4, 2026 18:33
Rana Singh (ranadeepsingh) added a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 4, 2026
## Summary
Persist each fitted top-K alongside retained values and reject incompatible LumpFeaturesModel lumpRules mutations across direct setters, generic generated-binding transfer, copy overrides, and loaded models.

## Prompting Intent
Address the independent medium-severity API review finding on PR microsoft#2596 without removing API-compatible params. Ensure a fitted model can never silently score with learned values that disagree with a post-fit K, and cover persistence, copy, Scala, Java, JSON, and generated-binding paths.

## Linked Sources
- Pull request: microsoft#2596
- Original proposal: microsoft#1941
- Feature request: microsoft#1891
- Independent review finding supplied in the PR follow-up request
- No Azure DevOps work item was supplied; tracking is through the linked GitHub issue.

## Rationale
Encode the fitted top-K inside the existing model-only keptValuesJson state instead of adding another generated mutable parameter. Direct model setters fail immediately, while transform-time state validation protects generic Param paths used by generated bindings. Exact no-op rule assignment remains allowed, and incompatible copy overrides fail before returning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (1)

core/src/main/scala/com/microsoft/azure/synapse/ml/stages/LumpFeatures.scala:297

  • parseKeptJson will throw a NullPointerException if keptValuesJson contains a null value (e.g., set via Java/Param APIs), which bypasses the intended IllegalArgumentException validation path. It should explicitly reject null JSON strings with a clear message before calling parseJson.
  private def parseKeptJson(name: String, json: String): JsValue =
    try json.parseJson
    catch {
      case NonFatal(e) =>
        throw new IllegalArgumentException(s"keptValuesJson for column '$name' is not valid JSON: '$json'.", e)
  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@ranadeepsingh
Rana Singh (ranadeepsingh) force-pushed the copilot/ancient-1941-lump-features branch from c818d70 to 50dfa51 Compare August 7, 2026 08:57
Rana Singh (ranadeepsingh) added a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 7, 2026
## Summary
Add dedicated transformer fuzzing coverage for LumpFeaturesModel so global experiment, serialization, Python, and R coverage gates recognize the persisted model.

## Prompting Intent
Repair the concrete UnitTests core failure from PR microsoft#2596 after Azure build 229219360 reported that LumpFeaturesModel had no directly registered fuzzers, while preserving all estimator tests.

## Linked Sources
- Pull request: microsoft#2596
- Failed Azure build: https://msdata.visualstudio.com/b9b2accc-2d1c-45b3-9d24-0eb5d78cc47f/_build/results?buildId=229219360
- Original proposal: microsoft#1941
- Feature request: microsoft#1891

## Rationale
Register a real TransformerFuzzing test object instead of exempting the model. This exercises deterministic transforms and model persistence while generating Python and R correspondence coverage expected by the repository-wide FuzzingTest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 7, 2026 08:57
Rana Singh (ranadeepsingh) added a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 7, 2026
## Summary
Persist each fitted top-K alongside retained values and reject incompatible LumpFeaturesModel lumpRules mutations across direct setters, generic generated-binding transfer, copy overrides, and loaded models.

## Prompting Intent
Address the independent medium-severity API review finding on PR microsoft#2596 without removing API-compatible params. Ensure a fitted model can never silently score with learned values that disagree with a post-fit K, and cover persistence, copy, Scala, Java, JSON, and generated-binding paths.

## Linked Sources
- Pull request: microsoft#2596
- Original proposal: microsoft#1941
- Feature request: microsoft#1891
- Independent review finding supplied in the PR follow-up request
- No Azure DevOps work item was supplied; tracking is through the linked GitHub issue.

## Rationale
Encode the fitted top-K inside the existing model-only keptValuesJson state instead of adding another generated mutable parameter. Direct model setters fail immediately, while transform-time state validation protects generic Param paths used by generated bindings. Exact no-op rule assignment remains allowed, and incompatible copy overrides fail before returning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rana Singh (ranadeepsingh) pushed a commit to ranadeepsingh/SynapseML that referenced this pull request Aug 7, 2026
## Summary
Persist the fit-time fallback inside learned categorical state, prevent all direct and generic mutation bypasses, keep copy and load behavior atomic, and make nullability match runtime output.

## Prompting Intent
Rebase PR microsoft#2596 onto current master and resolve review findings while keeping top-K scoring lean, deterministic, persisted, and compatible with Spark ML copy/load and generated language bindings.

## Linked Sources
- Pull request: microsoft#2596
- Original categorical lumping proposal: microsoft#1941
- Related issue: microsoft#1891
- Nullability review: microsoft#2596 (comment)

## Rationale
The reserved fallback is stored with the existing learned-state JSON rather than as a separately clearable Spark Param, so generated bindings expose no internal escape hatch. A compact in-memory snapshot restores and rejects generic mutations, copy extras are checked before transfer, and legacy artifacts are upgraded from their persisted fallback. Validation occurs once per schema/transform rather than per row.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 81d39bfc-927c-418a-90a8-e0f2cd8fc128
@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

## Summary
Add LumpFeatures as a Spark ML estimator with a persisted model, deterministic top-K learning, explicit other-bucket and null semantics, schema-safe transforms, generated bindings, and comprehensive tests.

## Prompting Intent
Recreate the valuable proposal from GitHub PR microsoft#1941 for current SynapseML without fitting during transform. Preserve lumpRules compatibility while covering persistence, copy behavior, special column names, unseen values, collisions, and Scala-first Python code generation.

## Linked Sources
- Original proposal PR: microsoft#1941
- Feature request: microsoft#1891
- No Azure DevOps work item was supplied; tracking is through the linked GitHub issue.

## Rationale
Learn category frequencies once in fit and persist only retained values so scoring is stable and side-effect free. Restrict v1 to string columns, rank ties by value, preserve nulls by default, and reject other-bucket collisions rather than silently merging real categories. Use Spark SQL expressions instead of UDFs and retain the multi-column lumpRules API.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Add dedicated transformer fuzzing coverage for LumpFeaturesModel so global experiment, serialization, Python, and R coverage gates recognize the persisted model.

## Prompting Intent
Repair the concrete UnitTests core failure from PR microsoft#2596 after Azure build 229219360 reported that LumpFeaturesModel had no directly registered fuzzers, while preserving all estimator tests.

## Linked Sources
- Pull request: microsoft#2596
- Failed Azure build: https://msdata.visualstudio.com/b9b2accc-2d1c-45b3-9d24-0eb5d78cc47f/_build/results?buildId=229219360
- Original proposal: microsoft#1941
- Feature request: microsoft#1891

## Rationale
Register a real TransformerFuzzing test object instead of exempting the model. This exercises deterministic transforms and model persistence while generating Python and R correspondence coverage expected by the repository-wide FuzzingTest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary
Persist each fitted top-K alongside retained values and reject incompatible LumpFeaturesModel lumpRules mutations across direct setters, generic generated-binding transfer, copy overrides, and loaded models.

## Prompting Intent
Address the independent medium-severity API review finding on PR microsoft#2596 without removing API-compatible params. Ensure a fitted model can never silently score with learned values that disagree with a post-fit K, and cover persistence, copy, Scala, Java, JSON, and generated-binding paths.

## Linked Sources
- Pull request: microsoft#2596
- Original proposal: microsoft#1941
- Feature request: microsoft#1891
- Independent review finding supplied in the PR follow-up request
- No Azure DevOps work item was supplied; tracking is through the linked GitHub issue.

## Rationale
Encode the fitted top-K inside the existing model-only keptValuesJson state instead of adding another generated mutable parameter. Direct model setters fail immediately, while transform-time state validation protects generic Param paths used by generated bindings. Exact no-op rule assignment remains allowed, and incompatible copy overrides fail before returning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rework the persisted top-K lumping stage so it is dependable as a training
feature-engineering step, not just correct on a single-column happy path.

Algorithm
- Add minCount and minFreq eligibility filters, applied before the lumpRules
  top-K cap. This matches the order scikit-learn's OneHotEncoder uses for
  min_frequency and max_categories, and R forcats / feature-engine use the
  same primary-threshold + secondary-cap shape. Top-K alone is blind to the
  distribution: it lumps healthy levels in a low-cardinality column, and in a
  long-tailed column it retains values covering almost none of the rows.
  Both default to no-ops, so existing behaviour is unchanged.
- Rewrite fit as a single pass. The rule columns are melted into
  (column, value) pairs and ranked with one windowed aggregation instead of
  one full scan per column plus a separate collision scan. Besides cutting
  fit from N+1 Spark jobs to 1, this guarantees every column is learned from
  the same materialization of the input; per-column jobs silently learn from
  different rows when the upstream plan is non-deterministic (sample, rand,
  unordered limit).

API
- Add an optional outputCols map so lumped values can be written to new
  columns instead of destroying the raw ones. Unset means in-place, so the
  default is unchanged. Destinations are validated (known source, non-empty,
  distinct, not already in the input schema) and ordered deterministically so
  transformSchema always matches transform.
- Fix the nullability contract: the declared schema now derives nullability
  from handleNull alone instead of intersecting it with the input column's
  nullability, so a non-nullable input under handleNull='keep' no longer
  declares a non-nullable output that the expression may not honour. This is
  the reviewer comment on the PR; the transform expression uses a typed null
  literal so declared and actual schemas agree on non-nullable inputs too.
- Expose the learned values to Python. LumpFeaturesModel becomes an internal
  wrapper with a hand-written override providing getKeptValues(), backed by a
  new getKeptValuesAsJson on the Scala model, so a fit can be audited from
  Python instead of being an opaque JSON param.

Docs and tests
- Document LumpFeatures in docs/Quick Examples with runnable Python and Scala
  examples; the stage was previously absent from the stages doc table.
- Add 13 tests covering the frequency filters and their ordering against the
  cap, per-column denominators, joint vs single-column fit agreement,
  outputCols behaviour/validation/round-trip, the non-nullable schema
  contract, and the JSON accessor. 41 tests pass, scalastyle clean on main
  and test, codegen and black clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3a108ab7-6879-4fa6-81de-ef2d43eb3ec5
## Summary
Persist the fit-time fallback inside learned categorical state, prevent all direct and generic mutation bypasses, keep copy and load behavior atomic, and make nullability match runtime output.

## Prompting Intent
Rebase PR microsoft#2596 onto current master and resolve review findings while keeping top-K scoring lean, deterministic, persisted, and compatible with Spark ML copy/load and generated language bindings.

## Linked Sources
- Pull request: microsoft#2596
- Original categorical lumping proposal: microsoft#1941
- Related issue: microsoft#1891
- Nullability review: microsoft#2596 (comment)

## Rationale
The reserved fallback is stored with the existing learned-state JSON rather than as a separately clearable Spark Param, so generated bindings expose no internal escape hatch. A compact in-memory snapshot restores and rejects generic mutations, copy extras are checked before transfer, and legacy artifacts are upgraded from their persisted fallback. Validation occurs once per schema/transform rather than per row.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 81d39bfc-927c-418a-90a8-e0f2cd8fc128
@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

Copilot AI review requested due to automatic review settings August 7, 2026 22:51
@ranadeepsingh
Rana Singh (ranadeepsingh) force-pushed the copilot/ancient-1941-lump-features branch from 50dfa51 to 8560216 Compare August 7, 2026 22:51
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@ranadeepsingh

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

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.

3 participants