You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
console marketplace: filter and page the catalog through the server's four facets #31267
Filing gate: ② follow-up owed by the #31173 landing (PR #31234, seat ACCEPT 6712743973 "Out of scope (1)"). ⛔ Not a claim.
Reader: domain:ui — ui/packages/app-shell/src/console/marketplace/MarketplacePage.tsx (the list read at L415), marketplaceApi.ts (listMarketplacePackages), marketplaceTaxonomy.ts (effectiveSolutionType).
Dedupe (open AND closed): marketplace facets console, listMarketplacePackages facets, solutionTypes console → none.
reach: every console user browsing the marketplace catalog once it holds more than 100 templates.
class: c · type: Enhancement
Grade: p3 — self-graded by the server seat (Ruling-ref: the maintainer, 「定级你可以自己决定」): the console works today on the first 100 rows; the facets only matter once the catalog grows.
listMarketplacePackages takes the four facets and sends each as a comma-joined query parameter, spelled exactly as the published spec names them: businessFunctions, industries, solutionTypes (plural; the card's solutionType is NOT what the server reads, an undeclared key is ignored) and maturity. OR within one facet, AND across facets, as the server applies them.
MarketplacePage.tsx stops reading the first 100 rows to filter in the browser; it passes the selected facet values and pages through limit / offset.
The server refuses with 400 VALIDATION_ERROR an undeclared facet value, a repeated facet key, an empty facet, and the retired ?category=. The console must send none of these (an unselected facet is omitted, not sent empty).
Row defaults agree already: a row without the columns reads solutionTypes = app and maturity = stable on the server, the same as effectiveSolutionType in the console. Keep the two in step.
Related: #31173, PR #31234, #31011 item 5, #30904 §6, cloud#3661 (the cloud list route adopts the same names).
Claim: PM loop round 2 · 2026-11-07T21:36Z
Session: session_01FEkQ5npnoTzeRFxu1Mj26Q (card thread, dev) · seat session_01FEkQ5nLA7wiVY5YWjT9Svr
Account: os-project-manager
Branch: claude/project-thread-044740
Worktree: objectstack-issue-31267
Domain: domain:ui
Seat: domain:ui#1
File surface: ui/packages/app-shell/src/console/marketplace/** (MarketplacePage.tsx, marketplaceApi.ts, marketplaceTaxonomy.ts) and their tests, root .changeset/
Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (follow-up owed by the #31173 landing, PR #31234)
Thread-read: 6712743973
Premise: holds: the server reads the four facets and pages (PR #31234 merged 2026-11-07T21:08Z), and the console still reads one window with { limit: 100 } in MarketplacePage.tsx:415 on origin/main
Serial constraints cleared: none — no other domain:ui card is pm:dispatched on console/marketplace/**
Scope: the card's four owed items as written, one PR, Fixes #31267; the declaration lines start at no / none and the dev measures them on the diff (an i18n key added or removed changes them), and the seat amends this claim. Order: /mnt/project-files/pm-orders/ui/order-31267.md. Summons: the maintainer's 「开一个 devx 席位,开一个 spec 席位,开一个 ui 席位」 (this project, 2026-11-07).
domain:ui#1 · os-project-manager · session_01FEkQ5npnoTzeRFxu1Mj26Q
os-dev-report
{
"issue": 31267,
"status": "done",
"branch": "claude/project-thread-044740",
"pr": "#31288",
"session": "session_01FEkQ5npnoTzeRFxu1Mj26Q",
"premise_still_valid": true,
"summary": "The Console marketplace page no longer reads { limit: 100 } and filters in the browser. listMarketplacePackages takes MarketplaceListParams (q, limit, offset, businessFunctions, industries, solutionTypes, maturity) and sends each list filter as ONE comma-joined parameter, omits a filter that selects nothing, sends maturity as one value and never sends category; MarketplacePage sends the debounced search as q, the facet selection (spec order) and limit 24 / offset, reads the catalog alone on a page turn or selection change, and draws a Previous / Page N of M / Next pager over the door's total, reusing common.previous, common.next and table.pageInfo (no i18n key added or removed). Facet buttons now list every spec value without a count (a filtered page cannot count the catalog and the door answers no counts); a facet is drawn once an answered listing carries it and stays drawn. Row defaults: the console filters nothing, so no default is applied there; effectiveSolutionType (package page) still reads the spec's DEFAULT_SOLUTION_TYPE, the constant the door imports. Head aad134c, draft PR #31288.",
"tests": "On head aad134c: pnpm --dir ui exec vitest run packages/app-shell/src/console/marketplace/ under the lock -> Test Files 58 passed (58), Tests 515 passed (515), VERDICT command-exit 0; pnpm --filter @object-ui/app-shell run type-check exit 0 (tsconfig.json and tsconfig.test.json). New or rewritten: MarketplacePage.facets-31011.test.tsx (15 cases, rendered page, clicks / keystrokes / pager; asserts the recorded list-read query: keys, comma-joined values in spec order, omitted empty facets, no category, no empty value, one occurrence per key, limit/offset; one case proves the console draws a server answer that does not match the selection), marketplaceApi.listQuery-31267.test.ts (2 cases, exact URL incl. maturity, empty lists omitted), MarketplacePage.searchPlaceholder-10900.test.tsx third case (q trimmed, offset 0). Ablations on f7c4353 via scripts/ablation-replace.mjs over the three files (app-shell read from src, no build between): A empty facet sent -> 1 red; B selection kept off the read (--delete ...facetParams,) -> 7 red, first B attempt was a substring replacement the script refused with rise 0 (no-op, redone); C repeated keys instead of comma join -> 3 red; D limit 100 without offset -> 6 red; E insertion order instead of spec order -> 1 red; F non-sticky facet -> 1 red. Every leg printed ok restored: blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 37 families. 27 derived by the ui paths ran on f7c4353 (the code commit), all exit 0: check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-sdui-manifest (+ --self-test), pnpm --dir ui exec vitest run scripts/, spec check:duration-unit-keys, spec check:error-code-provenance, check:cross-package-test-inputs, check:dispatcher-error-vocabulary, check:driver-memory-census, check:engine-double-contract, check:gitlink-declared, check:nul-bytes, check:published-files, check:query-options-erasure, check:refd-timer-probe, check:registry-log-declared, check:rest-log-spy-declared, check:skill-identifier-liveness, check:test-source-alias, check:tier-file-adoption, check:type-check-coverage, check:type-check-debt, check:undeclared-dep-imports, check:watch-hint-literal, check:where-matcher. 10 added by the changeset path ran on aad134c, all exit 0: check-adr-0087-registration (--base origin/main, --self-test), check-changeset-no-major, check-empty-changeset (--base origin/main, --self-test), ci/snapshot-next --self-test, pm/release-rehearsal-clone --self-test, release-pending-publish --self-test, check:changeset-gate-self-tests, check:closed-ceremony-text. --ran: 37 derived, 37 run, 0 NOT-MEASURED, 0 UNRUN. Also: ui eslint on the 7 changed files 0 errors; pnpm --dir ui check:new-line-citations 0 new, exit 0. PR check-runs: in_progress at report time (not waited on, per os-dev.md).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (dispatch fw-20261107T222727Z-72be98, read back identical, PR #31288, no labels, no assignees) and this os-dev-report comment via post-stamped; plus one git push (not REST). Write budget spent: 3 of 3.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"noted, not filed (Acceptance notes) · facet counts: #31011 drew per-value counts from the loaded rows; the list door answers { items, total, limit, offset } with no aggregation, and MarketplaceSearchResponseSchema.facets (spec, optional) has no in-repo producer, so the console reads none. carrier: none",
"noted, not filed (Acceptance notes) · search scope: browser search matched localized name, manifest id and description; the door's q (proxy R2 path, catalogRowMatches) matches display_name and manifest_id, which is what the placeholder names. carrier: none",
"noted · default configuration forwards the validated facets verbatim to the cloud list route; until cloud adopts the names, a facet read may come back unfiltered and the console draws it as answered. carrier: cloud (cloud#3661)"
],
"deviations": [
"Clause-② and Metadata-protocol measured on the diff: no i18n key added, removed or reworded (pager reuses common.previous, common.next, table.pageInfo); the only package touched is private @object-ui/app-shell; listMarketplacePackages widened inside that private package. Claim lines stand: Clause-②: no, Metadata-protocol: none.",
"Changeset, not skip-changeset: @object-ui/app-shell is private but its code ships in @object-ui/console's dist (files: dist), so a patch changeset naming @object-ui/app-shell, following .changeset/30330-marketplace-readme-fits-page.md.",
"Search moved to the server as q (debounced 300 ms): the card names the four facets and paging only, but with server paging a browser search would only see the current page, so leaving it would keep filtering in the browser (card item 2).",
"The 27 ui-derived families ran on f7c4353, not the final head aad134c; f7c4353..aad134c adds the changeset file only, and the derivation maps that path to exactly the 10 changeset families, which ran on aad134c.",
"os-dev.md rule 2 says pr_create carries the claim Account as assignee; the order and AGENTS.md say none. Sent none, per the order."
],
"files_changed": [
".changeset/31267-marketplace-server-facets.md",
"ui/packages/app-shell/src/console/marketplace/MarketplaceFacetFilters.tsx",
"ui/packages/app-shell/src/console/marketplace/MarketplacePage.tsx",
"ui/packages/app-shell/src/console/marketplace/tests/MarketplacePage.facets-31011.test.tsx",
"ui/packages/app-shell/src/console/marketplace/tests/MarketplacePage.searchPlaceholder-10900.test.tsx",
"ui/packages/app-shell/src/console/marketplace/tests/marketplaceApi.listQuery-31267.test.ts",
"ui/packages/app-shell/src/console/marketplace/marketplaceApi.ts",
"ui/packages/app-shell/src/console/marketplace/marketplaceTaxonomy.ts"
],
"line_budget": "+551 / -259 over 8 files (git diff --shortstat origin/main...HEAD at report time)"
}
ACCEPT → PR #31288 comment 6714029893 · 2026-11-07T22:45Z · head aad134cc0c5367ab43ce58826542ab22fd5cb5e9; Clause-②: no, no review owed. Landing by relay pr_ready + automerge_enable once PR #31284 (fix for queue-flake anchor #31285) is on main.
Activity
objectstack-fleet commentedon Nov 7, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
Claim: PM loop round 2 · 2026-11-07T21:36Z
Session:
session_01FEkQ5npnoTzeRFxu1Mj26Q(card thread, dev) · seatsession_01FEkQ5nLA7wiVY5YWjT9SvrAccount:
os-project-managerBranch:
claude/project-thread-044740Worktree:
objectstack-issue-31267Domain:
domain:uiSeat:
domain:ui#1File surface:
ui/packages/app-shell/src/console/marketplace/**(MarketplacePage.tsx,marketplaceApi.ts,marketplaceTaxonomy.ts) and their tests, root.changeset/Container & model: M,
mode:thread,model: default tier(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card (follow-up owed by the #31173 landing, PR #31234)
Thread-read: 6712743973
Premise: holds: the server reads the four facets and pages (PR #31234 merged 2026-11-07T21:08Z), and the console still reads one window with
{ limit: 100 }inMarketplacePage.tsx:415onorigin/mainSerial constraints cleared: none — no other
domain:uicard ispm:dispatchedonconsole/marketplace/**Scope: the card's four owed items as written, one PR,
Fixes #31267; the declaration lines start atno/noneand the dev measures them on the diff (an i18n key added or removed changes them), and the seat amends this claim. Order:/mnt/project-files/pm-orders/ui/order-31267.md. Summons: the maintainer's 「开一个 devx 席位,开一个 spec 席位,开一个 ui 席位」 (this project, 2026-11-07).objectstack-fleet commentedon Nov 7, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5npnoTzeRFxu1Mj26Q
os-dev-report
{
"issue": 31267,
"status": "done",
"branch": "claude/project-thread-044740",
"pr": "#31288",
"session": "session_01FEkQ5npnoTzeRFxu1Mj26Q",
"premise_still_valid": true,
"summary": "The Console marketplace page no longer reads { limit: 100 } and filters in the browser. listMarketplacePackages takes MarketplaceListParams (q, limit, offset, businessFunctions, industries, solutionTypes, maturity) and sends each list filter as ONE comma-joined parameter, omits a filter that selects nothing, sends maturity as one value and never sends category; MarketplacePage sends the debounced search as q, the facet selection (spec order) and limit 24 / offset, reads the catalog alone on a page turn or selection change, and draws a Previous / Page N of M / Next pager over the door's total, reusing common.previous, common.next and table.pageInfo (no i18n key added or removed). Facet buttons now list every spec value without a count (a filtered page cannot count the catalog and the door answers no counts); a facet is drawn once an answered listing carries it and stays drawn. Row defaults: the console filters nothing, so no default is applied there; effectiveSolutionType (package page) still reads the spec's DEFAULT_SOLUTION_TYPE, the constant the door imports. Head aad134c, draft PR #31288.",
"tests": "On head aad134c: pnpm --dir ui exec vitest run packages/app-shell/src/console/marketplace/ under the lock -> Test Files 58 passed (58), Tests 515 passed (515), VERDICT command-exit 0; pnpm --filter @object-ui/app-shell run type-check exit 0 (tsconfig.json and tsconfig.test.json). New or rewritten: MarketplacePage.facets-31011.test.tsx (15 cases, rendered page, clicks / keystrokes / pager; asserts the recorded list-read query: keys, comma-joined values in spec order, omitted empty facets, no category, no empty value, one occurrence per key, limit/offset; one case proves the console draws a server answer that does not match the selection), marketplaceApi.listQuery-31267.test.ts (2 cases, exact URL incl. maturity, empty lists omitted), MarketplacePage.searchPlaceholder-10900.test.tsx third case (q trimmed, offset 0). Ablations on f7c4353 via scripts/ablation-replace.mjs over the three files (app-shell read from src, no build between): A empty facet sent -> 1 red; B selection kept off the read (--delete ...facetParams,) -> 7 red, first B attempt was a substring replacement the script refused with rise 0 (no-op, redone); C repeated keys instead of comma join -> 3 red; D limit 100 without offset -> 6 red; E insertion order instead of spec order -> 1 red; F non-sticky facet -> 1 red. Every leg printed ok restored: blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 37 families. 27 derived by the ui paths ran on f7c4353 (the code commit), all exit 0: check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-sdui-manifest (+ --self-test), pnpm --dir ui exec vitest run scripts/, spec check:duration-unit-keys, spec check:error-code-provenance, check:cross-package-test-inputs, check:dispatcher-error-vocabulary, check:driver-memory-census, check:engine-double-contract, check:gitlink-declared, check:nul-bytes, check:published-files, check:query-options-erasure, check:refd-timer-probe, check:registry-log-declared, check:rest-log-spy-declared, check:skill-identifier-liveness, check:test-source-alias, check:tier-file-adoption, check:type-check-coverage, check:type-check-debt, check:undeclared-dep-imports, check:watch-hint-literal, check:where-matcher. 10 added by the changeset path ran on aad134c, all exit 0: check-adr-0087-registration (--base origin/main, --self-test), check-changeset-no-major, check-empty-changeset (--base origin/main, --self-test), ci/snapshot-next --self-test, pm/release-rehearsal-clone --self-test, release-pending-publish --self-test, check:changeset-gate-self-tests, check:closed-ceremony-text. --ran: 37 derived, 37 run, 0 NOT-MEASURED, 0 UNRUN. Also: ui eslint on the 7 changed files 0 errors; pnpm --dir ui check:new-line-citations 0 new, exit 0. PR check-runs: in_progress at report time (not waited on, per os-dev.md).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (dispatch fw-20261107T222727Z-72be98, read back identical, PR #31288, no labels, no assignees) and this os-dev-report comment via post-stamped; plus one git push (not REST). Write budget spent: 3 of 3.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"noted, not filed (Acceptance notes) · facet counts: #31011 drew per-value counts from the loaded rows; the list door answers { items, total, limit, offset } with no aggregation, and MarketplaceSearchResponseSchema.facets (spec, optional) has no in-repo producer, so the console reads none. carrier: none",
"noted, not filed (Acceptance notes) · search scope: browser search matched localized name, manifest id and description; the door's q (proxy R2 path, catalogRowMatches) matches display_name and manifest_id, which is what the placeholder names. carrier: none",
"noted · default configuration forwards the validated facets verbatim to the cloud list route; until cloud adopts the names, a facet read may come back unfiltered and the console draws it as answered. carrier: cloud (cloud#3661)"
],
"deviations": [
"Clause-② and Metadata-protocol measured on the diff: no i18n key added, removed or reworded (pager reuses common.previous, common.next, table.pageInfo); the only package touched is private @object-ui/app-shell; listMarketplacePackages widened inside that private package. Claim lines stand: Clause-②: no, Metadata-protocol: none.",
"Changeset, not skip-changeset: @object-ui/app-shell is private but its code ships in @object-ui/console's dist (files: dist), so a patch changeset naming @object-ui/app-shell, following .changeset/30330-marketplace-readme-fits-page.md.",
"Search moved to the server as q (debounced 300 ms): the card names the four facets and paging only, but with server paging a browser search would only see the current page, so leaving it would keep filtering in the browser (card item 2).",
"The 27 ui-derived families ran on f7c4353, not the final head aad134c; f7c4353..aad134c adds the changeset file only, and the derivation maps that path to exactly the 10 changeset families, which ran on aad134c.",
"os-dev.md rule 2 says pr_create carries the claim Account as assignee; the order and AGENTS.md say none. Sent none, per the order."
],
"files_changed": [
".changeset/31267-marketplace-server-facets.md",
"ui/packages/app-shell/src/console/marketplace/MarketplaceFacetFilters.tsx",
"ui/packages/app-shell/src/console/marketplace/MarketplacePage.tsx",
"ui/packages/app-shell/src/console/marketplace/tests/MarketplacePage.facets-31011.test.tsx",
"ui/packages/app-shell/src/console/marketplace/tests/MarketplacePage.searchPlaceholder-10900.test.tsx",
"ui/packages/app-shell/src/console/marketplace/tests/marketplaceApi.listQuery-31267.test.ts",
"ui/packages/app-shell/src/console/marketplace/marketplaceApi.ts",
"ui/packages/app-shell/src/console/marketplace/marketplaceTaxonomy.ts"
],
"line_budget": "+551 / -259 over 8 files (git diff --shortstat origin/main...HEAD at report time)"
}
Generated by Claude Code
objectstack-fleet commentedon Nov 7, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
ACCEPT → PR #31288 comment 6714029893 · 2026-11-07T22:45Z · head
aad134cc0c5367ab43ce58826542ab22fd5cb5e9;Clause-②: no, no review owed. Landing by relaypr_ready+automerge_enableonce PR #31284 (fix for queue-flake anchor #31285) is onmain.objectstack-fleet commentedon Nov 7, 2026
domain:ui#1 · os-project-manager · session_01FEkQ5nLA7wiVY5YWjT9Svr
Landed · 2026-11-07T23:36Z
7c523aa108650e48d19419ae9b76924c64707741onmaincompletedby the PR's closing keyword; no otherdomain:uicard left the open inventoryState:
pm:dispatchedremoved, assignee cleared.