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
Claim: PM loop round 19
Ruling-ref: none (triaged follow-up of #31 / PR #201)
Session: session_017nzWFRUo2U7evMkPdVniAn
Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-203-f3-type-sla
Worktree: hotclm-issue-203
Domain: repo:hotclm (single-lane sister repo — no domain:*)
Seat: repo:hotclm#1
File surface: src/flows/legal-review-sla.flow.ts · src/flows/_daily-sweep.ts (only if F3's query needs it; the stale notifyRecipients obligation clause may be fixed in passing) · src/objects/contract-type.object.ts (the review_sla_days help text) · src/email-templates/** (the F3 template only) · src/translations/{en,zh-CN}/ (F3 and review_sla_days strings) — stop on breach; explain in the report
Container & model: S, mode:subagent, model: opus (TIER_DEFAULT; hand-derived for a sister repo), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: this app's F3 legal-review reminder (fires on the contract type's own SLA, as the workbench tile counts) | PR #201 stored review_sla_days_offset | legal counsel
Thread-read: none
Premise: re-measured by the dev on origin/main7257a23 (@objectstack 18.3.0) with the declared demo staff
Serial constraints cleared: batch 12 lanes landed (PRs #202, #204, #205); nothing else in flight.
Claim amendment: PM loop round 19 · #203
Session: session_017nzWFRUo2U7evMkPdVniAn
Branch: claude/issue-203-f3-type-sla
Seat call: option A. F3 escalates to the head of legal at 2× the type SLA, as DESIGN.md §06 F3 already says (超一倍), so no new ruling is needed.
File surface, added: src/data/plan-contracts.ts (only handBackInReview's band and its guard text, so the one unassigned in-review row stays inside (SLA, 2×SLA] and the 「Nobody to tell」 edge stays covered) · src/datasets/contract.dataset.ts (only review_over_sla_count, which gains the same review_sla_days_offset: { $ne: null } guard, so the workbench tile and the reminder count the same rows; at 18.3.0 a NULL offset reads as 0 days, objectstack#29961).
{
"issue": 203,
"status": "done",
"branch": "claude/issue-203-f3-type-sla",
"pr": "https://github.com/objectstack-ai/hotclm/pull/206",
"session": "session_017nzWFRUo2U7evMkPdVniAn",
"premise_still_valid": true,
"summary": "F3 now selects in-review contracts whose review_started_at is earlier than { $now: true, addDays: { $field: 'review_sla_days_offset' } }, with review_sla_days_offset: { $ne: null }. The anchor is a literal operand, which the flow executor passes to the query unchanged (crud-nodes resolveNodeFilter evaluates CEL envelopes only) and the ObjectQL read path pins. Measured: 18.3 expresses the rule, so no refusal. The DESIGN §06 F3 head-of-legal copy (超一倍) is a partitioned per-row CEL decision, datetime(review_started_at) earlier than addDays(now(), offset + offset): one notice per row per run, which is F3's existing de-dup. The NULL guard is required because at 18.3.0 driver-sql reads a NULL addDays column as ZERO days (#25808 conformance table, row 4; also measured on the REST door). Per the seat's amendment (option A): the review_over_sla_count tile gets the same guard, and handBackInReview moves the unassigned in-review row to SLA + ceil(SLA/2) days so the Nobody-to-tell edge stays covered. Templates and topics are renamed to over_sla / over_double_sla; the review_sla_days help text (en + zh-CN) is rewritten. No stamp, hook or mirror column; _daily-sweep.ts is untouched.",
"tests": "Throwaway DBs, pnpm demo:zh on port 3170, the uncommitted every-minute cron override reverted afterwards (git diff HEAD = 0 lines). Fixture applied identically to both trees by direct SQLite edit after seed, because review_started_at and the offset are engine/system-written: DPA-2026-0005 started 6d ago, MSA-2026-0001 started 1d ago, NDA-2026-0003 offset NULL. Inbox read as persona via GET /api/v1/data/sys_inbox_message. BEFORE origin/main 7257a23: DPA 6d gets no reminder; NULL-offset NDA (38d) reminded once per tick; only the 30-60d rows reminded. AFTER 99c58b1: counsel2 '2x clm_legal_review_over_sla | warning | Legal review over SLA: 数据处理协议 — 渡鸦安保 [23:56:00, 23:57:00]', no head copy; MSA-2026-0001 (counsel1) none; NDA-2026-0003 (counsel1) none; 8 others over_double_sla critical once per tick each, legal.head 16 = 8 per tick; unassigned MSA-2026-0004 (8d, SLA 5) sends nothing (Nobody-to-tell edge). Fresh seed without fixture: 11 doubled per tick, legal.head 11 per tick. REST door as counsel1: unguarded anchor filter total 11 including NDA-2026-0003 (NULL read as 0 days); with $ne:null total 10. Tile 审查超时限 in Chromium zh-CN as counsel1 (POST /api/v1/analytics/dataset/query 200): main fresh 12 (MSA 6, NDA 2, SUP 1, DPA 1, LSE 1, ICA 1); branch fresh 12, same per type (the moved row is still over its SLA, so the numbers do not move); branch with fixture 10 (MSA 5, NDA 1, SUP 1, DPA 1, LSE 1, ICA 1), equal to F3's set for that tick. Console: one 404 resource error on both trees. Seed band probe (CONTRACT_PLAN): all 12 dealt in-review rows were past 2x SLA, hence the move. No ablation: metadata/config only, no tested behaviour pinned by a test file.",
"gates": "On final HEAD 99c58b1, exit codes captured before any pipe: pnpm install 0; pnpm validate 0 (Validation passed, 7 pre-existing warnings, the same 7 on origin/main, none on legal_review_sla); pnpm lint 0 (0 warnings, 6 suggestions, the same as main); pnpm typecheck 0; pnpm lint:i18n-gate 0 (0 missing keys across 2 locales); CLM_DEMO_SEED=1 pnpm validate 0. CI on PR #206: Validate completed success, a second Validate run in_progress at report time. dispatch-gates.mjs not applicable (hotclm has no such script; gates are the repo's own verify set).",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; hotclm has no dogfood battery",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/hotclm/pulls + POST /issues/206/assignees, read back identical 7895 bytes, assignee zhuangjianguo); this os-dev-report comment (POST /repos/objectstack-ai/hotclm/issues/203/comments). git push is not a REST write.",
"open_questions": [
{
"question": "Governed text for the seat to carry on PR #120: DESIGN.md §06 F3 row.",
"options": [
"A | F3 | `legal_review_sla` | 定时(日) | `in_review` 超过类型 `review_sla_days`(按合同上存储的 `review_sla_days_offset` 判定,与法务工作台「审查超时限」同一规则;该值为空的合同不提醒):提醒 `legal_owner`,超一倍抄送 `clm_legal_head`;每份合同每次运行只发一条 |",
"B Leave the row as it is: its intent already matches the implementation."
],
"recommendation": "A, because it names the stored column F3 and the tile share, and the NULL rule, which an upgraded database depends on."
},
{
"question": "DESIGN.md §12 row \"CEL 日期算术 | #7 | 到期、逾期由日任务盖戳字段 | 公式字段\" is stale on 18.3: @objectstack/formula registers daysBetween, addDays, now() and datetime(), and F3 now uses them in a flow edge. Revise it?",
"options": [
"A Seat drafts a §12 revision on PR #120 (whether a formula field may now use daysBetween is a separate product question)",
"B Leave it until a card needs date formulas"
],
"recommendation": "B, because no card needs it now; the stale claim lived in F3's header, which this PR removed."
}
],
"out_of_scope_findings": [
"class: a · reach: GET /api/v1/data/sys_inbox_message as counsel2@example.com on pnpm demo:zh returns English subjects ('Legal review over SLA: …'), and the same English (over_30_days) on origin/main 7257a23. The demo staff have sys_user.locale = null, so every email_template bundle falls to the en-US floor (_bundle.ts) in the zh-CN demo · dedupe words: demo:zh notifications English, demoStaff locale, sys_user.locale null, en-US floor, inbox language",
"carrier: none · noted, not filed — the F3 notice's {{ review_started_at }} hole renders the raw ISO instant (2026-10-09T00:00:00.000Z), unchanged from main (polish)",
"carrier: none · noted, not filed — src/data/contract.seed.ts comment says 'two contracts in review are handed back' while UNASSIGNED_IN_REVIEW = 1 (pre-existing drift; file outside the claim)"
]
}
Release: the F3 reminder fires when a review passes its contract type's own SLA and copies the head of legal at twice the SLA, the same rule the workbench tile counts; a contract whose SLA offset is still empty is neither reminded nor counted. The §06 F3 text is on PR #120. State: pm:dispatched removed, assignee cleared.
Activity
objectstack-fleet commentedon Nov 3, 2026
Claim: PM loop round 19
Ruling-ref: none (triaged follow-up of #31 / PR #201)
Session:
session_017nzWFRUo2U7evMkPdVniAnAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-203-f3-type-slaWorktree:
hotclm-issue-203Domain:
repo:hotclm(single-lane sister repo — nodomain:*)Seat:
repo:hotclm#1File surface:
src/flows/legal-review-sla.flow.ts·src/flows/_daily-sweep.ts(only if F3's query needs it; the stalenotifyRecipientsobligation clause may be fixed in passing) ·src/objects/contract-type.object.ts(thereview_sla_dayshelp text) ·src/email-templates/**(the F3 template only) ·src/translations/{en,zh-CN}/(F3 andreview_sla_daysstrings) — stop on breach; explain in the reportContainer & model:
S,mode:subagent,model: opus(TIER_DEFAULT; hand-derived for a sister repo),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
this app's F3 legal-review reminder (fires on the contract type's own SLA, as the workbench tile counts) | PR #201 stored review_sla_days_offset | legal counselThread-read: none
Premise: re-measured by the dev on
origin/main7257a23(@objectstack 18.3.0) with the declared demo staffSerial constraints cleared: batch 12 lanes landed (PRs #202, #204, #205); nothing else in flight.
Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
Claim amendment: PM loop round 19 · #203
Session:
session_017nzWFRUo2U7evMkPdVniAnBranch:
claude/issue-203-f3-type-slaSeat call: option A. F3 escalates to the head of legal at 2× the type SLA, as DESIGN.md §06 F3 already says (超一倍), so no new ruling is needed.
File surface, added:
src/data/plan-contracts.ts(onlyhandBackInReview's band and its guard text, so the one unassigned in-review row stays inside (SLA, 2×SLA] and the 「Nobody to tell」 edge stays covered) ·src/datasets/contract.dataset.ts(onlyreview_over_sla_count, which gains the samereview_sla_days_offset: { $ne: null }guard, so the workbench tile and the reminder count the same rows; at 18.3.0 a NULL offset reads as 0 days, objectstack#29961).Generated by Claude Code
objectstack-fleet commentedon Nov 4, 2026
os-dev-report
{ "issue": 203, "status": "done", "branch": "claude/issue-203-f3-type-sla", "pr": "https://github.com/objectstack-ai/hotclm/pull/206", "session": "session_017nzWFRUo2U7evMkPdVniAn", "premise_still_valid": true, "summary": "F3 now selects in-review contracts whose review_started_at is earlier than { $now: true, addDays: { $field: 'review_sla_days_offset' } }, with review_sla_days_offset: { $ne: null }. The anchor is a literal operand, which the flow executor passes to the query unchanged (crud-nodes resolveNodeFilter evaluates CEL envelopes only) and the ObjectQL read path pins. Measured: 18.3 expresses the rule, so no refusal. The DESIGN §06 F3 head-of-legal copy (超一倍) is a partitioned per-row CEL decision, datetime(review_started_at) earlier than addDays(now(), offset + offset): one notice per row per run, which is F3's existing de-dup. The NULL guard is required because at 18.3.0 driver-sql reads a NULL addDays column as ZERO days (#25808 conformance table, row 4; also measured on the REST door). Per the seat's amendment (option A): the review_over_sla_count tile gets the same guard, and handBackInReview moves the unassigned in-review row to SLA + ceil(SLA/2) days so the Nobody-to-tell edge stays covered. Templates and topics are renamed to over_sla / over_double_sla; the review_sla_days help text (en + zh-CN) is rewritten. No stamp, hook or mirror column; _daily-sweep.ts is untouched.", "tests": "Throwaway DBs, pnpm demo:zh on port 3170, the uncommitted every-minute cron override reverted afterwards (git diff HEAD = 0 lines). Fixture applied identically to both trees by direct SQLite edit after seed, because review_started_at and the offset are engine/system-written: DPA-2026-0005 started 6d ago, MSA-2026-0001 started 1d ago, NDA-2026-0003 offset NULL. Inbox read as persona via GET /api/v1/data/sys_inbox_message. BEFORE origin/main 7257a23: DPA 6d gets no reminder; NULL-offset NDA (38d) reminded once per tick; only the 30-60d rows reminded. AFTER 99c58b1: counsel2 '2x clm_legal_review_over_sla | warning | Legal review over SLA: 数据处理协议 — 渡鸦安保 [23:56:00, 23:57:00]', no head copy; MSA-2026-0001 (counsel1) none; NDA-2026-0003 (counsel1) none; 8 others over_double_sla critical once per tick each, legal.head 16 = 8 per tick; unassigned MSA-2026-0004 (8d, SLA 5) sends nothing (Nobody-to-tell edge). Fresh seed without fixture: 11 doubled per tick, legal.head 11 per tick. REST door as counsel1: unguarded anchor filter total 11 including NDA-2026-0003 (NULL read as 0 days); with $ne:null total 10. Tile 审查超时限 in Chromium zh-CN as counsel1 (POST /api/v1/analytics/dataset/query 200): main fresh 12 (MSA 6, NDA 2, SUP 1, DPA 1, LSE 1, ICA 1); branch fresh 12, same per type (the moved row is still over its SLA, so the numbers do not move); branch with fixture 10 (MSA 5, NDA 1, SUP 1, DPA 1, LSE 1, ICA 1), equal to F3's set for that tick. Console: one 404 resource error on both trees. Seed band probe (CONTRACT_PLAN): all 12 dealt in-review rows were past 2x SLA, hence the move. No ablation: metadata/config only, no tested behaviour pinned by a test file.", "gates": "On final HEAD 99c58b1, exit codes captured before any pipe: pnpm install 0; pnpm validate 0 (Validation passed, 7 pre-existing warnings, the same 7 on origin/main, none on legal_review_sla); pnpm lint 0 (0 warnings, 6 suggestions, the same as main); pnpm typecheck 0; pnpm lint:i18n-gate 0 (0 missing keys across 2 locales); CLM_DEMO_SEED=1 pnpm validate 0. CI on PR #206: Validate completed success, a second Validate run in_progress at report time. dispatch-gates.mjs not applicable (hotclm has no such script; gates are the repo's own verify set).", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; hotclm has no dogfood battery", "mcp_calls": "0", "api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/hotclm/pulls + POST /issues/206/assignees, read back identical 7895 bytes, assignee zhuangjianguo); this os-dev-report comment (POST /repos/objectstack-ai/hotclm/issues/203/comments). git push is not a REST write.", "open_questions": [ { "question": "Governed text for the seat to carry on PR #120: DESIGN.md §06 F3 row.", "options": [ "A | F3 | `legal_review_sla` | 定时(日) | `in_review` 超过类型 `review_sla_days`(按合同上存储的 `review_sla_days_offset` 判定,与法务工作台「审查超时限」同一规则;该值为空的合同不提醒):提醒 `legal_owner`,超一倍抄送 `clm_legal_head`;每份合同每次运行只发一条 |", "B Leave the row as it is: its intent already matches the implementation." ], "recommendation": "A, because it names the stored column F3 and the tile share, and the NULL rule, which an upgraded database depends on." }, { "question": "DESIGN.md §12 row \"CEL 日期算术 | #7 | 到期、逾期由日任务盖戳字段 | 公式字段\" is stale on 18.3: @objectstack/formula registers daysBetween, addDays, now() and datetime(), and F3 now uses them in a flow edge. Revise it?", "options": [ "A Seat drafts a §12 revision on PR #120 (whether a formula field may now use daysBetween is a separate product question)", "B Leave it until a card needs date formulas" ], "recommendation": "B, because no card needs it now; the stale claim lived in F3's header, which this PR removed." } ], "out_of_scope_findings": [ "class: a · reach: GET /api/v1/data/sys_inbox_message as counsel2@example.com on pnpm demo:zh returns English subjects ('Legal review over SLA: …'), and the same English (over_30_days) on origin/main 7257a23. The demo staff have sys_user.locale = null, so every email_template bundle falls to the en-US floor (_bundle.ts) in the zh-CN demo · dedupe words: demo:zh notifications English, demoStaff locale, sys_user.locale null, en-US floor, inbox language", "carrier: none · noted, not filed — the F3 notice's {{ review_started_at }} hole renders the raw ISO instant (2026-10-09T00:00:00.000Z), unchanged from main (polish)", "carrier: none · noted, not filed — src/data/contract.seed.ts comment says 'two contracts in review are handed back' while UNASSIGNED_IN_REVIEW = 1 (pre-existing drift; file outside the claim)" ] }objectstack-fleet commentedon Nov 4, 2026
Ruling-ref: none (triaged follow-up of #31)
Landed — PR #206 · 2026-11-04
MERGED(squash onmain), merged at its ACCEPT head99c58b1;Fixes #203closes this cardRelease: the F3 reminder fires when a review passes its contract type's own SLA and copies the head of legal at twice the SLA, the same rule the workbench tile counts; a contract whose SLA offset is still empty is neither reminded nor counted. The §06 F3 text is on PR #120. State:
pm:dispatchedremoved, assignee cleared.Generated by Claude Code
DESIGN.md §06 F3: remind on the stored per-type SLA offset (#203)