Repository navigation
Model eBay's Buy Browse scope beside the Sell Inventory modules - #10983
Conversation
extdeps.ebay.browse adds the buy-side scope of the existing eBay subject: the search and getItem operations, their response shapes read from the published buy_browse_v1_oas3 contract (v1.20.4), the numeric condition-ID table decoded onto the existing ConditionEnum, a typed search-filter grammar that cannot write a price without its currency, the contextualLocation header delivered price depends on, and the upstream fact that production Buy access is an eBay Partner Network application with no guaranteed approval. The 5,000/day Browse call limit joins extdeps.ebay.rate_limits, so product.capacity.quota derives its pool with no second authority; the ISO 4217 alphabetic code joins extdeps.currency.currency. The two new operations get published mock cases and the module enrolls as a scope carrier. developer.ebay.com returns 403 to our fetches; the contract was read from a mirror of eBay's published OpenAPI file and the prose facts from web.archive.org captures of the cited pages (2026-05/06). Closed by source inspection only here: no session route executes .dag witnesses, so test.claim.ebay_browse_witness first executes in CI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
…tity join Review 63298 findings, all taken: - BrowsePriceAtMost carries a MoneyAmountMicro, rendered through std.decimal fixed_point_wire at the filter boundary, instead of a string beside a typed currency. - BrowseConvertedAmount types currency and convertedFromCurrency as CurrencyCode, matching the Sell scope's EbayAmount, so the one eBay money-on-the-wire fact no longer has a weaker second shape. - parse_currency_alphabetic_code is removed: with the currency fields typed it had no production consumer. - capacity_quota_witness joins the rate-limit roster against the published scope keys in both directions instead of a count literal. Also fixes the four parse errors CI reported at f29da9a: annotations before test fns attach to nothing, and a literal brace in a string began interpolation. The search operation drops its category_ids input, which no consumer supplies. Executed locally with a gunbc built today (/cargo-target/release/gunbc): all eleven Browse witnesses pass. A condition-table mutation reds exactly the two witnesses that depend on the row, and removing the buy_browse key from the expected set reds the quota join. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63298 in b06a8ca. All four findings were right.
The commit also fixes the parse errors CI reported at f29da9a: annotations in front of How this was checked. I ran it locally with a
Pre-existing, not from this PR. |
…ge boundary Review 63312: browse_search_limit_max and browse_search_result_window were rows no fold read, and "offset must be a multiple of limit" was a comment. browse_search_page_admission now refuses a limit outside 1..200, an offset that is not a page boundary, and a page past the 10,000-item window, each as its own typed arm, before a request is formed. The witness covers the admitted page and all three refusals. Also imports CoverageClosureFact beside CoverageClosureEntry, as every sibling that writes Subject/JsonPending rows does. The module already resolved without it (record-literal constructors bind by corpus-wide uniqueness, and the witnesses executed), so this is conformance, not a compile fix. Executed locally with /cargo-target/release/gunbc: all twelve Browse witnesses pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63312 in the commit after b06a8ca.
I ran the Browse witness suite locally again: all twelve pass. — sent from sunny-carp-475 |
Review 63325: browse_production_access had no reader in the public closure and no declared frontier. ebay_browse_frontier_rows now names it and the two response types (BrowseItem, BrowseSearchPagedCollection), each with a dissolution that names the capability rather than an artifact. Approved access PLUS an observed response body folded on an executing entry fires them; approval alone, a fixture body, or a witness that the row exists does not. This follows the extdeps.backblaze.b2 frontier-row precedent. The witness checks the rows are well formed. Executed locally: all thirteen Browse witnesses pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63325 in 77c7198. I kept the row rather than dropping it: production access is an upstream fact about this subject, and deleting it would push the fact down into the consumer. What was missing is the declared frontier, so |
|
On review 63332's non-blocking note: agreed that — sent from sunny-carp-475 |
Review 63363: SearchItemSummaries defaulted limit to browse_search_limit_max, so an omitted limit went out as 200 where upstream's published default is 50. browse_search_limit_default = 50 is now the operation default. 200 stays the admission ceiling only, and a caller wanting larger pages says so, which is policy the consumer owns. The witness admits the default page. All thirteen Browse witnesses pass locally. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63363 in 895484e. The finding was right: an omitted |
Review 63380: ebay_browse_frontier_rows had only a shape check beside it, so the declared debt was invisible to gunbc.dissolution_census. The rows are now concatenated into gunbc.census_closure_frontier next to backblaze_b2_frontier_rows, and the witness asserts census membership for each row, the Cloudflare pattern. Executed locally: all thirteen Browse witnesses pass, and annotation_carrier's census_closure_frontier_rows_well_formed holds over the enlarged census. Removing the enrollment line reds the Browse membership check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63380 in 0fab94e. Checked locally:
|
CI's build lane at 0fab94e failed generated-artifact stage0-mirrors on extdeps_currency_currency.rs: the mirror did not carry the currency_alphabetic_code this branch added. Regenerated locally with a claim_executor built from this tree after merging origin/main (--required-regen). That file was the only drift across the candidate src/ tree, and the diff is the one function. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
CI at 650621d, attempt 1: none of the failures is in this change.
The stage0 mirror drift that reddened 0fab94e is fixed in 650621d. I checked it locally with I cancelled the attempt-2 rerun rather than spend runner slots re-measuring the main defect. I'll merge main and push once the repair lands. — sent from sunny-carp-475 |
# Conflicts: # dag/gunbc/extdeps_scope_frontier.dag
Review 63740: both Browse operations took marketplace_id as a NonEmptyStr, beside an annotation documenting that upstream silently substitutes EBAY_US for an invalid or missing ID. Both now take extdeps.ebay.ebay MarketplaceEnum, the type the Sell scope already uses, encoded by marketplace_wire_contract, so neither a missing nor a misspelled marketplace is writable. All thirteen Browse witnesses pass locally, and there is no stage0 mirror for this module. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63740 in d8b48c1. |
Review 63756: length(ebay_browse_frontier_rows) == 3 was a count copied from the tree. The witness now joins the rows against the three expected subjects (browse_production_access, BrowseItem, BrowseSearchPagedCollection) in both directions, the same shape as the quota witness's key join. Executed locally: passes clean, and a mutant that points one row at BrowseItemSummary reds it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r
|
Addressed review 63756 in a2358c0. The count is gone. |
# Conflicts: # dag/gunbc/extdeps_scope_frontier.dag
briansrls
left a comment
There was a problem hiding this comment.
The modeled eBay Browse authority is the right prerequisite for private #58, and I have no content objection at this head. Please refresh this branch onto current public main and rerun witnesses before merging: the only green run is against base f078c59, while current main has advanced by 13 commits. Private #58 must then rebase on private #65's detached-worktree composition fix and consume the landed symbols.
First of two PRs for the buyer-agent pipeline (
buyer-agent-pipeline, gunbc-privatestrategy.year_end_plan). This one covers exit-criterion part 1: the marketplace as a cited upstream, with the sheet's columns derivable from the API's real response shape. The pipeline itself (ListingObservation, the three-valued attribute sheet, PurchaseIntent) lands in gunbc-private and consumes this PR.What lands
extdeps.ebay.browse: the Buy Browse scope of the existing eBay subject, added next toinventory.dagrather than as a second eBay module tree (DESIGN §3, external upstream decomposition).ebay.Browse.SearchItemSummariesandebay.Browse.GetItem. Both are readonly and use application-token auth against the existingextdeps.ebay.oauthapi_scope_root.buy_browse_v1_oas3contract (v1.20.4). Modeled fields are the ones a buyer adjudicates; the rest are listed per type inCoverageClosureEntryresiduals, so nothing is dropped silently.ConditionEnum: same concept, different wire. That makes it one table in both directions, not a second enum. Unlisted IDs decode toAbsent, andMANUFACTURER_REFURBISHEDhas no ID, so encoding it refuses.priceandpriceCurrencyrender together, so a price without its currency can't be written.browse_contextual_location_headerbuilds theX-EBAY-C-ENDUSERCTXheader. Without it, calculated shipping isn't returned and a delivered price can't be formed.browse_production_accessrecords the upstream fact that production Buy access is an eBay Partner Network application with no guaranteed approval. The private pipeline consumes it as an intervention whose outcome can be a refusal.extdeps.ebay.rate_limits: addsebay_buy_browse_rate_limit, 5,000/day.product.capacity.quotaderives its pool unchanged, so the cadence is derivable, not asserted.capacity_quota_witnessnow counts 11 scopes, up from 10.extdeps.currency.currency: adds the ISO 4217 alphabetic code and its parse.browse.dagenrolled inscope_carrier_paths.test.claim.ebay_browse_witness: decode and round-trip controls, the full filter rendering, two filter refusals, the header against eBay's own example, and the rate-limit row.Consumers of these declarations (DESIGN §3c)
test.claim.ebay_browse_witness. They run:The rate-limit row is consumed by
product.capacity.quotathroughcapacity_quota_witness's identity join.browse_production_access: consumed by the private buyer pipeline in its companion change. It uses them for the Browse fold into listing evidence, the access standing, and the schedule's result-window check.Findings that change the downstream shape
ItemSummaryhas nolocalizedAspects,mpnorproduct. Rank, speed, capacity and MPN therefore cost onegetItemper candidate, and the scan cadence has to be derived from candidate volume against 5,000/day.priceplusshippingOptions[].shippingCost, evaluated at the buyer'scontextualLocation.Provenance and evidence standing
hendt/ebay-apispecs/buy_browse_v1_oas3.json,info.version1.20.4)..dagwitnesses, sotest.claim.ebay_browse_witnessfirst runs in CI.🤖 Generated with Claude Code
https://claude.ai/code/session_01X7jMc5D8JFmu8US1ZaZk6r