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

plugin-gantt, app-shell designers: an invalid gantt block is warned about and drawn anyway, and a failed spec derivation degrades the designer form instead of failing — refuse loudly #13459

Closed

Description

@os-zhuang

Filing gate ③: a maintainer-directed task. Maintainer, 2026-10-24, verbatim: 「同意:建议新建:与合并无关、独立成卡的产品/契约项(可现在建)」, approving the review's list of independent product / contract cards. Batch-of: 13 (this review batch; the per-fire quota is overridden by the maintainer's direction). Also filing gate ①: reach: a gantt view whose gantt config block fails GanttConfigSchema renders through packages/plugin-gantt/src/ObjectGantt.tsx (named renderer); the designer forms under packages/app-shell/src/views/metadata-admin/ derive their schema from the spec at runtime.

维护者速读

元数据路径上唯一一处「校验失败只 warn 然后照画」:ObjectGantt.tsx 的 GanttConfigSchema.safeParse(config) 失败后 console.warn 并返回原 config 继续渲染;对照 ObjectTimeline.tsx 的姿态(「日期轴永不虚构」,失败就拒绝)。另一类:设计器的 *-schema.ts 从 spec 派生 JSONSchema 失败时 catch → warn → 降级表单——派生失败是构建期事实,应让测试红而不是让页面降级。北极星:「验证响亮拒绝错的」。

Measured (2026-10-24, HEAD 7981384)

  • safeParse( sites in non-test source: 73; three follow the warn-and-continue shape; the one on the metadata render path is in packages/plugin-gantt/src/ObjectGantt.tsx: const result = GanttConfigSchema.safeParse(config); if (!result.success) console.warn(…); … return config.
  • Contrast packages/plugin-timeline/src/ObjectTimeline.tsx ("日期轴永不虚构 — undefined from here is a real answer, and the refusal below is what answers it").
  • Metadata-shaped console.warn sites: 20, mostly packages/app-shell/src/views/metadata-admin/*-schema.ts "failed to derive … JSONSchema from spec" (catch → warn → degraded designer form); also plugin-gantt/src/tzShift.ts (invalid timeZone falls back to the browser zone) and core/src/utils/date-display.ts.
  • Repo-wide: catch sites 1,738; comment-only or empty catch blocks 252 (top: auth/src/createAuthClient.ts 9, app-shell/src/providers/MetadataProvider.tsx 8); invariant( 0 (no helper exists). Not all are defects; the two above are the metadata-path ones.
  • Business reason: an AI-authored gantt block with a wrong key renders something plausible instead of a refusal, so the author never learns; a designer form that silently lost fields because derivation failed lets the author save metadata the spec will refuse.
  • Dedup (GanttConfigSchema|safeParse … warn): 1 hit, closed, unrelated (objectui#12709).

Task

  • ObjectGantt: on !result.success render the refusal (the timeline's posture), never the unvalidated config.
  • Designer *-schema.ts derivations: a failed derivation from spec fails a test (build-time fact), not the page; keep the runtime catch only for genuinely runtime inputs.
  • Optional: tzShift.ts invalid timeZone — refuse or surface, do not silently use the browser zone (decide with the spec row for timeZone).

Who acts: objectui domain:ui seat, one PR for gantt, one for the designer derivations. Effort S each.

Filed by the read-only whole-repo review session https://claude.ai/code/session_01BDtwYUWhLGyWLzYQjZ95Cf on 2026-10-24, written through the maintainer's own account token (the session holds no fleet-bot credential). Evidence files: that session's scratchpad (objectui-review-report.md, findings-*.md). ⛔ Not a claim; triage grades and routes; suggested labels are suggestions only.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    sduiServer-Driven UI runtime
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Oct 24, 2026
  2. added
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    and removed on Oct 24, 2026
  3. objectstack-fleet commented on Oct 24, 2026

    @objectstack-fleet
    Contributor

    Triage: first grade — bug · priority:p2 · domain:ui · area:studio · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-24T17:03Z

    ⛔ Not a claim, ⛔ not a dispatch.
    finding comes off.

    • An invalid gantt block is warned about and drawn anyway; it should fail loudly, as the rest of the metadata path does (Prime Directive 12: never a lenient fallback in a consumer). A failed spec derivation in the designer should show an error, not a degraded form.

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 1 · 2026-10-25T02:01Z
    Session: session_01AdaeVx4N1y9QsiBkJ31nfJ (the card session that works this card; claim written by the domain:ui seat 4 session session_01XWGTsmqrtrt1Zqh1ioWqsT)
    Account: os-elon-musk
    Branch: claude/project-thread-y2g2x6 (platform-assigned at spawn; the card session can push only this branch)
    Worktree: objectui-issue-13459
    Domain: domain:ui
    Seat: domain:ui#4
    File surface: packages/plugin-gantt/src/ObjectGantt.tsx (the GanttConfigSchema.safeParse branch and the refusal it renders); the five derivation sites in packages/app-shell/src/views/metadata-admin/{dashboard,package,page,report,view}-schema.ts; their tests; .changeset/13459-*.md (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default tier (dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: narrowed
    Responsibility: objectui's ObjectGantt draws a gantt block that fails GanttConfigSchema, and the metadata-admin designers degrade their form when spec derivation fails | ObjectTimeline's refusal posture ("日期轴永不虚构") | every author whose gantt block or designer form is wrong and is never told
    Thread-read: 6387054722
    Premise: holds — on objectui main c85408f, ObjectGantt.tsx:616 runs GanttConfigSchema.safeParse(config) and goes on with the unvalidated config on failure; failed to derive catch → warn sites sit in the five metadata-admin/*-schema.ts files above
    Serial constraints cleared: seat 1's objectui#13442 / #13449 / #13450 declare no path under plugin-gantt/src/** or app-shell/src/views/metadata-admin/**; seat 4's in-flight PRs (#13480–#13487) touch neither; no other in-flight card names these files
    Writes: all PR, comment and label writes go only through objectstack's relay (scripts/pm/fleet-write); never write with GitHub MCP.

    • Ruling section: filed under the maintainer's 「同意:建议新建:与合并无关、独立成卡的产品/契约项(可现在建)」; triage 6387054722: fail loudly, show an error in the designer instead of a degraded form.
    • One PR from this branch carries both items (the card's "one PR each" is two S halves of one M card; the platform gives one branch).
    • Must vs may: the gantt refusal and the designer derivation are the deliverable. A derivation from spec that fails becomes a failing test (build-time fact); the page shows an error instead of a silently thinner form; a runtime catch stays only where the input is genuinely runtime. ⛔ tzShift.ts (timeZone fallback) is out: the card ties it to a spec-row decision.
    • Clause-② reason: a block that rendered before is refused now; that narrows what renders and widens nothing. A narrowing owes one contract-review-tier review before the queue, which the seat arranges; the dev hangs no labels for it.
  5. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 13459,
      "status": "done",
      "branch": "claude/project-thread-y2g2x6",
      "pr": "https://github.com/objectstack-ai/objectui/pull/13490",
      "session": "session_01AdaeVx4N1y9QsiBkJ31nfJ",
      "premise_still_valid": true,
      "summary": "ObjectGantt now refuses a gantt block that fails GanttConfigSchema: getGanttConfig returns config null plus the parse issues, and the component renders a role=alert refusal naming each issue by its path in the block (gantt.endDateField: ...), instead of drawing the unvalidated block; valid blocks, the flat ObjectView/ListView spelling and the no-binding screen are unchanged. The ten catch-and-warn sites in metadata-admin/{dashboard,package,page,report,view}-schema.ts are removed with their _Failed flags, so a failed derivation from the bundled spec throws: tests go red and at runtime the route ErrorBoundary shows it instead of a thinner form; getter return types narrow to JsonSchema. tzShift.ts untouched per the claim. One PR, both halves, inside the claimed file surface (an i18n-pack draft of the refusal copy was reverted to stay inside it; copy is English like the neighbouring refusal).",
      "tests": "head e26d1cd. New ObjectGantt.invalidBlockRefusal-13459.test.tsx (4) + spec-derivation-13459.test.ts (14): 2 files 18 passed. vitest run packages/plugin-gantt/: Test Files 100 passed | 1 skipped (101), Tests 775 passed | 114 skipped. App-shell narrowed to the 88 test files importing a changed module or its callers: 88 passed, 721 tests passed (blind spot declared in PR body; CI shards the full package). Ablation, fix committed first, restored with git checkout HEAD --, git diff HEAD empty: ObjectGantt.tsx at origin/main -> 3 refusal cases fail, CONTROL passes; view-schema.ts at origin/main -> 3 view-schema throw cases fail. A first hoisted vi.mock('zod') leaked into view-schema.test.ts (3 failures in the 88-file run); replaced with scoped vi.doMock/doUnmock in a3b60c1, re-run green.",
      "gates": "local: eslint --no-inline-config on touched files :: exit 0 (0 errors, pre-existing warnings); type-check @object-ui/plugin-gantt :: exit 0; type-check @object-ui/app-shell :: exit 0 (turbo); check:new-line-citations :: exit 0; check:changeset-claims :: exit 0; check-changeset-no-major :: exit 0; check-changeset-presence :: exit 0; check:i18n-keys :: exit 0; check:vi-mock-specifiers :: exit 0; check:vi-mock-inherit :: exit 0; check:vi-mock-override-shape :: exit 0; check:control-bytes :: exit 0; check:test-path-roots :: exit 0. check:readme-exports NOT MEASURED (needs all dists). objectui has no dispatch-gates.mjs; list hand-derived from package.json. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no",
      "mcp_calls": "2 — mcp__github__issue_read (get, get_comments); no write tool",
      "api_writes": "3 — relay pr_create objectstack-ai/objectui (#13490, assignee os-elon-musk), relay pr_request_reviewers #13490, relay comment on #13459 (this report)",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: (a) candidate, not filed · reach: NOT MEASURED through a public door · evidence: packages/plugin-timeline/src/ObjectTimeline.tsx runs TimelineExtensionSchema.safeParse(schema) in an effect and only console.warns on failure, the same warn-and-draw shape this card removed from the gantt · dedupe words: TimelineExtensionSchema safeParse warn refusal",
        "carrier: none · noted in PR Acceptance notes"
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    ACCEPT → PR #13490 comment 6392708594 · domain:ui#4 · 2026-10-25T03:14Z. Metadata-protocol is narrowed, so the PR carries needs:contract-review and lands only after the director's contract-review record.

  7. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    Landed · domain:ui#4 · 2026-10-25T04:19Z

    PR #13490 merged at 2026-10-25T04:17Z, merge commit 320ec359e4b9eabcfb21022b77da2242e2e4b529, after the director's contract review PASS on the same head. The card closed completed through Fixes; pm:dispatched comes off in this stroke. objectui merges publish nothing (the changesets release is a human act).


    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

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2sduiServer-Driven UI runtime

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions