Repository navigation
date cells: a due-like date on a completed record still renders red "Overdue Nd" (Done tasks flagged overdue) #11815
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, search
on Oct 7, 2026 objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsPath: ② the capabilities an end user meets in the app — a record's dates | 缺项 | P3
Triage: first grade,
bug·priority:p3·domain:ui·area:records·pm:queue. Direction: no overdue styling on a finished recordTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T17:39Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in
packages/fields/src/index.tsx(resolveDueLikeat:1024,isOverdueInstantat:1046) ⇒domain:ui; rationale: a Studio or console surface in objectui. Filed from the browser QA pass of 2026-10-07 (objectstack879bd38c, objectui179f6fe9); paths re-read on objectuimain9990f9e122.- Why p3: completed work reads as late. Nothing is stored wrong.
- Direction:
- skip the overdue affordance when the record is finished, judged from what the metadata already declares (a
done/completedboolean, or a terminal state where one is declared) - ⛔ A new spec key ("settled when") is a spec change in objectstack and is not in this card
- skip the overdue affordance when the record is finished, judged from what the metadata already declares (a
Clause-②: no. Patch changeset in objectui.
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsClaim: PM loop round 8
Session:session_01DrKzdPdyLLBW3qpZ4vtk7z
Account:huangyiirene
Branch:claude/issue-11815-overdue-finished-record
Worktree:objectui-issue-11815
Domain:domain:ui
Seat:domain:ui#1
File surface (line numbers oncef0eee):packages/fields/src/index.tsx: the due-like decision (resolveDueLikeabout:1024,isOverdueInstantabout:1046) and the date cell that applies the overdue affordance. The cell skips it when the record is finished, judged from what the metadata already declares: adone/completedboolean, or a terminal state where one is declared.- At most one new module-private helper that reads the record's finished state.
- The tests beside these, and
.changeset/11815-*.md.
⛔ Not on it:
- A new spec key ("settled when"). Triage
6043405462names it a spec change in objectstack, not in this card. - Any exported member's signature or props in
@object-ui/fields(packages/fields/src/index.tsxis the package entry). If the cell cannot see the record without a published prop or parameter, the dev stops and reportsneeds_decision. That would beClause-②: yes. packages/components/src/ui/**andpackages/i18n/**.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui fields: a due-like date renders red "Overdue Nd" whenever it is past, whatever the record's state, because isOverdueInstant compares only the date with today | the platform path is right: the record's done boolean or terminal state is already declared metadata | every user reading a list or record of finished work, measured by the filer (Done tasks flagged Overdue)
Thread-read: 6043405462
Serial constraints cleared:noneblocking.area:recordsin flight: seat 3's objectui#11812 (CommandPalette.tsx), and this seat's objectui#11813 (plugin-grid/src/importParsers.ts). Both are disjoint frompackages/fields/src/index.tsx.- Open objectui PRs (objectui#11856, feat(app-shell): an object leaf's Studio panel edits its list view (objectui#11823, step 1) #11868, fix(app-shell): the form designer's drag live region names labels and places, not ids (objectui#11802) #11869, fix(app-shell,console): zh names a Studio pillar by its tab label; settings label probes stop logging missing-translation warnings (objectui#11801) #11870, fix(app-shell): Studio's nav rail draws a separator as a divider and a leaf's badge as the sidebar does (objectui#11791) #11873, fix(app-shell): Studio's field inspector closes on a view switch or Escape, and a read-only package reads as read-only (objectui#11781) #11874, fix(app-shell): notify recipients render online and are picked; record field values pick their field; New automation asks for the trigger (objectui#11788) #11875 and others): none touches
packages/fields/src/index.tsx. Read 2026-10-08T03:24Z. - This seat: dispatch is parallel,
batch3 working devs, on the maintainer's word in this session's chat (「改为并行派发,batch 3」, 「继续派发」).
Why
Clause-②: no: the overdue affordance is suppressed from metadata the renderer already reads. No export, prop,@object-ui/typesmember, spec key or accepted input is added. The dev stops if that proves false.objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11815,
"status": "needs_decision",
"branch": "claude/issue-11815-overdue-finished-record",
"pr": null,
"session": "session_01DrKzdPdyLLBW3qpZ4vtk7z (the claim 6051524199 session; this subagent runs under it)",
"premise_still_valid": true,
"summary": "No PR and no code: the fence stop condition is met, and the fix is Clause-②: yes. Measured on origin/main cef0eee: the overdue affordance is decided inside DateCellRenderer and DateTimeCellRenderer (packages/fields/src/index.tsx, through resolveDueLike and isOverdueInstant), and their only inputs are the exported CellRendererProps (value, field, isEditing, onChange). Every host passes value and field only: 13 call sites in 11 files (ObjectGrid, RelatedList, DetailSection, HeaderHighlight, RecordMetaFooter, ObjectKanban, ObjectGallery, plugin-dashboard recordFields, ReportViewer, ObjectTree, console ApprovalsInboxPage). No per-row context exists, so the cell cannot see the record without a new published prop or context. The one existing record channel, useRecordContext() in @object-ui/react, is mounted only by the record page. record:related_list renders inside it and reads it for the PARENT record, so a date cell reading it would judge child rows by their parent. The declared-metadata premise also only half holds. The installed @objectstack/spec 17.7.0 declares no terminal marker on a select option: SelectOptionSchema is strict, with label, value, description, color, default and visibleWhen. It declares no final state on the state_machine rule either, which has transitions only. A dead-end list does not mean finished: showcase task done → in_progress and crm opportunity closed_lost → prospecting are both finished and both reopenable. So the only completion signal the codebase already names is the boolean set completed / is_completed / done / is_done (BooleanCellRenderer, isCompletionField). In the issue's own repro grid that boolean is not fetched: the grid's $select is id plus the view's columns (plus predicate and grouping fields), and the showcase All Tasks view does not show done.",
"mechanism_hypotheses": {
"H1": "Held. resolveDueLike and isOverdueInstant are module-private and are called by DateCellRenderer and DateTimeCellRenderer only. Both receive value and field and nothing else; there is no record, no object field map and no cell context.",
"H2": "Falsified. The row reaches the host (data-table calls col.cell(cellValue, row); ObjectGrid builds cellRenderer as (value, row)) but stops there: every host renders the cell with value and field only. No per-row React context exists in react, core, components, plugin-grid or plugin-detail. RecordContext covers the record page only, and it names the wrong record inside related lists.",
"H3": "Partly held. showcase_task declares a status select with a done option (no terminal marker; the spec has none), a done boolean, a state_machine rule that allows done → in_progress (so done is not a dead end), and an activityMilestones row (field status, value done, type completed). Its type is an open activity-row kind, not a record-state declaration. Both repro seed rows (Audit current IA, App wireframes) carry status done and done: true."
},
"tests": "No code changed, so no gate is owed: no diff, no package touched, so there is no dependency-closure build. One reproduction read ran through os-verify-lock (slot dev-11815) at cef0eee: pnpm exec vitest run packages/fields/src/tests/DateCellRenderer.test.tsx --maxWorkers=2 gave 'Test Files 1 passed (1) / Tests 8 passed (8)' and VERDICT command-exit 0. Its existing pin 'labels a past due_date as "Overdue Nd" and colors it red' renders DateCellRenderer with value daysAgo(6) and field type date, name due_date. That is the issue's App wireframes case, and it gets 'Overdue 6d' with text-red-600 from the only two inputs the cell has. Gates, deviations, files_changed and head are in the keys below.",
"gates": [
{
"cmd": "bash /home/user/objectstack/scripts/pm/os-verify-lock.sh -c 'pnpm exec vitest run packages/fields/src/tests/DateCellRenderer.test.tsx --maxWorkers=2'",
"exit": 0,
"verdict": "os-verify-lock: VERDICT command-exit 0 (Tests 8 passed (8))",
"head": "cef0eee"
}
],
"deviations": [
"No PR, no changeset and no merge of origin/main. This is the fence needs_decision stop, and the merge is owed only before a final gate union, which there is none of. The branch was pushed empty at cef0eee as the write probe and the claim landing mark. The worktree /home/user/objectui-issue-11815 is left in place, clean.",
"The ruling and H3 presumed the spec declares terminal select options and object state machines with final states. Measured, it declares neither (summary). Reported here; I did not pick a route around it."
],
"files_changed": [],
"head": "cef0eee (worktree clean; branch equals origin/main)",
"mcp_calls": "0. No MCP GitHub tool was called, read or write. Reads went through gh api REST GETs: issue 11815 and its comments, and the comments of issue 11676.",
"api_writes": "1 relay write as objectstack-fleet[bot]: this os-dev-report comment via post-stamped.mjs (POST /repos//issues/11815/comments, carried by POST /repos/objectstack-ai/objectstack/dispatches). No pr_create, no label write, no assignee write. Plus one git push of the empty branch, which is not REST.",
"open_questions": [
{
"question": "Q1 - how does a date cell learn that its row is finished? Every route that reaches the grid where the defect was measured adds a published input to @object-ui/fields (Clause-②: yes).",
"options": [
"A2 - add one optional boolean prop to the exported CellRendererProps (name to be ruled). Each host computes it once per row through ONE shared logic-only helper in @object-ui/core, from the row and the object schema it already holds. DateCellRenderer and DateTimeCellRenderer then skip only the red class and the Overdue wording; the date text stays. Business: the hosts already hold the row at the cell site. Long-term: cells stay pure value renderers, the judgement has one home, and the prop is additive. AI: nothing new for an app author to write. Startup: about 13 call sites in 11 files across 8 packages for a P3, plus a projection harvest wherever the signal field is not a shown column.",
"A - add an optional record (row values) prop to CellRendererProps and let the cell judge. Business: the same reach as A2. Long-term: weaker. Judging a declared option marker also needs the object field definitions, so a second schema prop follows, and every cell can then read every field of the row. AI: neutral. Startup: the same host cost as A2, with a wider published surface.",
"C - read the existing useRecordContext() in the two cells; Clause-② stays no. Refused on measurement. Only the record page mounts it, so the issue repro (the Tasks grid) is untouched. And record:related_list renders inside it reading the PARENT record, so a finished project would hide the overdue styling of its unfinished tasks; the showcase project Tasks related list shows due_date. Long-term and AI: it gives a wrong answer that looks right.",
"D - no change in objectui until Q2 has a declared signal. This follows the objectui#11676 timeline precedent: a due-date judgement is a new card that declares its signals in the spec first. Business: completed rows keep reading as late (P3; nothing is stored wrong). Startup: zero cost."
],
"recommendation": "A2, after Q2 is ruled. Business: it is the only route that reaches the grid where the defect was measured. Long-term: one home for the judgement, and the cells stay value renderers. AI: there is no new author-facing key. Startup: the plumbing is wasted if Q2 picks no signal, so D holds until Q2 is ruled."
},
{
"question": "Q2 - what declared metadata says a record is finished? The ruling assumed the spec declares terminal options or final states. Measured on @objectstack/spec 17.7.0, it declares neither.",
"options": [
"S2 - a spec-declared terminal marker on a select option, filed as an objectstack spec card (triage put the new key out of this card). The spec already declares the idea at component level: record:path stages[].terminal (won or lost). Business: three measured producers carry a due-like date. showcase task has status done and a done boolean. app-todo task has status completed only; its is_completed boolean was removed on purpose in objectstack#7226 because nothing maintained it, and the app teaches status as the completion signal. app-crm activity has status completed only. S2 reaches 3 of 3 once authored. Long-term: contract-first, declaration over inference. AI: SelectOptionSchema is strict, so the key is checked at publish, and the runtime honours what is declared. Startup: one new spec key with a measured consumer (this card), across two repos.",
"S1 - the completion booleans the codebase already names (completed, is_completed, done, is_done in BooleanCellRenderer isCompletionField), read as value === true. Business: it reaches 1 of 3 measured producers (showcase only). In the repro grid the boolean is not in the row, so hosts must also harvest it into the projection, gated on declared fields and FLS like the objectui#7179 grouping harvest. Long-term: name inference, the shape objectui#11676 refused for the timeline: 'a guess here reads like a declaration and is wrong for every object that spells either one differently'. AI: an app that spells is_closed, or carries status only, gets nothing and no signal. Startup: no spec change.",
"S3 - read a state_machine dead end (an empty transitions list) as terminal. Refused on measurement: a dead end means not reopenable, not finished. showcase task done → in_progress and crm opportunity closed_lost → prospecting are both finished and reopenable, so the repro Done tasks would stay red."
],
"recommendation": "S2. Business: it is the only signal that reaches all three measured producers. Long-term and AI: it is declared and checked at publish. S1 does not stand alone: it reaches 1 of 3 producers, needs a projection change and is name inference. It could ride in the same helper only because the codebase already names those booleans. If the maintainer prefers no spec growth at this stage (startup axis, P3), then D under Q1 is the honest answer."
}
],
"out_of_scope_findings": []
}objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actions待裁:已完成的记录,日期还显示红色「逾期」——用什么声明判定「已完成」,单元格又如何得知
domain:ui执行席 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· 2026-10-08T03:35Z。依据 dev 实测报告6051620515(在maincef0eee上测得)。Release:
session_01DrKzdPdyLLBW3qpZ4vtk7z(席位domain:ui#1,账号huangyiirene)释放认领6051524199。原因: 认领围栏的停止条件已触发,修复属于Clause-②: yes。去向: 本卡改挂needs-user-decision,清空 assignee,退出活动队列。一句话问题
一条已经完成的任务,截止日期仍显示红色的「逾期 N 天」。修好它需要两件平台目前都不具备的东西:一个声明「这条记录已完成」的信号,以及把这个信号送到日期单元格的通道。两者都会扩大公开契约。
背景(实测)
- 逾期样式在
@object-ui/fields的DateCellRenderer/DateTimeCellRenderer内部判定(resolveDueLike+isOverdueInstant)。单元格唯一的输入是导出的CellRendererProps(value、field、isEditing、onChange)。 - 宿主共有 13 个调用点,分布在 11 个文件、8 个包(ObjectGrid、RelatedList、DetailSection、Kanban、Gallery、ReportViewer、dashboard 等),全部只传
value和field。行数据到了宿主,但没有传进单元格,也没有按行提供的 React context。 - 唯一现成的记录通道
useRecordContext()只在记录页挂载。而且在相关列表里它指向父记录:一个已完成的项目,会把它名下未完成任务的逾期样式也藏掉。所以不能用。 @objectstack/spec17.7.0 的SelectOptionSchema是 strict 的(label/value/description/color/default/visibleWhen),没有终态标记。state_machine也只有transitions,没有终态。用「没有出边」来推断也不成立:showcase 的 taskdone → in_progress、crm 的 opportunityclosed_lost → prospecting,这两个状态都算完成,又都能重开。- 代码里唯一已有的完成信号,是
BooleanCellRenderer的isCompletionField认的布尔名(completed/is_completed/done/is_done)。 - 三个实测产出方都带「像截止日」的日期字段:
- showcase task:既有
status=done,也有done布尔; - app-todo task:只有
status=completed,它的is_completed已在 objectstack#7226 有意删除; - app-crm activity:只有
status=completed。
- showcase task:既有
- 在 issue 复现的那个网格里,
done布尔并没有被查询出来($select= id + 视图列)。
Governing text
- triage 定级
6043405462:「skip the overdue affordance when the record is finished, judged from what the metadata already declares」,并且「⛔ A new spec key ("settled when") is a spec change in objectstack and is not in this card」。 - 先例 objectui#11676 裁决 A(
6011959066):时间线在没有声明信号之前,不做「逾期」判断。理由是「a guess here reads like a declaration and is wrong for every object that spells either one differently」。 - 协议声明:spec 和代码不一致时,默认改代码去对齐。本题是 spec 缺一个声明,要补就得单独在 objectstack 立 spec 卡,⛔ 不能作为本缺陷卡的实现选项。
前提(每条附 re-check 命令;复核时逐条跑)
- 单元格只拿到 value 和 field。
re-check:git -C /home/user/objectui grep -n "export interface CellRendererProps" origin/main -- packages/fields/src,然后读该接口的成员。阳性对照词:isEditing。 - spec 的 select 选项没有终态键。
re-check:git -C /home/user/objectstack grep -n "SelectOptionSchema" origin/main -- packages/spec/src | head,然后读该 schema 的键表。阳性对照词:visibleWhen。 - 网格不会多查视图之外的列。
re-check:读ObjectGrid拼$select的那一处。阳性对照词:$select。
选项(一次裁清 Q1「通道」与 Q2「信号」)
选项 做什么 客户看得到的后果 A objectstack 给 select 选项加一个终态标记(spec 卡;键名在 spec 卡里定)。objectui 给 CellRendererProps加一个可选布尔 prop,由@object-ui/core里唯一的 helper 按行算出(从行数据和对象 schema 算),各宿主透传。单元格只是在这个 prop 为真时不加红色和「逾期」字样,日期本身照常显示。三个实测产出方在声明终态后都不再误报;作者在发布时就会被校验。代价:跨两个仓库;约 13 个调用点;没被查询的信号字段,还要宿主补进查询(按 FLS 过滤)。 B 不改 spec,只认已有的完成布尔名(S1)。通道仍走 A 的那个 prop。 只覆盖 1/3 的产出方(showcase)。只有 status、或拼写不同的应用,什么也得不到,而且没有任何提示。 C 先不改。本卡挂 pm:on-hold,等 spec 声明了终态信号再做。已完成任务继续显示红色逾期(P3,不会存错任何数据)。零成本。 业务含义直译:
- A 等于给「状态」这个下拉框补上「哪几个值算结束」的标记,再让列表据此不标红。Salesforce 的 picklist 值带
IsClosed,Jira 的状态分为 To Do / In Progress / Done 三个类别,都是这样做的。 - B 等于按字段名猜:猜中的应用修好了,猜不中的应用照旧标红,也不会有人告诉你。
- C 等于先接受这个小瑕疵,等平台能声明「完成」再一次修对。
已否决的路线(实测排除):
- 读
useRecordContext:在相关列表里会拿父记录的状态去判断子记录,给出看似正确的错误答案。 - 把状态机里「没有出边」的状态当终态:可重开的完成态(例如 done)会照旧标红。
四棱
os-decision-facets ① 项目长远合理性:A 收窄特例——「完成」由声明决定,单元格只管渲染值,判断只有一个地方;B 增加按名字猜的特例(与 #11676 的先例相冲);C 中性。 ② 实际业务拉动:今天有人撞上——三个示例应用都有截止日期,复现截图里 Done 的任务显示红色;但这是 P3,不会写错任何数据。 ③ 防 AI 犯错:A 是闭合声明(strict schema,发布时校验),出错时会被明确拒绝;B 是静默容忍,拼写不同的应用悄悄失效,没人知道。 ④ 创业阶段不扩散:A 增加一个 spec 键和一个可选 prop,都是永久义务;C 零增量;B 不加 spec 键,但加一个 prop,还要长期维护一份名字表。Prior rulings read:
overdue completed done terminal option→ 2 hits(objectui#11815、#11676);objectstackselect option terminal marker final state→ 0;ADR none;thread: #11676 ruling6011959066推荐
A。两年后,「已完成」应当是状态选项上的一个声明(参照 Salesforce picklist 的
IsClosed、Jira 的状态类别),所有显示截止日期的地方都读这一个声明。- 只看①选 A;②③④ 是否翻转:否。④(创业期不扩散)只调整分期:先在 objectstack 落 spec 键,等 objectui 能安装到含该键的版本,再做单元格通道。
- 回退:C。 如果维护者认为现阶段不值得为一个 P3 增加 spec 键,本卡挂
pm:on-hold,写明Restart-when:为该 spec 卡关闭。 - 置信缺口: 没测过 report、kanban 等宿主在信号字段不在列中时,补查询要多大代价。也没测第三方应用里「完成」的其他拼写有多常见。
裁后执行(维护者只需裁方向)
- 裁 A:
- 本席在 objectstack 立 spec 卡(选项终态标记),回链本卡。
- 本卡改挂
pm:blocked,并加Blocked-by:指向那张 spec 卡。 - spec 发布、objectui 能安装到之后,重新认领本卡:
@object-ui/core的 helper 加CellRendererProps的可选 prop 加宿主透传。若规模过大,按宿主拆成子卡。
- 裁 B: 直接重新认领,用
Clause-②: yes认领(新增可选 prop),信号只认已有的布尔名。 - 裁 C: 本卡改挂
pm:on-hold,写明Restart-when: closed <spec 卡>,不立 spec 卡。
Generated by Claude Code
- 逾期样式在
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsRuling: batch #291 item 2 · letter D · maintainer 「同意」 2026-10-08T07:26Z
Director seat, summon #35, objectstack-ai/objectstack#12708,
session_01VYToj6PQehTEKNrjGM9akg(GitHubos-zhuang; written asobjectstack-fleet[bot]via the relay). Presented in batch #291 from thedomain:uiseat's decision request (6051653391): A a terminal marker on select options plus a cell channel, B existing boolean names only, C hold. The maintainer pushed back — 「每个状态不是可以自己配置颜色吗?done 配置为红色不是元数据的 bug 吗?为什么平台要兜一圈」 — and the seat's reading of the code answered: the red is the date cell's own affordance (not the status colour), decided from two guesses and never from the record;dueLikeis not a protocol key (objectui#9738) and the cell also guesses "due-like" from a field-name regex. The seat then put a fourth option, D, declared-only overdue; the maintainer asked how mainstream platforms do it (answered: monday.com's Deadline Mode links the date to a status whose Done labels settle it; ServiceNow and Salesforce never guess, the author declares a rule; terminal states live on the status values) and whether a field-levelconditionalFormattingshould carry such cases (answered: a deadline is a semantic, a style rule cannot produce the wording and would be re-authored per view; a field-level block is right for presentational rules without a semantic, filed as its own card), and answered 「同意」. Thread-read: 6051653391. Freshness: no comment since the presentation.The ruling
D — declared-only overdue. A date is a deadline only when its field declares
dueLike; the declaration carriessettledWhen, a per-record CEL predicate in thevisibleWhenfamily, and when it holds the deadline is settled: no overdue wording, no overdue colour. The field-name regex inresolveDueLikeretires (ADR-0049: nothing undeclared paints). The host evaluatessettledWhenagainst the row and hands the cell one optional boolean prop; the cell paints from the declaration alone. ⛔ Not taken: A (a protocol-level terminal concept on select options — not refused for ever;settledWhencan read such a marker if one is declared later), B (guessing by boolean names, the #11676 precedent), C (keep the red).One correction to the seat's own presentation. The seat called D "objectui only". It is not: the protocol's view schemas are strict with the passthrough window shut, so an application validated by
@objectstack/spec— the example apps, hotcrm — cannot authordueLikeat all today; the only way a date goes red is the name guess. The declaration therefore enters the protocol first, on the date and datetime field definitions, as objectstack-ai/objectstack#22227 (domain:spec,Clause-②: yes, filed in this act with the example apps' declarations in scope). This card is blocked by it.Prior rulings read: objectui#11676 ruling A 6011959066 (no overdue judgement without a declared signal), objectui#9738 ruling A 5731679919 (
dueLikeobjectui-owned until the protocol claims it — the protocol claims it now), triage 6043405462 → 3 hits; ADR-0049; thread: 4 comments. 自检: 只看①选 D(删掉平台的猜测、语义落在本体);②③④ 是否翻转:否。置信缺口:仓外应用依赖正则标红的有多少,未测。State
needs-user-decision→pm:blockedin this act; body lineBlocked-by: objectstack-ai/objectstack#22227; the unlock scan returns it to the queue when the spec card closes.- Then the
domain:uiseat re-claims withClause-②: yes(one optional prop onCellRendererProps; the published@object-ui/typesface follows the spec): retire the regex, readdueLikeand the host-evaluatedsettledWhenthrough the one helper in@object-ui/core, decide whether the mirror's view-leveldueLikeretires or stays as an override, pins beside the cells,@object-ui/fieldsand@object-ui/typeschangesets. - The companion card for presentational rules without a semantic, field-level
conditionalFormatting, is spec(ui): field-level conditionalFormatting — a field declares[{ condition, style }]cell rules (CEL overvalueandrecord), the row block's own grammar, for presentational rules that carry no semantic (maintainer-directed) objectstack#22228; it does not block this card. - The
Ruled:line is added to the body in the same act.
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsBlocked audit: objectstack-ai/objectstack#22227 closed, so the card moves
pm:blocked→pm:on-hold. The hold is now only the install faceTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-09T18:55Z. ⛔ Not a claim, ⛔ not a dispatch.Thread-read: 6054882132
-
What closed: spec(data): a date or datetime field declares its deadline semantic —
dueLikewithsettledWhen(per-record CEL), so overdue wording and colour derive from one declaration and the name-pattern guess retires (objectui#11815 ruled D) objectstack#22227 closedcompleted.dueLikeandsettledWhenlanded as215e66204a(PR feat(spec,lint): a date or datetime field declares its deadline: dueLike and settledWhen objectstack#22503). -
Why on hold, not queued:
6054882132said the unlock scan returns this card to the queue when the spec card closes. The cross-repo rule keys the unlock on the install face, not on the card:215e66204ais on the v18 line only, and npmlatestis 17.7.0, with no 18.x published;- objectui pins
@objectstack/spec^17.6.0.
So the console cannot yet read a
dueLikethe server serves, and the optionalCellRendererPropsprop would follow a spec face objectui has not installed. The precedents are objectui#11824 and objectui#11862. -
Restart-when: objectui's
@objectstack/specresolves a release that carries215e66204a. -
Then, as
6054882132set: thedomain:uiseat re-claims withClause-②: yes. It retires the regex, readsdueLikeand the host-evaluatedsettledWhenthrough the one helper, decides the mirror's view-leveldueLike, and adds pins beside the cells.
-
Ruled: 6054882132 · letter D · 2026-10-08T07:27Z
Blocked-by: objectstack-ai/objectstack#22227
Filing gate ① — product defect with a named location and a reproduction. reach: showcase Tasks grid: Audit current IA (Status Done) shows Due Date
Sep 19in red; App wireframes (Done) showsOverdue 6din red.Who acts on it: objectui triage → the console / records owner. ⛔ Not a claim. Found in a manual browser QA pass of the end-user console on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue,然后继续测试前端」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
A due-like date is styled overdue whenever it is in the past, regardless of whether the record is finished, so completed work reads as late. Within a short window the text is relative ("Overdue 6d"), beyond it absolute ("Sep 19") — both red.
Where it comes from (read in source)
resolveDueLikeinfields/src/index.tsxdecides "due-like" fromdueLike: trueor the field-name pattern (due,deadline,expires, …);isOverdueInstantthen compares only the date with today. Nothing consults the record's state.Expected
No overdue styling once the record is closed (a terminal status option, a
done/completedboolean, or an author-declared condition).Suggested direction (triage to rule)
Let
dueLiketake a "settled when" condition (or infer from a status field's terminal option / adoneboolean), and skip the overdue affordance when it holds.Environment
objectstack
879bd38c·examples/app-showcasebooted withobjectstack dev --ui --seed-adminon an isolated port and SQLite file · objectui179f6fe9(HEAD; the framework pin.objectui-shaisa58626c8) served by the console's Vite dev server, perf numbers from avite buildof the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform adminadmin@objectos.aiunless stated.Duplicate check
timeline.bucket.overduekey (objectui#11676) #11716 in plugin-timeline only (predates objectui 179f6fe), so the date-cell renderer was never covered: a different surface, not a regressionDedupe words: overdue red completed record · dueLike done task overdue · due date styling closed status
Filed by Claude Code (session
session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.Decision facets (added by
domain:uiseat 1,session_01DrKzdPdyLLBW3qpZ4vtk7z, from its analysis6051653391on this card)os-decision-facets
① 项目长远合理性:A 收窄特例——「完成」由声明决定,单元格只管渲染值,判断只有一个地方;B 增加按名字猜的特例(与 #11676 的先例相冲);C 中性。
② 实际业务拉动:今天有人撞上——三个示例应用都有截止日期,复现截图里 Done 的任务显示红色;但这是 P3,不会写错任何数据。
③ 防 AI 犯错:A 是闭合声明(strict schema,发布时校验),出错时会被明确拒绝;B 是静默容忍,拼写不同的应用悄悄失效,没人知道。
④ 创业阶段不扩散:A 增加一个 spec 键和一个可选 prop,都是永久义务;C 零增量;B 不加 spec 键,但加一个 prop,还要长期维护一份名字表。
Prior rulings read:
overdue completed done terminal option→ 2 hits(objectui#11815、#11676);objectstackselect option terminal marker final state→ 0;ADR none;thread: #11676 ruling6011959066推荐 A,回退 C。只看①选 A;②③④ 是否翻转:否(④只调分期:先落 spec 键,再做单元格通道)。
置信缺口:没测过 report、kanban 等宿主在信号字段不在列中时补查询的代价,也没测第三方应用里「完成」的其他拼写有多常见。完整分析见
6051653391。Generated by Claude Code