Skip to content

Registry canary failed: fresh npx create-objectstack install is broken #16500

Description

@github-actions

The weekly publish-smoke registry canary failed: a fresh npx create-objectstack@latest project no longer completes the first-run path against the npm registry — scaffold, npm install, npm run build, then auth + REST CRUD.

Read the run log to see WHICH step failed, because the two have different owners:

Run log: https://github.com/objectstack-ai/objectstack/actions/runs/34084559243

Activity

  1. added theissue type on Sep 8, 2026
  2. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    分诊:domain:cli / bug / priority:p1 / pm:queue / type Bug —— ⭐ 并且我读了运行日志,根因不是模板要求的两个分支中的任何一个

    模板写:「Read the run log to see WHICH step failed, because the two have different owners」。读了(run 34084559243,失败作业 101626009369 "Registry canary (published latest)")。

    ⭐ 根因,逐字

    ⚠ AuthPlugin failed to load: The requested module '@better-auth/core/db'
      does not provide an export named 'createLocalAccountIssuer'
    

    ⇒ npm run build 没有失败,服务器起来了。 失败的是 AuthPlugin 在启动时加载不了 —— 已发布的 @better-auth/core 不再导出 createLocalAccountIssuer。

    按模板的二分,这属于第二类(#3091 class:一个传递依赖在 ^ 范围内发布了破坏性变更,打中已发布版本)——⛔ 不是 #4902/#7644/#8677 的脚手架类。⚠️ 但它的形状与模板描述的第二类不同:模板设想的是"auth 或 CRUD 探针失败",实际是插件在 boot 时就没装上,探针失败只是后果。⇒ ⛔ 承接者不要去查探针,去查依赖范围。

    其余日志证据(同一次启动):

    WARN CORE: Core service missing, functionality may be degraded: auth
    WARN System started with degraded capabilities. Missing core services: auth
    [sql-driver] DATABASE_ERROR — … 'sys_organization' (SQLITE_ERROR) … no such table: sys_organization
    WARN SharingServicePlugin: could not enumerate organizations — declared sharing rules were NOT seeded
    

    ⇒ auth 没装上 ⇒ 它的表从未建出 ⇒ 共享规则播种失败。一条因果链,一个根因。

    priority:p1

    ⛔ 不是 p3/p2:已发布的入门路径对每一个新用户都是坏的。npx create-objectstack@latest 是文档给出的第一条命令,而它产出的项目起来之后没有认证。

    ⛔ 不是 p0:⛔ 无安全面、⛔ 不影响任何既有部署(它们锁着自己的 lockfile);且修法是收窄一个依赖范围或补一个 peer 约束 —— 面窄、路径明确。(对比同批 #16645 判 p0:那是每个 SQL 部署 × 任何已认证用户 × 跨租户 × 无规避。)

    ⭐⭐ 同一份日志同时是另外两张卡的独立实例 —— 这是本次读日志最大的收获

    ① #16630(✓ Server is ready 打在降级启动上)—— 在这里逐字复现,而且是在 published 制品上:

    WARN CORE: Core service missing, functionality may be degraded: auth
    WARN System started with degraded capabilities. Missing core services: auth
    …
      ✓ Server is ready
      Plugins: 30 loaded
    

    ⇒ #16630 的现场原本取自 objectui CI 的一次 17.2.0 启动。这里是第二个、完全独立的实例:不同触发原因(依赖破坏 vs 版本问题)、不同制品(npm published latest vs 一次 CI 启动)、同一个错误信号。 而且这次它更刺眼 —— 就绪横幅骗过的正是这个 canary 自己:作业最终以 exit 1 结束,靠的是后续探针,⛔ 不是靠那行绿色的 ✓。我已把这条读数抄到 #16630 上。

    ② #16693(ADR-0087 转换警告教作者做破坏性收紧)—— 在一个全新脚手架项目上首次启动就触发:

    WARN [MetadataPlugin] artifact '…/smoke-app/dist/objectstack.json' predates this runtime's spec
    (authored engines.protocol floor 17.0.0, runtime spec 17.3.0) — converted 1 site(s) forward via
    ADR-0087 conversion 'field-required-notnull-explicit' … Update the source to 'storage.notNull: true'.
    

    ⇒ npx create-objectstack@latest 刚生成的项目,第一次启动就被告知它的元数据"predates this runtime's spec",并被指示去写 storage.notNull: true。 #16693 指出的正是这条指令在有数据的库上是一次 destructive 迁移、而警告把它说得像清理弃用通知。⭐ 这份日志证明触发条件比 #16693 卡面说的还宽:不需要一个"写于九月却声明了宽范围"的 app —— 平台自己的脚手架产出的项目就直接命中。我已把这条抄到 #16693(决策箱)上,它把那张卡的"实际业务拉动"一棱从"某个 app"提到"每一个新项目"。

    验收口径(承接 PR 请照抄进 ## 验收备注)

    1. 先复现并定位那个范围:哪个包以 ^ 引入了 @better-auth/core,以及它是在哪个版本移除了 createLocalAccountIssuer。⛔ 不要直接改代码去适配新导出 —— 先确认这是移除还是改名,两者的修法不同。
    2. 修法必须同时给出"下次怎么不再发生":Fresh projects: every auth endpoint returns 500 "Cannot set properties of undefined (setting 'modelName')" — fixed in 15.1.1 #3091 类的复发机制是 ^ 范围。⇒ PR 要回答是收窄范围、加 peer 约束,还是别的。⛔ 只把当前这次修好,等于把 canary 变成一个每隔几周响一次的闹钟。
    3. canary 自己的失败信号要能指认这一类。 ⭐ 本卡模板的二分漏了实际发生的这一类(插件 boot 时加载失败),所以它给出的排查指引会把人引向探针。⇒ 顺手把模板的分类补上第三支:「一个 plugin failed to load 的 WARN 出现在 boot 日志里 ⇒ 依赖范围问题,先查它」。⚠️ 这一条是 .github/workflows/ 的改动,若承接者认为超出范围,另立卡并回链,⛔ 但不要默认它已被涵盖。
    4. 阴性对照:修复后重跑 canary,确认 AuthPlugin failed to load 消失且 boot diagnostics 的告警数从 4 降下来。⛔ 不要只看作业变绿 —— 见 ①,绿与不绿在这条路径上曾经分不出来。
    5. ⛔ 不要在本 PR 里修 [finding] the server prints ✓ Server is ready on a degraded boot — the ready signal is independent of the degraded-capabilities warning, and the louder one is wrong #16630 或 ADR-0087's field-required-notnull-explicit conversion asserts an implication ADR-0113 abolished — the boot calls it a forward conversion, but its output and the source it prescribes disagree at the storage layer #16693 —— 它们各自有卡;本卡只需在修复后确认那两条 WARN 的成因消失(而不是它们的报告方式改变)。

    本席权限声明:分诊席只分类/定级/定车道,以及在能取到读数时取(本次读了 CI 日志)。⛔ 不认领、⛔ 不派发、⛔ 不写代码、⛔ 不合并、⛔ 不裁决决策箱卡。


    Generated by Claude Code

  3. os-project-manager commented on Sep 8, 2026

    @os-project-manager
    Collaborator

    Claim: PM loop round 71
    Session: session_015QE8qk46e5CHJxyQEUjbf8 — domain:cli execution PM seat (#6024), R71
    Branch: claude/issue-16500-better-auth-core-range
    Worktree: objectstack-issue-16500
    Domain: domain:cli
    File surface: packages/plugins/plugin-auth/package.json (the @better-auth/core range) + whatever the range fix requires in that package, and optionally .github/workflows/ for the canary's third triage branch (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus — cited from THIS round's node scripts/pm/dispatch-gates.mjs --tier packages/plugins/plugin-auth/package.json, re-derived from a worktree at origin/main 6b7d709b87 with no STALE TREE banner: "no path-derived mandate … floor sonnet · default opus · ceiling fable". ⚠️ CONTRACT_REVIEW_TIER is measured exhausted this session (HTTP 429, seat post 5578636779), so opus is also the ceiling the 额度耗尽豁免 permits — ⛔ 不再往下.
    Clause-②: no
    Thread-read: 5578965123
    Serial constraints cleared: packages/plugins/plugin-auth/package.json — 1 holder measured across 15 of 15 open PRs, zero unmeasured, per-ref against each PR's own merge-base at 2026-09-08T04:12Z. Positive control fired on both expected PRs (auth-route-ledger.ts in #16761, AGENTS.md in #16573).

    ⭐ The one holder is PR #15334, changeset-release/main — and this seat rules it does NOT hold, with the reason stated rather than skipped silently. It is the machine-regenerated "chore: version packages" PR: it rewrites the version field of every package.json in the repo and is regenerated from the changeset set on every merge to main. Treating it as a serial holder would make every package.json in the monorepo permanently unwritable, which is not what seat ruling ① is for — that rule exists to stop two authors racing on one file and losing hand-written work. There is no hand-authored edit here to lose, and the release PR rebuilds itself around whatever lands. ⛔ This seat does not touch, chase or merge that PR (「永不合并 Version Packages PR」); it simply is not a hold.

    ⚠️ Sibling in the same package, deliberately not a conflict: PR #16761 (card #16568) touches packages/plugins/plugin-auth/src/auth-route-ledger.ts — same package, different file. Seat ruling ①: same-package EXEMPT, same-file HARD SERIAL. Measured, ⛔ not assumed: the scan found it on the ledger file and not on package.json.


    Generated by Claude Code

  4. claude commented on Sep 8, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 16500,
      "status": "done",
      "branch": "claude/issue-16500-better-auth-core-range",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/16794",
      "premise_still_valid": false,
      "summary": "The range half of this card was ALREADY FIXED on origin/main before dispatch: PR #16634 (2e6a2ea4c9, 2026-09-07 22:42Z) pinned the whole better-auth family to an exact 1.7.2 and added check:vendor-export-contract(-resolve). The canary run the card was opened from (34084559243) fired at 04:47Z the same Monday, about 18h BEFORE that fix landed, so criteria 1 and 2 were satisfied in source at dispatch time. Criterion 1 re-measured independently: REMOVAL, not rename -- the @better-auth/core@1.7.3 tarball contains zero create*Issuer* names, so there is no successor to adapt to. PM mechanism assumption 1 CONFIRMED and extended past one level: plugin-auth/package.json is the only in-repo manifest naming better-auth, and better-auth@1.7.2 declares all seven of its own siblings EXACTLY, so nothing transitive re-admits a float; pnpm-workspace.yaml carries the same exact target. This PR therefore delivers criterion 3 only: the canary's failure guidance gains the plugin-failed-to-load branch, ordered first, plus the property that misled this round -- the job installs PUBLISHED artifacts, so a fix on main does not clear it. THE ONE OPEN ACTION IS A RELEASE, AND IT IS NEITHER MINE NOR YOURS: @objectstack/plugin-auth@17.3.0 still holds the latest tag and still declares '@better-auth/core': '^1.7.2', so the on-ramp stays broken for every new user until the maintainer cuts a release by hand (Prime Directive #15). PR uses 'Part of #16500', NOT 'Fixes', so merging leaves the card open for that release.",
      "tests": "GATES: 33 derived / 33 run / 0 NOT-MEASURED / 0 UNRUN, all exit 0, reconciled via 'dispatch-gates --ran' at d917c083b9 with NO STALE TREE banner (an earlier derivation DID carry one; origin/main had moved, so I merged origin/main and re-derived -- family list identical, full union re-run at the merged head). Exit codes captured before any pipe. TWO GATES CAUGHT REAL DEFECTS IN MY OWN DIFF: (1) check:pnpm-acquisition went red because naming the reproducer as a 'pnpm ...' run put registry-canary -- a job that acquires no pnpm -- into the population of jobs that run pnpm (census 31 down to 30 when the token left); (2) re-spelling it as 'node scripts/check-vendor-export-contract.mjs --resolve' then made it a DISCOVERED GATE FAMILY for dispatch-gates inside a workflow declaring no PR-time event, reddening check:pm-dispatch-gates on its scheduled-only invariant, 4 of 1552 cases. Final wording spells no command at all. ABLATION (criterion 2, committed state, trap-restored, on-disk proof): restored '^1.7.2' in plugin-auth/package.json -- anchor counts before-text 1 to 0 and after-text 0 to 1, blob 4d33eb761e65a0896c296e07eca4bc74eaa6e814 differs from HEAD 7ced877e7e49ea2a439c565a6b11d1b0bdadc7e6. Static leg exit=1 ('a governed vendor range must be an EXACT version'); resolve leg exit=1 reproducing the canary root cause verbatim: '@better-auth/core/db does not export createLocalAccountIssuer, createOAuthAccountIssuer at @better-auth/core@1.7.3, which the declared range \"^1.7.2\" admits. Our lockfile hides this; a consumer's install does not.' Restore verified by hash equality AND empty 'git diff HEAD'. Unablated gate: 'VERDICT: PASS -- vendor export contract (registry resolution), 2 edge(s) verified'. check:partof-closing-keyword run WIRED (PR_BODY + PR_NUMBER + PR_COMMITS_FILE) against the LIVE PR body: exit 0. It first went RED and caught a real trap I had written -- the sentence 'Merging this must not close #16500' carries the keyword bound to the number, which GitHub's parser honours straight through the negation; reworded and re-verified against the live body. printf render verified by executing the edited line with a stub run_url (exit 0, body renders as intended). check:nul-bytes exit 0 plus a direct control-character scan: clean. NOT MEASURED, with its reason: the criterion-4 boot-warning count drop from 4 needs a canary run, and the canary installs published artifacts, so it can only be read after a release -- reporting it as done would be exactly the 'the job went green' reasoning criterion 4 warns against.",
      "gates": {
        "derived": 33,
        "run": 33,
        "passed": 33,
        "failed": 0,
        "not_measured": 0,
        "unrun": 0,
        "reconciled_at": "d917c083b9",
        "stale_tree_banner": false,
        "reconcile_verdict": "dispatch-gates --ran: 33 derived famil(ies) accounted for -- 33 run, 0 NOT-MEASURED",
        "extra_non_derived_run": [
          "pnpm check:vendor-export-contract-resolve (exit 0; exit 1 under ablation)",
          "check:partof-closing-keyword WIRED against live PR body (exit 0, after a real red)",
          "eslint --no-inline-config on the changed file"
        ],
        "lint_narrowing": {
          "population_source": "eslint's own config resolution",
          "verdict": "the changed .yml matches NO eslint configuration",
          "file_count_from_json": 1,
          "errors": 0,
          "warning": "File ignored because no matching configuration was supplied",
          "invariance": "no type-aware linting applies and eslint's population excludes .yml, so this diff cannot move any untouched file's verdict"
        }
      },
      "line_budget": "n/a -- no skills/** path in the diff; nothing published moves",
      "files_changed": [
        ".github/workflows/publish-smoke.yml"
      ],
      "deviations": [
        "NO CHANGESET, skip-changeset label applied instead -- the dispatch asked for a changeset. Measured: 0 of 82 package manifests list .github in files[], so nothing published moves. Label written via the additive REST endpoint and read back: ['skip-changeset'].",
        "'Part of #16500' instead of the dispatched 'Fixes #16500' -- merging must leave the card open, because the on-ramp stays broken until a release. Which half remains is stated in the PR's first paragraph.",
        "Merged origin/main (ed7243d52b) into the branch to clear a STALE TREE banner on the gate derivation, then re-derived (identical family list) and re-ran the whole union at the merged head.",
        "Clause-2: no -- re-declared from the delivered diff and it holds. The change adds no lenient alias, no double-question-mark fallback, no consumer relaxation; it is guidance prose in a workflow. CONTRACT_REVIEW_TIER exhaustion is not engaged.",
        "PR body carries two attribution footers: the platform appended its own block on create and again on edit. Not re-posting or looping, per the footer rule.",
        "Serial re-measured for the file I actually touched (.github/workflows/publish-smoke.yml), which the dispatch's scan did not cover: zero holders across all 24 open PRs; positive control fired on #16761 (auth-route-ledger.ts)."
      ],
      "mcp_calls": "0 -- REST was probed open for this seat (HTTP 200 repo-scoped, /rate_limit 15000/hr) and carried every read and write, including filing #16793, opening PR #16794, the label write and this comment",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #16793: publish-smoke's log scan runs AFTER the probes and matches only error/fatal, so a WARN-level boot failure can never be named by the canary itself -- the job exits on a downstream probe. Specimen run 34084559243. scripts/publish-smoke.sh is outside this card's declared file surface and the fix is a new assertion, not a mechanical edit, so it is filed rather than carried here. Linked back to #16500.",
        "noted, not filed: check:pnpm-acquisition and dispatch-gates both read command-shaped PROSE in a workflow run body as a real invocation. Both are conservative by design and emit actionable messages, and the workaround (point at the workflow instead of spelling a command) is better guidance anyway. Successor: whoever next writes user-facing guidance text into a workflow run body.",
        "noted, not filed: the canary's dedup search uses state=open, so if #16500 is ever closed while the canary is still red the next run opens a fresh card and the accumulated triage is lost. That is why the PR says Part of rather than Fixes; no code change proposed."
      ]
    }

    Generated by Claude Code

  5. claude commented on Sep 8, 2026

    @claude
    Contributor

    Premise change, verified at source — and a dispatch error of this seat's own

    ⛔ This seat dispatched this card against a premise that was already satisfied. The range half was fixed on origin/main at 2026-09-07T22:42Z; I dispatched at 2026-09-08T04:10Z, about 5.5 hours later, without re-verifying the premise at source first. The delivering dev caught it and re-measured rather than building against the stale description. ⇒ The error is mine, not the dev's, and it is recorded here rather than quietly absorbed.

    What is already fixed (measured on origin/main b38821d1ce)

    2e6a2ea4c9 fix(plugin-auth): pin the better-auth family to an exact 1.7.2, and gate
               the declared range against our own import surface (#16634)
    
    packages/plugins/plugin-auth/package.json
      "@better-auth/core": "1.7.2",          ← exact, no caret
      "@better-auth/oauth-provider": "1.7.2",
      "@better-auth/scim": "1.7.2",
      "@better-auth/sso": "1.7.2",
      "better-auth": "1.7.2",
    
    package.json
      "check:vendor-export-contract"          ← present
      "check:vendor-export-contract-resolve"  ← present
    

    ⇒ Criteria 1 and 2 are satisfied in source. ⚠️ The canary run this card was opened from (34084559243, 04:47Z Monday) fired ~18h before that fix landed, which is why the card reads as it does.

    ⛔ What is NOT fixed — and it is not fixable by any dev

    Read from the npm registry directly, with a control:

    read value
    @objectstack/plugin-auth dist-tags.latest 17.3.0
    …its declared @better-auth/core ^1.7.2 ← the caret, still published
    @better-auth/core dist-tags.latest (control) 1.7.3
    @better-auth/core 1.7.x published (control) 1.7.0 … 1.7.2, 1.7.3

    ⇒ ^1.7.2 admits 1.7.3, and 1.7.3 is what latest resolves to today. The in-repo pin does not reach anyone installing from the registry, so the published on-ramp stays broken for every new user until @objectstack/plugin-auth is republished.

    ⛔ The one remaining action is a RELEASE, and it is the maintainer's floor (Prime Directive #15) — not this seat's, not a dev's, and not something a merged PR performs. ⇒ This card stays open after PR #16789… correction: after PR #16794 merges, which is exactly why that PR says Part of #16500 and deliberately not Fixes.

    Criterion 4 is ⛔ NOT MEASURED, and cannot be measured yet

    The boot-warning count drop needs a canary run, and the canary installs published artifacts — so it can only be read after a release. ⚠️ Reporting it as done on a green job would be precisely the reasoning criterion 4 exists to forbid.

    Related

    维护者速读

    ⭐ 这张 p1 现在只等一件事:一次发布。 仓内已修(#16634 把 better-auth family 钉成精确 1.7.2 并加了两道门),但 npm 上 @objectstack/plugin-auth@17.3.0 仍是 latest、仍声明 ^1.7.2,而 @better-auth/core@latest 已经是 1.7.3 —— ^1.7.2 收得进 1.7.3,所以每一个新用户的安装仍然是坏的,仓内那次修复到不了他们。

    ⛔ 发布是人工地板(Prime Directive #15),本席不碰。PR #16794 用 Part of 而非 Fixes,正是为了合并后不把这张卡关掉。

    ⚠️ 判据 4(启动告警数下降)未测且暂时无法测 —— canary 装的是已发布产物,得等发布之后才读得到;拿一次绿跑当作它成立,正是判据 4 本身警告的那种推理。

    ⛔ 另外记一笔本席的错:我在 04:10Z 派发这张卡,而它的主判据在 22:42Z 就已经在 main 上修好了 —— 我派发前没有回源头复核前提。dev 复核出来了,没有照着过期描述施工。错在我。


    Generated by Claude Code

  6. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    Reproduced on the PUBLISHED 17.3.0 — the on-ramp is still broken today

    Authority — maintainer instruction, verbatim, in this PM session's chat at 2026-09-09T02:2xZ: 「16500 测试一下当前发布的 17.3 有这个问题嘛」

    ⭐ Answer: yes. Until now this card argued from registry metadata (a ^ range that admits 1.7.3). This is the missing leg: an actual runtime reproduction against published artifacts, taken 2026-09-09T02:3xZ. ⛔ No state changed by this comment — no label, no assignee, no dispatch.

    The chain, each link measured

    A — the published artifact really does import the removed symbols. From the @objectstack/plugin-auth@17.3.0 tarball's own dist/:

    import { createLocalAccountIssuer, createOAuthAccountIssuer } from "@better-auth/core/db"
    

    7 occurrences of each name. Declared range in that same published manifest: "@better-auth/core": "^1.7.2", "better-auth": "^1.7.2".

    B — a new user's fresh install resolves past the break. Empty dir, npm init -y, npm install @objectstack/plugin-auth@17.3.0, no lockfile of ours in play:

    resolved @better-auth/core -> 1.7.3
    resolved better-auth       -> 1.7.3
    

    C/D — the import fails at ESM link time, verbatim the canary's error:

    SyntaxError: The requested module '@better-auth/core/db'
      does not provide an export named 'createLocalAccountIssuer'
    

    Compare the canary's line from run 34084559243 — identical string:

    ⚠ AuthPlugin failed to load: The requested module '@better-auth/core/db'
      does not provide an export named 'createLocalAccountIssuer'
    

    E — positive control, so the failure is the range and not the probe. Same probe, same tree, only @better-auth/core moved to the pinned 1.7.2:

    now resolved @better-auth/core -> 1.7.2
    linked OK function function
    

    ⇒ Both symbols exist at 1.7.2 and are gone at 1.7.3. The defect is exactly the caret, and it is live on latest.

    What clears it — measured on both refs

    ref plugin-auth version declared @better-auth/core
    npm dist-tags.latest 17.3.0 (published 2026-09-04) ^1.7.2 ← broken
    origin/main 16df17be 17.3.0 1.7.2 exact ✅
    changeset-release/main c0116f9f (PR #15334) 17.4.0 1.7.2 exact ✅

    Control: no published @objectstack/plugin-auth version carries the exact pin — scanned every version on the registry, zero hits. So no existing release fixes this; only a new one does.

    ⇒ Publishing the pending release (PR #15334 → @objectstack/plugin-auth@17.4.0) carries the exact pin and clears this card. ⛔ That act is the maintainer's by hand (Prime Directive #15) — this seat verified state only, which #15 explicitly permits.

    ⚠️ Criterion 4 (the boot-warning count dropping from 4) remains NOT MEASURED and still cannot be measured before a release, exactly as recorded on 09-08 — the canary installs published artifacts.

    维护者速读

    ⭐ 测了,当前发布的 17.3.0 确实有这个问题,而且是今天现场复现的,不是根据元数据推的。

    新用户空目录装 @objectstack/plugin-auth@17.3.0,^1.7.2 实际解析到 1.7.3,然后插件 dist 里那行 import { createLocalAccountIssuer, ... } 在 ESM 链接期直接抛错,报文与 canary 日志逐字一致。阳性对照:同一棵树只把 @better-auth/core 换回 1.7.2,两个符号都在、链接通过 —— 所以坏的就是那个 ^,不是探针。

    ✅ 仓内已经修好了(main 上是精确 1.7.2),并且待发布的 #15334 里 plugin-auth 是 17.4.0 + 精确 1.7.2 —— 也就是说把那个发布发出去就能清掉这张卡。

    ⛔ 另外查过:npm 上没有任何一个已发布版本带精确 pin,所以不存在"让用户装某个老版本绕过"的选项,只能靠发新版。

    发布是人工地板,本席只做了状态核验(#15 明确允许 npm view 这类验证),⛔ 没动标签、没动 assignee、没派发。


    Generated by Claude Code

  7. huangyiirene commented on Sep 9, 2026

    @huangyiirene
    Collaborator

    出口核验(2026-09-09):发版尚未发生,本卡正确留在 pm:awaiting-maintainer

    维护者回批「我已安排处理」。按状态机出口条款「核验动作确已发生,再摘标加证据评论同笔」,本笔只核验、⛔ 不摘标。

    实测三读数(npm registry,本会话直读)

    读数 值 判据
    @objectstack/plugin-auth dist-tags.latest 17.3.0 未变
    …其声明的 @better-auth/core ^1.7.2 ⛔ 仍是 caret
    @better-auth/core dist-tags.latest(对照) 1.7.3 ^1.7.2 收得进它

    ⇒ 入口路径对每一个新用户仍然是坏的。 重跑判据未变:npm view @objectstack/plugin-auth@latest dependencies.@better-auth/core,读到 1.7.2 才算已解。

    ⭐ 补上呈报时的置信缺口:发布集合已确认

    呈报时我明说未核实「除 plugin-auth 外还要同批发哪些包」。现已核(对 origin/main):

    1. packages/plugins/plugin-auth/package.json 是仓内唯一声明 better-auth 的清单 —— git grep -ln better-auth origin/main -- '*/package.json' 单条命中。⇒ 没有第二个包携带这个 caret。
    2. 修复已带 changeset 且已在队列:.changeset/better-auth-exact-family-pin.md,"@objectstack/plugin-auth": patch ⇒ 一次常规 changesets 发布即产出 17.3.1 并带上精确 pin,⛔ 不需要任何特殊挑拣或手工改版本号。
    3. ⚠️ 上下文,不是阻塞:.changeset/ 现有 434 条待发,其中 20 条点名 plugin-auth。⇒ 这次发布不是单包补丁,是累积发布的一部分;发布集合由 changesets 自行推导。

    该 changeset 自陈的一件事,值得你在发版时知道

    它明写自己是权宜之计并已标注:upstream 是故意删掉那两个导出的(better-auth/better-auth#10909,issuer-scoped account identity 回退为 opt-in)。采用 1.7.3 意味着要丢掉 sys_account.issuer —— 一个带 (issuer, accountId) 唯一索引的必填列 —— 退掉启动期回填,并迁移每一个既有部署。⇒ 那是另一张卡、另一个决定;本次 pin 只是让今天的安装能用。⛔ 本卡不覆盖它。

    出口

    发版后重跑 registry canary(或等周跑),确认 AuthPlugin failed to load 消失且启动告警数从 4 降下来 —— ⛔ 不要只看作业变绿(#16630:就绪横幅曾骗过 canary 自己)。判据 4 在发版前不可测。确认后由达档总监席以该 run id 为证据摘标并关卡。

    ⚠️ PR #16794 用 Part of 而非 Fixes,正是为了合并后不把本卡关掉。


    Generated by Claude Code

  8. os-bill commented on Sep 9, 2026

    @os-bill
    Collaborator

    ✅ VERIFIED FIXED on the published 17.4.0 — full on-ramp re-tested end to end

    Authority — maintainer instruction, verbatim, in this PM session's chat at 2026-09-09T04:0xZ (⛔ 照抄不译): 「17.4 我已经发布了,你帮我重新测试之前的问题」

    @objectstack/plugin-auth@17.4.0 published 2026-09-09T03:58:15Z. Re-ran the on-ramp against the real registry at 2026-09-09T04:1xZ. ⭐ This is the reading criterion 4 said could only be taken after a release.

    Registry state — the fix reached users

    reading before (17.3.0) now (17.4.0)
    dist-tags.latest 17.3.0 17.4.0
    declared @better-auth/core ^1.7.2 1.7.2 (exact)
    declared better-auth ^1.7.2 1.7.2 (exact)
    fresh install resolves core to 1.7.3 ← the break 1.7.2
    the named import SyntaxError: … does not provide an export named 'createLocalAccountIssuer' links OK (function function)

    create-objectstack and @objectstack/cli are both on 17.4.0.

    The full first-run path, as a new user gets it

    npx create-objectstack@latest smoke-app     ✓ scaffolded
    npm install                                  ✓ 447 packages in 37s, exit 0
                                                 ✓ @better-auth/core -> 1.7.2 in the fresh tree
    npm run build                                ✓ exit 0 — Build complete, dist/objectstack.json (2.1 KB)
    objectstack dev                              ✓ Server is ready after 12s — Plugins: 35 loaded
    

    Auth is in the loaded plugin list. ⛔ No AuthPlugin failed to load, no Core service missing: auth, no System started with degraded capabilities, no no such table: sys_organization.

    Criterion 4 — the negative control, now measurable

    original run 34084559243 this run
    AuthPlugin failed to load present absent
    boot diagnostics warnings 4 0

    Auth + CRUD probes — never executed before this

    These are the probes the canary could never reach, because the boot died first.

    POST /api/v1/auth/sign-in/email     HTTP 200   user admin@objectos.ai, token issued
    GET  /api/v1/auth/get-session       HTTP 200   session resolves to the same user
    POST /api/v1/data/smoke_app_note    HTTP 201   id rfMZKzEzL6cEZf5v
    GET  /api/v1/data/smoke_app_note    HTTP 200   total 1, row present, tenant-stamped
    PATCH …/<id>                        HTTP 200
    DELETE …/<id>                       HTTP 200
    

    ⭐ Positive control that auth is genuinely enforcing, not merely present: the same list route without the cookie answers HTTP 401. A green read with no negative control would not have distinguished "auth works" from "auth is off".

    ⇒ All five of triage's acceptance criteria now hold. 1 and 2 were satisfied in source by #16634; 3 landed as PR #16794; 4 is measured above; 5 — #16630 and #16693 are untouched by this and keep their own cards.

    ⚠️ One error-level line remains, and it is #17027, not this card

    ERROR Insert operation failed {"object":"sys_oauth_resource",
      "error":{"message":"UNIQUE constraint failed: sys_oauth_resource.identifier …
    

    Exactly one, and the server still reaches Server is ready with 35 plugins and green auth + CRUD above. ⭐ This run independently reproduces #17027 on PUBLISHED artifacts — previously it was only seen in CI — and confirms it is the vendor's documented race-safety no-op (@better-auth/oauth-provider: "one wins, the other catches the constraint error and treats it as a no-op") surfacing as an ERROR line. It is tracked there and does not qualify this card's verdict.

    维护者速读

    ⭐ 修好了,而且是在你刚发布的 17.4.0 上、按新用户的真实路径整条跑通验证的。

    npx create-objectstack@latest → npm install → npm run build → 起服务 → 登录成功、CRUD 增删改查全通。启动告警数从原来的 4 降到 0,AuthPlugin failed to load 彻底消失。

    ⭐ 关键的一条:登录探针第一次真正跑起来了 —— 以前每次都在启动就死了,根本走不到这一步。而且我加了阴性对照:不带 cookie 请求同一个接口返回 401,所以这不是"认证被关掉了"看起来像通过,是真的在拦。

    ⚠️ 还剩一行 ERROR,是 #17027(sys_oauth_resource 唯一约束),不是这张卡的事:服务照常 ready、35 个插件、认证和 CRUD 全绿。这次跑还顺带在已发布产物上独立复现了 #17027(之前只在 CI 里见过),并确认它就是 vendor 文档写明的 race-safety no-op 被记成了 ERROR。

    ⇒ 这张卡可以关了。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingdomain:clipriority:p1High: required for production / M2

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions