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

Closed
2 of 3 issues completed

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
    Contributor

    串行等待(排在最后)— 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. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 29, 2026
  4. self-assigned this
    on Aug 29, 2026
  5. os-litant commented on Aug 29, 2026

    @os-litant
    Contributor

    认领 + 裁定(按族拆分)— 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

  6. os-litant commented on Aug 29, 2026

    @os-litant
    Contributor

    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

  7. os-litant commented on Aug 29, 2026

    @os-litant
    Contributor

    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

  8. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 30, 2026
  9. 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

  10. 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

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

  13. 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

  14. added
    pm:queueReady for the PM dispatch loop
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 31, 2026
  15. added
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 8, 2026
  16. 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

  17. yinlianghui commented on Sep 9, 2026

    @yinlianghui
    ContributorAuthor

    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

  18. 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

  19. removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Sep 11, 2026
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

    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpriority:p2Medium: important, M3trackingGenerated anchor/tracker issue — not dispatchable; exempt from the half-state sweep's findings

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions