Repository navigation
[ruled] 应用仓基本原则落编:阻塞是平台缺陷时,应用侧等待平台修复 —— ⛔ 不绕行、不半边落地(维护者 2026-08-31,判例 hotcrm#549) #13848
Description
Activity
huangyiirene commented
on Aug 31, 2026 CollaboratorAuthorMore actions补录:同日第二、三条基本原则(维护者 2026-08-31)—— 本卡落编范围扩为三条
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t本卡立卡后,维护者在同一决裁流转中续立两条原则,同属「应用仓基本原则」族,⛔ 不另开卡 —— 落编工作仍归 skills 席,一批做完。
原则二(出处 hotcrm#806 裁决,逐字)
「#806 我认为就是协议的问题,元数据应用应该是简化的业务实现,不应该编码处理这中 lint,要处理也是平台统一处理。」
⇒ 应用仓⛔不自建平台级 lint / 诊断 / 校验工具;发现的漂移类、校验类缺口一律定性为平台问题,立卡到平台仓统一处理(判例:hotcrm#806 → objectstack#13855)。
原则三(出处维护者续令,逐字)
「元数据应用就应该是在平台的规范下,基于skills 写元数据,并且使用平台提供的os命令校验元数据的合法性,而不是重新造轮子。这个也应该进入 hotcrm 的规范,甚至是 objectstack 的skills」
⇒ 元数据应用的工作方式三件套:在平台规范(spec)之下 · 基于 skills 写元数据 · 用平台
os命令校验元数据合法性;⛔ 不重新造轮子(不手写校验脚本、不自造布局/守卫机制、不复刻平台已有能力)。落点(维护者点名,skills 席执行)
- hotcrm 的规范(AGENTS/CLAUDE 或仓内 agent 指引)—— 三条全录;
- objectstack 的 skills —— 维护者原话「甚至是 objectstack 的skills」:含发布面
skills/(教应用作者的那套)的相应章节,受管面照旧 draft-only + 人工合并; - pm-dispatch 的 decision-analysis 参考(分歧推荐序邻段)—— 作为决裁荐向规则(原卡已列)。
Generated by Claude Code
huangyiirene commented
on Aug 31, 2026 CollaboratorAuthorMore actions补录:第四条基本原则(维护者 2026-08-31,出处 hotcrm#1422 决裁)
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t原则四(逐字)
「content/docs 为什么要有 cubes 清单表,文档应该是介绍业务概念」
⇒ 应用文档介绍业务概念,⛔ 不手抄机器清单:数据集/字段/组件等机器事实的唯一真相源是自描述元数据(
src/**声明),散文里的手抄表格没有生产者、必然漂移(hotcrm 四次实证:#610 #965 #977 #1228);想看语义层看元数据本身或平台对它的渲染。文档回答「这是什么、解决什么业务问题、怎么用」,清单归机器。判例:hotcrm#1422 —— cubes 清单表第四次漂移后,三个修法选项(钉行/去清单/codegen)全部不采,裁定清单表本身退场、文档改写为业务概念介绍。
边界注记(总监席划定,防扩杀):界面导航事实(如视图清单,hotcrm#1329/#1326 同日裁定保留并守卫)不属「机器清单手抄」—— 那是用户屏幕上可见事实的文档化;两类的分界 = 「读者在产品界面上能不能直接看到它」。
落编范围照旧三处(hotcrm 规范 / objectstack 发布 skills / pm-dispatch 决裁参考),与前三条一批,归 skills 席。
Generated by Claude Code
huangyiirene commented
on Aug 31, 2026 CollaboratorAuthorMore actionshotcrm AGENTS.md 增补规格(维护者 2026-08-31 索取:「基于以上决裁…需要补充哪些 agents.md」)—— skills 席按此施工,逐条带判例
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t。以下十二条全部提炼自 2026-08-31 当日裁决,每条判例可回查;措辞归 skills 席起草,受管面人工合并。一、身份与总纲
- 纯元数据应用定位:hotcrm 是业务功能的简化实现 —— 在平台规范下、基于 skills 写元数据、用
os命令校验合法性,⛔ 不重新造轮子(原则三)。只开发业务功能;平台能力一律在平台开发 —— 发现平台缺口 ⇒ 上行立平台卡,⛔ 不在本仓补偿(原则二;当日判例八连:fix: UI protocol design defects — widget id, action type unification, conditional validation, naming consistency #806→[Decision] 字段分组漂移已裁定为平台问题(hotcrm#806)—— 定统一机制:lint 镜像规则(不动契约)与/或 section 差量引用形式(契约扩宽) #13855、Studio 布局重构:Supabase 风格的 TopBar + LeftSidebar + Content #1203→[Decision]severity: 'warning'的校验规则没有受众概念 —— UI 级劝导在 seed/bootstrap 等机器写入路径上照样求值并打爆启动日志,且按写入次数而非按行计数 #13889、fix(service-tenant): register control-plane objects via manifest service #1212→objectui#7063、chore(deps)(deps-dev): bump @types/node from 22.19.19 to 25.9.1 #1247→objectui#7064、[P1] export: no print / PDF export — procurement orders & audit reports cannot be delivered #1301→autonumber 业务标识字段默认不唯一,可铸重号 —— 裁定:默认唯一(租户复合形状),显式退出才不唯一 #13894、重构多租户架构为“每环境单独数据库”高隔离模型 #1185→[Decision] Per-user notification locale —— 2026-08-13 裁决所等的「实测拉力」已到(hotcrm:4 个已发布语言 × 16 个 notify 节点 × 0 可本地化) #13881、chore(deps)(deps): bump @ai-sdk/provider from 2.0.1 to 3.0.8 #1069→requiredWhen(与字段级 min/max)是转换门,validations[]script 是真不变量 —— 边界是刻意的、已被双驱动实测,但平台没有任何一处教它 #13879、fix(driver-sql): add vitest.config.ts to resolve @objectstack/spec subpath imports #1231 的凭据机制作废)。
二、遇平台问题的行为
- 平台缺陷 ⇒ 等待平台修复:⛔ 不绕行(defensive coding / 形状容错 / 手写谓词复刻平台规则)、⛔ 不半边落地;阻塞落卡 blocked-by 机器可见;恢复执行前先核钉版本已含修复 + 复跑缺陷卡夹具(原则一;判例 Document dispatcher protocol in PROTOCOL_MAP #549/objectstack#11082/PR fix(plugin-security): compose controlled_by_parent across a chain (#11082) #11183)。
- ⛔ 不自建平台级工具:lint、校验、门禁、诊断类机制归平台统一(判例:fix: UI protocol design defects — widget id, action type unification, conditional validation, naming consistency #806 的 lint 半边作废、feat(automation): schedule flow trigger — auto-launch flows on cron/interval/once #1423 注释量门禁不建)。仓内测试只钉本仓自己的业务事实(如 PR chore: version packages #1291 的种子行 pin、Add action handler examples, modal cross-reference validation, and action.mdx doc sync #837 的「文档用词 = 语言包 label」守卫),⛔ 不建门禁农场。
- 平台默认不好 ⇒ 修默认,不逐处编写补偿(判例:fix(service-tenant): register control-plane objects via manifest service #1212 不逐磁贴写 emptyState 文案 → 平台默认空态;chore(deps)(deps-dev): bump @types/node from 22.19.19 to 25.9.1 #1247 不手调磁贴条归属 → hideEmpty 默认翻转)。
三、文档纪律
- 文档介绍业务概念,⛔ 不手抄机器清单(原则四,判例 docs(adr): ADR-0023 OpenAPI→Connector generator + ADR-0024 MCP servers as connectors #1422);边界 = 「读者在产品界面上能否直接看到」—— 界面导航事实(视图清单)可文档化并守卫([P3] release: template package publish / upgrade flow undefined — ecosystem blocked #1329/[P3] enterprise: no external auditor / read-only guest portal #1326),机器语义层清单不可。
- 中文文档面三规则:界面名词一律用 zh-CN 语言包译名([P3] release: template package publish / upgrade flow undefined — ecosystem blocked #1329);zh 标题带英文显式锚点 id、全语言锚点词汇单一(chore: version packages #1359);zh-Hant 约定的真实理由 = 主控台回退简体 + 避免简繁混排(chore: version packages #1368)。
四、元数据语义写法
- 不变量 vs 转换门按意图选工具:要不变量 ⇒
validations[]script(冻结不砖死);要转换条件 ⇒requiredWhen/字段 bounds(存量放行);散文别把转换门写成不变量(判例 chore(deps)(deps): bump @ai-sdk/provider from 2.0.1 to 3.0.8 #1069;平台教学半边requiredWhen(与字段级 min/max)是转换门,validations[]script 是真不变量 —— 边界是刻意的、已被双驱动实测,但平台没有任何一处教它 #13879)。 - 拦截立足于人的判决:机器信号(suspected)只警告,人写下的值(confirmed)才可拦;⛔ 不造 override 逃生舱(判例 chore(deps)(deps): bump the production-dependencies group across 1 directory with 3 updates #1288)。
- 提权最小化:screen flow 保持
runAs: 'user';需提权的写入拆进专职 system 子流经subflow调用;⛔ 不整流程提权换 readonly 生效;close_case是历史先例不是政策(判例 feat(notifications): ADR-0030 P0 — single ingress + layered model (framework) #1434)。 - 组织维度:
runAs: 'system'的扫描/汇总必须钉组织谓词(判例 chore: version packages #1372,Re-align stale @objectstack/objectql tests with current overlay registry & sys_metadata schema #1363 守卫为验收);租户列是平台默认注入的统一能力,⛔ 不逐对象声明、不逐对象「加租户维度」(判例 Fix CORS_ORIGIN wildcard patterns on Vercel deployments #1177 机制读数)。 - 刻意偏离必须写下:与全仓约定不同的刻意选择(demo 留空的职位、保留 resolved 的看板、复核窗口的常设授权、两套优先级词表)必须代码旁注释 + 守卫名册记录,否则会被下一个 agent「顺手对齐」(判例 [WIP] Investigate singular vs plural usage in code #1102/[P3] audit: platform audit log has no UI surface / no template-facing API doc #1328/chore: version packages #1342)。
五、裁决纪律
- 重挂前先查裁决:卡上已有维护者裁决记录的,⛔ 不重升级、不重裁(判例 [WIP] Add field groups metadata layer MVP #1198 的 8/22 失误);裁决权威台账在总监席座位贴(objectstack#13766 裁 B)。
落编时与本卡前四条原则合并成一个章节树,⛔ 不逐条散落;hotcrm AGENTS.md 为主落点,objectstack 发布 skills 取其中普适条目(1/2/4/5/7/8/9/10)。
Generated by Claude Code
- 纯元数据应用定位:hotcrm 是业务功能的简化实现 —— 在平台规范下、基于 skills 写元数据、用
huangyiirene commented
on Aug 31, 2026 CollaboratorAuthorMore actions范围拆分记录:hotcrm AGENTS.md 半边已开专卡 hotcrm#1437 并直派(维护者 2026-08-31)
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t维护者令(逐字):「AGENTS.md 增补清单 应该开skills卡片吧」+「现在就派发处理」。
⇒ 十二条增补规格(本卡评论 5481324665)已按「卡开在修复落地的仓」原则移交 hotcrm#1437(规格全文自含 + 施工约定:章节树合并、矛盾段清扫、受管面 draft + 人工合并),os-dev 已直派施工。
本卡剩余范围收窄为 objectstack 侧两半:① 发布 skills 取普适条目(规格第 1/2/4/5/7/8/9/10 条);② pm-dispatch decision-analysis 参考(分歧推荐序邻段)。四条原则的逐字引文单源照旧在本卡。hotcrm#1437 落地后回写落点记录。
Generated by Claude Code
huangyiirene commented
on Aug 31, 2026 CollaboratorAuthorMore actions补录:第五条基本原则 —— 逃生舱条款(维护者 2026-08-31)
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t原则五(逐字)
「或者说 skills 应该说明,逃生仓是极端场景按照客户需求自定义的场景下才需要,应该尽量避免。」
⇒ 布局逃生舱默认避免,教材写成阶梯:(1)
fieldGroups+Field.group派生是常态 —— 根本不写 sections;(2) 确需局部编排 ⇒ 组引用形式({ group: '<key>' },#13855/#13897 的机制);(3) 逐字段枚举仅限极端场景:具名客户定制需求 + 代码旁注明为何组引用不满足(跨组录入组合 / wizard-pane 结构)。⛔ 教程与示例不得把枚举当默认写法教(语料引力:存量教程全教枚举,不改教材 AI 会继续照抄)。背景裁断记录:维护者曾问「直接删除逃生舱?」——总监席分析(2026-08-31 会话记录):枚举半边是退役候选,但排布半边有三个结构性存在理由(
Field.group单值 ⇒ 跨组录入组合无法入组;fieldGroups 无嵌套 ⇒ wizard/pane 结构装不下;record 页需混排字段区与非字段组件);维护者择定教材收紧而非契约删除。解冻判据:若教材落地后新写元数据仍持续出现无注明理由的枚举 section,枚举退役问题(带存量普查)提回决策箱。落点增量
- objectstack 发布 skills(本卡既有范围):page-builder / schema-expressions 等教 sections 的页面改教阶梯写法,组引用为推荐形式(时序:feat(spec,lint): a layout section can reference a declared field group instead of copying its members #13897 合并后);
- hotcrm AGENTS.md:已令 chore(deps)(deps): bump the production-dependencies group across 1 directory with 11 updates #1437 的施工 agent 在 PR chore(deps)(deps-dev): bump @types/tar from 6.1.13 to 7.0.87 #1438 上补第五条(同分支追加提交,draft 姿态不变)。
Generated by Claude Code
huangyiirene commented
on Aug 31, 2026 CollaboratorAuthorMore actions落点回写:hotcrm AGENTS.md 半边已落地(维护者亲令合并,2026-08-31)
项目总监席 · session
session_01KGtaLpkW1mycWgkbSb3H6t- hotcrm#1437 → PR chore(deps)(deps-dev): bump @types/tar from 6.1.13 to 7.0.87 #1438 → main
8c40737,MERGED(维护者令「1438 同意合并」,授权入队记录在该 PR 评论 5481883301;merge queue 放行,chore(deps)(deps): bump the production-dependencies group across 1 directory with 11 updates #1437 随 Fixes 自动关闭 17:18Z); - 落地物:十二条并入 AGENTS.md 既有章节树(Scope 重写 / Constraint Checklist 文档纪律 / Metadata semantics 新章 / Ruling discipline 新章)+ 逃生舱条款(原则五)缀于 Metadata semantics 章末;四处与新原则矛盾的既有段落同 PR 改写(每处均先被独立测实已漂移);
- 姊妹发现 hotcrm#1439(ARCHITECTURE/DEPLOYMENT 同款过时段落)候该仓定级;存量审计 hotcrm#1440(81 处 sections:冗余 16 / 可映射 5 / 跨组结构 58 / 孤儿 2,合规理由注释 0)候该仓分级滚动。
本卡剩余范围(未动):objectstack 发布 skills 普适条目(含逃生舱阶梯教学,时序在 #13897 合并后)+ pm-dispatch decision-analysis 参考。skills 席照旧执行。
Generated by Claude Code
- hotcrm#1437 → PR chore(deps)(deps-dev): bump @types/tar from 6.1.13 to 7.0.87 #1438 → main
os-dev-report
{ "issue": 13848, "status": "done", "branch": "claude/issue-13848-app-principles-objectstack-half", "pr": "https://github.com/objectstack-ai/objectstack/pull/14052", "premise_still_valid": true, "summary": "Premise verified on today's origin/main before writing: no 等待平台修复 / wait-for-platform vocabulary anywhere under skills/ or .claude/skills/pm-dispatch/, and no group-reference ladder in the published catalog — the remaining range was entirely undone. PR 14052 (draft) lands both halves. LANDING MAP — spec rows went domain-scoped rather than all into objectstack-platform (Assumption A partially falsified, and the dispatch's 'land it where the reader is' clause applied): rows 1/2/4 as a new 'The App / Platform Boundary' section in skills/objectstack-platform/SKILL.md; row 5 (docs describe business concepts) in skills/objectstack-ui/SKILL.md after the Docs authoring rules; row 7 (invariant vs transition gate) in skills/objectstack-data/SKILL.md beside requiredWhen; row 8 (blocking rests on a human judgement) in skills/objectstack-data/rules/validation.md under Severity Levels; rows 9/10 (screen flow stays runAs user, elevated write via subflow; system sweep pins an org predicate) in skills/objectstack-automation/SKILL.md; principle five's escape-hatch ladder in skills/objectstack-ui/SKILL.md Record Presentation; clause 2 in .claude/skills/pm-dispatch/references/decision-analysis.md adjacent to the 四棱分歧推荐序 段. Reason for the spread: published skills load per domain, so a validations-vs-requiredWhen rule parked in the platform skill is never in context when an object schema is being written. Row 9 also corrected an existing drift — the readonly blockquote's blanket 'set runAs system' reads, to an agent writing a SCREEN flow, as 'elevate the whole flow'. Principle five also required rewriting this page's own two worked sections examples, which enumerated members and so taught the rung the ruling demotes; both now reference a declared group. TWO DISPATCH FACTS FALSIFIED, reported not silently complied with: (a) scripts/check-changeset-presence.mjs does not exist in this repo — MODULE_NOT_FOUND, read as a wrong path and not as a red gate; the changeset call was made from the three immediate skills-only precedents (PRs 14001, 13972, 13891, none carried one) plus the skip-changeset label, applied via the additive REST endpoint and read back; (b) the dispatch expected 17 gate families, the derived list is 32 — the derived list was used. Also reported: a PR-automation workflow appended a second copy of my signature footer to the PR body after creation; another actor's write, left alone per the never-correct-what-you-did-not-set rule, and my content is byte-intact (verified by full read-back diff). skip-changeset survived the size-labeler's later size/m write; read back after both.", "tests": "All exit codes captured before any pipe (cmd > log 2>&1; EXIT=$?); every verdict quoted from the gate's own printed line, never from a bare $?. Gate union run AFTER the final commit, at HEAD fa2a2ef70 — the same sha in the PR body. Family derived with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` (no hand-supplied paths; script took the changeset from the merge base itself, 7 paths, three-dot) => 32 families, run under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=dev-13848 (ACQUIRED after 0s; held 389s). Ran 36 total = those 32 + check:nul-bytes + check-skill-line-ratchet + the token ratchet's --self-test + check-ratchet-remedy-authority. RESULT: 34 green, 1 green after a prerequisite build, 1 NOT MEASURED. Green includes: 'check-skills-token-ratchet: 38 authored bundle file(s) within their ceilings' (exit 0); 'check-skills-token-ratchet self-test: 64 cases pass' (exit 0); 'check-skill-line-ratchet: decision-analysis.md is 46 lines (ceiling 46; headroom 0)' and 'widest table row is 0 bytes (pin 0; headroom 0)' (exit 0); 'check-skill-id-lint: 23 file(s) clean (pattern /#[0-9]{3,}/g)' (exit 0); 'check-ratchet-remedy-authority: 181 scripts swept; 12 mark the expanding remedy MAINTAINER-ONLY' (exit 0); plus check:doc-authoring, check:corpus-claim-drift, check:skill-frame-sync, check:skill-compatibility, check:skill-identifier-liveness, check:role-word, check:pm-governed-merges, check:pm-half-states, check:nul-bytes all exit 0. check:doc-formula-expressions returned exit 3 PREREQUISITE NOT MET twice in succession (first @objectstack/formula unbuilt, then @objectstack/lint unbuilt); after building both it is exit 0 — '22 record-scoped formula example(s) across 427 files / 1451 TS blocks judged clean', '9 spec TSDoc @example(s) clean', '14 field-level predicate(s) clean'. check-test-completeness is NOT MEASURED locally and is recorded as such, not as a red: it parses a test-run log, the derived family names it with no argument, and the gate itself prints that this branch is unreachable in CI. REGRESSION FOUND AND FIXED, with a reverse verification in both directions: commit 1 placed the authority comment block between the SHRINK-ONLY doc comment and `export const CEILINGS`, pushing that testimony outside the 400-byte anchor window check-ratchet-remedy-authority.mjs searches around each CEILINGS mention; the sweep reclassified the gate from `marked` to `excluded` and failed MISCLASSIFIED (exit 1). Attribution measured rather than assumed: a detached compare worktree at origin/main ran the same detector green (exit 0), the branch red (exit 1), so the regression was this PR's. A direct classifier probe confirmed the mechanism (MAIN: offers 1, target declared:CEILINGS, anchor=shrink, verdict marked / MINE: same offer, anchor=null, verdict excluded), and after moving the block above the doc comment the probe returns anchor=shrink, verdict marked on both. Compare worktree removed after use. Directionality note: this gate is NOT in the family dispatch-gates derives for these paths — it was run because a ratchet edit is what it polices, and it is the run that caught the only real defect in this PR. Budget deltas, all read from the ratchet's own report lines: platform 12704->12984, ui 25143->25445, data 13782->13892, data/rules/validation 3024->3109, automation 12618->12768; total growth +927 tokens, total ceiling raise +900 (27 absorbed by pre-existing headroom on three rows); bundle 186567->187494 (+0.50 percent). SKILL.md subtotal self-test pin shifted 118095->118910 = exactly the 815 raised across the four SKILL.md rows, preserving the id-strip claim's original 80 tokens of slack. decision-analysis.md needed NO line-ratchet raise: the clause was funded entirely by reflowing two paragraphs with the gate's own exported wrapLine (bullet 3->2 lines, paragraph 8->7 lines), freeing exactly the two lines the clause occupies.", "mcp_calls": "0 — the whole run used the container REST channel (repo-scoped probe returned 200 at open) plus git; card body, all 7 comments, PR creation, label write, reviewer request and every read-back went through curl. Zero MCP GitHub calls, so zero GraphQL pool burn.", "open_questions": [ { "question": "Is 900 ceiling tokens the right price for the five ruled principles? This is the only judgement in the PR that is not mechanical, and it is the human merge's call — the ratchet is shrink-only and the raise is MAINTAINER-ONLY territory, taken here only because the authorizing ruling names this landing surface by name.", "options": [ "A — merge as measured: +900 ceiling / +927 actual, 0.50 percent of the shipped bundle, all five rows initialised AT the measurement so each restarts with zero headroom", "B — cut the domain-scoped half (rows 7/8/9/10, +319 ceiling) and keep only the platform-boundary section plus the ui ladder, accepting that the validation and flow rules then live where the authoring agent does not load them", "C — refuse the raise and fund by deletion, which on these five files means removing live facts with no other home (the dispatch's own stop condition)" ], "recommendation": "A. Real business need is measured, not speculative: every row has a named same-day precedent where an app actually made the mistake, and rows 9/10 are the two whose failure mode leaks across tenants. Long-term soundness favours A over B because the cost of B is silent — a rule that ships in the wrong domain skill reads as landed and is never loaded. Preventing AI error is the axis that decides between A and B: rows 7/8/9/10 are precisely the picks an AI gets wrong at authoring time, so their placement is the whole value. Startup scope discipline is the one axis that argues for B, and it is answered by the arithmetic — 0.50 percent of the bundle, with the only genuine deletion available already taken (the two enumerating sections examples) rather than left on the table." } ], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
维护者裁定(2026-08-31,逐字):「关于 hotcrm 有一些基本原则应该写入skills,比如 549 ,既然是平台缺陷,就应该等待平台处理,而且实际上平台已经处理了。 11082」
要落编的原则
应用仓(hotcrm 及后续参考应用)的工作被平台缺陷阻塞时:
controlled_by_parent)被 objectstack#11082(二级链派生不收窄,org-wide 可读可写)阻塞;「只落 contract 半边」的劈半方案曾被呈报;维护者裁定等待。平台 2026-08-23 以 PR fix(plugin-security): compose controlled_by_parent across a chain (#11082) #11183 修复收口,原裁全量恢复执行 —— 等待被证明是对的:半边方案会花掉 contract-first 的选项,且给下一个读者留下「裁定执行了一半」的历史。落点(skills 席定夺具体文件)
候选:pm-dispatch 的 decision-analysis 参考(分歧推荐序邻段,作为应用仓决策的荐向规则)+ hotcrm 仓自己的 agent 指引。受管面,人工合并照旧。
⛔ 本卡由总监席按裁决立卡记录,落编工作归 skills 席;refs hotcrm#549、objectstack#11082、objectstack PR #11183。