Repository navigation
Description
epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
Filing gate: ④ child of epic #28236 (P3, cut 2026-11-01 on the maintainer's 「四项提速措施全部按推荐执行」, schedule reviewed) · plan of record: ADR-0146 Rollout P3 "N-26 the metadata directory into Studio (D1)", the half that waits on N-15 (schedule review table: N-26b ← N-15, N-26a). ⛔ Not a claim.
Part of #28236 (P3, child N-26b) · governs: ADR-0146 D3 ("On top, one surface": the pair's items in the same list, marked "customization", an override marked with the base it overrides, "only customizations"), D2 (the customization list, from served facts), D1 (the All metadata area) · lane: domain:ui · size: M.
Why it waits. The marks are N-15's served facts (#28411: the base's .custom overrides, extensions and counts). The surface they go on is N-26a's All metadata area.
Business reason. In Studio's All metadata area for HotCRM, an administrator browsing translations or email templates should see which ones they changed and which they added. They should also be able to filter to just those, in the same place the pillars show it. Without marks, the catalog cannot answer "what did we change on HotCRM" for the types the pillars do not cover.
Measured (35b178bd0a).
metadata-admin/DirectoryPage.tsxtiles show label, machine name, an item count scoped to the?package=package (countsByType, :149–156, :329), and writable/overlay badges (:187–191). Nothing marks a customization.ResourceListPage.tsxclassifies a row's source from its_packageId(:111–140, the Source badge at :875–904). It lists the scoped package only, so a base's list does not show the pair's items.packages/spec/src/kernel/customization-package.ts:94#customizationPackageIdand :111customizationBasePackageIdname the pair and its base.- N-15's route and field names: not landed, not verified. N-19's mark component: not landed (sibling card).
Wanted.
- With a base open in the All metadata area, each type list shows the base's items and the pair's items in one list. A pair item N-15 lists as an override is marked "customized", naming the base. Any other pair item is marked "added". Nothing is computed client-side (no diff, no
basedOnverdict, D2/D6). - An "only customizations" filter on each list, from the same read.
- Each directory tile shows the type's customization count. The directory header shows the base's total, both from N-15's served counts. Extensions are counted on the object tile.
- A failed or pending N-15 read draws no mark and no number, never "0", with the server's sentence on failure. A base with no pair draws no marks.
- One mark component for the whole console. Whichever of N-19 and this card lands first creates it, and the other reuses it.
- In the cross-package leg, rows of a pair are labelled with their base (
customizationBasePackageId).
Tests. Base + pair fixture with one overridden translation, one added email template and one extension field:
- the translation list marks the override "customized (HotCRM)" and the filter shows it alone;
- the email-template list marks the added item;
- the object tile counts the extension;
- a failed read draws no mark;
- a base without a pair is unchanged.
Release safety. Safe on its own: read-only marks over a served read (Blocked-by: #28411) on N-26a's area. Nothing is written or removed.
Not here. The area itself (N-26a). Pillar rail marks and the switcher fold (N-19). Landing counts (N-24). The simplified translation and email-template editors (N-25). Redirects (N-28).
Dedupe. Searched only customizations filter, customized added mark metadata directory: only #28411 and closed history.
Links back: #28236, #28411, ADR-0146 D1, D2, D3, D6.
Generated by Claude Code
Activity
objectstack-fleet commentedon Nov 1, 2026
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y
Unblocked · 2026-11-01T11:31Z ·
pm:blocked→pm:queueBlocked-by: #28411, #28561is met..customoverrides, its object extensions and its switched-off items, served rows only, with counts #28411 (N-15) landed by PR feat(runtime,spec): GET /packages/:id/customizations answers a base's overrides, extensions and switched-off items in one read #28595 (519089e1). Its route is mounted since main red: Dogfood Regression Gate — GET /packages/:id/customizations is ledgered but not mounted (#28595), so the route 404s at runtime #28622, fixed by PR fix(runtime): GET /packages/:id/customizations answers over HTTP, mounted beside the other package reads #28635 (28ef35e0). Studio's landing reads it live since PR feat(app-shell): each read-only base card on the Studio landing says how many items are customized and switched off #28634 (5e879eab).3694d3b8). The All metadata area is at/studio/<pkg>/metadata/…and/studio/~all/metadata/….GET /api/v1/packages/:id/customizationsandGetPackageCustomizationsResponseSchemain@objectstack/spec/api.pm:blockedon Studio: customize a read-only package's view, dashboard or report into <base>.custom — a declared override, its badge, and "Restore package original" (replaces #28147) #28562, so this card creates the one mark component (Wanted 5), and N-19 reuses it.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y
Claim: PM loop round 5 · 2026-11-01T11:35Z
Session:
session_01QsR2jSKpVAotd33JtFuXkP(card thread, os-dev); dispatched by seat sessionsession_01QsR2jR7ZFkpqmm4U8S1f9yAccount:
zhuangjianguoBranch:
claude/project-thread-84w3mr(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-28568Domain:
domain:uiSeat:
domain:ui#4File surface:
ui/packages/app-shell/src/views/metadata-admin/{DirectoryPage,ResourceListPage}.tsx, one new shared customization-mark component, the read helper (studio-design/packageCustomizations-io.ts, reused or extended), their tests, and the strings they draw (stop on breach; explain in the report)Container & model: M,
mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
All metadata lists show only the scoped package's rows and mark no customization | GET /packages/:id/customizations (#28411, mounted by #28635) serves a base's overrides, extensions and counts, and the area (#28561) is landed | an administrator asking "what did we change on HotCRM" for types the pillars do not coverThread-read: 6557359966
Premise: holds (at
origin/main3694d3b8DirectoryPageandResourceListPagedraw no customization mark; N-19 #28572 ispm:blocked, so no mark component exists yet)Serial constraints cleared: none open. N-19 (#28572, blocked) reuses the mark component this card creates. #28573 (claimed this round) edits
PermissionMatrixEditor.tsxand the Access pillar, which this card does not touch.The Clause-② line holds for strings in
@object-ui/i18n'sstudionamespace (Record<string, string>). A new key in alocales/*pack would widen the publishedentype. If the dev measures that, the report says so and the seat amends this line toyes (widening)beforepr_create.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:ui#4 · zhuangjianguo · session_01QsR2jSKpVAotd33JtFuXkP
os-dev-report
Delivered 2026-11-01T12:45Z for PR #28667 (draft).
{ "issue": 28568, "status": "done", "branch": "claude/project-thread-84w3mr", "pr": "https://github.com/objectstack-ai/objectstack/pull/28667", "head": "f42f397b", "session": "session_01QsR2jSKpVAotd33JtFuXkP", "premise_still_valid": true, "summary": "With a base open in Studio's All metadata area, each type list now holds the base's rows and its BASE.custom pair's rows. A row the served customization read lists as an override is marked 'Customized (BASE name)', any other pair row 'Added', with an 'Only customizations (n)' filter. Directory tiles show the type's served overrides (object also counts extension members) and the header the base's total. A pending or failed read draws no mark and no number (failure shows the server's sentence); Setup reads nothing; the cross-package leg labels a pair row 'Customization of BASE'. One mark component (studio-design/CustomizationMark.tsx) plus a pure rule module (customizationMarks.ts); packageCustomizations-io.ts reused and extended with fetchPackageCustomizations.", "tests": "At 879da8ff (f42f397b only edits the changeset text): new metadataAreaHost.customizations-28568.test.tsx (8 cases) and studio-design/customizationMarks.test.ts (8 cases), run together with every ui test naming the touched modules (git grep -l, 39 files) under os-verify-lock --maxWorkers=2: Test Files 39 passed (39), Tests 356 passed (356). Declared narrowing: the rest of app-shell is CI's Test UI. Ablations via ablation-replace.mjs, restored blob==HEAD each: (1) override key drops member -> 2 failed; (2) list scope drops pair rows -> 2 failed. app-shell type-check exit 0 at 52eb6b11 and 879da8ff; i18n type-check exit 0; eslint on 9 touched files 0 errors.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack: 34 commands, all exit 0. 31 at f42f397b (PR-body gates with GITHUB_EVENT_PATH on the sent body: check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword also exit 0). 3 at 52eb6b11: pnpm --dir ui exec vitest run scripts/ (169 files, 4900 tests passed, 2 skipped), check:query-options-erasure, check:type-check-debt (under lock). --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. node scripts/check-sdui-manifest.mjs exit 0. CI check-runs: in_progress at report time.", "line_budget": "changed lines vs merge base at pre-merge derivation: +782/-7 over 10 files (under the 3000 human-merge threshold); no skills/** touched", "files_changed": [ ".changeset/28568-all-metadata-customization-marks.md", "ui/packages/app-shell/src/views/metadata-admin/DirectoryPage.tsx", "ui/packages/app-shell/src/views/metadata-admin/ResourceListPage.tsx", "ui/packages/app-shell/src/views/metadata-admin/metadataAreaHost.customizations-28568.test.tsx", "ui/packages/app-shell/src/views/studio-design/CustomizationMark.tsx", "ui/packages/app-shell/src/views/studio-design/customizationMarks.ts", "ui/packages/app-shell/src/views/studio-design/customizationMarks.test.ts", "ui/packages/app-shell/src/views/studio-design/packageCustomizations-io.ts", "ui/packages/i18n/src/namespaces/studio/en.ts", "ui/packages/i18n/src/namespaces/studio/zh.ts" ], "clause_2_measurement": "no: all 13 new keys are in the studio namespace (plain string table), none in a locales/* pack; claim line kept verbatim", "deviations": [ "Merged origin/main (f23e0512) once before pr_create; no overlap with the touched files.", "Session handshake first named a wrong session id; corrected in the seat thread before the claim; claim and trailers carry session_01QsR2jSKpVAotd33JtFuXkP.", "No PR assignee or reviewer set (common rule 3/10 over the harness's MCP assign step).", "PR body slip, for the seat to correct (dev writes the body once): Tests section says customizationMarks.test.ts pins '(10 cases)'; it is 8 cases (16 in all with the 8 list/directory cases, as the 维护者速读 says). Replace '(10 cases)' with '(8 cases)'." ], "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "5 reads: issue_read x3 (get, get_comments x2), no MCP writes", "api_writes": "2 through scripts/pm: fleet-write pr_create (PR #28667, read-back identical), this post-stamped comment on #28568; plus git push (not REST)", "open_questions": [], "out_of_scope_findings": [ "class: none (note) · Tiles/header count only N-15's served overrides+extensions; items the pair ADDS are marked and filterable but counted nowhere, because the read does not list them. carrier: seat (N-15 declaration widening or N-24) · noted in PR Acceptance notes, not filed", "class: none (note) · The base's directory tiles come from a one-package diagnostics sweep (useGlobalDiagnostics in useMetadata.ts): a type only the pair holds draws no tile, and tile item counts exclude the pair's rows. Fix needs a pair-scoped second sweep outside this claim's file surface. carrier: seat · dedupe words: directory pair tile, customization package sweep, pair-only type tile" ] }objectstack-fleet commentedon Nov 1, 2026
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y
ACCEPT → PR #28667 comment 6558562088 · 2026-11-01T13:25Z · Clause-② no held (studio namespace keys only), no contract review owed · all ten required contexts green at
bfca84cdafter the zh census fix · acceptance notes (a) and (b) carried to N-19 #28572 · landing through the merge queue.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
domain:ui#4 · zhuangjianguo · session_01QsR2jR7ZFkpqmm4U8S1f9y
Landed · 2026-11-01T13:44Z · PR #28667 merged through the merge queue as
9182ff62. Record: ACCEPT 6558562088 atbfca84cd(Clause-② no, no contract review owed; the zh base-term census fix included).9182ff62~1)origin/main)customizationMarkOfinstudio-design/customizationMarks.tsdirectory-tile-customized-inmetadata-admin/DirectoryPage.tsxengine.customizationMark.keys ini18n/src/namespaces/studio/zh.tsThe card closed through
Fixes.pm:dispatchedcomes off in the same stroke as this note. The two acceptance gaps (pair-added items counted on no tile; a pair-only type draws no tile) are carried to N-19 #28572, which reusesCustomizationMark.tsx.Generated by Claude Code