Skip to content

Commit 17458f5

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-25053-oauth-application-type-options
2 parents 2d158a9 + 4feccc2 commit 17458f5

20 files changed

Lines changed: 1261 additions & 67 deletions
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@objectstack/platform-objects': patch
3+
---
4+
5+
fix(platform-objects): the Create User result dialog no longer tells an admin who typed the password to copy a temporary one
6+
7+
Clause-②: no (text only: the create-user result dialog's sentence and button; no param, response, status, outcome or export moves)
8+
9+
`sys_user.create_user`'s result dialog said "Copy the temporary password now — it is shown only once and never stored." with an "I have saved this password" button, in both outcomes. The endpoint returns `temporaryPassword` only when it generated one, so after a typed password the dialog showed the email alone and asked the admin to save a password it never showed. The dialog now reads "If a temporary password was generated, copy it now — it is shown only once and never stored." with a "Done" button — the same sentence and button as `set_user_password`, true for a typed and for a generated password. The zh-CN, ja-JP and es-ES bundles carry the same change, reusing `set_user_password`'s existing translations.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
'@objectstack/driver-sql': minor
3+
'@objectstack/service-datasource': minor
4+
---
5+
6+
fix(driver-sql): a SQLite database whose header SQLite cannot read fails `connect()` at once, naming the file, and a dangling symbolic link as the database's directory is refused on the boot that writes, as the read-only boot already refused it (#25019)
7+
8+
Three more SQLite files a declared datasource cannot use, each now classified by the file's own driver at connect:
9+
10+
- **A database whose header or schema SQLite cannot read** (a file truncated inside its 100-byte header, or short of the pages its schema names). The connection's first statement, `PRAGMA auto_vacuum`, answers `SQLITE_CORRUPT`; `SqlDriver.connect()` logged it as "Failed to set PRAGMA auto_vacuum=INCREMENTAL" and resolved over a file no statement could read. On a development boot, `resolveSqliteDriver` (`@objectstack/service-datasource`) then stepped down to wasm SQLite, whose open renamed the file to `<file>.corrupt-<timestamp>` and wrote an empty database in its place, under a warning that blamed the native addon. `connect()` now refuses it with a `SqliteDatabaseFileError` (`code: 'SQLITE_CORRUPT'`, `filename`, a message naming the file) in every mode, before anything is written, and `resolveSqliteDriver` re-throws it instead of stepping down. A database damaged deeper inside still connects: its first statement answers, and the damage surfaces on the read that reaches it, as before.
11+
- **A dangling symbolic link as the database's directory, on the boot that writes.** `connect()` took `mkdir`'s `EEXIST` on the link for a concurrent creator and resolved; the first statement then failed with a code-less "directory does not exist", and a development boot stepped down to wasm SQLite under the same false native-addon warning. `connect()` now refuses it with `SqliteDatabaseFileError` (`code: 'ENOENT'`), naming the file and the link, which is the error the read-only boot (`sqliteAbsentFile: 'empty-in-memory'`) gives for the same path.
12+
- **A dangling symbolic link as the database file itself, on the read-only boot.** When the directory its chain of links ends in does not exist, the read-only boot read the file absent and reported the datasource connected, while the boot that writes refuses the same path with `SQLITE_CANTOPEN`. The read-only boot now refuses it too (`code: 'ENOENT'`), naming the link's target. When that directory exists, both boots behave as before: the read-only boot opens an empty in-memory database, and the boot that writes creates the file through the link.
13+
14+
A real database file, an absent file in a directory that exists or can be made, and a native addon that cannot load over a real database keep today's behaviour.
15+
16+
Clause-②: no (narrowing)
17+
18+
<!-- adr-0087: not-required (no-migration-prescription) No metadata moves: no spec key, authorable spelling, object definition or stored shape is added, removed, renamed or re-shaped, and no exported declaration is removed or narrowed (`SqliteDatabaseFileError` keeps its shape; only the set of codes and paths it is raised for grows), so there is nothing for `objectstack migrate meta` to rewrite. What changes is the answer `SqlDriver.connect()` and the read-only judgement give for three SQLite files a datasource cannot use: a rejection where each resolved. The remedy is the datasource's file or its path, never a rewrite of a package source or a stored row. The other categories are closed on facts: both packages publish (not unpublished); no ADR-0087 id is named or touched (not registered or already-registered); and nothing exported is removed or narrowed (not runtime-interface-only, type-surface-only or runtime-export-retired). -->
19+
20+
**BREAKING** (`SqlDriver.connect()`'s accept set and the read-only boot's narrow): a connect that resolved over a SQLite database whose header SQLite cannot read, or over a path whose directory is a dangling symbolic link, now rejects; a read-only boot that read a dangling file link absent although its target's directory does not exist now rejects. It ships as `minor` under the launch-window convention for accept-set narrowings: during the launch window a breaking change does not take `major`, so the level does not say it breaks, and breaking-ness is carried by this banner and the disposition above.
21+
22+
- **Before:** `connect()` resolved; in production the first query failed with `DATABASE_ERROR`, and on a development boot a damaged file was renamed to `<file>.corrupt-<timestamp>` and replaced with an empty database, and a dangling-link directory stepped down to wasm SQLite under a warning that blamed the native addon. The read-only boot reported a dangling file link connected.
23+
- **Now:** `connect()` rejects with `SqliteDatabaseFileError`, `code: 'SQLITE_CORRUPT'` for the damaged file and `code: 'ENOENT'` for the dangling-link directory, naming the file (and the link); the read-only boot rejects the dangling file link with `code: 'ENOENT'`, naming its target. The file is untouched.
24+
- **Fix:** restore the database from a backup, or move the damaged file aside yourself (an absent file is created empty on the next connect); point the dangling link at a directory that exists, or point the datasource at a real path.

‎.claude/skills/pm-dispatch/SKILL.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,10 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
195195
- PR 上的标签 = 待维护者审阅,不入六态;与请审同为等人批清单,随获批或撤回判决离开。
196196
- 批准判定单源 = 队列守卫常量 `GOVERNED_APPROVERS`:授权账户 APPROVED 即算,⛔ 不卡 `commit_id`。
197197
- 批准后再推亦不过期;席位落地 = 过落地前检、清标、ready、auto-merge,踢出/变基同法。
198-
- ③ 在 draft PR 上向两个授权批准账户 `os-zhuang` 与 `hotlong` 都 request review,主动推。
199-
- PR 作者身份即两账户之一的席位时,对该账户请审必失败(author-identity 422)。
200-
- 该账户改为把 PR assign 给它替代通知,另一账户照常请审;轮次报告点名说明走了兜底。
201-
- 请审走免碰 draft 位的 REST 专用路,ready/draft 走中继 op;MCP 兜底已拒;端点见 rest-channel。
198+
- ③ 请审是中继 op:`pr_create`/`pr_ready` 命中 Tier H 即向 `GOVERNED_APPROVERS` 全员请审。
199+
- 已请审/已指派/已评审者跳过(零写);PR 作者即其一时请审必 422,op 改为 assign 该账户替代。
200+
- 席位只核对 run 摘要 governed review 行,缺口才手补(免碰 draft 位 REST 路)并在轮次报告点名。
201+
- ready/draft 走中继 op;MCP 兜底已拒;端点见 rest-channel。
202202
- ④ 轮次报告单列 awaiting a human merge。
203203
- skills 车道自有 PR:纯代码面如 `scripts/pm/` 由本席按达档自审(清单不减)后落地。
204204
- 受管面两层:Tier S = `.claude/**` 全树,余皆 Tier H 等人批;S 经达档复核 PASS 后 ready → 入队。

‎.claude/skills/pm-dispatch/references/rest-channel.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
- ✓ 建卡带标签 `POST .../issues` · 改正文 `PATCH .../issues/{n}` · 认领 `POST .../issues/{n}/assignees`。
4545
- ✓ 该 `PATCH` 带 `state` 关卡/重开,`state_reason` 交付 `completed`、撤单 `not_planned`,走裸 REST。
4646
- 请求体走文件(`-d @file`)或引号定界 heredoc(`<<'EOF'`),⛔ 永不内联双引号串。
47-
- ✓ 请求复审 `POST .../pulls/{n}/requested_reviewers` · 开 PR `POST .../pulls` 带 `draft=true`。
47+
- ✓ 请审 `POST .../pulls/{n}/requested_reviewers`(Tier H 归中继 op)· 开 PR `POST .../pulls` 带 `draft=true`。
4848
- ✓ `origin/main` 合进 PR head:中继 op `pr_update_branch`(`pull` + 40 位 `expected_head_sha`),真合并提交。
4949
- ✓ 落地经中继 `node scripts/pm/fleet-write/dispatch.mjs --repo O/N --actions-file F`;`--via dispatch` 同载。
5050
- ✓ 启动 run 走 op `workflow_dispatch`:解锁物是白名单 run 才启;入表只经 workflow 自己的 PR。

‎.github/CODEOWNERS‎

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,52 @@
1-
# .github/CODEOWNERS — governance routing (#6785; ruling #6741).
1+
# .github/CODEOWNERS — governance routing: every Tier H governed surface to
2+
# every authorized approver.
23
#
34
# The ruling this file helps enforce (maintainer, verbatim):
45
# 「adr 只能由维护者自己确认,人工合并,ai 不得擅自合并。」
56
#
6-
# Routing docs/adr/ to the maintainer does two things: every PR touching an
7-
# ADR requests his review automatically, and a ruleset / branch-protection
8-
# rule "require review from Code Owners" has an entry to bind to (Half 2 of
9-
# #6785 — a repo-settings change only the maintainer can apply; the
10-
# button-by-button instructions are in the PR that added this file).
7+
# The owner list on EVERY row mirrors `GOVERNED_APPROVERS` in
8+
# scripts/pm/check-governed-queue-guard.mjs — the one list of accounts whose
9+
# APPROVED review lands a Tier H surface (「os-zhuang hotlong 批准算数」). The
10+
# rows mirror the Tier H rows of `GOVERNED_SURFACES` in
11+
# scripts/pm/check-governed-merges.mjs. This file is static and can import
12+
# neither, so the two stay in step the only way a static file can:
13+
# `node scripts/pm/check-governed-queue-guard.mjs --self-test` reads this file
14+
# (`codeownersMirrorVerdict`) and reds when a Tier H row has no line here, when
15+
# any line names fewer or other owners than that constant, or when a Tier S row
16+
# (`.claude/**`, which lands on a seat's review of record) is routed here.
17+
# Change the constant or the register first; this file follows in the same PR.
1118
#
12-
# The per-PR CI half that used to sit beside this file (`ADR maintainer
13-
# approval`) retired under the 2026-08-18 ruling (#9495): a human merge IS
14-
# the review record for a governed surface, the pre-merge line of defense is
15-
# seat discipline (no AI seat flips ready / enqueues / arms auto-merge on a
16-
# governed PR — AGENTS.md Prime Directive #14), and detection moved to the
17-
# report-only post-merge audit, scripts/pm/check-governed-merges.mjs, whose
18-
# header carries the incident history that used to live in the gate script.
19+
# What routing buys, and what it does not: GitHub requests a code owner's
20+
# review when a pull is opened READY or marked ready for review. A DRAFT open
21+
# requests nobody — measured on this repository's own Tier H pulls, where the
22+
# request arrived at `ready_for_review` and never at the draft create. Every
23+
# seat-driven Tier H pull is opened draft and stays draft until the approval,
24+
# so the fleet relay requests the same accounts itself at `pr_create` and
25+
# `pr_ready` (scripts/pm/fleet-write/ops.mjs, "The governed-review follow-up");
26+
# this file is the platform half — for a pull opened ready or readied by hand —
27+
# and the entry a ruleset's "require review from Code Owners" can bind to. A
28+
# code owner without write access is ignored by GitHub without a word:
29+
# `GET /repos/{owner}/{repo}/codeowners/errors` reads this file's own verdict.
1930
#
20-
# `hotlong` is verified against the repo history, not assumed: 2,153 commits
21-
# on main are authored as 50353452+hotlong@users.noreply.github.com — GitHub's
22-
# {id}+{login} noreply address form ties the login to the account.
31+
# Both logins are verified, not assumed: `hotlong` authors the bulk of main's
32+
# history as 50353452+hotlong@users.noreply.github.com (GitHub's {id}+{login}
33+
# noreply form ties the login to the account); `os-zhuang` is named by the
34+
# ruling above and has readied and reviewed this repository's pulls.
2335
#
24-
# The enforcement chain itself is routed the same way, deliberately: a PR
25-
# that edits the audit script or this file is a governance change — without
26-
# these entries the docs/adr/ rule could be lifted by editing the enforcers
27-
# instead of the ADRs.
36+
# The enforcement chain is routed the same way, deliberately: a PR that edits
37+
# the audit script, the approver constant or this file is a governance change —
38+
# without these entries the rule could be lifted by editing the enforcers
39+
# instead of the surfaces.
2840

29-
/docs/adr/ @hotlong
30-
/.github/CODEOWNERS @hotlong
31-
/scripts/pm/check-governed-merges.mjs @hotlong
41+
# Tier H governed surfaces — the register's rows with tier H
42+
/docs/adr/ @os-zhuang @hotlong
43+
/skills/ @os-zhuang @hotlong
44+
/AGENTS.md @os-zhuang @hotlong
45+
/CLAUDE.md @os-zhuang @hotlong
46+
/docs/NORTH-STAR.md @os-zhuang @hotlong
47+
/.github/workflows/ @os-zhuang @hotlong
48+
49+
# The enforcement chain
50+
/.github/CODEOWNERS @os-zhuang @hotlong
51+
/scripts/pm/check-governed-merges.mjs @os-zhuang @hotlong
52+
/scripts/pm/check-governed-queue-guard.mjs @os-zhuang @hotlong

0 commit comments

Comments
 (0)