Skip to content

fix(MachineLearningScorer, v1.2): splice metric_list verbatim instead of double-encoding - #7003

Open
Yicong-Huang wants to merge 1 commit into
release/v1.2from
backport/6805-splice-metric-list-verbatim-instead-of-d-v1.2
Open

fix(MachineLearningScorer, v1.2): splice metric_list verbatim instead of double-encoding #7003
Yicong-Huang wants to merge 1 commit into
release/v1.2from
backport/6805-splice-metric-list-verbatim-instead-of-d-v1.2

Conversation

@Yicong-Huang

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Backport of #6805 to release/v1.2, cherry-picked from 3a51bfb.

Source fix only. The test changes from #6805 were omitted: the touched test spec(s) do not exist on release/v1.2 (or depend on main-only test infrastructure), so backporting them cleanly is not possible. Only the source fix is carried over, per maintainer guidance.

Any related issues, documentation, discussions?

Backport of #6805. Originally linked #6790.

How was this PR tested?

Release-branch CI runs on this PR. The source change cherry-picked cleanly; test changes were intentionally dropped (see above).

Was this PR authored or co-authored using generative AI tooling?

Yes — backport prepared with Claude Code (mechanical cherry-pick + conflict resolution; the change itself is #6805 by its original author).

🤖 Generated with Claude Code

…uble-encoding (#6805)

### What changes were proposed in this PR?

Fixes a double-encoding bug in `MachineLearningScorerOpDesc` where the
selected metrics collapse into a single malformed `metric_list` element.

`getSelectedMetrics()` returns the chosen metric names as one
comma-separated, already-quoted fragment (e.g. `'Accuracy','F1 Score'`)
and is spliced into the generated Python as a list:

```
metric_list = [${getSelectedMetrics()}]
```

Its return type was **`EncodableString`**, so the Python template
builder **re-encoded the whole fragment as one Python string value**
instead of splicing it verbatim. The emitted code became:

```python
metric_list = [self.decode_python_template('J0FjY3VyYWN5JywnRjEgU2NvcmUn')]
```

where the base64 `J0FjY3VyYWN5JywnRjEgU2NvcmUn` decodes to
`'Accuracy','F1 Score'` — i.e. the entire quoted list collapses into
**one** decoded string element:

```python
metric_list = ["'Accuracy','F1 Score'"]   # ONE element, incl. inner quotes
```

instead of the intended:

```python
metric_list = ['Accuracy', 'F1 Score']
```

So every downstream `if 'X' in metric_list` and `for metric in
metric_list` / `metrics_func[metric]` operates on that single malformed
element — the selected metrics are never matched, and the classification
path hits a `KeyError` on the bogus key. The Scorer produces wrong/empty
output for both the classification and regression paths.

**Fix:** change `getSelectedMetrics()`'s return type from
`EncodableString` to plain `String`, so the builder splices it verbatim
into `metric_list = ['Accuracy','F1 Score']`. The method body is
unchanged.

```diff
-  private def getSelectedMetrics(): EncodableString = {
+  private def getSelectedMetrics(): String = {
     val metric = if (isRegression) regressionMetrics else classificationMetrics
     metric.map(metric => getMetricName(metric)).mkString("'", "','", "'")
   }
```

### Any related issues, documentation, discussions?

Closes #6790

### How was this PR tested?

Added a regression test to `MachineLearningScorerOpDescSpec` that
constructs the descriptor with `classificationMetrics = List(accuracy,
f1Score)`, calls `generatePythonCode()`, and asserts:
- the emitted code contains `metric_list = ['Accuracy','F1 Score']`
(verbatim), and
- the metric names are **not** base64-re-encoded through the template
builder.

Both assertions fail on `main` (the line is emitted as `metric_list =
[self.decode_python_template('J0FjY3VyYWN5JywnRjEgU2NvcmUn')]`) and pass
with this change.

Ran the full suite locally:

```
sbt "WorkflowOperator/testOnly org.apache.texera.amber.operator.machineLearning.Scorer.MachineLearningScorerOpDescSpec"
...
Tests: succeeded 7, failed 0, canceled 0, ignored 0, pending 0
All tests passed.
```

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.8)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

(backported from commit 3a51bfb)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Yicong-Huang Yicong-Huang added the release/v1.2 back porting to release/v1.2 label Jul 29, 2026
@Yicong-Huang
Yicong-Huang requested a review from xuang7 July 29, 2026 04:30
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @carloea2
    You can notify them by mentioning @carloea2 in a comment.

@Yicong-Huang Yicong-Huang removed the release/v1.2 back porting to release/v1.2 label Jul 29, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.37%. Comparing base (fd5f487) to head (b4ce5a0).
⚠️ Report is 2 commits behind head on release/v1.2.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                Coverage Diff                 @@
##             release/v1.2    #7003      +/-   ##
==================================================
- Coverage           53.95%   52.37%   -1.58%     
- Complexity           1441     2487    +1046     
==================================================
  Files                 809     1077     +268     
  Lines               34144    42267    +8123     
  Branches             3448     4548    +1100     
==================================================
+ Hits                18421    22138    +3717     
- Misses              14815    18819    +4004     
- Partials              908     1310     +402     
Flag Coverage Δ *Carryforward flag
access-control-service 64.61% <ø> (ø)
agent-service 34.36% <ø> (ø) Carriedforward from fd5f487
amber 52.47% <ø> (-7.14%) ⬇️
computing-unit-managing-service 1.65% <ø> (ø)
config-service 56.06% <ø> (ø)
file-service 58.59% <ø> (ø)
frontend 47.19% <ø> (ø) Carriedforward from fd5f487
pyamber 90.87% <ø> (ø) Carriedforward from fd5f487
python 90.74% <ø> (ø) Carriedforward from fd5f487
workflow-compiling-service 58.69% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

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

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants