Repository navigation
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
Description
Activity
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsClaim: PM loop round 8
Session:session_01HihZ11bQSqjCgjzHbpv4M1
Account:zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-87-browser-test-17-7(isolation only — ⛔ this card pushes nothing)
Worktree:hotclm-issue-87
Domain:repo:hotclm(single-lane sister repo — nodomain:*)
Seat:repo:hotclm#1
File surface: none — observation only; the worktree is restored byte-identical
Container & model:L,mode:subagent,model: opus(TIER_DEFAULT; hand-derived for a sister repo)
Clause-②: no
Responsibility:n/a — not a defect card
Thread-read: none
Serial constraints cleared: #86 dispatched in parallel (its dev runs its own server; this card uses a different port and touches no file); PR #81 holdsAGENTS.md·CLAUDE.md·docs/backlog/README.md— untouched here
Read at: 2026-10-10T00:13ZMaintainer direct dispatch — the instruction, verbatim, given to this PM session on 2026-10-10: 「#85 同意合并,然后使用浏览器完整的测试。」
Generated by Claude Code
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsClaim: PM loop round 8
Session:session_01HihZ11bQSqjCgjzHbpv4M1
Account:zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-87-browser-test-17-7(evidence only: screenshots +REPORT.md, ⛔ never a PR, never merged)
Worktree: the cloud session's own checkout oforigin/main@c31c7e2
Domain:repo:hotclm(single-lane sister repo — nodomain:*)
Seat:repo:hotclm#1
File surface:qa/browser-test-17-7/**on the evidence branch only — no product file changes
Container & model:L,mode:cloud(maintainer instruction, below),model: opus(TIER_DEFAULT; hand-derived for a sister repo)
Clause-②: no
Responsibility:n/a — not a defect card
Thread-read: 6091466891
Serial constraints cleared: #86 dispatched in parallel (separate container); PR #81 holdsAGENTS.md·CLAUDE.md·docs/backlog/README.md— untouched here
Read at: 2026-10-10T00:19ZRe-dispatch. The first dispatch (
mode:subagent, claim above) was stopped by the seat before it produced output — no push, its local worktree removed clean. The maintainer then instructed, verbatim, 2026-10-10: 「浏览器全流程测试 开云卡片,并要求截图给我看」 → this card now runs as a cloud session, and screenshots are a required deliverable: they are pushed to the evidence branch above (the one exception to "observation cards push nothing"), and the seat relays them to the maintainer.
Generated by Claude Code
- added 3 commits that reference this issue
on Oct 10, 2026 objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 87, "status": "done", "pr": null, "branch": "claude/issue-87-browser-test-17-7", "tree": "c31c7e2", "platform": "@objectstack/* 17.7.0 (spec, runtime, cli, console, plugin-security, plugin-approvals, service-analytics — read from node_modules/.pnpm)", "files_changed": [], "deviations": [ "Opened objectstack-ai/hotclm#89 (the retired Studio home as the first screen) at the maintainer's direct request in this session (「这个是 studio 很早之前作废的首页,为什么会进这个页面,开issue」). The dispatch said no GitHub writes; the maintainer's instruction overrode it for that one issue. Attaching objectstack-ai/objectstack to file it upstream was denied in this session, so #89 asks the seat to forward it.", "Wrote the maintainer's rule 「平台的问题就等平台」 into AGENTS.md as local commit b782dad on claude/agents-platform-gaps-wait, in a separate worktree. NOT pushed: the maintainer's two questions about it are open. It is not part of #87's deliverable.", "Operator setup beyond the README: the README never asks for sys_user.manager_id. After the approval ladder stuck (finding 3), I set all three requesters' manager to the General Manager via POST /api/v1/auth/admin/set-user-manager, and recovered the stuck request with the admin's Override Reassign.", "Buttons that sit below the fold of an unscrollable dialog (finding 1) were pressed with keyboard focus + Enter, which a keyboard user could do. A mouse user cannot.", "The container restarted mid-run (about 01:02Z to 01:46Z). The database survived. I restarted with `pnpm dev` (no reseed), and later re-ran `pnpm demo` deliberately to measure suspect 6.", "Requester 1 was created through the Setup dialog, which forced a password change at first sign-in (finding 18). Its password was changed in the browser. The other ten accounts were created through the same endpoint with an explicit password.", "Screenshots are numbered NNN (three digits, renamed at the end) so they sort in the order taken. A few numbers are retakes of the same screen after a script fix. The index marks them." ], "mcp_calls": [ "github.search_issues objectstack-ai/hotclm (duplicate check before #89) → 0 results", "github.issue_write create objectstack-ai/hotclm#89", "claude-code-remote.add_repo objectstack-ai/objectstack (push) → denied by the session's permission policy" ], "writes": [ "git push origin claude/issue-87-browser-test-17-7 @ db6f58d (pass 1)", "git push @ 940ce50 (setup, homes, requester intake)", "git push @ da25eb4 (lifecycle through archive and backfill)", "git push @ final commit (inbox, dashboards, zh-CN, suspect 6/7, this report)", "GitHub issue objectstack-ai/hotclm#89 (maintainer-requested)" ] }All readings below are on tree
c31c7e2with platform 17.7.0. Chromium 1194 (Playwright 1.56.1) drove the browser at a 1440×900 viewport. Screenshots are inscreenshots/.Boot
Verdict: a passing boot. No
System started with degraded capabilities, nono such table, andPlugins: 41 loadedwith none failing to load. Measured on all four boots: twopnpm demoruns, onepnpm dev, and onepnpm demore-run.What the banner does say, none of which invalidates the run:
- Compile, 6 author-time warnings.
approval-approvers-may-resolve-emptyonmanager_review,legal_finance_joint,legal_only,finance_only,executive_signoffandgm_signoff. The first one comes true on a README-configured install: see finding 3.Capability "hierarchy-security" is provided by @objectstack/security-enterprise: it is open-source here, soown_and_reportsdegrades to owner-only, as DESIGN.md §04 says.
- Runtime warnings.
- Six scheduled flows are
NOT bound — disabled by deployment policy (OS_AUTOMATION_SCHEDULED_WORK_ENABLED is unset). This is suspect 2. [Analytics] No admitObjectRead configured and no "security" service registered at init. In practice it is harmless: analytics was scoped per audience every time (suspect 10).[Seeder] Inline seed exceeded 8000ms budget … continuing in background.OAuth is served UNENCRYPTED(dev).
- Six scheduled flows are
- Seed, first boot:
{"inserted":820,"errored":404}. All 404 areDeferred reference UNRESOLVED … sys_user.name not foundfor the README persona names, which is expected before the accounts exist; every row landed. - Seed, after the accounts were created and
pnpm demore-run: owners were handed over as the README promises.owner_idreads 43/43/34 across the three requesters, andlegal_ownerreads 34/34 across the two counsel. - Re-run after the daily jobs: see suspect 6.
One wording problem on the re-run: the closing operator note prints again, verbatim ("The seeded rows have no people on them yet … 我的合同 and 法务工作台 stay empty"), after the accounts exist and the rows were handed over. On a second run that note is false.
Ranked findings
Ranked by cost to the product. A = this app, P = the platform. Per the maintainer's rule 「平台的问题就等平台」, a platform finding carries symptom, minimal repro and version, and no app-side workaround is proposed.
1. A requester cannot finish the intake wizard with a mouse at 1440×900 (P)
- Trying to: launch a contract (the first thing a requester does).
- In the way: step 2, "Contract details", renders in a dialog that is taller than the screen and does not scroll.
- Measured:
height 1184px, top -142px, bottom 1042px, overflow-y: visible. - Its Submit button sits at y=977.
mouse.wheel×10 moves nothing. - The heading is clipped off the top.
- Measured:
- Same layout elsewhere: the action-parameter dialog of Backfill Executed Contract measures
height 2198px, top -649px. Its first five required fields (Contract Type, Counterparty, Title, Signed On, Executed Copy) sit above the top edge. - Width: the flow-screen dialog is a fixed
sm:max-w-md, measured at 448px wide.ScreenConfigSchema(strict) has no layout, columns or width key, so metadata cannot ask for more. Object create/edit forms, by contrast, render two columns and scroll (050,081). - Repro: any flow
screennode or actionparamslist longer than about 12 fields, on a 900px-high viewport. 17.7.0 console. - Evidence:
016,018(after 10 wheel ticks),111/112(backfill), and the geometry readings above.
2. Submitting from the intake wizard fails for every requester (A)
- Trying to: finish the wizard with "Submit now" on.
- In the way:
POST /api/v1/automation/contract_intake/runs/…/resume {"submit_now":true}→400 FLOW_FAILED "Node 'submit_contract' failed: update_record(clm_contract) failed: You are not allowed to save this record with the values you entered." - Server log:
[Security] RLS check FAILED on update 'clm_contract' — write denied (fail-closed). - Cause:
- The requester's
contract_requester_edit_windowpolicy hasusing: status in (draft, submitted)and nocheck, and on 17.5+ theusingpredicate also checks the row after the write. - Submission auto-hops to
in_reviewonce F2 assigns a legal owner, so the post-image fails. - The header Submit button on the same draft succeeds (
POST /api/v1/actions/clm_contract/submit_contract → 200), so the product works by one door and not by the other.
- The requester's
- Smallest fix: give the policy an explicit
checkthat admits the statuses submission can land in (submitted,in_review,in_approval). The alternative is to run the wizard's submit node the way the action runs. - Evidence:
025,026;034/035(header Submit works); log lines quoted.
3. The approval ladder sticks forever at rung 1 on a README-configured install (A, with a P symptom)
- Trying to: send a reviewed contract for approval.
- In the way:
- The request opens on
current_step: "manager_review"withpending_approvers: ["manager:undefined"]. Nobody's inbox shows it, andlockRecordkeeps the contract locked. - The only recovery is a platform admin's Override Reassign (
061–063). - The README's operator setup never mentions
sys_user.manager_id. That column can only be set throughPOST /api/v1/auth/admin/set-user-manager, as the compile warning itself says. - The request's
submitter_idis the lawyer who clicked Send for Approval, not the requester.
- The request opens on
- After the operator set managers: rung 1 → General Manager approved (
069), rung 2legal_only→ Legal Head approved (073). The contract reachedapprovedwithapproved_atstamped. So the ladder works once someone tells the operator the step the README leaves out. - Smallest fix (A): the README operator setup names the manager step, or F5 declares
onEmptyApprovers: 'fallback'onmanager_review, as the platform's own warning suggests. - P symptom: a slate that resolves empty is stored as the literal
"manager:undefined", with no diagnostic on the request. - Evidence:
057–060,064–073.GET /api/v1/approvals/requests?object=clm_contract&recordId=… → pending_approvers ["manager:undefined"].
4. Only
clm_admincan move a contract from approved to signing, andclm_admincannot write the contract (A, decision)- Records Manager, who holds
execute_contract:GET /api/v1/data/clm_contract/<approved id> → 404 RECORD_NOT_FOUND. Records sees 0 of the 5 approved contracts, because its policy starts atsigning, and the page says "Record not found" (075). - Legal sees the approved contract with no Start Signing button (
076), because legal lacksexecute_contract. clm_adminsees Start Signing but cannot write the contract at all:PATCH clm_contract/<id> → 403 "You do not have access to this record". Theclm_adminset carries no update RLS policy onclm_contract, so 17.5's fail-closed denies it. This is suspect 4.- It also cannot add the clean version the signing guard needs:
POST clm_contract_version → 403 "master 'clm_contract' not editable by this user (row-level security)"(079). - The flow only completed because legal uploaded the clean version (
084/085) andclm_adminthen pressed Start Signing (086).
- It also cannot add the clean version the signing guard needs:
- Smallest fix: a decision rather than a patch. DESIGN.md §05 lists 发起签署 on the header but never says who presses it. Either records reads
approved, or legal getsexecute_contract. Theclm_adminupdate policy is a separate one-line gap. - Evidence:
074–086, and the PATCH/POST readings above.
5. A requester cannot complete their own obligation once the contract is in force (A)
- Trying to: mark "Provide the annual security attestation" done from My Obligations.
- In the way:
PATCH clm_obligation/-YpaMcuIEzJyRhnt {"status":"done"} → 403 "requires edit access to its master record (master 'clm_contract' not editable by this user (row-level security))". The form says "You don't have permission to save this record" (095).- The obligation is a master-detail child of an
activecontract, outside the requester's draft/submitted edit window. - DESIGN.md §04 promises requesters "RU(本人负责)" on obligations. Every requester obligation on an active contract is unreachable.
- The obligation is a master-detail child of an
- Smallest fix: an app decision about whether obligation updates need the master editable (
controlled_by_parent), or a requester update path on active contracts limited to obligation fields. - Evidence:
092–095.
6. First screen after sign-in is the retired Studio home with an empty sidebar (P, with A contributing) → #89
GET /api/v1/meta/app/clmanswers"navigation": []for the dev admin, because every group is gated on aclm_*.accesscapability the admin lacks.- The console's app index route then falls back to
StudioHomePage(index-ocmkyCt6.js:Wv(app) ? <Navigate…/> : <StudioHomePage/>). - Nothing on the screen is about contracts, or says what to do next.
- Evidence:
002,003,005(the data is there by direct URL), and issue #89.
7. Header actions succeed and the page keeps showing the old state (A)
- Submit, Send for Approval, Start Signing and Activate all answer
200 {"success":true}and toast "Action completed successfully". The header still shows the old status and the old button until a manual reload. 034shows Draft + Submit after the contract was alreadyin_review, and035is the same page after a reload.- Smallest fix:
refreshAfter: trueon thetransition()actions incontract-lifecycle.actions.ts. Terminate and Start Renewal already set it.
8. Finance has no Edit on a payment instalment page (P)
/security/explain(update) answersallowed:true, andPATCH clm_payment_plan/2Z5jVv89O6rz4Ezwas finance →200.- The record header renders no Edit button for finance or
clm_admin. The dev admin gets one (098). - The only UI path left for finance is list "Edit inline".
- Repro: sign in as a
clm_finance_controllerand open anyclm_payment_planrecord. 17.7.0.
9. Requesters and lawyers get 403 on the contract page's Discussion and Approvals tabs, and on their own files (P/A, #86 in flight)
- On
main:GET sys_comment → 403GET sys_activity → 403, also on every page's header activity feedGET sys_attachment → 403GET sys_approval_request → 403
- The Discussion tab says "You don't have permission to view activity/comments" (
033), and the Approvals tab is blank for the requester (030). - New beyond A business requester and a legal counsel get "You don't have permission" on the contract's Discussion tab and a blank Approvals tab —
sys_activity/sys_comment/sys_attachment/sys_approval_requestanswer 403 #86:GET sys_file → 403for the requester. The server logssys_file lookup failed; file fields keep their raw ids and will render as "no file". The requester's own just-uploaded version 1 shows no file, and the Attachments panel says "You don't have access to these attachments" (036).
10. Deviation create form refuses with "Status is required" although
openis the declared default (P)clm_deviation.statusdeclares{ value: 'open', default: true }. The spec'sSelectOption.defaultis described as "Is default option".- The console's create form leaves the select on "Select an option" and blocks Create (
050). - Repro: any
Field.selectwith an option-leveldefault: true, opened in a create form. 17.7.0.
11. Developer notes shown to users as help text (A)
- Field descriptions are rendered as help text:
- "open → accepted / rejected / withdrawn; the decided states are terminal (contract.hook.ts)" (
050) - "Enforced by contract.hook.ts; overdue is written only by the daily job (card 09)" and "measures arrears against … (card 09)" (
095) - "(DESIGN.md §01: signing entities are configuration, not schema)", "(DESIGN.md §04)", "(§13 Q2)", "(clm_approval_rule)", "The expiry job (F13) flags is_expiring renewal_notice_days…" (
111)
- "open → accepted / rejected / withdrawn; the decided states are terminal (contract.hook.ts)" (
- Dashboard widget descriptions:
- "Not an average duration — see the PR."
- "The ball is in their court — the queue F4 chases"
- "Older than every seeded type SLA (longest is 10 days) — a fixed threshold…" (
121)
- The approval ladder's rung label reads "Head of Legal + Finance Controller (会签)" in the English UI (
065). - Smallest fix: move implementation notes to code comments and keep
descriptionuser-facing.
12. Refusals reach the user with the platform's internal prefix (P)
- The toast reads
hook 'contract_state_machine' threw: Error: 1 deviation(s) are still open; decide each one before the contract enters approval.(053), and likewise for "A current clean version is required before signing." (077). - The app's message is good. The prefix is the platform's.
- Repro: a
beforeUpdatehook that throws an Error, reached throughPOST /api/v1/actions/.... 17.7.0.
13. The Expiry Calendar plots at most 100 contracts, and
?top=0reports zero rows (P)- Calendar: the view fetches
GET /api/v1/data/clm_contract?top=100&select=…,end_datewith no date window. The total is 122, so up to 22 contracts never appear on the calendar. Evidence:041, the network reading. ?top=0:GET /api/v1/data/clm_contract?top=0 → {"total":0}, while?top=1 → {"total":122}. The console issues thistop=0probe on every list page. 17.7.0.
14. The grid footer's "Sum" is the visible page's sum, shown beside the full row count (P)
- Payment Schedule shows "Planned Amount: Sum: 3,685,900.00 · Actual Amount: Sum: 3,685,900.00 · 300 records" (
096). - Across all 300 rows the sums are 40,607,000 planned and 12,445,700 actual. The footer is the first 25 rows.
15. No one is told an approval is waiting on them (A or P, undetermined)
- When rungs opened for the GM and the Legal Head, both had
sys_inbox_messagetotal 0. - The only CLM message before the jobs ran was the requester's "Contract approved…" (
115). - The approvals inbox does list the request (
064,070), so the approver has to know to look.
16. New version form defaults "Current" off, and two versions can both be current (A)
- The contract-page version form defaults
is_currentto off, so a clean version saved as offered (079,082) does not satisfy the signing guard ("A current clean version is required"). - After ticking it, versions 1 (draft) and 3 (clean) were both
is_current: true. Nothing keeps it exclusive.
17.
pnpm demore-run after the daily jobs silently undoes them (A) — suspect 6- See suspect 6 below.
18. Setup → Create User ignores the password you type (P)
- The dialog posts
{"generatePassword":true,"mustChangePassword":true,…,"password":"<typed>"}by default. - The account then gets a one-time generated password and a forced change at first sign-in (
006,007). - Repro: Setup → Users → Create User, type a password, Confirm. 17.7.0.
19. Smaller things a real user would notice
- Requester's view switcher: shows the legal tabs ("Awaiting Intake", "My Reviews", "7 more") and all three analytics dashboards, including Legal Workbench (
012,124). (A) - Records' contract list: shows New and Import, although its profile has
allowCreate: falseonclm_contract(button reading). (P) - Wizard contract-type picker: offers "Create new" to a requester who cannot create contract types (
014). (P) - Wizard step 3 (First version): offers a "Draft from template" toggle on a type whose own text says it carries no template (
020). (A) - Start Renewal: creates
NDA-2026-0023withrenewed_fromset, toasts "Renewal draft created.", and leaves the user on the old contract with no link to the draft. The button stays (099). (A) - Approval sheet: shows raw values
nda,other,in_approval(065). (P) /security/explain: answersallowed:true(update) for Records on a contract that isRECORD_NOT_FOUNDfor Records, and forclm_admin, whose real PATCH is denied. The diagnostic contradicts the write door. (P)- Abandoned wizard: closing the wizard after step 3 leaves an orphan draft. NDA-2026-0021 was left by an aborted run. (A)
- Backfilled contract owner:
SUP-2026-0019is owned by the Records Manager who keyed it in, not by any business owner. (A, worth a decision)
What worked as designed (positive controls)
These were measured, not assumed:
- Guards refuse with clear messages:
- "1 deviation(s) are still open…" (
053) - "A current clean version is required before signing." (
077) - "An archive number is given when the contract is closed; this one is active…" (
106)
- "1 deviation(s) are still open…" (
- Legal review: creating a review →
201(048); accepting a deviation →200(055). - F8: filed the round's executed copy as a
final_signedversion, and Activate stampedactivated_at,signed_atandexecuted_at(091). - Termination: stores its reason and
closed_at(101). - Archive: records archiving a terminated contract stamps
archived_at(109). - F16 backfill: creates an
active,is_backfilled: truecontract (114). - Lists: every list reading matched the data API.
The card's 10 suspects
- First-run navigation / empty 我的合同 — reproduces.
- Dev admin:
GET /api/v1/meta/app/clm → navigation: [], the sidebar is empty, and the first screen is the Studio home (002, #89). - The data is there: 120 contracts by direct URL (
005). - After the README setup, each persona's groups and lists fill (
008–012). A lawyer's landing page is the requester's "My Contracts" view, empty for a lawyer (008).
- Dev admin:
- Scheduled work OFF by default — reproduces.
- Boot: six flows "NOT bound — disabled by deployment policy".
- Fresh demo inbox: 0 messages for every persona except one produced by my own approval (
115–117). - After
POST /api/v1/automation/{legal_review_sla,turn_stalled,obligation_due,payment_overdue,renewal_notice,expiration_sweep}/trigger(allsuccess:true), the inboxes read requester1 10, requester2 6, legal1 2, legal2 4 and finance 18 (118–120). renewal_noticeandexpiration_sweepproduced nothing, although 11 contracts carryis_expiring.- The run summaries say
acted 0for five of the six flows even where messages were sent.
- Requester / legal Discussion "no permission" and Approvals blank — reproduces on
main.sys_comment,sys_activity,sys_attachmentandsys_approval_requestall → 403 (030,033,060). Thesys_file403 (finding 9) is additional. A business requester and a legal counsel get "You don't have permission" on the contract's Discussion tab and a blank Approvals tab —sys_activity/sys_comment/sys_attachment/sys_approval_requestanswer 403 #86 is in flight and was not touched. clm_admincannot edit a contract pastsubmitted— reproduces. Measured atapproved:PATCH → 403 "You do not have access to this record", and a version insert → 403 (finding 4,079).- Backfill invisible to legal — reproduces. The All Contracts toolbar shows "Backfill Executed Contract" for records and
clm_adminbut not forlegal1, because the action requiresexecute_contract. Button reading, plus111for records. pnpm demore-run after the daily jobs — reproduces, in a new shape.- Seed summary:
{"inserted":0,"updated":18,"skipped":801,"errored":1}. - The error:
Failed to write clm_contract record #104 (Lease Agreement — Granite Facilities): A terminated contract is closed; its status cannot change to active. That is the contract legal terminated in this run. - Worse, the 18 updates silently reverse
payment_overdue's work: 18 part-paid instalments go fromoverdueback topartial, because overdue → partial is an allowed transition. Overdue drops from 30 to 12 and nothing says so. pnpm demostops being re-runnable once the daily jobs have run: the seed re-asserts statuses the state machines refuse to go back to #41'soverdue → plannederror does not appear on 17.7.0.
- Seed summary:
- Declared fields with no consumer as a visible hole — does not reproduce on the screens opened.
- The default record pages render every field: the clause's Standard and Fallback wording (
148), and the counterparty's fields (147). - None of [Decision] 17.4 的新规则指出 21 个字段声明了却没人读——展品该给它们消费者,还是删掉声明 #38's 21 fields is a
clm_contractfield, so the custom contract page has no hole from them. - This check is not exhaustive: list views and related lists do not show them.
- The default record pages render every field: the clause's Standard and Fallback wording (
- zh-CN — reproduces for the flow screen only.
- In the intake wizard, labels and the step-1 help are Chinese.
- The step-2 screen description ("The core terms every contract carries…") and every select option (Head office; Sales / Procurement / Legal…; "USD — US Dollar"…; Net 15 / Net 30…) stay English (
138,139). This is upstreamobjectstack-ai/objectstack#22507. - Chrome, lists, the detail page (option "总部", "USD — 美元") and all three dashboards, including chart category labels (
142,144), are Chinese. - The demo data is English because this is the en book (
pnpm demo:zhwas not run).
- List views page at 50 — does not reproduce as a problem.
- The app pins
pagination: { pageSize: 25 }on every primary view, so All Contracts fetchestop=25and Payment Schedule pages 25 ("Page 1 of 12",096). - The legal queue views fetch
top=50, and the calendartop=100(finding 13). No list felt wrong for its size, apart from the calendar cap.
- The app pins
- Analytics on 17.7.0 — does not reproduce.
- Every widget renders with no analytics error (
calls N, errors 0on all 18 dashboard loads). - Values match
/api/v1/dataread as the same user:- legal1: 6 / 12 / 6 / 2 / 2 (↓78% vs 9 last month); 12 expiring; 21 high-risk; routes 12 / 42 / 23 / 4; USD 9,407,000 active; 30 overdue = 3,413,450.
- requester1: 3 / 4; USD 2,518,500; 11 overdue = 798,700.
- executive: 3 / 5; USD 5,356,500; 4 overdue = 1,066,800.
- finance and records: legal widgets 0; USD 9,407,000; 30 overdue = 3,413,450.
- Analytics is scoped per audience, matching each audience's own data reads.
- Every widget renders with no analytics error (
Product files unchanged
git diff --stat origin/main -- . ':!qa/browser-test-17-7'(origin/main =c31c7e2):(empty)Screenshot index
File What it shows 001-p1-sign-in-page Pass 1: sign-in page 002-p1-first-screen-after-sign-in Pass 1: retired Studio home, empty sidebar (#89) 003-p1-navigation-app-switcher-open Pass 1: app switcher — HotCLM / Setup only 004-p1-inbox-bell-before-jobs Pass 1: inbox "You're all caught up" 005-p1-admin-direct-url-contract-list Pass 1: the 120 contracts exist, by direct URL only 006-setup-create-user-dialog Setup → Create User dialog (finding 18) 007-req1-forced-password-change Forced password change on first sign-in (finding 18) 008–011 Homes: legal1, finance, records, clm_admin 012-req1-home Requester home: 我的合同 › Launched by Me, filled 013–015 Intake step 1: type + counterparty pickers ("Create new" offered) 016-req1-intake-step2-contract-details Intake step 2, dialog clipped top and bottom (finding 1) 017, 019 Intake step 2 filled (017 is a retake) 018-finding-intake-step2-submit-below-viewport-after-wheel Submit unreachable after wheel scrolling (finding 1) 020 Intake step 3, "Draft from template" toggle on a template-less type 021–023 Intake step 4: upload first version (021 is a retake) 024–026 Intake step 5: "Submit now" → FLOW_FAILED (finding 2) 027–033 Requester's draft: overview and every tab; Approvals blank, Discussion 403 (suspect 3) 034, 035 Header Submit succeeds; the page does not refresh until reload (finding 7) 036 Versions tab: the requester's own file shows "no file", attachments 403 (finding 9) 037–043 Legal desk: Awaiting Intake, My Reviews, In Negotiation, All Contracts, Expiry Calendar, My Obligations, Waiting on Me 044–048 Legal records an approved review 049–051 Deviation form: Status not prefilled (finding 10); deviation created open 052, 053 Send for Approval refused while a deviation is open; toast with internal prefix (finding 12) 054–057 Deviation accepted → Send for Approval succeeds 058–060 Ladder stuck on "manager_review" (finding 3): Setup list as admin, Approvals tab as admin and as legal 061–063 Admin Override Reassign to the GM 064–069 GM: Waiting on Me → request sheet → Approve (064/065 are retakes of 066/067) 070–073 Legal Head: Waiting on Me → Approve → contract approved 074, 075 Records: Awaiting Execution; approved contract "Record not found" (finding 4) 076 Legal: approved contract, no Start Signing 077–080 clm_admin: Start Signing refused; version insert 403 (finding 4, suspect 4) 081–086 Legal uploads a clean version (081/082 saved with Current off; 084/085 with it on); clm_admin Start Signing succeeds 087, 088 Records: Awaiting Execution with the QA contract; Signing tab (records cannot open a round) 089, 090 Legal opens a completed wet-ink signature round 091-records-activate-succeeded Records activates (F8 filed final_signed from the round) 092–095 Requester My Obligations → mark done → 403 (finding 5) 096–098 Finance Payment Schedule (footer Sum, finding 14); payment page with no Edit (finding 8) 099 Start Renewal → renewal draft created; no link to it 100, 101 Legal terminates an active contract with a reason 102, 103 Records: Awaiting Archive, Contract Register 104–106 Archive number refused on an active contract (positive control) 107–110 Archive number on the terminated contract; archived_at stamped 111–114 Backfill dialog off the top of the viewport (finding 1); filled; "Executed contract recorded." (111 is a retake of 112) 115–117 Inbox before the daily jobs: requester1, legal1, finance 118–120 Inbox after triggering the six jobs 121–123 Dashboards as legal1 124–126 Dashboards as requester1 127–129 Dashboards as finance 130–132 Dashboards as records 133–135 Dashboards as executive 136 zh-CN: requester home 137–139 zh-CN: intake wizard; step 2 body text and options in English (suspect 8) 140 zh-CN: contract detail page 141–144 zh-CN: all three dashboards; Pipeline by Stage chart labels in Chinese 145–148 Suspect 7: Clause Library list, clause record with its wording, counterparty record - Compile, 6 author-time warnings.
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsACCEPT — observation card, no PR · 2026-10-10T02:40Z
Collected by the
repo:hotclmseat from the evidence branchclaude/issue-87-browser-test-17-7@173a166(cloud sessionsession_012BtouqNfFazqX5akwoC8Jk); the report is theos-dev-reportcomment above.check reading product files untouched git diff --stat c31c7e2 origin/claude/issue-87-browser-test-17-7 -- . ':!qa/browser-test-17-7'→ emptyboot passing — 41 plugins, no degraded capabilities, no no such tablescreenshots 148 under qa/browser-test-17-7/screenshots/, indexed inREPORT.md; relayed to the maintainersuspects 1–10 each answered with a reading (1–6 and 8 reproduce; 7, 9, 10 do not) no PR none open for the branch; the branch is evidence only and is not merged Deviation noted, not charged: hotclm#89 was opened in the cloud session at the maintainer's direct request there; it has since moved to objectstack-ai/objectui#12079. An
AGENTS.mddraft (claude/agents-platform-gaps-wait, local, unpushed) is between that session and the maintainer and is not part of this card.Where every finding went
- Platform → filed upstream (maintainer, 2026-10-10: 「你遇到的平台问题应该提交issue」): First screen after sign-in is the retired Studio home when the app serves an empty navigation objectui#12079 (Studio home on empty navigation) · console: a screen flow renders every screen in a fixed 448px single-column dialog, so a long screen pushes its Submit below the viewport on a 1440px display (17.7.0) objectui#12080 (narrow, unscrollable screen / action-param dialog — evidence added) · console (17.7.0): seven UI defects measured in one full browser pass of a metadata app — missing Edit, capped calendar, page-only footer sum, ignored password, and three affordances shown to users who cannot use them objectui#12081 (seven Console defects: missing Edit, calendar cap, page-only footer sum, ignored password, three ungated affordances) · runtime (17.7.0): three server-side defects seen from a metadata app — hook refusals reach users with an internal prefix,
?top=0answerstotal: 0, andsecurity/explainallows updates the write door refuses objectstack#22588 (hook-refusal prefix,?top=0total, explain vs door) · plugin-approvals: amanagerapprover whose owner has nomanager_idlands as the literalmanager:undefinedinpending_approvers, where the documented contract says the request opens with an empty slate (17.7.0) objectstack#22558 (manager:undefined) · plugin-approvals:sys_approval_requesthas no parent-record read gate on the data door, and the ruled record-reader tier cannot be switched on by an app (17.7.0) objectstack#22559 (approval data door) · A screen flow's select options and screendescriptionhave no key in theflowstranslation face — the zh-CN intake wizard translates its labels and placeholders and keeps its options and body text in English (17.7.0) objectstack#22507 (flow screen i18n). Already fixed upstream after the 17.7.0 pin, not refiled: objectui#11914 (select default), objectui#12047 (Upload affordance). - App → this repo: finding 2 (wizard "Submit now" fails for every requester) → filed The intake wizard's "Submit now" fails for every requester —
FLOW_FAILED, the edit-window RLS policy refuses the post-submit row, while the header Submit button on the same draft succeeds #90, dispatched next. Finding 5 (requester cannot complete own obligation on an active contract) → evidence for DESIGN.md §04 givesclm_requesterupdate on its own obligations, andcontrolled_by_parentrefuses it for all 200 — 我负责的履约 is read-only for the audience it is built for #64. Suspect 6 (demo re-run silently reverts 18 overdue instalments) → evidence forpnpm demostops being re-runnable once the daily jobs have run: the seed re-asserts statuses the state machines refuse to go back to #41. Finding 9'ssys_file403 and A business requester and a legal counsel get "You don't have permission" on the contract's Discussion tab and a blank Approvals tab —sys_activity/sys_comment/sys_attachment/sys_approval_requestanswer 403 #86's Approvals half → A business requester and a legal counsel get "You don't have permission" on the contract's Discussion tab and a blank Approvals tab —sys_activity/sys_comment/sys_attachment/sys_approval_requestanswer 403 #86. The remaining app findings (3 approval ladder on a README install, 4 who presses Start Signing — a decision, 7 header actions do not refresh, 11 developer notes as help text, 15 approvers not notified, 16 two current versions, 19's smaller items, the two jobs that produced nothing) are queued in the seat post and filed over the next fires (per-fire filing cap).
Generated by Claude Code
- Platform → filed upstream (maintainer, 2026-10-10: 「你遇到的平台问题应该提交issue」): First screen after sign-in is the retired Studio home when the app serves an empty navigation objectui#12079 (Studio home on empty navigation) · console: a screen flow renders every screen in a fixed 448px single-column dialog, so a long screen pushes its Submit below the viewport on a 1440px display (17.7.0) objectui#12080 (narrow, unscrollable screen / action-param dialog — evidence added) · console (17.7.0): seven UI defects measured in one full browser pass of a metadata app — missing Edit, capped calendar, page-only footer sum, ignored password, and three affordances shown to users who cannot use them objectui#12081 (seven Console defects: missing Edit, calendar cap, page-only footer sum, ignored password, three ungated affordances) · runtime (17.7.0): three server-side defects seen from a metadata app — hook refusals reach users with an internal prefix,
objectstack-fleet commented
on Oct 10, 2026 ContributorAuthorMore actionsAddendum · 2026-10-10T02:44Z — the cloud session pushed a final revision after the ACCEPT above (
81cb18b: a Platform issues to file section P1–P16, and #88 confirmed in the browser on46e65f0— requester and legal read and post on the Discussion tab, screenshots149/150). Dispositions for the four items not already covered: P13 / P15 / P16 (server cap) → filed objectstack-ai/objectstack#22590; P14 ("System" on every activity row) → evidence on objectstack-ai/objectstack#22510; P16 (header widget's unscopedsys_activitycall) → item 8 on objectstack-ai/objectui#12081. P1–P12 map onto objectui#12080 / #12081, objectstack#22588 and the already-fixed objectui#11914.
Generated by Claude Code
Filing class: ③ maintainer direct dispatch. Maintainer, 2026-10-10, verbatim: 「#85 同意合并,然后使用浏览器完整的测试。」
⛔ Observation only. This card produces NO code and NO pull request. Its deliverable is a report of what the browser actually did. The seat turns findings into cards. ⛔ Do not fix anything you find — a fix inside an observation pass is an unreviewed change with no card behind it. Precedent for the shape: #45 (the M3 dogfood pass on 17.4.0).
Why now
PR #85 merged at
c31c7e2:mainmoved from@objectstack/*17.4.0 to 17.7.0 across three minor releases with breaking changes in security (17.5 RLS fails closed; 17.6 deny baseline and FLS at every query door; 17.7 "a row the caller cannot read is not there" on the write doors), analytics, flows, approvals and i18n. #85's own browser pass verified the upgrade; this card is the whole product, end to end, on the new platform.Pass 1 — first run, as a stranger (⛔ no README operator setup)
Fresh worktree off
origin/main@c31c7e2,pnpm install,pnpm demo, sign in as the seeded dev admin, and stop. Report what a first-time evaluator sees in the first sixty seconds: navigation groups, empty screens, the first screen's text, and anything that tells them what to do next. This is the reading behind #28 and #11 — re-measure, ⛔ do not assume.Pass 2 — the full lifecycle, after the operator setup
Do the README setup, then drive contracts all the way through as the right audience at each step — intake → acceptance → review and deviations → approval ladder → signature and execution formalities → activation → obligations and payments → renewal / expiry / termination → archive — plus the backfill (F16) path. Use every audience group the README names (requester, legal, finance, records, admin), not admin for everything: a screen that only works for an admin is not a working screen. Then the inbox, every dashboard, and one full pass in zh-CN.
Known suspects — say for each whether it reproduces on 17.7.0 (verify, ⛔ do not assume)
pnpm demo开箱即用时没有任何账号能打开「我的合同」——要不要让脚本建账号,与 #11 第一问耦合 #28, [Decision]DESIGN.md§04 makesclm_requesterevery employee's default, but a set that grantsclm_requester.accesscannot bind toeveryone#11).@objectstack/*dependencies from 17.4.0 to 17.7.0, walking the official upgrade checklists of 17.5, 17.6 and 17.7 #82, in the decision box): what does an evaluator see in the inbox on a fresh demo with no manual trigger? Then trigger the jobs by hand (POST /api/v1/automation/NAME/trigger) and read the inbox again.sys_activity/sys_comment/sys_attachment/sys_approval_requestanswer 403 #86 — a dev is working it in parallel; report the reading, ⛔ do not touch it).clm_admincannot edit a contract pastsubmitted(evidence on [Decision]DESIGN.md§04 makesclm_requesterevery employee's default, but a set that grantsclm_requester.accesscannot bind toeveryone#11).pnpm demore-run after the daily jobs have run (pnpm demostops being re-runnable once the daily jobs have run: the seed re-asserts statuses the state machines refuse to go back to #41).objectstack-ai/objectstack#22507); chart category labels; anything else still English./api/v1/data, per audience?What to report — not a bug list
For each finding: what the user was trying to do, what got in the way, the smallest change that would fix it, and whether the producer is this app or the platform (platform causes go upstream, ⛔ not into this app). Rank by cost to the product. Specifically wanted: the first-sixty-seconds problem; dead ends (missing / disabled / unexplained refusals); places the product lies (labels, counts, empty states that do not match the data); anything an evaluator would have to be told.
Evidence rules
GET … → 200 {"total":0}beats "the list looked empty").System started with degraded capabilities,no such table, or a plugin that failed to load means the run is not of the product — report it first.c31c7e2) and the platform version (17.7.0).Filed by the
repo:hotclmPM seat on the maintainer's instruction.