From ec7bbcab05a7ed788445455c3ae0271ac0f2a70a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 03:02:03 +0000 Subject: [PATCH 1/5] =?UTF-8?q?docs(north-star,pm-dispatch):=20the=20featu?= =?UTF-8?q?re=20axis=20=E2=80=94=20area:*=20labels,=20the=20=E3=80=8C?= =?UTF-8?q?=E8=B7=AF=E3=80=8D=20section=20as=20an=20ordered=20list=20of=20?= =?UTF-8?q?feature=20points?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 1 and step 2 of the charter: eleven `area:*` label rows in the PM label vocabulary (objectstack + objectui), a top-level `axis` field on all fifteen platform-checklist area files, and a 「路上的功能点」 list under the North Star's 「唯一的度量,那条路」 seeded with the docs-authoring feature and the checklist's currently open P0 items, ordered by the road's steps. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude --- docs/NORTH-STAR.md | 26 ++++++++++- .../areas/access-security.json | 1 + docs/qa/platform-checklist/areas/ai.json | 1 + .../platform-checklist/areas/api-backend.json | 1 + .../platform-checklist/areas/approvals.json | 1 + .../areas/attachments-storage.json | 1 + .../platform-checklist/areas/automation.json | 1 + docs/qa/platform-checklist/areas/cli.json | 1 + .../platform-checklist/areas/dashboards.json | 1 + docs/qa/platform-checklist/areas/i18n.json | 1 + .../areas/identity-auth.json | 1 + .../areas/integration-system.json | 1 + .../areas/platform-core.json | 1 + .../areas/records-forms.json | 1 + docs/qa/platform-checklist/areas/search.json | 1 + .../areas/studio-authoring.json | 1 + scripts/pm/ensure-pm-labels.sh | 46 +++++++++++++++++++ 17 files changed, 86 insertions(+), 1 deletion(-) diff --git a/docs/NORTH-STAR.md b/docs/NORTH-STAR.md index 15ee9de8265..7dd271d623a 100644 --- a/docs/NORTH-STAR.md +++ b/docs/NORTH-STAR.md @@ -10,9 +10,33 @@ **唯一的度量,那条路**:一个新的 AI 开发者(人在旁验收)从 `npm create objectstack` 出发:写元数据 → 本地跑起来、看到 → 验证响亮拒绝错的、放行对的 → 发布并装进一个环境 → 接一个 Agent(社区版走 MCP),让它在应用里完成一次真实业务操作 → 按客户一句话需求迭代一次。每周真走一遍,结果落一张 run record。第一个断掉的步骤就是当前的 P0;跑得通但结果错的是 P2。 +**路上的功能点**:这条路上要做的功能点,自上而下就是顺序 —— 这张表就是路线图,改它即改优先级。每行 `轴 · 功能点(业务语言) · 清单项 id · 路步(P 后面是那条路的第几步)`。 + +- studio · 管理员在界面里写 Markdown 文档并加到菜单(含 book) · 清单项待写 · P2 +- studio · 不写代码走完建包 → 建对象 → 记录 → 应用 → 发布 → 终端用户,零重启 · studio-authoring.first-run-loop · P2 +- records · 在界面里把一条记录建出来、看见、改掉、删掉 · records-forms.crud-roundtrip · P3 +- access · 受限成员只看得到自己的行,管理员看得到全部 · access-security.rls-both-sides · P3 +- access · 写入挡得住:只读字段被剥、伪造与转移 owner 被拒、批量照验 · access-security.write-path-guards · P3 +- access · 每个权限集的增删改查逐格兑现,收回的动作真的被拒 · access-security.crud-permission-matrix · P3 +- access · 四种共享模型各自声明的基线都挡得住 · access-security.owd-sharing-matrix · P3 +- access · 匿名请求在每个挂出来的 API 家族都统一按未认证拒绝,先于任何资源解析 · access-security.anonymous-deny-surfaces · P3 +- access · 没有活跃组织的会话是合法状态,且失败向关,永不写空租户 · access-security.no-active-org-session-semantics · P3 +- workflow · 非管理员从自己的应用进得去完整的审批收件箱 · approvals.account-app-entry · P3 +- api-integration · 数据 API 的查询契约:每个过滤算子答案已知,错的输入响亮拒绝 · api-backend.query-contract-matrix · P3 +- devpath · 一条命令把应用跑起来:能登录、数据库选择诚实、端口与陈旧都说出来 · cli.dev-boot-contract · P3 +- devpath · 起来就是干净的:健康与就绪都通,没有降级横幅,控制台与应用元数据都供得上 · platform-core.boot-health · P3 +- devpath · 种子数据原样落库,重放不多不少 · platform-core.seed-integrity · P3 +- devpath · 管理员从控制台登得进去,刷新后会话还在,过期后重新认证干净 · platform-core.console-login · P3 +- devpath · 每个导航面都渲染得出来,坏了也看得见错误边界,不是白屏 · platform-core.nav-surfaces-render · P3 +- devpath · 自带的应用(Setup / Account)每个菜单目标都打得开,门是挡不是报错 · platform-core.builtin-apps-nav-render · P3 +- api-integration · 数据源密钥写不进去也读不出来:内联即拒,两道读口都打码 · integration-system.datasource-credential-refusal-matrix · P4 +- workflow · 停用一个随包发的流程,冷重启之后它还是停的 · automation.packaged-flow-disable-durable · P5 +- api-integration · 停用的随包动作在两道派发门都被拒,且拒得出于开关而非权限 · api-backend.packaged-action-disabled-dispatch · P5 +- ai · 没有密钥 MCP 就不起;拿成员的密钥连上,读与聚合都照他的权限走,吊销下一次调用即生效 · ai.mcp-stdio-fail-closed · P6 + **优先级**: 1. 安全与数据完整性永远最高,不等路。 -2. 路断了、或清单上的能力断了 ⇒ P0/P1;能跑但出错 ⇒ P2;不在路上、不在清单上 ⇒ p3 或不做。 +2. 路断了、或清单上的能力断了 ⇒ P0/P1;能跑但出错 ⇒ P2;不在路上、不在清单上 ⇒ p3 或不做。定级读「路上的功能点」:改那张表即改优先级,⛔ 不逐卡改档。 3. 产品仓还有开放的 P0/P1 时,任何车道不派 p2/p3 的工具卡、契约卫生卡;解锁产品 P0/P1 的仪器卡沿链继承其优先级。 4. 因为写的是 AI、用的也是 AI:元数据既要 AI 能写——错的必须被响亮拒绝并给处方,永不静默落库;也要 AI 能用——声明了的对象、动作、agent / tool / skill 元数据在运行时兑现,MCP 面暴露的就是应用真能做的。写给 AI 的文档与 skills 说错一句,等于产品缺陷。 diff --git a/docs/qa/platform-checklist/areas/access-security.json b/docs/qa/platform-checklist/areas/access-security.json index 717400791d0..895864a0fa1 100644 --- a/docs/qa/platform-checklist/areas/access-security.json +++ b/docs/qa/platform-checklist/areas/access-security.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "access-security", + "axis": "access", "title": "Access, permissions, RLS/FLS, write-path guards", "items": [ { diff --git a/docs/qa/platform-checklist/areas/ai.json b/docs/qa/platform-checklist/areas/ai.json index c31bd6ba721..a87053463d5 100644 --- a/docs/qa/platform-checklist/areas/ai.json +++ b/docs/qa/platform-checklist/areas/ai.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md. NOTE: AI is deliberately absent from the showcase app (ADR-0063 — platform-owned), so most items here carry explicit fixture requirements instead of assuming showcase seeds. BOUNDARY: the in-product agent runtime (`@objectstack/service-ai`) is Cloud/EE (cloud repo) — the OPEN framework serves the metadata surface, the MCP surface (packages/mcp), and honest 501s on /ai/** (route-ledger '* /ai/**' row); items below only assert what the open framework actually runs.", "area": "ai", + "axis": "ai", "title": "AI — agents, tools, skills, MCP", "items": [ { diff --git a/docs/qa/platform-checklist/areas/api-backend.json b/docs/qa/platform-checklist/areas/api-backend.json index de1da6a79d3..66cfc5eaadd 100644 --- a/docs/qa/platform-checklist/areas/api-backend.json +++ b/docs/qa/platform-checklist/areas/api-backend.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "api-backend", + "axis": "api-integration", "title": "REST / batch / formula / build-time gates", "items": [ { diff --git a/docs/qa/platform-checklist/areas/approvals.json b/docs/qa/platform-checklist/areas/approvals.json index 2e7e6a8f1fd..11c32cef709 100644 --- a/docs/qa/platform-checklist/areas/approvals.json +++ b/docs/qa/platform-checklist/areas/approvals.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "approvals", + "axis": "workflow", "title": "Approvals — quorum, per-group sign-off (会签), inbox", "items": [ { diff --git a/docs/qa/platform-checklist/areas/attachments-storage.json b/docs/qa/platform-checklist/areas/attachments-storage.json index d33d74bfd47..6d1ee43863f 100644 --- a/docs/qa/platform-checklist/areas/attachments-storage.json +++ b/docs/qa/platform-checklist/areas/attachments-storage.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "attachments-storage", + "axis": "files", "title": "Attachments & storage — presigned/chunked upload, signed-URL downloads, parent-derived access, sys_file lifecycle", "fixtures": { "$comment": "AREA-LEVEL standing fixtures. An item opts in with fixtures.provisioning = { use: \"\", why: \"…\" }; the recipe is written ONCE here so four items do not carry four drifting copies of the same twenty-call sequence. Recipes are runtime-provisioned (no repo file is touched, nothing to seed, nothing to un-seed beyond the teardown line) and every call below is grounded in framework source at the cited file:line — replay them literally, and if one 4xxs, re-read the citation before assuming the recipe rotted.", diff --git a/docs/qa/platform-checklist/areas/automation.json b/docs/qa/platform-checklist/areas/automation.json index 27f5fd02032..19cc7e43b9e 100644 --- a/docs/qa/platform-checklist/areas/automation.json +++ b/docs/qa/platform-checklist/areas/automation.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "automation", + "axis": "workflow", "title": "Automation — flows, triggers, roll-ups", "fixtures": { "$comment": "AREA-LEVEL standing fixtures. An item opts in with fixtures.provisioning = { use: \"\", why: \"…\" }; the recipe is written ONCE here so several items do not carry drifting copies of the same call sequence. Recipes are runtime-provisioned (no repo file is touched, nothing to seed) and every call is grounded in framework source at the cited file:line — replay them literally, and if one 4xxs, re-read the citation before assuming the recipe rotted. Shape copied from qa-scratch-authz in areas/attachments-storage.json (#7716/#7670).", diff --git a/docs/qa/platform-checklist/areas/cli.json b/docs/qa/platform-checklist/areas/cli.json index 67ca79f5cd8..1dd4608414e 100644 --- a/docs/qa/platform-checklist/areas/cli.json +++ b/docs/qa/platform-checklist/areas/cli.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "cli", + "axis": "devpath", "title": "CLI — os dev/build/migrate/verify/test boot, load, execution & exit-code contracts, scaffold first-run, flag/command error UX", "items": [ { diff --git a/docs/qa/platform-checklist/areas/dashboards.json b/docs/qa/platform-checklist/areas/dashboards.json index 7c402bacb03..ada007d90ec 100644 --- a/docs/qa/platform-checklist/areas/dashboards.json +++ b/docs/qa/platform-checklist/areas/dashboards.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "dashboards", + "axis": "reports", "title": "Dashboards, reports, analytics", "items": [ { diff --git a/docs/qa/platform-checklist/areas/i18n.json b/docs/qa/platform-checklist/areas/i18n.json index b7f612656d0..4400ea7f3cd 100644 --- a/docs/qa/platform-checklist/areas/i18n.json +++ b/docs/qa/platform-checklist/areas/i18n.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "i18n", + "axis": "i18n", "title": "Internationalization", "items": [ { diff --git a/docs/qa/platform-checklist/areas/identity-auth.json b/docs/qa/platform-checklist/areas/identity-auth.json index f6baec3c23c..e23fba2eeaf 100644 --- a/docs/qa/platform-checklist/areas/identity-auth.json +++ b/docs/qa/platform-checklist/areas/identity-auth.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "identity-auth", + "axis": "identity", "title": "Auth, login, identity", "items": [ { diff --git a/docs/qa/platform-checklist/areas/integration-system.json b/docs/qa/platform-checklist/areas/integration-system.json index e7a03c90136..6bd8797f077 100644 --- a/docs/qa/platform-checklist/areas/integration-system.json +++ b/docs/qa/platform-checklist/areas/integration-system.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md. FIXTURE MAP for this area (all in-repo, CI-deterministic): the showcase ships four declarative connectors (examples/app-showcase/src/system/connectors/index.ts — rest/openapi/mcp provider-bound instances + one enabled:false catalog descriptor), an outbound webhook (src/automation/webhooks — shipped inactive), a cron job (src/automation/jobs — showcase_health_sweep), an email template (src/system/emails — showcase_task_done_email) and two notify flows (src/automation/flows).", "area": "integration-system", + "axis": "api-integration", "title": "Integration & system services — connectors, webhooks, jobs, email templates, notifications", "items": [ { diff --git a/docs/qa/platform-checklist/areas/platform-core.json b/docs/qa/platform-checklist/areas/platform-core.json index 54047bdf3a0..0e4b222fa33 100644 --- a/docs/qa/platform-checklist/areas/platform-core.json +++ b/docs/qa/platform-checklist/areas/platform-core.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "platform-core", + "axis": "devpath", "title": "Platform core — boot, health, console shell, metadata pipeline", "items": [ { diff --git a/docs/qa/platform-checklist/areas/records-forms.json b/docs/qa/platform-checklist/areas/records-forms.json index f05cbe5fbe0..611bb7d610a 100644 --- a/docs/qa/platform-checklist/areas/records-forms.json +++ b/docs/qa/platform-checklist/areas/records-forms.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "records-forms", + "axis": "records", "title": "Records, lists, detail pages, forms", "fixtures": { "$comment": "AREA-LEVEL standing fixtures. An item opts in with fixtures.provisioning = { use: \"\", why: \"…\" }; the recipe is written ONCE here so several items do not carry drifting copies of the same sequence. Recipes are runtime-provisioned (no repo file is touched, nothing to seed, nothing to un-seed beyond the teardown line) and every call below is grounded in framework source at the cited file:line — replay them literally, and if one 4xxs, re-read the citation before assuming the recipe rotted.", diff --git a/docs/qa/platform-checklist/areas/search.json b/docs/qa/platform-checklist/areas/search.json index 8462ecaa0e6..2e6b2e4c6ed 100644 --- a/docs/qa/platform-checklist/areas/search.json +++ b/docs/qa/platform-checklist/areas/search.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "search", + "axis": "records", "title": "Record search — $search executor, field scoping, RLS composition, pinyin recall, freshness", "fixtures": { "$comment": "AREA-LEVEL standing fixtures. An item opts in with fixtures.provisioning = { use: \"\", why: \"…\" }; the recipe is written ONCE here so several items do not carry drifting copies of the same call sequence. Recipes are runtime-provisioned (no repo file is touched, nothing to seed) and every call is grounded in framework source at the cited file:line — replay them literally, and if one 4xxs, re-read the citation before assuming the recipe rotted. Shape copied from qa-scratch-authz in areas/attachments-storage.json (#7716/#7670).", diff --git a/docs/qa/platform-checklist/areas/studio-authoring.json b/docs/qa/platform-checklist/areas/studio-authoring.json index 7d734fa6cb9..fe97323e93a 100644 --- a/docs/qa/platform-checklist/areas/studio-authoring.json +++ b/docs/qa/platform-checklist/areas/studio-authoring.json @@ -1,6 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "studio-authoring", + "axis": "studio", "title": "Studio authoring — the admin/maker loop: packages, objects, views, record pages, draft→publish", "items": [ { diff --git a/scripts/pm/ensure-pm-labels.sh b/scripts/pm/ensure-pm-labels.sh index 9be245e956c..19c5c5d63b5 100644 --- a/scripts/pm/ensure-pm-labels.sh +++ b/scripts/pm/ensure-pm-labels.sh @@ -465,6 +465,52 @@ gh label create domain:devx -R objectstack-ai/objectui -c bfd4f2 -d "objectui de gh label create domain:spec -R objectstack-ai/objectui -c bfd4f2 -d "objectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane" 2>/dev/null || true gh label create domain:ui -R objectstack-ai/objectui -c bfd4f2 -d "objectui ui stream: fix lands on the published library or apps — objectui execution seat" 2>/dev/null || true +# The FEATURE AXIS — `area:*`, one per card, eleven values. It is the PLANNING +# axis: priority is judged on it, and `domain:*` beside it decides only which +# seat may claim which files. The eleven values are the North Star definition +# line (「做出来的是什么」) plus the road it measures, so the axis and the +# product definition cannot drift apart without one of them being edited. +# +# Triage applies it at FIRST GRADING, in the same label write as `domain:*` and +# `priority:*`; a filer may pre-apply it; a tooling card carries the area it +# PROTECTS (a card that protects no area is not filed at all). ⛔ No backfill of +# the existing backlog — a card gets its area when it is next touched. +# +# Four named consumers (SKILL.md 状态模型, 「一个标签存在当且仅当有具名读者」): +# the maintainer's board view by area; triage grading, where the card's priority +# is inherited from the checklist item in that area; the parent-card grouping +# for a cross-layer feature point; and the execution seat's candidate order. +# The checklist end of that inheritance is machine-readable: every +# docs/qa/platform-checklist/areas/*.json carries a top-level `axis` naming one +# of these eleven values. +# +# TWO repos, deliberately, and not the five-repo loop above: a feature point +# spans 协议 → 运行时 → 前端, which is objectstack plus objectui. cloud is +# parked (北极星「现在不做」), objectos is the docs/site repo, and hotcrm is the +# exemplar APP — its cards are app cards, and a platform gap found there is +# filed in the platform repo, where it gets its area. Widening the loop is a +# vocabulary decision, not a maintenance edit. +# +# ⚠️ Every -d below is ≤100 characters (`check:pm-label-desc-cap`), and each +# names the CUSTOMER capability rather than the packages that implement it — +# the axis is read by the maintainer planning product, not by a seat routing +# files. One colour family (`c2e0c6` … `0e8a16` are taken; the axis uses one +# shade of its own, `d2dae2`, so an area label is recognisable at a glance in a +# label list that already carries `domain:*` in `bfd4f2`). +for R in objectstack-ai/objectstack objectstack-ai/objectui; do + gh label create area:records -R "$R" -c d2dae2 -d "Business objects, records, the views that show data, usable forms, search" 2>/dev/null || true + gh label create area:access -R "$R" -c d2dae2 -d "Permissions that actually hold — RLS/FLS, sharing model, write-path guards" 2>/dev/null || true + gh label create area:workflow -R "$R" -c d2dae2 -d "Approvals and automation — the work that runs without a person driving it" 2>/dev/null || true + gh label create area:reports -R "$R" -c d2dae2 -d "Business reporting — dashboards, reports, the numbers a manager reads" 2>/dev/null || true + gh label create area:identity -R "$R" -c d2dae2 -d "Login and identity — sign-up, sessions, organization membership, SSO" 2>/dev/null || true + gh label create area:api-integration -R "$R" -c d2dae2 -d "The API a customer can call, and integrations — REST, connectors, webhooks, jobs" 2>/dev/null || true + gh label create area:files -R "$R" -c d2dae2 -d "Files — upload, download, signed URLs, access derived from the parent record" 2>/dev/null || true + gh label create area:i18n -R "$R" -c d2dae2 -d "The customer's own language, across UI, metadata and notifications" 2>/dev/null || true + gh label create area:studio -R "$R" -c d2dae2 -d "Changing a running app without code — authoring, publish, docs and the portal" 2>/dev/null || true + gh label create area:ai -R "$R" -c d2dae2 -d "AI-native — agent / tool / skill metadata, and the MCP surface an agent drives" 2>/dev/null || true + gh label create area:devpath -R "$R" -c d2dae2 -d "The road — create, dev, verify, publish/install, connect an agent, iterate" 2>/dev/null || true +done + # Release board — `target:` marks a release BLOCKER for that major # (SKILL.md "发版板"). Its consumer is a named query, one per backlog: # `label:target: is:open`, and all three boards reading empty IS the From 7543240b903a103e69af9957087df73cf1709630 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 03:14:53 +0000 Subject: [PATCH 2/5] =?UTF-8?q?docs(pm-dispatch):=20domain:*=20retreats=20?= =?UTF-8?q?to=20file=20ownership=20=E2=80=94=20the=20candidate=20order=20i?= =?UTF-8?q?s=20the=20roadmap=20order,=20cross-layer=20feature=20points=20f?= =?UTF-8?q?ile=20as=20one=20parent=20plus=20per-layer=20sub-issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 3 of the charter, paid in place on a ratchet with headroom 0 on every file: SKILL.md stays at 813 lines and core-rules.md at 151. Added: the `area:*` glossary row (its four named readers, the roadmap position that the candidate order reads, and the one-feature-point-per-axis in-flight cap ride in the row, which the length rule exempts); a line in 域车道 saying `domain:*` decides file ownership and nothing else; and the cross-layer filing shape in 分诊座位职责. Paid by retiring three lines whose content has a home elsewhere: the `packages/lint` exception (the 域车道 table's own devx row and references/lanes/spec.md 范围), the seat-roster line (全体座位的不变量 plus 座位贴协议), and the multi-lane-only sweep line (多仓协调 carries both halves). Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude --- .claude/skills/pm-dispatch/SKILL.md | 16 ++++++++-------- .../skills/pm-dispatch/references/core-rules.md | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.claude/skills/pm-dispatch/SKILL.md b/.claude/skills/pm-dispatch/SKILL.md index 379f8b07e98..32ff921dc2f 100644 --- a/.claude/skills/pm-dispatch/SKILL.md +++ b/.claude/skills/pm-dispatch/SKILL.md @@ -118,6 +118,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 | `pm:epic`(父单或 sub-issue) | 已由 epic PM 保留;其它 PM 永不取;⛔ 永不与 `pm:queue` 同挂 | | `pm:seat` | 座位登记贴:协议载体,不是待分诊的工作 | | `priority:p0` | 插队:可超 `batch`、破轮次立即派发;⛔ 不豁免同文件串行、深度等待与认领协议 | +| `area:*` | 功能轴:每卡恰一个;分诊首触打,与 `domain:*` 同笔;工具卡打它所护的轴;⛔ 不回填存量。四读者:维护者按轴看板;定级继承该轴清单项;父单分组;候选顺序,即「功能点位次」= 父单在「路上的功能点」上的次序;同轴至多一个在飞,除非文件面不相交 | | open PR 引用该单 | 已实现,复核中 | | merged PR 带 `Fixes #n` | 完成(GitHub 关单) | @@ -132,7 +133,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - declared≠enforced 观察类 ⇒ 转 enforce-or-remove 通道;真 won't-fix 候选 ⇒ 逐卡进决策箱。 - 派发与折叠检查时读半状态巡查锚的 H17 触发文件索引,与本次派发文件面求交。 - 相交 ⇒ 按该 hold 评论的 rider/restart 条款处置:点名该单,顺手活列为申报过的增项。 -- 关闭即在同一笔摘掉 `pm:*` 状态标;`domain:*` 与类型标签留下,归属不是状态。 +- 关闭即在同一笔摘掉 `pm:*` 状态标;`domain:*`、`area:*` 与类型标签留下,归属不是状态。 - `state_reason` 与关闭理由一致:撤单/不做 ⇒ `not_planned`,重复 ⇒ `duplicate` + `duplicate_of`。 - `Blocked-by:` 行是机器可 grep 的反向索引,一遍读喂三个职责,⛔ 只做第一件。 - 三职责:上游关单放回解锁卡;按解锁扇出排序;在合并后的 ref 上重验回队卡文件面。 @@ -211,7 +212,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - transfer 不可用时重建:出处头 + 裸 `#N` 改全名 + 关源单为 moved。 - 缝卡收窄为真协调卡:留 objectstack 带 `repo:*`,正文点名读者(哪个座位、哪一步)。 - 决策收件箱按仓:平台在 objectstack / objectui,元数据项目在本仓;在飞卡 ⛔ 不中途转仓。 -- 规则 2:跨仓 feature 或 objectui 消费的 `Seam:` 卡恒由分诊立父单 + 每仓一子单,spec/后端先行。 +- 规则 2:跨层功能点或 objectui 消费的 `Seam:` 卡恒由分诊立父单 + 逐层子单,spec/后端先行。 - 下游带 `Blocked-by: #`;`Blocked-by` 未关闭/未合并的不派发,对 GitHub 现验。 - 被链接或同父的两单永不同批。 - pin 滞后是盲区:本仓 pin 是否已覆盖该 commit 是第二读数,派发前用 REST `compare` 核祖先。 @@ -239,7 +240,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 ## 域车道 - 锚定规则:每个包恰属一个域;`domain:*` = 修复落地包的域;`Seam:` 卡归 spec 席,默认纵向派发。 -- 唯一例外 `packages/lint` 等与 spec 相交的 devx 面:围着 spec 契约转的归 `domain:spec`,余留 devx。 +- `domain:*` 只决定文件归属:锚定、热文件串行、单认领路径;⛔ 不是队列或优先级单位。 - `Seam:` 卡认领申报两端;验收 = 消费端读该键(活性账本行离开 `planned`)或键随账本行退役。 - 域由分诊读代码判定,⛔ 绝不从 issue 标题的词汇猜域;说不出修复碰哪个文件就还不可标。 @@ -255,7 +256,6 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 | (无固定归属,按落点分诊) | `packages/apps/*`、`packages/console`(dist 由脚本生成 ⛔ 不手改;UI 缺陷走 `repo:objectui`)、`examples/*`(归它演练的子系统)、`docs/audits/**` | - 表未覆盖的包首次分诊时归类并走 PR 更新本表;新增或退役 `domain:*` 必须同批改本表。 -- 座位在编以 `label:pm:seat` 索引为准,每车道(`domain:*`/`repo:*`)一组座位贴、每席恰一张。 - `domain:*` 只由分诊席产出,例外仅在飞卡衍生 sub-issue 承父卡域;无标签的卡 ⛔ 不得认领。 - 跨域例外路径:拆不动的跨域单 PR 由分诊席指定一个车道 PM 认领,认领评论申报文件面。 - 派发前在飞检查:读本车道 `pm:dispatched` 卡认领评论申报的文件面,本地求交、不另发查询。 @@ -291,7 +291,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 ## Epic 子树车道 -- 大开发(父单 + sub-issue 树)整体委托一个专职 PM 会话:`/pm-dispatch epic:#`。 +- 大开发与跨层功能点(spec/运行时/前端)整体委托一个专职 PM 会话:`/pm-dispatch epic:#`。 - 委托信号成对落地:父单打 `pm:epic` + 正文写会话 ID 与声明的文件领地。 - epic 立卡挂父单、打 `pm:epic`,⛔ 永不 `pm:queue`;`label:pm:epic` 即父子保留全集,域座位不取。 - 队列 = 子树 open 未认领 sub-issue,每轮重读不缓存;其它 PM 候选获取跳过整棵子树。 @@ -307,7 +307,6 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 ## 分诊座位职责 -- sweep 与首触定级只对多车道仓,单车道仓机械三务自理。 - 发版板(无板仓跳过)、查重/shadow 检查与代裁通道全仓照跑。 - fire 开局只按名加载互斥检查所需工具,`ToolSearch` 用 `select:`;判定本轮有活才加载其余。 - ⛔ 分诊 fresh session 开局不做泛关键词 ToolSearch;可验判据:空转轮 ~4 万 token 以内。 @@ -365,6 +364,7 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - 清单项会 fail 才算断,继承其 `priority`;缺项先补账本;⛔「有人在等」不是定级判据。 - 路由是分诊的技术判断,⛔ 永不升级哪个仓的问题;父单是协调节点,永不派发。 - 父单已有子结构的:父单队列标签即可,分诊逐个展开路由、补 `Blocked-by:` 排序。 +- 跨层功能点(≥2 层)立父单带 `area:*`+`pm:epic`+清单项级,逐层子单按 `Blocked-by:` 排。 - 每张留一条英文审计评论(`Triage: lands in …; rationale: …`),可选带 `Size/model suggestion:` 行。 - 查重/shadow 检查先按文件/机制查本仓与姊妹仓 open 卡(含 `pm:dispatched`),再跟引用与关键词。 - 同文件同机制 = 同一发现,不分车道,首触定级即并:证据搬先卡,后卡关 `duplicate_of`。 @@ -461,9 +461,9 @@ PM 的工作是循环:选卡 → 认领 → 派发 → 收集 → 复核 → 报 - 阻塞项无主 ⇒ 被挡席认领做掉,不限大小;在该卡走完整认领、尊重其热文件串行队。 - 阻塞项在飞 ⇒ 等:`pm:blocking` 在其车道排最前、等待者写该卡;p0/p1 优先级沿链传递。 - 取卡前置 = `docs/NORTH-STAR.md`「优先级」第 3 条:产品仓开放 P0/P1 每次取卡现读。 -- 取卡全序:`priority:p0` > `pm:blocking` > `target:` 板上项 > p1 > p2 > p3 > 无级;同级先 `Bug` 再卡龄。 +- 取卡全序:`priority:p0` > `pm:blocking` > 功能点位次 > 板上项 > p1 > p2 > p3 > 无级。 - `pm:blocking` 级内先按解锁扇出(从 `Blocked-by:` 反向索引现算,⛔ 扇出数不落标签)。 -- 全序每级取既有信号现读/现算,零逐卡维护;优先非豁免;无级/缺 `Path:` 轮报记分诊缺口。 +- 全序每级现读/现算,零逐卡维护;同级先 `Bug` 再卡龄;无级/缺 `Path:` 轮报记分诊缺口。 - 解锁那一刻 PM 自己的判断最不可信:裁决收窄或关掉了那张卡是假设不是前提。 - 该假设以机制假设身份进派发令,被证伪就在同一张卡公开更正。 diff --git a/.claude/skills/pm-dispatch/references/core-rules.md b/.claude/skills/pm-dispatch/references/core-rules.md index 4efc27146ef..c6db88d87bf 100644 --- a/.claude/skills/pm-dispatch/references/core-rules.md +++ b/.claude/skills/pm-dispatch/references/core-rules.md @@ -55,15 +55,15 @@ - 多车道仓的域标签、type、定级与查重只由中央分诊生产,单车道仓自理三务不产域标签。 - 跨仓查重与 shadow 检查恒归中央 ⛔ 不下放;决策卡入本仓收件箱,在飞卡 ⛔ 不中途转仓。 - issue 住在修复落地的仓,抽掉 objectstack 仍成立的当场转仓;缝卡须带仓标签并点名读者。 -- 跨仓 feature 或跨仓 `Seam:` 卡拆成父单加每仓子单,下游带 `Blocked-by:`,上游未关 ⛔ 不派发。 +- 跨层功能点或跨仓 `Seam:` 卡拆成父单加逐层子单,下游带 `Blocked-by:`,上游未关 ⛔ 不派发。 - pin 消费的仓派发前核 pin 是否已覆盖那个提交,发布包消费的仓判据是消费方可安装。 - 上游未发版时转 hold ⛔ 不回队列;已验收产物流向另一仓由接受席立即立后续单。 - 跨座位请求即立卡进目标车道,自卡翻 `pm:blocked`;阻塞项无主由被挡席认领,在飞即等。 - 认领席跟到 MERGED,派发后的跨车道面不移卡、借隔离复核;新 spec 工作由 spec 席收口。 ## 域车道 -- 每个包恰好属于一个域,域标签 = 修复落地包的域;例外与 `Seam:` 卡见 SKILL.md 锚定规则。 +- 每个包恰好属于一个域,域标签 = 修复落地包的域,只决文件归属 ⛔ 非队列非优先级单位。 - 域由分诊读代码判定,⛔ 绝不从 issue 标题的词汇猜域;说不出修复碰哪个文件就还不可标。 -- 域到包家族的对照表住 SKILL.md,增删一个域标签必须同批改那张表。 +- 域到包家族的对照表住 SKILL.md,增删一个域标签同批改那张表;`area:*` 是功能轴,首触打。 - 域标签只由分诊席产出,例外仅在飞卡衍生 sub-issue 承父卡域;无标签的卡 ⛔ 不得认领。 - 跨域单 PR 由分诊席指定一个车道 PM 认领并申报完整文件面,在飞检查同域跨域皆跑。 - 合并队列是共享串行资源,谁发现 flake 谁修或立单,⛔ 不绕行。 @@ -105,7 +105,7 @@ - 同批独立性按文件面不相交判,⛔ 不按包;同区域硬串行,冲突交合并队列仲裁 ⛔ 不手排。 - 家族派发须过五门:同缺陷同修法、同包区域、成员皆已裁、逐成员可核、点名排除清单。 - 两张以上排队卡共享热文件时,必须以五门为判据显式回答折叠还是串行。 -- 取卡全序:插队卡、有下游依赖者的卡、板上项、p1、p2、p3、无级;同级缺陷卡先再卡龄。 +- 取卡全序:插队卡、有下游依赖的卡、功能点位次、板上项、p1-p3、无级;同级先缺陷卡。 - 认领原子对:一次标签写入完成认领与状态对调,随后留 `Claim:` 开头的评论并重读全线程。 - 更早的他会话认领即让行并交出已诊断的一切;认领逾一天且无合并证据即疑死。 - dev 自死不等于维护者中止,需显式信号;回收前先救工作树,有提交的活分支 ⛔ 永不回收。 From 420bd091703ebc91156654b96dcefcc4eb3bfdf8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 03:29:17 +0000 Subject: [PATCH 3/5] =?UTF-8?q?docs(north-star,pm-dispatch):=20the=20API?= =?UTF-8?q?=20axis=20is=20named=20area:api=20=E2=80=94=20the=20maintainer'?= =?UTF-8?q?s=20one=20amendment=20to=20the=20eleven?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The charter card's axis list was confirmed with a single rename, so the value is `area:api` in all four places it is spelled: the label row in scripts/pm/ensure-pm-labels.sh, the `axis` value in the api-backend and integration-system checklist area files, and the three roadmap lines in docs/NORTH-STAR.md. The customer capability behind it is unchanged. The label block's rows are re-padded to the new longest id, and its comment records the amendment WITHOUT writing the retired spelling: a grep for the old name must not find a live-looking value, so the maintainer's sentence is cited on the card's ruling comment rather than quoted here. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude --- docs/NORTH-STAR.md | 6 ++-- .../platform-checklist/areas/api-backend.json | 2 +- .../areas/integration-system.json | 2 +- scripts/pm/ensure-pm-labels.sh | 28 +++++++++++-------- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/docs/NORTH-STAR.md b/docs/NORTH-STAR.md index 7dd271d623a..e5e03262e1f 100644 --- a/docs/NORTH-STAR.md +++ b/docs/NORTH-STAR.md @@ -22,16 +22,16 @@ - access · 匿名请求在每个挂出来的 API 家族都统一按未认证拒绝,先于任何资源解析 · access-security.anonymous-deny-surfaces · P3 - access · 没有活跃组织的会话是合法状态,且失败向关,永不写空租户 · access-security.no-active-org-session-semantics · P3 - workflow · 非管理员从自己的应用进得去完整的审批收件箱 · approvals.account-app-entry · P3 -- api-integration · 数据 API 的查询契约:每个过滤算子答案已知,错的输入响亮拒绝 · api-backend.query-contract-matrix · P3 +- api · 数据 API 的查询契约:每个过滤算子答案已知,错的输入响亮拒绝 · api-backend.query-contract-matrix · P3 - devpath · 一条命令把应用跑起来:能登录、数据库选择诚实、端口与陈旧都说出来 · cli.dev-boot-contract · P3 - devpath · 起来就是干净的:健康与就绪都通,没有降级横幅,控制台与应用元数据都供得上 · platform-core.boot-health · P3 - devpath · 种子数据原样落库,重放不多不少 · platform-core.seed-integrity · P3 - devpath · 管理员从控制台登得进去,刷新后会话还在,过期后重新认证干净 · platform-core.console-login · P3 - devpath · 每个导航面都渲染得出来,坏了也看得见错误边界,不是白屏 · platform-core.nav-surfaces-render · P3 - devpath · 自带的应用(Setup / Account)每个菜单目标都打得开,门是挡不是报错 · platform-core.builtin-apps-nav-render · P3 -- api-integration · 数据源密钥写不进去也读不出来:内联即拒,两道读口都打码 · integration-system.datasource-credential-refusal-matrix · P4 +- api · 数据源密钥写不进去也读不出来:内联即拒,两道读口都打码 · integration-system.datasource-credential-refusal-matrix · P4 - workflow · 停用一个随包发的流程,冷重启之后它还是停的 · automation.packaged-flow-disable-durable · P5 -- api-integration · 停用的随包动作在两道派发门都被拒,且拒得出于开关而非权限 · api-backend.packaged-action-disabled-dispatch · P5 +- api · 停用的随包动作在两道派发门都被拒,且拒得出于开关而非权限 · api-backend.packaged-action-disabled-dispatch · P5 - ai · 没有密钥 MCP 就不起;拿成员的密钥连上,读与聚合都照他的权限走,吊销下一次调用即生效 · ai.mcp-stdio-fail-closed · P6 **优先级**: diff --git a/docs/qa/platform-checklist/areas/api-backend.json b/docs/qa/platform-checklist/areas/api-backend.json index 66cfc5eaadd..81e3e69f6ab 100644 --- a/docs/qa/platform-checklist/areas/api-backend.json +++ b/docs/qa/platform-checklist/areas/api-backend.json @@ -1,7 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md.", "area": "api-backend", - "axis": "api-integration", + "axis": "api", "title": "REST / batch / formula / build-time gates", "items": [ { diff --git a/docs/qa/platform-checklist/areas/integration-system.json b/docs/qa/platform-checklist/areas/integration-system.json index 6bd8797f077..8c5d0ea43d9 100644 --- a/docs/qa/platform-checklist/areas/integration-system.json +++ b/docs/qa/platform-checklist/areas/integration-system.json @@ -1,7 +1,7 @@ { "$comment": "Standing platform test checklist — area ledger. Hand-edited, append-only; validated by scripts/check-platform-checklist.mjs (pnpm check:platform-checklist). Authoring rules: docs/qa/platform-checklist/README.md · execution protocol: RUNNER.md. FIXTURE MAP for this area (all in-repo, CI-deterministic): the showcase ships four declarative connectors (examples/app-showcase/src/system/connectors/index.ts — rest/openapi/mcp provider-bound instances + one enabled:false catalog descriptor), an outbound webhook (src/automation/webhooks — shipped inactive), a cron job (src/automation/jobs — showcase_health_sweep), an email template (src/system/emails — showcase_task_done_email) and two notify flows (src/automation/flows).", "area": "integration-system", - "axis": "api-integration", + "axis": "api", "title": "Integration & system services — connectors, webhooks, jobs, email templates, notifications", "items": [ { diff --git a/scripts/pm/ensure-pm-labels.sh b/scripts/pm/ensure-pm-labels.sh index 19c5c5d63b5..50142a82a08 100644 --- a/scripts/pm/ensure-pm-labels.sh +++ b/scripts/pm/ensure-pm-labels.sh @@ -470,6 +470,12 @@ gh label create domain:ui -R objectstack-ai/objectui -c bfd4f2 -d "objectui ui # seat may claim which files. The eleven values are the North Star definition # line (「做出来的是什么」) plus the road it measures, so the axis and the # product definition cannot drift apart without one of them being edited. +# The eleven were put to the maintainer on the charter card and confirmed there +# (2026-09-21) with ONE amendment: the API/integration value was shortened to +# `area:api`, its customer capability (可对外的 API 与集成) unchanged. ⛔ The +# longer spelling this replaced is deliberately NOT written here — the retired +# name must not survive a `git grep` as though it were still a value. The +# maintainer's sentence is quoted verbatim on that card's ruling comment. # # Triage applies it at FIRST GRADING, in the same label write as `domain:*` and # `priority:*`; a filer may pre-apply it; a tooling card carries the area it @@ -498,17 +504,17 @@ gh label create domain:ui -R objectstack-ai/objectui -c bfd4f2 -d "objectui ui # shade of its own, `d2dae2`, so an area label is recognisable at a glance in a # label list that already carries `domain:*` in `bfd4f2`). for R in objectstack-ai/objectstack objectstack-ai/objectui; do - gh label create area:records -R "$R" -c d2dae2 -d "Business objects, records, the views that show data, usable forms, search" 2>/dev/null || true - gh label create area:access -R "$R" -c d2dae2 -d "Permissions that actually hold — RLS/FLS, sharing model, write-path guards" 2>/dev/null || true - gh label create area:workflow -R "$R" -c d2dae2 -d "Approvals and automation — the work that runs without a person driving it" 2>/dev/null || true - gh label create area:reports -R "$R" -c d2dae2 -d "Business reporting — dashboards, reports, the numbers a manager reads" 2>/dev/null || true - gh label create area:identity -R "$R" -c d2dae2 -d "Login and identity — sign-up, sessions, organization membership, SSO" 2>/dev/null || true - gh label create area:api-integration -R "$R" -c d2dae2 -d "The API a customer can call, and integrations — REST, connectors, webhooks, jobs" 2>/dev/null || true - gh label create area:files -R "$R" -c d2dae2 -d "Files — upload, download, signed URLs, access derived from the parent record" 2>/dev/null || true - gh label create area:i18n -R "$R" -c d2dae2 -d "The customer's own language, across UI, metadata and notifications" 2>/dev/null || true - gh label create area:studio -R "$R" -c d2dae2 -d "Changing a running app without code — authoring, publish, docs and the portal" 2>/dev/null || true - gh label create area:ai -R "$R" -c d2dae2 -d "AI-native — agent / tool / skill metadata, and the MCP surface an agent drives" 2>/dev/null || true - gh label create area:devpath -R "$R" -c d2dae2 -d "The road — create, dev, verify, publish/install, connect an agent, iterate" 2>/dev/null || true + gh label create area:records -R "$R" -c d2dae2 -d "Business objects, records, the views that show data, usable forms, search" 2>/dev/null || true + gh label create area:access -R "$R" -c d2dae2 -d "Permissions that actually hold — RLS/FLS, sharing model, write-path guards" 2>/dev/null || true + gh label create area:workflow -R "$R" -c d2dae2 -d "Approvals and automation — the work that runs without a person driving it" 2>/dev/null || true + gh label create area:reports -R "$R" -c d2dae2 -d "Business reporting — dashboards, reports, the numbers a manager reads" 2>/dev/null || true + gh label create area:identity -R "$R" -c d2dae2 -d "Login and identity — sign-up, sessions, organization membership, SSO" 2>/dev/null || true + gh label create area:api -R "$R" -c d2dae2 -d "The API a customer can call, and integrations — REST, connectors, webhooks, jobs" 2>/dev/null || true + gh label create area:files -R "$R" -c d2dae2 -d "Files — upload, download, signed URLs, access derived from the parent record" 2>/dev/null || true + gh label create area:i18n -R "$R" -c d2dae2 -d "The customer's own language, across UI, metadata and notifications" 2>/dev/null || true + gh label create area:studio -R "$R" -c d2dae2 -d "Changing a running app without code — authoring, publish, docs and the portal" 2>/dev/null || true + gh label create area:ai -R "$R" -c d2dae2 -d "AI-native — agent / tool / skill metadata, and the MCP surface an agent drives" 2>/dev/null || true + gh label create area:devpath -R "$R" -c d2dae2 -d "The road — create, dev, verify, publish/install, connect an agent, iterate" 2>/dev/null || true done # Release board — `target:` marks a release BLOCKER for that major From 16418377774926fc3602f6a5649811557e24f21a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 04:23:33 +0000 Subject: [PATCH 4/5] =?UTF-8?q?docs(north-star):=20=E3=80=8C=E8=B7=AF?= =?UTF-8?q?=E4=B8=8A=E7=9A=84=E5=8A=9F=E8=83=BD=E7=82=B9=E3=80=8D=20is=20t?= =?UTF-8?q?he=20platform's=20feature=20map,=20not=20a=20to-do=20list=20?= =?UTF-8?q?=E2=80=94=20every=20checklist=20item=20belongs=20to=20exactly?= =?UTF-8?q?=20one=20feature=20point?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maintainer read the first version and said it looked like a handful of issues rather than the platform's feature list. It was: one card plus the checklist's currently-failing P0 items. This rewrites the section as the whole feature map. Six blocks, one per step of the road the North Star already measures, and inside each block one line per feature point at capability level — a customer-visible capability that runs from the protocol through the runtime to the frontend. The end-user capabilities (records, access, workflow, reports, identity, files, i18n) sit at the step where the road first needs them, which is where the app is first run and seen. The completeness claim is mechanical, not editorial: the feature points are derived by grouping every item in docs/qa/platform-checklist/areas/*.json so that each item belongs to exactly one line — 264 items on disk, 264 mapped, zero unmapped, zero double-mapped, zero ids the ledger does not have. The per-item listing is on the card. The 路步 column is gone (the block position is the step), the docs-authoring feature keeps its 「清单项待写」 slot, and the page's own rules hold: no counts, no pass/fail status, no new headings, and the ledger is still not copied here. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude --- docs/NORTH-STAR.md | 118 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 23 deletions(-) diff --git a/docs/NORTH-STAR.md b/docs/NORTH-STAR.md index e5e03262e1f..51cee6cf4e9 100644 --- a/docs/NORTH-STAR.md +++ b/docs/NORTH-STAR.md @@ -10,29 +10,101 @@ **唯一的度量,那条路**:一个新的 AI 开发者(人在旁验收)从 `npm create objectstack` 出发:写元数据 → 本地跑起来、看到 → 验证响亮拒绝错的、放行对的 → 发布并装进一个环境 → 接一个 Agent(社区版走 MCP),让它在应用里完成一次真实业务操作 → 按客户一句话需求迭代一次。每周真走一遍,结果落一张 run record。第一个断掉的步骤就是当前的 P0;跑得通但结果错的是 P2。 -**路上的功能点**:这条路上要做的功能点,自上而下就是顺序 —— 这张表就是路线图,改它即改优先级。每行 `轴 · 功能点(业务语言) · 清单项 id · 路步(P 后面是那条路的第几步)`。 - -- studio · 管理员在界面里写 Markdown 文档并加到菜单(含 book) · 清单项待写 · P2 -- studio · 不写代码走完建包 → 建对象 → 记录 → 应用 → 发布 → 终端用户,零重启 · studio-authoring.first-run-loop · P2 -- records · 在界面里把一条记录建出来、看见、改掉、删掉 · records-forms.crud-roundtrip · P3 -- access · 受限成员只看得到自己的行,管理员看得到全部 · access-security.rls-both-sides · P3 -- access · 写入挡得住:只读字段被剥、伪造与转移 owner 被拒、批量照验 · access-security.write-path-guards · P3 -- access · 每个权限集的增删改查逐格兑现,收回的动作真的被拒 · access-security.crud-permission-matrix · P3 -- access · 四种共享模型各自声明的基线都挡得住 · access-security.owd-sharing-matrix · P3 -- access · 匿名请求在每个挂出来的 API 家族都统一按未认证拒绝,先于任何资源解析 · access-security.anonymous-deny-surfaces · P3 -- access · 没有活跃组织的会话是合法状态,且失败向关,永不写空租户 · access-security.no-active-org-session-semantics · P3 -- workflow · 非管理员从自己的应用进得去完整的审批收件箱 · approvals.account-app-entry · P3 -- api · 数据 API 的查询契约:每个过滤算子答案已知,错的输入响亮拒绝 · api-backend.query-contract-matrix · P3 -- devpath · 一条命令把应用跑起来:能登录、数据库选择诚实、端口与陈旧都说出来 · cli.dev-boot-contract · P3 -- devpath · 起来就是干净的:健康与就绪都通,没有降级横幅,控制台与应用元数据都供得上 · platform-core.boot-health · P3 -- devpath · 种子数据原样落库,重放不多不少 · platform-core.seed-integrity · P3 -- devpath · 管理员从控制台登得进去,刷新后会话还在,过期后重新认证干净 · platform-core.console-login · P3 -- devpath · 每个导航面都渲染得出来,坏了也看得见错误边界,不是白屏 · platform-core.nav-surfaces-render · P3 -- devpath · 自带的应用(Setup / Account)每个菜单目标都打得开,门是挡不是报错 · platform-core.builtin-apps-nav-render · P3 -- api · 数据源密钥写不进去也读不出来:内联即拒,两道读口都打码 · integration-system.datasource-credential-refusal-matrix · P4 -- workflow · 停用一个随包发的流程,冷重启之后它还是停的 · automation.packaged-flow-disable-durable · P5 -- api · 停用的随包动作在两道派发门都被拒,且拒得出于开关而非权限 · api-backend.packaged-action-disabled-dispatch · P5 -- ai · 没有密钥 MCP 就不起;拿成员的密钥连上,读与聚合都照他的权限走,吊销下一次调用即生效 · ai.mcp-stdio-fail-closed · P6 +**路上的功能点**:平台要做出来的功能点,一行一个,按那条路的步骤排;自上而下就是顺序 —— 这张表就是路线图,改它即改优先级。每行 `轴 · 功能点(业务语言) · 清单区 · 项 id`,一个功能点从协议到运行时到前端是一整条;`docs/qa/platform-checklist/` 里的每一项都恰好属于这里的一行(未写的项标「清单项待写」)。id 不带前缀时属于它前面那个清单区,跨区的写全名。 + +**① 出发:`npm create objectstack` 起项目,写元数据** + +- devpath · 一条命令起一个项目:脚手架、装好、验证通过、控制台首屏画得出来 · cli · scaffold-first-run, scaffold-console-first-paint +- devpath · 构建是作者的第一道关:错误带位置,产物与统计出得来 · cli · build-own-contract +- devpath · 写进元数据的代码片段有边界:钩子与动作体拒绝越界写法 · cli · hook-body-extraction-gates +- studio · 不写代码建对象、字段、列表、表单与记录页 · studio-authoring · object-designer-roundtrip, view-authoring-live, record-page-roundtrip +- studio · 自定义页面:块组合、页面变量与页面级动作、三档源码 · studio-authoring · custom-page-render-and-blocks, page-variables-and-actions, custom-page-source-tiers +- studio · 先草稿后发布:发布是原子的,冲突与非法草稿当场被拒 · studio-authoring · draft-publish-lifecycle, authoring-validation-not-persisted +- studio · Studio 的判定与边界:表达式与引擎一致、权限矩阵编得动、注册表决定什么能在运行中改 · studio-authoring · expression-editors, permission-matrix-editor-ux, org-override-registry-gate +- studio · 管理员在界面里写 Markdown 文档并加到菜单(含 book),按受众发布成门户 · studio-authoring + platform-core · 清单项待写, platform-core.docs-audience-gate, platform-core.docs-portal-render + +**② 本地跑起来、看到 —— 终端用户在应用里用到的能力,都在这一步第一次被需要** + +- devpath · 一条命令把应用跑起来:健康与就绪都通、数据库选择诚实、端口与陈旧都说出来 · cli + platform-core · dev-boot-contract, platform-core.boot-health, platform-core.runtime-config-boot-read +- devpath · 种子数据原样落库,重放不多不少 · platform-core · seed-integrity, seed-mode-matrix +- devpath · 登得进去,外壳记得住:导航、自带应用、收藏与最近、主题、快捷键、返回键 · platform-core · console-login, nav-surfaces-render, builtin-apps-nav-render, shell-nav-personalization, theme-mode-persistence, keyboard-shortcut-surface, url-overlay-contract, home-admin-cluster-links, console-installability-indicators, app-management-toggle +- devpath · 平台设置在界面里改:改完真的生效、留痕、密钥只存句柄 · platform-core · settings-hub-roundtrip +- devpath · 元数据注册表对外可读,只有可写的包改得动 · platform-core · metadata-registry-serving, metadata-authoring-roundtrip +- records · 一条记录建出来、看见、改掉、删掉,也能照着再建一条 · records-forms · crud-roundtrip, record-clone-contract +- records · 每种字段都渲染得出、收得下、存得住,错的当场拒 · records-forms · field-type-matrix, field-type-constraints, field-unique-enforcement, encrypted-field-behavior +- records · 列表能干活:筛选、搜索、排序、分页、保存视图、行内编辑、导出、批量 · records-forms · list-view-capabilities, view-type-gallery, adhoc-filter-sort-builder, grid-personalization, saved-view-management, bulk-select-all-matching +- records · 看板、日历、甘特是能拖的,不是图片 · records-forms · kanban-drag-persistence, calendar-interactions, gantt-interactions +- records · 表单能用:布局、脏数据守卫、联动显示与必填、级联选项 · records-forms · form-view-gallery, form-dirty-guard, conditional-rules-header, conditional-rules-grid, cascading-options, cascading-multilevel-and-clear, field-group-visible-when +- records · 主从一起存、相关列表在服务端分页、查找框里顺手新建 · records-forms · master-detail-atomic-save, related-list-server-pagination, lookup-picker-create-new +- records · 写入规则在服务端兑现,撞车响亮、后悔得了、改过什么看得见 · records-forms · validation-rule-type-matrix, object-hook-lifecycle, delete-behavior-matrix, concurrent-edit-conflict, record-edit-undo, field-history-tracking +- records · 记录上的动作与协作:按钮在声明的位置、参数契约在派发时兑现、讨论与 @ 提醒 · records-forms · action-location-matrix, action-param-widgets, upload-guard-blocks-confirm, record-discussion-mentions +- records · 搜得到:跨字段、字段限定、权限一致、拼音、即时新鲜;全局搜索与命令面板同一条路 · search · cross-field-object-search, field-scoped-narrowing, rls-both-personas, pinyin-flag-both-sides, freshness-and-empty, console-global-search, command-palette-navigation +- access · 行级与字段级权限两边都对:受限成员只看自己的,该只读的只读、该看不见的不回给前端 · access-security · rls-both-sides, scope-depth-asymmetry, fls-mask-and-strip +- access · 增删改查逐格兑现,改完权限立刻换脸,自查接口与服务端一致 · access-security · crud-permission-matrix, permission-matrix-edit-loop, me-permissions-aggregation-parity +- access · 写入路径挡得住:只读剥离、伪造与转移 owner 被拒、默认可见度只能收紧 · access-security · write-path-guards, owd-save-gate +- access · 共享:默认基线、规则放宽、单条手工共享、建议的绑定 · access-security · owd-sharing-matrix, sharing-rules-widen, record-share-grant-revoke, sharing-rule-authoring-ui, suggested-binding-loop +- access · 匿名进不来:每个 API 家族统一拒,且先于任何资源解析;没有活跃组织也是合法状态 · access-security · anonymous-deny-surfaces, no-active-org-session-semantics +- access · 对外开的小门:公开表单与分享链接,能收回、不泄露 · access-security · public-form-intake, share-link-capability-tokens, share-link-landing-page +- access · 说得清也查得到:逐层归因的访问解释、审计浏览、记录查看留痕、平台管理员身份本身挡得住 · access-security · record-access-explain, audit-log-browser, record-view-read-audit, platform-owner-email-anchor +- identity · 登录方式按配置开关,广告出来的就是真能用的 · identity-auth · auth-method-matrix, sso-enforced-first-paint, phone-signin-surfaces +- identity · 第一次装好就有主人:零用户首跑、注册闸门、邮箱验证 · identity-auth · first-run-owner-bootstrap, self-signup-gate, email-verification-loop +- identity · 自己回得来、自己改得动:忘了密码、改资料、看得见也收得回会话 · identity-auth · self-service-password-reset, self-service-profile-password, session-list-revoke +- identity · 两步验证:开启、验证、备份码、关闭 · identity-auth · two-factor-enrollment-reveal, two-factor-verify-to-activate, two-factor-backup-codes, two-factor-disable-lifecycle +- identity · 组织、团队与业务单元,以及管理员的用户运维 · identity-auth · org-membership-team-management, teams-bu-membership, invitation-scope-gates, workspace-org-switch, admin-lifecycle-operations, identity-import-wizard +- identity · 对外身份:OAuth 授权与社交账号绑定 · identity-auth · oauth-app-consent-loop, linked-accounts-social +- workflow · 审批走得完:会签、法定人数、动态审批人、超时升级、请假代理 · approvals · per-group-signoff, quorum-m-of-n, dynamic-approver-routing, sla-escalation, ooo-delegation-reroute, approver-resolution-matrix +- workflow · 审批在界面里做:收件箱、记录页按钮、键盘流、待办计数、通知直达 · approvals · inbox-metadata-actions, viewer-gating-submitter-side, record-page-decisions, inbox-keyboard-flow, pending-count-surfaces, account-app-entry, setup-nav-entry, notification-deep-link +- workflow · 审批的每个动作都由服务端状态机兜底,邮件一键也是同一条路 · approvals · decision-action-matrix, decision-only-via-service, status-mirror-field, email-action-token-door +- workflow · 流程跑得起来:节点类型、触发类型、运行树与日志 · automation · flow-node-type-matrix, trigger-type-matrix, flow-run-step-nesting, flow-runs-page-test-trigger, trigger-status-contract +- workflow · 流程的出错、暂停与定时:try/catch、屏幕流、冷重启接着跑、汇总与时间触发、开关即刹车 · automation · flow-error-handling, screen-flow-roundtrip, durable-suspend-restart, rollup-summary-filter, time-relative-trigger, flow-toggle-kill-switch +- reports · 图表画得出来、类型齐、空数据体面、写错的键响亮;钻得下去、全局筛选重新取数 · dashboards · chart-first-paint, chart-type-matrix, empty-null-bucket-boundaries, strict-widget-rejects-stray-keys, drill-through-range, global-filters-rescope +- reports · 报表自己建、自己存、只归自己,还能按时自己发出去 · dashboards · dataset-report-authoring, saved-report-ownership, report-schedule-dispatch-delivery +- reports · 经营数字对得上:系统总览与分析立方体 · dashboards · system-overview-live-counts, cube-query +- files · 传得上、下得来,权限跟着父记录走 · attachments-storage · presigned-upload-roundtrip, download-authz-both-sides, read-inherits-parent-rls, attach-requires-parent-edit +- files · 文件的一生与表单里的文件格:提交、墓碑、回收、续传,大小与类型服务端再验一次 · attachments-storage · sys-file-status-pipeline, orphan-tombstone-reap, upload-session-abort, inline-grid-receipt-cells, field-accept-maxsize-server-enforced +- i18n · 整个应用说客户的语言,Studio 跟着切,通知也落到对的语言 · i18n · surface-matrix, studio-follows-app-locale, notification-localized-and-clears +- api · 查询契约:算子、参数、聚合、日期窗口都有已知答案 · api-backend · query-contract-matrix, aggregate-contract-matrix, date-range-preset-matrix, filter-comparand-conformance +- api · 批量与写入门逐行有结果;错误信封与路由台账:码是登记过的,挂出来的就是真在跑的 · api-backend · bulk-write-contract, batch-transactional-discovery, error-envelope-ledger, route-ledger-live-parity +- api · 自己声明的 API 端点挂成真 URL,开发者控制台里当场试得通 · api-backend · declarative-endpoint-execution, api-console-discovery-execute +- api · REST 面的构造契约:开关决定挂什么;公式与计时也归同一份契约管 · api-backend · rest-crud-config-contract, rest-batch-config-contract, rest-metadata-config-contract, rest-route-generation-tombstones, api-methods-verb-gate, server-timing-admin-gated, formula-gates, formula-stdlib-matrix +- api · 连上外部系统:连接器声明式落地、坏了只降级一个、鉴权与命令白名单、流程里调得到 · integration-system + automation · connector-declarative-boot, connector-degraded-recovery, connector-stdio-default-deny, connector-spec-path-no-escape, connector-descriptor-audit, connector-auth-kind-application, flow-connector-picker, automation.connector-dispatch-matrix +- api · 外部数据源接进来当自己的对象用,密钥写不进也读不出 · integration-system + cli · external-datasource-federated-read, external-schema-introspection, external-schema-drift-gate, external-schema-browser-ui, datasource-admin-lifecycle, datasource-credential-refusal-matrix, cli.datasource-introspect-codegen +- api · 往外发、往里收:webhook、定时任务、邮件模板、收件箱投递与订阅偏好、铃铛已读 · integration-system + platform-core · webhook-lifecycle, job-scheduled-run, email-template-render, notify-inbox-delivery, notification-preference-suppression, platform-core.notification-center + +**③ 验证:响亮拒绝错的,放行对的** + +- devpath · `objectstack verify` 的判词是封闭的,失败才非零退出;质量套件跑在真应用上 · cli · verify-verdict-exit-mapping, qa-suite-execution +- devpath · 体检与弃用扫描:每项都有归属,说得出处方 · cli · doctor-health-report, doctor-deprecation-scan +- devpath · lint 的严重度是封闭的,只有错误才拦;命令用错了要响亮 · cli · lint-severity-exit-contract, flag-command-error-ux +- api · 写错的元数据在作者的门口就被拒,并给处方 · api-backend · enforce-or-remove-authoring-gates, retired-def-refusal +- i18n · 翻译键写错了两个门都拒,构建门禁能变红 · i18n · strict-translation-key-rejection, build-gates-hold +- studio · 存量元数据的体检:逐条报出不合规与位置 · studio-authoring · metadata-diagnostics-sweep + +**④ 发布并装进一个环境** + +- devpath · 打成插件:清单在打包边界就被强制 · cli · plugin-manifest-build-contract +- devpath · 装进来:兼容性、命名空间、启停与卸载,REST 侧同一套生命周期 · platform-core + api-backend · manifest-install-contract, package-lifecycle-enable-disable, api-backend.package-rest-lifecycle +- devpath · 从市场装:有没有控制面都装得上,界面不说谎 · platform-core · marketplace-install-local-lifecycle, marketplace-console-honesty +- devpath · 迁移:先看计划再动手,中断了说得出下一步,老写法给得出改法 · cli + platform-core · migrate-plan-apply-json, migrate-meta-codemod, migrate-duplicates-inventory, platform-core.interrupted-migration-boot-report +- devpath · 随包发来的对象只能扩不能改,启停逐条记在激活台账上;过期数据按保留期回收 · platform-core + access-security · packaged-object-extend-only, activation-ledger-registration-home, activation-ledger-row-contract, lifecycle-retention-sweep, access-security.activation-write-operator-gate +- workflow · 随包发的流程与动作:停用要持久、被依赖时拒绝、可克隆、两道门一样严 · automation + api-backend + access-security · packaged-flow-disable-durable, packaged-flow-subflow-disable-refusal, packaged-flow-clone-contract, setup-packaged-automation-board, api-backend.packaged-action-disabled-dispatch, api-backend.action-activation-door-contract, access-security.packaged-flow-write-door-parity +- access · 装进来的包带着它声明的能力与权限集,只读的包锁住 Studio · access-security + studio-authoring · capability-declaration-lifecycle, packaged-permission-set-lifecycle, readonly-package-locks-studio, studio-authoring.packaged-automation-studio-lock +- studio · 随包发来的视图与仪表盘,是可以直接改的那一类 · studio-authoring · packaged-display-class-direct-edit + +**⑤ 接一个 Agent(社区版走 MCP),让它完成一次真实业务操作** + +- ai · agent / tool / skill 元数据写得进、列得出,退役键给处方 · ai · agent-tool-skill-metadata-roundtrip +- ai · MCP 面按文档开关:HTTP 与 stdio 两条路都失败向关 · ai · mcp-http-surface, mcp-stdio-fail-closed +- ai · Agent 能做的就是应用真能做的:动作先开口子,表达式当场校验 · ai · mcp-run-action-exposure-gate, mcp-validate-expression +- ai · 技能说明书投到 MCP 的提示上 · ai · skill-instructions-mcp-prompts +- ai · 社区版没有的就诚实说没有,界面也不摆空架子 · ai · open-edition-honest-degradation, console-ai-surface-gating +- identity · 给 Agent 一把个人密钥:只显示一次,能撤也能恢复 · identity-auth · api-key-ui-lifecycle + +**⑥ 按客户一句话需求迭代一次** + +- studio · 首跑闭环:建包 → 建对象 → 记录 → 应用 → 发布 → 终端用户,零代码零重启 · studio-authoring · first-run-loop +- records · 把客户的存量数据搬进来:编码、映射、转换、撤销与取消 · records-forms · import-wizard-encoding-and-hints, named-import-mapping, import-job-undo-cancel, import-transform-matrix +- devpath · 迭代带来的结构变化:dev 启动只自愈安全的那部分,生产不自作主张 · cli · dev-automigrate-policy **优先级**: 1. 安全与数据完整性永远最高,不等路。 From 410c37f7108c69c44601771e6ab2d6477e054a4e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 21 Sep 2026 04:53:52 +0000 Subject: [PATCH 5/5] docs(north-star): the formula engine is its own feature point, and retention leaves the packaged-object line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two lines the round-3 review judged wrong about what they describe, fixed in the map rather than in the prose alone. The CEL formula items pin the formula engine — the stdlib's registered functions answering known values against the built package, and date-arithmetic failing at build time — not RestServerConfig's construction contract, so they get their own line and the REST line drops 公式. 计时 stays there because the Server-Timing item really does sit on it, beside the verb gate. The ADR-0057 lifecycle sweep is telemetry retention, not packaged-artifact governance; it moves to its own ops line in the step where the app is running and off the packaged-object / activation-ledger line, whose wording loses the clause with it. Nothing else in the section moved: every one of the checklist's items is still on exactly one line, four fields per line, no digits, no new headings. Claude-Session: https://claude.ai/code/session_012GcsUbuqFGBibkEDMRC1eE Co-authored-by: Claude --- docs/NORTH-STAR.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/NORTH-STAR.md b/docs/NORTH-STAR.md index 51cee6cf4e9..50d7aecacd2 100644 --- a/docs/NORTH-STAR.md +++ b/docs/NORTH-STAR.md @@ -29,6 +29,7 @@ - devpath · 种子数据原样落库,重放不多不少 · platform-core · seed-integrity, seed-mode-matrix - devpath · 登得进去,外壳记得住:导航、自带应用、收藏与最近、主题、快捷键、返回键 · platform-core · console-login, nav-surfaces-render, builtin-apps-nav-render, shell-nav-personalization, theme-mode-persistence, keyboard-shortcut-surface, url-overlay-contract, home-admin-cluster-links, console-installability-indicators, app-management-toggle - devpath · 平台设置在界面里改:改完真的生效、留痕、密钥只存句柄 · platform-core · settings-hub-roundtrip +- devpath · 遥测与生命周期数据按保留期回收,声明了归档的对象绝不热删 · platform-core · lifecycle-retention-sweep - devpath · 元数据注册表对外可读,只有可写的包改得动 · platform-core · metadata-registry-serving, metadata-authoring-roundtrip - records · 一条记录建出来、看见、改掉、删掉,也能照着再建一条 · records-forms · crud-roundtrip, record-clone-contract - records · 每种字段都渲染得出、收得下、存得住,错的当场拒 · records-forms · field-type-matrix, field-type-constraints, field-unique-enforcement, encrypted-field-behavior @@ -66,7 +67,8 @@ - api · 查询契约:算子、参数、聚合、日期窗口都有已知答案 · api-backend · query-contract-matrix, aggregate-contract-matrix, date-range-preset-matrix, filter-comparand-conformance - api · 批量与写入门逐行有结果;错误信封与路由台账:码是登记过的,挂出来的就是真在跑的 · api-backend · bulk-write-contract, batch-transactional-discovery, error-envelope-ledger, route-ledger-live-parity - api · 自己声明的 API 端点挂成真 URL,开发者控制台里当场试得通 · api-backend · declarative-endpoint-execution, api-console-discovery-execute -- api · REST 面的构造契约:开关决定挂什么;公式与计时也归同一份契约管 · api-backend · rest-crud-config-contract, rest-batch-config-contract, rest-metadata-config-contract, rest-route-generation-tombstones, api-methods-verb-gate, server-timing-admin-gated, formula-gates, formula-stdlib-matrix +- api · REST 面的构造契约:开关决定挂什么、哪些动词准过,计时只对管理员开 · api-backend · rest-crud-config-contract, rest-batch-config-contract, rest-metadata-config-contract, rest-route-generation-tombstones, api-methods-verb-gate, server-timing-admin-gated +- api · 公式引擎:标准库函数逐个给出已知答案,写错的表达式在构建时就被挡下 · api-backend · formula-stdlib-matrix, formula-gates - api · 连上外部系统:连接器声明式落地、坏了只降级一个、鉴权与命令白名单、流程里调得到 · integration-system + automation · connector-declarative-boot, connector-degraded-recovery, connector-stdio-default-deny, connector-spec-path-no-escape, connector-descriptor-audit, connector-auth-kind-application, flow-connector-picker, automation.connector-dispatch-matrix - api · 外部数据源接进来当自己的对象用,密钥写不进也读不出 · integration-system + cli · external-datasource-federated-read, external-schema-introspection, external-schema-drift-gate, external-schema-browser-ui, datasource-admin-lifecycle, datasource-credential-refusal-matrix, cli.datasource-introspect-codegen - api · 往外发、往里收:webhook、定时任务、邮件模板、收件箱投递与订阅偏好、铃铛已读 · integration-system + platform-core · webhook-lifecycle, job-scheduled-run, email-template-render, notify-inbox-delivery, notification-preference-suppression, platform-core.notification-center @@ -86,7 +88,7 @@ - devpath · 装进来:兼容性、命名空间、启停与卸载,REST 侧同一套生命周期 · platform-core + api-backend · manifest-install-contract, package-lifecycle-enable-disable, api-backend.package-rest-lifecycle - devpath · 从市场装:有没有控制面都装得上,界面不说谎 · platform-core · marketplace-install-local-lifecycle, marketplace-console-honesty - devpath · 迁移:先看计划再动手,中断了说得出下一步,老写法给得出改法 · cli + platform-core · migrate-plan-apply-json, migrate-meta-codemod, migrate-duplicates-inventory, platform-core.interrupted-migration-boot-report -- devpath · 随包发来的对象只能扩不能改,启停逐条记在激活台账上;过期数据按保留期回收 · platform-core + access-security · packaged-object-extend-only, activation-ledger-registration-home, activation-ledger-row-contract, lifecycle-retention-sweep, access-security.activation-write-operator-gate +- devpath · 随包发来的对象只能扩不能改,启停逐条记在激活台账上 · platform-core + access-security · packaged-object-extend-only, activation-ledger-registration-home, activation-ledger-row-contract, access-security.activation-write-operator-gate - workflow · 随包发的流程与动作:停用要持久、被依赖时拒绝、可克隆、两道门一样严 · automation + api-backend + access-security · packaged-flow-disable-durable, packaged-flow-subflow-disable-refusal, packaged-flow-clone-contract, setup-packaged-automation-board, api-backend.packaged-action-disabled-dispatch, api-backend.action-activation-door-contract, access-security.packaged-flow-write-door-parity - access · 装进来的包带着它声明的能力与权限集,只读的包锁住 Studio · access-security + studio-authoring · capability-declaration-lifecycle, packaged-permission-set-lifecycle, readonly-package-locks-studio, studio-authoring.packaged-automation-studio-lock - studio · 随包发来的视图与仪表盘,是可以直接改的那一类 · studio-authoring · packaged-display-class-direct-edit