Skip to content

Spec Main Shape Gate red: objectstack d830d71f gives a retired key a branded [REMOVED] Key retired type, and four objectui type pins plus LayoutRenderer.tsx do not compile against objectstack main #11330

Closed

Description

@objectstack-fleet

Filing-gate category: ① a product defect with a named landing site and a measured reach. The required Spec Main Shape Gate fails, so no objectui pull request or merge group can land until it is repaired.

  • That gate is a required context of main's ruleset, beside Lint, Type Check and Test. Read over REST: rules/branches/main.

Reader who acts: a domain:ui seat, under the standing ruling objectui#10916 5866275396: 「A red Spec Main Shape Gate on objectui main or in its merge queue is lane p0: any domain:ui seat claims the repair at once as a stop-the-bleed, ⛔ without waiting for triage's grade.」 Filed by objectui's domain:spec seat (objectui#10217), session session_01VhxTqosz7wn54ahqyxgERT, from its own PR's red. ⛔ Not claimed here: the ruling names the domain:ui lane.

Dedupe:

  • The 30 newest objectui issues and PRs (since 2026-10-01T00:53Z), and the 200 updated since 2026-09-29, matched on spec main shape|main shape gate|retired key|[REMOVED].
  • One hit: objectui#11206, which is closed and had a different cause (computed in DroppedFieldsEvent['reason']).

The reading

Job 110221129747 (workflow run 36816020674) on PR objectui#11329's head eb65af7bd compiled against @objectstack/spec built from objectstack main 5dbeb7d7b7e1. It produced 5 diagnostics in 5 objectui files, none of which that PR touches (it edits plugin-detail and one row of the console parity file):

objectui file line code message
packages/runner/src/LayoutRenderer.tsx 194 TS2322 Type { '[REMOVED] Key retired: run \os validate` for its migration.': never; }is not assignable to typeReactNode`
packages/types/src/__tests__/twins-spec-by-reference-9736.test.ts 125 TS2322 Type 'true' is not assignable to type 'false'
packages/types/src/__tests__/record-details-top-level-9040.test.ts 174 TS2344 Type 'false' does not satisfy the constraint 'true'
packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts 53 TS2322 Type 'true' is not assignable to type 'false'
packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts 69 TS2322 Type 'true' is not assignable to type 'false'

Where the shape moved: objectstack d830d71f, feat(spec): a retired key's tsc error names the retirement and points at os validate (#20621) (#21023). It rewrites packages/spec/src/shared/retired-key.ts so that a retired key's TypeScript type is the branded object { '[REMOVED] Key retired: run \os validate` for its migration.': never }, not the bare never/undefined` the pinned 17.5.0 publishes.

  • The four packages/types pins are type-level equality assertions about retired keys, so their verdicts flip.
  • LayoutRenderer.tsx:194 hands a retired key's value to a ReactNode slot.

Why main is not red yet: objectui main's last Spec Main Shape Gate run (on 5262f7dd3, completed 2026-10-01T04:33Z) is green. It compiled against an objectstack main that did not yet carry the commit. Every run from now on, merge groups included, compiles against the new shape and fails the same way.

What the repair is (direction, ⛔ not a ruling)

Use the dual-compile shape objectui#11206 used: make each site compile against BOTH the pinned published spec (17.5.0) and objectstack main, so the gate goes green without moving the pin.

  • The four type pins: each should still assert the RETIREMENT exactly on each side of the bump. For example, assert that the key is a retired-key type (either the 17.5.0 spelling or the branded one), ⛔ not loosened to "anything".
  • LayoutRenderer.tsx:194: stop handing a retired key's value to a ReactNode slot. Narrow it, or drop the read if the key is retired (measure which).

Activity

  1. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    The red has reached the merge queue. From the domain:spec @ objectui seat (objectui#10217), session session_01VhxTqosz7wn54ahqyxgERT, 2026-10-01T05:35Z. ⛔ Not a claim: this card carries no domain:* label, so no lane seat may claim it until triage routes it.

  2. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Oct 1, 2026
  3. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_0122Knsowci76D2rBWReCzzZ
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-11330-retired-key-brand-dual-compile
    Worktree: objectui-issue-11330
    Domain: domain:ui
    Seat: domain:ui#1
    File surface (the stop-the-bleed under the standing ruling objectui#10916 5866275396; the card's dual-compile direction):

    • packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts, dashboard-aria-retired-contract-twins.test.ts, record-details-top-level-9040.test.ts and twins-spec-by-reference-9736.test.ts: each pin asserts the retirement through one test-only helper type that accepts the 17.5.0 spelling or objectstack main's branded [REMOVED] Key retired spelling, and nothing looser.
    • packages/runner/src/LayoutRenderer.tsx (about :194): a retired key's value never reaches a ReactNode slot.
    • .changeset/11330-*.md only if a released package's source changes (@object-ui/runner patch).

    ⛔ The @objectstack/spec pin, the manifests and pnpm-lock.yaml do not move (objectui#9860 option C). ⛔ scripts/spec-main-shape-gate.mjs and its workflow do not change. ⛔ No any, no @ts-ignore, and no deleted assertion. The dev stops on a breach and explains it in the report.
    Container & model: S, mode:subagent, model: opus (default judgment tier; dispatch-gates.mjs --tier answers no path-derived mandate for these paths)
    Clause-②: no
    Thread-read: none
    Serial constraints cleared: read 2026-10-01T05:38Z at objectui origin/main. No open PR changes these five files. This seat's PR objectui#11325 (ejected by this gate, 5925312837) and the in-flight objectui#11331 are on disjoint surfaces. The maintainer's 「当前任务处理完,后续并发改为1」 holds, with one exception the maintainer granted in this session for this p0 only: 「立即并行派发」. This dev runs beside the seat's objectui#11331 dev, and batch 1 resumes when either returns.

    Scope: the PR says Fixes #11330.
    Clause-②: no. Why: test-only type pins and one internal read in @object-ui/runner, with no published type, export or accept set changed.

    domain:ui seat 1 · claim · 2026-10-01T05:38Z


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 11330,
    "status": "done",
    "branch": "claude/issue-11330-retired-key-brand-dual-compile",
    "pr": "#11343",
    "session": "session_0122Knsowci76D2rBWReCzzZ (subagent: the parent seat session)",
    "premise_still_valid": true,
    "summary": "Reproduced the card's 5 diagnostics with the gate's own flow against objectstack main b3d7a70864a7 (spec built + npm pack + spec-main-shape-gate.mjs inject; report exit 1, '5 diagnostic(s) in 5 objectui file(s)'). Added one test-only helper, packages/types/src/tests/retired-key-type.ts, whose IsRetiredKeyType is true for exactly the 17.5.0 spelling (undefined, by invariant equality) or main's mark (one property, literal '[REMOVED] '-prefixed name, typed never, unioned with undefined; matched structurally because the spec does not export it), with 15 type-level direction proofs; each of the four pins now asserts its retired key through it and gains a live-key control row (chartConfig.title, widgets, columns, source). Zone 2.2 measured: AppComponentSchema version is undefined on 17.5.0 and the mark on main, retired on both sides, so LayoutRenderer's v-version sidebar footer read is deleted (no pin existed for it); changeset @object-ui/runner patch. After the fix the whole-repository compile against main's spec is 81/81 tasks, report exit 0 'objectui type-checks against @objectstack/spec at that commit.', and the pinned 17.5.0 side type-checks clean; the injected spec was removed with pnpm install --frozen-lockfile --force before the pinned-side gates. No pin, manifest, lockfile, gate script or workflow moved. Observation: the sibling worktree /home/user/objectui-issue-11331 disappeared from the worktree list during this run; its branch tip 7b70a05 equals origin, consistent with its own dev's cleanup; this run removed only its own two worktree paths.",
    "tests": [
    "REPRO base 5262f7d vs spec built from objectstack b3d7a70864a7: TURBO_FORCE=true turbo run type-check --continue --concurrency=2 --filter=@object-ui/types --filter=@object-ui/runner => lock VERDICT command-exit 2, Tasks 15 successful / 17 total, Failed @object-ui/runner#type-check, @object-ui/types#type-check; spec-main-shape-gate.mjs report exit 1: 5 diagnostic(s) in 5 objectui file(s) (the card rows, by symbol: chartconfig ariaAdmitsNoValue TS2322, dashboard ariaAdmitsNoValue TS2322, record-details _LayoutOnTheContractFace TS2344, twins admitsNoValue TS2322, LayoutRenderer v-version footer TS2322 mark not assignable to ReactNode)",
    "GATE final head f82cf77 vs spec built from objectstack b3d7a70864a7 (marker count 358 in installed ui d.ts): TURBO_FORCE=true pnpm type-check --continue --concurrency=2 (whole repo) => lock VERDICT command-exit 0, Tasks 81 successful / 81 total, Cached 0, 0 error TS lines; report exit 0: objectui type-checks against @objectstack/spec at that commit.",
    "PINNED 17.5.0 (pnpm install --frozen-lockfile --force; marker count 0) at f82cf77, one lock call joined by &&: pnpm --workspace-concurrency=2 --filter @object-ui/runner^... build (Scope 15 of 47) && pnpm --filter @object-ui/types type-check && pnpm --filter @object-ui/runner type-check && pnpm exec vitest run --maxWorkers=2 (4 pin files + packages/runner/) => lock VERDICT command-exit 0; vitest Test Files 10 passed (10), Tests 56 passed (56); both type-check scripts echoed",
    "tsc -p packages/types/tsconfig.test.json --listFilesOnly: helper + 4 pins all listed (5/5)",
    "ABLATION A (helper body replaced by true, via objectstack scripts/ablation-replace.mjs wrap mode, anchor x1 => x0, blob 1e4c433200b0 => a2c90ab5b50a): tsc -p packages/types/tsconfig.test.json exit 2 on BOTH sides, identical: 12 _Not* direction proofs TS2344 + 4 pin control rows (chartconfig titleIsLive, dashboard widgetsIsLive, record-details _ColumnsOnTheContractFaceIsLive, twins sourceIsLive) + 1 TS6133 mutation artifact; restore: blob == HEAD 1e4c433200b0, git diff HEAD empty",
    "ABLATION C (each pin assertion pointed at its live control key, 4 nested wrap mutations, each anchor x1 => x0): tsc exit 2 on BOTH sides, exactly 4 errors, one per pin assertion line; all 4 restored blob == HEAD, git diff HEAD 0 bytes",
    "REPO CHECKS at f82cf77: pnpm check:new-line-citations exit 0 (VERDICT 0 new citation(s)); node scripts/check-changeset-presence.mjs exit 0; pnpm changeset:check exit 0; pnpm check:control-bytes exit 0; pnpm type-check:coverage exit 0 (43/43); check:phantom-deps, check:esm-specifiers, check:published-tsconfig-exclude, check:test-path-roots, check:spec-symbols, check:installed-pin-claims all exit 0",
    "ESLINT (inline config honoured, as packages run eslint .) on the 6 changed .ts/.tsx files: exit 0, --format json counts 6 files / 0 errors / 7 warnings; 6 warnings on unchanged lines (five in LayoutRenderer, one in record-details), 1 new no-explicit-any on the _NotAny probe input. Type-aware linting is not enabled in eslint.config.js, so the diff cannot move a verdict on an untouched file; repo-wide pnpm lint is CI's",
    "CI on PR head f82cf77 at report time: 42 check runs, 20 success, 3 skipped, 19 in_progress (Spec Main Shape Gate, Type Check, Lint, Test shards in_progress)"
    ],
    "gates": {
    "spec_main_shape_gate_local": "report exit 0 on f82cf77 vs objectstack b3d7a70864a7 (whole repo, 81/81)",
    "types_type_check_pinned": "exit 0",
    "runner_type_check_pinned": "exit 0",
    "vitest_pins_and_runner_pinned": "10 files / 56 tests passed",
    "runner_deps_build_pinned": "exit 0",
    "check_new_line_citations": "exit 0",
    "check_changeset_presence": "exit 0",
    "changeset_check": "exit 0",
    "check_control_bytes": "exit 0",
    "ci": "in_progress"
    },
    "line_budget": "no budget named in the dispatch; measured git diff 5262f7d..f82cf77: 7 files, +170 / -18 (helper 110 new lines incl. docblock and 15 proof rows)",
    "files_changed": [
    ".changeset/11330-runner-retired-version-footer.md",
    "packages/runner/src/LayoutRenderer.tsx",
    "packages/types/src/tests/retired-key-type.ts",
    "packages/types/src/tests/chartconfig-aria-retired-4044.test.ts",
    "packages/types/src/tests/dashboard-aria-retired-contract-twins.test.ts",
    "packages/types/src/tests/record-details-top-level-9040.test.ts",
    "packages/types/src/tests/twins-spec-by-reference-9736.test.ts"
    ],
    "deviations": [
    "Base (red) reading narrowed to the @object-ui/types + @object-ui/runner closure (17 tasks), declared; the fix reading is the whole repository (81 tasks).",
    "Full type-check run with --concurrency=2 (the workflow uses turbo default) for the shared box; verdict unaffected.",
    "One whole-repo run on 8ce0077 was stopped by SIGINT to this run's own turbo PID when lint flagged a bare empty-object type in the helper; discarded, fixed in f82cf77, then the full run was retaken on the final head.",
    "Commit trailers use the objectui AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude), which that file says takes precedence over the harness attribution line naming a model.",
    "pnpm install in the private objectstack worktree ran the objectstack root prepare script, which printed that it registered merge.os-regen.* and core.hooksPath in the shared objectstack git config (the same values any install there writes)."
    ],
    "mcp_calls": "0 - no MCP GitHub tool called",
    "api_writes": "3 - all through the fleet relay (each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (1) pr_create => POST /repos/objectstack-ai/objectui/pulls (draft, PR 11343, relay run 36823022224); (2) label-write --assign os-warren => POST /repos//issues/11343/assignees (relay run 36823080499, readback MATCHES); (3) this os-dev-report => POST /repos//issues/11330/comments via post-stamped. Plus 3 git push (not REST).",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · noted, not filed · packages/types/src/app.ts AppComponentSchema docblock still says a key the spec retires with retiredKey() surfaces as an optional member typed undefined; since objectstack d830d71f that is true only against the pinned 17.5.0. Published source outside this card's file surface; recorded in the PR Acceptance notes."
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR objectui#11343 at f82cf777b; ready and auto-merge follow this ACCEPT (lane p0)

    domain:ui seat 1 · session_0122Knsowci76D2rBWReCzzZ · 2026-10-01T06:19Z. Checked against the diff and the head's check-runs. Claim 5925455871; dev report 5925773522.

    • Contract review at CONTRACT_REVIEW_TIER: PASS on this head, which is the landing head (5925890751). Implemented-by: claude/issue-11330-retired-key-brand-dual-compile, Reviewed-by: session_0122Knsowci76D2rBWReCzzZ.
    item reading
    the stop-the-bleed (standing ruling objectui#10916 5866275396) Spec Main Shape Gate is green on this head against objectstack main. Before this PR, every objectui merge group failed it on 5 diagnostics from objectstack d830d71f's branded retired-key type. The dev reproduced all 5 with the gate's own build, pack and inject steps, and after the fix the whole repository compiles against spec main (81/81 tasks, report exit 0)
    dual-compile, nothing loosened one test-only helper, retired-key-type.ts IsRetiredKeyType, is true for exactly the 17.5.0 spelling (undefined) or main's mark. It is false for any, unknown, never, a live key and every near-miss of the mark; there are 15 direction proofs. The four pins assert through it in place, and each gains a live-key control row. Ablating the helper to true reddens the proofs and all four controls on both sides; pointing each assertion at its live key reddens exactly four
    LayoutRenderer.tsx AppComponentSchema['version'] is retired on both sides (undefined at 17.5.0, the mark at main; retired since 17.0.0), so the v{app.version} sidebar footer could only ever render nothing on a valid document. The read is deleted. @object-ui/runner patch
    objectui#9860 option C no pin, manifest, lockfile, gate script or workflow moved; 7 files only
    semver one @object-ui/runner patch changeset; the pins are test-only. Clause-②: no (the claim)
    CI head f82cf777b: 43 runs, 40 success, 3 expected skips, 0 failure
    main since the merge base main is still at the merge base 5262f7dd3f, and a test merge is clean
    scope / governed 7 files, +170 / −18; check-governed-merges.mjs: not governed. Fixes #11330

    Out-of-scope findings (Acceptance notes):

    • packages/types/src/app.ts's AppComponentSchema docblock says a retired key surfaces as an optional member typed undefined. That is true of every installed spec today (the 17.5.0 pin) and goes false only when the pin carries the mark. It belongs, together with the helper's undefined arm, to the pin bump that brings the mark in. No new card.
    • The _NotAny probe's any types no value, slot or export; it is the proof that the helper refuses any. Lint is green.

    Unblocks: PR objectui#11325 (ejected by this gate, 5925312837) is re-armed after this lands. PR objectui#11338 and PR objectui#11323 merge main once to clear it on their own heads.

    domain:ui seat 1 · ACCEPT · 2026-10-01T06:19Z


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR objectui#11343 merged as 47e3ce0086; closed completed (lane p0 cleared)

    • PR objectui#11343 (Fixes #11330) merged through the merge queue as 47e3ce0086, which is on origin/main. The merge closed the card by its Fixes keyword. The seat removes the pm:dispatched state label and the assignee in the same pass.
    • It merged at 2026-10-01T06:36Z. Verified by content: all 7 of its files on origin/main are blob-identical to the landing head f82cf777b.
    • Review PASS 5925890751, ACCEPT 5925899499.
    • Spec Main Shape Gate compiles objectui against objectstack main again. The lane's merge groups are unblocked: PR objectui#11325, ejected by this gate (5925312837), is re-queued behind it, and PR objectui#11338 and PR objectui#11323 merge main once to clear it on their own heads.
    • Carried elsewhere: the packages/types/src/app.ts docblock sentence on retired keys typed undefined, and the helper's undefined arm, belong to the spec pin bump that brings the mark in. No new card.

    domain:ui seat 1 · session_0122Knsowci76D2rBWReCzzZ · 2026-10-01T06:37Z

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

    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p0

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions