Repository navigation
[Decision] §09 要「各段时长」和「超 SLA」,但语义层算不出时间差——两问共用一个补法 #31
Description
Activity
- added a commit that references this issue
on Sep 8, 2026 zhuangjianguo commented
on Sep 9, 2026 CollaboratorMore actions前提刷新 —— 平台侧根因已有卡,且在等维护者动作。 ⛔ 不是裁决,不动标签。
本卡第一问的实测(
avg(submitted_at)返回2025.9166666666667,derived: { op: 'difference' }渲染出-0.849999999999909)在上游已经立案:objectstack-ai/objectstack#16737— service-analytics:AVG()over aField.datetimemeasure returns SQLite's text→numeric coercion (an average YEAR) with no error, andderived: { op: 'difference' }renders the difference of two of them as a clean plausible number —— open,且带pm:awaiting-maintainer(决定已做,只剩一次 GitHub 之外的人工动作)。同族另有两张 open:#16099(无任何层拒绝不自洽的聚合/字段类型配对,
avgover datetime 在 SQLite 能跑、在 Postgres 报错)与 #15768(datetime 度量在分析响应里被定型为number)。这对本卡的意义:选项 1C(向平台提需求,等它落地前维持替代物)在写这张卡时是「时间不可控」的假设面,现在它有具体载体和状态了。⇒ 裁本卡之前应先读 #16737 的现状 —— 如果平台给出日期差度量或修掉静默强制转换,1A 的「日任务盖戳字段」就不是唯一出路,1C 的成本估计也要重算。
另:本卡与 #11 #19 #20 #28 同属前提取自
@objectstack/*17.3.0 的一批。#35 已把本仓推到 17.4.0 并于今日合并(PR #37,origin/main@5d5a254,锁文件零 17.3.0 残留)。⇒ 这一批的平台能力断言现在都该在 17.4 上重跑再定,本卡的语义层限制(ADR-0021 不收 SQL/表达式、跨对象过滤被拒)尤其需要重验。取数时刻 2026-09-09T14:5xZ。
Generated by Claude Code
zhuangjianguo commented
on Sep 9, 2026 CollaboratorMore actions裁定:1C + 2B —— 去平台修;本仓维持替代物并把措辞改成如实
维护者裁决,2026-09-09,常设决裁批第 1 批,逐字:
第 1 批 平台的问题去平台修,业务的问题按照你的意见。
本卡的阻塞源是平台缺陷(语义层不做日期减法;
AVG()打在 datetime 上返回平均年份)⇒ 走「去平台修」。这也与决策分析写法的应用仓推荐序特例一致:阻塞源是平台缺陷 ⇒ 恒荐等待;⛔ 不荐绕行(形状容错、复刻平台规则)、不荐劈半落地。⇒ 1C(等平台)+ 2B(保留固定阈值,措辞如实)。⛔ 因此 1A / 2A 明确不采纳:用每日任务在应用里补出分析层该有的日期运算,正是该特例点名的「复刻平台规则」。
⚠️ 公开更正:我呈报时对 1C 的描述被一个更晚的读数证伪呈报时我把 1C 写成「一次修好所有应用」。录裁前重读平台侧,这句话不成立:
- 平台卡
objectstack-ai/objectstack#16737— open,bug·priority:p2·domain:services·pm:awaiting-maintainer,assigneeos-trump。 - 它已经有一个 open PR:
objectstack-ai/objectstack#16778,标题逐字:feat(service-analytics)!: refuse an aggregate a datetime measure's field type cannot carry, and reconcile the storage-form annotations to one measured statement
⇒ 平台选定的补法是拒绝,不是提供。#16778 合并后,本仓依然算不出各段时长 —— 变化的是:那条「能跑通、能渲染、结果错」的路径会开始响亮报错,而不是给出
-0.849999999999909这种可信的假数。洞被堵上了,能力没拿到。 这对本卡的意义:
- 防错轴的紧急项(静默假数)由 #16778 解决 —— 那是本卡真正危险的部分,它有归宿了。
- 第 9 章要的「各段时长」在可预见的将来仍然给不出,除非平台另有一张卡提供日期差度量原语。#16737 的验收清单第 3 条明说「Either it errors, or it returns something a reader cannot mistake for a duration」—— 两条路都不产出时长。
⛔ 我不静默重裁。裁定按字面执行为 1C + 2B。但若你看了上面这段觉得「等一个只会报错的修复」不是你要的意思,说一句,本卡回决策箱重开选项(那时真正的选项是:向平台立一张日期差度量原语的能力卡,还是接受第 9 章永久少这两个数)。
裁后执行
- 状态转换:
needs-user-decision→pm:blocked,正文加机器可读行Blocked-by: objectstack-ai/objectstack#16737(同一笔标签写入)。 - §09 措辞如实(随折叠的设计文档 PR,链首 [Decision]
DESIGN.md§03 requires a termination reason but declares no field for it #6,本卡为Refs #31的搭车项,⛔ 非Fixes):第 9 章不再无条件承诺「各段时长」与「超 SLA」,改为记明现状 —— 交付的是阶段覆盖数与审批吞吐,两个原指标等平台的日期能力,并点名 #16737。沉默地留着一个兑现不了的承诺,正是本卡自己反对的形状。 - 卡 09 的 F3(法务 SLA 巡检)按 2B 写:固定阈值,且砖的标题必须自带阈值(「审查超 30 天」而不是「超 SLA」),因为九种合同类型的真实 SLA 是 2/3/5/10 天,30 天高于全部 —— 标题自陈阈值,读者就不会误读成按类型的违约。
- 解锁判据:#16737 关闭时本卡回队重验,⛔ 判据不是「PR 合并」而是「本仓升到含该修复的版本后,那条错路确实报错」。跨仓解锁判据是消费方可安装。
- 已在平台卡上留下本仓作为具名下游消费者的记录。
Generated by Claude Code
- 平台卡
- added 5 commits that reference this issue
on Sep 9, 2026 zhuangjianguo commented
on Sep 10, 2026 CollaboratorMore actions席位裁定 —— 解锁判据未满足,
pm:blocked保持#80 在本仓实际安装的版本上重跑了这张卡的探针。判据没有满足,而且这张卡的措辞刚好证明了它自己的价值。
实测(17.4.0,54 个
@objectstack/*包全部 17.4.0,better-sqlite313.0.3,从node_modules读出)那条错路三层都不拦:
层 结果 作者期 validate/lint/typecheck全部退出 0,derived原样编进dist/objectstack.json查询构建 POST /api/v1/analytics/dataset/query→ HTTP 200,回显AVG(submitted_at)执行 cycle_days = -0.8555555555556111,avg_submitted = 2025.8833333333334操作员看到的是两块普通指标砖:
-0.86 / Avg Cycle (days?)和2,025.88 / Avg Submitted—— 没有报错横幅、没有空态、没有校验提示、控制台无错。这是本卡列出的三种结局里的第三种,也是本卡认定最危险的那种:它照样撒谎。 数值与本卡原记录的
-0.849999999999909不同,只因演示数据的日期随启动日漂移;机制与行数(120 行 / 60 已提交 / 72 已生效)完全一致。⇒ 本卡「⛔ 不得用应用侧日任务盖戳」与 §09 已记录的交付面全部不变。
pm:blocked保持,⛔ 不进决策箱,⛔ 不需要维护者现在做任何事。⚠️ 上游卡已关闭,而没有任何已发布版本带着那个修复这是本轮最该记下的一件事:
-
objectstack-ai/objectstack#16737已于 2026-09-10 06:13Z 关闭(completed)。 -
@objectstack/service-analytics的latest就是 17.4.0 —— npm 上 17.x 之后没有更新的发布版。 -
而 17.4.0 自己的
CHANGELOG.md白纸黑字写着这个洞是开的(我自己拉的包,逐字核过):sum/avgover a temporal column are refused by no layer and answered by the backend (an epoch mean on SQLite, an error on Postgres) … a derived measure is numeric by construction, becausecomputeDerivedcoerces its operands withNumber().
这正是本卡当初把判据写成「消费方可安装」而不是「上游 PR 已合并」的理由。 那句 ⛔ 今天兑现了:上游卡关了,本仓装的版本行为一个字节没变。判据措辞是对的,⛔ 不要改它。
一条上游发版说明里的新事实,比本卡原有的更细
洞是按后端分岔的:SQLite 上是 epoch 均值(静默假数),Postgres 上是报错。 也就是说这个陷阱是演示环境(SQLite)专属的 —— 真正跑在 Postgres 上的部署会直接报错。本卡原文只写了「⛔ 未在第二种方言上复核」,现在平台自己的发版说明把答案写出来了。这对将来落地 1A/2A 时怎么描述这个字段有用,⛔ 但不改变今天的裁定。
⚠️ 一个容易看错的地方,记下来免得下次踩17.4.0 确实发了这一族的两个兄弟修复(min/max 的类型描述),但没发「拒绝」那一半:装好的包里搜不到
16737也搜不到16778。skim 一眼 temporal 相关的发版说明,很容易把兄弟当成本体。 下一次读 #16737 状态的人请先看latest的实际行为,不要只看 issue 是不是 closed。已做
上游 #16737 上补了一条消费方读数(
latest上行为未变 + 它自己 CHANGELOG 的原话),⛔ 措辞是「请问哪个发布版会带上」,不是「你关错了」—— 修复很可能已在main上,只是还没发版。附:本卡引用的 17.3.0 测量已刷新
src/datasets/cycle-time.dataset.ts注释里那段标着 17.3.0 的测量,现在有了 17.4.0 的同形读数:形状相同、数字更新、结论不变。⛔ 那条注释本身不改(#80 明令禁止),刷新后的读数落在 #80 的报告里。顺带一提:正因为那条注释老老实实标了版本号,这个缺口才看得见 —— 一条不标版本的测量会一直被当成当前事实。
Generated by Claude Code
-
objectstack-fleet commented
on Oct 9, 2026 ContributorMore actionsSeat note · 2026-10-09T14:41Z — waiting state, written on the card.
- 17.4.0 reading (Re-run #31's unlock probe on 17.4.0 — its criterion may already be met and nobody has looked #80, 2026-09-10): criterion not met — the derived difference still renders
-0.86with no refusal at any layer. - Upstream:
objectstack-ai/objectstack#16737closed completed 2026-09-10, after that reading. Closure is not the criterion; this card's own criterion is that the wrong path errors in this repo, on the version it has installed. - Now waiting on: Upgrade the
@objectstack/*dependencies from 17.4.0 to 17.7.0, walking the official upgrade checklists of 17.5, 17.6 and 17.7 #82 (@objectstack/*17.4.0 → 17.7.0, in flight since 2026-10-09). Its dispatch carries Re-run #31's unlock probe on 17.4.0 — its criterion may already be met and nobody has looked #80's probe, re-run on 17.7.0, as a report-only increment. When that reading lands, the seat decides this card's state from it.
Generated by Claude Code
- 17.4.0 reading (Re-run #31's unlock probe on 17.4.0 — its criterion may already be met and nobody has looked #80, 2026-09-10): criterion not met — the derived difference still renders
objectstack-fleet commented
on Oct 9, 2026 ContributorMore actionsSeat note · 2026-10-09T16:08Z — the 17.7.0 reading exists.
#82's dev re-ran #80's probe on 17.7.0 (PR #85, section #31's unlock probe on 17.7.0): the wrong path now errors at every door —
os validate/os buildexit 1 (measure-aggregate-field-type-refused×2),PUT /api/v1/meta/dataset/probe31_cycle→422 INVALID_METADATAwith nothing stored,POST /api/v1/analytics/queryavg(submitted_at)→400 INVALID_FIELD(query was NOT run). Probe never committed; tree restored and proved by state.This card's criterion is 「本仓升到含该修复的版本后那条错路确实报错」 — it is met on the branch, and becomes this repo's state when PR #85 merges (
mainis still on 17.4.0 until then). At that merge the seat brings this card back to the maintainer: 1C's wait is over, and as this card's own correction recorded, the platform fixed by refusing, not by providing — the per-stage durations remain uncomputable on 17.7.0.
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorMore actions解锁判据已成立——请决定本卡怎么收尾 · 2026-10-10T00:17Z
Governing text: 本卡裁定 1C(维护者,2026-09-09,第 1 批)「阻塞源是平台缺陷 ⇒ 去平台修。解锁判据是消费方可安装(本仓升到含该修复的版本后那条错路确实报错)」·
DESIGN.md§09维护者速读
事情:PR #85 已合并(
c31c7e2),本仓main现在是 17.7.0。上一条评论里的探针在 17.7.0 上测得:那条错路(对Field.datetime求avg再相减)在每一道门都报错——作者时os validate拒绝、保存门422、查询门400。本卡自己的解锁判据成立了,「渲染出一个干净的错数」这个风险已经消失。但要知道:平台的修法是拒绝而不是提供(本卡 2026-09-09 的更正里已说明),所以 §09 原本想要的「各段时长 / 超 SLA」在 17.7.0 上仍然算不出来。现在的替代物(阶段覆盖数、审批吞吐、固定 30 天阈值且标题写明阈值)照 1C + 2B 继续有效。
你要做的:回一个字母。
做法 代价 / 收益 A(推荐) 关单(完成):1C 的等待已经结束,危险的错数已被平台拒绝,替代物按 1C + 2B 保留 零工作量;§09 不再承诺算不出来的指标 B 改选 1A:日任务把各段时长 / 超 SLA 盖成合同上的持久字段 §09 字面兑现;需要你定字段名与语义(公开契约),并动日任务与 §03 四棱分析
- 实际业务需求:周转时长与超 SLA 是法务负责人真实会问的问题;但目前没有任何用户或部署在等这两个数,拉动来自设计文档本身。
- 项目长远合理性:A 停在平台能兑现的范围内;B 等于在应用里补平台不提供的度量——1C 当初的取向正是不在应用里绕路。
- 防 AI 写错:平台现在会响亮拒绝错误写法,A 下不会再有 agent 造出错数;B 会引入新的盖戳字段与日任务,需要新的正确性保证。
- 创业阶段不扩散:A 不扩散;B 新增字段与任务逻辑。
Generated by Claude Code
Blocked-by: objectstack-ai/objectstack#16737
维护者速读
事情:设计方案第 9 章要两样东西,卡 10(#29 / PR #30)照着做时发现平台这一版给不了:
review_started_at去比另一个对象的列(clm_contract_type.review_sla_days,九种类型分别是 2/3/5/10 天)。分析层既不能按公式过滤(§12 缺口 [Decision] Two states inDESIGN.md§03 are dead ends: a started obligation cannot go overdue, a partly paid instalment cannot be completed #10),跨对象过滤也被直接拒绝。两问的补法是同一个:让日任务把结果盖成合同上的持久字段,之后分析层直接读那个数就行。这正是 §12 缺口 #7 已经为另一个日期运算问题选定的形状(「到期、逾期由日任务盖戳字段」),所以不是新机制。
为什么必须你拍板:字段叫什么、语义是什么,是公开契约;而且它落在卡 09(日任务那张卡)的地盘上,不是卡 10 能自己加的。
你要做的:回两个字母,比如「1A 2A」。
第一问 —— 各段时长
这里最值得你看一眼的,是它差点怎么错
开发 agent 先按直觉写了
derived: { op: 'difference', of: [avg_activated, avg_submitted] }。它不报错。它解析通过、运行成功、渲染出一个数:-0.849999999999909。原因实测如下:
Field.datetime在 SQLite 上存的是 ISO 文本,AVG()触发 SQLite 的文本→数字强制转换,取到开头的年。于是那个-0.85是两个平均年份之差——一个干净、合理、可以直接进仪表盘的错数。这就是本来会发布出去的形态。 卡 10 因此改为交付「各阶段覆盖数」(已提交 60 · 已开始审查 41 · 已批准 34 · 已签署 72 · 已生效 72)和一块标明为「审批吞吐」的砖,§09 要的「本月 vs 上月」对比则用平台自己的
compareTo: { kind: 'previousPeriod' }原语实现,没有硬编码差值。选项
clm_contract上加持久的时长字段,由日任务盖戳——与 §12 缺口 #7 同形datediff类度量,或Field.datetime改存数值时间戳),在它落地前维持替代物contract_cycle_time数据集第二问 —— 超 SLA
卡 10 交付的是固定 30 天阈值,并把砖的标题写成「审查超 30 天」而不是「超 SLA」——因为九种类型的 SLA 是 2/3/5/10 天,30 天高于全部,且标题自己说明了阈值,读者不会误以为它是按类型的违约。
review_due_at(或违约布尔),砖改为过滤持久列四棱分析(两问共用)
实际业务需求 — 偏 A。「合同平均要走多久」和「哪些审查压过了 SLA」是 CLM 买家评估流程效率时最先问的两个问题,也是对标 Ironclad/Agiloft 时销售会被追问的两个数。1B/2B 等于承认这个产品答不出来。
项目长远合理性 — 明确偏 A,理由是一致性:这个设计对完全相同的问题(日期运算算不了)已经在 §12 缺口 #7 选过一次答案,就是「日任务盖戳字段」。同一个问题给两种答案,是下一个作者最容易踩空的地方。而且持久数值列可过滤、可排序、可聚合——这正是
clm_contract那五个汇总字段被做成summary而不是公式的同一个理由。防 AI 写错 — 这一棱最偏 A,而且差距最大。今天的状态是:语义层里存在一条能跑通、能渲染、结果错的路径(
op: 'difference'那个-0.85)。只要这条路还开着,下一个作者——人或 AI——照直觉写就会写出它,而且没有任何闸门会拦。1A 把正确答案变成一个现成的持久字段,等于把那条错路的诱因移走。1B 反而更危险:它把「这里算不出时长」写进文档,却不改变「随手一写就能得到一个假时长」这个事实。创业阶段不扩散 — 略偏 B。1A 要加字段、改 §03、给卡 09 加活。但卡 09 本来就要建一个跑在这些对象上的日任务,所以边际成本是「一个字段加一次盖戳」,不是一套新机制。2A 更是搭同一趟车。
结论:三棱同向 A,第四棱的成本因为卡 09 已有日任务而被大幅摊薄。推荐 1A 2A。 若你更想省,1B 2B 也自洽,但必须写进 §09——沉默不可接受,理由同 #10:把矛盾留给下游卡片,就是把它推给一个更没权限、也更有压力悄悄编一个答案的位置。
⛔ 字段名与语义我没有替你定,那是公开契约。
影响
不阻塞。PR #30 本身不声称任何时长,可以按现状合并(正在做第一轮 rework,原因与本卡无关)。这两问的落地在卡 09——那张卡同时还等着 #6、#10、#14 三张决策卡,所以一并回答可以让卡 09 一次派发到位。
关联
#29 / PR #30(来源)· 卡 09(落地处,尚未派发)· #6 #10 #14(同样卡住卡 09 的三张)·
DESIGN.md§09、§12 缺口 #7 与 #10。