Skip to content

Record four maintainer rulings in DESIGN.md §03, §06 and §09 - #40

Merged
zhuangjianguo merged 2 commits into
mainfrom
claude/issue-6-design-rulings
Sep 10, 2026
Merged

zhuangjianguo merged 2 commits into
mainfrom
claude/issue-6-design-rulings

Conversation

@claude

@claude claude Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

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 stays pm:blocked on objectstack-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.

Card Ruling Edit Section
#6 A clm_contract field list gains termination_reason §03
#10 1A + 2A two state-table rows gain three edges §03
#14 A F9 loses the intake-payment clause; §03 gains nothing §06
#31 2B (rider) §09 states what is delivered, names the platform card §09
#31 2B (rework r1) 管理层 bullet made consistent with that paragraph §09
#31 2B (rework r1) Insights row stops promising 周转分析 §02

维护者速读(草稿)

席位按自己对 diff 的读数校正后,作为评论发布定稿。

改了什么 — 设计方案里六处「你已经拍板、但文档还写着旧话」的地方,一次改齐,只动 DESIGN.md 一个文件。① 合同上补一个「终止原因」字段(多行文本,只在合同终止那一刻必填,发起表单上永远不出现);② 义务状态补一条「进行中 → 逾期」,付款期次状态补「部分付款 → 已付清 / 逾期」;③ 第 6 章 F9 删掉「发起时填了付款安排则生成付款计划」这半句;④ 第 9 章不再承诺「各段时长」和按类型的「超 SLA」,改成写明今天真正交付什么。返工轮又加了两处:⑤ 第 9 章「管理层」看板那一条原来写着「审批瓶颈(各台阶平均停留)」——它本身就是一个「各段时长」,跟同一节里刚写下的「不交付时长」自相矛盾,现在改成写明那四块砖真正显示的东西(四级审批台阶各一块,显示各台阶的路由量,不是停留时长);⑥ 第 2 章的「Insights」那一行原来指着第 9 章说「周转分析」,而第 9 章现在说不做了,这一行同步改成如实的说法。第 2 章只动这一行。

为什么改 — 这几处都是文档自己跟自己打架,而且都是声明了运行时兑现不了的能力。终止守卫要求填「终止原因」,可字段清单里没有这个字段,实现只能盖终止日期;一份已经开始做的义务反而不能标逾期,而没人动过的可以;付了一半的款是个死胡同,永远结不了;F9 说发起时能填付款安排,可发起人既没有地方填、也无权写付款计划(第 4 章刻意把钱交给财务);第 9 章要的「平均周转」需要两个时间戳相减,而语义层做不了减法——早先按直觉写出来的那个版本不报错,它渲染出一个干净可信的假数 -0.85(其实是两个「平均年份」之差)。⑤⑥ 两处是同一个道理的收尾:改了一半的文档比没改的更容易误导。第 9 章一边说「不交付时长」一边还列着一个时长指标,第 2 章还在替它对外承诺,读者只会更糊涂。而且「审批瓶颈」除了平台算不了日期,还多一条自己的原因——审批阶梯的起止时间根本没地方读(标准演示数据下审批请求表零行,F5 从未运行),所以就算将来平台补上日期运算,这个数仍然出不来。这一点已经写进第 9 章,免得下一个人以为平台一修就有。

风险与代价(含回滚) — 低。这是纯文档改动:四个门禁(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);第三个还要额外等审批请求有数据。⚠️ 请注意平台在飞的补法是拒绝那条错路而不是提供日期运算,所以修完之后时长仍然算不出来,只是不会再给假数了——这一点写在 #31 的裁定里,本 PR 只是照录。回滚: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=$?):

validate=0 lint=0 typecheck=0 i18n-gate=0

Identical to round 1 on 1127e52, including the warning counts:

$ pnpm typecheck
> tsc --noEmit
(no output)

$ pnpm lint
  21 warning(s), 5 suggestion(s) (901ms)

$ pnpm lint:i18n-gate
✓ i18n gate
  LOCALES  : "en", "zh-CN" checked (required: en, zh-CN)
  REACH    : 12 surface classes walked — object=34 · field=271 · option=188 · section=35 ·
             view=37 · action=41 · app=2 · navigation=28 · dashboard=6 · widget=38 ·
             dataset=70 · page=2
  COVERAGE : 0 missing keys across 2 locale(s)

validate and lint print pre-existing warnings about src/ fields (clm_review.comments, clm_signature.signers, the gm_signoff empty-slate note). All name src/ 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:

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

…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

Copy link
Copy Markdown
Collaborator

维护者速读(终稿)

席位已按自己对 diff 的读数校正草稿并填入席位意见。这份评论是给你读的那一份,PR 正文里的草稿不必再看。
复核结论在 #6(ACCEPT,head 9e53a01,CI 2/2 绿)。⛔ 受管面,本席不合,等你。

改了什么 — 只动 DESIGN.md 一个文件,六处,+10/−8。

# 章节 改动 出处
① §03 字段清单 合同上补「终止原因」(多行文本,只在终止那一刻必填,发起表单上永不出现) 你裁 #6 → A
② §03 状态表 义务补「进行中 → 逾期」;付款期次补「部分付款 → 已付清 / 逾期」 你裁 #10 → 1A+2A
③ §06 F9 删掉「发起时填了付款安排则生成付款计划」半句,且不补任何替代句 你裁 #14 → A
④ §09 不再承诺「各段时长」与按类型「超 SLA」,改写成今天真正交付什么 你裁 #31 → 2B
⑤ §09 管理层 「审批瓶颈(各台阶平均停留)」→「各台阶路由量(读 F2 盖的 route_* 标志;是流量,不是停留)」 返工轮,见下
⑥ §02 第 80 行 Insights 那行不再对外承诺「周转分析」 返工轮,见下

为什么改 — 前四条是把你今天拍的板记进文档。共同点是:它们都曾声明了运行时兑现不了的能力——守卫要求填终止原因而字段不存在;已经在做的义务反而不能标逾期;付了一半的款永远结不了;F9 说发起时能填付款安排,而发起人既无处填也无权写;第 9 章要的平均周转需要两个时间戳相减,而语义层做不了减法,早先按直觉写出来的版本不报错、渲染出一个可信的假数 -0.85(实为两个「平均年份」之差)。

⑤⑥ 是我在复核时打回加的,理由是改了一半的文档比没改的更容易误导:第 9 章一边宣布「不交付时长」,一边还列着一个时长指标;第 2 章还在替它对外承诺。

风险与代价(含回滚) — 低,且我核过它为什么低。四个门禁全 0,返工后重跑仍全 0 且告警条数一字未变(21 warnings / 5 suggestions);没有任何门禁读 DESIGN.md(tsconfig 只收 objectstack.config.ts 与 src/**/*),所以这个 diff 在结构上不可能移动它们。产品能力今天零变化——代码在 #39 落地;⑤ 更是连代码都不涉及,看板本来就是那么做的(src/dashboards/executive.dashboard.ts 交付的就是四块路由量砖),改的只是文档对既有事实的描述。

代价是白纸黑字少承诺了三个数:各段时长、按类型的「超 SLA」、各台阶平均停留。⚠️ 两点你该知道:

  1. 前两个等平台(objectstack-ai/objectstack#16737),但平台在飞的补法是「拒绝」而不是「提供」——修完之后仍然算不出时长,只是不再给假数。
  2. 第三个(各台阶平均停留)还多一条与平台无关的原因,是返工轮查出来的:审批台阶的起止无处可读,sys_approval_request 在标准演示数据下零行,F5 审批阶梯从未运行过。所以就算平台补上日期运算,这个数仍然出不来。已写进 §09,免得下一个人以为平台一修就有。

回滚:git revert 两个 commit,无迁移、无数据、无依赖。

席位意见 — 建议合并,理由三条,也附一条我自己的越界申报。

  • 它只做了记录,没有夹带。 我逐行读了 diff:七处 hunk 全落在 §02/§03/§06/§09,§01、§04、§05、§07、§08、§10–§13 一行未动。Decision: where does the intake-captured payment arrangement F9 reads actually live? #14 的裁定 A 是一次纯删除——最容易被悄悄软化成一句「以后可能要读」的地方,它没有。
  • ⑤ 是这轮最有价值的产出,而且超出了我的要求。 我只要求「让 §09 别自相矛盾」,返工回来的却多查出了那条与平台无关的第二原因(审批请求零行)。这把一个「等平台就好了」的错误预期提前掐掉了。
  • ⛔ 我自己越界了一行,申报在此。 我原本明令 dev 不许碰 §02,返工时为 ⑥ 放开了一行——因为是这个 PR 把那个指针弄悬空的,把矛盾留到以后正是这几张卡本身在反对的模式。就这一行,§02 其余未动,我已核对。你若认为不该动,砍掉 ⑥ 那一行即可,其余五处独立成立。

你要做的 — 确认①–④就是你今天拍的那四板、⑤⑥是让同一份文档不自相矛盾,然后合并这个 PR(受管面,按 AGENTS.md 归你合)。


Generated by Claude Code

@zhuangjianguo
zhuangjianguo marked this pull request as ready for review September 9, 2026 15:49
This was referenced Sep 9, 2026
@zhuangjianguo
zhuangjianguo merged commit 296fab8 into main Sep 10, 2026
2 checks passed
zhuangjianguo pushed a commit that referenced this pull request Sep 10, 2026
§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
zhuangjianguo pushed a commit that referenced this pull request Sep 10, 2026
…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
zhuangjianguo pushed a commit that referenced this pull request Sep 10, 2026
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
zhuangjianguo pushed a commit that referenced this pull request Sep 10, 2026
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
zhuangjianguo pushed a commit that referenced this pull request Sep 10, 2026
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
zhuangjianguo pushed a commit that referenced this pull request Sep 10, 2026
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants