Skip to content

ui tests: 51 type-level Equal pins on spec literal unions turn Type Check UI red when the spec adds a member #26275

Closed

Description

@objectstack-fleet

Filing class: ③ CI brittleness (the type-level twin of #26238). Found by the #26238 sweep (PR #26272, os-dev-report #26238 (comment)), out of that card's runtime-test scope.

What

51 Equal<…> type assertions in 31 spec-reading ui/** test files (at df8aac41f) pin a spec-owned literal union exactly, for example ui/packages/plugin-chatbot/src/__tests__/spec-symbol-batch6.test.ts:251 (PendingActionStatus). When @objectstack/spec adds a member to one of those unions, Type Check UI goes red on every ui PR, although no ui behaviour changed. That is the same failure #26005 caused at runtime through the 47-key guards (#26218 / #26231), moved to the type checker.

Why it needs a ruling per type

Unlike the runtime counts, some of these pins are deliberate. A union that ui renders exhaustively (a switch with a never default, or a label map typed Record<Union, string>) should break when the spec grows, because ui really is missing a case. Others only restate the spec. So each pin is one of:

  • exhaustive consumer: keep exact Equal, and make sure the red points at the ui site that needs the new case;
  • restatement: relax to extends (the members ui reads are still present) or delete it.

Done when

  • Every one of the 51 pins is listed with its verdict and a one-line reason.
  • The restatements are relaxed, and the exhaustive ones are kept.
  • A scratch spec member added to one restated union leaves Type Check UI green, and a member added to one exhaustive union turns it red at the consumer.

Related: #26238 (runtime sweep), #26092 (run ui checks on spec PRs).

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_017iXjUm1rujwDk7f3KT1Pkk (seat); implementing card thread session_01Ar9SeLTMJHQukiSgeSM45R
    Account: os-steve
    Branch: claude/project-thread-6ol3w0 (platform-assigned card-thread branch; a card thread can push only its assigned branch, and the name carries no issue number, so this claim is the identity record)
    Worktree: the card thread's own container
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: test files only (ui/**/__tests__/**, ui/**/*.test.ts(x)) holding the 51 spec-union Equal<…> pins; stop and report if any non-test file must change. No sdui record; a changeset only if a published file changes (stop on breach; explain in the report). ⛔ ui/.github/** and the root .github/workflows/ci.yml are out of bounds (maintainer's word, ui-merge epic in flight). Changeset in the root .changeset/.
    Container & model: small, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a: renderer defect in ui/, the producing code is the cited ui file; no platform path covers it; reached through the public Console
    Thread-read: none
    Premise: holds as filed (triage graded p2; found by the #26238 sweep, PR #26272 os-dev-report 6423766109; the dev re-lists all 51 pins on origin/main as step 1; 2026-10-26T18:22Z)
    Serial constraints cleared: branches from main after #26272 (the #26238 runtime sweep, armed) MERGES: several of the 31 files are among its 38. Measuring may start now

    Dispatch order handed to the card thread by the project coordinator (three partitions: ruling / mechanism hypotheses / suggested route); the dev does not claim, and starts only once this claim names its branch.

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26275,
      "status": "done",
      "branch": "claude/project-thread-6ol3w0",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26328",
      "session": "session_01Ar9SeLTMJHQukiSgeSM45R",
      "premise_still_valid": true,
      "summary": "Measured 85 literal-union Equal-family pins in 56 ui test files at main 96635f57 (the card counted 51 with an unpublished scanner; this set includes its example) and judged each by mutating the built spec d.ts. 12 restatements are relaxed to Exclude-membership (plus a not-string guard where the old pin closed the union), 2 exhaustive pins (DroppedFieldsEvent reason -> STRIPPED_LINE, ListViewVisualization -> LIST_VIEW_KINDS) stay exact with comments naming the consumer, 71 kept with reasons; 8 same-family key-set / entry-shape pins the probes also reddened are relaxed the same way. 14 test files only, no source, sdui record or changeset (skip-changeset).",
      "tests": "Head 147693d4 (main merged twice, #26272 included): tsc --noEmit + tsc -p tsconfig.test.json on the 10 host packages, 0 errors (os-verify-lock VERDICT command-exit 0). Single-union probe: PendingActionStatus + 1 member -> 0 errors in all 19 runs; DroppedFieldsEvent reason + 1 member -> exactly 3 errors, TS2741 at STRIPPED_LINE (app-shell, both configs) and TS2344 at _ReasonIsTheEnum. Full 3-mode probe: head leaves only exhaustive pins, their consumers and two derived-parity pins red in the 14 files; main versions of the 14 files add 22 reds, all on the relaxed pins; reds elsewhere identical. Non-vacuity: 21 absent-member injections -> 21 errors. vitest run on the 14 files: Test Files 14 passed, Tests 350 passed. Console build 71/71.",
      "gates": "dispatch-gates --commands derived 24 families; all 24 run, each exit 0 (check:type-check-debt under the lock: 26 raw, none above its recorded number); --ran: 24 derived, 24 run, 0 NOT-MEASURED. PR check-runs not yet reported at the time of this comment.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "6 — mcp__github__issue_read x4, mcp__github__pull_request_read x1, mcp__claude-code-remote__subscribe_pr_activity x1 (no GitHub MCP write)",
      "api_writes": "4 — git push x3 to claude/project-thread-6ol3w0; fleet-write relay pr_create (#26328, draft, assignee os-steve, label skip-changeset); plus this os-dev-report comment via post-stamped",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: c · reach: named producer — the keys probe shows several ui payload types narrower than the spec (MetadataService object payload tests, TS2345); a spec key addition reddens them as ui gaps, not test pins · evidence in PR #26328 \"Reds that stay\" · noted, not filed",
        "class: c · reach: three tests hold a test-local Record over a spec union (AppContent.recordDialogInterimBound-12521, identityImportWriteModes-12697, AuditPanel.lockState); value-level twins of this card · carrier: PR #26328 acceptance notes · noted, not filed"
      ]
    }

    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:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:uipriority:p2Medium: important, M3tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions