Skip to content

Commit 3ba4752

Browse files
committed
Merge origin/main into claude/issue-15929-governing-text-step
main now carries the maintainer-brief change to the same SKILL.md section (auto-merged; one line removed below this branch's hunk) and the rules-only rewrite of the lane job descriptions, which conflicted with this branch's two director.md lines. Resolved on main's rewritten director.md: the two lines are re-applied under 职责二 and paid by two in-place compressions (61+62, 69+70) so the file stays at its new 72-line ceiling. Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox Co-authored-by: Claude <noreply@anthropic.com>
2 parents 2a149b3 + a2051fa commit 3ba4752

27 files changed

Lines changed: 1713 additions & 841 deletions
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
"@objectstack/plugin-auth": patch
3+
---
4+
5+
The auth catch-all yields only a 404 that disclaims ownership — better-auth's own 404 answers can no longer be replaced by another route's
6+
7+
`registerAuthRoutes` mounts one catch-all over the whole auth namespace (`rawApp.all(`${basePath}/*`)`), and since #4088 that catch-all is deliberately not terminal: when better-auth answers 404 it calls `next()` and lets whatever else matched answer instead. That yield is load-bearing — `plugin-hono-server` mounts `/auth/me/permissions` and `/auth/me/localization` from its own `kernel:ready` hook, and without it those two are reachable only when HonoServerPlugin happens to register first.
8+
9+
What the yield could not express is **which** 404 may be handed on, because it had only the status to go on. So every 404 was yielded, including the ones that are better-auth's own answer on a path its router serves. Measured with the shipped handler on a real Hono app: add one broad downstream mount — `app.all('/api/v1/*', c => c.json({}))`, the shape a composition adds — and
10+
11+
```
12+
POST /api/v1/auth/delete-user -> 200 {}
13+
```
14+
15+
where better-auth answered 404 because `user.deleteUser` is deliberately unconfigured. That route is not hypothetical: `auth-route-ledger.ts` carries it under the `disabled` disposition precisely because it is published and refused — and the same holds for every 404 a routed endpoint produces for a bad token, an unknown id, or an admin family the deployment does mount. Those answers were all up for grabs.
16+
17+
The catch-all now asks better-auth's live instance whether it owns the path before it yields. The seam is `auth.api` — the same one `auth-route-ledger.conformance.test.ts` reads and the same one the `/admin/` dogfood sweep derives from, because there is no route table to enumerate by hand; matching mirrors better-call's own `createRouter` walk, including its `SERVER_ONLY` skip and its `:param` syntax. That skip is load-bearing rather than cosmetic: measured on the stock boot, the nine `/admin/oauth2/*` endpoints are in `auth.api` and every one carries `SERVER_ONLY: true`, so better-call never routes them — their 404 is an unrouted one and stays yieldable, because ownership is "does better-call route this", not "is it in `auth.api`". An ownership table that cannot be built answers "not owned", so an enumeration failure degrades to the previous behaviour rather than taking the #4088 surface down with it.
18+
19+
**The mount is untouched.** It still claims exactly `${basePath}/*` and still forwards every request under it to better-auth. What narrowed is only which 404 may be handed on.
20+
21+
**Upgrade note — a composition that mounts a route matching paths under the auth base path may see a 404 where it previously saw its own answer.** Affected: deployments that register a route which also matches `/api/v1/auth/...` — most often a broad wildcard over the API prefix — mounted *after* AuthPlugin. Before this release, any request to a path better-auth serves but answers 404 on (a switched-off capability, not an unknown path) was passed to that route and the caller received *its* response, commonly `200` with an empty object. From this release the caller receives better-auth's 404. Callers that treated such a response as success — `res.ok`, `status === 200`, "no error thrown" — will start seeing the refusal that was always the real answer; that is the point of the change, and the wire shape they now get is the one a deployment without the extra mount has always returned. Nothing to do if you mount no such route: paths better-auth does **not** own are yielded as before, so `/auth/me/permissions`, `/auth/me/localization` and any other sibling route under the auth prefix are unaffected in either registration order.
22+
23+
**One carve-out to that sentence, measured and bounded.** A **trailing-slash or doubled-slash spelling of a path better-auth DOES own**`/api/v1/auth/delete-user/`, `/api/v1/auth//sign-in/social` — is now claimed rather than yielded. better-call treats those spellings as unrouted (it refuses on a `//` and on trailing-slash parity before it looks the route up), while this ownership table strips the trailing slash and drops empty segments and so counts them as owned. On a composition with a broad downstream mount, such a spelling therefore answers better-auth's 404 instead of that mount's response. Only those two spellings, only of a path better-auth already owns, and only where such a mount exists: no route in this repo registers a spelling of that shape, and every genuinely unowned path — every `/auth/me/*` route included — is yielded exactly as it was. Aligning the table with better-call's own pre-checks is tracked as a follow-up rather than carried here.

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
9393
- 所有状态在 GitHub:只经 issue 标签、assignee、正文行与 `pm:seat` 座位贴读写。
9494
- 循环必须能从全新会话恢复。
9595
- PM 不写文件、不写代码;唯一例外及其全部条件见红线。
96-
- GitHub 上一切新内容用英文。
97-
- 中文只留三通道:轮次报告、派发令里的裁决引文、决策四维分析(评论与四棱块)。
96+
- GitHub 上一切新内容用英文;中文只留四通道,含 `## 维护者速读`(受管 PR 与决策卡)
97+
- 另三通道:轮次报告、派发令里的裁决引文、决策四维分析(评论与四棱块)。
9898
- 裁决引文照抄不译;四维中文只管新记录,存量英文块 ⛔ 不迁移;存量中文 ⛔ 不追溯改写。
9999
- 先认领后动工;assignee 不是你 ⇒ 已被认领,永不碰。
100100
- 一座位一车道双射:域 X 谁管、PM Y 管什么,各恰好一个答案。
@@ -351,11 +351,12 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
351351
- `pm:queue` 也收恢复不变量的 finding 与 test-only pin。
352352
- `needs-user-decision` = 设计卡、feature/契约形状提案、需要 appetite 的多周程序。
353353
- 碰存量数据迁移形状或删除已发布能力的卡也进决策箱。
354-
- 决策卡落卡必带四棱卡面块,⛔ 不留待有人接手再补。
354+
- 决策卡落卡必带四棱卡面块与其上的「维护者速读」,⛔ 不留待有人接手再补。
355+
- 决策卡的速读同题,用业务语言先讲事情与选项,末句只问一字:A/B/C 或是否。
355356
- `finding` = 观察类(死代码、未演练漂移、抛光;真实但今天没有用户撞上),待首次定级。
356357
- 先修复:正文被 sanitizer 截断的卡不可派发,评论修复指令后跳过。
357358
- 停摆指令判据必须比其它分类更硬(双读取),事后证伪同处公开作废。
358-
- 决策箱勤务:落卡入箱时校验/补全标准四棱卡面块;存量卡低频子轮回填,语言按不变量。
359+
- 决策箱勤务:落卡入箱时校验/补全四棱块与速读;存量卡低频子轮回填,语言按不变量。
359360
- 原生 issue 类型 Bug/Feature/Task 是分诊的固定产出。
360361
- 分诊席是 `type` 字段的唯一权威生产者;立单者可预填,分诊校正。
361362
- 判据:违背已声明契约 ⇒ `Bug`,扩大接受集/公开面 ⇒ `Feature`,其余 ⇒ `Task`
@@ -592,13 +593,10 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
592593
- PR 形态与范围:draft、目标 `main``Fixes`/`Part of` 首行判据,翻 ready 前亲核。
593594
- `Part of` 卡 MERGED 时点收口;changed files 范围与 changeset/`skip-changeset` 分流;测试证据。
594595
- 报告在草稿 PR 时点到达,CI 收敛读数只属于复核侧:gate `in_progress` 是诚实读数。
595-
- 放行前亲核判据;收敛期补丁轮与本单等 CI 例外见 checklist。
596596
- 绿色输出≠ 该绿证明了被测风险:拒收断言、全绿方向与时序、pin 翻转、边界后收益。
597597
- 证伪是好运行:`premise_still_valid: false` 是再分诊输入;dev 纠正 PM 当众认。
598-
- 判据被测量推翻照 ACCEPT,证据要件在 checklist。
599598
- 删除与二进制:死代码删除亲核引用面;`+0/-0` 先疑 NUL;sweep 范围外产出成组列出。
600-
-`skills/**` 的 PR 加问整包价值密度:从整包加载的客户 agent 的座位上读。
601-
- ⛔ 不从功能作者的座位读价值密度。
599+
-`skills/**` 的 PR 加问整包价值密度:从整包加载的客户 agent 座位读,⛔ 不从作者座位读。
602600
- 超派发预算或小功能大扩写 ⇒ REWORK,⛔ 不因已经写好了放行。
603601
- 判决 ACCEPT:issue 英文短评论,核对清单结论 + 抽查读数 + 偏差,链接 PR,⛔ 不复述其叙事。
604602
- 判决 REWORK:逐项反馈,同认领重派;补丁轮优先 SendMessage 续派原 dev;最多 2 轮,第三次升级。
@@ -607,18 +605,21 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
607605
- 路径面用 `get_files` 取,⛔ 不看报告自述;动手之前先分,不是事后对照。
608606
- governed 面统一定义:`docs/adr/**` + `.claude/**`(全量,含 agents/hooks/settings)+ `skills/**`
609607
- governed 面同含 `AGENTS.md` + `CLAUDE.md`;agent 指令文件跨仓同判,仓集读 `GOVERNED_REPOS`,此处不列。
610-
- 路径面一条命中 ⇒ ACCEPT 换终局四件套。
608+
- 路径面一条命中 ⇒ ACCEPT 换终局四件套,混合 diff ⛔ 不按比例判;要拆让 dev 单独开 PR
611609
- ① 复核结论照常写在 issue 上;技能面 PR 的复核席须跑在契约复审档位。
612610
- ② PR 留给维护者看得见地悬着;终局两条:人工直合即审核记录;授权批准 ⇒ 队列放行。
611+
- 看得见 = ACCEPT 同笔挂 `needs-user-decision` + 贴终稿「维护者速读」评论;①仍是审核记录。
612+
- 速读五段固定:改了什么/为什么改/风险与代价(含回滚)/席位意见/你要做的(一个动作)。
613+
- 草稿归 dev:受管面 PR 正文带 `## 维护者速读(草稿)`,中文、业务角度,席位意见留空。
614+
- 终稿 = 席位对照自己读的 diff 校正草稿、填席位意见后贴评论;维护者只读评论。
615+
- PR 上的标签 = 待维护者审阅,不入六态;与请审同为等人合清单,随合并或撤回判决离开。
613616
- 批准判定单源 = 队列守卫常量 `GOVERNED_APPROVERS`:授权账户 APPROVED 即算,⛔ 不卡 `commit_id`
614617
- 批准后再推提交也不过期;无批准 ⛔ 不翻 ready、不入队、不挂 auto-merge。
615618
- ③ 在 draft PR 上向两个授权批准账户 `os-zhuang``hotlong` 都 request review,主动推。
616-
- 等人合清单从此活在 GitHub 的 Review-requested 队列,合并自动消项。
617619
- PR 作者身份即两账户之一的席位时,对该账户请审必失败(author-identity 422)。
618620
- 该账户改为把 PR assign 给它替代通知,另一账户照常请审;轮次报告点名说明走了兜底。
619621
- 请审走免碰 draft 位的专用 REST 端点,MCP 兜底显式带 `draft: true`;端点事实住 platform-readings。
620622
- ④ 轮次报告单列 awaiting a human merge。
621-
- 混合 diff 一条命中就分叉,⛔ 不按比例判;要拆就让 dev 单独开 PR。
622623
- 已入队才读到本条 ⇒ 转 draft 与 disable 都做;出队以阳性探针答,ref 缺席只旁证。
623624
- skills 车道自有 PR 再按 diff 内容分流:diff 含任一 `.md` 文件 ⇒ 终局四件套照旧。
624625
- 纯代码面(`scripts/pm/` 工具、`.claude/` hooks/workflows/settings、非 md 产物)⇒ skills 席自审。
@@ -755,7 +756,6 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报
755756
- 长远合理性权重恒 ≥50%:推荐以长远的读数领起,四轴冲突时其余各轴合起来投不翻它。
756757
- 权重按缩小而非扩大特例与契约增生读,⛔ 不据它为投机扩张背书。
757758
- 权重是推荐规则不是授权规则:50% 不把人工地板的事变成可派发的事。
758-
- 标准四棱卡面块是落卡与升级的必备件,每张 `needs-user-decision` 卡落卡即带。
759759
- 收件箱由维护者定期消化,⛔ 不 assign 推送。
760760
- 四维分析从业务的角度写;写法六项与四棱块固定形状见 `references/decision-analysis.md`
761761
- 推荐是输入,永不是放行,人工地板不变。
Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
# 过滤 / 谓词语义的编译面清单(references —— 按需加载)
1+
# 过滤与谓词语义的编译面清单
22

3-
出处:主文件「派发」
4-
的过滤/谓词语义标准条款 —— 命中该条款的派发令把本清单**逐面抄进去**,PR 逐面申报。
5-
维护纪律与派发前复核串在正文内,
6-
一并适用:**这张表由 PR 维护、派发前先跑复核串重验,⛔ 不凭记忆抄**
3+
见 SKILL.md 〈派发〉的过滤与谓词语义条款;命中它的派发令逐面抄进本清单,PR 逐面申报。
4+
维护纪律与复核串一并适用:这张表由 PR 维护、派发前先跑复核串重验,⛔ 不凭记忆抄。
75

8-
编译面清单(逐面实测 @ `main` `48f98b0`,2026-08-07):
6+
编译面清单(行号每天在动,派发前按下方复核串重验):
97

108
| # || 落点(file:line) | 备注 |
119
| --- | --- | --- | --- |
@@ -15,12 +13,12 @@
1513
| 4 | service-analytics filter-normalizer | `packages/services/service-analytics/src/strategies/filter-normalizer.ts:1235`(`lowerAnalyticsWhere`) | analytics / cube 侧 |
1614
| 5 | `formula` | `packages/formula/src/matches-filter.ts:73`(`matchesFilterCondition`) | RLS 写侧 `check` 与公式求值;JS 两值语义的基准面 |
1715
| 半面 | objectql `having-filter` | `packages/objectql/src/having-filter.ts:92` / `:98`(`applyHaving` / `matchesHaving`) | 聚合****过滤。算半面是因为词表是子集,**但申报义务不打折** —— 它是**唯一没有 conformance 表覆盖的面**(`FILTER_LOGIC_CASES` 不驱动 HAVING 路径),所以漏了它连门禁都不会红 |
18-
| 已解冻 | `driver-memory` / `driver-mongodb` | `packages/drivers/driver-memory/src/memory-matcher.ts:134`(`checkCondition`)、`packages/drivers/driver-mongodb/src/mongodb-filter.ts:700`(`translateFieldOperators`) | 2026-08-05 投入冻结,**2026-08-11 两条裁决解除** ⇒ 「不在范围 + 冻结指令」作废,按普通面申报 |
16+
| 已解冻 | `driver-memory` / `driver-mongodb` | `packages/drivers/driver-memory/src/memory-matcher.ts:134`(`checkCondition`)、`packages/drivers/driver-mongodb/src/mongodb-filter.ts:700`(`translateFieldOperators`) | 冻结指令与不在范围的旧判定均已作废,按普通面申报 |
1917

20-
**这张表本身由 PR 维护 —— 与域表同一纪律
21-
** 增删一面(新驱动、新求值器、某面被合并或退役、冻结状态变化)的那个 PR 顺手改这里,
22-
不留给下一次裁决重新数。清单****过期是必然的,清单**没有维护者**才是缺陷
23-
24-
⚠️ 派发前复核一遍再抄,⛔ 不要凭这张表的记忆填派发令:本仓的包路径搬过家(驱动进
25-
`packages/drivers/`、服务进 `packages/services/`),行号更是每天在动。一条够用的复核串:`grep
26-
-rn 'matchesFilterCondition\|buildWhereSQL\|compileScopedFilterToSql' packages --include=*.ts | grep -v node_modules`。
18+
增删一面的那个 PR 顺手改这里,不留给下一次裁决重新数
19+
触发增删的四种事件:新驱动、新求值器、某面被合并或退役、冻结状态变化
20+
清单会过期是必然的,清单没有维护者才是缺陷
21+
派发前复核一遍再抄,⛔ 不凭本表的记忆填派发令:包路径搬过家,行号更是每天在动。
22+
一条够用的复核串:
23+
`grep -rn 'matchesFilterCondition\|buildWhereSQL\|compileScopedFilterToSql'
24+
packages --include=*.ts | grep -v node_modules`。
Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
1-
# 车道岗位说明:domain:cli(references/lanes —— 座位贴指针指向本文件)
1+
# 车道岗位说明:domain:cli
22

3-
岗位说明版本化于此,升级走技能 PR;现值状态恒在座位贴,⛔ 不迁入本文件
3+
见 SKILL.md 〈座位贴协议〉;本文是本车道岗位说明,现值状态恒在座位贴,⛔ 不迁入本文
44

55
## 范围
66

77
- `packages/cli``runtime``verify``qa``types``packages/rest`
88
`packages/mcp``packages/observability``packages/client*`
99
`cloud-connection``create-objectstack``packages/adapters/*`
1010
`plugin-hono-server``plugin-dev`
11-
- 红线:按落点判归属 —— 标题挂 cli 而落点在别包的卡只上报误标不改签;
12-
`packages/spec` 恒归 spec 座位;`/meta` 路由**本体**归本席,元数据格式/接受面归
13-
`domain:spec`
11+
- 红线:按落点判归属 —— 标题挂 cli 而落点在别包的卡只上报误标,⛔ 不改签。
12+
- `packages/spec` 恒归 spec 座位
13+
- `/meta` 路由本体归本席,元数据格式与接受面归 `domain:spec`
1414

1515
## 常设承诺
1616

17-
- **PR 侧绿 ≠ 队列侧绿**;队列分支读法与边界在 platform-readings(条目名
18-
`main/pr-{number}-{parent sha}`,parent sha 可重建队序;⚠️ ref 在出队后滞留)。
19-
- `dispatch-gates.mjs` 只报**路径推导**的地板 —— 条款②从卡**内容**判且优先于它;已知盲
20-
区:它不点名 `pnpm lint` 族 ⇒ 本车道派发令恒补一句「跑 `pnpm lint`」。
21-
- ⛔ 永不削弱门禁 —— 棘轮上跳是门禁在报你的改动有缺陷;规则文案里自带的逃生舱只用
22-
于它描述的那种情形。
17+
- PR 侧绿不等于队列侧绿;队列分支条目名、队序重建与出队滞留住 `../platform-readings.md`
18+
- `dispatch-gates.mjs` 只报路径推导的地板,条款②从卡内容判且优先于它。
19+
- 已知盲区:它不点名 `pnpm lint` 族 ⇒ 本车道派发令恒补一句跑 `pnpm lint`
20+
- ⛔ 永不削弱门禁:棘轮上跳是门禁在报你的改动有缺陷。
21+
- 规则文案里自带的逃生舱只用于它描述的那种情形。
2322

2423
## 席内判断
2524

26-
- **探针的 baseline 也是测量**,而且是没人复查的那个 —— 判据恒读命中行本身,⛔ 不
27-
读命中数;断言「文本被删」的探针要锚在消失的那段上(被删串的前缀在删除后仍然幸
28-
存是构造使然)。
29-
- 静默时长是**发探针**的门槛,永不是判死的(本车道实测基线:派发 → draft PR ≈
30-
35–50 分钟);分支无提交 + SendMessage 探针便宜,且实测能复活假死的 dev —— ⛔ 永
31-
不往可能活着的 worktree 派第二个 agent。
25+
- 探针的 baseline 也是测量,而且是没人复查的那个 ⇒ 判据恒读命中行本身,⛔ 不读命中数。
26+
- 断言文本被删的探针要锚在消失的那段上:被删串的前缀在删除后仍幸存是构造使然。
27+
- 静默时长是发探针的门槛,永不是判死的门槛;基线自本车道实录,⛔ 不写成常数。
28+
- 分支无提交加 SendMessage 探针便宜,且能复活假死的 dev。
29+
- ⛔ 永不往可能活着的 worktree 派第二个 agent。

0 commit comments

Comments
 (0)