Repository navigation
Record four maintainer rulings in DESIGN.md §03, §06 and §09 - #40
Conversation
…d §09 Four adjudications landed on 2026-09-09 (batch 1, verbatim: 「第 1 批 平台的 问题去平台修,业务的问题按照你的意见。」). The design document still stated the pre-ruling text. This records each one, and nothing else. §03 field list gains `termination_reason` (textarea, required only when the status is `terminated`, never on the intake form). The `active → terminated` guard already demanded a termination reason; it now names a field that exists. §03 state tables gain the two missing edges: `clm_obligation.status` `in_progress → overdue` (a started obligation could not be marked late while an untouched one could) and `clm_payment_plan.status` `partial → paid/overdue` (`partial` had no outgoing edge at all). §06 F9 loses 「发起时填了付款安排则生成 `clm_payment_plan`」. Nothing at intake can fill a payment arrangement and the requester holds only R on `clm_payment_plan` (§04), so the clause was a declaration the runtime does not honour. Payment plans are created by finance after activation; §04 already grants finance RCU, so no replacement text is needed and none is added. §09 stops promising per-stage durations and a by-type over-SLA list. The semantic layer takes neither SQL nor expressions (ADR-0021), and `AVG()` over a `Field.datetime` silently returns an average YEAR. Both metrics wait on objectstack-ai/objectstack#16737; §09 now states what is actually delivered. The code half of all four lands in #39. Docs-only: no gate reads DESIGN.md. Refs #6, #10, #14, #31 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
Rework round 1 on PR #40, both edits inside ruling 2B's 「改 §09 措辞」. §09 excluded per-stage durations in one paragraph while the 管理层 bullet three lines above still promised 审批瓶颈(各台阶平均停留)— itself a per-stage duration. A section that contradicts itself is not truthful, so the bullet now states what the board actually delivers: four routing-load tiles, one per rung of the §04 ladder, reading the `route_*` flags F2 stamps. The tile is described, not deleted; the board has a real widget there. The limits paragraph now also names the dwell and records its second, non- platform cause: `sys_approval_request` holds 0 rows on a stock demo and F5 never ran, so the rungs have no start and no end to subtract. That cause outlives objectstack-ai/objectstack#16737, and saying so keeps the next reader from expecting the platform fix to deliver a dwell. The prohibition on stamping the metrics from an app-side daily job now names its two subjects instead of saying "these two", which became ambiguous once a third metric was discussed. §02's Insights row pointed at §09 for 周转分析. This PR is what makes that pointer dangle, so it is corrected here rather than filed for later: the row now says stage stamps deliver coverage counts and approval throughput, with durations waiting on the platform. One line; nothing else in §02 moves. Refs #6, #10, #14, #31 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
维护者速读(终稿)
改了什么 — 只动
为什么改 — 前四条是把你今天拍的板记进文档。共同点是:它们都曾声明了运行时兑现不了的能力——守卫要求填终止原因而字段不存在;已经在做的义务反而不能标逾期;付了一半的款永远结不了;F9 说发起时能填付款安排,而发起人既无处填也无权写;第 9 章要的平均周转需要两个时间戳相减,而语义层做不了减法,早先按直觉写出来的版本不报错、渲染出一个可信的假数 ⑤⑥ 是我在复核时打回加的,理由是改了一半的文档比没改的更容易误导:第 9 章一边宣布「不交付时长」,一边还列着一个时长指标;第 2 章还在替它对外承诺。 风险与代价(含回滚) — 低,且我核过它为什么低。四个门禁全 0,返工后重跑仍全 0 且告警条数一字未变(21 warnings / 5 suggestions);没有任何门禁读 代价是白纸黑字少承诺了三个数:各段时长、按类型的「超 SLA」、各台阶平均停留。
回滚: 席位意见 — 建议合并,理由三条,也附一条我自己的越界申报。
你要做的 — 确认①–④就是你今天拍的那四板、⑤⑥是让同一份文档不自相矛盾,然后合并这个 PR(受管面,按 Generated by Claude Code |
§09 still specified 各阶段合同数漏斗 — a funnel over every lifecycle stage. Two merged cards moved the app off that in two independent ways, and the design authority never caught up: - #48 / PR #57 replaced the mark with `type: 'horizontal-bar'` ordered by the measure, because a funnel asserts monotonic decline over a book that does not decline (§10: draft 10 · submitted 6 · in_review 12 · in_approval 8 · approved 4 · signing 6 · active 60 — a bowtie). - #59 / PR #62 narrowed the filter to the six in-flight stages, on the criterion the widget's comment states: whether legal still has work to do on the stage. `active` and the four terminal outcomes are all out. The bullet now names the mark and the coverage; a new paragraph carries the reasoning and states that no authored stage order is promised — `options.stageOrder` is read only by console 17.4.0's funnel branch and is dropped silently outside `en` (objectstack-ai/objectstack#17344). Promising an ordering this platform version cannot deliver is the same defect class PR #40 just removed from this section. Documentation only: no app file changes, and no gate reads `DESIGN.md`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
…ages (#63) 09 still specified the Legal Workbench stage widget as 各阶段合同数漏斗 — a funnel over every lifecycle stage. The app stopped shipping a funnel in #48 (PR #57 made it a horizontal-bar ordered by the measure) and narrowed what it plots in #59 (PR #62 dropped `active`, leaving the six in-flight stages), and the design authority never caught up. The bullet now names the mark and the coverage, and a new paragraph carries the reasoning: a funnel asserts monotonic decline and this book does not decline (10's spread — draft 10 · submitted 6 · in_review 12 · in_approval 8 · approved 4 · signing 6 · active 60), so the mark was asserting something the numbers do not say. The admission criterion is whether legal still has work to do on the stage, which is why `active` and the four terminal outcomes are all out; the size of the in-force book belongs to the 管理层 board. It also records the non-promise, which is the half a list bullet cannot carry: 09 must NOT describe an authorable stage order. options.stageOrder was removed deliberately in PR #57 — console 17.4.0 reads it only in the funnel branch and drops it silently outside `en` (objectstack-ai/objectstack#17344). Recording the negative is what stops the next reader re-adding it, the same way PR #40 recorded rather than silently deleted the 各段时长 promises from this section. Sits alongside PR #40's 09 rewrite: the 各段时长 paragraph and every other row are byte-identical, and 01-04 are unchanged. No app file is touched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
The legal dashboard's header carried a copy of §09's six-brick list. That copy drifted three times in two days — two items rewritten by PR #40 (1127e52), the third by PR #70 (30fd863) — and by the end all three described bricks this file does not implement. Replace the copy with a pointer to §09, which cannot drift. The cycle-time dataset's stage-count paragraph contrasted its counts with "the status funnel on the legal workbench", a funnel that has not existed since PR #57 made that widget a bar chart. Keep the measurement and its reason (signed_at 72 exceeds submitted_at 60; backfilled in-force book, no intake) and drop the claim that a funnel exists to contrast with. Comments only: no metadata, no behaviour, no DESIGN.md change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
Two comments quoted a 09 that has since moved — the mirror of the cards that fixed documents describing code wrongly. legal.dashboard.ts's header carried a copy of 09's six-item brick list, and the copy lost the race three times in two days: two items were rewritten by PR #40 (1127e52) and the third by PR #70 (30fd863), leaving all three describing bricks this file does not implement — the board ships review_ageing titled "In Review Over 30 Days", approval_throughput titled "Approved This Month", and a horizontal-bar. Two of them named metrics 09 now explicitly declines to deliver. The quote is removed rather than updated: updating buys correctness until the next 09 edit and leaves the same trap armed, while a pointer cannot drift. The header now says the list is deliberately absent, so the next reader does not paste it back, and cites commit shas — immutable — instead of prose. cycle-time.dataset.ts contrasted its five coverage counts with "the status funnel on the legal workbench", which has been a horizontal-bar since PR #57. The contrast is inverted rather than deleted: there is no funnel there either, and the same non-monotone book is the reason. The measurement stays — signed_at (72) exceeding submitted_at (60), and the backfill that explains it. Comments only: no metadata key, no widget, no dataset field, no dimension. These files are inside the gates' surface and the gates pass — but comments are invisible to tsc, which is why the drift went unnoticed for two days. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
09 changed direction on 2026-09-09 (1127e52, PR #40; final state 30fd863, PR #70): per-stage durations and the per-type "over SLA" are outside the V1.0 delivery surface, the legal bricks are 30-day review ageing and approval throughput, the executive position carries per-rung routing volume, and the cycle-time dataset carries stage-reached counts with no duration measure. Five comments under src/ still described the 09 that existed before that ruling, reading as "09 asks for X and we cannot deliver it" when 09 now declines X for the very reasons those comments give. The authority ran backwards: the source file was presented as falling short of the design while it is in fact what the design settled on. Each is now written as what the code delivers and why that is right, citing 09 as the authority that agrees. No measurement is deleted — Field.datetime stored as ISO text so AVG() answers an average year, the -0.85 that is the difference of two average years, ADR-0021 leaving the semantic layer no SQL and no expressions, sys_approval_request holding zero rows on a stock demo — because 09 now cites those same measurements as its reasons, and they were taken here. executive.dashboard.ts's header took #71's remedy: the copied 09 brick list is gone and a pointer replaces it, naming the one brick it advertised that this file never built so nobody pastes the list back. Three stale forward-promises went with the framing, all of them things 09 now forbids or the code does not have: - "a persisted review_due_at stamped by the daily job belongs to card 09" — 09 forbids filling the per-type breach from an application-side job, and decision #31 ruled the same way on the notification side (legal-review-sla .flow.ts already said so). - "a daily job stamping clm_contract ... Raised on the PR" for durations — same prohibition. - 'the group title says "Routing Load"' — there is no group title and no such string; the four tiles are titled "Routes: <rung>". Every citation of objectstack#16737 now carries the qualifier: the in-flight platform fix makes the wrong path ERROR rather than adding date arithmetic, so a duration stays uncomputable after it lands. It merely stops rendering a plausible fake number. Comments only: no type, filter, options, dataset field, dimension or widget id, and no line outside comment syntax changed. These three files are inside all four gates' surface and the gates pass — but comments are invisible to tsc, which is exactly why the drift went unnoticed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
…ng (#75) The 2026-09-09 maintainer ruling (PR #40, 1127e52) put per-stage durations, per-type SLA breach and approval dwell outside the V1.0 surface, and 09 now records that. Five comments still read as "09 asks for X and we cannot deliver it", which inverts the authority: the source file was presented as falling short of the design when it is in fact what the design settled on. Each now says what the code delivers and why that is right, citing 09 as the authority that agrees. The four route_* tiles ARE 09's brick at the executive position; the fixed 30-day tile IS what 09 prescribes for review ageing, with F3's reminder firing on the same threshold so the tile and the reminder cannot tell two stories; approval_throughput IS 09's brick; and the stage-reached counts with no duration measure ARE 09's bullet for the dataset. executive.dashboard.ts's header takes PR #74's remedy — the copied list out, a pointer in — naming the one brick it advertised that this file never built. No measurement is deleted. The ISO-text AVG() average year, the -0.85 difference of two average years, ADR-0021 taking no SQL or expressions, and sys_approval_request holding zero rows all stay, reframed from shortfall into the reasons 09 itself now cites. Every citation of the upstream tracker gains the qualifier that the in-flight fix makes the wrong path ERROR rather than adding date arithmetic, so a duration stays uncomputable after it lands. Three stale forward-promises inside those same comments go with them: a daily-job-stamped review_due_at said to "belong to card 09", the same route said to be "raised on the PR" — both now forbidden by 09 outright — and a claim that a group title says "Routing Load", a string that exists nowhere in the repo. Comment-only. The gates do cover these files, and an ablation shows why the drift survived anyway: restoring the three files to their pre-fix state leaves all four gates green, because tsc parses comments and reads nothing in them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
Refs #6
Refs #10
Refs #14
Refs #31
⛔ Deliberately not
Fixes. The substantive half of #6/#10/#14 is code and lands in #39 (card 09); #31 stayspm:blockedonobjectstack-ai/objectstack#16737. None of the four cards closes here.One file. Four edits recording maintainer rulings made on 2026-09-09 (batch 1, verbatim: 「第 1 批 平台的问题去平台修,业务的问题按照你的意见。」), plus two consistency edits added in rework round 1.
clm_contractfield list gainstermination_reason维护者速读(草稿)
改了什么 — 设计方案里六处「你已经拍板、但文档还写着旧话」的地方,一次改齐,只动
DESIGN.md一个文件。① 合同上补一个「终止原因」字段(多行文本,只在合同终止那一刻必填,发起表单上永远不出现);② 义务状态补一条「进行中 → 逾期」,付款期次状态补「部分付款 → 已付清 / 逾期」;③ 第 6 章 F9 删掉「发起时填了付款安排则生成付款计划」这半句;④ 第 9 章不再承诺「各段时长」和按类型的「超 SLA」,改成写明今天真正交付什么。返工轮又加了两处:⑤ 第 9 章「管理层」看板那一条原来写着「审批瓶颈(各台阶平均停留)」——它本身就是一个「各段时长」,跟同一节里刚写下的「不交付时长」自相矛盾,现在改成写明那四块砖真正显示的东西(四级审批台阶各一块,显示各台阶的路由量,不是停留时长);⑥ 第 2 章的「Insights」那一行原来指着第 9 章说「周转分析」,而第 9 章现在说不做了,这一行同步改成如实的说法。第 2 章只动这一行。为什么改 — 这几处都是文档自己跟自己打架,而且都是声明了运行时兑现不了的能力。终止守卫要求填「终止原因」,可字段清单里没有这个字段,实现只能盖终止日期;一份已经开始做的义务反而不能标逾期,而没人动过的可以;付了一半的款是个死胡同,永远结不了;F9 说发起时能填付款安排,可发起人既没有地方填、也无权写付款计划(第 4 章刻意把钱交给财务);第 9 章要的「平均周转」需要两个时间戳相减,而语义层做不了减法——早先按直觉写出来的那个版本不报错,它渲染出一个干净可信的假数
-0.85(其实是两个「平均年份」之差)。⑤⑥ 两处是同一个道理的收尾:改了一半的文档比没改的更容易误导。第 9 章一边说「不交付时长」一边还列着一个时长指标,第 2 章还在替它对外承诺,读者只会更糊涂。而且「审批瓶颈」除了平台算不了日期,还多一条自己的原因——审批阶梯的起止时间根本没地方读(标准演示数据下审批请求表零行,F5 从未运行),所以就算将来平台补上日期运算,这个数仍然出不来。这一点已经写进第 9 章,免得下一个人以为平台一修就有。风险与代价(含回滚) — 低。这是纯文档改动:四个门禁(⚠️ 请注意平台在飞的补法是拒绝那条错路而不是提供日期运算,所以修完之后时长仍然算不出来,只是不会再给假数了——这一点写在 #31 的裁定里,本 PR 只是照录。回滚:
validate/lint/typecheck/lint:i18n-gate)全部退出码 0,返工后重跑仍然全 0、告警条数一字未变(21 warnings / 5 suggestions),且没有任何门禁读DESIGN.md(tsconfig只收objectstack.config.ts与src/**/*),所以这个 diff 在结构上不可能移动它们。产品能力今天一点没变——真正的代码在 #39 落地,⑤⑥ 两处更是连代码都不涉及:看板早就是这么做的(src/dashboards/executive.dashboard.ts交付的就是四块「Routes: …」路由量砖),改的只是文档对它的描述,属于让文档追上已经发布的现实。代价是第 9 章白纸黑字少承诺了三个数:「各段时长」、按类型的「超 SLA」、「各台阶平均停留」。前两个等平台补日期能力(objectstack-ai/objectstack#16737);第三个还要额外等审批请求有数据。git revert两个 commit 即可,无迁移、无数据、无依赖。席位意见 —
你要做的 — 读一眼上面的表,确认前四条就是你 2026-09-09 拍的那四板、后两条是让同一份文档不自相矛盾;确认无误就合并(受管面,按
AGENTS.md留给你合)。Gates
Run in the worktree on
9e53a01, exit code captured before any pipe (cmd > log 2>&1; EXIT=$?):Identical to round 1 on
1127e52, including the warning counts:validateandlintprint pre-existing warnings aboutsrc/fields (clm_review.comments,clm_signature.signers, thegm_signoffempty-slate note). All namesrc/declarations this PR does not touch, and none is new.No browser verification, deliberately. This PR changes no runnable surface — it edits a design document that no gate parses and no runtime loads. There is nothing to click.
AGENTS.md's browser rule scopes itself to "every card that changes a surface a human touches"; this card changes none.Verification of the dispatch's quoted text
The dispatch quoted §03 and §06 from a reading taken today and asked me to confirm each string before editing. All four quotes matched the file byte-for-byte; every edit in both rounds was applied by exact-match replacement asserting exactly one occurrence. No stale premise.
Hunks touched, whole diff against
origin/main: line 80 (§02, the single line the rework authorized), 106 (§03 field list), 140–141 (§03 state rows), 234 (§06 F9), 297 / 302 / 307–308 (§09). §01, §04, §05, §07, §08, §10, §11, §12 and §13 are untouched.Acceptance notes
One finding, knowingly left alone:
DESIGN.md§03 are dead ends: a started obligation cannot go overdue, a partly paid instalment cannot be completed #10」 gap reference has no row in §12. The §12 table's 编号 column carries Post-signature domain:clm_obligation,clm_payment_plan, and the contract roll-ups (card 03, M1) #9, Card 09 — F9 activation · F3/F4/F10–F14 scheduled jobs · F16 executed upload (M3) #39, The demo opens on an empty screen:owner_idis NULL on all 120 seeded contracts, so 我的合同 › Launched by Me is blank for every audience #27, docs+objects: design proposal V1.0 (maintainer-confirmed), global-first, AI participation, Agiloft gap, roadmap #1, fix: make the app browsable — declareauth, pin better-auth, require browser verification #7 and [PM seat] repo:hotclm — ⏳ vacant #36 — no [Decision] Two states inDESIGN.md§03 are dead ends: a started obligation cannot go overdue, a partly paid instalment cannot be completed #10. Pre-existing, cosmetic, and unrelated to any of the four rulings, so it is left as found rather than fixed as a rider.The two findings this section carried in round 1 — §02's dangling Insights pointer and §09's contradictory 管理层 bullet — were promoted into the diff by the rework and are no longer open.
🤖 Generated with Claude Code
https://claude.ai/code/session_01R3n3GGzobdegM4HUzah1iR
Generated by Claude Code