Skip to content

Seven smaller things a real user hits — item 5: a pnpm demo re-run prints the first-run operator note, false by then - #106

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-99-orphan-draft-and-demo-note
Oct 25, 2026
Merged

zhuangjianguo merged 1 commit into
mainfrom
claude/issue-99-orphan-draft-and-demo-note

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #99 (items 4 and 5)

This PR changes code for item 5 only. Item 4 (an abandoned intake wizard leaves an orphan draft) was re-measured and reproduces on 449667e, but no flow change in this app prevents it. The fix needs either a platform capability or a product decision, so it goes back to the card as needs_decision with no code here. Items 2, 3, 4 and 7 remain open on #99.

Clause-②: no
Metadata-protocol: none

Item 5 — pnpm demo re-run printed the first-run operator note

scripts/demo.mjs printed the same closing note on every run. Its step 1 ends "run this again", so the operator is told to make exactly the second run on which that note is false.

What changed (one file, scripts/demo.mjs):

  • signIn also returns the session token the sign-in answers.
  • New readRoster(port, token): while the priming server (demo off) is still up, it reads GET /api/v1/data/sys_user?fields=id,name,manager_id&filter={"name":{"$in":[the five persona names]}} as the dev admin. It returns the persona names that have no account, plus the existing requesters with no manager_id. A failed read returns { unknown: reason }.
    • This is the right moment, not only a convenient one: the demo boot's seed resolves its user references against the accounts that exist when it runs.
  • REQUESTER_ACCOUNTS / COUNSEL_ACCOUNTS mirror CONTRACT_OWNERS / LEGAL_OWNERS in src/data/keys.ts. This is the same mirror DEMO_USER already keeps, for the same reason: this file runs before anything compiles. If they drift, only the note's wording goes wrong; the seed never reads this list.
  • The constant note became operatorSetupNote(roster):
    • none of the five accounts exists, so the first-run text, unchanged (FIRST_RUN_NOTE);
    • the roster could not be read, so one line saying why, then the first-run text;
    • some accounts exist, so only the steps still undone, each naming its accounts: missing accounts, requesters with no manager, and the ERROR [SeedLoader] explanation only while an account is missing;
    • all five exist and every requester has a manager, so a short "Setup check — nothing left to do" note.
  • primeAdminAccount returns { primingMs, roster }, and announceOperatorSetup takes the roster.

Measured. Every run is pnpm demo -- --port 3991 in this worktree, with the terminal captured to a file. The accounts were created as the README says: five named accounts, clm_requester set rows for the three requesters, clm_legal_counsel positions for the two counsel.

run tree database state before the run note printed reading after the seed
1 449667e empty first-run note ("two setup steps, and one thing about the log") {"inserted":820,…,"errored":404}, 404 ERROR [SeedLoader] lines
2 449667e five accounts created, no managers the same first-run note, verbatim: "The seeded rows have no people on them yet … so 我的合同 and 法务工作台 stay empty" owner_id 43 / 44 / 34 across the three requesters (the 44 includes the item-4 probe draft), 0 rows on the dev admin, no ERROR [SeedLoader] line, so steps 1 and 3 were false
3 d7806a9 same as run 2 "Before you open the app — one setup step": 1. Give Business Requester 1, Business Requester 2 and Business Requester 3 a manager … n/a
4 d7806a9 managers set through POST /api/v1/auth/admin/set-user-manager → 200 ×3 "Setup check — nothing left to do": the five accounts exist … every business requester has a manager … after the background seed: owner_id 43 / 44 / 34, legal_owner 34 / 34 / 53 null (README: 34 / 34), 0 ERROR [SeedLoader] lines
5 d7806a9 empty again (previous database moved aside) first-run note; its 34 lines are identical (diff) to run 1's n/a

The partial state (some accounts missing) was rendered offline from the same function. Every line fits the note's 76-column rule, and no account name breaks across lines.

Item 4 — why there is no flow change

Re-measured on 449667e in Chromium at 1440×900, signed in as Business Requester 1. The launch dialog was given Mutual Non-Disclosure Agreement and a picked counterparty. Then Confirm → "Contract details" (title, governing law, confidentiality term) → Submit → "First version" (the type carries no template) → Submit → the dialog shows "Upload the first version" → the dialog's Close.

  • POST /api/v1/automation/contract_intake/trigger → 200 paused screen_core; …/resume → 200 paused screen_document; …/resume → 200 paused screen_upload (kind object-form). Closing the dialog sent no request: no cancel, no resume.
  • Left behind: NDA-2026-0021 (the same number as the Full browser test on 17.7.0 main: drive the whole contract lifecycle as every audience, in en and zh-CN, and report what a real user hits #87 run), status: draft, owner_id = the requester, version_count: 0, zero clm_contract_version rows. The run is listed paused at screen_upload with no end.
  • The requester cannot remove it: DELETE /api/v1/data/clm_contract/… → 403 PERMISSION_DENIED (DESIGN.md §04 grants the requester RCU). No action cancels a draft.
  • Console during the drive: the two registry warnings and the 404 / 401 before sign-in, the same messages every boot logs. Nothing from the wizard itself.

Why a reorder does not fix it. The draft is created at create_contract because the next interactive step, screen_upload, is an object form on clm_contract_version. That form saves the version itself, and its required contract field must point at an existing contract. A file can only come from that form. In the 17.7.0 console's flat-screen renderer (RecordDetailView chunk, the screen-field switch), the only widget types are lookup (with reference), select, boolean, textarea/markdown, number/currency/email/date and text, with no file input. DESIGN.md §06 F1 orders it "上传首版或标记「按模板」→ 建合同(draft)与版本 v1". The flow cannot follow that order until a flat screen can take the file. Moving screen_schedule ahead of the writes would remove the orphan only on the template path, and the reported case is the no-template path. Collecting the file in the launch dialog instead would reshape the app around a platform gap, which the lane ruling 「平台的问题就等平台」 rules out. The options go to the card in the report.

For the 18.1 re-application: this PR moves, adds or removes no node, edge or value slot in src/flows/contract-intake.flow.ts, and the file is untouched. src/translations/*/flows.ts is untouched too.

Gates — on d7806a9

Run under the shared verify lock, each with its exit code captured to its own file before any pipe (VERDICT … held the lock 12s · waited 0s):

pnpm validate        exit 0   ✓ Validation passed (706ms)   (warnings: the pre-existing approval-approvers-may-resolve-empty set and hierarchy-security)
pnpm lint            exit 0   6 suggestion(s) (695ms)       (all pre-existing, contract_approval)
pnpm typecheck       exit 0   tsc --noEmit, no output
pnpm lint:i18n-gate  exit 0   ✓ i18n gate · COVERAGE : 0 missing keys across 2 locale(s)

Acceptance notes

  • Boot reading: every run was a passing boot, with Plugins: 41 loaded in all five. There was no System started with degraded capabilities and no no such table. The six scheduled flows are NOT bound — disabled by deployment policy, as on main.
  • The note is still printed once and only after the banner. The pnpm demo prints its "now create the three requesters" instruction ~290 lines and 120 ERROR lines before the ready banner, so nobody reads it #49 placement logic is unchanged.
  • Readings are exact. They are not part of the note's text, which keeps the existing rule "SHAPE, never a census".
  • Seen in passing and not changed here: the contract-intake.flow.ts header says a flat screen has "NO record picker", which was measured on 17.3.0. The 17.7.0 renderer has a lookup widget when reference is set. The file-input half of the same sentence still holds.

Generated by Claude Code

The closing note told the operator to create the five persona accounts and
run `pnpm demo` again, then printed the same first-run text on that second
run, when the accounts existed and the seed had handed the rows over.

The priming boot now reads, as the dev admin, which of the five named
accounts exist and which requesters have a manager, and the note is built
from that: the first-run text unchanged while none exists (or the read
fails, which it says), the steps still undone naming their accounts once
some do, and a short all-done note otherwise.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — ACCEPT · head d7806a9 · item 5 · 2026-10-25T03:14Z

check reading
shape draft → main, line 1 Part of #99 (items 4 and 5), no closing keyword next to any open issue; assignee zhuangjianguo
CI on the head both Validate check-runs success on d7806a9 = PR head.sha
scope 1 file, scripts/demo.mjs (+192/−9); contract-intake.flow.ts and src/translations/*/flows.ts untouched (the pending 18.1 upgrade rewrites those); nothing governed
the fix the priming boot reads sys_user for the five named accounts (and requesters' manager_id) as the dev admin and prints only what is still undone; an unreadable roster falls back to the full first-run note and says why
measured (dev) 5 real runs: empty DB → first-run note (identical to main by diff); accounts, no managers → one step naming the three requesters; managers set → "nothing left to do"; owner_id 43/44/34, 0 ERROR [SeedLoader]
deviation, seat correction the branch commit's trailer was made model-free against the session's required attribution; the squash commit carries the required trailer
item 4 no code; needs_decision goes to the maintainer separately

Landing: under the maintainer's merge authorization (project thread: 「pr 你审核之后可以帮我合并」).


Generated by Claude Code

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