Commit Graph
190 Commits
Author SHA1 Message Date
weichen 97b947a8e3 Merge branch 'main' into fix/multiuser-project-collab-r2
ci / test-and-build (pull_request) Successful in 1m13s
governance / governance (pull_request) Successful in 16s
2026-10-20 07:01:35 +00:00
weichen e73f2ad9dd U5-Frontend integration-tests via PI direct (cursor 3/3 blocked on Playwright + vitest-only)
governance / governance (pull_request) Successful in 13s
ci / test-and-build (pull_request) Successful in 3m38s
Why: cursor 3/3 exhausted; PI direct dispatched as host integration work.

Scope: 8 test files (7 modified + 1 new), 255 insertions, 29 new vitest tests covering 11 U4 frontend-auto-discover scenarios end-to-end:
- AutoDiscover (3 new in store.test.ts)
- CapabilityGroup (3 new in rolePermissions.test.ts + 6 new in panels)
- CreatorOwnerMemberDuties (4 new across adminRdmSections/projectmeta/AccountUsersPanel)
- MemberManagementEntryHidden (3 new in adminRdmSections/projectmeta)
- EmptyListNoCreate (4 new in projectmeta/TaskSidebar)
- DefaultProjectDisabled (1 new in store.test.ts/projectmeta)
- RefreshBackoff + RefreshSingleFlight + RefreshHiddenPause + RefreshReconnectCompensate
- ProjectLifecycleConversation (5 new in test/conversation-work.test.ts)

Verification: npm run build ok (5.35s); ./node_modules/.bin/vitest run 656/656 (was 627, +29 new); new 29 tests across all 11 patterns all pass; no production files touched.

Refs: plan revision 3 U5-Frontend; /tmp/iam-link-u5-frontend-pi-verify-20261019.json exit=0.
2026-10-20 06:50:53 +00:00
agent-exec-transport d997d4a4d0 agent-exec transport 85c00f1e2274be1a84b73a421987fc69/ba12fd06dc72
governance / governance (pull_request) Successful in 16s
ci / test-and-build (pull_request) Successful in 34m20s
2026-10-20 06:21:55 +00:00
weichen 2bd5116f58 Merge Frontend main into U4 branch for L1→main sync
governance / governance (pull_request) Successful in 13s
ci / test-and-build (pull_request) Successful in 2m21s
2026-10-20 03:26:56 +00:00
agent-exec-transport 3c22d0957a agent-exec transport f9152d30e9410417157ea4a3a9a926ba/e09f009fa9f5
governance / governance (pull_request) Successful in 23s
ci / test-and-build (pull_request) Successful in 36s
2026-10-20 01:48:41 +00:00
agent-exec-transport e296d38ec2 agent-exec transport 0bde562073461c828c740d52a55a8b5d/a5fbfeb4311f 2026-10-20 01:19:46 +00:00
agent-exec-transport f01579890d agent-exec transport 280102ed04383156d99d681a10a5b302/b5e3788d8c79
governance / governance (pull_request) Successful in 15s
ci / test-and-build (pull_request) Successful in 27s
2026-10-19 15:14:12 +00:00
agent-exec-transport 7d43ef6ff7 agent-exec transport a4840fd95e17330e094af504afeba096/59a2059a0705
governance / governance (pull_request) Successful in 15s
ci / test-and-build (pull_request) Successful in 36s
2026-10-19 14:25:36 +00:00
agent-exec-transport ce15f7977b agent-exec transport 548284a3917af91d24d89efd66e5ec7c/d0c96d333a18 2026-10-19 09:40:34 +00:00
agent-exec-transport 164ea66039 agent-exec transport 9f1c4114b4dc96cd086583d1c03cd7a4/07c6c40e6ebc 2026-10-19 03:37:22 +00:00
agent-exec-transport 72c941c772 agent-exec transport 4a9e9a1c45e7ac50517ea954d95026bb/16e6bae28677 2026-10-18 16:51:49 +00:00
agent-exec-transport d47c49350b agent-exec transport 832aaeb220c114fdce38450a7e3d2dc7/e80375762b4e 2026-10-18 16:31:17 +00:00
agent-exec-transport cf07aef3d1 agent-exec transport e0882b049f8aabe5f01b03d73f7fcb71/8260fbbdf34b 2026-10-18 12:50:28 +00:00
weichenandCursor df7818f02a Merge Frontend main into the unified document renderer workspace
governance / governance (pull_request) Successful in 15s
Why: PR #106 is behind main by 15 commits (password login, regulation
citations, RDM member search) and conflicted in RdmAuditWorkspace.tsx and
rdmManagement.ts; the user authorized merging the renderer line on 2026-10-18.
Evidence: content is the agent-exec transport ec5012fe (cursor worker, unit
frontend-task11-sync-main-50ec836-r2, receipt
/tmp/cleanup-20261018/render/frontend-sync-run2.json, SELF): tsc -b, vitest
541/541 and vite build passed; host reviewed both conflict resolutions as unions.
Impact: no behaviour removed from either side; regulation tab and document
open flow coexist in the materials tab.
Refs: PR #106, Frontend main 50ec836

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 12:32:10 +00:00
weichen 8260bf5bb4 Merge branch 'main' into feature/rdm-settings-phase1a
governance / governance (pull_request) Successful in 15s
2026-10-18 11:05:04 +00:00
agent-exec-transport 6a3f2447f0 agent-exec transport 4cf12d612fc8a946cd63c630834d3beb/35d799203497 2026-10-18 10:53:59 +00:00
agent-exec-transport 96ab2ebd32 agent-exec transport ec7392fedc38af5f4b87509ddc658ec3/46e128ab5767
governance / governance (pull_request) Successful in 18s
2026-10-18 10:53:45 +00:00
weichenandCursor 1445f9e2af Give audit history fetches their own seq owner and label tree row state
governance / governance (pull_request) Successful in 15s
Why: TimelineTab's history effect read the shared events genRef without
incrementing it, so two overlapping history requests both passed the
check and a stale response could overwrite a fresher one, violating the
single-async-owner / drop-stale-events rule. Tree row buttons also hid
their expand state from assistive tech and announced the decorative caret.

Evidence: new src/components/RdmAuditWorkspace.test.tsx (7 cases) covers
out-of-order resolve, stale rejection, cleanup invalidation, ref isolation
and aria attributes; reverting to the non-incrementing read fails 3 cases.
npm test 43 files / 503 tests pass; npm run build ok;
node scripts/check-knip.mjs 50 <= 51; test/design-guard.test.ts 7/7.

Impact: history state now owned by historyGenRef via startLatestFetch
(incremented per fetch, checked on resolve, invalidated on cleanup); the
events-list seq is untouched. Expandable tree buttons expose
aria-expanded, non-expandable rows omit it, caret is aria-hidden.

Refs: review findings on RdmAuditWorkspace (TimelineTab history seq,
tree row a11y); AGENTS.md async-state rule; DESIGN.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 07:27:41 +00:00
weichenandCursor 0d6b8d7745 Merge readable-audit two-trees frontend work into the render workspace
Why: Owner decision merge_whole requires the parent "two trees" initiative's
Frontend work (local-only 95e1948, feature/rdm-two-trees-readable-audit:
814643f..95e1948) to ship together with the unified document render
workspace branch.

Evidence:
- Conflict src/components/RdmAuditWorkspace.tsx (TreeList render): HEAD added
  a per-document "阅读与交付" open button inside the old two-level doc/section
  list; 95e1948 replaced that list with the recursive TreeNodeRow. Kept the
  recursive TreeNodeRow and moved the open button into it (wrapped in
  .rdm-audit-tree-row, onOpenDoc threaded through recursion, shown for
  kind === 'doc' at any depth; aria-label keeps "阅读与交付:<title>").
  MaterialsTab/DocumentRenderWorkspace, saveBase64File and key={pid} from
  HEAD and readable presentation, paging, detail seq-guard, trace relation
  and timeline changes from 95e1948 merged cleanly.
- Conflict src/styles.css (both appended at end of file): kept HEAD's
  render workspace / cockpit rules followed by 95e1948's 760px media query.
- Semantic fix e2e/rdm-audit.playwright.ts: tree kind is now shown in
  business language, so the section filter matches '章节' instead of
  'section'.
- npm test: 42 files, 496 tests passed (incl. design-guard,
  rdmAuditPresentation, rdmAuditTree); npm run build: ok;
  node scripts/check-knip.mjs: 50 <= 51; npx playwright test --list: 78 tests
  in 17 files.

Impact: RDM audit materials tab renders both project trees recursively with
readable names and still opens any document in the render workspace; audit
timeline and trace show readable records and retired/stale relations.

Refs: 95e1948 (814643f, b52f965, c9b55eb, b921bef, 505aba3, 1ef68ab,
ad503c9, 987be74, 95e1948); HEAD 50d12ce

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 07:16:47 +00:00
weichenandCursor 50d12ce974 Anchor review annotations on the selected node text range
governance / governance (pull_request) Successful in 15s
Why: RDM now anchors annotations on nodeId + textStart + textEnd + textHash
(spec 06 §2) and acceptance 10 §5 requires accurate comment ranges. The
workspace only sent whole-node annotations and ignored quote/needsReanchor.

- Selecting text inside one node's title in the reader view records a
  code-point range (Array.from indices; surrogate pairs and ZWJ emoji are
  counted as runes, half-pair endpoints widen) and sends textStart/textEnd
  plus quote, so RDM rejects rather than misplaces a drifted range.
- No selection keeps whole-node behavior; replies never carry range params;
  textHash/range are never sent; a range is dropped if it belongs to another
  node.
- Selections spanning several nodes or containing no node text record no
  range and show a notice that the whole node will be annotated; the composer
  always shows the scope with a "whole node" escape.
- Annotation items show the server quote and a visible needs-reanchor state;
  review_anchor_invalid: errors map to readable Chinese text.
- Reader titles become role=button spans because browsers do not allow text
  selection inside <button>.

Evidence: npm test 40 files / 486 tests pass (30 new in
test/review-annotation-anchor.test.ts); npm run build exit 0;
node scripts/check-knip.mjs "50 <= 51"; design-guard 7/7; playwright
--list compiles 13 tests; headless Chromium check of the selection reader
(single, multi-node, triple-click clamp, emoji offsets).

Impact: document review UI only; base-gate decision source anchoring is
unchanged. Offsets are computed on the displayed node title (no frozen-text
read endpoint exists), guarded by quote equality on the server.

Refs: unified renderer plan Task 13; phase1 F2; spec 06 §2
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 06:27:22 +00:00
weichen 0e05624823 Merge remote-tracking branch 'origin/main' into feature/unified-document-renderer-task11 2026-10-18 01:04:41 +00:00
weichenandCursor 12553f53eb Locate review items and render trace by tree node id and mask audit-only trace
Why: RDM be80ad4 (docs/design/render-node-id-contract.md) accepts workspace tree
node ids (dn-/sec-/legacy-) for review annotate/revise, adds treeNodeId to receipts,
rdm.render.review.view items and trace entries while nodeId stays canonical, points
anchored-to at the tree node id, and marks audit-reader trace entries with
contentMasked=true. Grouping review items by the canonical nodeId left them all
unlocated, and the workspace showed no render trace at all.

Evidence: npx tsc --noEmit exit 0; npx vitest run 39 files / 456 tests passed (12 new
in test/document-render-workspace.test.ts: treeNodeId grouping with nodeId fallback
and orphan rules for annotations and revisions, data-locate targets, annotate/revise
payload carrying the selected tree node id, layer=render filtering, anchored-to
against tree nodes without canonical fallback, masked entries never reading body
fields, empty state); npm run build ok; node scripts/check-knip.mjs 51 <= 51;
e2e/document-renderer.playwright.ts type-checks (tsc exit 0) and
npx playwright test --list loads 13 tests.

Impact: locateNodeId (treeNodeId first, nodeId fallback, otherwise unlocated) is
shared by diagnostics, review grouping and trace. Clicking an annotation or revision
group, a reply, or a trace node locates and re-scrolls like diagnostics. Annotate and
revise send the selected tree node id as nodeId. A 渲染链条 panel reads
rdm.inspect.relations (kind=doc) through the single guarded resource owner (stale
responses dropped) and reloads after preview, submit, export, review and decision
actions. Masked entries show metadata only with a 内容已遮蔽 marker and a panel
notice. The e2e spec is unchanged: §11-5b already asserts that the group title is the
selected tree node, and the leak scan is untouched. Not run against a live backend
or browser here.

Refs: RDM be80ad4 docs/design/render-node-id-contract.md; unified renderer spec 10
§11 items 4, 5 and 7; DESIGN.md §8, §9.2, §11.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 00:34:04 +00:00
weichenandCursor 6727cdd30f Locate render diagnostics by tree node id and expect published DHF rules
Why: Browser acceptance (/tmp/renderer-browser-acceptance/20261017T061021Z) found
§11-4 showed 25/25 diagnostics as 未定位节点 because the renderer nodeId is the
canonical mapping id (pp.cover.document-number.value) while the workspace tree uses
dn-… ids; RDM now adds treeNodeId to every diagnostic. §11-3 failed only because
the e2e spec still expected 已验证/未发布 although all 44 DHF profiles are published.

Evidence: npx tsc --noEmit exit 0; npx vitest run 39 files / 445 tests passed (4 new
in test/document-render-workspace.test.ts covering treeNodeId, nodeId fallback,
unknown ids and per-node counts); npm run build ok; node scripts/check-knip.mjs
unused exports 51 <= 51; e2e/document-renderer.playwright.ts type-checks (tsc exit 0)
and playwright test --list loads 13 tests. Real rdm.render.profiles payload in
evidence/network/item3-author.jsonl: template rule state=published,
publicationAllowed=true, no blockedReason, refusal controlled_requires_exact_profile.

Impact: normalizeDiagnostics keeps treeNodeId; locateDiagnostic resolves treeNodeId
first and falls back to nodeId, otherwise the diagnostic stays explicitly unlocated.
Badges and the 有诊断问题 filter count by the located tree node. Clicking a located
diagnostic selects the node and scrolls it into view in canvas or reader, also on a
repeated click. Diagnostics loading keeps its single request guard. §11-3 now asserts
已发布, 可正式交付, an enabled option and no reason, and still asserts source, version,
the no-fallback notice and refusal. Not run against a live backend or browser here.

Refs: unified renderer plan Task 13 §11 items 3 and 4; spec 10 §11 item 3;
summary.md root causes §A and §B.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-18 00:12:58 +00:00
weichen 92864db8d3 Clarify user management flows 2026-10-17 11:56:33 +00:00
weichen fb1f9f246b Fallback proofless recovery to temporary reset 2026-10-17 10:43:47 +00:00
weichen 2f8009b967 Use password login and admin temporary resets 2026-10-17 10:30:17 +00:00
weichen 83e81d12ac Sync panorama node detail on refresh; scope scenario 4 to the fixture doc
Why: the cockpit refresh reloaded overview and tree but left the node
detail at its old snapshot, so the 刷新对齐 banner persisted after
refreshing (DV-R05 wants every projection to advance). PanoramaNode now
refetches when the overview snapshotRevision advances. Scenario 4 also
scoped its tree clicks to the 验证主体报告 branch — the unscoped first
caret expanded an unrelated rdm-self doc.

Evidence: tsc clean, vitest green, build green (SELF); seven-scenario
rerun to be recorded on the Dev I4 card.

Impact: cockpit panorama + e2e spec.

Refs: rollout I4
2026-10-17 04:30:32 +00:00
weichen c3d8205839 Show version block in panorama node view
Why: the I4 scenarios assert the version collapsible for a selected
section in the panorama (not only the reader); the panorama node view
had no version block, so .cockpit-versions-toggle never existed there.
Also normalize null list projections in the panorama node detail fetch
(same Go nil-slice issue fixed for the panel earlier).

Evidence: tsc clean, vitest green, build green (SELF); seven-scenario
rerun to be recorded on the Dev I4 card.

Impact: cockpit panorama only.

Refs: rollout I4
2026-10-17 04:07:58 +00:00
weichen dd159c24d0 Normalize null list projections in cockpit node detail
Why: rdm.cockpit.node projects empty conflicts as items:null (Go nil
slice) while sources arrive as []; the panel read items.length on null
and crashed, so the conflicts empty state never rendered (I4 e2e
scenario 3).

Evidence: tsc clean, vitest green, build green (SELF); seven-scenario
rerun to be recorded on the Dev I4 card.

Impact: cockpit panel only.

Refs: rollout I4
2026-10-17 03:58:53 +00:00
weichenandCursor 0d4d1be198 Anchor render workspace decisions to a committed source message
Why: The base gate (cmdbus.RequiresProjectWorkDecision) refuses rdm.review.doc.approve/reject/final unless the request carries a committed conversation source as top-level conversationId and anchorMessageId. The workspace sent bare params, so the decision buttons were refused in the real product.

Evidence: vitest 39 files / 441 tests passed (22 new in test/document-decision.test.ts); npx tsc --noEmit clean; npm run build ok; check-knip unused exports 51 <= 51; e2e/document-renderer.playwright.ts type-checks and lists 13 tests. Request shape from pins/agent-system-backend: internal/server/server.go:1276-1304 (body decode), internal/cmdbus/cmdbus.go:109-134 and 385, internal/app/app.go:646-665 (preflight), server.go:1010-1150 (message POST returns the committed message).

Impact: approve/reject/final first post a Chinese decision message to the host project's 文档审签记录 conversation (reused, or created), then dispatch with its id as the anchor (entrance button). Identity is never sent. Any failing step shows a readable refusal and nothing is dispatched. Double-click is ignored while an action is in flight, and retries reuse the operation id so the server returns the same source message. rdmCommand takes an optional source; rdm.render.* is unchanged. The e2e spec drives §11-5c through the workspace only and asserts the anchored, committed receipt. Not run against a live backend or browser here.

Refs: unified renderer plan Task 11; RDM cmdbus gate (pins/agent-system-backend internal/cmdbus/cmdbus.go:109-134); live-verify sequence /tmp/live-verify/run.sh lines 56-70 and 140-146.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 03:41:10 +00:00
weichen a56ce3e1df Fix cockpit project option field: payload is projectId, not id
Why: the local ProjectView interface invented 'id'; rdm.project.list
returns projectId. Every option value was undefined, so auto-select set
pid to undefined and the overview request was never issued — cockpit
showed 加载概览… forever after the project list loaded (I4 e2e scenario 1).

Evidence: tsc clean, vitest green, build green (SELF); network probe shows
rdm.cockpit.overview 200 and .cockpit-stats rendered; seven-scenario rerun
to be recorded on the Dev I4 card.

Impact: cockpit entry only.

Refs: rollout I4
2026-10-17 03:16:47 +00:00
weichen 10f8388bb8 Auto-select first visible project on cockpit entry
Why: the cockpit rendered the project dropdown with no project selected
and an empty main area — the design's 首屏 default (first visible project
drives the overview) was never implemented; caught by I4 e2e scenario 1
which got past the project list but never saw .cockpit-stats.

Evidence: tsc clean, vitest green, build green (SELF); seven-scenario
rerun to be recorded on the Dev I4 card.

Impact: cockpit entry only.

Refs: rollout I4
2026-10-17 02:45:17 +00:00
weichenandCursor 7f3538da22 Add review decisions, rule binding and package download to the render workspace
Why: Task 11 requires the document render workspace to offer approve, reject and final decisions, rule bind/unbind for document, document type and project default, and the full delivery package, so reviewers and settings holders no longer need other screens.

Evidence: vitest 38 files / 419 tests passed (new test/document-render-actions.test.ts covers decision entries from frozen duties, decision payloads without identity fields, package availability, refusal codes, binding candidates and payloads, perm gating and SSR visibility); tsc --noEmit clean; knip unused exports 51 <= baseline 51.

Impact: decision entries show only when the command is enabled and the frozen submission lists the session user; binding needs rdm.perm.check project.settings allowed=true; package appears only for ready deliveries; organization-default binding is not offered from the workspace (domain admin only).

Refs: unified renderer plan Task 11, 05 section 9, 06 section 6, 07 sections 1 and 5; RDM plugins/rdm/plugin.go review.doc.* and render.profile.* schemas (7169944, 4b7ac2a, 75ba50c).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 02:32:45 +00:00
weichen 5ede8df52a Fix inverted cancel guard in cockpit project loader
Why: #102 rewrote the bare-array fallback into a multi-line callback and
turned 'if (!c) setProjects(...)' into an early 'if (!c) return', which
skips setProjects on the normal (non-cancelled) path — the cockpit then
hangs on 加载中 forever, caught by I4 e2e scenario 1.

Evidence: tsc clean, vitest 324/324, build green (SELF); seven-scenario
browser suite rerun recorded on the Dev I4 card.

Impact: cockpit entry only.

Refs: rollout I4
2026-10-17 02:28:47 +00:00
weichenandCursor d5e6b12e75 Merge origin/main into the document render workspace branch
Why: origin/main carries the cockpit, account and duty-settings work; the render workspace branch needs its rdmRender capability state kept beside the new rdmCockpitAvailable flag.

Evidence: store.ts conflicts resolved by keeping both sides in the identity reset and capability refresh paths; tsc --noEmit clean; vitest run 37 files / 394 tests passed; npm run build passed; knip unused exports 51 <= baseline 51.

Impact: refresh failure and identity reset now clear rdmCockpitAvailable and rdmRender together; no behavior removed from either side.

Refs: unified renderer plan Task 11 (09-implementation-plan.md); Dev precheck verdict SHARED_WORKSPACE_BUSY recorded in the task report.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-17 02:22:39 +00:00
weichen c9ef3c0f0a Unwrap projects payload in cockpit project loader
Why: rdm.project.list returns { projects: [...] }; the cockpit component
assumed a bare array and always rendered 暂无可见研发项目, caught by I4 e2e
scenario 1.

Evidence: tsc/vitest/build green (SELF); browser e2e rerun recorded on the
Dev I4 card.

Impact: cockpit entry only.

Refs: rollout I4
2026-10-16 15:31:52 +00:00
weichen 804170ec66 Wire cockpit flag into sidebar workspace entries
Why: TaskSidebar builds its own workspace entry list without the cockpit
flag, so the 文档驾驶舱 entry never appeared in the sidebar even when the
command probe passed (caught by I4 e2e scenario 1).

Evidence: tsc/vitest/vite build green (SELF); cockpit e2e suite re-run via
Dev scripts/e2e.sh follows on the Dev I4 card.

Impact: sidebar entry visibility only; no behavior change elsewhere.

Refs: rollout I4
2026-10-16 15:27:16 +00:00
weichen 86770e35fb Add cockpit reader view and evidence panel (I3)
Why: implement the reviewed I3 increment - continuous body reading with
per-section status lines, version summary with collapsed line-diff (backend
versions projection from RDM PR #420), right evidence panel with
sources/history/impacts/conflicts tabs, panorama-reader positioning on the
shared selection, per user+project view preferences (panorama/reader,
density, panel tab), strict-seq history merging and honest restricted states.

Evidence: 10 new pure-logic tests (prefs validation, version summary and
diff marks, strict history merge drops, reader assembly three-state); vitest
324/324 green; tsc and vite build green; tokens-only styles.

Impact: cockpit-only; no fourth column, no standalone graph (relations stay
in the right panel); reader entry is explicit (panorama button / view toggle).

Refs: rollout I3
2026-10-16 12:21:24 +00:00
weichen 17996cf4dd Add document cockpit workspace consuming rdm.cockpit.* (I2)
Why: implement the reviewed I2 increment - statistics band, structure tree
with lazy section pages, panorama center (project overview + node summary),
shared selection/filter, snapshot-consistency banner and honest states, per
the frozen contract (Dev docs/superpowers 2026-10-16, rollout section 7).

Evidence: vitest 314/314 green (14 new pure-logic tests covering capability
gate, true-zero vs unavailable stats, filter toggle, snapshot equality and
update notice, context key, selection survival, honest badges); tsc -b and
vite production build green.

Impact: new workspace entry (rdm-cockpit, gated on the seven cockpit
commands); no changes to existing surfaces; reader view and right panel
land in I3.

Refs: rollout I2
2026-10-16 09:03:48 +00:00
weichen e895a4f6a8 Close the account chain UI against the current backend contract
Why: the forced password gate still submitted an empty current password
after the backend began requiring it (current_required), locking every
account seeded with an initial password out of the workbench, and the
admin user panel had no client for the owner-confirmed recovery
proposal contract that replaced one-time key issuing (HTTP 410).
Evidence: npm test 300 passed; tsc -b && vite build ok; knip issues
54 <= baseline 55 (SELF).
Impact: mode-aware ChangePasswordGate with current-password input,
admin recovery proposal panel, owner-side account settings section,
recovery proposal client methods; no backend changes.
Refs: backend 8dfc223, b9c0a34; frontend #94
2026-10-16 07:49:25 +00:00
weichen bcb81719ce Drop the login-key issue client and fix hint punctuation
Why: independent review flagged the issue client still targeting the 410
endpoint and a hint sentence ending with a period.
Evidence: npm run build + npm test re-run on the fix (SELF).
Impact: api client surface only.
Refs: review brief /tmp/review-brief-admin-user-contract.md
2026-10-16 07:15:43 +00:00
weichenandCursor 36f2fbea34 Fix render workspace gaps found by real-product browser acceptance
Why: Running §11 against RDM d63f1db showed three Frontend defects. A
validated template rule with a server blockedReason was disabled for
preview, although the server only restricts formal delivery. A reviewer
opening the document in another session could not find the author's
submission until an export existed. Template-instance blocks without a
title (cover, sign-off table, fields) rendered as blank canvas nodes and
reader headings.

Evidence: npx vitest run (35 files, 363 tests passed); npm run build ok;
node scripts/check-knip.mjs (43 <= 43); browser run under
/tmp/renderer-browser-acceptance/20261016T064052Z (item1 172 nodes,
preview generated with the validated template rule).

Impact: Preview is offered for validated/draft rules while formal submit
stays blocked; the current submission comes from rdm.review.doc.status;
untitled nodes show "<kind>(<templateBlockId>)".

Refs: unified renderer plan Task 13 §11
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 06:49:28 +00:00
weichen d8e610aebe Align admin user creation with the pending-account contract
Why: backend 8dfc223 replaced POST /api/admin/users with strict
{owner, profile} decoding and returned 410 for login-key issuing, so the
UI create form failed with 400 unknown field name. Creation now sends
{owner, profile:{name}} only; password input, admin checkbox and the
login-key issue entry are removed; notice points to the local CLI
initialize-account flow. passwords.ts lost its only consumer.
Evidence: npm run build + npm test (34 files/293 passed) + knip identical
to baseline on the task worktree (SELF).
Impact: UsersPanel and api client only; no style/token changes.
Refs: backend 8dfc223, b9c0a34
2026-10-16 06:41:27 +00:00
weichen 10635387e0 Gate project override settings to owners and admins
Why: S9 acceptance finding 3 — the project settings modal exposed the
host override settings (including the model/key group, masked) to plain
project members; the duties data plane was already permission-enforced,
but the host settings surface had no gate.

Evidence: vitest 34 files / 293 tests pass with the change; tsc reports
no errors in the modified file. Ruling per the acceptance plan P1-B:
the modal entry stays (granted duty managers need the RDM tabs), while
the host override settings group renders only for the project owner or
a system admin; RDM tabs keep their own fail-closed gating.

Impact: ProjectSettingsModal project tab renders an explanatory empty
state for non-privileged viewers; members/duties/matrix tabs unchanged.
Refs: S9 acceptance report P1-B
2026-10-16 05:09:58 +00:00
weichenandCursor de65026238 Align document render workspace with real RDM server payloads
Why: Independent review of a81e94a..85428b4 found five contract mismatches
against the RDM server: profile sources document-type/project-default were
dropped, the refusal object {code,message} was ignored, submit receipts were
read as `id` instead of `submissionId`, diagnostics were expected inside
preview/export receipts (they live in a separate diagnostics delivery blob),
and rdm.inspect.tree was treated as recursive although it returns one level.

Evidence: New tests use the server JSON shapes (RenderProfileOptions,
RenderDeliveryReceipt, DocSubmissionRec, rdmRenderDownload, InspectTree); 26
of them fail against the previous implementation. npx vitest run: 35 files,
359 tests passed; npm run build: ok; scripts/check-knip.mjs: unused exports
43 <= 43; git diff --cached --check: clean.

Impact: Rules panel lists all five sources with Chinese labels and keeps the
server's selected default; refusals render readably; a new submission is
auto-selected; diagnostics are fetched via rdm.render.download kind=diagnostics
under a sequence/epoch guard with readable failures and a Chinese receipt
state label; the document tree is walked breadth-first (depth 12, 2000 nodes,
concurrency 4) with a truncation notice. Playwright spec asserts per-node
diagnostic anchors after preview (authored, not run).

Refs: unified renderer plan Task 11 review findings
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 01:29:13 +00:00
weichenandCursor 85428b4633 Add document render workspace with profiles, preview, review and downloads
Why: unified renderer Task 11 needs a reader/delivery UI over the RDM
document tree: four-level rule selection with controlled-document
no-fallback explanation, preview with node-linked diagnostics, a
structure canvas and a linear reader sharing one selection and filter,
review annotations/revisions, and per-delivery downloads.

Evidence: npx vitest run -> 35 files, 338 tests passed (45 new in
test/document-render-workspace.test.ts, design-guard green);
npm run build -> tsc -b + vite build ok; npx knip -> findings identical
to the pre-existing baseline (check-knip 43 <= 43); git diff --check
clean. e2e/document-renderer.playwright.ts authored, not executed.

Impact: new src/documentRenderPresentation.ts (pure helpers) and
src/components/DocumentRenderWorkspace.tsx, opened from a per-document
"阅读与交付" action in the audit materials tree; store gains an
rdmRender capability probe (fail-closed); audit export reuses the shared
base64 file saver; token-only styles appended to styles.css. Async
state is owned per hook with request guards plus identity epoch, and
the workspace remounts per identity/project/document scope.

Refs: unified renderer plan Task 11
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 23:44:39 +00:00
weichenandCursor e33d17e1a6 Show the layered Python environment in the admin zone.
Why: Approving an extra package, rebuilding the base layer, reclaiming unused layers, and uploading a wheel need an admin surface that uses the existing admin controls.
Evidence: SELF tsc of the new panel reported no errors in frontend sources. UI package type errors come from missing node_modules in this worktree, not from this panel.
Impact: Administrators get a Python 环境 section. Other admin sections are unchanged.
Refs: .task/feature-layered-python-env.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 13:52:55 +00:00
weichenandCursor 985fc0f931 Adopt the server duty draft when a save result is unknown
Why: a lost write response was keeping the old duty version, so the next save replayed it, and a busy save could stay locked if another request advanced the sequence.
Evidence: SELF vitest duty-draft 6 passed, tsc passed, knip 43, Playwright duty flows 3 passed.
Impact: an unknown save reloads server roles, confirmation resets, and busy clears even if a later read is discarded.
Refs: docs/proposals/2026-10-15-rdm-duty-matrix-rework.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 09:06:24 +00:00
weichenandCursor 6093beb27e Merge origin/main into the duty matrix branch
Why: project settings must keep the shared duty draft and must not regain template document creation from main.
Evidence: SELF vitest 292 passed, tsc --noEmit passed, knip unused exports 43.
Impact: the duties tab stays assignment-only while conversation ordering from main is included.
Refs: docs/proposals/2026-10-15-rdm-duty-matrix-rework.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-15 08:37:53 +00:00
weichen 3555f815af Keep late background progress out of a newer conversation turn
Why: Completion or progress from an earlier task could appear in the process of an unrelated newer answer.

Evidence: The new ownership regression fails before the guard and passes afterward; the frontend suite, TypeScript and unchanged export gate pass.

Impact: Project child progress only into its originating live turn while still reconciling background results.

Refs: feature/workbench-flow-completion chronological display requirement
2026-10-15 07:51:41 +00:00