[Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

Description

@huangyiirene

由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

#14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

事实(逐字来自 #14454 第 3 项)

ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

选项(逐字来自 #14454)

  • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
  • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

两者都要写回 ADR-0130(docs-only 卡另开)。

<!-- os-decision-facets -->
① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

相关

#14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
       blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      
      Skip to content

      [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

      Description

      @huangyiirene

      由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

      #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

      事实(逐字来自 #14454 第 3 项)

      ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

      来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

      选项(逐字来自 #14454)

      • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
      • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

      两者都要写回 ADR-0130(docs-only 卡另开)。

      <!-- os-decision-facets -->
      ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
      ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
      ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
      ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

      推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

      ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

      置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

      相关

      #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

      Generated by Claude Code

      Activity

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

      Metadata

      Metadata

      Assignees

      No one assigned

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
          Skip to content

          [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

          Description

          @huangyiirene

          由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

          #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

          事实(逐字来自 #14454 第 3 项)

          ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

          来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

          选项(逐字来自 #14454)

          • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
          • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

          两者都要写回 ADR-0130(docs-only 卡另开)。

          <!-- os-decision-facets -->
          ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
          ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
          ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
          ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

          推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

          ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

          置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

          相关

          #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

          Generated by Claude Code

          Activity

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

          Metadata

          Metadata

          Assignees

          No one assigned

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

              Description

              @huangyiirene

              由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

              #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

              事实(逐字来自 #14454 第 3 项)

              ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

              来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

              选项(逐字来自 #14454)

              • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
              • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

              两者都要写回 ADR-0130(docs-only 卡另开)。

              <!-- os-decision-facets -->
              ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
              ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
              ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
              ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

              推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

              ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

              置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

              相关

              #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

              Generated by Claude Code

              Activity

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

              Metadata

              Metadata

              Assignees

              No one assigned

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
                  Skip to content

                  [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

                  Description

                  @huangyiirene

                  由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

                  #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

                  事实(逐字来自 #14454 第 3 项)

                  ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

                  来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

                  选项(逐字来自 #14454)

                  • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
                  • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

                  两者都要写回 ADR-0130(docs-only 卡另开)。

                  <!-- os-decision-facets -->
                  ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
                  ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
                  ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
                  ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

                  推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

                  ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

                  置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

                  相关

                  #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

                  Generated by Claude Code

                  Activity

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

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                      Skip to content

                      [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

                      Description

                      @huangyiirene

                      由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

                      #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

                      事实(逐字来自 #14454 第 3 项)

                      ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

                      来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

                      选项(逐字来自 #14454)

                      • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
                      • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

                      两者都要写回 ADR-0130(docs-only 卡另开)。

                      <!-- os-decision-facets -->
                      ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
                      ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
                      ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
                      ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

                      推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

                      ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

                      置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

                      相关

                      #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

                      Generated by Claude Code

                      Activity

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

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                          Skip to content

                          [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

                          Description

                          @huangyiirene

                          由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

                          #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

                          事实(逐字来自 #14454 第 3 项)

                          ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

                          来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

                          选项(逐字来自 #14454)

                          • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
                          • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

                          两者都要写回 ADR-0130(docs-only 卡另开)。

                          <!-- os-decision-facets -->
                          ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
                          ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
                          ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
                          ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

                          推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

                          ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

                          置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

                          相关

                          #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

                          Generated by Claude Code

                          Activity

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

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                              Skip to content

                              [Decision] 权限集没有模块归属:ADR-0130 §1.3(a) 点名的痛点在分拆后并没有被消掉 —— 允许按包组合,还是明确记录它不在边界范围内? #14457

                              Description

                              @huangyiirene

                              由分诊席(会话 session_019kDRpB7D2XzVzkaLp57T5D,R+94)自 #14454 拆出。

                              #14454 同时挂了 pm:queueneeds-user-decision —— 而六个 pm 状态是 ONE-OF,同挂会让同一张卡既进可派发库存又进维护者收件箱。它这样挂是因为卡本身确实是混的:第 1、2、4 项是测量与 pin(可直接派),第 3 项要维护者拍板。⇒ 第 3 项拆到这里,#14454 留作可派发的测量卡。⛔ 拆分不改任何事实,原文照录。

                              事实(逐字来自 #14454 第 3 项)

                              ADR-0130 §1.3(a) 把 30 行 × 9 列 × 6 套的权限矩阵列为无边界的三个可量化后果之一,并把包边界作为 Studio 一直缺的分组。但权限集天然跨域授权 —— HotCRM 6 套里 4 套横跨 5–6 个模块 —— 它不能住在某个模块里,分拆后矩阵依旧是平的。

                              来源:hotcrm 分拆方案 objectstack-ai/hotcrm#1448 / PR hotcrm#1449,docs/architecture/module-split-plan.md §「上游缺口」。父单 #14122

                              选项(逐字来自 #14454)

                              • A. 允许权限集按包组合 —— 模块把自己对象的授权贡献进 app 拥有的角色,类似 navigationContributions
                              • B. 明确记录「权限矩阵不在 ADR-0130 创造的边界范围内」 —— Studio 的分组收益不含它。

                              两者都要写回 ADR-0130(docs-only 卡另开)。

                              <!-- os-decision-facets -->
                              ① 项目长远合理性(权重 ≥50%):ADR-0130 的整个卖点是「包边界让 Studio 能分组」,而权限矩阵是它 §1.3(a) 自己点名的三个可量化痛点之一。A 让边界在权限面也成立,ADR 的自陈收益兑现;B 等于承认最痛的那一块不在边界内 —— ADR 的收益打折,而且这个折扣以后每个读 §1.3(a) 的人都要重新发现一次。⚠️ 但 A 新增一个组合机制,声明面 +1,是永久义务;按本轴本义,这一笔要如实记在 A 的账上。
                              ② 实际业务拉动:实测,不是假想 —— HotCRM 6 套权限集里 4 套横跨 5–6 个模块,而分拆方案今天就卡在这一项上定不了稿。这是四轴里唯一有硬数字的一轴。
                              ③ 防 AI 犯错:B 之下,一个 AI 作者面对横跨五个模块的权限集,没有任何结构告诉它新对象的授权该写在哪 —— 它会猜,而猜错是静默的(多授或少授,两个方向都不会响亮拒绝)。A 让「这个对象的授权归哪个模块」有唯一答案。这一轴 A 明显占优。
                              ④ 创业阶段不扩散:B 零新增声明面;A 新增一个组合机制 —— 但 A 复用 navigationContributions 已有的形状,不是从零发明一套,增量比看上去小。

                              推荐:先量一格再裁,而且那一格本来就要量 —— #14454 第 2 项要为 navigationContributions[].group 钉三条 pin(按目标 app 的 group id 解析 / 贡献进不存在的 group 要可见地失败 / 多包贡献同一 group 由 priority 定序)。三条全绿 ⇒「贡献进别人拥有的容器」这个形状在平台上成立且成本已知,A 的实现≈复刻既有形状,荐 A(①②③ 同向);任一条不成立 ⇒ A 的地基本身没有,只剩 B,而 B 必须把「Studio 的分组收益不含权限矩阵」明确写回 ADR-0130,⛔ 不许默默留着 —— 那正是本卡存在的原因。

                              ⛔ 席位不代裁:A 属功能新增 + ADR 类,双重人工地板。

                              置信缺口(本分析看不见什么):看不见 ADR-0130 的「Studio 分组」收益对维护者值多少 —— 那是产品判断不是工程判断;也没量过除 HotCRM 之外还有哪些应用存在跨模块权限集,所以②的硬数字只有一个样本。

                              相关

                              #14454(测量与 pin 的那三项)· #14122(父单)· ADR-0130 §1.3(a) · objectstack-ai/hotcrm#1448

                              Generated by Claude Code

                              Activity

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

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions