Skip to content

sdk-sync: API 2.0.0+ffb34b7 → sdk-java (minor) - #89

Closed
marketdata-sdk-sync[bot] wants to merge 2 commits into
mainfrom
sdk-sync/2.0.0-ffb34b7
Closed

marketdata-sdk-sync[bot] wants to merge 2 commits into
mainfrom
sdk-sync/2.0.0-ffb34b7

Conversation

@marketdata-sdk-sync

@marketdata-sdk-sync marketdata-sdk-sync Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Generated by sdk-auto-sync for API release 2.0.0 (commit ffb34b7).

Changes in the API surface

Snapshots ae2b047c8f6f → c2a31e277345:

~ GET /v1/options/chain/{underlying}/ ?dte: string  (was integer)

What the agent did

tests: Confirmed: the build fails as expected, with compilation errors on the not-yet-existing DteFilter type and the ExpirationFilter.dte(DteFilter) overload. No production code or existing test lines were touched.

Added tests for the dte parameter's type change (integer → string) on /v1/options/chain/{underlying}/, assuming a new DteFilter sealed type (values/range/comparison) plus an additive ExpirationFilter.dte(DteFilter) overload, leaving the existing dte(int) single-value overload untouched (regression already covered by the pre-existing chainExpirationFilterDteTranslatesToDteParam test):

  • Wire tests: comma-separated list, closed range, comparison operator (3 new forms; single-value form already tested).
  • Validation tests: empty list, negative/over-36500 entries for list/range/comparison, reversed range — all on the new DteFilter type only.
  • Integration tests: list (dedup bound), range (bounds check), comparison (operator check) against the live chain endpoint, asserting decoded dte values.
    gradle test --no-daemon --console=plain fails at compileTestJava as expected, since DteFilter doesn't exist yet.

implement: All changes are within src/main and src/test/src/integrationTest, no build/gradle/CI files touched, and no test was weakened.

Added DteFilter (sealed: Values/Range/Comparison, 0–36500 day validation) for the chain endpoint's dte string syntax, reached via a new, additive ExpirationFilter.dte(DteFilter) overload alongside the untouched dte(int) single-value form. Wired translation into OptionsResource.applyExpirationFilter/dteFilterWireValue (comma-join, dashed range, operator prefix). No test from phase 1 was weakened; gradle test and gradle build (incl. 100% JaCoCo and Spotless) pass clean.

review fix 1: All three findings addressed, no build/gradle/CI files touched, no CHANGELOG edit.

  • docs/options/chain.md:23 — added the three DteFilter forms (values/range/comparison) next to the dte(int) line with their wire shapes, added the DteFilter import and three example calls to the Java example block.
  • OptionsResourceTest.java:1004 — added chainExpirationFilterDteComparisonLtRendersWithOperatorPrefix, ...GtRendersWithOperatorPrefix, and ...LteRendersWithOperatorPrefix, asserting dte=%3C45, dte=%3E30, dte=%3C%3D45 respectively, so all four DteFilter.Operator constants now have a wire assertion.
  • OptionsIntegrationTest.java:152 — rewrote chainDteValuesReturnsAtMostAsManyDistinctExpirationsAsRequested (renamed to chainDteValuesReturnsClosestExpirationPerRequestedValue) to require 2–3 distinct expirations (ruling out the unfiltered front-month-only case) and to assert each row's dte() lands within 15 days of one of the requested values (7/30/60); this is a fix to a test I wrote in phase 1, not a weakening.

No production logic changed in this round beyond the doc; DteFilter/ExpirationFilter/OptionsResource wiring from phase 2 already covered the new operators, so only tests and docs needed updates.

changelog: Added changelog entry under [Unreleased] describing DteFilter sealed interface and extended dte parameter syntax (comma-separated lists, closed ranges, comparison operators) for the chain endpoint per Market Data API 2.0.0.

Files

  • CHANGELOG.md
  • docs/options/chain.md
  • src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java
  • src/main/java/com/marketdata/sdk/OptionsResource.java
  • src/main/java/com/marketdata/sdk/options/DteFilter.java
  • src/main/java/com/marketdata/sdk/options/ExpirationFilter.java
  • src/test/java/com/marketdata/sdk/OptionsResourceTest.java

Version

Public-surface change computed by the pipeline: minor

  • added: DteFilter — New sealed interface for extended dte parameter syntax supporting comma-separated lists, ranges, and comparisons.
  • added: DteFilter.Values — New sealed subtype of DteFilter for comma-separated list syntax.
  • added: DteFilter.Range — New sealed subtype of DteFilter for closed range syntax.
  • added: DteFilter.Comparison — New sealed subtype of DteFilter for comparison operator syntax.
  • added: DteFilter.Operator — New enum for comparison operators: GT, GTE, LT, LTE.
  • added: DteFilter.Operator.GT
  • added: DteFilter.Operator.GTE
  • added: DteFilter.Operator.LT
  • added: DteFilter.Operator.LTE
  • added: DteFilter.Operator.wireValue() — Returns the wire-form operator string (e.g. ">=" for GTE).
  • added: DteFilter.MAX_DAYS — Constant indicating maximum allowed days value (36500).
  • added: DteFilter.values(List) — Factory method to create a Values variant from a list of integers.
  • added: DteFilter.range(int, int) — Factory method to create a Range variant from min and max values.
  • added: DteFilter.comparison(Operator, int) — Factory method to create a Comparison variant from an operator and days value.
  • added: ExpirationFilter.dte(DteFilter) — New overload accepting DteFilter for extended syntax; original dte(int) remains unchanged.
  • added: ExpirationFilter.DteSyntax — New sealed subtype of ExpirationFilter for the extended dte syntax variant.

Live-API suite

  • src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java

Files of this suite changed by this pull request. The pipeline did not run the suite (it has no API token); the repository runs it with /integrationtest.

Job log

The full record of this job — every phase, test and build result, review findings and how they were resolved, and each fix round after the PR was opened — is in the job log comment.


4 coder run(s) · 3 review(s) · 96 turns · 8,222,126 tokens · US$ 5.48 · item 5c097984-5f7b-401b-abba-235a3f417767

Agent runs
  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 1,445,903 tokens (113,264 in, 1,299,093 cached, 33,546 out) · 20 turns · US$ 1.06
  • coder · claude-sonnet-5 · 3,018,645 tokens (21,978 in, 2,986,519 cached, 10,148 out) · 22 turns · US$ 0.79
  • reviewer · claude-haiku-4-5-20251001, claude-opus-5 · 851,217 tokens (97,568 in, 741,791 cached, 11,858 out) · 18 turns · US$ 1.68
  • coder · claude-sonnet-5 · 2,357,741 tokens (20,542 in, 2,328,879 cached, 8,320 out) · 15 turns · US$ 0.63
  • reviewer · claude-haiku-4-5-20251001, claude-opus-5 · 186,078 tokens (55,886 in, 126,193 cached, 3,999 out) · 6 turns · US$ 0.76
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 81,361 tokens (80,072 in, 0 cached, 1,289 out) · 2 turns · US$ 0.38
  • analyst · claude-haiku-4-5-20251001 · 135,315 tokens (34,631 in, 96,446 cached, 4,238 out) · 7 turns · US$ 0.11
  • changelog · claude-haiku-4-5-20251001 · 145,866 tokens (26,622 in, 117,332 cached, 1,912 out) · 6 turns · US$ 0.08

tests: Confirmed: the build fails as expected, with compilation errors on the not-yet-existing `DteFilter` type and the `ExpirationFilter.dte(DteFilter)` overload. No production code or existing test lines were touched.

Added tests for the `dte` parameter's type change (`integer` → `string`) on `/v1/options/chain/{underlying}/`, assuming a new `DteFilter` sealed type (`values`/`range`/`comparison`) plus an additive `ExpirationFilter.dte(DteFilter)` overload, leaving the existing `dte(int)` single-value overload untouched (regression already covered by the pre-existing `chainExpirationFilterDteTranslatesToDteParam` test):
- Wire tests: comma-separated list, closed range, comparison operator (3 new forms; single-value form already tested).
- Validation tests: empty list, negative/over-36500 entries for list/range/comparison, reversed range — all on the new `DteFilter` type only.
- Integration tests: list (dedup bound), range (bounds check), comparison (operator check) against the live chain endpoint, asserting decoded `dte` values.
`gradle test --no-daemon --console=plain` fails at `compileTestJava` as expected, since `DteFilter` doesn't exist yet.

implement: All changes are within `src/main` and `src/test`/`src/integrationTest`, no build/gradle/CI files touched, and no test was weakened.

Added `DteFilter` (sealed: `Values`/`Range`/`Comparison`, 0–36500 day validation) for the chain endpoint's `dte` string syntax, reached via a new, additive `ExpirationFilter.dte(DteFilter)` overload alongside the untouched `dte(int)` single-value form. Wired translation into `OptionsResource.applyExpirationFilter`/`dteFilterWireValue` (comma-join, dashed range, operator prefix). No test from phase 1 was weakened; `gradle test` and `gradle build` (incl. 100% JaCoCo and Spotless) pass clean.

review fix 1: All three findings addressed, no build/gradle/CI files touched, no CHANGELOG edit.

- `docs/options/chain.md:23` — added the three `DteFilter` forms (`values`/`range`/`comparison`) next to the `dte(int)` line with their wire shapes, added the `DteFilter` import and three example calls to the Java example block.
- `OptionsResourceTest.java:1004` — added `chainExpirationFilterDteComparisonLtRendersWithOperatorPrefix`, `...GtRendersWithOperatorPrefix`, and `...LteRendersWithOperatorPrefix`, asserting `dte=%3C45`, `dte=%3E30`, `dte=%3C%3D45` respectively, so all four `DteFilter.Operator` constants now have a wire assertion.
- `OptionsIntegrationTest.java:152` — rewrote `chainDteValuesReturnsAtMostAsManyDistinctExpirationsAsRequested` (renamed to `chainDteValuesReturnsClosestExpirationPerRequestedValue`) to require 2–3 distinct expirations (ruling out the unfiltered front-month-only case) and to assert each row's `dte()` lands within 15 days of one of the requested values (7/30/60); this is a fix to a test I wrote in phase 1, not a weakening.

No production logic changed in this round beyond the doc; `DteFilter`/`ExpirationFilter`/`OptionsResource` wiring from phase 2 already covered the new operators, so only tests and docs needed updates.

changelog: Added changelog entry under `[Unreleased]` describing `DteFilter` sealed interface and extended dte parameter syntax (comma-separated lists, closed ranges, comparison operators) for the chain endpoint per Market Data API 2.0.0.
@marketdata-sdk-sync marketdata-sdk-sync Bot added the sdk-sync: in progress sdk-sync is still working on this PR: CI, code review, fixes label Oct 5, 2026
@marketdata-sdk-sync

marketdata-sdk-sync Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Author

🧾 Job log — sdk-sync

sdk-auto-sync job log

API release 2.0.0 (commit ffb34b7)
SDK sdk-java
Branch sdk-sync/2.0.0-ffb34b7
API surface ae2b047c8f6f → c2a31e277345
Date 2026-10-05 15:49:27Z
Outcome done

Changes in the API surface

~ GET /v1/options/chain/{underlying}/ ?dte: string  (was integer)

1. tests

Coder (20 turns, US$ 1.06):

Confirmed: the build fails as expected, with compilation errors on the not-yet-existing DteFilter type and the ExpirationFilter.dte(DteFilter) overload. No production code or existing test lines were touched.

Added tests for the dte parameter's type change (integer → string) on /v1/options/chain/{underlying}/, assuming a new DteFilter sealed type (values/range/comparison) plus an additive ExpirationFilter.dte(DteFilter) overload, leaving the existing dte(int) single-value overload untouched (regression already covered by the pre-existing chainExpirationFilterDteTranslatesToDteParam test):

  • Wire tests: comma-separated list, closed range, comparison operator (3 new forms; single-value form already tested).
  • Validation tests: empty list, negative/over-36500 entries for list/range/comparison, reversed range — all on the new DteFilter type only.
  • Integration tests: list (dedup bound), range (bounds check), comparison (operator check) against the live chain endpoint, asserting decoded dte values.
    gradle test --no-daemon --console=plain fails at compileTestJava as expected, since DteFilter doesn't exist yet.

Gates:

  • tests (expected to fail), attempt 1: failed — Execution failed for task ':compileTestJava' (registered by plugin class 'org.gradle.api.plugins.JavaBasePlugin').

2. implement

Coder (22 turns, US$ 0.79):

All changes are within src/main and src/test/src/integrationTest, no build/gradle/CI files touched, and no test was weakened.

Added DteFilter (sealed: Values/Range/Comparison, 0–36500 day validation) for the chain endpoint's dte string syntax, reached via a new, additive ExpirationFilter.dte(DteFilter) overload alongside the untouched dte(int) single-value form. Wired translation into OptionsResource.applyExpirationFilter/dteFilterWireValue (comma-join, dashed range, operator prefix). No test from phase 1 was weakened; gradle test and gradle build (incl. 100% JaCoCo and Spotless) pass clean.

Gates:

  • tests, attempt 1: passed
  • build, attempt 1: passed

3. review 1

Reviewer (18 turns, US$ 1.68): 3 blocking finding(s)

The dte widening is modelled correctly: a new sealed DteFilter plus an additive ExpirationFilter.dte(DteFilter) overload, with the existing dte(int) and its validation untouched, so the public surface is additive (new type, new overload, new permitted sealed subtype) and the three new wire forms encode as the API describes. Two gaps remain: the docs/options/chain.md resource page still documents only the old filter variants, and the new Operator enum has a wire test for GTE only even though the API description itself enumerates <45. One new integration test also passes without the parameter reaching the wire.

  • [major] docs/options/chain.md:23 — The chain resource page enumerates the ExpirationFilter variants but was not updated for this change: ExpirationFilter.dte(DteFilter) and the new public DteFilter type (values/range/comparison, MAX_DAYS) are undocumented. Add the three new forms with their wire shapes (?dte=15,30,45, ?dte=0-45, ?dte=>=30) next to line 23, and the DteFilter import to the example block.
  • [major] src/test/java/com/marketdata/sdk/OptionsResourceTest.java:1004 — DteFilter.Operator is a new enum with four constants, but only GTE is asserted on the wire; LT — which the API description enumerates explicitly as <45 — and GT/LTE have no request assertion (the LT reference at line 1309 is a validation test, not a wire test). Add wire tests asserting dte=%3C45, dte=%3E30 and dte=%3C%3D45.
  • [major] src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:152 — chainDteValuesReturnsAtMostAsManyDistinctExpirationsAsRequested passes even if dte never reaches the wire: with no expiration filter the API returns the front-month only, so one distinct expiration also satisfies isLessThanOrEqualTo(3). Assert the comma-list actually took effect, e.g. distinctExpirations is between 2 and 3, or that each row's dte() is near one of 7/30/60.

4. review fix 1

Findings sent back to the coder:

  • [major] docs/options/chain.md:23 — The chain resource page enumerates the ExpirationFilter variants but was not updated for this change: ExpirationFilter.dte(DteFilter) and the new public DteFilter type (values/range/comparison, MAX_DAYS) are undocumented. Add the three new forms with their wire shapes (?dte=15,30,45, ?dte=0-45, ?dte=>=30) next to line 23, and the DteFilter import to the example block.
  • [major] src/test/java/com/marketdata/sdk/OptionsResourceTest.java:1004 — DteFilter.Operator is a new enum with four constants, but only GTE is asserted on the wire; LT — which the API description enumerates explicitly as <45 — and GT/LTE have no request assertion (the LT reference at line 1309 is a validation test, not a wire test). Add wire tests asserting dte=%3C45, dte=%3E30 and dte=%3C%3D45.
  • [major] src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:152 — chainDteValuesReturnsAtMostAsManyDistinctExpirationsAsRequested passes even if dte never reaches the wire: with no expiration filter the API returns the front-month only, so one distinct expiration also satisfies isLessThanOrEqualTo(3). Assert the comma-list actually took effect, e.g. distinctExpirations is between 2 and 3, or that each row's dte() is near one of 7/30/60.

Coder (15 turns, US$ 0.63):

All three findings addressed, no build/gradle/CI files touched, no CHANGELOG edit.

  • docs/options/chain.md:23 — added the three DteFilter forms (values/range/comparison) next to the dte(int) line with their wire shapes, added the DteFilter import and three example calls to the Java example block.
  • OptionsResourceTest.java:1004 — added chainExpirationFilterDteComparisonLtRendersWithOperatorPrefix, ...GtRendersWithOperatorPrefix, and ...LteRendersWithOperatorPrefix, asserting dte=%3C45, dte=%3E30, dte=%3C%3D45 respectively, so all four DteFilter.Operator constants now have a wire assertion.
  • OptionsIntegrationTest.java:152 — rewrote chainDteValuesReturnsAtMostAsManyDistinctExpirationsAsRequested (renamed to chainDteValuesReturnsClosestExpirationPerRequestedValue) to require 2–3 distinct expirations (ruling out the unfiltered front-month-only case) and to assert each row's dte() lands within 15 days of one of the requested values (7/30/60); this is a fix to a test I wrote in phase 1, not a weakening.

No production logic changed in this round beyond the doc; DteFilter/ExpirationFilter/OptionsResource wiring from phase 2 already covered the new operators, so only tests and docs needed updates.

Gates:

  • tests, attempt 1: passed
  • build, attempt 1: passed

5. review 2

Reviewer (6 turns, US$ 0.76): approved

All three findings from look 1 are resolved. The new LT/GT/LTE wire tests assert encodings that match DteFilter.Operator.wireValue() and HttpTransport.encodeQueryComponent, so they fail without the change; the integration test now proves the comma list reached the wire rather than passing on the unfiltered front-month default. No test was weakened and nothing new is wrong in what the fix touched.

  • no findings

6. security

Security (2 turns, US$ 0.38): approved

The change adds a sealed DteFilter type (Values/Range/Comparison) and wires it into the chain endpoint's ?dte= query parameter. All inputs feeding the query string are either validated integers (bounded 0–36500) or fixed enum wire strings, so there is no injection, path-traversal, secret-handling, or unsafe-default risk introduced by this diff.

  • no findings

7. assess

Analyst (7 turns, US$ 0.11) — public surface:

The change adds support for extended DTE filter syntax through a new sealed DteFilter interface with three variants (values list, closed range, and comparison), and adds a corresponding overload ExpirationFilter.dte(DteFilter) to accept this new type. All changes are additive; the existing ExpirationFilter.dte(int) method is unaffected.

  • added: DteFilter — New sealed interface for extended dte parameter syntax supporting comma-separated lists, ranges, and comparisons.
  • added: DteFilter.Values — New sealed subtype of DteFilter for comma-separated list syntax.
  • added: DteFilter.Range — New sealed subtype of DteFilter for closed range syntax.
  • added: DteFilter.Comparison — New sealed subtype of DteFilter for comparison operator syntax.
  • added: DteFilter.Operator — New enum for comparison operators: GT, GTE, LT, LTE.
  • added: DteFilter.Operator.GT
  • added: DteFilter.Operator.GTE
  • added: DteFilter.Operator.LT
  • added: DteFilter.Operator.LTE
  • added: DteFilter.Operator.wireValue() — Returns the wire-form operator string (e.g. ">=" for GTE).
  • added: DteFilter.MAX_DAYS — Constant indicating maximum allowed days value (36500).
  • added: DteFilter.values(List) — Factory method to create a Values variant from a list of integers.
  • added: DteFilter.range(int, int) — Factory method to create a Range variant from min and max values.
  • added: DteFilter.comparison(Operator, int) — Factory method to create a Comparison variant from an operator and days value.
  • added: ExpirationFilter.dte(DteFilter) — New overload accepting DteFilter for extended syntax; original dte(int) remains unchanged.
  • added: ExpirationFilter.DteSyntax — New sealed subtype of ExpirationFilter for the extended dte syntax variant.

Computed by the pipeline: minor; changelog entry written

8. changelog

Coder (6 turns, US$ 0.08):

Added changelog entry under [Unreleased] describing DteFilter sealed interface and extended dte parameter syntax (comma-separated lists, closed ranges, comparison operators) for the chain endpoint per Market Data API 2.0.0.

Gates:

  • build, attempt 1: passed

Totals

  • Bump: minor
  • Coder runs: 4
  • Review runs: 3
  • Gates run: 6 (1 failed)
  • Files changed by the agent: 7
  • Turns: 96
  • Tokens: 8,222,126
  • Estimated cost: US$ 5.48

Agent runs

  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 1,445,903 tokens (113,264 in, 1,299,093 cached, 33,546 out) · 20 turns · US$ 1.06
  • coder · claude-sonnet-5 · 3,018,645 tokens (21,978 in, 2,986,519 cached, 10,148 out) · 22 turns · US$ 0.79
  • reviewer · claude-haiku-4-5-20251001, claude-opus-5 · 851,217 tokens (97,568 in, 741,791 cached, 11,858 out) · 18 turns · US$ 1.68
  • coder · claude-sonnet-5 · 2,357,741 tokens (20,542 in, 2,328,879 cached, 8,320 out) · 15 turns · US$ 0.63
  • reviewer · claude-haiku-4-5-20251001, claude-opus-5 · 186,078 tokens (55,886 in, 126,193 cached, 3,999 out) · 6 turns · US$ 0.76
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 81,361 tokens (80,072 in, 0 cached, 1,289 out) · 2 turns · US$ 0.38
  • analyst · claude-haiku-4-5-20251001 · 135,315 tokens (34,631 in, 96,446 cached, 4,238 out) · 7 turns · US$ 0.11
  • changelog · claude-haiku-4-5-20251001 · 145,866 tokens (26,622 in, 117,332 cached, 1,912 out) · 6 turns · US$ 0.08

Code review fix 1 — 2026-10-05 16:06:42Z

Outcome: done

1. code review fix 1

The code review asked for changes:

  • [Should fix] Public constructors bypass validation (src/main/java/com/marketdata/sdk/options/DteFilter.java:88-95)
    The three public record constructors allow states rejected by the factories, such as an empty values list, a reversed or negative range, and a null comparison operator. Those values can produce invalid query strings or a late NullPointerException. Move the validation into compact record constructors so every public construction path enforces the same invariants.
    Evidence: record Values(List<Integer> days) implements DteFilter { ... }, record Range(int min, int max) implements DteFilter {}, and record Comparison(Operator operator, int days) implements DteFilter {} are public interface members without equivalent constructor validation.
  • [Should fix] Reachable null branch is excluded (src/main/java/com/marketdata/sdk/options/DteFilter.java:47-51)
    The comment says the null guard is unreachable, but Java callers can directly invoke DteFilter.comparison(null, 30). Marking the method @Generated hides this untested public branch from coverage; remove the annotation and add a test for the documented exception behavior.
    Evidence: // @Generated: the null-operator guard is unreachable through the public comparison factories followed by @Generated and static Comparison comparison(Operator operator, int days).

Coder (18 turns, US$ 0.39):

Both gates pass (gradle test and gradle build, including JaCoCo coverage and Spotless) on the first attempt.

Summary of findings addressed:

  • Public constructors bypass validation (DteFilter.java): moved all validation (non-empty/bounds for Values, bounds+ordering for Range, non-null operator+bounds for Comparison) into each record's compact constructor, so new DteFilter.Values(...), new DteFilter.Range(...), and new DteFilter.Comparison(...) now enforce the same invariants as the static factories, which now just delegate to the canonical constructors. Added tests calling the record constructors directly for the empty-list, reversed-range, and null-operator cases.
  • Reachable null branch excluded via @Generated: removed the @Generated annotation and its comment from comparison(...) (the check moved to Comparison's compact constructor, which is not annotated) and added dteFilterComparisonRejectsNullOperator, asserting DteFilter.comparison(null, 30) throws IllegalArgumentException.
  • Left StrikeFilter.java's identical @Generated/null-check pattern untouched — it's pre-existing code outside this PR's diff, not covered by these findings.
  • No CHANGELOG change: the existing [Unreleased] entry already documents "full validation" on the factories, and this fix only relocates that same validation to be enforced on every construction path, with the same exception type and messages.

Gates:

  • tests, attempt 1: passed
  • build, attempt 1: passed

2. review 1

Reviewer (12 turns, US$ 1.14): approved

The fix moves all three DteFilter invariants into the records' compact constructors and deletes the @Generated suppression, so every public construction path now validates and the null-operator branch is covered by new tests; behaviour through the factories is unchanged (same exception types and messages), so nothing in CHANGELOG.md or docs/options/chain.md goes stale and no public signature breaks. Line coverage stays reachable: each new throw line has a test (empty list, reversed range, null operator via both the factory and the canonical constructor). validateDays as a private static interface method is accessible from the nested records, and no existing test was weakened.

  • [minor] src/main/java/com/marketdata/sdk/options/DteFilter.java:81 — The now-explicit public canonical constructors of Range and Comparison reject inputs with IllegalArgumentException, but neither they nor the range/comparison factory javadoc state the constraint (min <= max, non-null operator, 0..MAX_DAYS). Add the constraint to the factory doc comments the way StrikeFilter.range does ("{@code min} must not exceed {@code max}").

3. security

Security (2 turns, US$ 0.21): approved

The fix moves validation into the DteFilter record compact constructors so all public construction paths (factories and direct record constructors) enforce the same invariants, and removes the stale @generated annotation, adding a test for the null-operator record path. This is a validation-hardening change with no new user-input-to-request path, no credential or logging exposure, and no build/dependency/CI changes — no security issue found.

  • no findings

@codecov

codecov Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.30%. Comparing base (d744f98) to head (749fc61).

Additional details and impacted files
@@             Coverage Diff              @@
##               main      #89      +/-   ##
============================================
+ Coverage     98.27%   98.30%   +0.03%     
- Complexity     1043     1054      +11     
============================================
  Files           123      124       +1     
  Lines          2606     2654      +48     
  Branches        301      308       +7     
============================================
+ Hits           2561     2609      +48     
  Partials         45       45              
Files with missing lines Coverage Δ
.../main/java/com/marketdata/sdk/OptionsResource.java 98.58% <100.00%> (+0.05%) ⬆️
...ain/java/com/marketdata/sdk/options/DteFilter.java 100.00% <100.00%> (ø)
...a/com/marketdata/sdk/options/ExpirationFilter.java 95.65% <100.00%> (+0.65%) ⬆️

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d744f98...749fc61. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@marketdata-code-review

marketdata-code-review Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

⛔ Blocked — Code review

The change adds additive DTE list, range, and comparison filters, wires them into option-chain requests, and documents and tests the new forms. Version impact: minor; existing Java and Kotlin callers retain the unchanged dte(int) surface.

Rating patch 5/6 (solid) · proof 3/6 (partial) · overall 3/6

Before merge

  • Proof: Run /integrationtest with an API token and provide the output showing the three new live DTE filter tests passing.

Since last review

  • Resolved: 31a70d8f, ad6530e8
  • 0 still open, 0 new

Reviewed 749fc61 · revision 2 · codex (gpt-5.6-sol) · claude unavailable · rules: default, sdk

code review fix 1: Both gates pass (`gradle test` and `gradle build`, including JaCoCo coverage and Spotless) on the first attempt.

Summary of findings addressed:
- Public constructors bypass validation (`DteFilter.java`): moved all validation (non-empty/bounds for `Values`, bounds+ordering for `Range`, non-null operator+bounds for `Comparison`) into each record's compact constructor, so `new DteFilter.Values(...)`, `new DteFilter.Range(...)`, and `new DteFilter.Comparison(...)` now enforce the same invariants as the static factories, which now just delegate to the canonical constructors. Added tests calling the record constructors directly for the empty-list, reversed-range, and null-operator cases.
- Reachable null branch excluded via `@Generated`: removed the `@Generated` annotation and its comment from `comparison(...)` (the check moved to `Comparison`'s compact constructor, which is not annotated) and added `dteFilterComparisonRejectsNullOperator`, asserting `DteFilter.comparison(null, 30)` throws `IllegalArgumentException`.
- Left `StrikeFilter.java`'s identical `@Generated`/null-check pattern untouched — it's pre-existing code outside this PR's diff, not covered by these findings.
- No CHANGELOG change: the existing `[Unreleased]` entry already documents "full validation" on the factories, and this fix only relocates that same validation to be enforced on every construction path, with the same exception type and messages.
@marketdata-sdk-sync

Copy link
Copy Markdown
Author

🙋 Needs a person — sdk-sync

Why: the code review blocked the PR (⛔ Blocked) with nothing the pipeline can act on

Nothing from the code review.

Code-review fix rounds used: 1 of 2 · CI repairs used: 0 of 2

What to do

  1. Read the review comment: it blocks the PR for a reason the pipeline cannot act on.
  2. Then mark the PR ready for review and comment @marketdata-code-review re-review: the review bot skips drafts. The pipeline does not touch this PR again.

This pull request is back to draft and labelled sdk-sync: needs human; the release row says PR_NEEDS_HUMAN_REVIEW.

@marketdata-sdk-sync
marketdata-sdk-sync Bot marked this pull request as draft October 5, 2026 16:27
@marketdata-sdk-sync marketdata-sdk-sync Bot added sdk-sync: needs human sdk-sync stopped: a person has to look (see the PR's comments) and removed sdk-sync: in progress sdk-sync is still working on this PR: CI, code review, fixes labels Oct 5, 2026
@MarketDataDev03
MarketDataDev03 deleted the sdk-sync/2.0.0-ffb34b7 branch October 7, 2026 15:20
@MarketDataDev03

Copy link
Copy Markdown
Collaborator

Closed to rerun the sdk-sync pipeline from scratch for API 2.0.0 (complete-change list, live suite in CI).

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: needs changes sdk-sync: needs human sdk-sync stopped: a person has to look (see the PR's comments)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant