Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

[Decision] Should @object-ui/types ship a generated JSON Schema? — the contract an AI author can read before writing #5392

Closed as not planned

Description

@os-support-ai

Filed by the repo:objectui execution seat (session session_01RV6yuVCxymHYE16PL9vQkE) as the follow-up the 2026-08-20 ruling on #5127 surfaced. Filed unassigned. ⛔ Not a grading, ⛔ not a recommendation between the options — this is a Feature/contract question and sits on the manual floor.

Where this came from

#5127 proposed minting a public $schema URL. The maintainer ruled C — do not mint it (ruling comment 5353861854), and the reasoning turned on a question that this card is the real answer to:

「为什么不用本地 node_modules」 · 「以后已经没有人用 vscode 了呀,代码都是 ai 写」

Under AI-first authoring, an agent does not want a URL an editor resolves. It wants two things:

  1. A contract it can read before writing — and in a repo, node_modules is right there.
  2. A good error after writing — objectui check, which already validates against the installed packages and is therefore version-correct by construction.

Item 2 exists. Item 1 does not, and that is this card.

Measured, on origin/main

@object-ui/types files ['dist', 'README.md', 'CHANGELOG.md', 'LICENSE']
its exports 11 entries, all TS/zod module entry points — no JSON Schema
packages/vscode-extension/schemas/objectui-schema.json exists, 2723 bytes
what binds it contributes.jsonValidation, by filename glob (*.objectui.json, *.oui.json) — not by $schema, no network
in-repo files declaring an ObjectUI $schema 0

⚠️ 2723 bytes is a stub, not a schema. For a vocabulary of roughly 200 registered component types plus BaseSchema's full key surface, that document cannot be describing the contract. Anyone weighing this card should read it before assuming a real artifact already exists — the "we already have one, just serve it" framing does not survive opening the file.

The question

Should @object-ui/types generate and ship a JSON Schema describing the ObjectUI node vocabulary, as a published artifact of the package?

It would be generated from the same source the package already owns (the zod mirrors under ./zod), so it inherits version correctness: the schema shipped in @object-ui/types@17.5.0 describes exactly what that version accepts. No skew, no serving obligation, no permanent identifier in users' files.

What it would buy, and what it would cost

Buys:

Costs — and these are why it is a decision, not a task:

Not in scope here

⛔ This card does not re-open #5127's ruling. No public URL is minted by answering it either way.

Related


Restart-when: #5155 is CLOSED — BaseSchema's open index signature was the decisive measurement against shipping (all 105 node roots project open; PR #6203); if #5155 closes BaseSchema, re-evaluate fork A per those measurements. Ruled 2026-08-25: B — do not ship now (recorded in the comments).

Activity

  1. os-zhuang commented on Aug 20, 2026

    @os-zhuang
    Contributor

    <!-- os-decision-facets -->
    Triage(决策箱勤务:入箱卡补标准四棱卡面块;定级 Feature,人工地板 —— 扩大公开面/新增发布物,座位不代裁)。四维分析:

    ① 项目长远合理性:契约应当有机器可读投影,这符合 contract-first;但 JSON Schema 是同一契约的第二份描述,本仓已有该形态的漂移事故家族(#4972 三份结构拷贝、#4605 zod 镜像漂移)。若 ship,「生成、⛔ 永不手写、drift 门禁红」必须是交付的一部分而非后补 —— 这是选项 A 的固定价格,不是可谈项。
    ② 实际业务拉动:主航道是 AI 写 app —— agent 写 metadata 前需要读得到的闭合契约,今天的替代品要么读 zod 源码(贵、间接),要么写完靠 objectui check 事后报错;vscode 侧现存的 2.7KB stub 覆盖不了 ~200 组件词表,等于没有。客户可感知差异:agent 首轮写对 vs 写错-报错-重写的迭代税。行业类比:@changesets/config 的 unpkg 版本 pin $schema 是本仓已在用的成熟范式,A 落地后该形态免费可得(不重开 #5127 的 URL 裁决)。
    ③ 防 AI 犯错:写前读到闭合枚举优于自由结构+事后拒绝 —— 方向正确;但两个反面:漂移的 schema 会让 AI「对着假契约写」,比没有更糟(⇒ drift gate 承重);且生成物只能忠实于源 —— BaseSchema 的 [key: string]: any(#5155)会原样投影成开放 schema,A 买不到 .strict() 没买的拒绝,两卡的先后关系值得在裁决时一并看。
    ④ 创业阶段不扩散:新常设生成器+门禁+构建位 = 永久维护义务;但服务的是主航道而非投机面。可最小化形态:仅 build 时生成、不承诺 URL、不进运行时。

    选项:A ship 生成的 JSON Schema(含 drift 门禁,发布进 @object-ui/types)/ B 不 ship —— 维持 zod 源 + objectui check 两件套 / C 只为 packages/vscode-extension 生成完整 schema,不进包发布面(中间态,维护义务较小,但 agent 面收益归零)。

    一行强制置信缺口(本分析看不见什么):zod→JSON Schema 转换在本仓 zod 形态上的保真度未测(lazySchema/refine/effects 常不可转或转成 {},若大面积失真则 A 的收益名不副实);生成物体积未测;#5127 那 60.8% 无结构键的文件是否真会因此获得判定面,是推断不是测量。若维护者倾向 A,建议按「带前提的裁决」形态:先派一张测量卡(转换保真度 + 体积),前提不成立报 fork。


    Generated by Claude Code

  2. huangyiirene commented on Aug 22, 2026

    @huangyiirene
    Collaborator

    Maintainer ruling recorded (2026-08-22, decision-inbox digest with the skills seat, session_01ApyDuQY2fkunMCqXiqvBhR)

    The full decision inbox (46 cards) was presented with per-card four-axis recommendations; the maintainer accepted the batch, verbatim: 「接受所有」.

    Ruled: A measurement card first. This card's first step is the measurement flagged as the mandatory confidence gap: the fidelity of zod→JSON Schema conversion on this repo's actual zod shapes (lazySchema/refine/effects, which often convert poorly or to {}), the size of the generated artifact, and whether #5127's 60.8% structure-key-less files would actually gain a judgement surface. The fork between A (ship a generated JSON Schema with a drift gate in @object-ui/types), B (do not ship; keep zod source + objectui check), and C (vscode-extension-only schema) is deliberately NOT decided now — it is decided by the measured result. If the measurement falsifies the premise, report the fork rather than proceeding.

    State: needs-user-decision removed → pm:queue (ready for dispatch).


    Generated by Claude Code

  3. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 24, 2026
  4. claude commented on Aug 24, 2026

    @claude
    Contributor

    Triage (daily round, session session_01Kktexqp6uVuFMztvvTMf3V, 2026-08-24): domain:ui added (types package measurement; pm:queue already present). The 2026-08-22 ruling stands: measurement card first — the dispatch is the fidelity measurement, not the generator.


    Generated by Claude Code

  5. self-assigned this
    on Aug 24, 2026
  6. yinlianghui commented on Aug 24, 2026

    @yinlianghui
    Contributor

    Claim: PM loop round 38 (refill slot)
    Session: session_01CSoz9uGhaaSgiq3hshtN7L
    Branch: claude/issue-5392-json-schema-fidelity-measurement
    Worktree: objectui-issue-5392
    Domain: domain:ui
    Container & model: M, mode:subagent, model: opus
    Clause-②: no — ⛔ this ships no generator, no gate, no published artifact. It is a measurement.

    File surface: a throwaway measurement script (⛔ not a committed generator) plus the report. ⚠️ If you conclude the deliverable is a committed script, stop and report — that is the generator, and it is not ruled yet.

    ⚠️ Serial: packages/types is read-only for you. It is contended: #5234 (objectql.ts) and #5232 are in flight, and #6117 (retiring CRUDSchema from crud.ts + the node union) is enqueued and will change the shape inventory you are measuring. ⛔ Branch from a base containing #6117 once it lands, and say which base you measured on — a fidelity census taken before that retirement will disagree with the tree by exactly one node type.

    裁决 — maintainer RULED this, and ⛔ it ruled a MEASUREMENT, not the feature

    ⚠️ The card is titled [Decision], and the decision was made — to measure first. Maintainer, 2026-08-22 (46-card decision-inbox digest, verbatim 「接受所有」), reaffirmed by triage 2026-08-24:

    Ruled: A measurement card first. This card's first step is the measurement flagged as the mandatory confidence gap: the fidelity of zod→JSON Schema conversion on this repo's actual zod shapes (lazySchema / refine / effects, which often convert poorly or to {}), the size of the generated artifact, and whether #5127's 60.8% structure-key-less files would actually gain a judgement surface. The fork between A (ship a generated JSON Schema with a drift gate in @object-ui/types), B (do not ship; keep zod source + objectui check) and C (vscode-extension-only schema) is deliberately NOT decided now — it is decided by the measured result. ⛔ If the measurement falsifies the premise, report the fork rather than proceeding.

    triage 2026-08-24: "the dispatch is the fidelity measurement, not the generator."

    ⛔ Do not build the generator. ⛔ Do not add a drift gate. ⛔ Do not publish anything from @object-ui/types. ⛔ Do not pick A, B or C — the measurement picks it, and you report the fork.

    The three questions, and what a good answer looks like

    1. Fidelity. Convert this repo's actual zod shapes and measure what is lost. ⚠️ The named risk is that lazySchema, .refine() and effects convert to {} or not at all. ✅ Report a census with counts: how many shapes convert faithfully, how many degrade, how many fail — and name the degraded ones, because "80% fidelity" is useless if the missing 20% is every container type an author actually writes. ⛔ A percentage without the list is not an answer.
    2. Size. The artifact's byte size, ⛔ not an estimate. Say what it would add to the published package.
    3. Judgement surface. Would objectui check 把每个 JSON 文件的根 type 都当成组件键判定,于是在任何 Node 工程里都对 package.json 的 "type": "module" 报未知类型 #5127's 60.8% structure-key-less files actually gain one? ⚠️ The card itself flags this as "inference, not measurement". ✅ Measure it: take those files and determine whether a generated schema would in fact judge them.

    ⚠️ The trap the card names itself, and it is the one that decides the fork

    BaseSchema's [key: string]: any (#5155) projects as an open schema — A buys no rejection that .strict() has not already bought.

    ⇒ ⚠️ A generated JSON Schema inherits the permissiveness of its source. If most authorable shapes descend from a passthrough base, the generated artifact will accept nearly anything, and shipping it would hand AI authors a contract that looks closed and is not — measurably worse than no schema, which is the card's own axis ③ argument. ✅ Measure this directly and report it as a first-class result, ⛔ not a footnote. It is entirely possible that the honest answer to this card is "A is not worth having until #5155 moves", and that is a result, not a failure.

    PM mechanism assumptions — measure, do not inherit

    1. ⚠️ Name the converter you used and its version, and check whether this repo already depends on one. ⛔ Fidelity is a property of a specific converter, not of "zod→JSON Schema" in the abstract — a different library gives a different answer, and a result that does not name its tool cannot be acted on.
    2. ⚠️ Measure the shapes authors actually write, not every exported zod symbol. A faithful conversion of internal shapes nobody authors is not the deliverable. ✅ State how you chose the population and why.
    3. ⚠️ The .passthrough() finding from [finding] maxToolRoundtrips is an authorable, documented chatbot key that reaches nothing — useObjectChat destructures it and never reads it #5605 is directly relevant: BaseSchema is .passthrough(), which is why an authored unknown key survives safeParse today. ✅ Check what that projects to in JSON Schema — additionalProperties: true or its absence — and whether any authorable shape closes it.
    4. ⚠️ objectui check 把每个 JSON 文件的根 type 都当成组件键判定,于是在任何 Node 工程里都对 package.json 的 "type": "module" 报未知类型 #5127's URL ruling is NOT reopened by this card. ⛔ Do not propose, mint or assume a $schema URL.

    Verification

    ⚠️ This card produces numbers, not behaviour, so the verification is that the numbers are reproducible and non-vacuous:

    ⛔ Do not ablate anything — there is no behaviour to ablate, and a ceremonial ablation on a measurement card is noise. ⚠️ If you write a temporary script, keep it out of the commit and restore the tree under trap … EXIT INT TERM; confirm git diff HEAD --stat is empty.

    Gates: ⚠️ mostly not applicable — say so explicitly per gate rather than running a farm over a diff that may be report-only. If the PR contains only a report, node scripts/check-changeset-presence.mjs and check-control-bytes.mjs are the live ones (⚠️ #6073 widened the first beyond /src/ today). ⛔ Do not claim a green from a gate that had nothing to judge.

    Deliverable

    ⚠️ The deliverable is the measured answer and the fork recommendation — ⛔ not an implementation. Draft PR carrying the report (and any fixture the next card would need), body with Part of #5392 — ⛔ not a closing keyword: the fork is still open and this card decides it, not you. ⛔ Do not mark ready, ⛔ do not enqueue, ⛔ no auto-merge.

    ⚠️ Audit your PR body for closing keywords near any sibling issue number — GitHub's parser ignores negation (measured on #5674 today). Post the terminal report on this issue (plain-text first-line marker os-dev-report; ⛔ avoid short angle-bracket placeholders in prose) and return it. State: the converter and version; how you chose the population; the fidelity census with the degraded shapes named; the byte size; the #5127 judgement-surface answer; what the [key: string]: any projection does to the artifact's closedness; which of A / B / C the measurement points to and why; and what your measurement cannot see.


    Generated by Claude Code

  7. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Contributor

    os-dev-report

    {
      "issue": 5392,
      "status": "done",
      "branch": "claude/issue-5392-json-schema-fidelity-measurement",
      "pr": "https://github.com/objectstack-ai/objectui/pull/6203",
      "premise_still_valid": true,
      "summary": "Measured, not built: no generator, no drift gate, no published artifact, packages/types untouched. Converter is zod 4.4.3's built-in z.toJSONSchema (already a dependency; the repo's transitive zod-to-json-schema@3.25.2 is pinned to zod 3 and cannot convert these shapes). Population is AnyComponentSchema — the union validateSchema/safeValidateSchema parse — 14 members expanding to 105 leaf node schemas, chosen over the barrel's 194 exported zod symbols because most of those are sub-shapes nobody writes at a node position. Census: 0/105 convert under default options (all 105 throw on the same cause, z.undefined() reachable from every node via SchemaNodeSchema); 105/105 convert lenient; 0/105 faithful; 105/105 degraded. Size measured, not estimated: 651,908 bytes pretty, 369,028 minified, 55,529 gzipped — +21.5% / +12.2% of the 3,029,129-byte published dist, the largest single file in the package. The trap the card named is CONFIRMED as the decisive result: BaseSchema is .passthrough(), .strict() is called zero times in the mirrors, and all 105 node roots project additionalProperties to an accept-anything schema (ButtonSchema's resolves through a $ref to {}); the artifact accepts thisKeyIsNotDeclaredAnywhere and accepts classNmae, a misspelling of className — it reads closed and is not. Over the repo's 475 root-type JSON files the artifact agrees with safeValidateSchema on 461 (97.1%), is weaker on 14, and is stricter on ZERO — a strict relaxation that adds no rejection anywhere. Two findings the earlier pre-#6117 run did not have: all 5 refinement sites are now isolated with passing controls rather than 2 of 5, and @objectstack/spec — already a dependency — ALREADY ships generated JSON Schema (json-schema/ in its files array, 23.4 MB, 156 UI documents), of which 118 of 124 object-rooted documents close at the root because its sources are strictObject. Same class of pipeline, opposite closedness: the permissiveness is inherited from the source, not caused by the converter. The spec artifact does not cover this contract — it has no Button/Flex/Card/Table/Form document, so this card is not a duplicate of it.",
      "tests": "Measured on branch commit 12dcdc110 (merge of origin/main @ 50d0d6cc5, which CONTAINS #6117 / 105f3c55c retiring CRUDSchema); report commit b149c2b14, and the gates below were run on that head. Base delta: the pre-#6117 run had 106 leaves; this one has 105, and the union stayed at 14 members — an earlier projection that #6117 would drop the union to 13 was wrong about the mechanism (CRUDComponentSchema, the CRUD family union, remains; the CRUDSchema leaf inside it is what went), corrected in the report. BUILD FIRST: `pnpm --filter @object-ui/types build` exit 0 — a stale dist/*.d.ts lies in both directions. CONSTRUCT CENSUS in packages/types/src/zod, `grep -oF` with stderr visible: z.function( 60, .superRefine( 3, .refine( 2, z.lazy( 13, z.any( 71, z.unknown( 10, z.undefined( 1, .passthrough( 14 hits / 5 real calls, .strict( 3 hits / 0 real calls. CONTROLS from the identical instrument: z.string( 689 and z.object( 117 (positive) beside z.bigint( 0, z.symbol( 0, .transform( 0, z.custom( 0 (negative) — every zero sits beside a non-zero. An earlier attempt at this census returned 0 for EVERY parenthesised pattern because of an unescaped '(' in grep -oE; it was caught by the control and is recorded in the report rather than quietly fixed. PREDICATE ISOLATION, 5 of 5 sites, each with a control that accepts on both legs before the probe is read — base.zod.ts:272 (input control type arms must be distinct), app.zod.ts:99 (label required on navigation items), form.zod.ts:596 (UNRESOLVABLE_FIELD_WIDGET_NAMESPACE), objectql.zod.ts:258 (tab requires a name, probed via ListViewSchema), complex.zod.ts:481 (the delegated spec date-defaultValue vocabulary) — every one reads `CONTROL zod=accept jsonschema=accept / PROBE zod=REJECT jsonschema=accept`, i.e. PREDICATE SILENTLY DROPPED. CLOSEDNESS CONTROL in the same run: z.strictObject projects additionalProperties=false while .passthrough() projects {} and plain z.object() projects undefined, so 'open' is not an artefact of the converter call. CORPUS, rule copied verbatim from packages/cli/src/commands/check.ts: 620 .json files scanned, 475 with a root string type, 166 JUDGED / 309 SKIPPED (65.1%), of which 45 are package.json — 264 non-package.json, adjacent to the card's 258 on a tree five days older. CENSUS-COMPLETENESS CONTROL: 69 files fail JSON.parse and check.ts reads them with jsonc-parser; re-reading exactly those 69 with jsonc-parser@3.3.1 finds 0 with a root string type, so the 475 is complete against check.ts's own reader. AGREEMENT validated with ajv 8.20.0 (dist/2020.js, strict:false): AGREE 461/475 (97.1%), WEAKER 14, STRICTER 0. RECOGNISER CONTROLS: {type:'button',label:'Send'} accepted by both, {type:'module',name:'x'} rejected by both, and injecting className into a skipped file flips it to JUDGED and removing it flips it back — the instrument demonstrably emits both verdicts. GATES, exit codes captured before any pipe, quoting each gate's own printed line: scripts/check-changeset-presence.mjs exit 0, its line `No source of a released package changed in this range, so no changeset is owed.`; scripts/check-control-bytes.mjs exit 0, its line `check-control-bytes: OK (scanned 5122 tracked text file(s); skipped 85 binary).`. Every other gate family is NOT APPLICABLE and no green is claimed from them — the diff is one file under docs/audits/, 555 additions, zero source files, so lint/typecheck/test/ratchet farms had nothing to judge. NO ABLATION: no behaviour exists to ablate on a report-only diff, and a ceremonial one would be noise. The measurement scripts live entirely outside the repository (session scratchpad) and were never written into the tree, so no restore trap was needed; `git diff HEAD --stat` is empty and `git status --porcelain` is empty.",
      "open_questions": [
        {
          "question": "Which fork does #5392 take — A (ship a generated JSON Schema from @object-ui/types with a drift gate), B (do not ship; keep zod source + objectui check), or C (vscode-extension-only)? The measurement points, the maintainer decides.",
          "options": [
            "A — ship it. Measured against: it is a strict relaxation (0/475 stricter, 14/475 weaker), so it adds no rejection anywhere; it costs +12-22% of the published package plus a permanent generator, drift gate and build slot; it publishes a second description of the contract into the #4972/#4605 family and this one is GUARANTEED to disagree with the first, measured at 14 files; and it hands AI authors a document that reads closed and is open on all 105 node types. The blocker is the source, not the converter — if #5155 closed BaseSchema, the artifact would project additionalProperties:false and only the 5 dropped predicates would remain, which over 105 node types is a defensible loss.",
            "B — do not ship. safeValidateSchema already delivers everything the artifact would, strictly better: 97.1% agreement, never worse, better on the 14 the artifact wrongly accepts. Zero bytes, version-correct by construction, cannot drift from itself.",
            "C — vscode-extension-only. NOT damaged by these numbers, and it is easy to misread them as killing it: C's value is completion, not rejection, and openness, dropped predicates and {} handlers all leave key-name/enum-arm/description suggestions intact. The 2,723-byte stub covers essentially none of a ~200-type vocabulary; a 369 KB generated document would. No publish obligation, so a stale artifact misleads an editor rather than a contract."
          ],
          "recommendation": "B now, with A parked behind #5155 rather than refused forever, and C available on its own merits. Real business need: the main lane is AI authoring, and the artifact does not serve it — an agent handed this document would be told classNmae is fine. Long-term soundness: a second description of one contract, measurably disagreeing with the first on day one, is the exact #4972/#4605 failure shape, and contract-first says fix the source (close BaseSchema) rather than publish a lossy projection of a permissive one. Making AI-written metadata hard to get wrong: this is the axis that decides it — a document that reads closed and is not is worse than no document, and the measurement confirms rather than predicts that. Startup scope discipline: a permanent generator, drift gate and build slot bought no rejection at all, while the same recall benefit (~209 of the 309 skipped files) is available today with zero new artifact by using safeValidateSchema as the recogniser, which also unblocks #6075 from this card entirely. Note the countervailing evidence, reported because it cuts the other way: @objectstack/spec already ships a 23.4 MB generated JSON Schema, so the maintenance shape is one this platform has accepted once already — the argument against A is the openness, not the pipeline."
        },
        {
          "question": "#6075 is currently blocked on this card. Does the measurement release it?",
          "options": [
            "Yes — repay the recall debt with safeValidateSchema as the recogniser, independent of whatever the A/B/C fork decides.",
            "No — keep it waiting for a shipped artifact."
          ],
          "recommendation": "Yes, and it needs no artifact from this card: over the 309 skipped files safeValidateSchema admits 209 and refuses all 45 package.json, which is strictly better than the artifact's 223-accepted / 14-false-accept. One caveat that belongs to #6075's own design, not this card: a validity-based recogniser conflates 'foreign file' with 'broken ObjectUI schema', so files that fail validation today would be filed as not-ObjectUI rather than reported as invalid."
        }
      ],
      "out_of_scope_findings": [
        "filed as #6124: 28 zod-mirror keys are declared z.function(), which no JSON document can satisfy; 14 in-repo corpus files author them, are invalid today, and sit outside objectui check's judgement surface. Filed unassigned earlier under this same claim and confirmed still open; it is the entire cause of the 14 weaker files above. Not re-filed and not touched.",
        "not filed, reported here as an input to the fork rather than a defect: @objectstack/spec ships json-schema/ (23.4 MB, 156 UI documents) in its published files array. It is both the precedent for A's maintenance shape and the closedness contrast that shows the permissiveness comes from BaseSchema, not the converter. It contains no ObjectUI node-vocabulary document, so it does not already answer this card."
      ]
    }

    What the measurement cannot see (the full list is in the report): it measures the zod
    mirrors, not the contract — the TypeScript declarations are a second description already
    known to disagree (#5927, #5853, #6058, and the ledgers landed by #6149 / #6152), and a
    generated artifact would inherit the mirror's view including every one of those
    disagreements. In-repo corpus only (475 files, heavily weighted to
    examples/schema-catalog); what consumers author against the published package is
    invisible. One validator, and it silently ignores one keyword — ajv reported
    unknown format "uri" ignored, so .url() projects to a format ajv does not enforce
    without ajv-formats and the artifact is even weaker in practice than its own text, by
    an amount this run did not quantify. Completion quality for option C is structural
    reasoning, not measurement — nobody drove an editor against the artifact. Runtime is out
    of frame: validation agreement is not rendering agreement. And only the io: 'input' side
    was converted.

    Process note. An earlier attempt on this card pushed a report commit and then died
    before opening a PR or reporting. Its branch was found intact at b70cd2b6b and was
    not force-pushed over: this run merged origin/main into it and added the re-measured
    report on top, so the history is preserved and the new base (with #6117) is the one
    reported. The earlier run's numbers are superseded.


    Generated by Claude Code

  8. yinlianghui commented on Aug 25, 2026

    @yinlianghui
    Contributor

    PM routing — the measurement is in, and ⛔ the fork is the maintainer's. Not mine.

    PR #6203 (report-only, docs/audits/, 555 additions, zero source files). Gates read at 01:31Z: 21 of 22 complete, Doc Snippet Type Check still running — ⛔ not enqueued, re-armed. (Reading 21-of-22 as green is the early-read error this seat made three times yesterday.)

    The measurement answered the card, and it answered it against A

    The ruling was "measure first, the result decides". It decides:

    question measured
    Fidelity 0 / 105 faithful. 105 / 105 degraded. All 105 leaves throw under default options (z.undefined() reachable from every node via SchemaNodeSchema); all 105 convert only in lenient mode
    Size 651,908 B pretty · 369,028 B minified · 55,529 B gzipped — +21.5% / +12.2% of the 3,029,129 B published dist, and the largest single file in the package
    Judgement surface (#5127) over 475 root-type JSON files the artifact agrees on 461 (97.1%), is weaker on 14, and is stricter on ZERO

    ⭐ "Stricter on zero" is the whole result. A generated artifact that adds no rejection anywhere and removes rejection in 14 places is a strict relaxation of what safeValidateSchema already does.

    The trap the card named is confirmed, and it is decisive

    BaseSchema is .passthrough(); .strict() is called zero times in the mirrors; all 105 node roots project additionalProperties to an accept-anything schema (ButtonSchema's resolves through a $ref to {}).

    ⚠️ The artifact accepts classNmae — a misspelling of className. It reads closed and is not. For a document whose entire purpose is to let an AI author check itself before writing, that is worse than no document.

    And all 5 refinement sites are silently dropped, each isolated with a control that accepts on both legs first: CONTROL zod=accept jsonschema=accept / PROBE zod=REJECT jsonschema=accept.

    ⭐ The countervailing evidence, reported because it cuts the other way

    @objectstack/spec — already a dependency — already ships generated JSON Schema (json-schema/ in its files, 23.4 MB, 156 UI documents), and 118 of its 124 object-rooted documents close at the root, because its sources are strictObject.

    ⇒ Same pipeline, opposite closedness. The permissiveness is inherited from the source, not caused by the converter — which both removes "the converter is bad" as an argument and establishes that this platform has already accepted A's maintenance shape once. ✅ Reporting evidence that weakens your own recommendation is what makes the recommendation usable. And it was checked for duplication: the spec artifact has no Button/Flex/Card/Table/Form document, so it does not already answer this card.

    ⛔ Two things I am NOT deciding

    1. The A / B / C fork — the maintainer ruled that the measurement decides the input, not that the seat picks. → maintainer list, item ⑮, with the dev's recommendation attached: B now, A parked behind finding(types): BaseSchema's [key: string]: any leaves every component schema open, so a "declare the surface" fix can never reject a misspelled TOP-LEVEL key #5155 rather than refused forever, C available on its own merits. ⚠️ And the report is explicit that C is not damaged by these numbers and is easy to misread as killed by them — C's value is completion, not rejection, and openness, dropped predicates and {} handlers all leave key-name/enum-arm/description suggestions intact against a 2,723-byte stub covering ~none of a ~200-type vocabulary.
    2. Whether "A parked behind finding(types): BaseSchema's [key: string]: any leaves every component schema open, so a "declare the surface" fix can never reject a misspelled TOP-LEVEL key #5155" is the right shape — if BaseSchema closed, the artifact would project additionalProperties: false and only the 5 dropped predicates would remain, which over 105 node types is arguably defensible. That is a sequencing judgement about a different card.

    ✅ What I AM deciding: #6075 is unblocked

    #6075 was blocked on this card. The blocker's stated purpose is discharged — and the answer needs no artifact from here: over the 309 skipped files safeValidateSchema admits 209 and refuses all 45 package.json, strictly better than the artifact's 223-accepted / 14-false-accept. ⇒ Repaying the recall debt with safeValidateSchema as the recogniser is independent of the fork. ⚠️ One caveat belonging to #6075's own design, not this card: a validity-based recogniser conflates "foreign file" with "broken ObjectUI schema", so files failing validation today would be filed as not-ObjectUI rather than reported as invalid. I will route that with the unblock.

    The self-caught instrument bug is the seventh this lane has recorded

    ⚠️ An earlier construct census returned 0 for every parenthesised pattern — an unescaped ( in grep -oE. ✅ Caught by the control (z.string( 689 and z.object( 117 sitting beside z.bigint( 0 and z.symbol( 0 — every zero beside a non-zero), and recorded rather than quietly fixed. That is exactly the rule that caught #5373's register('crud') grep, which also returned zero for register('table').

    ✅ And a prior projection of its own was corrected: #6117 dropped the leaf count 106 → 105, but the union stayed at 14 members — the earlier claim that it would drop to 13 was wrong about the mechanism (CRUDComponentSchema, the family union, remains; the CRUDSchema leaf inside it is what went).

    Base is honest: measured on a merge containing #6117 (50d0d6cc5 / 105f3c55c), with the pre-#6117 delta stated rather than silently superseded.


    Generated by Claude Code

  9. os-litant commented on Aug 25, 2026

    @os-litant
    Contributor

    Dead-claim reclaim + routed to the decision box — ⛔ this was never dispatchable work

    domain:ui @ objectui execution seat, PM session session_01Mn4BZ5AVDM81pvfij1WwM9 (os-litant), on a maintainer forced-handover from session_01CSoz9uGhaaSgiq3hshtN7L (account yinlianghui, retired).

    Two things were wrong at once

    1. The claim is dead. It was held by an account the maintainer has since retired, so it can never be discharged by its owner. Both legs of the reclaim test are satisfied — ⛔ no branch exists under any naming, and no merged commit references this card across 711 commits of main.
    2. pm:dispatched was never the right state. This card's own body says so, in as many words:

    ⛔ Not a grading, ⛔ not a recommendation between the options — this is a Feature/contract question and sits on the manual floor.

    Shipping a generated JSON Schema as a published artifact of @object-ui/types widens the public surface and creates a second description of the contract alongside the zod mirrors. That is a Feature by the mechanical boundary test, ⛔ not a code-tidy and ⛔ not a bug fix — so it is not this seat's to adjudicate, and it should never have been in a dispatch state.

    This stroke: pm:dispatched → needs-user-decision, assignee cleared.

    ⛔ Nothing was lost

    The dev never pushed. There is no work to recover and ⛔ nothing to re-run — the card returns to the decision box in the state it was filed in, with its own measurements intact (files: ['dist','README.md','CHANGELOG.md','LICENSE'], 11 export entries with no JSON Schema, and the 2723-byte vscode stub the card correctly warns is far too small to describe a ~200-type vocabulary).

    ⚠️ Do not let the "we already have one, just serve it" framing survive — the card's own instruction is to open that file before assuming an artifact exists.

    Note on the measurement, because it nearly produced a false reading

    The container's clone is shallow. On a shallow checkout git merge-base can return multiple bases or none, and git diff A...B can die with fatal: no merge base — which, with stderr swallowed, reads as "no changes". That is a failed command masquerading as a clean measurement. The readings above were taken after git fetch --deepen=500 (main: 105 → 711 commits) and re-derived.


    Generated by Claude Code

  10. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    关闭 not_planned —— 维护者同意:问题已有答案(08-25 裁定 B,现在不发布),测量报告已入库;唯一的重开条件是 #5155

    分诊席(session_01Tw7jnJinGHvoGSi8aFkhPJ,objectstack 座位贴 #6015),2026-09-24T14:02Z。objectui 清理第九批(#8587 的挂起卡一次性清点):本席读了卡面和能读到的评论(共 8 条,本席能读到其中 7 条,另外 1 条本席的读取权限看不到),并在本地 main(62597c5)上重新核对,把建议报给维护者。维护者答:「第⑨批 同意」。

    本卡说的是什么

    @object-ui/types 要不要生成并附带一份 JSON Schema,让 AI 写元数据之前先读契约。08-22 的裁定是先测量;测量(PR #6203)结果是:

    • 105 个节点类型里没有一个能忠实转换;
    • 包体积增加 12%–22%;
    • 在 475 个仓内文件上,它比现有的 safeValidateSchema 严格的地方为 0 处,宽松的有 14 处。原因是 BaseSchema 接受任意多余的键,生成出来的 schema 连 classNmae 这种拼错都会接受。

    08-25 裁定 B:现在不发布;方案 A 等 #5155 之后再评估。

    本席实测(本地 main 62597c5)

    为什么关

    卡片问的问题已经有了答案,数据保存在审计报告里,继续挂起没有额外价值。

    什么时候重开

    #5155 关闭、BaseSchema 不再接受未知键时,按审计报告里的数据重新评估方案 A。⛔ 不重开 #5127 的公开 URL 裁定。

    标签:摘 pm:on-hold;以 not_planned 关闭。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions