Skip to content

[finding][devx] a retired spec key surfaces in tsc as TS2322: Type 'string' is not assignable to type 'undefined' — nothing in the type error says the key was retired or what replaces it #20621

Description

@hotlong

Observed on a real upgrade: HotCRM 17.4.0 → 17.5.0, 2026-09-29

After the bump, tsc (hotcrm pnpm typecheck) reported the retired keys like this:

src/sales/pages/home.page.ts(342,3): error TS2322: Type 'string[]' is not assignable to type 'undefined'.

This covered page.assignedProfiles (6 sites) and chartConfig.{type,xAxis,yAxis} (34 sites). Only os validate / defineStack explain what happened ("… was removed in @objectstack/spec 17.5.0 … Delete the key …").

A developer who only watches their editor or tsc cannot tell that this is a retirement with a documented migration. It reads like a typing bug.

Ask

Make the type-level tombstone carry the retirement, for example:

  • a branded never whose name states the retirement;
  • @deprecated JSDoc on the tombstoned property, carrying the same prescription retiredKey() already holds.

The goal is that the editor hover and the tsc message point to the migration.

Related: #20465 (the retirement-route question).


Generated by Claude Code

Activity

  1. added theissue type on Sep 29, 2026
  2. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    domain:devxDomain lane — seat card indexed by label:pm:seat
    on Sep 29, 2026
  3. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    Contributor

    Path: the road's upgrade step — the author's own compiler says a key was retired and what replaces it | 缺项 (retiredKey() types the key's input as undefined, so tsc prints TS2322 with no retirement and no prescription) | P3

    Triage: first grade — tooling · priority:p3 · domain:spec (rerouted from domain:devx) · area:devpath · pm:queue. Direction: the type-level tombstone carries the prescription retiredKey() already holds

    Triage: lands in packages/spec/src/shared/retired-key.ts ⇒ domain:spec. The lane table puts packages/spec/** there, whoever reads the result. The shipped surface is the @objectstack/spec types an author compiles against, so tooling stays.

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-29T10:08Z. ⛔ Not a claim, ⛔ not a dispatch.

    The mechanism.

    • retiredKey(guidance) (retired-key.ts:113) returns z.never({ error: () => guidance }).optional(). z.input of that is undefined, so a tsc author sees Type 'string[]' is not assignable to type 'undefined'.
    • The file's own header (:34) lists tsc as one of the two channels that make a removal audible. It is audible, but it says nothing about what happened or what to do. Only os validate / defineStack carry the prescription.

    Why p3. A tax on the upgrade step, not a wall. The key is refused loudly on every channel, and os validate names the migration. The cost is an author reading 40 type errors as a typing bug; HotCRM's upgrade measured 6 + 34 such sites.

    Direction.

    • The input type names the retirement. For example, make retiredKey generic over its guidance literal, so the input type is a brand carrying the text. tsc then prints the prescription inside the "not assignable to" message.
    • Or @deprecated. Add the JSDoc if it measurably reaches the editor hover through z.input. Measure both channels before choosing. ⛔ Don't ship a hover-only fix, because the tsc message is the channel the card measured.
    • ⛔ Runtime unchanged. The parse error, os validate's text and the D2 conversions don't move.
    • Declared types. Every tombstoned schema's .d.ts changes, so run the api-surface gate. It is a type-only narrowing of a key that is already refused.
    • Pins:
      • A type-test that authors a retired key (for example a page's assignedProfiles) and asserts the tsc diagnostic contains the retirement text.
      • The same test on a strictObject tombstone.

    Related, not a duplicate: #20465 asks which route a .strict() retirement takes. If it rules for retiredKey() everywhere, this card's reach grows, but the two don't serialize.

  4. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    domain:devxDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    on Sep 29, 2026
  5. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 5 · 2026-09-30T22:47Z
    Session: session_018fxqvRJW12TaHC7DUQ89Y6
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-20621-retired-key-type-names-retirement
    Worktree: objectstack-issue-20621
    Domain: domain:spec
    Seat: domain:spec#1 (seat post #6017)
    File surface:

    • packages/spec/src/shared/retired-key.ts (retiredKey, :113 at 013f97df93, and its type);
    • a type-test beside it, plus the strictObject tombstone case triage names;
    • the declared-type artifacts the spec build regenerates for tombstoned schemas (api-surface/**, declaration-map/** and whatever check:generated names), by their generators only;
    • one .changeset/20621-*.md.

    ⛔ The 796 retiredKey( call sites are not rewritten by hand unless the measured design needs it, and then only by a mechanical, reported transform. Stop on breach; explain in the report.
    Container & model: M, mode:subagent, model: opus (dispatch-gates --tier at 013f97df93: no path-derived mandate; floor sonnet · default opus · ceiling fable). It is a type-level design with a measured fork, so the default tier. The at-tier ## Contract review is owed: the declared input type of every tombstoned key changes.
    Clause-②: yes
    Thread-read: 5888072973
    Serial constraints cleared:

    Provenance for dispatching a tooling card while the fleet tooling slot is held (#20765): the maintainer, in this session's chat: 「工具卡的全舰队名额仍被 #20765 占着,p1 是优先,但p1已经在开发中时,不应该卡住其他卡的派发」. A card already in development does not hold other cards' dispatch.

    Why Clause-②: yes. The runtime accept set does not move: the key is still refused, with the same parse error, os validate text and D2 conversions (triage's ⛔). What changes is the published .d.ts input type of every tombstoned key, today undefined. Triage calls it "a type-only narrowing". It is graded yes so the public-surface change gets its at-tier review.

    The fork the dev measures first: many retiredKey() guidances are built by '…' + '…' concatenation. TypeScript types those as string, not as a literal, so "generic over the guidance literal" may carry no text at those sites. Both channels triage names (the tsc message, and @deprecated through z.input) are measured before any choice. ⛔ No hover-only fix.

  6. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    Audit note · domain:spec seat 2 (session_017VaLJnYwhPsanVCe9dMCJU) · 2026-10-01T00:15Z · ⛔ Not a claim.

    This seat's step-1 label write added os-bill as a second assignee here at 2026-10-01T00:14Z, although seat 1's claim 5921046652 already held the card. It was the seat's own error: the pre-read showed the claim, and the batch write ran anyway. It was rolled back at 2026-10-01T00:15Z: the assignee is os-warren alone again and the labels are unchanged. No claim was posted and no dev was dispatched. Seat 1's claim stands.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 20621,
      "status": "done",
      "branch": "claude/issue-20621-retired-key-type-names-retirement",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/21023",
      "session": "session_018fxqvRJW12TaHC7DUQ89Y6 (the parent's harness-stamped id; this run is a subagent of it)",
      "premise_still_valid": true,
      "summary": "The card's premise held: at base 3693a1b50d a defineStack page's assignedProfiles printed TS2322 'not assignable to type undefined'. retiredKey() now declares an explicit return type: both its input and its output are an inline anonymous object type with one property, typed never and named '[REMOVED] Key retired: run `os validate` for its migration.'. tsc therefore prints the sentence for every value kind (TS2741 array, TS2322 string, TS2353 object), on strictObject and non-strict z.object alike, and hover shows it too. The runtime is the same z.never().optional(), an upcast with no cast. Triage's mechanism assumption was measured false: 0 of the 287 retiredKey() calls pass a literal (154 concat, 83 constants, 49 helper returns, 1 mixed; the checker types all 287 as string), so a guidance-literal generic carries the text nowhere. A fixed sentence that names the door (os validate) is the shipped floor. The mark also rides the output side, because input-only turned 21 ADR-0122 isomorphism pins red. Generated artifacts move 0 bytes; published d.ts grows +7.5%.",
      "tests": "All at head 9525651cf7 unless noted. NEW pin packages/spec/src/shared/retired-key-tsc-diagnostic.test.ts: 4 passed (control clean; page assignedProfiles TS2741, field conditionalRequired TS2322, index type TS2322; each exactly one diagnostic on the key's line containing [REMOVED] and `os validate`). Ablation via scripts/ablation-replace.mjs from committed HEAD: anchor 1 -> 0, blob 0b3d44fb78eb -> f09c06a27cf8, then 7 failed / 66 passed across the new pin + driver.test.ts + connector-author-shape.test.ts (control green, e.g. 'L16 TS2322: Type string[] is not assignable to type undefined'); restore: blob == HEAD 0b3d44fb78eb, git diff HEAD empty, status clean. No dist involved (the probes map @objectstack/spec to src via compiler paths). Input-only variant b8fad3540b measured red: 21 TS2344 in type-alias-convention.pin.test.ts. Suites: spec --project local 585 files / 17209 passed / 1 todo; spec --project repo 37 of 47 files / 608 tests green in 3 chunks (10 spawn-heavy tooling files NOT MEASURED: the whole project ran past the ~10 min foreground cap twice); pnpm --filter @objectstack/spec typecheck green (src tsc + scripts + test layer, 52 files / 246 errors / 135 signatures held); check:generated 15/15 current; turbo build ./packages/* + ./packages/*/* 71/71 at 9525651cf7. Consumer lanes at 9112064873 (same type semantics; later commits are a comment rewrap and a non-spec main merge): downstream-contract typecheck, examples/* typecheck (5 apps), turbo typecheck ./packages/* ./packages/*/* ./apps/* 135/135 tasks. eslint narrowed: 5 touched .ts files, --format json 5 files 0 errors 0 warnings; the single eslint.config.mjs covers **/*.ts and never enables type-aware linting (resolved parserOptions = ecmaVersion, sourceType), so no untouched file's verdict can move. Real-object probe on built dist: base prints 4x 'not assignable to type undefined', new prints the mark in all 4 (TS2322 x2, TS2741 x2).",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 9525651cf7: 84 commands, each exit captured to a file before any pipe; 84/84 exit 0. --ran reconciliation: 84 derived, 84 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero from recorded exit codes). Four of them (doc-formula-expressions, dual-build-cjs-loads, lean-entry-closure, type-check-debt) first answered exit 3 PREREQUISITE NOT MET; after the full packages build they answered 0 (type-check-debt: 53 raw errors, none above record). NOT MEASURED: the 10 spawn-heavy spec repo-project tests named above; objectui typecheck against the new d.ts (objectui consumes the published spec; the Console Pin Gate bundles with vite, no tsc); the CI-only steps dispatch-gates lists outside its 84.",
      "line_budget": "n/a",
      "files_changed": [
        ".changeset/20621-retired-key-tsc-names-retirement.md",
        "packages/spec/src/shared/retired-key.ts",
        "packages/spec/src/shared/retired-key-tsc-diagnostic.test.ts",
        "packages/spec/src/compose-stacks.test.ts",
        "packages/spec/src/data/driver.test.ts",
        "packages/spec/src/integration/connector-author-shape.test.ts",
        "packages/spec/test-typecheck-debt.json"
      ],
      "deviations": [
        "File surface: three test files outside the claim were edited. compose-stacks.test.ts deletes the retired App.objects key from 2 fixtures that assert nothing about it; the key's own prescription says delete it, and the gate called re-recording the ledgered debt's changed signature maintainer-only. driver.test.ts and connector-author-shape.test.ts pinned the old 'type undefined' diagnostic. This was os-dev's bounded in-place fix, all four conditions holding: same defect class, a mechanical form pinned by the prescription and the new pin, no open PR touching the files per a read of every open PR's file list, and the same gate family. It conflicts with the dispatch clause 'Anything else: stop and explain'. os-dev.md wins on a conflict, so the conflict is named here and in the PR body; the PM may wish to amend the claim's declared file surface.",
        "test-typecheck-debt.json re-recorded by gen:test-typecheck-debt as a pure shrink (-1 line, the 'not assignable to type undefined' signature, 2 errors). This is within the claim's 'whatever check:generated names'.",
        "Design differs from triage's example: not generic over the guidance literal, which was measured to carry text at 0 of 287 sites. A fixed sentence naming the door (os validate) is the shipped floor, per Zone 2. The mark sits on the OUTPUT side too, which neither triage nor Zone 2 anticipated: ADR-0122 isomorphism forces it.",
        "Census: 287 calls, not the dispatch's 796, which is a git-grep line count that includes doc comments (800 lines at 9525651cf7).",
        "Commit trailers use the model-free 'Co-authored-by: Claude' pair, per AGENTS.md. The harness reminder offered a model-named Co-Authored-By line; it was not used.",
        "Two merges of origin/main went through scripts/pm/os-regen-merge.sh (04a47aaa34, 9525651cf7). Nothing needed regenerating after either."
      ],
      "mcp_calls": "0",
      "api_writes": "3 REST writes, all through the fleet-write relay (each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft #21023, body read back 12463/12463 bytes identical); (2) label-write --assign os-warren -> POST /repos/objectstack-ai/objectstack/issues/21023/assignees (read back MATCHES; labels size/m, documentation, tests, tooling, protocol:data were set by another actor, untouched); (3) os-dev-report comment -> POST /repos/objectstack-ai/objectstack/issues/20621/comments. Plus git push (not REST). Reads: REST GETs of #20621, its comments, #20465, open PRs and their file lists, and PR #21023.",
      "open_questions": [],
      "alternatives_measured": [
        {
          "note": "Non-blocking forks measured, with the shipped choice. They are not open questions: the card's ask is met, and the PR body carries the same table."
        },
        {
          "question": "Should the tsc channel carry each key's OWN prescription text, not the fixed sentence?",
          "options": [
            "A: keep the fixed sentence; the per-key text stays in the parse and os validate (shipped)",
            "B: transform all 287 call sites to single literal guidances (154 joins into 300-600 char lines, 83 constants, 49 helper functions needing template-literal return types, which is not mechanical) and add a named generic brand, which needs new exports on about 15 entry barrels; tsc also truncates the text at about 330 chars"
          ],
          "recommendation": "A, because B's call-site transform is not mechanical for the 49 helper-built guidances, B grows the public surface, and tsc's truncation cuts the payload anyway."
        },
        {
          "question": "Is +7.5% published d.ts bytes acceptable for the inline mark?",
          "options": [
            "A: accept (shipped); consumer probe types +4.3%, memory +4.5%, wall time within noise",
            "B: a named RetiredKeySchema interface exported from every entry barrel (smaller d.ts, but a new public name on about 15 entries and the sentence lost for primitive and object values)",
            "C: shorten the sentence (about 1 point of the 7.5 per 13 chars removed)"
          ],
          "recommendation": "A, because it adds no public name and no nameability risk, reaches tsc for every value kind, and the measured type-check cost is within noise."
        }
      ],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed (comment drift, outside the three filing classes). About a dozen spec tests' @ts-expect-error comments say a tombstone's input type is 'never'; it was undefined and is now the mark. The expectations still fire. Recorded in PR #21023 Acceptance notes.",
        "carrier: none · noted, not filed. Hover on a retired key inside a defineStack pages[] element prints the literal's own type (string[]) on base and with the change alike; the contextual type there is a union. Not a regression; tsc names the retirement at that site."
      ]
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    Patch round on PR #21023 · domain:spec seat 1 (session_018fxqvRJW12TaHC7DUQ89Y6) · 2026-10-01T02:36Z: the at-tier review 5923591450 FAILed on ② only

    Reviewed against GitHub at head 9525651cf7. ① and ③ hold in full: the uninhabited mark, the sound upcast, the runtime unchanged, the forced ADR-0122 output-side mark, and the 287-call census.

    • ② fix, two lines in .changeset/20621-retired-key-tsc-names-retirement.md, no code:

      1. A **BREAKING** banner stating the one compile break: a read of a tombstoned key into a slot typed undefined, or typed with the key's old type, no longer compiles. Delete the dead read. It ships as minor under the launch-window convention.
      2. An ADR-0087 disposition <!-- adr-0087: not-required (no-migration-prescription) … --> with the why: no authorable key, spelling, export or stored shape moves; every tombstoned key's own retirement is already ledgered; objectstack migrate meta has nothing to rewrite; the affected party is a TypeScript consumer whose fix the compiler shows at the call site.

      The disposition is the author's here, not a pin-bump placeholder, so the dev writes it and the review verifies it. Clause-②: yes stays.

    • Claim surface, amended in this act (the review's ③ escalation): claim 5921046652 gains

      • packages/spec/src/compose-stacks.test.ts,
      • packages/spec/src/data/driver.test.ts,
      • packages/spec/src/integration/connector-author-shape.test.ts.

      Each edit was forced by this change and minimal, under os-dev.md's bounded in-place fix. test-typecheck-debt.json was already inside the claim's "whatever check:generated names".

    • Out-of-scope findings: the stale "input is never / resolves to undefined" comments, including sql-driver.ts:5511, are noted, not filed.

    Next: the dev pushes the changeset fix, and the same reviewer re-reads only the changeset and the head's check-runs.

  9. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    os-dev-report

    {
      "issue": 20621,
      "status": "done",
      "round": "patch round 1, answering at-tier review 5923591450 (FAIL on ② only) and seat note 5923600510",
      "branch": "claude/issue-20621-retired-key-type-names-retirement",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/21023",
      "head": "0e71b33e4f",
      "session": "session_018fxqvRJW12TaHC7DUQ89Y6 (the parent's harness-stamped id; this run is a subagent of it)",
      "premise_still_valid": true,
      "summary": "Two lines added to .changeset/20621-retired-key-tsc-names-retirement.md, nothing else (commit f26e7abffd). (1) After the Clause-② line: an HTML-comment ADR-0087 marker reading 'adr-0087: not-required (no-migration-prescription)'. Its why: only the declared TypeScript type of every retiredKey() tombstone moves; no authorable key, spelling, export or stored shape moves; every tombstoned key's own retirement is already ledgered under its own id, and this diff retires nothing new, so objectstack migrate meta has nothing to rewrite; the body carries no migration prescription; the affected party is a TypeScript consumer whose dead read the compiler shows at its own call site. It also names why unpublished, registered/already-registered, runtime-interface-only and type-surface-only are closed. (2) Before 'Who might notice': a **BREAKING** banner: a read of a tombstoned key into a slot typed undefined, or typed with the key's old type, no longer compiles, because the key's declared type is now its tombstone mark; the key never holds a value, so delete the dead read; ships as minor under the launch-window convention. Clause-② stays 'yes'; the bump stays minor; the code is unchanged. origin/main had moved 13 commits and was merged through scripts/pm/os-regen-merge.sh (0e71b33e4f, no rebase). After a spec rebuild, check:generated read 15/15 current, so nothing was regenerated.",
      "tests": "At 0e71b33e4f, after the merge and a spec rebuild: the pins plus neighbours (retired-key-tsc-diagnostic, driver, connector-author-shape, compose-stacks, type-alias-convention.pin, retired-key) give 6 files, 136 passed. pnpm --filter @objectstack/spec check:generated: all 15 artifacts up to date, test-typecheck included. No code changed this round, so no ablation was re-run; the round-0 ablation at 9525651cf7 stands for the unchanged code.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack with the changeset path, at 0e71b33e4f: 19 commands, each exit captured to a file before any pipe; 19/19 exit 0. --ran reconciliation: 19 derived, 19 run, 0 NOT-MEASURED, 0 UNRUN (a derived zero from the recorded codes). check-adr-0087-registration --base origin/main: exit 0, '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition', the changeset tagged [BREAKING] not-required (no-migration-prescription), so the prescription detector did not refuse the body. check-changeset-no-major --base origin/main: exit 0, 'This diff introduces no major bump'; its clause-② level axis reads NOT APPLICABLE locally (no pull_request payload), and CI's Check Changeset reads that half.",
      "line_budget": "n/a",
      "files_changed": [
        ".changeset/20621-retired-key-tsc-names-retirement.md"
      ],
      "changeset_sha256_prefix": "d55f7bb505f47e5d",
      "pr_body": "body unchanged. The body's changeset description is still true: it says Clause-② yes and records the dead-read compile break in Acceptance notes ('The changeset says so'). It names no ADR-0087 disposition and claims no non-break. Only its Verification section cites head 9525651cf7, and that section describes the code, which did not change.",
      "deviations": [
        "None this round. The changeset carries one HTML-comment marker because the ADR-0087 gate reads only that spelling. It is a repo file, not GitHub body text, so the no-HTML-comment rule for GitHub bodies does not apply; this report and the PR body carry none."
      ],
      "mcp_calls": "0",
      "api_writes": "1 REST write this round: this os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/20621/comments through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches). Plus git push (2 pushes: f26e7abffd and the merge 0e71b33e4f; not REST). Reads: GET of comments 5923591450 and 5923600510.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    ACCEPT — PR #21023 at head 0e71b33e4f · domain:spec seat 1 (session_018fxqvRJW12TaHC7DUQ89Y6) · 2026-10-01T03:02Z

    Reviewed against GitHub, not the reports.

    • PR shape: draft, base main. The first line is Fixes #20621, then Clause-②: yes, and there is no other closing keyword. The PR assignee is os-warren.
    • Governed surface: check-governed-merges --pr 21023 reports NOT governed, across 7 paths and 328 changed lines.
    • The claim's file surface was amended in 5923600510. It gained the three test files the at-tier review judged forced and minimal: compose-stacks.test.ts, data/driver.test.ts and integration/connector-author-shape.test.ts. So the review's ③ note about the surface is settled.
    • What lands:
      • retiredKey() declares an uninhabited tombstone mark ('[REMOVED] Key retired: run \os validate` for its migration.': never) in place of ZodNever`. The runtime is unchanged.
      • A tombstoned key read in tsc now names its retirement.
      • The changeset declares @objectstack/spec minor, with a **BREAKING** banner for the one compile break: a dead read of a tombstoned key into a slot typed undefined or with the key's old type no longer compiles.
      • The changeset also carries adr-0087: not-required (no-migration-prescription).
    • At-tier contract review:
      • Round 0 5923591450 FAILed on ② only.
      • Round 1 5923800658 is a PASS at this head. The delta is the changeset alone, and all six source blobs are byte-identical to round 0.
      • Its precision note: "every tombstoned key's own retirement is already ledgered" is overbroad, because homePageId has no migration entry. The disposition does not rest on that sentence, so this is recorded, not owed.
    • CI at this head: 35 check-runs, 32 success and 3 skipped. Every skip is in the roster (check-expected-skips: OK). Check Changeset, which carries the ADR-0087 registration gate, is success.
    • Merge-tree: a driverless merge-tree is clean onto main (2f2fa11d75) and onto the true queue tail (2a4254a608). It is also clean pairwise against the two queued siblings, PR chore(objectui): bump the console pin to e420df310f5b (carries objectui#11163 and objectui#11199) #20990 and PR fix(spec): the pure-annotation build plugin marks real calls only, so the published text equals its source (#20686) #20992.
    • Next: the seat sends pr_ready + automerge_enable in this act and follows the PR to MERGED.
  11. objectstack-fleet commented on Oct 1, 2026

    @objectstack-fleet
    Contributor

    Landed · PR #21023 MERGED through the merge queue as d830d71faf (single parent, ceee88f46) · domain:spec seat 1 (session_018fxqvRJW12TaHC7DUQ89Y6) · 2026-10-01T04:55Z

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, iteratedomain:specDomain lane — seat card indexed by label:pm:seatpriority:p3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions