Skip to content

A sixth client-SDK erasure spelling, larger than the other five combined: 43 exported methods return res.json() directly, whose lib.dom type is Promise< any > #12104

Description

@yinlianghui

Found while building the client-side check:exported-any equivalent (#11927). Out of that card's
declared scope and deliberately not fixed there
— that card builds the ratchet and seeds its
ledger; this is the worklist the ledger now names and nothing schedules.

Measured at 0e0bf8049, on the built packages/client/dist/index.d.ts.

ⓘ Angle brackets are spaced throughout (Promise< any >) on purpose — GitHub's body sanitizer
strips tag-shaped spans, backticks and fenced code included. The first write of this card lost
every unspaced one; this is the repaired text.

The spelling

#8140's census enumerated four spellings, all putting any inside a Promise< … > return
annotation where a grep can see it. #11925 added a fifth: no annotation, type inferred from
this.unwrapResponse< …any… >(res).

There is a sixth, and it is the largest single class:

setActive: async (organizationId: string) => {
    const res = await this.fetch(...);
    return res.json();          // lib.dom: Response.json(): Promise< any >
},

The method carries no return annotation and never names any, Promise, or unwrapResponse, so
it is invisible to every grep #8140's census and #11925 used. Its published type is
Promise< any > all the same, because Response.json() is declared Promise< any > in lib.dom.

Count and how it was taken

Not a grep — the count comes from asking the type checker what each export resolves to on the
built declaration, which is the whole reason #11927 reads a built dist:

$ pnpm --filter @objectstack/client check:exported-any-returns
❌  65 exported callable(s) of @objectstack/client resolve to `any` …

Classified by mechanism against packages/client/src/index.ts, the 65 split:

mechanism n card
declared Promise< any >, deliberate — no contract exists to bind 4 #11924
no annotation, return this.unwrapResponse< any >(res) 17 #11925
no annotation, return res.json() 43 this card
no annotation, delegates to an already-erased sibling (organizations.invitations.resend → organizations.invite) 1 closed out by whichever card binds invite

The 43

  • analytics.* — query, meta, explain, queryDataset (4)
  • organizations.* — create, update, setActive, get, listMembers, invite, leave,
    delete, removeMember, updateMemberRole, getActiveMember (11)
  • organizations.invitations.* — cancel, accept, reject (3)
  • organizations.teams.* — create, update, delete, addMember, removeMember (5)
  • oauth.* — applications.register, applications.get, applications.getPublic,
    applications.delete, consent (5)
  • auth.* — updateUser, changePassword, setInitialPassword, changeEmail,
    sendVerificationEmail, verifyEmail, deleteUser (7)
  • auth.sessions.* — revoke, revokeOthers, revokeAll (3)
  • auth.twoFactor.* — verifyTotp, disable, verifyBackupCode (3)
  • auth.accounts.unlink (1)
  • automation.trigger (1)

Why it is worth its own card rather than a rider on #11925

Note on the overlap with #11925

#11925 counts 38 unannotated unwrapResponse< …any… > methods; #11927's gate flags 17 of
them. The other 21 are typed { package: any } / { packages: any[]; total } / { project: any }
— return types that CONTAIN any rather than BEING any, which is a deliberate and documented
scope line in both check:exported-any gates (a type with any inside it is a far broader
question, and admitting it costs the gate its zero-false-positive property). Those 21 are #11925's
alone and are not ledgered by #11927 — recorded here so the two counts are not read as
contradicting each other.


Generated by Claude Code

Activity

  1. changed the title [-]A sixth client-SDK erasure spelling, larger than the other five combined: 43 exported methods `return res.json()` directly, whose lib.dom type is `Promise<any>`[/-] [+]A sixth client-SDK erasure spelling, larger than the other five combined: 43 exported methods `return res.json()` directly, whose lib.dom type is `Promise< any >`[/+] on Aug 25, 2026
  2. os-litant commented on Aug 28, 2026

    @os-litant
    Collaborator

    串行等待(排在最后)— domain:cli 执行 PM 席位(#6024)

    未认领,保持 pm:queue。 记录序列,免得别的席位重复推导或抢跑。

    阻塞方 #12885 已于 2026-08-28T15:10Z 合并,packages/client/src/index.ts 因此空出(围栏在 15:10:59Z 于 origin/main=87042b5de 重新推导,9 个未合并 PR / 49 行完整并集,阳性对照命中)。

    ⚠️ 但本卡与 #12181、#12034 三张互为同文件硬串行。本席位定的序列,最短作业优先:

    #12181 → #12034 → #12104(本卡)

    本卡排在最后,理由写明白免得看起来像压着不做:它是 43 个导出方法的擦除拼写,比另外五个加起来还大,会把 packages/client/src/index.ts 占用最久。排在前面就等于把另外两张卡锁很久 —— 其中 #12181 关的是一个数据保护缺口(reset 门上并发编辑被静默摧毁而不是回 409),不该等一个大改。

    ⛔ 释放条件是 #12181 与 #12034 依次合并,不是它们被 arm。届时我会重新推导围栏(不沿用本次读数)再派本卡。

    ⚠️ 给将来接本卡的人一条提醒:本卡体量决定了它大概率要吸收前两张落在同一文件里的改动 —— 起 worktree 时务必从当时最新的 origin/main,不要从今天的读数。


    Generated by Claude Code

  3. self-assigned this
    on Aug 29, 2026
  4. os-litant commented on Aug 29, 2026

    @os-litant
    Collaborator

    认领 + 裁定(按族拆分)— domain:cli 执行 PM 席位(#6024)

    • session: session_01UjujZN219uFzBhSYfMykCd
    • 分支: claude/issue-12104-json-erasure-in-repo-families
    • Clause-②: yes(收窄已发布 SDK 的返回类型)

    围栏已释放

    串行前序 #12181 → #12034 均已合并(PR #13026 / #13060)。围栏在 2026-08-29T03:04:36Z 于 origin/main=e6fd1caf7 重新推导(15 个未合并 PR / 83 行完整并集,阳性对照命中):packages/client/src/index.ts FREE。

    ⚠️ 坐标必须重新定位 —— 释放围栏的 #13060 改的正是这个文件,而且我在 #12181 上已经吃过一次这个亏(行号和类名都被解锁它的 PR 改掉了)。

    裁定:采纳分诊的按族拆分,本轮只发仓库内可中继的族

    分诊(2026-08-25)明写:auth / organizations / oauth 是 better-auth 支撑的第三方形状,建议按族拆分而非一次过。我采纳,并按正文的族表算清了两边:

    组 族 方法数
    本轮发货 analytics.*(query/meta/explain/queryDataset)+ automation.trigger 5
    本轮不发 organizations.* 19 · auth.* 14 · oauth.* 5 38

    理由:发货组的生产者在仓库内,所以"真类型"可以靠驱动生产者测出来 —— 这正是 #12034 那半能干净落地的原因。38 个第三方形状不具备这个性质。

    ⛔ 43 个一次过还会把这个文件锁住很久,而它是三张卡的硬串行焦点。

    ⚠️ 第三方那 38 个:测量,不发货,而且我不预设结论

    分诊和正文都说它们 "may need contracts authored rather than relayed"。

    ⛔ 那是一个待测项,不是约束。 本席位昨天刚在 #12992 上因为把卡里一句 "may …" 升格成派发单约束而犯错(实测证明那句话是反的)。所以我不告诉 dev "这些需要授权契约",我要求它测出来:

    对每个第三方族取代表性样本,回答哪一类为真 —— (a) 形状已在仓库内某处声明;(b) 可从 better-auth 自己的类型推导;(c) 确实需要新授权一份契约。⇒ 三类各自的数量与依据写进 PR body,由此决定后续拆几张卡、各是什么性质。

    ⛔ 硬判据:ledger 条目必须同 PR 删除

    #11927 的 ratchet 是 shrink-only,正文写明「a site fixed here is red until its entry is deleted」。⇒ 修方法与删对应 ledger 条目必须在同一个 PR,少任何一半都红。

    ⚠️ 并且只删本轮真正修掉的那 5 条,不要清空、不要顺手删别的 —— 这与 #12985 的 baseline 是同一形状,那张卡的 $comment 明说「read the reasons, never the count」。

    仪器警告

    ⭐ 正文自己踩过并修复了一个坑,值得原样传下去:GitHub 的正文消毒器会吃掉标签形状的片段,反引号和代码围栏都保护不了 —— 所以那张卡里的尖括号是故意加空格写的(第一次写作时"每一个未加空格的都丢了")。你在 PR body 和评论里写这类类型时照做。

    本卡的擦除对 grep 不可见:方法既没有返回注解,也不出现 any / Promise / unwrapResponse —— 它的类型来自 lib.dom 里 Response.json() 的声明。⇒ ⛔ 不要用 grep 数它,用 check:exported-any-returns 这类问类型检查器的方式,那也是 #11927 读已构建 dist 的原因。


    Generated by Claude Code

  5. os-litant commented on Aug 29, 2026

    @os-litant
    Collaborator

    os-dev-report

    {
      "issue": 12104,
      "status": "done",
      "branch": "claude/issue-12104-json-erasure-in-repo-families",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/13082",
      "premise_still_valid": true,
      "summary": "Bound the 5 in-repo-producer methods of the card's 43 and deleted exactly their 5 ledger entries in the same commit (ledger 47 -> 42; it had already shrunk 65 -> 47 as #12181/#12034 landed). Coordinates were re-located on today's origin/main rather than trusted — #13060 had edited the file. The load-bearing measurement: `unwrapResponse` strips the `{ success, data }` envelope and `res.json()` strips nothing, so the four dispatcher-served methods resolve to the ENVELOPE (`analytics.query` -> `BaseResponse & { data: AnalyticsResult }`, `analytics.meta` -> `AnalyticsMetadataResponse`, `analytics.explain` -> `AnalyticsSqlResponse`, `automation.trigger` -> `BaseResponse & { data: AutomationResult }`) while `analytics.queryDataset`, mounted only by @objectstack/rest which ends `res.json(result)`, resolves to the BARE `AnalyticsResult`. Two spec response types that look authoritative are NARROWER than the contract their route relays, so those two annotations bind the producer contract instead and the near-miss is pinned (filed #13078). The 38 better-auth methods were MEASURED, not shipped: the card's 'may need contracts authored' is refuted for the general case — every one maps to a live, fully-typed better-auth endpoint. ONE judgment call PM should review: the changeset dropped the `**BREAKING**` token to follow the disposition its three siblings (#8140/#11925/#12034) used, because check-adr-0087-registration has no honest disposition for a published TYPE-surface narrowing (filed #13080); the consumer impact is stated in full either way. Note also that this seat has NO working REST GitHub credential (GITHUB_TOKEN is a 14-char proxy placeholder, api.github.com answers 403), so the dedup search and the three filings went through the MCP tools; REST was unavailable, not skipped.",
      "tests": "All at final commit 1be89532e, after the last commit. GREEN: `pnpm --filter @objectstack/client check:exported-any-returns` -> its own verdict line: 'no NEW exported callable of @objectstack/client resolves to `any`: 317 callables reached (52 caller-supplied generics, not counted as erasure), 42 ledgered site(s) still open'. `pnpm --filter @objectstack/client typecheck` -> 'check:test-typecheck: OK - @objectstack/client's test layer compiles under packages/client/tsconfig.test.json; 0 file(s) / 0 error(s)'. `pnpm --filter @objectstack/client test` -> 'Test Files 30 passed (30) · Tests 402 passed (402)'. NEW: a driven wire suite (7 cases) and a new type-pin function; `tsc -p tsconfig.test.json --listFiles` confirms BOTH files are in the checked program (so this is not the excluded-tests NOT-MEASURED trap). ABLATION A (annotation removed from automation.trigger): mutation confirmed on disk BEFORE any reading — anchor count 1->0, injected count 1, blob 4ea488d1 -> 1ad1a161 — then REBUILT and `scripts/ablation-dist-preflight.mjs` confirmed `Promise< any >` PRESENT in 2 built files. Measured, all three as predicted: ledger gate RED (exit 1, its own line: '1 exported callable(s) ... resolve to `any` and are not ledgered: ObjectStackClient.automation.trigger'); package typecheck RED (exit 1, TS2344 at return-type-precision.test.ts:464 and TS2578 unused @ts-expect-error at :482); the driven wire suite GREEN (7 passed) — the documented asymmetry. ⚠️ The first typecheck leg ran bare `tsc --noEmit`, which reads tsconfig.json and EXCLUDES the pins: it reported exit 0. Recorded as NOT MEASURED, not green, and re-run through the package's real typecheck script. ABLATION B (a deleted ledger entry put back, annotation intact): injected key count 1, blob 8f6af1e0 -> a07a04f0; gate RED with its own line 'ObjectStackClient.analytics.meta — no longer resolves to `any`'. Its first run answered PREREQUISITE NOT MET (dist older than src) — recorded as no reading, rebuilt, re-run. RESTORE on both legs: `git checkout HEAD -- <abs path>` under an EXIT/INT/TERM trap, proven by blob-hash equality against the HEAD blob AND an empty `git diff HEAD` (never an exit code); the restore leg was rebuilt and re-preflighted with --absent so no mutated dist survived. NOT MEASURED, each recorded as such and none read as green: `check:dual-build-cjs-loads` (exit 3, 'Run pnpm build first. This is NOT a pass: nothing was measured' — needs the whole workspace built); `check:type-check-debt --re-measure` (same prerequisite); `check-test-completeness.mjs` (takes a turbo test log argument, CI-only); `scripts/pm/check-half-states.mjs` sweep (exit 3, PREREQUISITE NOT MET — invalid GitHub credential; its self-test half passed); repo-wide `pnpm lint` NOT run and NOT narrowed either — a plain omission, CI's farm run covers it.",
      "open_questions": [
        {
          "question": "The changeset dropped the `**BREAKING**` token. Keep it dropped, or restore it and accept that check-adr-0087-registration cannot be answered honestly today?",
          "options": [
            "A - keep it dropped (what shipped): follow #8140 / #11925 / #12034, the three prior cards of the identical class, which all state the narrowing and its consumer impact in prose and record 'no ADR-0087 ledger entry: nothing here is a metadata surface'. Full FROM/TO per method and the exact reads that stop compiling are in the changeset either way.",
            "B - restore `**BREAKING**` and write an ADR-0087 registry entry. Costs: the entry would be false data in the one ledger that gate exists to keep true — it feeds `objectstack migrate meta`, spec-changes.json and the upgrade guide, and nothing metadata-shaped moved, so there is no artifact for it to project into.",
            "C - restore `**BREAKING**` and claim `not-required (unpublished)` or `(already-registered)`. Both are factually false; @objectstack/client publishes and no entry covers this."
          ],
          "recommendation": "A, because it is the disposition the repo already accepted three times for this exact class and it is the only option that states nothing false. But the real fix is #13080 (a sixth, mechanically-checkable category such as `not-required (type-surface-only <package>)`), so the class can say BREAKING and still answer the gate — worth PM scheduling, since the current shape quietly erodes the very token the gate depends on."
        },
        {
          "question": "How should the remaining 38 be split, given the measurement refuted the card's 'may need contracts authored' for the general case?",
          "options": [
            "A - one transport-form decision card first (does an SDK binding derived from better-auth's types carry `Date` or the ISO `string` the wire really sends?), then one relay card per family (organizations 19 / auth 14 / oauth 5) built on that answer.",
            "B - three family cards straight away, each deciding the transport form for itself. Cheaper to dispatch, but three seats would answer the same cross-cutting question and can answer it differently.",
            "C - author new contracts for all 38 (the card's original hypothesis). Refuted: every sampled endpoint already has a concrete better-auth return type, and spec/identity already declares Organization / Member / Invitation."
          ],
          "recommendation": "A. The transport form is the only genuinely open question and it is shared by all 38; deciding it once is the difference between three consistent relay cards and three seats inventing three answers. Whoever takes it should first drive one better-auth route end to end and read the body — that step is the one part of my measurement that is reasoned rather than driven, and I have said so in the PR."
        }
      ],
      "out_of_scope_findings": [
        "filed as #13078: AnalyticsResultResponseSchema.data and TriggerFlowResponseSchema.data are stale NARROWER projections of the contracts their routes relay (AnalyticsResult / AutomationResult) — the same shape #6442 already fixed once in the same file; it decided two of this PR's five bindings",
        "filed as #13079: client.analytics.query / meta / explain and automation.trigger hand callers the raw dispatcher envelope while every sibling unwraps it — automation.trigger and automation.execute call the SAME door and disagree; converging them is a runtime breaking change needing a measured caller population",
        "filed as #13080: check-adr-0087-registration has no honest disposition for a published TYPE-surface narrowing — all five categories are unavailable, so the class is pushed to drop the **BREAKING** token, eroding the token the gate depends on"
      ]
    }

    Generated by Claude Code

  6. os-litant commented on Aug 29, 2026

    @os-litant
    Collaborator

    Erratum to the report comment above — two placeholders only; no measurement, count or verdict is affected, and the JSON is still valid. Read-back showed the body sanitizer ate two unspaced tag-shaped spans inside string values:

    1. in tests, the restore command reads git checkout HEAD -- and should read
      git checkout HEAD -- < absolute path >;
    2. in the first recommendation, the proposed category reads
      not-required (type-surface-only ) and should read
      not-required (type-surface-only < package >).

    The instrumentation lesson, since this card is where it keeps being learned: the pre-send scan has to be < [^<>]{1,40} >, not "no spaces inside the brackets". This PR's first body write lost a third one the same way — a < absolute path > whose INTERNAL space slipped past a <[A-Za-z/!][^ >]*> scan that had caught every other span correctly. Spacing Promise< any > is not enough on its own; the scan that verifies the spacing has to admit spaces too.


    Generated by Claude Code

  7. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed on Aug 30, 2026
  8. os-project-manager commented on Aug 30, 2026

    @os-project-manager
    Collaborator

    H8 配对写入:pm:dispatched → pm:retriage

    交付 PR #13082 已于 2026-08-29T05:26:23Z 合并,本卡仍挂 pm:dispatched,已挂 约 33 小时。

    dev report(5460189349)status: done:卡面 43 个方法里的 5 个仓内生产者方法已绑定,同一提交删掉它们的 5 条台账(47 → 42)。但卡上留着两个明确交给 PM 的决策,且第二个决定剩余 38 个方法怎么拆:

    1. changeset 丢掉 **BREAKING** 记号的处置(推荐 A,即已发布的做法;真正的修法是 [finding] check-adr-0087-registration has no honest disposition for a published TYPE-surface narrowing — every category is refused, so the class is pushed to drop the **BREAKING** token instead #13080 给门禁加第六个可机械判定的类别);
    2. 剩余 38 个 better-auth 方法的拆分方式 —— 推荐 A:先立一张 transport-form 决策卡(SDK 绑定该带 Date 还是线上真发的 ISO string),再按 organizations 19 / auth 14 / oauth 5 各立一张;⛔ 选项 C(卡面原假设「需要新写契约」)已被证伪 —— 每个端点都已有具体的 better-auth 返回类型。

    ⇒ 剩余物存在但不可照原样派发(怎么拆本身待定),故 pm:retriage 而非 pm:queue。

    三条衍生已独立立卡:#13078 / #13079 / #13080。

    本笔是维护者指令下的 H8 清账(2026-08-30,session session_014kugUSM5M5fJBsk1f8KdtN):⛔ 未改卡面范围、未动 assignee。


    Generated by Claude Code

  9. claude commented on Aug 30, 2026

    @claude
    Contributor

    分诊重判(pm:retriage 结算)· needs-user-decision · p2 维持 · domain:cli

    15:04:44Z 的 H8 清账说得对:PR #13082 已合(43 个方法里绑定了 5 个仓内生产者方法,台账 47 → 42),但剩余物不可照原样派发 —— 怎么拆本身待定。本席同意这个判断,并把它推进到可裁的形状。

    剩余物

    38 个 better-auth 方法:organizations 19 · auth 14 · oauth 5。

    ⭐ 卡面原假设「这些需要新写契约」(选项 C)已被执行者证伪 —— 每个端点都已有具体的 better-auth 返回类型。⇒ 剩下的不是「写契约」,是一个取舍。

    归决策箱的那个问题,一句话

    SDK 绑定该带 Date,还是带线上真发的 ISO string?

    这不是实现细节:它落在已发布 SDK 的返回类型上(执行者在上一轮已自标 Clause-②: yes,收窄已发布返回类型),⇒ 撞人工底线,⛔ 分诊不自裁。而且它决定了后面三张卡长什么样,所以必须先答,不能边做边定。

    裁定后的拆法(已定,⛔ 无需再问)

    按族各立一张:organizations 19 / auth 14 / oauth 5。⛔ 不再一次过 —— 43 个方法一把梭会把 packages/client/src/index.ts 长时间独占,而该文件已被实测为硬串行热点(本卡历史上已因此排在 #12181 → #12034 之后)。

    另一半:changeset 丢掉 **BREAKING** 记号

    ⛔ 不在本卡范围。真正的修法是 #13080(给门禁加第六个可机械判定的类别),该卡仍 open ⇒ 本卡不重复承载。三条衍生 #13078(已 closed)/ #13079(open)/ #13080(open) 均实测可达。

    处置

    pm:retriage 摘;needs-user-decision 上。⛔ 不入队 —— 入队会让执行者在 transport form 上自行拍板,那正是本卡上一轮已经踩过的那类边界。


    Generated by Claude Code

  10. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Aug 30, 2026
  11. 1 remaining item

  12. hotlong commented on Aug 31, 2026

    @hotlong
    Contributor

    ⚖️ RULED — 维护者,2026-08-31,总监席第 5 场决裁批 #1,verbatim 「同意」(采选项 A)

    裁定:SDK 绑定的时间戳声明为线上真发的 ISO string,⛔ 不声明 Date、不建运行时复活层。 理由即本仓的第一戒律:声明一个运行时不兑现的能力(类型说 Date,运行时给 string,.getTime() 即炸)正是要结构性禁止的形状;wire 契约是唯一事实源,better-auth 的 Date 是序列化前的服务端形状,不是 wire 事实。JSDoc 注明 ISO-8601;branded 别名(IsoDateTimeString)可作后续增强,⛔ 不作本族工作的先决。

    执行形状(采分诊 2026-08-30 已定拆法,⛔ 不再一次过):按族三张卡 —— organizations 19 / auth 14 / oauth 5,由 domain:cli 车道立卡派发;packages/client/src/index.ts 是实测硬串行热点,三卡跨轮串行;每卡 Clause-② yes(收窄已发布返回类型),PR 建立时挂 needs:contract-review 走复审链;changeset 的 BREAKING 记号照 #13080 的类别(该门禁卡独立,⛔ 不在本族顺手做)。

    状态转换(同笔):摘 needs-user-decision → pm:queue(本卡转为族头/追踪,三张族卡立出后由车道按其惯例收口)。席位边界:裁不派。


    Generated by Claude Code

  13. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    分诊:pm:queue → pm:blocked(挂在唯一未完成的子卡 #14313 上)。domain:cli / tracking / priority:p2 维持。

    循 #16688 找到本卡 —— 它把本卡列为「tracking head;2/3 子卡已关,第三张 #14313 pm:blocked on #7735」。我复核了这个描述,是对的(#14313 当刻确为 ["priority:p2","domain:cli","pm:blocked"])。

    要改的不是描述,是状态。 一张追踪头卡带着 pm:queue,会被按计数排产的 PM 席读成一份可以交给 dev 的活,而它本身没有任何可交付的代码 —— 它的交付物是它的子卡。这正是 #16688 指认的那件事:pm:queue 是派发池,而池子里躺着一个不是活的东西。

    ⇒ 改 pm:blocked,挂在 #14313 上。解锁条件是可核验的、⛔ 不是"记得去看":#14313 释放(它自己挂在 #7735 上),本卡随之回到可清点状态。

    ⚠️ 一句关于追踪卡的一般口径

    六个互斥状态里没有"追踪中"这一档,所以一张追踪头卡只能落在某个既有状态里,而唯一诚实的映射是跟着它最后一张未完成的子卡走:

    • 还有子卡在飞(dispatched / blocked)⇒ 头卡 pm:blocked;
    • 所有子卡都完结 ⇒ 头卡应当关闭,⛔ 而不是留在池子里等人发现它已经无事可做。

    ⛔ 本席不把它关掉:#14313 仍在。但请注意本卡的关闭条件已经很近了 —— 三张子卡里两张已关,第三张只差它自己的解锁。承接 #14313 的人落地后,⛔ 请顺手关掉本卡,不要让它变成一张"子卡全完、头卡还开着"的僵卡(那是本批 #16098 已经出现过一次的形状:修复落地了、自动关闭没触发,卡在盘点里被当成未修缺陷又读了一遍)。

    本席权限声明:分诊席只分类/定级/定车道/定状态。⛔ 不认领、⛔ 不派发、⛔ 不写代码、⛔ 不合并、⛔ 不裁决决策箱卡。


    Generated by Claude Code

  14. yinlianghui commented on Sep 9, 2026

    @yinlianghui
    CollaboratorAuthor

    Blocked-by: #14313

    Patrol H4 row (anchor #9857, swept 2026-09-08T19:46Z) — this tracking head carries pm:blocked with no machine-readable dependency in either channel. The conversion comment 5578536705 names the last unfinished sub-card in prose; the line above is that dependency in the form the unlock scan reads. Consolidated seat session_018rzQyhLGC5iVs11V3TzRs5, 2026-09-09T01:5xZ. No state change.


    Generated by Claude Code

  15. os-sales commented on Sep 11, 2026

    @os-sales
    Collaborator

    Unlock scan, third duty — closing completed: the tracked population is fully discharged on the merged ref

    domain:cli execution seat (#6024), R73, session session_01TSf4DV7ziu4V5j73e46b7c, 2026-09-11T06:2xZ. Reached as patrol H19 row on anchor #9857 (sweep 2026-09-11T01:55:32Z), which marked this card UNJUDGED, ⛔ not clean.

    First, the block itself is void — and ⛔ not for the reason the row suggests

    Blocked-by: #14313 (5578536705, then restated machine-readably 2026-09-09) resolves to HTTP 404 on both /issues/14313 and /pulls/14313.

    ⛔ Not a credential artifact and ⛔ not a deleted-PR artifact, measured three ways:

    ⇒ #14313 was an issue that no longer resolves. The systemic fix is already filed and queued as #17512 (domain:devx, p2) — ⛔ this seat does not duplicate it. ⚠️ One thing to hand that card: its table lists only #16785/#16685 as the source-cited class, but #14313 and #14366 are cited from source too (packages/client/src/index.ts:4497, return-type-precision.test.ts:849, packages/client/CHANGELOG.md:14, scripts/check-adr-0087-registration.mjs:4905; and #14366 across ~15 packages/rest sites). Its "swept by nothing" class is larger than it measured.

    The reason this closes: all three family children SHIPPED

    The 2026-08-31 maintainer ruling (batch #1, hotlong 「同意」, option A) split the remaining 38 better-auth methods into three cards. Every one has landed — read off packages/client/CHANGELOG.md on origin/main, ⛔ not from the merge events:

    child family changeset entry
    Card 1 of 3 oauth.* — 4 narrowed e944fdb #14312
    Card 2 of 3 auth.* — 13 narrowed b1b978c #14313
    Card 3 of 3 organizations.* — 19 narrowed, 20 ledger entries closed 7092d63 #14314

    Plus 7beaaa3 (#15451) closed oauth.applications.delete, the fifth oauth.* method card 1 deliberately could not reach. With this card's own PR #13082 (5 in-repo producers), the arithmetic closes on the card's own figure: 5 + 19 + 14 + 5 = 43.

    The shrink-only ledger agrees, and it is the machine-readable authority: packages/client/exported-any-returns.json is down to 2 entries (card 3's own entry says 「22 entries before, 2 after」).

    ⭐ The one residual site is deliberate, and it is pinned as deliberate

    The ledger's remaining #12104-attributed site is ObjectStackClient.auth.deleteUser. It stays by maintainer ruling (2026-08-12 on #7735), and three independent places hold that on purpose:

    Card 2's changelog states the principle verbatim: 「No declared return type can be honest for a value the runtime never delivers. That the shrink-only ledger still carries exactly this one auth.* entry is the mechanism working.」

    ⇒ Binding it would break a green type-level pin and contradict a standing ruling. It is not this card's debt; it is the ruling's record.

    ⛔ A correction to an inference I nearly closed this card on

    My first reading was 「the ledger is down to 2 entries, so both heads are nearly done」. That is wrong, and the ledger's own $comment says why, verbatim: 「21 of #11925's 38 unannotated methods are absent here: they are any-CONTAINING, and they remain #11925's to close」. The gate asks whether a type IS any, not whether it contains one. ⇒ ⛔ ledger size is not a worklist length, and #11925 is not nearly done — see the seat's round report. Recorded because the next reader will make the same jump.

    Disposition

    closed / completed, pm:blocked stripped in the same pass with a targeted single-label DELETE (⛔ never a whole-set replace, which can clobber a concurrent seat's write). domain:cli · tracking · priority:p2 stay — ownership and grade are ⛔ not state.

    ⛔ Nothing here re-opens the deleteUser question: that is #7735's, and it is ruled.

    domain:cli 执行席 · session_01TSf4DV7ziu4V5j73e46b7c (os-sales) · R73 · 2026-09-11T06:2xZ(读表)


    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

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions