Repository navigation
Studio metadata coverage gaps: surface remaining types + promote un-typed concepts #2657
Description
Activity
Update — object-scoped
actionlanded (objectui#2330, merged)Since filing, a chunk of Part A shipped in the new Studio's Data pillar (objectstack-ai/objectui#2330):
action→ per-object tab (done). Object actions carryobjectNameand defineStack folds them into the object's inlineactions[], so they render as an Actions tab on the object, master-detail, reusing the realActionDefaultInspectorform (create / edit / delete, persisted via the object draft). This supersedes the earlier "surfaceactionin Interfaces" suggestion: object actions belong on the object; Interfaces should host only global actions (objectNameunset /global_nav).- Also shipped alongside: per-object API and Hooks tabs, object icons in the rail, and a cross-pillar declutter (removed the "same renderer" jargon badges, softened caps type-tags).
Two save-blocking bugs were found by driving real configs and fixed in the same PR (hook
conditionobject-vs-string render crash; unseededtype:'script'action 422 onbody.language).Revised remaining work
Part A (objectui UI — no framework change):
-
action(object-scoped) — done - global
action— theobjectName-less /global_navslice still needs a home (Interfaces or a global surface) -
dataset— Interfaces rail (preview already registered → cheapest remaining win) -
job→ Automations ·role→ Access (generic SchemaForm) - new AI pillar —
agent(read-only per ADR-0063 §2) /tool/skill - new System pillar —
translation/email_template/book/doc(+ a global, executable API console)
Part B (framework
@objectstack/spec— still the blocking dependency): unchanged —webhooks/connectors/portals/sharingRules/apisneed to become registered metadata types before Studio can surface them generically.分诊(spec 车道欠账代扫,维护者 2026-08-05 指令):挂
needs-user-decision——正文的 Ask 本就是给维护者的两问(Part B 五个概念哪些晋升为注册元数据类型及顺序;Part A 布局确认)。⚠️ 过时前提警告:覆盖矩阵是 07-06 快照 + 07-07 增量,一个月间已部分被超越——至少apis已随 #5312 注册为api元数据类型(Part B 五项之一已事实完成),object-scopedaction已落(objectui#2330)。建议拍板前先让 spec 车道重跑一次两仓覆盖审计刷新矩阵,避免按旧地图决策;届时 Part B 余项(webhooks/connectors/portals/sharingRules)按 ADR-0088 准入逐个过。不构成认领。会话:session_01N3uGFF8teXbpgtbEJ1aYXu
Generated by Claude Code
处置(2026-08-06):退回派发队列——先修事实,再谈拍板。
复核结论:现矩阵已失真,维护者无法在过时地图上做有效决策:
api已注册(#5312);role/profile已随 ADR-0090 整 kind 退役、validation随 ADR-0088 退役——「27 类」基数不成立,Security 两行作废。任务(S-M,spec 车道自裁执行):重跑两仓覆盖审计、砍死行、刷新矩阵(Part A 的 dataset 上 rail 等「最便宜赢面」一并核对)。产出后,唯一需要维护者的窄问题(Part B 余四项 webhooks/connectors/portals/sharingRules 的 ADR-0088 准入与排序)与 #3257 打包成一次 Studio appetite 拍板再上决策箱。
经办:PM 会话
session_01GcjbQLUQKysMU9uXB34iyv;维护者 2026-08-06 审阅决策简报后授权按建议执行(否决窗口:可评论/重开推翻)。
Generated by Claude Code
【决策箱注记】维护者 2026-08-06 批复全舰队决策箱评估报告(批复「同意」),本单处置:
拍板前置已批——spec 座位先重跑两仓覆盖审计:正文覆盖矩阵为一个月前快照,已知漂移至少两处(apis 已随 #5312 注册为元数据类型——Part B 五项之一事实完成;object-scoped action 已落 objectui#2330),按旧地图拍 Part A pillar 布局与 Part B 晋升顺序必错。
审计结果(新覆盖矩阵 + Part B 各项现状)回填本单后,再提请 Part A / Part B 终裁。本单保留
needs-user-decision。评估会话:
session_01N3uGFF8teXbpgtbEJ1aYXu
Generated by Claude Code
Disposition (maintainer 2026-08-07, 「按建议」 from the release-board audit): stays off the v17 board — this is program-scale (multi-week, cross-repo) and its coverage matrix above is stale (
apipromoted via #5312;role/profile/validationretired; Studio pillar set moved). Next actionable step is the prerequisite audit #6234 (refresh the two-repo matrix; dispatched), whose output lands here as one structured comment. The maintainer's one-shot appetite ruling (ADR-0088 admission + ordering, bundled with the Studio appetite question in #3257) happens on this issue afterwards — likely a v18-train program.pm:blocked+Blocked-by: #6234applied.
Generated by Claude Code
Refreshed two-repo metadata-type coverage matrix (audit requested by #6234)
Read-only audit. Every fact below is read from
origin/mainof the two clones, never a working tree:- objectstack
origin/main@8e2bbba24f76d56daad166b6b776c69d8c3ac0dc - objectui
origin/main@7dfbeb704e1eace5dc5eae1d6168c4ded805a32b
Headline: two of this issue's five Part-B rows are no longer open questions —
apiswas admitted (#5271 / PR #5312) andportalswas deleted from the spec (#3464), so the maintainer's ruling is over three rows, not five. The three that remain are also much further along than the body implies: all three are already ingested as registry item types, already reachable at/api/v1/meta/..., already writable, and already have live boot-time consumers. What they lack is the schema binding — and that gap is currently a write hole, not just a missing feature.
1. The current registered set — 26 kinds, not 27
DEFAULT_METADATA_TYPE_REGISTRY—packages/spec/src/kernel/metadata-plugin.zod.ts:593-828; the closedMetadataTypeSchemaenum it keys off is:72-158.domain kinds registry lines data (5) objectfieldhookseedmapping604, 605, 613, 621, 627 ui (7) viewpagedashboardappactionreportdataset634-642 automation (2) flowjob649, 684 system (7) datasourceexternal_catalogapitranslationemail_templatedocbook692, 713, 762, 763, 764, 770, 774 security (2) permissionposition777, 778 ai (3) agenttoolskill825-827 26 registered. 25 of them resolve a canonical Zod schema (
BUILTIN_METADATA_TYPE_SCHEMAS,packages/spec/src/kernel/metadata-type-schemas.ts:79-143); the one exception isexternal_catalog, whose absence is deliberate and permanent (ADR-0088 §3; noted atmetadata-type-schemas.ts:152-154). So there is no registered-but-schemaless drift today apart from that one designed case.17 of 26 additionally declare a
FormView(METADATA_FORM_REGISTRY,packages/spec/src/system/metadata-form-registry.ts:66-89). The nine without one —seedmappingjobdatasourceexternal_catalogapitranslationdocbook— still render, from the JSON Schema derived from their Zod schema.This issue's "27 authorable metadata types" is therefore stale in both directions: the base is 26, and three rows it counted (
role,profile,validation) no longer exist at all.
2. Correction that reshapes the whole Part-A table: there are two authoring surfaces, not one
This issue's matrix scores every kind against "New Studio", which produces a long column of ❌ for kinds that are, in fact, fully authorable today.
(a)
StudioDesignSurface— now FOUR pillars, four rail types.
objectui packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx:145-150→data/automations/interfaces/access. The rails load exactly four types:pillar rail type load site Data objectStudioDesignSurface.tsx:1200,:2039Automations flow:2849Interfaces app(nav tree drives page/view/dashboard/report canvases):1231Access permission(+ package OWD overview):3289Plus the object-scoped tabs that landed since this issue was filed:
ObjectActionsPanel.tsx,ObjectApiPanel.tsx,ObjectHooksPanel.tsx,ObjectValidationsPanel.tsx,ObjectFormDesigner.tsx,ObjectSettingsPanel.tsx.(b) The generic Metadata Directory — registry-driven, covers everything.
objectui packages/app-shell/src/views/metadata-admin/DirectoryPage.tsx+registry.ts:1-28: "Add it toDEFAULT_METADATA_TYPE_REGISTRY(framework). Done. It shows up in the Setup app's Metadata Directory with a working list / create / edit / history out of the box." It reads/meta/typesat runtime and needs no per-type code.So the honest Part-A statement is: every registered kind is already authorable; what a subset lacks is a pillar (an opinionated, object-centric design surface). Rows this issue marks ❌ —
datasetjobseedmappingdatasourcetranslationemail_templatebookdocagenttoolskill— are all live in the directory today.
3. The refreshed candidate matrix
Legend for ADR-0088 admission (
docs/adr/0088-metadata-kind-admission-and-retirement.md): (1) independent lifecycle · (2) declarative governability · (3) a real consumer.candidate registered? authorable Zod schema REST reach today Studio real consumers (declaration sites) ADR-0088 admission blockers size apis→api✅ DONE metadata-plugin.zod.ts:762✅ ApiEndpointSchema(metadata-type-schemas.ts:129)/api/v1/meta/api/...validated (422)Directory + per-object API tab ( ObjectApiPanel.tsx)endpoint executor + /openapi.json; showcaseKIND_COVERAGE.apidemonstrated; ledgerliveness/api.json1·2·3 pass — shipped (PR #5312, size/xl)portals❌ N/A — collection REMOVED ❌ no PortalSchemaanywhere on mainnone none zero n/a n/a row deleted webhooks→webhook❌ (ingested, not registered) ✅ WebhookSchemapackages/spec/src/automation/webhook.zod.ts:133—strictObject, ADR-0010 envelope declared (:215,:228)/api/v1/meta/webhook/...UNVALIDATED 200Directory tile (synthesised entry, raw-JSON); objectui does client-validate it ( clientValidation.ts:124)plugin-webhooks/src/bootstrap-declared-webhooks.tsre-parse()s at boot →sys_webhook→AutoEnqueuer; ledgerliveness/webhook.json= 11/11 propslive; governed viaSPEC_ONLY_SCHEMAS(check-liveness.mts:194-198)1·2·3 pass door question (§6); re-point the fixtures that use webhookas the canonical "no static registry entry" specimenM connectors→connector❌ (ingested, not registered) ⚠️ two contend:ConnectorSchemaintegration/connector.zod.ts:648(runtime instance) vsDeclarativeConnectorEntrySchema:843(the actualconnectors:shape). Non-strict, no ADR-0010 envelope/api/v1/meta/connector/...UNVALIDATED 200; separatelyGET /api/v1/automation/connectors(runtime/src/route-ledger.ts:233)Directory tile only; flow canvas has a connector_actionnodeservice-automation/src/plugin.ts:1016+materializes provider-bound entries at boot;engine.tsconnector registry; 4 connector packages; showcaseSTACK_COLLECTION_COVERAGE.connectorsdemonstrated1·2·3 pass no liveness ledger; must pick which schema the kind resolves; superRefine⇒ZodEffects, so the/meta/typesJSON Schema emission must be measured, not assumedL sharingRules→sharing_rule❌ (ingested, not registered) ✅ SharingRuleSchema=CriteriaSharingRuleSchemapackages/spec/src/security/sharing.zod.ts:217—.strict(), no ADR-0010 envelope/api/v1/meta/sharing_rule/...UNVALIDATED 200; separately a full CRUD family at/api/v1/sharing/rules(client/src/index.ts:3491-3541)Access pillar shows OWD + AccessExplainPanelrule kinds, not rule authoringplugin-sharing/src/bootstrap-declared-sharing-rules.ts→SharingRuleService.defineRule→sys_sharing_rule; 4 lint rules (validate-sharing-rule-enforceability/validate-org-axis-red-lines/validate-expressions/authoring-rules)1·2 pass; 3 with a caveat — the bridge does not .parse()the spec schema (onlydefineStackand lint do)no liveness ledger; .strict()+ no envelope ⇒ stamped items would be rejected at parse, the exact trap #5312 measured onapi; three write doors and no ruling on which is canonicalL The measured proof that the three unregistered rows are writable-and-unvalidated today — this is the single most important new fact in the audit:
getMetaTypes()synthesises a descriptor withallowRuntimeCreate: truefor any type with no registry row (packages/metadata-protocol/src/protocol.ts:2988-3008).- Both write gates deliberately agree with that synthesis, and their comments name
connectorby hand:sys-metadata-repository.ts:198-207and theintent === 'runtime-only'fall-through at:1009-1016. - With no registry row there is no schema, and with no schema there is no validation:
resolveOverlaySchema(protocol.ts:327) returnsnull, and the save path is guarded by a bareif (schema)(protocol.ts:7857-7860). - An in-repo test asserts the outcome:
packages/objectql/src/protocol-meta.test.ts:1461-1469savestype: 'webhook'with body{ name, url, events: [...] }and expectssuccess: true.eventsis not aWebhookSchemakey — it is a rejected alias that maps totriggers— andobject/triggersare absent. A spec-invalid webhook stores 200 today.
This is byte-for-byte the hole #5206/#5271 closed for
api: enforced but undeclared, the mirror of declared-but-unenforced.Zero-hit control for
portals(Operational-note-6 discipline):git grep -F "portals:" origin/main -- examples packages/qa→ 0 files, while the same grep in the same scope returns 6 files for"apis:"and 11 for"positions:".PortalSchemahas noexport constdeclaration site anywhere on main; the only surviving mentions are a tombstone comment and CHANGELOGs. The tombstone reads (packages/spec/src/stack.zod.ts:247-250):#3464: the top-levelportalscollection was removed —PortalSchemawas a never-enforced, no-op projection (no dispatcher route family, auth scope, LayoutDispatcher, NavigationBuilder or ThemeProvider ever consumed it). Author external-user UI with apps/views + positions and permission sets.
4. Per-row delta vs the matrix in this issue's body
Part B (the five concepts):
row as filed 2026-07-06 now what changed apis"code-only via contributes.routes"registered kind api#5271 / PR #5312 ( size/xl) added registry entry + enum member + schema binding + protection envelope + ledger +KIND_COVERAGErow. ADR-0121 + the #5040 executor made clause 3 true.portals" PortalSchema— external-user projections"deleted from the spec #3464. This row is not "pending admission"; its subject no longer exists. Nothing to rule on. webhooks"not registered metadata types" still unregistered — but bridged, governed, and unvalidated-writable #3461/#3489 built the boot materializer; #3462/#3485 enrolled it in the liveness ledger via SPEC_ONLY_SCHEMAS; #3490 flipped all mapped propsdead → liveand left "reassess type registration" as its explicitly optional item 5. That reassessment is exactly this ruling.connectors"not registered metadata types" still unregistered — bridged (ADR-0097), two candidate schemas, no ledger ADR-0097 + #2977/#3016/#3056 built provider-bound materialization; the stack collection now parses DeclarativeConnectorEntrySchema, notConnectorSchema— this issue's body names the wrong schema.sharingRules"not registered metadata types" still unregistered — bridged (ADR-0057 D6), three write doors, no ledger #2077/#1887/ADR-0058 D3 built the compile-and-seed bridge; #3896 hardened the two doors that could seed a permissive match-all. Part A (Studio placement) — dead rows and landed rows:
row as filed verdict now role→ Access,profile(✅ Access)VOID. Both kinds retired by ADR-0090 D2/D3. The replacement positionis registered (:778), has aFormView(metadata-form-registry.ts:80) and a Studio preview (objectui previews/index.ts:73).validation(🟡 nested, script-only)VOID as a kind — retired by the ADR-0088 addendum. Rules are authored inline as object.validations[], and the Studio Data pillar edits them there (ObjectValidationsPanel.tsx).hook(🟠 in-progress)landed — ObjectHooksPanel.tsx.per-object API reference landed — ObjectApiPanel.tsx.action→ Interfaces "quick win"superseded — object-scoped actions landed as an object tab (objectui#2330, ObjectActionsPanel.tsx). Only the global (objectName-less) slice is still homeless.dataset→ Interfaces "cheapest remaining win"preview registered ( previews/index.ts:47), still no pillar rail. Still the cheapest pillar win.seedmappingjobdatasourcetranslationemail_templatebookdocagenttoolskill❌re-scored: all are authorable in the Metadata Directory today; ❌ should read "no pillar", not "no home". external_catalog➖ intentionally skipunchanged and now permanent — ADR-0088 §3 makes runtime-created the design, not a gap. "of the 27 types the Studio surfaces ~11" 26 kinds; 4 pillar rails ( object/flow/app/permission) + all 26 in the directory.
5. Additional drift found while reading (not part of the ask; filed separately, listed here for completeness)
- Six independent enumerations of the stack-collection set, none answerable to
stack.zod.ts.PLURAL_TO_SINGULAR/MAP_SUPPORTED_FIELDS(spec/src/shared/metadata-collection.zod.ts),metadataArrayKeys(objectql/src/engine.ts:2283, still lists retiredworkflows/approvals/roles/profiles/policies/ragPipelines),ARTIFACT_FIELD_TO_TYPE(metadata/src/plugin.ts:60, maps seedsdata→ the analytics kinddatasetand omitsdatasets/jobs/datasources/translations/capabilities),MetadataCategoryEnum(spec/src/kernel/package-artifact.zod.ts:49, still lists retiredtriggers/workflows), andSTACK_COLLECTION_COVERAGE(examples/app-showcase/src/coverage.ts:181, unlikeKIND_COVERAGEit is not ratcheted against anything, and tracks 3 of ~9 non-kind collections). Directly relevant here: promoting any row above means touching several of these by hand, with no gate to catch a miss. → filed as Six independent enumerations of the stack-collection set, none answerable tostack.zod.ts— one is mis-aimed and two still list retired kinds #6242 - objectui client-validation opt-outs resting on premises that are false or name the wrong schema (
app-shell/src/views/metadata-admin/clientValidation.ts:88-92):sharing_ruleis skipped as "declared but has empty shape" (it is a.strict()8-key object atsharing.zod.ts:217);translationis judged byTranslationBundleSchemawhen the kind resolvesTranslationItemSchema;connectoris skipped for requiring anidfield thatConnectorSchema:648does not have. Same class as theemail_templatemis-binding documented 40 lines below it in the same file. → filed as clientValidation.ts: three metadata types opt out of client-side Zod validation on premises that are stale or name the wrong schema (sharing_rule/translation/connector) objectui#3561
6. Decision inputs for the appetite ruling
6.1 The one question that precedes all three rows.
apiwas a clean promotion because the metadata item itself is what the runtime reads — the endpoint matcher indexes storedapirows, so binding a schema was a pure shape-check with a byte-identical authorization verdict. The three remaining rows are not that shape. Each has:- an authoring collection in
stack.zod.ts, - a boot materializer into a runtime table/registry, and
- that runtime table as the enforced-canonical shape (
sys_webhook, the connector registry,sys_sharing_rule).
So "register the kind" does not mean the same thing it meant for
api. It resolves to one of two very different programs:- (i) Metadata store becomes a second authoring store whose rows nothing materializes after boot. A rule/webhook/connector authored through
PUT /meta/...would validate, save, report success — and never reach the dispatcher. That is the ADR-0049 false-compliance shape the platform keeps paying to remove, arriving through a new door. - (ii) Build a metadata → runtime write bridge per row (multi-week, per row, and for
sharing_ruleit must also decide what happens to the existing/api/v1/sharing/rulesfamily).
This decision is the same decision for all three rows and it precedes every size estimate below. Ruling "admit" without ruling (i)/(ii) buys the failure mode, not the feature.
6.2 The step that is cheap, additive, and does not need the ruling. The current state is worse than "not promoted": three types are writable with zero validation through
/meta, and one of them (webhook) has an in-repo test asserting that a spec-invalid body saves 200.registerMetadataTypeSchema(type, schema)(metadata-type-schemas.ts:183) exists precisely to bind a schema without a registry entry — it changes no authorization verdict, adds no Studio surface, and closes the hole. Cost: S. It also makes/meta/typesemit a real JSON Schema, which upgrades the Directory from a raw-JSON textarea to a real form for free. This is available today and is independent of the appetite ruling.6.3 Sizes, calibrated against the one real precedent. PR #5312 promoted
api— a kind that already had a full schema, a real consumer, an ADR, and a ledger — and it landed atsize/xl. Read the sizes below against that bar:row size why webhookM Everything the apipromotion had to build already exists: strict schema, ADR-0010 envelope (webhook.zod.ts:215,:228), a liveness ledger with 11/11 propslive, a boot consumer that already.parse()s. Remaining: registry entry + enum + schema-map binding +KIND_COVERAGErow + re-pointing the fixtures that currently usewebhookas the canonical "no static registry entry" specimen. #3490 already scoped this as its optional item 5.connectorL No liveness ledger → the ratchet ( check-liveness.mts:145-153) demands one or aPENDING_GOVERNANCEdebt entry with an issue, over an 800-line schema. Must first rule which schema the kind resolves (ConnectorSchemavsDeclarativeConnectorEntrySchema). No ADR-0010 envelope.superRefine⇒ZodEffects, soz.toJSONSchema()behaviour on the/meta/typespayload must be measured before promising a Studio form.sharing_ruleL No ledger. .strict()and no ADR-0010 envelope: stamped items would be rejected at parse — the precise failure #5312 measured onapi(unrecognized_keys: ['packageId','state']) and had to resolve by listingapiinSTILL_STRIP. And it is the only row with a third door already shipped (/api/v1/sharing/rules, includingPOST .../evaluate), so promotion without a canonical-door ruling multiplies doors on the surface where #3896 showed the least-validating path decides safety.6.4 Ordering dependencies.
- §6.1 (what registration means for a bridged collection) gates all three rows. One ruling, not three.
- §6.2 (bind schemas without registering) is independent and should not wait — it removes today's hazard either way.
- If rows are admitted:
webhook→connector→sharing_rule.webhookis the smallest delta and the only one whose governance artifacts are already built, so it is also the cheapest way to learn whether (i) or (ii) is the right answer before paying for it twice more. - Every promotion additionally costs a showcase
KIND_COVERAGErow (ratcheted —examples/app-showcase/test/coverage.test.ts:96-104fails CI on a registered kind with no entry) and a liveness ledger (ratcheted —check-liveness.mts:145-153). Neither is optional and neither is in this issue's body.
6.5 Where #3257 touches this. #3257 (
pm:on-hold) is a rendering-mechanism card, not an admission card: whether the design-time authoring surface converges onto the protocol (fieldForm/metadata-form-registry) as a three-step ratchet. It overlaps this issue at exactly one point — the cost of the Studio half of any promoted row. Its own PM note records thatMETADATA_FORM_REGISTRYis already the single source of the/metaform payload (metadata-protocol/src/protocol.ts:94) and that objectui already consumes the servedentry.form(EmbeddedItemEditor.tsx:62), so the generic path is live and a newly registered kind gets a real form the moment it declares one. #3257's restart condition (b) is literally "after #2657's audit refresh, bundle with its Part B admission narrow question into ONE Studio appetite ruling" — this comment is that refresh. #3257 covers none of the three admission rows on its own; it covers whether the field designer stops being hand-written, and its suggested slice-B (simple field types render fromfieldForm, complex blocks stay bespoke, M) is orthogonal to the admission verdict.6.6 Recommendation (offered, not decided). Take §6.2 now as an unconditional S — it closes a live unvalidated-write hole on three types and costs no capability surface. Then rule §6.1 as a single question, and if the answer is (ii)-with-appetite, admit
webhookonly as the pilot and re-measure before committing toconnector/sharing_rule. Grounds: on the startup-focus axis the three rows have real business pull as capabilities (all three are demonstrated in the showcase and bridged at boot) but zero measured pull for a second authoring store — nothing today asks to author a webhook or a sharing rule through/metarather than through its declaration or its runtime table; on the long-term-soundness axis, promoting before ruling (i)/(ii) is exactly the "declared but does not deliver" shape ADR-0088 exists to prevent; and on the AI-authoring axis, §6.2 is strictly the better answer to the AI-safety concern than promotion is, because it makes the wrong body fail loudly at the door without minting a second door to get it wrong through.
Generated by Claude Code
- objectstack
Decision now ready (audit #6234 delivered above;
pm:blockedcleared →needs-user-decision). The refreshed matrix corrects the frame:portalsis deleted (#3464) so the ruling covers three rows — webhook / connector / sharing_rule — and all three are already writable throughPUT /metawith zero validation (option A below closes that today).The one question that precedes every row: what does registering mean for a collection that already has a boot materializer and an enforced runtime table?
- A — bind schemas WITHOUT registering (size S): closes the unvalidated-write hole, upgrades the Metadata Directory to real forms, defers admission at no cost. → Already split out as meta: bind Zod schemas for webhook / connector / sharing_rule WITHOUT registering the kinds — close the unvalidated
PUT /metawrite hole (#2657 audit, option A) #6245 and queued (unconditional under any later ruling). - B — register + let
sys_metadatabe a second authoring store: cheapest headline, but an authored webhook/rule validates, saves, reports success and never reaches the dispatcher — the ADR-0049 false-compliance shape through a new door. Recommend against. - C — register + build a metadata→runtime write bridge per row: correct but multi-week per row (webhook M, connector L, sharing_rule L — and sharing_rule must also rule the fate of the shipped
/api/v1/sharing/rulesCRUD family). If chosen, pilot webhook alone first.
Recommendation (three axes, full argument in the audit comment): A now (done via #6245); defer B-vs-C until a real consumer asks to author these through
/meta— today there is measured pull for the capabilities but zero measured pull for a second authoring store. Likely a v18-train question. Awaiting the maintainer's ruling; the Part-A Studio placement question from the original body is largely dissolved by the Metadata Directory finding.
Generated by Claude Code
- A — bind schemas WITHOUT registering (size S): closes the unvalidated-write hole, upgrades the Metadata Directory to real forms, defers admission at no cost. → Already split out as meta: bind Zod schemas for webhook / connector / sharing_rule WITHOUT registering the kinds — close the unvalidated
16 remaining items
H17 notice (no restart) —
domain:specseat,session_01H2oQebDDxYKfWZusyd8GXk, 2026-09-04T08:00Z. Dispatching #14676 touchespackages/spec/src/integration/connector.zod.ts, one of this hold'sRestart-touchfiles (comment 5511474502), so the hold was re-read before the dispatch. The restart condition — an open card asking to author awebhook/connector/sharing_rulethrough/meta— is not what #14676 is: it retires the deaderrorMappingkey and its two rule/config schemas fromConnectorSchemaunder ADR-0049 enforce-or-remove (triage 5516704842), and touches neither the metadata-type registry nor the schema map. No rider is taken on this hold; Part B stays on hold on the 2026-08-09 ruling. Recorded so the next H17 reader does not re-derive it.
Generated by Claude Code
- added a commit that references this issue
on Sep 17, 2026 - addedpriority:p2Medium: important, M3Medium: important, M3and removed
on Sep 19, 2026 Triage:
Path: studio-authoring; gradenone→p2; disposition keep (returned topm:queue).rationale: Studio runs; of 27 authorable metadata types it surfaces ~11. That is coverage which is incomplete, not a capability that is broken, and North Star rule 2 grades it P2 rather than P0/P1.
⚠️ Noted for a later pass, not acted on here: this is an umbrella spanning ~16 types and should be split before any dispatch.Re-graded against
docs/NORTH-STAR.mdas part of the maintainer-assigned full-board sweep.pm:on-holdwas removed because the charter permits that state only with a machine-readable wake condition. Closures in this sweep are the maintainer's call — this card was kept, not closed.
Generated by Claude Code
- addedpriority:p1High: required for production / M2High: required for production / M2and removedpriority:p2Medium: important, M3Medium: important, M3priority:p1High: required for production / M2High: required for production / M2
on Sep 19, 2026 Correction — this seat's batch-1 re-grade on this card is withdrawn
Triage seat (#6015),
session_01Y6AwMBAN8zRUHgmgFdV1Qr. Earlier today this card was re-graded and moved topm:queue. Its prior labels have been restored.⛔ The re-grade was made without reading this thread, and it contradicted the ruling recorded here:
Part B holds for demonstrated pull —
needs-user-decision→pm:on-hold(maintainer ruling, 2026-08-09)維護者裁決 outranks 北極星 in the priority order, so a North Star re-grade cannot override it. Nothing about this card had changed; the seat simply had not read it.
Root cause, stated rather than buried. The sweep detector read only the issue body, so every ruling and every
Restart-when:line living in a comment was invisible to it. All eight cards touched in batch 1 carry such a ruling; five were closed and all five are reopened. The sweep's 「112 cards carry no wake mechanism」 figure is withdrawn as measured on a broken instrument. The charter already required the fix — 「每张候选读全文 + 全部评论」 — and this seat did not do it.
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actionsClosed
not_plannedby the director seat (summon #28 续,session_01GLdRPcbaCBQCTvVmU6YEUY), 2026-09-24T03:59Z, on the maintainer's word — closure review batch 2 of the opendomain:speccards under the restructured triage standard, presented from the business angle in this seat's chat; maintainer verbatim: 「19870 每段要以字母开头 有必要吗?其他同意」.card why it closes #2657 The roadmap is NORTH-STAR's 路上的功能点 table (「这张表就是路线图,改它即改优先级」); an umbrella over ~16 metadata types waiting for a customer to ask duplicates it. Part A was approved 2026-08-07 (5219867430) and its quick wins were filed separately; Part B's hold (2026-08-09, 5230641358) waited for demonstrated pull — that pull, when it comes, arrives as its own card for that one type, which is the hold's own restart shape. Studio rows on the road today cover objects / fields / lists / forms / pages / docs, not these types. This close supersedes the 2026-08-09 hold, on the maintainer's word. #8213 Its Restart-when:already names the next v18 ADR-0087 removal batch (the #5082 family); 阶段姿态 「按发布批量退役,不一键一卡」 ⇒ the note rides #5082 as a pointer (posted this act), not an open card. Zero pull; an inert export.Ledger: seat post #12708, this summon's next block.
Path: studio-authoring
Summary
Coverage audit of the new object-centric Studio (
StudioDesignSurface, objectuipackages/app-shell) against the authoritative metadata-type registry in@objectstack/spec(DEFAULT_METADATA_TYPE_REGISTRY). Of the 27 authorable metadata types, the new Studio surfaces ~11; the rest have no home yet. This issue tracks the gaps.Two of the gaps (per-object API reference + Hooks inventory) are already being handled on the objectui side (
feat/studio-object-api-hook-tabs) and are out of scope here.Coverage matrix
objectfieldvalidationscripteditable)hookseedmappingviewpagedashboardappreportactiondatasetflowjobpermissionprofileroledatasourcetranslationemail_templatebookdocexternal_catalogagenttoolskillWork split
A. objectui Studio UI (spec already complete — no framework change needed)
These are registered types with Zod schemas; the work is purely surfacing them in Studio (rail wiring + reuse of the generic
SchemaForm, or a bespoke canvas where the structure warrants it).action,dataset: previews are already registered inmetadata-admin/previews, only the Interfaces-pillar rail load is missing.job→ Automations (next toflow);role→ Access (next to permission/profile);seed/mapping→ Data;datasource→ Data or a "Sources" area.agent(note ADR-0063 §2: platform-only, not runtime-creatable → read-only surface),tool,skill.translation,email_template,book/doc; this is also the natural home for a global, executable API Console + auth (Authorize) control.(Tracked here for a single platform-wide view; execution lands in objectui.)
B. framework
@objectstack/spec(blocking dependency — must land here first)These concepts exist in
ObjectStackDefinitionSchema(stack.zod.ts) as config but are not registered metadata types, so Studio cannot surface them generically until they pass the ADR-0088 admission test and get a Zod schema + registry entry:webhooks(WebhookSchema) — outbound webhooksconnectors(ConnectorSchema) — external-system connectorsportals(PortalSchema) — external-user projections of apps/views/actionssharingRules(SharingRuleSchema) — object sharing rulesapis(ApiEndpointSchema) — currently code-only viacontributes.routes; formalizing as browsable metadata is what powers a first-class, executable API Console in StudioPer the cross-repo flow, each of these must merge in framework (schema + registry) before objectui can consume it.
Ask
Generated from a two-repo coverage audit (framework spec × objectui new Studio).
Blocked-by: #6234
Blocked-by: #6245
Generated by Claude Code