Repository navigation
pnpm demo stops being re-runnable once the daily jobs have run: the seed re-asserts statuses the state machines refuse to go back to - #176
Merged
Conversation
…sks wrote The demo datasets now declare the lifecycle columns `applyOn: 'create'` (@objectstack 18.2.0, objectstack#25761): `status` on contracts, obligations and payment instalments, `is_expiring`, the stage timestamps and routing flags, `approval_status`, `is_backfilled`, `termination_reason`, the archive number and stamp, an obligation's `completed_at` and an instalment's receipt. The seed writes them when it creates a row and leaves them alone on a row a re-run matches. Before, a re-run after the daily jobs walked F11's 18 overdue instalments back to partial, reset is_expiring so F12 re-sent its notice, and had the state machines refuse (and drop whole) a contract F13 had expired or legal had terminated. README states the re-run promise again, with its limits. Also rewrites the src/data comments that still told the operator to create the demo accounts and re-run: since #171 the platform creates them before the seed runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn
Contributor
Author
席位核对 — ACCEPT · head
|
| check | reading |
|---|---|
| shape | draft → main, Fixes #41; mergeable clean |
| CI on the head | both Validate check-runs success on ab8a2af = PR head.sha |
| scope | 6 files (+159/−71), all in src/data/ plus README.md. 24 lifecycle columns get applyOn: 'create' (objectstack#25761, shipped in 18.2.0): 18 on clm_contract as one set, status + completed_at on clm_obligation, and status, actual_date, actual_amount, invoice_no on clm_payment_plan. legal_owner / owner_id stay always, so a re-run still re-deals the book. Nothing governed |
| the defect | measured. On main a second pnpm demo gave {updated 20, errored 3}, with 18 overdue→partial reversals. On the branch it gave {updated 0, errored 0}: job-written values were kept, deleted rows came back, and F12 was not re-sent |
| README | the re-run promise is back, with its three limits stated: lifecycle columns keep their stamped dates while fixture dates slide forward; deleted rows return; staff are re-dealt |
| stale comments | keys.ts, contract.seed.ts, negotiation.seed.ts and plan-contracts.ts now describe demo staff (PR #171), not the two-boot handover |
| left open | the deviation and signature status re-assert was not measured and is noted in the PR. Whether clm_review.reviewer should name a lawyer instead of the dev admin is open and goes to #19's dev. Neither blocks this card |
Landing: under the maintainer's merge authorization (project thread: 「你可以自己审核的就自己合并」).
Generated by Claude Code
zhuangjianguo
marked this pull request as ready for review
October 27, 2026 11:19
This was referenced Oct 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #41
Clause-②: no
Metadata-protocol: none
Ruling-ref: comment 6395830052 (letter A), step 3. The platform card objectstack-ai/objectstack#25761 shipped in 18.2.0 (
493a6c4,columns.FIELD.applyOn: 'create'ondefineSeed), andmainpins 18.2.0 (PR #155). Sessionsession_017nzWFRUo2U7evMkPdVniAn, branchclaude/issue-41-seed-apply-on-create, headab8a2af.What changed
src/data/contract.seed.ts.columnsdeclares these 18 contract columnsapplyOn: 'create':status,is_expiring,is_backfilledroute_legal_head,route_finance,route_executive,route_gm,approval_statussubmitted_at,review_started_at,approved_at,signed_at,executed_at,activated_at,closed_attermination_reason,archive_no,archived_atThe set starts from the single-writer family that
contract.object.tsdocuments: "stage timestamps and routing flags … the state machine and the F2/F5/F9–F14 flows", plusis_backfilled(F16). Card 09's jobs are among those writers: F12 writesis_expiring, F13 movesstatustoexpired, F9 stampsactivated_atand F14 stampsarchived_at. Three more columns are written in the same write as a transition, so they are in the set too:status,termination_reason(Terminate) andarchive_no(the number that stampsarchived_at). These columns move as one set. A create-onlystatusbeside analwaysapproved_atwould let a re-run blank the stamp on a contract someone has approved since.owner_idandlegal_ownerstayalways. They are how the book is dealt to the demo staff.src/data/post-signature.seed.ts.status(F10 writesoverdue) andcompleted_at(stamped ondone).status(F11 writesdueandoverdue), plus the receipt thatpartial/paidrecords:actual_date(stamped by the state machine),actual_amountandinvoice_no.README. "The demo dataset" makes the re-run promise again: it runs after the jobs and after desk work, puts deleted rows back, and does not turn the clock back. Three stated limits:
Stale comments.⚠️ note) still said "the operator creates the accounts and runs
keys.ts(DEMO_USER,CONTRACT_OWNERS,LEGAL_OWNERS,obligationOwnerOf,deviationDeciderOf),contract.seed.ts(owner_id),negotiation.seed.ts(reviewer) andplan-contracts.ts(the rung-1 rationale and theTERM_ENDED_YESTERDAY_PER_BRANCHpnpm demoagain". They now say that since #171 the platform creates the demo staff before the seed runs.clm_review.reviewerstill names the Dev Admin. This PR does not change it (see Acceptance notes).Measured: one sequence,
origin/main0159171against this branch, @objectstack 18.2.0, better-sqlite3, port 3153Harness (stated as the seat directed). On 18.2.0 the daily jobs cannot be started on demand:
POST /api/v1/automation/{obligation_due,payment_overdue,renewal_notice,expiration_sweep,legal_review_sla,turn_stalled}/triggeras the dev admin answers403 PERMISSION_DENIED"This caller may not start this flow. A flow that runs on its own trigger starts there, or as a sub-flow from a parent flow'ssubflownode." (objectstack#25643,flow-start-admission.ts). The jobs were therefore fired on their own schedule trigger. A measurement-only edit ofsrc/flows/_daily-sweep.ts:108set the cron to'* * * * *', which covers all six sweeps, includingexpiration_sweep's0 7 * * *. The edit was never committed: it was reverted before each re-run boot and before the commit, andgit diff HEAD -- src/flowsis 0 bytes. All six sweeps fired (sys_joblast_status: success).Sequence on each tree:
pnpm demowith the harness.clm_obligation,clm_payment_plan, and the contract roll-ups (card 03, M1) #3 paid. clm.admin@ deletes one obligation and one instalment.pnpm demoagain on the same database (--log-level info).maininserted 830, errored 0inserted 830, errored 0overdue12 → 30 (18partialflagged) · 1 contract expired (F13) · 1 auto-renew draft ·is_expiringtrue 13 → 14WARN [Seeder] Seed loading completed with 3 dropped record(s) and 3 error(s) … {"inserted":2,"updated":20,"skipped":805,"errored":3}INFO [Seeder] Seed loading complete {"inserted":2,"updated":0,"skipped":828,"errored":0}✗ … Master Services Agreement — Cobalt Pharmaceuticals: A terminated contract is closed; its status cannot change to active.·✗ … Mutual Non-Disclosure Agreement — Basalt Energy: A expired contract is closed; its status cannot change to active.·✗ clm_payment_plan record #262 …: A paid instalment is settled; its status cannot change to due.ERROR [SeedLoader]lines: 0)overdue → partial×18 (overdue 30 → 12), silentoverdue(30)is_expiring true → falsetruearchive_no "ARC-41-TEST" → null,archived_at → null: the archive is undone, silentlyinserted 2)inserted 2)renewal_notice … selected=25 acted=1: notice count 1 → 2 (re-sent)selected=22 acted=0: notice count stays 1payment_overdue … acted=18:clm_payment_overdue18 → 36 (re-sent)The step 3–4 diff was taken row by row by id (
end_date,planned_dateanddue_dateexcluded, since they slide by design). Beyond the rows above,mainchanged nothing else, and the branch changed nothing at all except re-creating the two deleted rows.Read as the personas in the browser (Chromium
/opt/pw-browsers/chromium, zh-CN, signed in through the Console form, branch after the re-run):finance@example.com: overdue instalments total 30, partial 0.counsel2@example.com: the Cobalt contract isterminated, its reason is kept andclosed_atis set; the Basalt NDA isexpired.records@example.com: the Beacon contract isexpired,ARC-41-TEST,archived_atset.NOT MEASURED: the requester marking an obligation done.
PATCH clm_obligationasrequester2@example.comanswered403 "[Security] Access denied: update on 'clm_obligation' requires edit access to its master record (master 'clm_contract' not editable by this user (row-level security))". No alternate route was taken.completed_atcreate-only is therefore argued from the state machine, not measured.Gates (worktree
hotclm-issue-41; the bytes were then committed unchanged asab8a2af; each exit code was captured before any pipe)pnpm install→ exit 0pnpm validate→ exit 0,✓ Validation passed (1104ms)pnpm lint→ exit 0,6 suggestion(s), 0 warnings, none insrc/datapnpm typecheck→ exit 0pnpm lint:i18n-gate→ exit 0,COVERAGE : 0 missing keys across 2 locale(s)CLM_DEMO_SEED=1 pnpm validate→ exit 0,✓ Validation passed (1341ms). This parses the 24columnskeys throughdefineSeedandSeedSchema; a misspelt key would be refused here.Acceptance notes
clm_review.reviewerstill names the Dev Admin. Legal Counsel 1/2 now exist when the seed runs, but the right reviewer depends on the review stage. Legal and compliance would go to the counterparty's counsel. Finance would arguably go to the Finance Controller. Business would go to the requester.scripts/demo.mjs(outsidesrc/data) also mirrorsDEMO_USERas the one name it verifies before seeding. So this is not a one-line change, and it is reported rather than made. The comments now say it is open.open → accepted) or signature round is still re-asserted by a re-run, and the state machine may refuse it. This was not measured; the README states it as a limit.start_date,end_date,due_dateandplanned_dateslide forward on each re-run.🤖 Generated with Claude Code
https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn