Commit Graph
189 Commits
Author SHA1 Message Date
weichen 097ba8f457 merge: dev (08bf615 cache race fix) 2026-09-14 03:36:17 +00:00
weichenandCursor 08bf615f95 fix(web): keep hydrated content across late list sync
Hard refresh wiped cache/ready after a successful hydrate, then the
unchanged fingerprint never re-ran the effect. Invalidate only via a
planner that preserves list-sync hits and re-hydrates after post-task drops.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 03:33:37 +00:00
weichen 2907c5025d test(docgov): record controlled content UI acceptance and UI-06 cache race diagnosis 2026-09-14 03:33:33 +00:00
weichenandCursor f693e1c474 fix(web): stop hydrating local legacy mock documents
Login-seeded doc-001 is not server-backed; align shouldLoad with
revisionToolbarMountMode so content and revision-state are never requested.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:56:35 +00:00
weichenandCursor c159786a70 fix(docgov): keep markdown hard-breaks and unify content hashes
Semantic-preserving canonicalization, same-byte write paths, structured
content errors, and a dry-run-default migration_repair stop 404s caused
by trimming project-143 hard-breaks and no-op lease hydrations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:02:53 +00:00
weichenandCursor 00737c7d5e fix(web): allow frp-mix.com Host for Vite dev server
FRP reverse-proxy access to :3100 was blocked by Vite host checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 01:30:38 +00:00
weichenandCursor 5db2d9a3b1 fix(e2e): persist the winning A1 body snippet for post-restart
UI-13b already made A1 the durable document, but phase-state still expected the UI-06 marker. Record successful saves as the latest snippet, ignore conflict drafts, and write that final value at UI-15-pre without relaxing the restore assertion.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:28:17 +00:00
weichenandCursor 0936a94fdf fix(e2e): write post-restart results to a separate ledger
A successful post-restart recordPass would overwrite the main 18-case ui-acceptance-results.json. Keep that historical name for main and write ui-acceptance-results-post-restart.json after restart, while still sharing phase-state and secrets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:23:27 +00:00
weichenandCursor 3c26fcb2f8 fix(e2e): assert restored project in the banner and isolate phase artifacts
Page-wide project-name text hits both the top bar and the session rail after restart. Click the complementary exact title, then assert the banner exact name. Split Playwright output and HTML reports by UI_PHASE so post-restart cannot wipe main traces.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:21:09 +00:00
weichenandCursor 8b6bf2cca1 fix(api): sync removed members and fail tasks without a ledger
Remove now reconciles document slots and returns ERR_DUTY_SYNC on
failure. CreateOrGetDocument errors abort the task. The frontend
refreshes workflow docs after add, update, restore, and remove.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:29:53 +00:00
weichenandCursor 7ef34a685d fix(web): send document_duty on member add, update, and restore
Post-create role changes were silently dropping reviewer/approver
because only project_role was persisted.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:16:44 +00:00
weichenandCursor c1bdfe3920 feat(web): persist exclusive reviewer duty on project create
Keep project_role as member/viewer, send document_duty=reviewer for USER_B, and clear the seed 李主管 reviewer so the assigned reviewer is the one that syncs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:57:53 +00:00
weichenandCursor c86e229303 fix(e2e): require exact reviewer duty, reject viewer fallback
USER_B is assigned reviewer in UI-01. Accept only role=reviewer on
the duty control, and reject assignable or enabled selects.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:28:15 +00:00
weichenandCursor c8318e8551 fix(e2e): read duty from select value, not row option text
UI-13a treated concatenated select options as the current role.
Assert the control value or badge role for that doc instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:26:23 +00:00
weichenandCursor ba4bb41e1c fix(e2e): switch to workflow category before opening controlled docs
UI-13a stayed on private after upload, so the doc menu had no
doc_proj* entries. Always use the category trigger first, then exact id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:03:23 +00:00
weichenandCursor f0ab254ed1 fix(e2e): accept already-completed squad turns without waiting inflight
UI-11 can finish before the waiter sees pending. Treat success terminals
as done, keep upload/correspondence/error checks, and cover both timelines.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 20:43:33 +00:00
weichenandCursor 9b43bd6a73 fix(web): bind editor saves to the opened doc and real PATCH
Drop test-only ETag helpers. App now calls saveControlledBlockEdit,
which PATCHes once on the bound editor docId or fail-closes. Resume
hydrate after a blocked first load, and refuse silent doc switches.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 20:00:47 +00:00
weichenandCursor 1b04d962d1 fix(web): keep block ids and drafts across editor hydration races
Background GET rebuilt markdown AST with Math.random ids and dropped
head_block_map, so save closed the modal without PATCH. Align hydrate
to the ledger map, gate in-flight responses, and fail-closed on stale ids.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:54:36 +00:00
weichenandCursor bebe1e3690 test(e2e): open UI-11 prelim_design by registered doc_proj id
Card title is 系统初步设计方案, not 系统设计输入; select doc_proj*_prelim_design so the template slot cannot be mistaken for the generated document.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:46:21 +00:00
weichenandCursor bdd1b35b86 test(e2e): require UI-11 task run 202 before completion
Arm tasks/runs waiter before send and assert HTTP 202 so a sync DOC_BUSY completed turn cannot pass as a new document run.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:42:44 +00:00
weichenandCursor 56e052f3cb fix(web): prefer named deliverable over negated 需求
Explicit aliases (including 系统设计输入) must win before keyword fallback so UI-11 does not route to intake.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:42:44 +00:00
weichenandCursor 9f676273df test(e2e): wait for overlay CSS transition to settle
Poll pane document-block computed styles until two frames match.
Pure requires transparent background and box-shadow none; manual/all
require a real overlay mark without hard-coded theme colors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:24:27 +00:00
weichenandCursor 20b6092cf0 test(e2e): sample overlay styles on pane document-blocks
UI-07 reads every active-pane document-block after the real overlay
fetch. Pure must stay unmarked; manual/all may share amber on the
same human hunk. UI-10 waits for history to auto-close.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:06:53 +00:00
weichenandCursor 5c42ba7c45 test(e2e): save inside editor dialog with exact 保存修改
UI-06/13b click 保存修改 only inside 编辑受控块; UI-13a asserts
the dialog is absent instead of a page-wide /保存/ match.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:46:37 +00:00
weichenandCursor a42895ccdc feat(web): give block editor an accessible dialog label
Expose role=dialog and a stable aria-label so save can be scoped
without changing the modal's visuals or save behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:46:37 +00:00
weichenandCursor faaacae5f6 test(e2e): locate pane blocks by document-block testid
UI-06 and UI-13b reuse the pane-scoped helper; stop clicking overlay
or native heading/paragraph tags that the renderer does not emit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:24:54 +00:00
weichenandCursor 9e0901ce25 feat(web): mark real document blocks without overlay
Add data-testid=document-block plus block id on every wrapper so
pure-mode editors stay addressable without changing visuals.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:24:54 +00:00
weichenandCursor cf3d126436 feat(web): never name-escalate server controlled zero duty ids
Mark server summaries dutiesAuthoritative so id 0 stays fail-closed
viewer instead of matching names like a legacy local document.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:08:35 +00:00
weichenandCursor d5ce81228c feat(web): keep viewer comments read-only
Hide add-comment affordances and reject submit for viewer; keep
author/reviewer/approver comment roles unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:08:35 +00:00
weichenandCursor 4dbd9eecb9 feat(web): fail-closed controlled save without hydrate ETag
Reject revision-state network/5xx and missing ledger on controlled
hydrate; never PATCH 0:0 unless the document is freeform.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:08:35 +00:00
weichenandCursor be33409297 test(e2e): open both editors before UI-13b first save
Require matching r/etag on both windows and keep A2's editor filled
before A1 saves so the conflict is a real race.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:02:23 +00:00
weichenandCursor eefdd4c4fd feat(web): keep server duties and PATCH with hydrate ETag
Retain ledger author/reviewer/approver, fail-closed unknown users to
viewer, and send the opened revision ETag instead of a fresh GET.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:02:23 +00:00
weichenandCursor 5571e93922 test(e2e): pin UI-05b to intake and tighten history/conflict paths
Require 当前受控文档 deixis plus tasks/runs task_key/doc_id checks so reject stays on intake; compare inside 版本历史, hide the project from non-member C, and split UI-13 into reviewer-readonly plus dual-author conflict.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 16:50:02 +00:00
weichenandCursor ca01a1cf9d test(e2e): open pending change report before confirm or reject
UI-04 must close via the dialog 关闭 button; UI-05a/05b must click 待确认报告 and assert panel actions so leftover first-round reports cannot hide the decision path.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 16:25:39 +00:00
weichenandCursor 6f0057c014 fix(docgov): pin task routing to active controlled doc on current-doc deixis
When the user refers to the current document, keep task_key/doc_id on the selected registered doc_proj instead of rerouting by domain keywords.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:43:42 +00:00
weichenandCursor 900af79e14 fix(docgov): quality gate self-pollution, server repair budget, quality_failed UI
受控小队任务服务端启用修复预算;否定性自检引用不再误报;quality_failed 保持失败且不激活未过门禁稿。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:00:50 +00:00
weichenandCursor 43e03e4969 fix(docgov): idempotent lookup before busy; SSE write deadline heartbeat
Return existing task run 202 for the same turn before scope/preflight so
SSE disconnect retries do not hit DOC_BUSY or duplicate chat. Extend
task-run events write deadlines with heartbeats without dropping global
HTTP WriteTimeout. Reconnect subscribeTaskRunEvents on EOF via after_seq.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 14:37:18 +00:00
weichenandCursor 020712dfbd fix(e2e): UI-11 send upload to register freeform doc-free
Chip assert after setInputFiles, wait POST /freeform-documents 2xx on
send, then pin doc-free pane id and drain this-turn assistant before
leaving UI-11.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 14:07:41 +00:00
weichenandCursor c33a6d8406 fix(e2e): strict squad terminal and doc-free upload selectors
Only completed/pending_author_confirmation pass waitForSquadCompletion;
category trigger/data-category for private open; UI-11/16 pin exact
doc-free id without global attachment text clicks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 14:05:46 +00:00
weichenandCursor 301e1f401e fix(e2e): stable doc selector and this-turn assistant waits
Add doc-selector-trigger / active-document-pane data attrs; resolve
assistant via virtualizer data-index siblings; UI-02/03 and open-by-id
helpers stop relying on global text or first dropdown-trigger.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 14:01:41 +00:00
weichenandCursor 7466a15319 fix(docgov): harden UI-03 sync poll, reconnectRunId, and E2E status attrs
Use deliverablesRef + limited poll for post-task server docs; pass
reconnectRunId across auto-retry; GetRun reads idempotency_key;
StartClaimedRun fails closed on UpdateRun; MessageBubble/E2E scope
this-turn assistant; correct audit retry/schema19 wording.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 13:54:49 +00:00
weichenandCursor 76e2028761 fix(docgov): UI-03 post-task doc sync, claim idempotency, schema30
Restore controlled-doc merge after task terminal states, prioritize intake
template match, ClaimRun before chat writes, and extend chk for
pending_author_confirmation via goose 00030. Real volume migrate + UI
re-run remain pre-merge gates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 13:39:07 +00:00
weichenandCursor 5096581651 fix(projectinstance): resolve pre-activation task scope via governing three-state
Never-activated projects were allowed by access ABAC but rejected with
TASK_SCOPE_UNRESOLVED 409; use GetGoverningInstanceForAccess so nil maps to
ScopePreActivation, live to stage scope, and closed stays unresolved.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 12:59:10 +00:00
weichenandCursor b78574b065 fix(web): lock create-project confirm against double-submit race
React state bootstrapId could be read as null by two concurrent confirms;
use a sync in-flight ref plus submitting UI so create runs once and member
retry stays serial/idempotent.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 12:35:46 +00:00
weichenandCursor c6558bc757 fix(web): persist initial project members after createProject
Create Project no longer treats local member lists as success: non-creator
initialMembers are upserted via the authorized members API, with bootstrap
project id retained for idempotent retry when persistence partially fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 12:25:22 +00:00
weichen cd69cfd4d8 test(e2e): select project member by exact visible row 2026-09-13 12:03:16 +00:00
weichen 1d2cecc522 test(e2e): scope project creation selectors to fixed modal 2026-09-13 12:02:01 +00:00
weichen fed7af1982 test(e2e): drive real UI bootstrap and role assignment 2026-09-13 11:59:13 +00:00
weichenandCursor ec8a45a5fe fix(web): sync parent user directory after admin account changes
AdminSettingsModal previously left onRefreshUsers as a dead prop, so newly
created users never reached App allUsers/localStorage and Create Project
member candidates stayed stale (UI-01). Wire syncAdminUserDirectories,
surface refresh errors, and document the residual cross-device directory gap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:58:06 +00:00
weichenandCursor 4d4ea20e63 chore(e2e): keep Antigravity evidence path and UI harness tweaks
Preserve uncommitted Playwright config/spec adjustments for the ongoing
document-revision runtime acceptance run.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:37:03 +00:00