Skip to content

test(verify): derive an operator's configuration from its schema - #8361

Draft
kz930 wants to merge 7 commits into
apache:mainfrom
kz930:feat/verify-derive-a-configuration
Draft

kz930 wants to merge 7 commits into
apache:mainfrom
kz930:feat/verify-derive-a-configuration

Conversation

@kz930

@kz930 kz930 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

An operator is configured by a form, and the form is generated from the
descriptor's own annotations. The same annotations are enough to fill it without
a human: an enum offers its constants, a column knob takes a column of the type
its rule allows, a numeric knob its declared bounds, and a conditional field is
filled only where the branch that shows it is taken.

@SampleColumn names the column a knob means where a type cannot say it: the
opening price among four numbers, the country code among several strings.

This produces one configuration. Turning that configuration into the several a
parity run needs is the change after this one, which is why this PR is now half
the size it was when it was opened. The two halves share no member: this side
reaches a value through buildObject, decide and valueFor, and the sweep
reaches its own through rowFills, columnFill and leafFill. Nothing was
rewritten to make the seam. Whole members moved out, and every line that stays
is the line that was there.

Any related issues, documentation, discussions?

Part of #8325, 21 of 27; that issue lists the set in order. This is the first
half of the configuration generator, and #8388 is the second.

Closes #8423, the task this change is the whole of.

How was this PR tested?

Seven tests here drive the generator across the config shapes it has to handle:
an operator with no config at all, a flat one with column knobs and an enum, a
nested list of objects with a free-form value, and the three ways a column knob
resolves, by sample, by type rule, and by staying off a column a sibling took.

Two of them read @SampleColumn on operators that carry it only after the
operator families land, earlier in the sequence than this change. Until those
merge, the two report the first column instead of the named one.

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

Generated-by: Claude Code (Opus 5)

An operator is configured by a form, and the form is generated from the
descriptor's own annotations. The same annotations are enough to fill it
without a human: an enum offers its constants, a column knob takes a column of
the type its rule allows, a numeric knob its declared bounds, and a
conditional field is filled only where the branch that shows it is taken.

This is one file because it is one decision made repeatedly — what a knob may
hold — and splitting it would put half of that decision on either side of a
boundary.

`@SampleColumn` names the column a knob means where a type cannot say it: the
opening price among four numbers, the country code among several strings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added feature common platform Non-amber Scala service paths labels Sep 2, 2026
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

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

  • No candidates found from git blame history.

@codecov-commenter

codecov-commenter commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.00%. Comparing base (7976744) to head (2e121b5).
⚠️ Report is 38 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8361      +/-   ##
============================================
- Coverage     94.11%   94.00%   -0.11%     
- Complexity     4811     4862      +51     
============================================
  Files          1197     1204       +7     
  Lines         48813    49076     +263     
  Branches       5906     5948      +42     
============================================
+ Hits          45939    46135     +196     
- Misses         1420     1465      +45     
- Partials       1454     1476      +22     
Flag Coverage Δ *Carryforward flag
access-control-service 80.18% <ø> (-0.82%) ⬇️
agent-service 99.32% <ø> (ø) Carriedforward from 4c59eb4
amber 90.08% <ø> (ø) Carriedforward from 4c59eb4
computing-unit-managing-service 77.14% <ø> (+3.47%) ⬆️
config-service 87.12% <ø> (+0.12%) ⬆️
file-service 83.65% <ø> (-4.27%) ⬇️ Carriedforward from 4c59eb4
frontend 96.86% <ø> (ø) Carriedforward from 4c59eb4
notebook-migration-service 83.73% <ø> (+4.42%) ⬆️
pyamber 98.47% <ø> (ø) Carriedforward from 4c59eb4
workflow-compiling-service 77.19% <ø> (ø) Carriedforward from 4c59eb4

*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.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 11 worse · ⚪ 4 noise (<±5%) · 0 without baseline

CI benchmark results are noisy; treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 379 0.232 27,135/33,877/33,877 us 🔴 +124.4% / 🔴 +110.0%
🔴 bs=100 sw=10 sl=64 944 0.576 105,743/139,352/139,352 us 🔴 +39.5% / 🔴 +28.2%
🔴 bs=1000 sw=10 sl=64 1,091 0.666 913,013/1,038,672/1,038,672 us 🔴 +10.8% / 🟢 -8.4%
Baseline details

Latest main ded7ba1 from 2026-09-10T13:35:13.323Z

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 379 tuples/sec 794.23 tuples/sec 755.28 tuples/sec -52.3% -49.8%
bs=10 sw=10 sl=64 MB/s 0.232 MB/s 0.485 MB/s 0.461 MB/s -52.1% -49.7%
bs=10 sw=10 sl=64 p50 27,135 us 12,270 us 12,957 us +121.2% +109.4%
bs=10 sw=10 sl=64 p95 33,877 us 15,100 us 16,134 us +124.4% +110.0%
bs=10 sw=10 sl=64 p99 33,877 us 23,414 us 20,333 us +44.7% +66.6%
bs=100 sw=10 sl=64 throughput 944 tuples/sec 1,066 tuples/sec 980.1 tuples/sec -11.4% -3.7%
bs=100 sw=10 sl=64 MB/s 0.576 MB/s 0.651 MB/s 0.598 MB/s -11.5% -3.7%
bs=100 sw=10 sl=64 p50 105,743 us 93,132 us 101,894 us +13.5% +3.8%
bs=100 sw=10 sl=64 p95 139,352 us 99,900 us 108,718 us +39.5% +28.2%
bs=100 sw=10 sl=64 p99 139,352 us 110,595 us 122,482 us +26.0% +13.8%
bs=1000 sw=10 sl=64 throughput 1,091 tuples/sec 1,118 tuples/sec 1,011 tuples/sec -2.4% +7.9%
bs=1000 sw=10 sl=64 MB/s 0.666 MB/s 0.682 MB/s 0.617 MB/s -2.4% +7.9%
bs=1000 sw=10 sl=64 p50 913,013 us 891,284 us 996,422 us +2.4% -8.4%
bs=1000 sw=10 sl=64 p95 1,038,672 us 937,543 us 1,037,670 us +10.8% +0.1%
bs=1000 sw=10 sl=64 p99 1,038,672 us 1,014,119 us 1,072,152 us +2.4% -3.1%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,527.12,200,128000,379,0.232,27134.99,33877.34,33877.34
1,100,10,64,20,2119.10,2000,1280000,944,0.576,105743.44,139352.46,139352.46
2,1000,10,64,20,18337.37,20000,12800000,1091,0.666,913013.21,1038671.90,1038671.90

@github-actions github-actions Bot removed the common label Sep 2, 2026
kz930 and others added 2 commits September 2, 2026 17:48
A candlestick reads four prices and the day they belong to, which a type
cannot tell apart; a choropleth reads a country code the same way, and a
value to shade it by that a type rule does narrow. Both are what the
annotation and the rule are for.

These read operators that land before this change does, so they belong here
rather than being added back afterwards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The generator did two jobs in one file: derive a valid configuration for an
operator from the annotations it already carries, and sweep that configuration
into the variants a parity run needs. At two thousand lines it was the largest
change in the export series and the only one that could not be read in one
sitting.

This change leaves the first job. The sweep follows as its own change on top of
it, restoring the members verbatim.

The two jobs share no member. The base pass reaches its values through
buildObject, decide and valueFor; the sweep reaches its own through rowFills,
columnFill and leafFill, and the four entry points that return variants are the
only callers of either. Nothing was rewritten to make the seam: whole members
moved out, and every line that stays is the line that was there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… above

Splitting the sweep out of this file moved members by their declaration, which
left the block of documentation above three of them behind. Each then sat over
the member that followed, describing something else: a JSON pointer helper's
text over the one that reads a field's key, a nested-row accessor's over the one
that reads a field's declared example, and a free-scalar test's over the type-id
registry.

None of them is wrong about the member it was written for. They travel with it.

The class's own header and the column-resolution comment lose the parts a reader
gets from the code beside them: an assembly strategy the next twenty lines carry
out, and a numbered list of the tiers an `orElse` chain already reads as.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 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.

The schema based configuration generator looks good.

@kz930
kz930 marked this pull request as draft September 4, 2026 17:12
ConfigGenerator names @SampleColumn in five places, and the annotation
itself was in the change that introduces the trait, where nothing reads
it. It is test-only metadata: it names the column in the shared fixture
that should fill an @AutofillAttributeName field, so a parity run reads a
realistic value rather than whatever the first column happens to hold.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The annotation is applied on operator fields, so it has to exist before
the first change that annotates one, which is ten steps earlier than this.
It goes there instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot removed the common label Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature platform Non-amber Scala service paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Derive an operator's configuration from its schema

3 participants