You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Overdue tasks no longer read as overdue on @objectstack 18.2: declare dueLike / settledWhen on duly_task.due_date #151
Filing gate: ① product defect, user-visible, reproduced in a browser (regression from the 18.2 upgrade, #144).
What happened
On main at c20d397 (@objectstack/* 18.2.0), pnpm demo, Chromium, signed in as the demo admin:
Surface
17.3.0 (74342a1, same demo)
18.2.0 (c20d397)
My week, Emissions return — Northgate, due yesterday
Yesterday, in red
Oct 26, plain black
Task record header, Due
Yesterday, in red
Yesterday, plain black
Board card, Due
—
Yesterday, plain
So an overdue task no longer looks overdue anywhere a person reads their week. That is the screen the product is built around.
Why
src/views/task.view.ts (the my_week block, "The due column needs no format key") relies on a behaviour measured on console 17.2: the date cell guessed "this is a deadline" from the field NAME (due_date matches /(^|_)(due|deadline|…)(_|$)/) and rendered relative, red-when-past wording.
@objectstack/spec 18 replaced the guess with a declaration (spec CHANGELOG, change 215e662):
dueLike: true on a date / datetime field declares it a deadline. When it is absent, nothing is inferred from the name.
settledWhen (CEL over record) says when the deadline no longer counts, so done or skipped rows stop reading as overdue.
grep -rn "dueLike\|settledWhen" src on main returns nothing, so 18.2's console treats due_date as a plain date.
Fix direction
src/objects/task.object.ts: on due_date, add dueLike: true and settledWhen: P\record.status in ['done', 'skipped', 'cancelled']``. The second key is an improvement over 17.x, where a done task's past date still read red.
Decide the same for duly_assignment.due_date, which is a deadline too.
Rewrite the stale comment in task.view.ts.
Pin it. A test asserts the field declares dueLike with a settledWhen that parses, so the next upgrade cannot drop it silently.
pnpm validate judges the CEL (@objectstack/lint field-rule pass).
Acceptance
In pnpm demo on 18.2, My week shows the overdue task's due date in the overdue style with relative wording. A task completed after its due date does not.
Business reason
Who benefits: every task owner, and every manager reading Late, Board or My week. The scenario: a person opens My week and must see what is already late without reading dates. Without the fix, late work looks the same as work due next month, and the reminders are the only signal left.
Reader
The duly pm-dispatch seat dispatches this to a dev (small, metadata plus one test).
Duplicate check
dueLike overdue date red due_date relative rendering lost in objectstack-ai/duly: 0 hits, open or closed.
Evidence
Screenshots in the project's shared folder duly-18.2-browser-check/: v173/01-my-week.png and v173/task-record.png (17.3), en-US/01-my-week.png and en-US/21-task-record.png (18.2).
First touch by the duly lane seat at 2026-10-27T11:30Z (session session_011HyoSXGRy6L13mYq1Hp4n1).
Graded:priority:p1, size S, pm:ready. This is a regression from Upgrade to @objectstack 18.2.0 #144, and the seat's ACCEPT on Upgrade to @objectstack 18.2.0 #144 missed it: the PR's tests and gates cannot see how a date renders. It hits My week, the screen the product is built around.
Responsibility: the app. Spec 18 replaced the platform's name-based guess with a declaration the app has to make, so this is not a platform defect.
Scope as filed, plus three rulings:
duly_assignment.due_date also gets dueLike, with its own settledWhen matched to the assignment's status set. It is the same kind of deadline, so leaving it out would leave the same bug one screen away.
Before choosing the settledWhen set, check it against every terminal value of duly_task.status in src/objects/task.object.ts. Do not copy it from this card.
The pin test reads the compiled artifact or the object metadata, not a source grep.
Acceptance adds: a browser check on 18.2 in pnpm demo with en and zh-CN screenshots of My week, showing one overdue open task styled as overdue and one done task past its date styled plainly.
Claim: PM loop round 2
Session: session_011HyoSXGRy6L13mYq1Hp4n1
Account: os-warren (the seat's linked user; the card's assignee)
Branch: claude/project-thread-na7mq9 (platform-assigned card-thread branch, at origin/mainc20d397)
Worktree: duly-issue-151
Domain: n/a. objectstack-ai/duly is a single-lane app repo with no domain:*.
Seat: repo:duly#1
File surface: src/objects/task.object.ts, src/objects/assignment.object.ts, src/views/task.view.ts, test/due-like.test.ts (new). Stop on any breach and explain it in the report.
Container & model: S, mode:thread, model: TIER_DEFAULT (hand-derived), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: the app. Spec 18 requires the declaration; see the seat triage.
Thread-read: 6440813957
Premise: holds. grep -rn "dueLike\|settledWhen" src on c20d397 returns nothing (the card measures this).
Serial constraints cleared: #150 is in flight on src/data/demo-catalog.ts, src/data/demo-history.ts and test/demo-calendar.test.ts, and #152 on src/data/demo-org.ts, a test and docs/getting-started.md. Neither intersects this surface.
Claim amendment (2026-10-27T11:39Z): File surface adds src/translations/authored-text.ts. Declaring settledWhen adds a CEL value envelope on the field, and test/i18n-coverage.test.ts needs verdicts for object.fields{}.settledWhen.dialect and .source. These are two machine(...) entries, next to the existing per-option visibleWhen ones. No open card touches that file (#150 and #152 checked), so no serial constraint changes.
{
"issue": 151,
"status": "done",
"branch": "claude/project-thread-na7mq9",
"pr": "https://github.com/objectstack-ai/duly/pull/153",
"session": "session_01JQwxbZCHwAE9M9pfaL3X4G",
"premise_still_valid": true,
"summary": "duly_task.due_date and duly_assignment.due_date now declare dueLike: true with settledWhen over each object's terminal statuses: task record.status in ['done','skipped','cancelled'] (open and in_progress are the only live values), assignment record.status == 'closed' (draft and dispatched stay live). The stale my_week comment in task.view.ts is rewritten. New test/due-like.test.ts reads both objects off the composed stack and pins dueLike, the exact settledWhen envelope, a settled-or-live classification of every status option, and FieldSchema acceptance. Surface breach, stopped and resolved: test/i18n-coverage.test.ts refused the new settledWhen.dialect/.source paths, so two machine() verdicts went into src/translations/authored-text.ts after the seat amended the Claim.",
"tests": "head 0e26cd9: pnpm test exit 0, Test Files 37 passed (37), Tests 897 passed (897); test/due-like.test.ts 6/6. Ablation on the committed fix: removing dueLike+settledWhen from duly_task.due_date (anchor count 1 -> 0 on disk) gave 2 failed / 4 passed, restored by git checkout HEAD, git diff HEAD empty. No build/dist leg: the test reads src via the config import.",
"gates": "head 0e26cd9, exit codes captured before any pipe: pnpm validate 0 (Validation passed), pnpm typecheck 0, pnpm test 0, pnpm build 0 (dist/objectstack.json carries both settledWhen). CEL gate probe: settledWhen mutated to record.statuz gives validate exit 1 'unknown field statuz on duly_assignment, did you mean status', restored. Browser: pnpm demo (en) and demo:zh on this branch as the demo admin. My week overdue open task 'Emissions return - Northgate' renders text-red-600 with hover title Yesterday / 昨天; All tasks searched to that duty shows five done past-due rows plain and the open one red; task record header shows Yesterday in red. Screenshots in project folder duly-151-overdue/. PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "12 — issue_read x3, create_pull_request, issue_write (PR assignee os-warren), update_pull_request (reviewer request refused: os-warren is the PR author), pull_request_read, add_issue_comment (this report); plus hearthbot thread messages. Write tools are in the list: this card thread has no fleet-write relay wired, so the PR, assignee and this report went through the GitHub MCP as os-warren.",
"api_writes": "0 — no REST proxy writes; git push of claude/project-thread-na7mq9 only",
"open_questions": [
{
"question": "Console 18.2's grid date cell shows the absolute date and puts relative wording in the hover title when the field has no format; 17.x showed 'Yesterday' inline. The card's acceptance mentions relative wording. Restore it inline on My week?",
"options": ["A: leave as is: overdue red in the grid, relative wording on hover and in the record header", "B: add field-level format: 'relative' on duly_task.due_date, a free-form reader-defined key, so every grid shows 'Yesterday' / 'In 3 days' inline"],
"recommendation": "A, because the red style is what lets a person see lateness without reading dates, and B leans on an unvalidated display hint across every surface; take B only if Warren wants 17.x parity."
}
],
"out_of_scope_findings": [
"carrier: none · duly_assignment has no past-due row in the demo, so its declaration is verified by test and validate only, not in a browser · noted, not filed"
]
}
Activity
objectstack-fleet commentedon Oct 27, 2026
Seat triage
First touch by the duly lane seat at 2026-10-27T11:30Z (session
session_011HyoSXGRy6L13mYq1Hp4n1).priority:p1, size S,pm:ready. This is a regression from Upgrade to @objectstack 18.2.0 #144, and the seat's ACCEPT on Upgrade to @objectstack 18.2.0 #144 missed it: the PR's tests and gates cannot see how a date renders. It hits My week, the screen the product is built around.duly_assignment.due_datealso getsdueLike, with its ownsettledWhenmatched to the assignment's status set. It is the same kind of deadline, so leaving it out would leave the same bug one screen away.settledWhenset, check it against every terminal value ofduly_task.statusinsrc/objects/task.object.ts. Do not copy it from this card.pnpm demowith en and zh-CN screenshots of My week, showing one overdue open task styled as overdue and one done task past its date styled plainly.src/objects/task.object.ts,src/objects/assignment.object.ts,src/views/task.view.ts, one test file.Clause-②: no.Metadata-protocol: none. It does not intersect Demo fixture drifts with the wall clock: "Not moving" leaves 2–3 from 2026-11-08 and "Stalled-not-late" hits 0 from 2027-01-01 #150 (src/data/demo-catalog.ts,src/data/demo-history.ts,test/demo-calendar.test.ts).Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 2
Session:
session_011HyoSXGRy6L13mYq1Hp4n1Account:
os-warren(the seat's linked user; the card's assignee)Branch:
claude/project-thread-na7mq9(platform-assigned card-thread branch, atorigin/mainc20d397)Worktree:
duly-issue-151Domain: n/a. objectstack-ai/duly is a single-lane app repo with no
domain:*.Seat:
repo:duly#1File surface:
src/objects/task.object.ts,src/objects/assignment.object.ts,src/views/task.view.ts,test/due-like.test.ts(new). Stop on any breach and explain it in the report.Container & model:
S,mode:thread,model: TIER_DEFAULT(hand-derived),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: the app. Spec 18 requires the declaration; see the seat triage.
Thread-read: 6440813957
Premise: holds.
grep -rn "dueLike\|settledWhen" srconc20d397returns nothing (the card measures this).Serial constraints cleared: #150 is in flight on
src/data/demo-catalog.ts,src/data/demo-history.tsandtest/demo-calendar.test.ts, and #152 onsrc/data/demo-org.ts, a test anddocs/getting-started.md. Neither intersects this surface.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim amendment (2026-10-27T11:39Z): File surface adds
src/translations/authored-text.ts. DeclaringsettledWhenadds a CEL value envelope on the field, andtest/i18n-coverage.test.tsneeds verdicts forobject.fields{}.settledWhen.dialectand.source. These are twomachine(...)entries, next to the existing per-optionvisibleWhenones. No open card touches that file (#150 and #152 checked), so no serial constraint changes.Generated by Claude Code
os-warren commentedon Oct 27, 2026
os-dev-report
{ "issue": 151, "status": "done", "branch": "claude/project-thread-na7mq9", "pr": "https://github.com/objectstack-ai/duly/pull/153", "session": "session_01JQwxbZCHwAE9M9pfaL3X4G", "premise_still_valid": true, "summary": "duly_task.due_date and duly_assignment.due_date now declare dueLike: true with settledWhen over each object's terminal statuses: task record.status in ['done','skipped','cancelled'] (open and in_progress are the only live values), assignment record.status == 'closed' (draft and dispatched stay live). The stale my_week comment in task.view.ts is rewritten. New test/due-like.test.ts reads both objects off the composed stack and pins dueLike, the exact settledWhen envelope, a settled-or-live classification of every status option, and FieldSchema acceptance. Surface breach, stopped and resolved: test/i18n-coverage.test.ts refused the new settledWhen.dialect/.source paths, so two machine() verdicts went into src/translations/authored-text.ts after the seat amended the Claim.", "tests": "head 0e26cd9: pnpm test exit 0, Test Files 37 passed (37), Tests 897 passed (897); test/due-like.test.ts 6/6. Ablation on the committed fix: removing dueLike+settledWhen from duly_task.due_date (anchor count 1 -> 0 on disk) gave 2 failed / 4 passed, restored by git checkout HEAD, git diff HEAD empty. No build/dist leg: the test reads src via the config import.", "gates": "head 0e26cd9, exit codes captured before any pipe: pnpm validate 0 (Validation passed), pnpm typecheck 0, pnpm test 0, pnpm build 0 (dist/objectstack.json carries both settledWhen). CEL gate probe: settledWhen mutated to record.statuz gives validate exit 1 'unknown field statuz on duly_assignment, did you mean status', restored. Browser: pnpm demo (en) and demo:zh on this branch as the demo admin. My week overdue open task 'Emissions return - Northgate' renders text-red-600 with hover title Yesterday / 昨天; All tasks searched to that duty shows five done past-due rows plain and the open one red; task record header shows Yesterday in red. Screenshots in project folder duly-151-overdue/. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "12 — issue_read x3, create_pull_request, issue_write (PR assignee os-warren), update_pull_request (reviewer request refused: os-warren is the PR author), pull_request_read, add_issue_comment (this report); plus hearthbot thread messages. Write tools are in the list: this card thread has no fleet-write relay wired, so the PR, assignee and this report went through the GitHub MCP as os-warren.", "api_writes": "0 — no REST proxy writes; git push of claude/project-thread-na7mq9 only", "open_questions": [ { "question": "Console 18.2's grid date cell shows the absolute date and puts relative wording in the hover title when the field has no format; 17.x showed 'Yesterday' inline. The card's acceptance mentions relative wording. Restore it inline on My week?", "options": ["A: leave as is: overdue red in the grid, relative wording on hover and in the record header", "B: add field-level format: 'relative' on duly_task.due_date, a free-form reader-defined key, so every grid shows 'Yesterday' / 'In 3 days' inline"], "recommendation": "A, because the red style is what lets a person see lateness without reading dates, and B leans on an unvalidated display hint across every surface; take B only if Warren wants 17.x parity." } ], "out_of_scope_findings": [ "carrier: none · duly_assignment has no past-due row in the demo, so its declaration is verified by test and validate only, not in a browser · noted, not filed" ] }Generated by Claude Code