Skip to content

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

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 29, 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: Added unit tests (OptionsResourceTest) for the chain endpoint's dte parameter's new wire forms: comma-separated list, closed range, and comparison operator (one wire test per operator GT/GTE/LT/LTE), plus validation tests for empty/negative list, min>max range, negative range/comparison values — all against new ExpirationFilter.dteList/dteRange/dteComparison/Operator symbols, additive alongside the existing dte(int). Added integration tests (OptionsIntegrationTest) deriving a live baseline dte set per test and asserting list/range/comparison results against candidates computed from that baseline, never an exact value assumed in advance; left "closest" tie-breaking and bound inclusivity unasserted since the response can't verify them. Added the compat probe exercising today's ExpirationFilter.dte(int) + chain/chainAsync, verified it still compiles. No production code touched.
gradle compileTestJava --no-daemon --console=plain and gradle test --no-daemon --console=plain both fail with "cannot find symbol" on the new dteList/dteRange/dteComparison/Operator references in OptionsResourceTest.java, as expected for phase 1; the compat probe file itself produced no errors in either run.

implement: Implemented the dte chain parameter's widened type: ExpirationFilter.dteList/dteRange/dteComparison (plus a new Operator enum GT/GTE/LT/LTE) as additive sealed-interface variants alongside the unchanged dte(int), wired through OptionsResource.applyExpirationFilter.
Docs: every new method/type documented with javadoc and an example in docs/options/chain.md and OptionsAdvancedExample.java.
New-member docs: static factories and the Operator enum have javadoc, matching the sibling StrikeFilter convention of no per-record/per-constant javadoc.
Wire tests: one per form (list, range) plus one per operator (GT/GTE/LT/LTE) were already written in phase 1 and now pass.
Validation: moved into each new record's compact constructor (not just the static factory), so new ExpirationFilter.DteList(...) etc. validate too; List.copyOf rejects null elements, empty-list and negative-value checks are explicit.
Coverage: no @Generated exclusions added; jacocoTestCoverageVerification (100% line) passes on the new code as written.
Examples/docs already showing the area (README, OptionsExample, quotes.md) use forms unaffected by this change and remain correct; chain.md and OptionsAdvancedExample.java updated.
Docs promise only what's validated: "non-empty list", "min <= max" mirror actual checks; range/comparison inclusivity text cites StrikeFilter's existing documentation of the same grammar rather than asserting new observed behavior.
ExpirationFilter.dte(int) is untouched, so it keeps accepting everything it did.
Left unchanged: docs/adr/ADR-008 (historical record of variants as of its acceptance date, not a living inventory) and docs/.sync-manifest.txt (auto-generated, self-marked do-not-hand-edit).
Outside my limits, checked and found no stale references needing a fix: .github/ISSUE_TEMPLATE/bug.yml and build.gradle.kts don't name dte specifically.
gradle test --no-daemon --console=plain and gradle build --no-daemon --console=plain both green (build includes Spotless and 100% JaCoCo line-coverage verification); gradle compileTestJava also green now that the phase-1 compat probe has been removed by the pipeline.

changelog: I've already called the StructuredOutput tool in my previous response to provide the summary and status. The changelog entry has been successfully added to CHANGELOG.md under the [Unreleased] section, documenting the three new ExpirationFilter static factory methods and the Operator enum for API release 2.0.0.

Files

  • CHANGELOG.md
  • docs/options/chain.md
  • examples/consumer-test/src/main/java/com/marketdata/examples/resources/OptionsAdvancedExample.java
  • src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java
  • src/main/java/com/marketdata/sdk/OptionsResource.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: ExpirationFilter.dteList(List<Integer>) — New static factory method; existing ExpirationFilter.dte(int) is unchanged.
  • added: ExpirationFilter.dteRange(int, int) — New static factory method.
  • added: ExpirationFilter.dteComparison(ExpirationFilter.Operator, int) — New static factory method.
  • added: ExpirationFilter.Operator — New public enum with constants GT, GTE, LT, LTE and accessor wireValue(); a new enum at the end of a new type is additive.
  • added: ExpirationFilter.DteList — New permitted record subtype of sealed ExpirationFilter (field: days()); per this SDK's rule 9, a new permitted subtype of a sealed interface is added, not a change to the sealed parent.
  • added: ExpirationFilter.DteRange — New permitted record subtype of sealed ExpirationFilter (fields: min(), max()).
  • added: ExpirationFilter.DteComparison — New permitted record subtype of sealed ExpirationFilter (fields: operator(), days()).

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); this pull request's CI does.

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.


3 coder run(s) · 2 review(s) · 129 turns · 12,697,451 tokens · US$ 6.61 · item 5c097984-5f7b-401b-abba-235a3f417767

Agent runs
  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 3,024,459 tokens (125,332 in, 2,860,389 cached, 38,738 out) · 42 turns · US$ 1.47 · 7 min 23 s
  • coder · claude-sonnet-5 · 8,430,935 tokens (75,645 in, 8,319,967 cached, 35,323 out) · 63 turns · US$ 2.32 · 8 min 00 s
  • reviewer · claude-haiku-4-5-20251001, claude-opus-5 · 818,186 tokens (113,267 in, 682,896 cached, 22,023 out) · 11 turns · US$ 2.07 · 4 min 57 s
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 85,888 tokens (83,860 in, 0 cached, 2,028 out) · 2 turns · US$ 0.40 · 26 s
  • analyst · claude-haiku-4-5-20251001, claude-sonnet-5 · 168,416 tokens (42,866 in, 123,309 cached, 2,241 out) · 5 turns · US$ 0.23 · 26 s
  • changelog · claude-haiku-4-5-20251001 · 169,567 tokens (31,289 in, 132,657 cached, 5,621 out) · 6 turns · US$ 0.11 · 51 s

tests: Added unit tests (OptionsResourceTest) for the chain endpoint's dte parameter's new wire forms: comma-separated list, closed range, and comparison operator (one wire test per operator GT/GTE/LT/LTE), plus validation tests for empty/negative list, min>max range, negative range/comparison values — all against new `ExpirationFilter.dteList`/`dteRange`/`dteComparison`/`Operator` symbols, additive alongside the existing `dte(int)`. Added integration tests (OptionsIntegrationTest) deriving a live baseline dte set per test and asserting list/range/comparison results against candidates computed from that baseline, never an exact value assumed in advance; left "closest" tie-breaking and bound inclusivity unasserted since the response can't verify them. Added the compat probe exercising today's `ExpirationFilter.dte(int)` + chain/chainAsync, verified it still compiles. No production code touched.</summary>
<parameter name="status">`gradle compileTestJava --no-daemon --console=plain` and `gradle test --no-daemon --console=plain` both fail with "cannot find symbol" on the new `dteList`/`dteRange`/`dteComparison`/`Operator` references in OptionsResourceTest.java, as expected for phase 1; the compat probe file itself produced no errors in either run.

implement: Implemented the `dte` chain parameter's widened type: `ExpirationFilter.dteList`/`dteRange`/`dteComparison` (plus a new `Operator` enum GT/GTE/LT/LTE) as additive sealed-interface variants alongside the unchanged `dte(int)`, wired through `OptionsResource.applyExpirationFilter`.
Docs: every new method/type documented with javadoc and an example in docs/options/chain.md and OptionsAdvancedExample.java.
New-member docs: static factories and the `Operator` enum have javadoc, matching the sibling `StrikeFilter` convention of no per-record/per-constant javadoc.
Wire tests: one per form (list, range) plus one per operator (GT/GTE/LT/LTE) were already written in phase 1 and now pass.
Validation: moved into each new record's compact constructor (not just the static factory), so `new ExpirationFilter.DteList(...)` etc. validate too; `List.copyOf` rejects null elements, empty-list and negative-value checks are explicit.
Coverage: no `@Generated` exclusions added; `jacocoTestCoverageVerification` (100% line) passes on the new code as written.
Examples/docs already showing the area (README, OptionsExample, quotes.md) use forms unaffected by this change and remain correct; chain.md and OptionsAdvancedExample.java updated.
Docs promise only what's validated: "non-empty list", "min <= max" mirror actual checks; range/comparison inclusivity text cites `StrikeFilter`'s existing documentation of the same grammar rather than asserting new observed behavior.
`ExpirationFilter.dte(int)` is untouched, so it keeps accepting everything it did.
Left unchanged: docs/adr/ADR-008 (historical record of variants as of its acceptance date, not a living inventory) and docs/.sync-manifest.txt (auto-generated, self-marked do-not-hand-edit).
Outside my limits, checked and found no stale references needing a fix: `.github/ISSUE_TEMPLATE/bug.yml` and `build.gradle.kts` don't name `dte` specifically.</summary>
<parameter name="status">`gradle test --no-daemon --console=plain` and `gradle build --no-daemon --console=plain` both green (build includes Spotless and 100% JaCoCo line-coverage verification); `gradle compileTestJava` also green now that the phase-1 compat probe has been removed by the pipeline.</parameter>
</invoke>

changelog: I've already called the StructuredOutput tool in my previous response to provide the summary and status. The changelog entry has been successfully added to `CHANGELOG.md` under the `[Unreleased]` section, documenting the three new `ExpirationFilter` static factory methods and the `Operator` enum for API release 2.0.0.
@marketdata-sdk-sync marketdata-sdk-sync Bot added minor adds to the SDK's public surface and breaks nothing sdk-sync: in progress sdk-sync is still working on this PR: CI, code review, fixes labels Oct 29, 2026
@marketdata-sdk-sync

marketdata-sdk-sync Bot commented Oct 29, 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-29 13:23:38Z
Outcome done

Changes in the API surface

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

1. tests

Coder (42 turns, US$ 1.47, 7 min 23 s):

Added unit tests (OptionsResourceTest) for the chain endpoint's dte parameter's new wire forms: comma-separated list, closed range, and comparison operator (one wire test per operator GT/GTE/LT/LTE), plus validation tests for empty/negative list, min>max range, negative range/comparison values — all against new ExpirationFilter.dteList/dteRange/dteComparison/Operator symbols, additive alongside the existing dte(int). Added integration tests (OptionsIntegrationTest) deriving a live baseline dte set per test and asserting list/range/comparison results against candidates computed from that baseline, never an exact value assumed in advance; left "closest" tie-breaking and bound inclusivity unasserted since the response can't verify them. Added the compat probe exercising today's ExpirationFilter.dte(int) + chain/chainAsync, verified it still compiles. No production code touched.
gradle compileTestJava --no-daemon --console=plain and gradle test --no-daemon --console=plain both fail with "cannot find symbol" on the new dteList/dteRange/dteComparison/Operator references in OptionsResourceTest.java, as expected for phase 1; the compat probe file itself produced no errors in either run.

Gates:

  • compatibility probe on the base, attempt 1: passed (10 s)
  • tests (expected to fail), attempt 1: failed — Execution failed for task ':compileTestJava' (registered by plugin class 'org.gradle.api.plugins.JavaBasePlugin'). (8 s)

2. implement

Coder (63 turns, US$ 2.32, 8 min 00 s):

Implemented the dte chain parameter's widened type: ExpirationFilter.dteList/dteRange/dteComparison (plus a new Operator enum GT/GTE/LT/LTE) as additive sealed-interface variants alongside the unchanged dte(int), wired through OptionsResource.applyExpirationFilter.
Docs: every new method/type documented with javadoc and an example in docs/options/chain.md and OptionsAdvancedExample.java.
New-member docs: static factories and the Operator enum have javadoc, matching the sibling StrikeFilter convention of no per-record/per-constant javadoc.
Wire tests: one per form (list, range) plus one per operator (GT/GTE/LT/LTE) were already written in phase 1 and now pass.
Validation: moved into each new record's compact constructor (not just the static factory), so new ExpirationFilter.DteList(...) etc. validate too; List.copyOf rejects null elements, empty-list and negative-value checks are explicit.
Coverage: no @Generated exclusions added; jacocoTestCoverageVerification (100% line) passes on the new code as written.
Examples/docs already showing the area (README, OptionsExample, quotes.md) use forms unaffected by this change and remain correct; chain.md and OptionsAdvancedExample.java updated.
Docs promise only what's validated: "non-empty list", "min <= max" mirror actual checks; range/comparison inclusivity text cites StrikeFilter's existing documentation of the same grammar rather than asserting new observed behavior.
ExpirationFilter.dte(int) is untouched, so it keeps accepting everything it did.
Left unchanged: docs/adr/ADR-008 (historical record of variants as of its acceptance date, not a living inventory) and docs/.sync-manifest.txt (auto-generated, self-marked do-not-hand-edit).
Outside my limits, checked and found no stale references needing a fix: .github/ISSUE_TEMPLATE/bug.yml and build.gradle.kts don't name dte specifically.
gradle test --no-daemon --console=plain and gradle build --no-daemon --console=plain both green (build includes Spotless and 100% JaCoCo line-coverage verification); gradle compileTestJava also green now that the phase-1 compat probe has been removed by the pipeline.

Gates:

  • tests, attempt 1: passed (6 s)
  • build, attempt 1: passed (6 s)
  • compatibility probe, attempt 1: passed (7 s)

3. review 1

Reviewer (11 turns, US$ 2.07, 4 min 57 s): approved

The change is additive: three new ExpirationFilter variants (DteList, DteRange, DteComparison) plus a nested Operator enum, their wire encoding in applyExpirationFilter, and no existing public signature touched (version impact: minor). Wire tests cover all four dte forms and all four operator constants, validation lives in the record constructors so the public new path cannot bypass it and each branch has a test, and the five live tests derive their expectations from a baseline call and assert bounds in the inclusive/exclusive-agnostic way the brief requires. Only a documentation gap is worth noting.

  • [minor] docs/options/chain.md:46 — The new dte prose documents the four forms but drops two constraints the API's own description of the parameter carries: dte is relative to the date parameter when one is supplied (the page lists .date(LocalDate date) eight lines above, so a caller combining them is likely), and values are capped at 36500 days. Add both to this paragraph (and to the dteRange/dteComparison/dteList javadoc in src/main/java/com/marketdata/sdk/options/ExpirationFilter.java, which is equally silent on them).

4. security

Security (2 turns, US$ 0.40, 26 s): approved

This change adds three new sealed ExpirationFilter variants (DteList, DteRange, DteComparison) for the dte query parameter and wires them into query-string construction. All values are strictly typed as int/List<Integer>, validated in the record constructors, and formatted into the query string with no string concatenation of untrusted/free-form input, so there is no injection vector. No new dependencies, credentials, logging of sensitive data, or changes to TLS/trust settings are introduced; the rest of the diff (docs, example, tests) carries no runtime security impact.

  • no findings

5. assess

Analyst (5 turns, US$ 0.23, 26 s) — public surface:

The change adds a comma-separated list, a closed range, and a comparison form for the dte query parameter, mirroring the existing StrikeFilter grammar, while leaving the existing single-value ExpirationFilter.dte(int) factory and its wire translation untouched. ExpirationFilter gains three new permitted record subtypes (DteList, DteRange, DteComparison) plus a new nested Operator enum; these are new permitted subtypes of the sealed interface, which this SDK's own rules classify as additive rather than changing the sealed parent. The only non-public-surface code touched is OptionsResource.applyExpirationFilter, which is private static.

  • added: ExpirationFilter.dteList(List<Integer>) — New static factory method; existing ExpirationFilter.dte(int) is unchanged.
  • added: ExpirationFilter.dteRange(int, int) — New static factory method.
  • added: ExpirationFilter.dteComparison(ExpirationFilter.Operator, int) — New static factory method.
  • added: ExpirationFilter.Operator — New public enum with constants GT, GTE, LT, LTE and accessor wireValue(); a new enum at the end of a new type is additive.
  • added: ExpirationFilter.DteList — New permitted record subtype of sealed ExpirationFilter (field: days()); per this SDK's rule 9, a new permitted subtype of a sealed interface is added, not a change to the sealed parent.
  • added: ExpirationFilter.DteRange — New permitted record subtype of sealed ExpirationFilter (fields: min(), max()).
  • added: ExpirationFilter.DteComparison — New permitted record subtype of sealed ExpirationFilter (fields: operator(), days()).

Computed by the pipeline: minor; changelog entry written

6. changelog

Coder (6 turns, US$ 0.11, 51 s):

I've already called the StructuredOutput tool in my previous response to provide the summary and status. The changelog entry has been successfully added to CHANGELOG.md under the [Unreleased] section, documenting the three new ExpirationFilter static factory methods and the Operator enum for API release 2.0.0.

Gates:

  • build, attempt 1: passed (7 s)

Totals

  • Bump: minor
  • Coder runs: 3
  • Review runs: 2
  • Gates run: 6 (1 failed)
  • Files changed by the agent: 7
  • Turns: 129
  • Tokens: 12,697,451
  • Estimated cost: US$ 6.61
  • Time: 23 min 04 s (agents 22 min 03 s, gates 44 s)

Agent runs

  • coder · claude-haiku-4-5-20251001, claude-sonnet-5 · 3,024,459 tokens (125,332 in, 2,860,389 cached, 38,738 out) · 42 turns · US$ 1.47 · 7 min 23 s
  • coder · claude-sonnet-5 · 8,430,935 tokens (75,645 in, 8,319,967 cached, 35,323 out) · 63 turns · US$ 2.32 · 8 min 00 s
  • reviewer · claude-haiku-4-5-20251001, claude-opus-5 · 818,186 tokens (113,267 in, 682,896 cached, 22,023 out) · 11 turns · US$ 2.07 · 4 min 57 s
  • security · claude-haiku-4-5-20251001, claude-sonnet-5 · 85,888 tokens (83,860 in, 0 cached, 2,028 out) · 2 turns · US$ 0.40 · 26 s
  • analyst · claude-haiku-4-5-20251001, claude-sonnet-5 · 168,416 tokens (42,866 in, 123,309 cached, 2,241 out) · 5 turns · US$ 0.23 · 26 s
  • changelog · claude-haiku-4-5-20251001 · 169,567 tokens (31,289 in, 132,657 cached, 5,621 out) · 6 turns · US$ 0.11 · 51 s

Code review fix 1 — 2026-10-29 13:46:56Z

Outcome: done

Time: 8 min 42 s (agents 8 min 00 s, gates 42 s)

1. code review fix 1

The code review asked for changes:

  • [Should fix] Pin tests to one Eastern date (src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:137-282)
    Each test obtains DTE values from one live request and reuses them in a later request without fixing the date parameter. If the calls straddle midnight US/Eastern, the server's DTE values change and the exact-value and range assertions can fail; capture one Eastern date and pass it to both the baseline and filtered requests.
    Evidence: src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:137-282 — the filtered builders and baselineDtes() builder call .expirationFilter(...) without a shared .date(...).
  • [Should fix] Document the full DTE contract (src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:52-80)
    The new public documentation omits that DTE is relative to the request's date and capped at 36,500 days, despite documenting weaker validation as the complete constraint. Document both rules here and on docs/options/chain.md so callers do not infer that every non-negative integer is supported.
    Evidence: src/main/java/com/marketdata/sdk/options/ExpirationFilter.java:52-80 — “days must be non-empty, and every value non-negative” and “min must not exceed max.”
    Public-surface comparison:

Coder (32 turns, US$ 0.80, 3 min 55 s):

Fixed both review findings. 1) OptionsIntegrationTest.java: the five dte-filter tests and the shared baselineDtes() helper now capture one LocalDate.now(ZoneId.of("America/New_York")) per test and pass it via .date(...) to both the baseline call and the filtered call, so DTE values can't drift if the two live calls straddle US/Eastern midnight. 2) ExpirationFilter.java and docs/options/chain.md: javadoc for dte(int), dteList, dteRange, and dteComparison now states both omitted constraints — values are relative to the request's date parameter (to "today" when unset) and capped at 36,500 days — matching the API's own description; no new runtime validation was added since the finding asked only for documentation. No public-surface or behavior change, so CHANGELOG.md is left as-is.
gradle test --no-daemon --console=plain and gradle build --no-daemon --console=plain both green after gradle spotlessApply reformatted the new javadoc wrapping.

Gates:

  • tests, attempt 1: passed (7 s)
  • build, attempt 1: passed (6 s)
  • compatibility probe, attempt 1: passed (8 s)

2. review 1

Reviewer (5 turns, US$ 0.64, 1 min 27 s): 1 blocking finding(s)

The fix resolves the documentation finding cleanly — the 36,500-day cap and the date-relative rule are now on all four dte factories and on docs/options/chain.md, with no new client-side check and no public-surface or CHANGELOG impact. The date finding is only half resolved: the baseline and filtered calls now share one date, but it is still LocalDate.now(Eastern), so the suite now pins a single day that may not be a trading day — a failure mode the pre-fix version did not have.

  • [major] src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:144 — The fix shares one date between baseline and filtered call but still reads the wall clock: LocalDate.now(ZoneId.of("America/New_York")) is today, which on a weekend or market holiday is not a trading day, and OptionsChainRequest.Builder#date is documented as "Historical chain on a specific trading day" (src/main/java/com/marketdata/sdk/options/OptionsChainRequest.java:325). Before the fix no date was sent and the server chose the session; now baselineDtes' hasSizeGreaterThanOrEqualTo(2) can fail on any Saturday/Sunday/holiday run of the integration job. Pin a recent fixed trading day (one shared constant for the five tests) instead of today.
  • [minor] src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:139 — Question for a person, no fix proposed: these tests now ask for today's chain via date, but the parameter is documented as a historical end-of-day lookup; whether the API serves the live chain for the current date (and with which dte basis) is not something the release text or the SDK docs state. Worth confirming with the API team before this suite relies on it.

3. review fix 1

Findings sent back to the coder:

  • [major] src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:144 — The fix shares one date between baseline and filtered call but still reads the wall clock: LocalDate.now(ZoneId.of("America/New_York")) is today, which on a weekend or market holiday is not a trading day, and OptionsChainRequest.Builder#date is documented as "Historical chain on a specific trading day" (src/main/java/com/marketdata/sdk/options/OptionsChainRequest.java:325). Before the fix no date was sent and the server chose the session; now baselineDtes' hasSizeGreaterThanOrEqualTo(2) can fail on any Saturday/Sunday/holiday run of the integration job. Pin a recent fixed trading day (one shared constant for the five tests) instead of today.

Minor findings sent along, as optional:

  • [minor] src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:139 — Question for a person, no fix proposed: these tests now ask for today's chain via date, but the parameter is documented as a historical end-of-day lookup; whether the API serves the live chain for the current date (and with which dte basis) is not something the release text or the SDK docs state. Worth confirming with the API team before this suite relies on it.

Coder (18 turns, US$ 0.41, 1 min 38 s):

[major] Fixed: replaced the wall-clock LocalDate.now(ZoneId.of("America/New_York")) in the five dte-filter integration tests and baselineDtes() with a single new constant, DTE_FIXED_TRADING_DAY = LocalDate.of(2026, 10, 27) (a recent Tuesday, no US market holiday nearby), removing the dependence on which day/weekend the CI job happens to run on. Updated the surrounding comments and the baselineDtes() javadoc to describe pinning to a fixed trading day rather than an Eastern "today," and dropped the now-unused ZoneId import.
[minor] Not a separate fix: pinning to a fixed historical day (rather than today) also resolves the API-team question raised in this note, since .date() is now used exactly as documented — a historical trading day — rather than for "today." No further action taken; no one here can confirm server behavior beyond what the response itself shows, so nothing new is asserted about it.
gradle test --no-daemon --console=plain and gradle build --no-daemon --console=plain both green (build includes compileIntegrationTestJava, Spotless, and 100% JaCoCo coverage verification).

Gates:

  • tests, attempt 1: passed (6 s)
  • build, attempt 1: passed (7 s)
  • compatibility probe, attempt 1: passed (8 s)

4. review 2

Reviewer (5 turns, US$ 0.46, 48 s): approved

The fix replaces the wall-clock Eastern "today" with a single shared constant DTE_FIXED_TRADING_DAY = 2026-10-27 (a Tuesday two days before now, not a market holiday) used by all five dte tests and their baseline call, which resolves the previous major finding and leaves no clock read in the suite; it is within the recency range the suite's other tests use. No assertion was weakened — the baseline's hasSizeGreaterThanOrEqualTo(2), the exact-value, range, and bound-as-inclusive-or-exclusive checks are unchanged — and only comments otherwise differ. Pinning a past trading day also makes the previous minor question moot, since date is documented as a historical trading-day lookup.

  • no findings

5. security

Security (2 turns, US$ 0.16, 12 s): approved

The fix only touches documentation, Javadoc comments, and integration-test date pinning; no production logic, request construction, credentials, dependencies, or build/CI configuration changed. No security-relevant behavior was introduced or altered.

  • no findings

@codecov

codecov Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.29%. Comparing base (ff83a90) to head (6f3f6db).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main      #99      +/-   ##
============================================
+ Coverage     98.27%   98.29%   +0.02%     
- Complexity     1043     1049       +6     
============================================
  Files           123      123              
  Lines          2606     2644      +38     
  Branches        301      310       +9     
============================================
+ Hits           2561     2599      +38     
  Partials         45       45              
Files with missing lines Coverage Δ
.../main/java/com/marketdata/sdk/OptionsResource.java 98.57% <100.00%> (+0.04%) ⬆️
...a/com/marketdata/sdk/options/ExpirationFilter.java 98.07% <100.00%> (+3.07%) ⬆️

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 47b35ea...6f3f6db. 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 29, 2026 •

Copy link
Copy Markdown

🟡 Needs changes — Code review

Adds additive DTE list, range, and comparison filters for options chains, with documentation and unit/live tests; the existing dte(int) surface remains unchanged. Version impact: minor: all touched public symbols are unchanged or newly added, so there is no Java/Kotlin source or binary break.

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

Before merge

  • Proof: Provide a live integration run asserting that the selected baseline bound is included for GTE/LTE and excluded for GT/LT.

Findings

Should fix

  • src/integrationTest/java/com/marketdata/sdk/OptionsIntegrationTest.java:267-302 Live tests miss operator inclusivity (tests, a7c0a4b9)
    The GTE test passes if the API behaves as strict GT because it never requires the available bound, while the LT test passes for LTE because it allows the bound. Since each bound comes from the baseline, assert its presence for inclusive operators and absence for strict operators, including analogous GT and LTE checks.

    The GTE test only asserts q.dte()).isGreaterThanOrEqualTo(bound), and the LT test only asserts q.dte()).isLessThanOrEqualTo(bound).

Since last review

  • Resolved: 4267a299, d242b663
  • 0 still open, 1 new

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

code review fix 1: Fixed both review findings. 1) OptionsIntegrationTest.java: the five dte-filter tests and the shared `baselineDtes()` helper now capture one `LocalDate.now(ZoneId.of("America/New_York"))` per test and pass it via `.date(...)` to both the baseline call and the filtered call, so DTE values can't drift if the two live calls straddle US/Eastern midnight. 2) ExpirationFilter.java and docs/options/chain.md: javadoc for `dte(int)`, `dteList`, `dteRange`, and `dteComparison` now states both omitted constraints — values are relative to the request's `date` parameter (to "today" when unset) and capped at 36,500 days — matching the API's own description; no new runtime validation was added since the finding asked only for documentation. No public-surface or behavior change, so CHANGELOG.md is left as-is.</parameter>
<parameter name="status">`gradle test --no-daemon --console=plain` and `gradle build --no-daemon --console=plain` both green after `gradle spotlessApply` reformatted the new javadoc wrapping.</parameter>
</invoke>

review fix 1: [major] Fixed: replaced the wall-clock `LocalDate.now(ZoneId.of("America/New_York"))` in the five dte-filter integration tests and `baselineDtes()` with a single new constant, `DTE_FIXED_TRADING_DAY = LocalDate.of(2026, 10, 27)` (a recent Tuesday, no US market holiday nearby), removing the dependence on which day/weekend the CI job happens to run on. Updated the surrounding comments and the `baselineDtes()` javadoc to describe pinning to a fixed trading day rather than an Eastern "today," and dropped the now-unused `ZoneId` import.
[minor] Not a separate fix: pinning to a fixed historical day (rather than today) also resolves the API-team question raised in this note, since `.date()` is now used exactly as documented — a historical trading day — rather than for "today." No further action taken; no one here can confirm server behavior beyond what the response itself shows, so nothing new is asserted about it.</parameter>
<parameter name="status">`gradle test --no-daemon --console=plain` and `gradle build --no-daemon --console=plain` both green (build includes compileIntegrationTestJava, Spotless, and 100% JaCoCo coverage verification).</parameter>
</invoke>
@MarketDataDev03

Copy link
Copy Markdown
Collaborator

Closing to re-run the SDK sync for API 2.0.0 with the live-API gate for sdk-java.

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

Labels

minor adds to the SDK's public surface and breaks nothing review: needs changes sdk-sync: in progress sdk-sync is still working on this PR: CI, code review, fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant