Skip to content

Studio metadata coverage gaps: surface remaining types + promote un-typed concepts #2657

Description

@os-zhuang

Path: studio-authoring

Summary

Coverage audit of the new object-centric Studio (StudioDesignSurface, objectui packages/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

Domain Type New Studio
Data object ✅ full (fields / form / validations / settings)
Data field validation 🟡 nested in object (validation: only script editable)
Data hook 🟠 in-progress (objectui, separate PR)
Data seed mapping ❌
UI view page dashboard app report ✅ Interfaces pillar
UI action dataset ❌ previews already registered, just not railed
Automation flow ✅ Automations pillar
Automation job ❌
Security permission profile ✅ Access pillar
Security role ❌
System datasource translation email_template book doc ❌
System external_catalog ➖ runtime-derived by Sync wizard — intentionally skip
AI agent tool skill ❌ no AI pillar exists

Work 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).

  • Quick wins — action, dataset: previews are already registered in metadata-admin/previews, only the Interfaces-pillar rail load is missing.
  • Fill existing pillars — job → Automations (next to flow); role → Access (next to permission/profile); seed/mapping → Data; datasource → Data or a "Sources" area.
  • New AI pillar — agent (note ADR-0063 §2: platform-only, not runtime-creatable → read-only surface), tool, skill.
  • New System/Integration pillar — 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 webhooks
  • connectors (ConnectorSchema) — external-system connectors
  • portals (PortalSchema) — external-user projections of apps/views/actions
  • sharingRules (SharingRuleSchema) — object sharing rules
  • apis (ApiEndpointSchema) — currently code-only via contributes.routes; formalizing as browsable metadata is what powers a first-class, executable API Console in Studio

Per the cross-repo flow, each of these must merge in framework (schema + registry) before objectui can consume it.

Ask

  1. Decide which of the Part B concepts are worth promoting to registered metadata types (and in what order).
  2. Confirm the Part A placement plan (pillars) so objectui can schedule the UI work.

Generated from a two-repo coverage audit (framework spec × objectui new Studio).

Blocked-by: #6234
Blocked-by: #6245


Generated by Claude Code

Activity

  1. os-zhuang commented on Jul 7, 2026

    @os-zhuang
    ContributorAuthor

    Update — object-scoped action landed (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 carry objectName and defineStack folds them into the object's inline actions[], so they render as an Actions tab on the object, master-detail, reusing the real ActionDefaultInspector form (create / edit / delete, persisted via the object draft). This supersedes the earlier "surface action in Interfaces" suggestion: object actions belong on the object; Interfaces should host only global actions (objectName unset / 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 condition object-vs-string render crash; unseeded type:'script' action 422 on body.language).

    Revised remaining work

    Part A (objectui UI — no framework change):

    • action (object-scoped) — done
    • global action — the objectName-less / global_nav slice 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 / apis need to become registered metadata types before Studio can surface them generically.

  2. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    分诊(spec 车道欠账代扫,维护者 2026-08-05 指令):挂 needs-user-decision——正文的 Ask 本就是给维护者的两问(Part B 五个概念哪些晋升为注册元数据类型及顺序;Part A 布局确认)。⚠️ 过时前提警告:覆盖矩阵是 07-06 快照 + 07-07 增量,一个月间已部分被超越——至少 apis 已随 #5312 注册为 api 元数据类型(Part B 五项之一已事实完成),object-scoped action 已落(objectui#2330)。建议拍板前先让 spec 车道重跑一次两仓覆盖审计刷新矩阵,避免按旧地图决策;届时 Part B 余项(webhooks/connectors/portals/sharingRules)按 ADR-0088 准入逐个过。不构成认领。会话:session_01N3uGFF8teXbpgtbEJ1aYXu


    Generated by Claude Code

  3. claude commented on Aug 6, 2026

    @claude
    Contributor

    处置(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

  4. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    【决策箱注记】维护者 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

  5. hotlong commented on Aug 7, 2026

    @hotlong
    Contributor

    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 (api promoted via #5312; role/profile/validation retired; 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: #6234 applied.


    Generated by Claude Code

  6. hotlong commented on Aug 7, 2026

    @hotlong
    Contributor

    Refreshed two-repo metadata-type coverage matrix (audit requested by #6234)

    Read-only audit. Every fact below is read from origin/main of 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 — apis was admitted (#5271 / PR #5312) and portals was 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 closed MetadataTypeSchema enum it keys off is :72-158.

    domain kinds registry lines
    data (5) object field hook seed mapping 604, 605, 613, 621, 627
    ui (7) view page dashboard app action report dataset 634-642
    automation (2) flow job 649, 684
    system (7) datasource external_catalog api translation email_template doc book 692, 713, 762, 763, 764, 770, 774
    security (2) permission position 777, 778
    ai (3) agent tool skill 825-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 is external_catalog, whose absence is deliberate and permanent (ADR-0088 §3; noted at metadata-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 — seed mapping job datasource external_catalog api translation doc book — 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 object StudioDesignSurface.tsx:1200, :2039
    Automations flow :2849
    Interfaces app (nav tree drives page/view/dashboard/report canvases) :1231
    Access permission (+ package OWD overview) :3289

    Plus 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 to DEFAULT_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/types at 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 ❌ — dataset job seed mapping datasource translation email_template book doc agent tool skill — 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; showcase KIND_COVERAGE.api demonstrated; ledger liveness/api.json 1·2·3 pass — shipped (PR #5312, size/xl)
    portals ❌ N/A — collection REMOVED ❌ no PortalSchema anywhere on main none none zero n/a n/a row deleted
    webhooks → webhook ❌ (ingested, not registered) ✅ WebhookSchema packages/spec/src/automation/webhook.zod.ts:133 — strictObject, ADR-0010 envelope declared (:215, :228) /api/v1/meta/webhook/... UNVALIDATED 200 Directory tile (synthesised entry, raw-JSON); objectui does client-validate it (clientValidation.ts:124) plugin-webhooks/src/bootstrap-declared-webhooks.ts re-parse()s at boot → sys_webhook → AutoEnqueuer; ledger liveness/webhook.json = 11/11 props live; governed via SPEC_ONLY_SCHEMAS (check-liveness.mts:194-198) 1·2·3 pass door question (§6); re-point the fixtures that use webhook as the canonical "no static registry entry" specimen M
    connectors → connector ❌ (ingested, not registered) ⚠️ two contend: ConnectorSchema integration/connector.zod.ts:648 (runtime instance) vs DeclarativeConnectorEntrySchema :843 (the actual connectors: shape). Non-strict, no ADR-0010 envelope /api/v1/meta/connector/... UNVALIDATED 200; separately GET /api/v1/automation/connectors (runtime/src/route-ledger.ts:233) Directory tile only; flow canvas has a connector_action node service-automation/src/plugin.ts:1016+ materializes provider-bound entries at boot; engine.ts connector registry; 4 connector packages; showcase STACK_COLLECTION_COVERAGE.connectors demonstrated 1·2·3 pass no liveness ledger; must pick which schema the kind resolves; superRefine ⇒ ZodEffects, so the /meta/types JSON Schema emission must be measured, not assumed L
    sharingRules → sharing_rule ❌ (ingested, not registered) ✅ SharingRuleSchema = CriteriaSharingRuleSchema packages/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 + AccessExplainPanel rule kinds, not rule authoring plugin-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 (only defineStack and lint do) no liveness ledger; .strict() + no envelope ⇒ stamped items would be rejected at parse, the exact trap #5312 measured on api; three write doors and no ruling on which is canonical L

    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 with allowRuntimeCreate: true for 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 connector by hand: sys-metadata-repository.ts:198-207 and the intent === '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) returns null, and the save path is guarded by a bare if (schema) (protocol.ts:7857-7860).
    • An in-repo test asserts the outcome: packages/objectql/src/protocol-meta.test.ts:1461-1469 saves type: 'webhook' with body { name, url, events: [...] } and expects success: true. events is not a WebhookSchema key — it is a rejected alias that maps to triggers — and object/triggers are 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:". PortalSchema has no export const declaration 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-level portals collection was removed — PortalSchema was 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_COVERAGE row. 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 props dead → live and 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, not ConnectorSchema — 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 position is registered (:778), has a FormView (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.
    seed mapping job datasource translation email_template book doc agent tool skill ❌ re-scored: all are authorable in the Metadata Directory today; ❌ should read "no pillar", not "no home".
    external_catalog ➖ intentionally skip unchanged 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 retired workflows/approvals/roles/profiles/policies/ragPipelines), ARTIFACT_FIELD_TO_TYPE (metadata/src/plugin.ts:60, maps seeds data → the analytics kind dataset and omits datasets/jobs/datasources/translations/capabilities), MetadataCategoryEnum (spec/src/kernel/package-artifact.zod.ts:49, still lists retired triggers/workflows), and STACK_COLLECTION_COVERAGE (examples/app-showcase/src/coverage.ts:181, unlike KIND_COVERAGE it 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 to stack.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_rule is skipped as "declared but has empty shape" (it is a .strict() 8-key object at sharing.zod.ts:217); translation is judged by TranslationBundleSchema when the kind resolves TranslationItemSchema; connector is skipped for requiring an id field that ConnectorSchema:648 does not have. Same class as the email_template mis-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. api was a clean promotion because the metadata item itself is what the runtime reads — the endpoint matcher indexes stored api rows, 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:

    1. an authoring collection in stack.zod.ts,
    2. a boot materializer into a runtime table/registry, and
    3. 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_rule it must also decide what happens to the existing /api/v1/sharing/rules family).

    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/types emit 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 at size/xl. Read the sizes below against that bar:

    row size why
    webhook M Everything the api promotion had to build already exists: strict schema, ADR-0010 envelope (webhook.zod.ts:215, :228), a liveness ledger with 11/11 props live, a boot consumer that already .parse()s. Remaining: registry entry + enum + schema-map binding + KIND_COVERAGE row + re-pointing the fixtures that currently use webhook as the canonical "no static registry entry" specimen. #3490 already scoped this as its optional item 5.
    connector L No liveness ledger → the ratchet (check-liveness.mts:145-153) demands one or a PENDING_GOVERNANCE debt entry with an issue, over an 800-line schema. Must first rule which schema the kind resolves (ConnectorSchema vs DeclarativeConnectorEntrySchema). No ADR-0010 envelope. superRefine ⇒ ZodEffects, so z.toJSONSchema() behaviour on the /meta/types payload must be measured before promising a Studio form.
    sharing_rule L No ledger. .strict() and no ADR-0010 envelope: stamped items would be rejected at parse — the precise failure #5312 measured on api (unrecognized_keys: ['packageId','state']) and had to resolve by listing api in STILL_STRIP. And it is the only row with a third door already shipped (/api/v1/sharing/rules, including POST .../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.

    1. §6.1 (what registration means for a bridged collection) gates all three rows. One ruling, not three.
    2. §6.2 (bind schemas without registering) is independent and should not wait — it removes today's hazard either way.
    3. If rows are admitted: webhook → connector → sharing_rule. webhook is 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.
    4. Every promotion additionally costs a showcase KIND_COVERAGE row (ratcheted — examples/app-showcase/test/coverage.test.ts:96-104 fails 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 that METADATA_FORM_REGISTRY is already the single source of the /meta form payload (metadata-protocol/src/protocol.ts:94) and that objectui already consumes the served entry.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 from fieldForm, 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 webhook only as the pilot and re-measure before committing to connector/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 /meta rather 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

  7. hotlong commented on Aug 7, 2026

    @hotlong
    Contributor

    Decision now ready (audit #6234 delivered above; pm:blocked cleared → needs-user-decision). The refreshed matrix corrects the frame: portals is deleted (#3464) so the ruling covers three rows — webhook / connector / sharing_rule — and all three are already writable through PUT /meta with 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 /meta write hole (#2657 audit, option A) #6245 and queued (unconditional under any later ruling).
    • B — register + let sys_metadata be 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/rules CRUD 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

  8. 16 remaining items

  9. os-justin commented on Sep 4, 2026

    @os-justin
    Collaborator

    H17 notice (no restart) — domain:spec seat, session_01H2oQebDDxYKfWZusyd8GXk, 2026-09-04T08:00Z. Dispatching #14676 touches packages/spec/src/integration/connector.zod.ts, one of this hold's Restart-touch files (comment 5511474502), so the hold was re-read before the dispatch. The restart condition — an open card asking to author a webhook / connector / sharing_rule through /meta — is not what #14676 is: it retires the dead errorMapping key and its two rule/config schemas from ConnectorSchema under 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

  10. os-litant commented on Sep 19, 2026

    @os-litant
    Collaborator

    Triage: Path: studio-authoring; grade none → p2; disposition keep (returned to pm: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.md as part of the maintainer-assigned full-board sweep. pm:on-hold was 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

  11. added
    priority:p1High: required for production / M2
    and removed
    priority:p1High: required for production / M2
    on Sep 19, 2026
  12. os-litant commented on Sep 19, 2026

    @os-litant
    Collaborator

    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 to pm: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

  13. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Closed not_planned by the director seat (summon #28 续, session_01GLdRPcbaCBQCTvVmU6YEUY), 2026-09-24T03:59Z, on the maintainer's word — closure review batch 2 of the open domain:spec cards 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.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions