Compare commits

..
Author SHA1 Message Date
weichenandCursor ed29cb5200 docs(ops): close Wave 0 status and ignore multi-GB UI dumps
Point CURRENT and FEATURE-MATRIX at the arch-check baseline, and keep local Playwright traces out of git.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 13:00:35 +00:00
weichenandCursor e9d57ea772 feat(arch): add contracts skeleton and warn-mode arch-check
Give later waves a measurable import/table/path baseline without changing business behavior or occupying the integration slot.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 13:00:32 +00:00
weichenandCursor 241bfccc1e docs(adr): accept modular monolith decoupling architecture
Record the contract-first, single-writer design so Wave 0 has an accepted boundary to implement against.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 13:00:29 +00:00
weichenandCursor f2a7fa94d2 docs(workflow): record frozen plan 409 and optional-duty governance docs
Keep the audit, remediation, and MVP rule review with the short-term tasks so later waves do not rediscover the 409 root cause.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 13:00:26 +00:00
weichenandCursor ea3eeadb77 chore(ops): remove Herdr agent roles and dispatch scripts
Drop live roster/policy and herdr-agent start/dispatch helpers so collaboration follows AGENTS worktree/mutex only; archive prior governance evidence.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 05:22:04 +00:00
weichen c5810cd907 merge: fix/controlled-content-ui-acceptance-closeout 2026-09-14 04:03:46 +00:00
weichen 6ef80acf8d docs(docgov): reconcile remediation status with UI evidence 2026-09-14 04:03:39 +00:00
weichen ba67c467c4 docs(docgov): close controlled content UI remediation 2026-09-14 04:03:33 +00:00
weichen 81b75b3546 merge: fix/controlled-content-ui-acceptance 2026-09-14 04:01:23 +00:00
weichen 43460ae9ed docs(test-report): align UI acceptance report and checklists with exact results SSOT 2026-09-14 04:00:36 +00:00
weichen fbd8fe469f docs(test-report): complete full-chain post-restart UI acceptance 2026-09-14 03:54:53 +00:00
weichen 36c40f6a86 docs(test-report): record full-chain-final main phase complete pass 2026-09-14 03:50:38 +00:00
weichen 097ba8f457 merge: dev (08bf615 cache race fix) 2026-09-14 03:36:17 +00:00
weichen 36e4bc3001 merge: fix/controlled-content-canonical-hash cache-race 2026-09-14 03:34:41 +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
weichen 9098069aee merge: dev (f693e1c stop hydrating local legacy mock documents) 2026-09-14 02:59:52 +00:00
weichen d0e8f60915 merge: fix/controlled-content-canonical-hash follow-up 2026-09-14 02:57:20 +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
weichen 46e275db98 docs(test): define browser-only acceptance checklist 2026-09-14 02:39:20 +00:00
weichen 6f07dfcab6 docs(test): claim controlled content UI acceptance 2026-09-14 02:35:20 +00:00
weichen 84fdd7d0bf merge: fix/controlled-content-canonical-hash 2026-09-14 02:31:34 +00:00
weichen 8b47451b90 docs(ops): occupy integration slot for content repair 2026-09-14 02:31:25 +00:00
weichenandCursor e3b72ad64b fix(cli): require positive live-dev identity and exclusive backups
Live apply now accepts only :5433/agent_system_dev plus a data/dev
host root, maps stored work dirs fail-closed, and reports unique
O_EXCL backups after a parent-directory fsync.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:30:11 +00:00
weichenandCursor 96fd0e9e6f fix(docgov): persist exclusive old-head backups with dir fsync
Apply now writes the destructive old head markdown beside the original
file, refuses to clobber existing backups, and fsyncs the parent
directory after the atomic persist.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:24:49 +00:00
weichenandCursor 50576a2ec5 docs(docgov): record review-blocker fixes and isolated PG gap
W7 must live-apply project 143 before UI acceptance. Isolated
TEST_DATABASE_URL was unavailable; shared env databases were not used.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:21:57 +00:00
weichenandCursor 838864f3b2 fix(cli): add gated live-dev reconcile mode and path mapping
Default still refuses shared DSN/paths. Apply to dev requires --live,
--environment dev, a single --doc-id, and confirm REPAIR_SINGLE_DEV_DOC.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:21:56 +00:00
weichenandCursor 8892290bf7 fix(docgov): keep repair revision numbers and refuse drifted heads
migration_repair is not a human revision. HashUpdater now loads from DB
and retries still sync. Content reads return a structured drift conflict
instead of the destructive old head.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:21:50 +00:00
weichenandCursor e7b46e92d2 feat(db): allow migration_repair snapshot and event kinds
00028 check constraints would reject a real PG apply. Add goose 00032
with Up/Down so repair snapshots can persist.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 02:21:44 +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
weichen f80e7a1ea1 docs(audit): diagnose project143 document content 404 2026-09-14 01:47:21 +00:00
weichen 79d2676bbf merge: docs/release-vite-frp-slot 2026-09-14 01:32:32 +00:00
weichenandCursor 2d0d499aec docs(ops): release integration slot after vite frp merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 01:32:32 +00:00
weichen d208b0e3e4 merge: fix/vite-frp-allowed-hosts 2026-09-14 01:31:56 +00:00
weichenandCursor e760373fd0 docs(ops): occupy integration slot for vite frp merge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 01:31:56 +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
weichen 36a59d6700 merge: feature/software-project-bootstrap-plan 2026-09-14 01:13:42 +00:00
weichen 8ce41e101b docs(workflow): design software project bootstrap suite 2026-09-14 01:13:33 +00:00
weichen bad2410994 merge: feature/document-revision-session-close 2026-09-14 00:29:18 +00:00
weichenandCursor 9345109dca docs(ops): archive completed document-revision session files
Move done DOCREV short-terms, checklists, and handoffs into archive/ops and retarget relative links after Round20 close-out.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 00:27:18 +00:00
weichen 4bf8b6d993 merge: fix/document-revision-evidence-count 2026-09-14 00:23:31 +00:00
weichenandCursor bf4f9bdba0 docs(test): split 21 screenshots from 21 results
Record top-level screenshots as 20 main/pre plus 1 post, and the full-package race as FAIL 109.279s instead of a cached ok line.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 00:23:11 +00:00
weichen 5d79da60fc merge: feature/document-revision-runtime-ui-final-report 2026-09-14 00:21:23 +00:00
weichenandCursor 07507c7c24 docs(test): correct runtime UI final-report facts
Rename the close-out branch to feature/*, record 20 screenshots, and state rebuild-then-app-restart so the environment notes match Round20.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 00:20:56 +00:00
weichenandCursor 89163d2d18 docs(test): close document revision runtime UI Round20
Record the official Playwright headless pass for project 6159 and release the runtime integration slot without claiming the whole system production-ready.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 00:17:47 +00:00
weichen b258ab86a5 merge: fix/document-revision-pg-id-remap 2026-09-13 23:48:18 +00:00
weichenandCursor acf62a23d0 docs(audit): separate candidate 175 from output snapshot 250
The 6158 field ledger wrote candidate id=175 and report id=175; 250 is the output snapshot, not the candidate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:45:14 +00:00
weichenandCursor 4e0951fe70 docs(ops): record PG ledger ID remap milestone
Claim the document-revision mutex and document the 6158 first-generation not-found root cause without calling UI-03 done.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:43:56 +00:00
weichenandCursor 2d0fcb94bc fix(docrevision): keep PG snapshot IDs ahead of in-memory counters
Opening a template stored database IDs without advancing nextSnapID, so the next temporary snapshot could overwrite and then delete the real baseline. Adopt helpers now bump every counter and only drop a map entry when it still points at the same object.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:43:56 +00:00
weichen fa6a033c95 merge: fix/document-revision-post-restart-final-snippet 2026-09-13 23:28:53 +00:00
weichenandCursor 39df2d88f7 docs(ops): claim post-restart durable body snippet task
Record that the second restart already restored V3/r2 and that only the stale UI-06 bodySnippet expectation was wrong.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:28:17 +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
weichen eb85b8a068 merge: fix/document-revision-post-restart-selector 2026-09-13 23:23:59 +00:00
weichenandCursor 1a98c0cdeb docs(ops): record phase-split UI acceptance results JSON
Document that main keeps ui-acceptance-results.json and post-restart writes a sibling ledger so the 18-case main book is not overwritten.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:23:28 +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 8907b61745 docs(ops): claim post-restart project title selector task
Record the schema31 strict-mode failure, the banner/entry locator contract, and phase-split Playwright directories. Do not mark UI-15 passed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 23:21:09 +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
weichen b824948a5a merge: fix/document-revision-reviewer-duty-sync 2026-09-13 22:48:05 +00:00
weichenandCursor a0196142a3 docs(ops): record heal lock serialization against duty transfer
Note that HealProjectDocuments now shares pg_advisory_xact_lock(project_id) with member writes so an old reviewer cannot be written back.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:44:40 +00:00
weichenandCursor 09e3581def fix(docduty): serialize heal with the project duty lock
Heal used to resolve and backfill on the pool without the member-write advisory lock, so a stale snapshot of reviewer A could overwrite a committed transfer to B. Lock, resolve, and document updates now share one transaction and the same lock key.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:44:40 +00:00
weichenandCursor d7d656f66f docs(ops): record atomic duty-revoke transaction
Document that lock, holder reads, member writes, and reviewer/approver slot clears share one transaction, with heal after commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:37:27 +00:00
weichenandCursor 0fa4a5784e fix(authz): clear reviewer/approver slots in the member-write transaction
Duty revoke must share the project advisory lock with reading old holders and writing members, so a post-commit service snapshot cannot miss a transfer. Heal still fills the new holder after commit, and sync failure stays ERR_DUTY_SYNC.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:37:24 +00:00
weichenandCursor be394bf617 docs(ops): record final reviewer duty-sync repair round
Sync short-term, checklist, and handoff with remaining 6145 risk and
the isolated PG verification path.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:29:53 +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 9a19bcc12c fix(docduty): revoke inactive slots and explicit duty changes
Empty assigned heal now clears only exited or non-member reviewer/approver
holders and never blanks author. Explicit reconcile uses the pre-update
duty plus a project advisory lock so viewer demotion and transfers are
not left to generic heal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:29:53 +00:00
weichenandCursor ec89b4c8b0 docs(ops): record independent-review duty-sync tighten
Document assigned-authoritative heal, member-change sync, owner
non-demotion, isolated PG command, compatibility, and remaining 6145 risk.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:16:44 +00:00
weichenandCursor c2d4e9a55c test(docduty): add isolated PG heal, backfill, and concurrency fixtures
Require TEST_DATABASE_URL and refuse agent_system_dev. Script creates a
throwaway database, runs packages serially, then drops it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:16:44 +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 4512132b20 fix(api): keep owner role and sync docs after duty upsert
Omit project_role no longer defaults to member. Exclusive duty writes
take an advisory lock and retry conflicts so last-writer wins without
dual reviewers. Author write tests require err==nil.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:16:43 +00:00
weichenandCursor 2f0a1b337c fix(docduty): treat assigned duty as authoritative on heal
Align document slots to project document_duty even when the wrong ID is
an active member, and fail generate/list instead of returning stale
placeholder duties. Owner author backfill now picks creator, else lowest ID.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 22:16:36 +00:00
weichenandCursor 60e2b1adf2 docs(ops): mark reviewer duty-sync commits complete
Keep the short-term checklist aligned with the four atomic commits on this branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:58:02 +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 6a68e04f1f feat(docduty): resolve project reviewer onto controlled docs
Stop inventing reviewer_id=2. Use project document_duty as the authority, heal missing or non-member placeholders, and keep write paths rejected for reviewer and outsiders.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:57:44 +00:00
weichenandCursor 6cd3991bad feat(db): store document duty on project members
Project access roles cannot carry reviewer. Persist a separate exclusive document_duty so later controlled docs can inherit the assigned reviewer.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:57:43 +00:00
weichenandCursor dd24105742 docs(ops): register reviewer duty-sync task
UI-13a now proves USER_B is viewer despite UI-01 assigning reviewer; claim a new mutex and document the 6145 ledger gap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:57:22 +00:00
weichen 639969ff7e merge: fix/document-revision-duty-cell-assertion 2026-09-13 21:29:26 +00:00
weichenandCursor 5183d2866d docs(ops): record tightened duty-cell test count
UI-13a reviewer contract now has 6 unit cases; keep the short-term note aligned without rewriting the already-reviewed fix commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:28:55 +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
weichen dd5671e542 merge: fix/document-revision-workflow-category-navigation 2026-09-13 21:06:37 +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
weichen 48a4dcb86d merge: fix/document-revision-fast-completion-observation 2026-09-13 20:44:26 +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
weichen 339e871242 merge: fix/document-revision-quality-repair-workspace-contract 2026-09-13 20:21:05 +00:00
weichenandCursor 01c5972ead fix(squad): void quality repair rounds on backend or containment failure
Promote root output.md only when the runner succeeded, protected parents
were untouched, and the local target is trusted. Restore errors abort
instead of being ignored.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 20:20:13 +00:00
weichenandCursor b7cfb28217 fix(squad): keep quality repair inside a local snapshot workspace
Repair TASK.md told the model to edit ../../output.md, so the local
target never appeared and UI-03 stayed quality_failed. Snapshot parent
inputs locally, restore them on containment violations, and promote
only a trusted repair/output.md before revalidate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 20:15:54 +00:00
weichen 8b1a531947 merge: fix/document-revision-editor-hydration-race 2026-09-13 20:02:09 +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
weichen 4c465d2cb0 merge: fix/document-revision-pi-runner-module 2026-09-13 19:30:05 +00:00
weichenandCursor 21c8a0063b docs: claim pi-agent settle-policy image COPY hotfix
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:29:34 +00:00
weichenandCursor 369fe7bf51 fix(pi-agent): copy settle-policy into the runner image
runner.mjs imports ./settle-policy.mjs but the Dockerfile only copied
runner.mjs, which crashed shuimu-pi-agent-dev on import. COPY the
runtime module and assert every relative import is in the image set.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:29:34 +00:00
weichen 55a4f399fa merge: fix/document-revision-prelim-output 2026-09-13 19:26:50 +00:00
weichenandCursor 051e69ccd1 fix(pi-agent): clear recovered SDK transients before settle
auto_retry_end success=true now drops providerTransient and lastErr so
a later agent_settled can succeed when the in-process retry landed a
real target. A new error after recovery still fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:25:41 +00:00
weichenandCursor becd295c9d fix(service): keep explicit backend failure fail-closed
A this-invocation output.md is preserved and never retried over, but
Success=false stays a step failure so truncated writes cannot pass.
Prior-round residue without a trusted patch is also not success.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:24:47 +00:00
weichenandCursor d9c1791e56 docs: record dockerignore hole and tightened step retry contract
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:21:56 +00:00
weichenandCursor 6fd685fd47 fix(service): retry only safe transients and keep existing targets
Fresh step invocation is limited to provider terminated/connection plus
a missing target, or an explicit runner failure. A deliverable already
on disk is accepted and never overwritten.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:21:56 +00:00
weichenandCursor 35b2e922bf fix(deploy): keep official templates in the image build context
*.md was excluding templates/docs from Docker context, so COPY and
go:embed could not see prelim_design.md at /app. Un-ignore those trees
and assert the smoke image can cat the official file.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:21:56 +00:00
weichenandCursor 7be683d9c7 docs: record UI-11 write-terminated settled-failure root cause
Separate MiniMax/SDK connection failures from the product gap that
reported process 0 and agent_settled as step success.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:17:09 +00:00
weichenandCursor 11bdba0052 fix(pi-agent): treat exhausted SDK retry plus settle as failure
agent_settled after terminated or auto_retry_end success=false is not a
deliverable. Return retryable for provider transients and keep clean
missing targets permanent.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:17:09 +00:00
weichenandCursor ce89939cd8 feat(service): retry transient step failures with a fresh invocation
runOneStep re-executes the backend at most once when the first attempt
is a settled failure or missing target after provider errors, records
each attempt honestly, and fail-closes after the bound.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:17:09 +00:00
weichenandCursor 98619c7b56 feat(agent): classify settled-failure as bounded retryable
Treat process-0 plus terminated/Connection error/auto_retry_end as a
provider transient. Permanent missing deliverables stay fail-closed and
are never reconstructed from truncated write arguments.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:16:46 +00:00
weichenandCursor 32cf9ad4fc docs: claim UI-11 prelim output contract gap in_progress
Record the missing-output.md failure, embed/path-mapping tradeoffs, and CURRENT mutex without marking the task done.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:09:48 +00:00
weichenandCursor 333c7a604f fix(pi-agent): do not settle success without a deliverable
agent_settled after exhausted retries is not success; missing or empty target files must return ok:false instead of an empty patch list.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:09:48 +00:00
weichenandCursor 4a97ff5dd1 fix(agent): map runner patch paths and require real targets
Normalize absolute, ./, and duplicated step prefixes onto output.md, and fail closed when the runner reports ok without a non-empty deliverable.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:09:48 +00:00
weichenandCursor e04829ee8e fix(template): embed official doc templates for container cwd
App images have no templates/ checkout, so GetDocTemplate fell back to a two-section stub and prelim_design lost its real contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 19:09:48 +00:00
weichen 2a58674299 merge: fix/document-revision-second-doc-routing-lease 2026-09-13 18:47:14 +00:00
weichenandCursor 4dcc5011ac docs: record UI-11 prelim_design card title vs prompt alias
Keep the routing/lease task in_progress and document why the second-doc locator must use the registered doc id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:46:21 +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 9a9e25806c docs: claim UI-11 routing and lease gap in_progress
Record the tenth-round routing/lease failure, request-scoped release tradeoff, and CURRENT claim without marking the task done.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:42:44 +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 9f6401847d fix(docgov): release human lease after PATCH request
Request-scoped defer release after authorized acquire so success/409/projection failure cannot leave a 15m residual that blocks squad runs.

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
weichen 77f5db1e90 merge: fix/document-revision-e2e-overlay-transition 2026-09-13 18:25:05 +00:00
weichenandCursor 59dc73ec7c docs: claim UI-07 transition sampling gap in_progress
Link the archived ninth-round mid-transition failure; do not mark
the task done before a real UI rerun.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:24:27 +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
weichen 58ae25444d merge: fix/document-revision-e2e-overlay-selector 2026-09-13 18:07:46 +00:00
weichenandCursor 18a5457c07 docs: claim UI-07 overlay selector gap in_progress
Link the archived eighth-round failure; do not mark the task done
before a real UI rerun.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 18:06:53 +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
weichen 1b020790da merge: fix/document-revision-e2e-save-selector 2026-09-13 17:47:28 +00:00
weichenandCursor 5705f99fdc docs: claim UI-06 save-selector gap in_progress
Link the archived seventh-round failure; do not mark the task done
before a real UI rerun.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:46:37 +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
weichen 4a4fbcf2a6 merge: fix/document-revision-e2e-block-selector 2026-09-13 17:25:41 +00:00
weichenandCursor bb9f347fc9 docs: claim UI-06 block selector gap in_progress
Link the archived sixth-round failure; do not mark the task done
before a real UI rerun.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:24:54 +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
weichen 61905e99c1 merge: fix/document-revision-e2e-reject-routing 2026-09-13 17:09:42 +00:00
weichenandCursor d45efa2ff1 docs: record fail-closed ETag and viewer comment hardening
Keep the reject-routing task in_progress; no real UI rerun this round.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:08:35 +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 0a34daf4b5 docs: record duty forgery and ETag overwrite risks
Document the privilege-escalation and silent-overwrite hazards; keep
the reject-routing task in_progress pending real UI rerun.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:02:23 +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 79797cab7c feat(docgov): project document summary returns authoritative duties
ListWorkflowDocumentsByProject now projects author/reviewer/approver
id+name so clients cannot invent the current user as author.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 17:02:23 +00:00
weichenandCursor 52c0292ff7 docs(ops): keep pending-flow in_progress and split its mutex
UI-05b has not reached reject yet, so pending-flow cannot be done; move it to pending-report-ui so reject-routing can keep document-revision-runtime-ui.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 16:50:58 +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
weichen 3157a66f2d merge: fix/document-revision-e2e-pending-flow 2026-09-13 16:26:19 +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
weichen e6cd7bef9e merge: fix/document-revision-quality-context 2026-09-13 16:11:14 +00:00
weichenandCursor 75345431e4 fix(squad): require action-plan table separator and equal columns
Reject 待续 status-cell exemptions unless the same contiguous table has a header immediately followed by a valid separator and the data row width matches the header.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 16:10:24 +00:00
weichenandCursor dee18d7fc0 fix(squad): exempt only action-plan status cells for 待续
Treat structured 阶段/状态/进度 cells as workflow state, not hedging, while still failing body, lists, and non-status columns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:59:56 +00:00
weichen 40526773be merge: fix/document-revision-active-doc-routing 2026-09-13 15:44:48 +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
weichen 86598e7d0e merge: fix/document-revision-sse-idempotency 2026-09-13 15:22:59 +00:00
weichenandCursor f4aa0da14f test(docgov): lock quality projection, stage halt, and uncontrolled auto-repair
补齐 QualityReport 拦截投影与阶段停链断言,并证明 CLI 非受控路径 AutoRepair=false 不会追加 repair 步。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:20:42 +00:00
weichenandCursor 2d86d330e5 fix(docgov): keep squad AutoRepair/Success semantics; force repair only on controlled docs
小队修复预算只认 AutoRepair,Success 只表示执行完成;bizdev 在解析出 docRec 后强制开启修复,投影与阶段停链仍以 QualityReport 为准。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:19:20 +00:00
weichenandCursor 9e50bc0543 fix(docgov): stop ExecuteStage on quality_failed without absorbing facts
阶段链在 ExecuteTask err=nil 后同时检查质量门禁与 Success;失败立即停链并保留 artifact,不注入 ExtractedData/PriorDoc,不宣称阶段成功。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:17:40 +00:00
weichenandCursor 107f898362 fix(docgov): tighten prohibited-phrase exemption; lock stage request fields
自检豁免改为同行且须 meta+否定紧邻或引号引用,避免正文「无」误放过;buildBizdevStageRequest 单测锁住身份/职责字段与 AutoRepair 契约。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:16:12 +00:00
weichenandCursor 92488b327a fix(docgov): short-circuit quality_failed before controlled doc projection
质量门禁未过时在 SetDocumentWorkDir/Materialize/哈希更新/完成活动之前返回,保留隔离工作区与失败摘要,不改正式 head。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 15:14:55 +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
weichen f3e4eeb42b merge: fix/document-revision-runtime-ui03 2026-09-13 14:08:21 +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
weichen e45c2b7d36 merge: fix/document-revision-runtime-task-scope 2026-09-13 13:00:17 +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
weichen aeeb48ba7d merge: fix/document-revision-runtime-ui02-access 2026-09-13 12:36:12 +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 1fd500e2b9 docs(audit): record UI-01/02 access, chat authz, and member persist fixes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 12:25:22 +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
weichenandCursor cc394c815c fix(api): require project membership before chat and chat SSE
Unrestricted stage access on projects without a live workflow must not
let arbitrary authenticated users join by project_id. Enforce member or
creator (admin per existing policy) before stage ABAC, and reject chat
streams with JSON 403 before SSE headers/flush.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 12:25:22 +00:00
weichenandCursor f50692be25 fix(projectinstance): distinguish never-activated vs closed governing instances
GetLiveInstance remains active-only; access ABAC now uses
GetGoverningInstanceForAccess so completed/terminated PG rows are not
treated as unrestricted legacy projects, while brand-new projects without
instances stay open for creators.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 12:25:22 +00:00
weichen 0553c48039 merge: feature/herdr-agent-governance 2026-09-13 12:16:29 +00:00
weichen 6544f523f5 docs(ops): finalize Herdr governance integration 2026-09-13 12:16:14 +00:00
weichen e37a5fa399 docs(ops): close Herdr governance task 2026-09-13 12:16:08 +00:00
weichen 846638197d Merge branch 'dev' into feature/herdr-agent-governance 2026-09-13 12:15:07 +00:00
weichen 187084c517 feat(ops): add Herdr agent routing governance 2026-09-13 12:04:41 +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 d282b1e526 merge: fix/document-revision-runtime-user-directory 2026-09-13 11:59:19 +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
weichen 8c5cac17ef merge: fix/document-revision-runtime-auth-ui-evidence 2026-09-13 11:38:02 +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
weichenandCursor c70cdf7261 docs(ops): record UI-00 auth snake_case mapping finding
Add audit note and cross-link short-term/checklist/CURRENT for the
admin entry regression found in real browser acceptance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:37:03 +00:00
weichenandCursor d421fba472 fix(api): fail closed when status update cannot set user role
Return the UpdateUserRole error instead of silently continuing when an
admin approves a user with an explicit role_id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:37:03 +00:00
weichenandCursor f189ce9ff9 fix(auth): surface BootstrapAdminFromConfig UpdateUserRole failures
Do not ignore role promotion errors when ensuring the configured admin
account holds role-admin; cover success and failure with unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:37:03 +00:00
weichenandCursor cf28e53308 fix(web): map Go UserAccount snake_case fields at auth API boundary
Normalize role_id/employee_id/must_change_password/created_at into
camelCase for login, me, and admin user mutations so admin UI gates work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:37:03 +00:00
weichen 0b36a6ede0 merge: document-revision-ui-e2e-slot 2026-09-13 11:15:47 +00:00
weichen 53f988da49 docs(ops): advance document revision follow-up to UI e2e 2026-09-13 11:15:47 +00:00
weichen edbd01e5cc merge: fix/document-revision-runtime-ui-evidence 2026-09-13 11:13:58 +00:00
weichen 2f4d27d28d docs(ops): mark document revision follow-up merge phase 2026-09-13 11:13:53 +00:00
weichenandCursor 00a31e9b8d fix(e2e): require ADMIN_* env for UI acceptance credentials
Drop the hardcoded admin password fallback so secrets never ship in the
spec; missing ADMIN_USERNAME/ADMIN_PASSWORD fails the suite explicitly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:13:22 +00:00
weichenandCursor e5139d980a docs(ops): note upload freeform registration before send
Record client_key create path and no-orphan send contract on the
document-revision-runtime short-term task.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor 59b6db74bb test(e2e): tighten UI-01 zero revision-state 404 assertions
Match only hyphenated doc-p template paths, reset logs after login, and
expect registered uploads to use server doc-free ledgers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor 91de320b67 fix(web): mount revision toolbar for registered uploads only
Keep template/legacy gates; allow doc-free uploaded_file toolbars while
blocking unregistered doc-upload orphans.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor ef0b2645e5 feat(web): await freeform upload register before send
Make InputArea/onSendMessage async; fail closed with an explicit UI error
when createFreeformDoc fails, and persist fileStore under server doc-free IDs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor a3c6df309b feat(api): expose POST /freeform-documents for upload registration
Authorize project members, reject direct project_shared creates, and
cover idempotent client_key plus revision-state after register.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor 9c7d6d49b2 feat(freedoc): CreateDocument with client_key idempotency
Support direct freeform create for upload fact-source registration while
keeping source_content_sha256 as a content fingerprint only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor 1e364f17ab feat(db): add freeform client_key for idempotent upload registration
Persist owner-scoped client_key on freeform_documents so upload create
can retry safely without inventing local doc-upload orphans.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00
weichenandCursor 9a36e7c896 docs(ops): document UI_PHASE split for Playwright acceptance
Note main vs post-restart runs and credential-safe evidence layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:53:35 +00:00
weichenandCursor bd53984790 test(web): rewrite DOCREV UI acceptance without false PASS paths
Require observed squad start before terminal status, dual high-risk
confirm/reject, computed overlay diffs, real A/B contexts, UI logout,
and UI_PHASE post-restart evidence. Sanitize network paths; no mocks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:53:35 +00:00
weichenandCursor fe979fdd21 fix(web): gate DocumentRevisionToolbar to server-backed docs
Skip revision-state for template-only and legacy local mocks; show a
non-error preview hint instead of 「账本未就绪」. Keep generated controlled
and server freeform on the toolbar; leave IndexedDB upload orphans unmounted.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:53:35 +00:00
weichen 5724f4f74e docs(ops): advance document revision slot to real UI e2e 2026-09-13 10:14:07 +00:00
weichen d94b0d17f5 merge: fix/document-revision-runtime 2026-09-13 10:12:51 +00:00
weichen a7bd65b489 docs(docrev): record fresh gates and acquire integration slot 2026-09-13 10:12:45 +00:00
weichenandCursor 353d9fdf33 docs(ops): drop PutChangeProposal from decision-idempotency notes
Record that compensation must not seed memory-only proposal state.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:10:56 +00:00
weichenandCursor 0aae84d0a8 fix(docgov): remove PutChangeProposal memory-seed helper
Do not expose a production path that mutates only the in-memory proposal
index. Cover decision idempotency via ProposeModification+Decide and the
existing package MarkProposalApplied tests instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:10:56 +00:00
weichenandCursor 5f2063ebbe docs(ops): mark Playwright UI acceptance skeleton as checked in
Point the UI checklist at the committed runtime spec and config instead of
a deferred plan-only placeholder.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:09:32 +00:00
weichenandCursor 09488132dd docs(ops): note decision idempotency and Playwright skeleton
Record MarkProposalApplied ordering, CommitAgentVersion retry contract,
and the UI acceptance skeleton paths on the short-term task.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:09:18 +00:00
weichenandCursor 46769467bf chore(web): add Playwright UI-only acceptance skeleton
Add @playwright/test, headless config, and document-revision-runtime specs
gated by RUN_UI_ACCEPTANCE without mocks, routes, or API/DB fixtures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:09:18 +00:00
weichenandCursor 9c8a41982c fix(api): guide idempotent decision retry after governance mark failure
Surface a same-decision retry hint and cover commit-then-MarkProposalApplied
compensation via PutChangeProposal when the proposal index was missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:09:18 +00:00
weichenandCursor 9a9ffa48cc fix(docrevision): allow idempotent commit retry after ledger commit
When a candidate is already committed, matching expected hashes return the
current revision state so projection and MarkProposalApplied can finish;
reject on an already-committed candidate stays an error.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:09:18 +00:00
weichenandCursor 0b5f4997e2 fix(docgov): mark proposal applied after durable DB write
Write applied status to Postgres before mutating memory so a failed UPDATE
cannot leave a false in-memory applied state; treat already-applied as
idempotent success and expose PutChangeProposal for compensation seeding.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:09:18 +00:00
weichenandCursor 6fb40af05e docs(ops): note frontend pending_author_confirmation mapping
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:04:14 +00:00
weichenandCursor 7f88b6d882 fix(web): map pending_author_confirmation instead of defaulting completed
History refresh now preserves awaiting-author status and shows a visible
待编制人确认 label; live done path reads run terminal status before paint.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:04:05 +00:00
weichenandCursor 9ed5987104 test(bizdev): drain pending confirmations in full-link stage E2E
Stage chain now stops on high-risk candidates; full-link mirrors the
product path of confirm + re-run until success or DocGov proposal intercept.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 10:00:45 +00:00
weichenandCursor b5a3b72756 fix(bizdev): stop stage chain on pending agent confirmation
PendingAgentCandidateID must not continue the stage loop or inject
unconfirmed MarkdownBody/ExtractedData as PriorDoc. Return explicit
awaiting-confirmation status; user re-runs the stage after deciding.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:57:54 +00:00
weichenandCursor c990bcdb89 fix(bizdev): record delivery activity only after commit; surface proposal mark errors
Move RecordActivity off the pre-Materialize path: pending writes an explicit
awaiting note, failures skip completion, committed records 完成交付物.
MarkProposalApplied failures now return retryable governance/projection errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:55:42 +00:00
weichenandCursor d07d201728 docs(ops): record high-risk fact-source and pending reply gates
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:51:15 +00:00
weichenandCursor 0c6fb090ff fix(chat): show pending confirmation instead of completed for high-risk
Sync coordinator and async CompletionSummary use pending_author_confirmation
with artifact metadata for document entry; completed only after commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:51:15 +00:00
weichenandCursor 4f5a6188a7 fix(docgov): defer fact-source update until high-risk commit
Materialize needs_confirmation restores ledger head to output.md and
document_records hash; only committed heads update DocGov. Decision
handler projects after commit or reject. Stage gates DocGov proposals
via PendingProposal, not bare RequiresAuthorApproval.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:51:15 +00:00
weichenandCursor 87971fc953 docs(test): add high-risk confirm/reject branches to UI acceptance plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:38:22 +00:00
weichenandCursor 5caefc887a feat(web): full change-report panel and pending confirm/reject UI
Prefer pending reports on the toolbar, show risk items and impacts, and
call the decision API only when can_decide_pending is true.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:38:22 +00:00
weichenandCursor 79e8349d71 feat(docrevision): expose pending high-risk candidate on revision-state
Surface pending_candidate_id, report id, and risk so NeedsConfirmation
candidates are discoverable before they enter the version list.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:38:22 +00:00
weichenandCursor 8594feb6cc docs(ops): note Materialize honesty and lease/projection review fixes
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:32:08 +00:00
weichenandCursor 7b48ca2ecc fix(docgov): assert edit duty before lease; project via SaveDocumentContent
Unauthorized actors no longer grab leases; controlled PATCH projects through
DocGov so author_last_edited and audit survive, with idempotent retry on failure.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:32:08 +00:00
weichenandCursor 645c4b67b0 fix(bizdev): surface Materialize failures and block invalid auto-commit
TaskRunResult now fails visibly when ledger/report materialization errors;
invalid or unassessed reports are never auto-committed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:32:08 +00:00
weichenandCursor 4a91105e99 docs(docrev): evidence for materialize, patch order, and UI refresh
Expand the headless UI checklist and record remaining real blockers without
claiming PI narrative or E2E completion.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:27:07 +00:00
weichenandCursor ff1a126415 feat(web): refresh revision toolbar after save and expose report entry
Bump revisionRefreshKey on save/hydrate so r and overlay reload; add a
latest change-report button wired to version change_report_id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:27:07 +00:00
weichenandCursor 75ec8785f3 fix(api): assert edit rights before ledger, then project body
Prevent fact-source writes ahead of ledger commit; projection failures return
DOCUMENT_PROJECTION_FAILED while keeping the ledger authoritative.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:27:07 +00:00
weichenandCursor a288dcf0cc feat(docrevision): materialize first-gen agent report without fiction
Open an explicit empty baseline then create a deterministic candidate/report
so the first squad success is visible as fallback analysis, not OpenTemplate-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:27:07 +00:00
weichenandCursor 7f8331f893 fix(docrevision): harden empty docID, per-doc auth, and failed-save honesty
Stage generation without a real document must not panic or enter the ledger.
Unknown orphan IDs are denied, write paths check author/lease/lifecycle, PATCH
no longer returns a fake 200, and overlay matching survives client/server block id drift.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 09:02:54 +00:00
weichenandCursor 95f0ead131 docs(ops): record document-revision-runtime gate evidence and commits
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 08:48:54 +00:00
weichenandCursor fa615fee2a docs(test): add headless UI acceptance plan for document revision runtime
Separate browser-only real acceptance from engineering unit/build gates and record gate evidence on the short-term task.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 08:48:32 +00:00
weichenandCursor d79fdf6ffa feat(web): persist freeform block edits and apply overlay modes
Stop skipping freeform PATCH saves and decorate BlockRenderer for pure/manual/all revision views with clear empty states.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 08:48:32 +00:00
weichenandCursor 46a1fcc945 feat(api): authorize revision routes and project fact-source saves
Resolve controlled/freeform/orphan docs, bootstrap on GET, write output.md or freeform content on PATCH, and wire lineage impacts for agent candidates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 08:48:32 +00:00
weichenandCursor ed1e232022 feat(docrevision): persist ledger in PostgreSQL with bootstrap
Hydrate/mutate against schema 00028, ensure first-access bootstrap, and build deterministic change reports instead of static fiction.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 08:48:32 +00:00
weichenandCursor 7ea686e6ba docs(docrev): audit runtime 404 and claim docgov remediation
Record in-memory ledger root cause, PG persistence plan, and CURRENT mutex claim on fix/document-revision-runtime.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 08:35:19 +00:00
weichen c6c22494f8 merge: docs/release-slot-docrev 2026-09-13 08:14:05 +00:00
weichen 41bbc4049c docs(ops): release integration slot and record dev schema 28 healthy 2026-09-13 08:14:02 +00:00
weichen 17fc510c2c merge: feature/document-revision-management 2026-09-13 08:12:33 +00:00
weichen 501cde7c12 docs(ops): occupy integration slot for document revision merge 2026-09-13 08:12:27 +00:00
weichen 5e1a7e6584 fix(web): pass bearer auth in document revision api and fix ts unused imports 2026-09-13 08:12:19 +00:00
weichenandCursor 4f5bde899a docs(test): archive DOCREV waves and record unit evidence
Update CURRENT/FEATURE-MATRIX, archive short-term tasks, and add
document-revision management test report for Wave 0–6 delivery.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 06:15:20 +00:00
weichenandCursor 9aafe7bd37 feat(web): persist block edits via revision API and compare UI
Remove hardcoded editor actor, add revision toolbar/history/compare
panels, conflict banner, and notification status actions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 06:15:20 +00:00
weichenandCursor 7a7162dcee feat(api): wire document revision HTTP and agent/freeform hooks
Expose revision-state/versions/diff/PATCH content/candidate decision
APIs; emit document notification outbox events; bootstrap ledger from
bizdev success and freeform updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 06:15:20 +00:00
weichenandCursor 268a9bdb56 feat(service): implement docrevision Version/Revision kernel
Add canonicalize, stable block map, diff, risk floor, memory ledger
service, contract fixtures, concurrency tests, and backfill CLI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 06:15:20 +00:00
weichenandCursor 7bbd6783fc feat(db): add document revision ledger schema 00028
Introduce immutable blobs/snapshots, versions, events, candidates,
change reports, and ledger_* root pointers; rename freeform
current_version_id to legacy_version_id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 06:15:20 +00:00
weichenandCursor 7778559201 docs(docrev): freeze version boundary ADR and Wave 0 task
Accept DOCREV decision gates, archive design short-term, and mark
FEATURE-MATRIX partial as implementation starts on feature branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 05:58:49 +00:00
weichen e372a1467c merge: finalize conversation intent state verification 2026-09-13 04:47:33 +00:00
weichen a676bd0b95 docs(test): record final conversation state smoke 2026-09-13 04:47:29 +00:00
weichen 5bc333b1aa merge: busy preflight without failed runs 2026-09-13 04:44:03 +00:00
weichen 357fcc79ee docs(ops): occupy slot for busy preflight 2026-09-13 04:43:58 +00:00
weichen 6ab8b52113 fix(taskrun): reject busy documents before run creation 2026-09-13 04:43:50 +00:00
weichen 2660260758 merge: fixture cleanup evidence 2026-09-13 04:38:01 +00:00
weichen f17781adb6 docs(test): record fixture workspace cleanup 2026-09-13 04:37:57 +00:00
weichen a7c073d85c merge: release chat integration slot 2026-09-13 04:36:32 +00:00
weichen 06dacc9956 docs(ops): release chat integration slot 2026-09-13 04:36:25 +00:00
weichen 1cd2e681ed merge: truthful integration rebuild command 2026-09-13 04:35:58 +00:00
weichen 0225906f3f fix(ops): rebuild images for integration smoke 2026-09-13 04:35:52 +00:00
weichen e0f07060b9 merge: readonly summary HTTP coverage 2026-09-13 04:29:22 +00:00
weichen deaec82a7c test(chat): cover readonly summary HTTP path 2026-09-13 04:29:17 +00:00
weichen d7a19d4786 merge: authorized readonly document summary 2026-09-13 04:27:16 +00:00
weichen a830d9dcc1 docs(ops): occupy slot for summary integration 2026-09-13 04:27:10 +00:00
weichen cd506d8cc7 fix(chat): add authorized readonly document summaries 2026-09-13 04:27:01 +00:00
weichen 55639b3d26 merge: release chat integration slot 2026-09-13 04:20:02 +00:00
weichen efe630d033 docs(ops): record dev smoke and release slot 2026-09-13 04:19:58 +00:00
weichen ef61e77192 merge: fix/conversation-intent-state 2026-09-13 03:51:55 +00:00
weichen 30ace0234b docs(ops): occupy integration slot for chat fixes 2026-09-13 03:51:45 +00:00
weichen 95ab2badf6 fix(chat): preserve intent and task runtime state 2026-09-13 03:51:18 +00:00
weichenandCursor 995e099026 fix(web): use fatal error class for auth-related chat errors
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:33:34 +00:00
weichenandCursor 38e2e32807 fix(web): satisfy chatRetry task auto-retry type check in docker build
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:32:57 +00:00
weichenandCursor 3e242e6d36 fix(docgov): reclaim orphan squad leases and align run_id
Use task run_id as doc lease holder so release tracks execution, and reclaim squad locks when the holder run is missing or no longer running.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:32:20 +00:00
weichenandCursor 0c5256c60c fix(web): bind task API to resolved intake key when URS-only pool
When deliverables only expose user_requirements templates, requirement phrases still must POST intake on V0.1. Re-resolve task_key on retry and skip auto-retry for stage gate errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:30:13 +00:00
weichenandCursor d08cbdc2de fix(web): route 初始需求 to intake and map stage 403 errors
Debug logs showed task runs used user_requirements on V0.1 while the active stage only allows intake. Prefer intake for 初始需求/摸底 phrasing and surface DOC_TASK_NOT_IN_ACTIVE_STAGE instead of SESSION_FORBIDDEN.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:28:36 +00:00
weichenandCursor 3afd606635 fix(web): resolve project id from session id for task runs
Task template messages were posting to project_id=1 when local session cache lacked projectId, causing 403 on POST /api/v1/tasks/runs. Parse sess-p{id}-u{user} encoding as fallback and surface HTTP status on task failures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:23:53 +00:00
weichenandCursor 8032dce435 fix(chat): rebuild path and clarify stream auth errors
Rebuild dev backend so message visibility uses scope-aware filtering instead of dropping messages without stage_key. Map HTTP 401/403 on chat stream to actionable auth errors instead of generic NETWORK_ERROR.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:20:38 +00:00
weichenandCursor e0721a7944 fix(web): add favicon assets to stop /favicon.ico 404
Add public favicon.svg and favicon.ico and link them from index.html
so browsers stop requesting a missing root icon on refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:14:22 +00:00
weichenandCursor 2636542418 fix(web): repair duplicate else in useChatWindow loadInitialWindow
Remove a stray else branch left from the refresh-state refactor that
broke Vite/esbuild parsing on page reload.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:07:51 +00:00
weichenandCursor dca83f0dea docs(chat): archive refresh remediation test report and close gap
Update gap-matrix CHAT-HISTORY-REFRESH to PASS, sync CURRENT and
short-term checklist with implementation evidence.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:06:11 +00:00
weichenandCursor b6aebc8176 fix(web): improve chat window refresh state and user-scoped cache
Distinguish authorized-empty and forbidden phases; skip caching day
buckets with zero messages; bind window cache keys to user id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:06:11 +00:00
weichenandCursor 4b8d8bf6d6 fix(chat): unify history read authorization and stats filtering
Apply session ownership plus scope_kind visibility across window, day,
search, dates, categories, unread, and digest endpoints; add PG refresh
regression test for pre-activation and task-scoped messages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:06:11 +00:00
weichenandCursor 1abafa3176 fix(chat): add message scope columns and write-path resolution
Persist workflow_instance_id, stage_instance_id, scope_kind on chat
messages and task runs; resolve scope from live instance for chat and
document tasks so refresh can apply consistent stage authorization.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 03:06:08 +00:00
weichen 210fe4a7bb merge: feature/sync-wip-2026-09-13 — container env config and chat refresh docs
CI / go-vet-and-short-test (push) Failing after 1s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
2026-09-13 02:55:31 +00:00
weichenandCursor 6101bf8bef docs(audit): add chat history refresh diagnosis and remediation trail
Record refresh disappearance root cause, gap-matrix blocker, short-term
task, handoff, and archive evidence for CHAT-HISTORY-REFRESH.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:55:21 +00:00
weichenandCursor fe0bb3a503 fix(config): layer root and env compose files with expanded overrides
Load agent/cursor env overrides in config loader; pass root .env plus
environment-specific env files in env-service; align compose env_file mounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:55:18 +00:00
weichen 40fdd9315c merge: feature/chore-history-rewrite — history rewrite tooling and docs
CI / go-vet-and-short-test (push) Failing after 1s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 35s
2026-09-13 02:51:33 +00:00
weichenandCursor 9e8ff2ff4a chore(scripts): add epic history rewrite tooling and SHA map docs
Replay 358 linear commits as 14 feature/fix epics with merge --no-ff;
include manifest, rewrite script, SHA map, and git-workflow-helper alignment.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:51:33 +00:00
weichen 4a7b571c8d merge: feature/agent-docs-system — doc taxonomy and branch policy 2026-09-13 02:50:23 +00:00
weichen f9656d899e merge: fix/governance-v2-codex — three-workflow governance and Codex P0 2026-09-13 02:50:23 +00:00
weichenandCursor f30886e442 docs(agents): require feature branches off dev for all work
Align AGENTS, Cursor rule, PROJECT, README, templates, and CURRENT with
strategy A: no direct commits on dev/test/main; all work branches from dev.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen 7ffbadfaa8 merge: feature/workflow-abac-taskrun — workflow ABAC taskrun and QA 2026-09-13 02:50:23 +00:00
weichenandCursor edcfcd321c docs(ops): 勾选 pi-agent provider 修复提交证据
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 81743dcb75 docs(ops): remove .doc root stubs and archive completed research
Delete 15 redirect stubs now that canonical paths exist under audit/
and remediation/. Move completed ops/research to archive, fix internal
links, and remove untracked duplicate test-report workspace artifacts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 73bf08275b docs(test): record pi-agent E2E v5 PASS after env sync fix
Full lifecycle passed in 714s with MiniMax token, RUNNER_AUTH_TOKEN, and shared KB connected.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor c60599379f fix(agent): 将 pi-agent 默认模型对齐为 MiniMax-M2.7-highspeed
根因是 Go 默认 provider 误为 cc-switch-kimi-for-coding,且 app 容器未注入 PI_AGENT_*,导致 runner 收到未知 provider。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor be9a6d4640 docs(archive): relocate superpowers, workflow, and test assets
Move docs/superpowers to archive/design/superpowers with stubs;
archive workflow rules to PROJECT SSOT; separate test-report assets.
Update Go doc path references.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 037c6084c5 docs(config): align .env.example with dual-env compose layout
Document CONTEXT_DB/SYSTEM_DB aliases, pi-agent secrets sync to configs/.env.dev, and compose vs host Go variable scope.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 575c2da092 fix(deploy): main 环境注入生产密钥并完成本地冒烟验收
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 20f52d025b docs(agents): multi-agent rules, templates, and tool entrypoints
Rewrite AGENTS.md with taxonomy, worktree, and integration slot rules;
add FEATURE-MATRIX-driven CURRENT; tool stubs; session-close checklist.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor bb0af3873d docs(test): record pi-agent E2E v3 failure at 60m step timeout
V0.1 step_01_organize exceeded AgentTimeout after KB and timeout passthrough fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 2fbb0b29a6 docs(audit): 以 gap-matrix 与 ops 对齐 Codex 再审计结论
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 511864bad0 docs(ops): scaffold doc taxonomy and relocate audit/remediation
Establish .doc/{status,audit,remediation,archive} structure with README
maps, migrate 15 root audit/remediation docs, and add redirect stubs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 033ef70ac9 fix(squad): propagate AgentTimeout to pi-agent step execution
E2E v2 still hit 30min runner timeout because runOneStep ignored ExecuteOptions.Timeout; inject shared KB config in pi-agent E2E test.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 0547bd58a8 fix(ops): HTTP 超时、env status 只读;test/dev 镜像重建 schema 25
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor f4619757e2 fix(test): extend pi-agent E2E AgentTimeout to 60m for stage runs.
V0.1 workflow steps exceeded the default 30m pi-agent /v1/run deadline; align test config with production AGENT_TIMEOUT and runner env vars.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen 3d09bd6d7d fix(quality): 闭环 Go 质量门禁(鉴权富化/V0.5/vet/health/KB gate/记忆轮询) 2026-09-13 02:50:23 +00:00
weichenandCursor c6c7423ec6 docs(test): record pi-agent E2E failure at V0.1 stage timeout.
Document 33min run with dialogue steps passing and workflow ExecuteStage failing on pi-agent /v1/run deadline.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor ac9fe7f09b chore(ops): 新增退休非正式工作流定义脚本
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 9598705fc7 chore(ops): add test env smoke script and document test soak pass.
Provide git-push-dev helper, DEP-001 smoke checks for test compose, and update E2E/soak test report.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 8c5dd97d63 feat(db): 同步种子用户与项目序列避免冷启动主键冲突
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 72879c6e22 fix(db): enable test env cold-start migrations on empty database.
Use pgvector image with extensions-only init, seed legacy users before project/chat fixtures, and align test compose with goose-only schema bootstrap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 3b7b49c624 fix(api): 任务同步与SSE入口补齐项目成员鉴权
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor f73988e567 docs(test): update report with successful push and dev soak.
Record Gitea token push, restarted dev server ready checks, and 60s soak pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 0d10c9adfe docs(ops): 建立通用 AGENTS 手册与本仓 PROJECT/CLAUDE 入口
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor c1b8f23b14 docs(test): report PG fix, CI short suite, and soak/E2E progress.
Document seed user reactivation, full short test pass, readiness soak, and blocked git push pending credentials.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen 185c42fc94 test(governance): 补跑 product_manager PG+PI 全链路并通过
抽取 runPiAgentGovernanceE2E 共用 harness,新增 system_reqs 真实 Agent 验收并更新测试报告。
2026-09-13 02:50:23 +00:00
weichenandCursor c7aba86376 fix(test): stabilize PG seed users and CI short test suite.
Reactivate dev seed users after auth PG tests, use unique session tokens, fix import guard and coordinator assertions, and skip flaky E2E in short mode; add pg_restore CI drill job.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen 390c0e3c71 docs(test): 更新 gap matrix MISSING-04 为 PASS 2026-09-13 02:50:23 +00:00
weichenandCursor 81f118098d docs(test): archive QA-001 backup drill and penetration test report.
Record template MIME, CI gate, backup/RPO drill, and security negative case results per test report standard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen 784d852ac0 test(governance): PI Agent PG 全链路实测通过并固化运行条件
修复 runner 鉴权与 data/dev 工作区挂载,使用正式 main 工作流完成 intake→批准→推进。
2026-09-13 02:50:23 +00:00
weichenandCursor 1ebed78bf5 test(security): add automated penetration negative test matrix.
Cover anonymous admin/task access, body limits, MIME rejection, strict readiness, and CORS allowlist without legacy test principals.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen d6f5e0e28a feat(projectcontext): bizdev 注入项目对话并完成 PG 治理 E2E
新增 ctxmgr 项目对话采集并接入 PM/TE BuildSnapshot;PG 测试统一 TEST_DATABASE_URL 并使用三正式工作流 key。
2026-09-13 02:50:23 +00:00
weichenandCursor d957b05569 chore(ops): add system DB backup and restore drill scripts.
Support dev/test/main pg_dump backups with RPO manifest metadata and a restore drill that validates dump integrity and migration idempotency.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandClaude Sonnet 5 a6501e5b31 docs(audit): comprehensive project code review and remediation plan
Complete audit and remediation documentation for Chat-Agent-System:

- 2026-09-12-AUDIT-INDEX.md: Document index and quick navigation guide
- 2026-09-12-audit-summary-report.md: Overall project assessment (5.7/10)
  - 12 identified defects (3 critical, 4 high, 5 medium)
  - 3 incomplete features
  - Risk assessment and remediation timeline (61h total)

- 2026-09-12-comprehensive-audit-and-remediation-plan.md: Detailed analysis
  - BUG-01 to BUG-12: Root cause, code locations, impact
  - MISSING-01 to MISSING-04: New feature design
  - Phase A/B/C remediation strategy

- 2026-09-12-remediation-tasks-and-acceptance-checklist.md: Executable tasks
  - 15 detailed tasks with code snippets and test cases
  - 61 hours total effort (Phase A:15h, B:26h, C:20h)

- 2026-09-12-quick-reference-guide.md: Fast lookup and diagnostics
  - Symptom → root cause → solution matrix
  - Code hotspot map and common Q&A

Key findings:
- Project 70% complete, needs immediate remediation
- 3 critical bugs affecting project lifecycle, security, data consistency
- 0% E2E test coverage
- 88 test definitions polluting development database

Recommendation: Start Phase A immediately (critical fixes), complete all remediation within one week.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 02:50:23 +00:00
weichen 0beddd9887 ci(qa): add QA-001 gate with go vet, short tests, and migration check. 2026-09-13 02:50:23 +00:00
weichen 77b8d07cd7 fix(governance): 统一文档访问判定与上下文快照排除计数
补齐 DocumentAccessDecider HTTP 409、projectcontext 私有对话排除统计,并更新整改 gap matrix 与测试报告。
2026-09-13 02:50:23 +00:00
weichenandCursor 6bc238c665 feat(upload): reuse MIME validator for workflow template uploads.
Centralize template extension, magic-byte, and HTML/script rejection in upload.ValidateTemplate so admin template POST matches project asset hardening.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 574dd16546 fix(frontend): skip hash anchor navigation until session is validated
Avoid chat day fetches with empty session_id on the login page when a stale URL hash is present.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 5856585d1d feat(ops): compose runner auth, upload MIME validation, and test soak
Wire RUNNER_AUTH_TOKEN through dev/test/main Compose, validate uploads
with extension whitelist and content sniffing, add readiness soak script
and short PG loop test, and require runner token in prod when URL is set.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 38e44a2606 docs(workflow): record three-workflow governance remediation and test report
Archive the strict governance design notes and validation report for the 2026-09-12 remediation cycle.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor d7a144de26 feat(taskrun): resume interrupted runs and harden P1 security gaps
Add confirm-gated resume API with resumable flag, Phase 5 finalize fault
and rolling-restart replay tests, Mermaid strict mode, request body limits,
and optional Runner Bearer auth between app and pi-agent.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor ad6e38d11a test(workflow): add governance regression and activation PG coverage
Cover public auth config, catalog policy, official main workflow activation on Postgres, and conn-busy metadata writeback fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 3ade654256 feat(taskrun): add worker lease/heartbeat and Phase 5 fault injection tests
Introduce goose v20 lease columns with heartbeat loops so only expired
leases are marked interrupted on restart; add PG tests for concurrent
stage advance, active lease survival, and backup migration idempotency.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 47984f4863 fix(frontend): gate data fetches until session validated and improve workflow UX
Prevent login-page 401 noise by deferring project/chat API calls until auth is confirmed, use public-config for registration policy, and add client-side duty assignment checks before saving workflow plans.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor aea391cdaf feat(taskrun): persist runs/events and fix finalize-before-done ordering
Add goose v19 task_runs/task_run_events tables with PG store for restart
replay, orphan interruption on startup, strict /ready checks, and strip
client work_dir from chat/SSE paths per P0 path sandbox requirements.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor d5a9a29eec feat(api): add workflow catalog routes and public auth config endpoint
Expose governance APIs for workflow selection/termination and allow login pages to read registration policy without admin credentials.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 12756b13e6 fix(projectworkflow): generate UTF-8 safe project codes for Chinese names
Truncate project codes by rune instead of byte to prevent invalid PostgreSQL UTF-8 sequences from mixed CJK and ASCII slugs.

test(server): add PG pi-agent governance E2E and Phase 5 acceptance matrix

Cover Chinese HTTP project create, pi-agent intake after workflow activate, authz negatives, activate idempotency, and migration version gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor f07178fa73 feat(service): enforce three-workflow governance and instance lifecycle
Wire catalog policy, v2 manifests, stage access, activation metadata fixes, and coordinator instance advance around frozen workflow snapshots.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor c1f6830178 docs(test): fix report structure for blended ABAC and PG chain cases
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 543ca310da feat(db): add workflow schema v2 and catalog governance migrations
Introduce catalog governance tables and extend workflow schema v2 so only the three official workflows are selectable at runtime.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 4b168854ba feat(abac): filter blended squad context and add PG governance E2E
Route BuildBlendedSquadContext through stage access gate, and add PG integration test covering activate, doc approval hook, notifications, ABAC, and stage advance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 90f77eac93 feat(authz): implement six-phase permissions, settings and workflow v2
Close P0 auth gaps for lineage/runs, stage ABAC fail-closed, and
project:create; add IAM migrations 00021-23, me settings APIs, schema v2
manifests, orchestrator skeleton, and gate A regression coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 79811aa759 docs(test): add pi-agent E2E and bizdev ABAC acceptance report
Record real pi-agent lifecycle run (676s PASS) and stage access gate unit test results per delivery checklist.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 2795af2d09 fix(e2e): authenticate multi-role docgov steps in pi-agent lifecycle test
Align seeded user IDs and use per-role Bearer tokens so review reject/approve actions run as the assigned reviewer instead of the legacy fallback principal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 7c5f8deeb1 feat(abac): gate bizdev agent context by workflow stage duties
Inject stage access gate into bizdev service so task execution, project context reads, and prior docs respect live workflow ABAC.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor f6410508aa test(e2e): extend pi-agent lifecycle timeout to 1h
Allow long-running ad-hoc pi-agent steps by raising the HTTP client limit and documenting the 1h go test invocation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor b6035991d4 feat(notification): add 24h stage advance reminder and confirm on advance.
Poll pending requests every 15 minutes, emit deduplicated escalation notifications, and close requests when creator confirms stage advance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor d9f3d40423 feat(abac): enforce stage access on chat, search and SSE streams.
Tag messages with stage_key metadata, block sends for unauthorized roles, and filter history/search/case results by allowed stages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 69a3be5463 feat(web): poll stage ready notifications to refresh advance banner.
Poll project notifications every 15s and reload readiness when stage_ready_to_advance arrives.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 4bfe1cb5ad feat(api): wire document approval hook and project notifications API.
Register workflow approval callback on server start and expose GET /projects/{id}/notifications.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 32b88beee0 feat(projectinstance): refresh stage readiness after document approval.
Sync doc task status on approve and evaluate whether to emit stage advance readiness; chain docgov hooks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 10fa91de61 feat(notification): emit deduplicated stage ready to advance events.
Write outbox row and creator notification when a stage first becomes advance-ready.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor ff81170f47 feat(db): add outbox, notifications and stage advance request tables.
Support transactional stage.ready_to_advance events with dedupe by stage instance and config revision.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor ec2ea02e8a feat(abac): restrict workflow document access by active stage duties.
Resolve stage access from live instance assignments and filter document list/content for non-assigned roles.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor b402426257 test(db): add PG integration test for activation and stage advance.
Verify migration 00017 and full plan→preview→activate→advance chain against dev Postgres.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor e0c39aa38c feat(service): add stage gate readiness and creator-confirmed advance.
Evaluate required document approvals before stage transition, expose readiness/advance APIs, show StageAdvanceBanner in the UI, and keep legacy workflow switch for explicit initial_workflow_key projects.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 50c5f2ab0d docs(test): add Phase 3 project workflow governance test report.
Document planning-mode creation, plan/preview/activate unit results, and API regression outcomes for the instance governance MVP.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor 1fa6e9aa77 feat(web): add project workflow settings wizard and replace free switcher.
Topbar shows configure/view workflow actions under governance mode with a multi-step ProjectSettingsModal for plan, duty assignment, and confirmed activation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor be5cdb1ef6 feat(api): expose project settings endpoints and block legacy workflow switching.
Add settings/plan/preview/activate routes and reject active-workflow toggles when governance instances or planning projects require configured activation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichenandCursor dc629fc4b8 feat(service): implement project workflow plan, preview, and activation flow.
New projectinstance package validates three-duty separation, issues confirmation tokens, and activates immutable workflow instances; new projects start in planning mode.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:23 +00:00
weichen a24b00d393 merge: feature/security-iam — P0 security and IAM Phase 0-1 2026-09-13 02:50:22 +00:00
weichenandCursor 0f5bc426e8 feat(db): add project workflow instance tables for Phase 3 governance.
Introduce planning/active lifecycle, instance snapshots, duty assignments, and activation confirmation tokens with single-live-instance constraints.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 21de3bc39e merge: feature/chat-idempotency-task — turn idempotency and task materials 2026-09-13 02:50:22 +00:00
weichenandCursor 016c3a9791 test(docs): Phase 1 completion gates, PG integration tests, and report
Add disabled-user 401, admin roles/sessions handler tests, optional PG store
integration, cross-project 403 fixture, and update the Phase 1 test report to
reflect completion status.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichenandCursor 654e19a12d docs(test): Phase 2 workflow designer test report and plan
Archive validator/publish test results and document Phase 2 MVP scope
boundaries ahead of Phase 3 project activation work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHEN fcf00e7d1a chore(scripts): fix backfill script import and run projection for ws_intake 2026-09-13 02:50:22 +00:00
weichenandCursor a56d033d3c feat(web): fail-closed capabilities and admin roles from server API
Stop persisting roles to localStorage as authority; AdminSettingsModal reads
and writes role matrices via /api/v1/admin/roles; hasPermission denies when
capabilities are not loaded from /auth/me.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichenandCursor ebbfc2db18 feat(web): add admin workflows and template library tab
Admin console can list workflow definitions, validate/publish draft versions,
and view bootstrap template assets from the server API.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 9d40a91f9d feat(web): sync workflow docs from server and persist task artifact in chat
Pass doc_id on task runs, merge server deliverable state by task_key,
fetch controlled document content when opening non-template docs, and
map metadata.artifact after refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichenandCursor 6219caf690 feat(authz): complete Phase 1 admin roles, sessions, and unified admin gate
Add roles CRUD backed by system_roles tables, session list/revoke APIs,
capabilities fallback for memory mode, and route all admin checks through
AuthorizationService instead of hardcoded role-admin checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichenandCursor 967dd9becd feat(api): add admin workflow and template management endpoints
Expose draft/validate/publish/retire workflow APIs and template upload/list
routes wired to workflowdef service with DBCatalog refresh on publish.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 68765023a2 feat(api): add workflow document list, content read, and backfill script
Expose project controlled documents from DocGov, serve authenticated
output.md content by doc_id, and add idempotent backfill for run_1789111889557885000.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 8cdc839650 test(docs): Phase 1 IAM authz tests and test report
Extend P0 and auth/me handler tests for members endpoint and capabilities; archive Phase 1 test report under .doc/test-reports/.
2026-09-13 02:50:22 +00:00
weichenandCursor edffe74009 feat(db): add workflow definitions, versions, and template asset tables
Introduce Phase 2 IAM-adjacent schema for versioned workflow definitions,
template assets/versions, and workflow_defs permissions seed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 238f1d9346 feat(agent): unify async task FinalizeTaskRun projection to chat and runs
Extend taskrun executors to return full TaskRunResult, finalize assistant
placeholder content with artifact metadata, and map quality_failed terminal
state instead of metadata-only updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 47b8179824 feat(web): wire project members CRUD to REST API
Add projectMembers client and role adapter; sync members from server on login and modal open; persist add/update/remove via /api/v1/projects/{id}/members.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 91b257393e docs(test): add longtask P0 observer and materials test report
Archive automated regression results for stream materials, observer disconnect,
project asset upload, and ResolveMaterials assembly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 844bfd2803 feat(web): consume server capabilities for RBAC decisions
Fetch and cache capabilities from /auth/me on login and session restore; hasPermission prefers server capabilities over local role definitions.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor bbd1218922 feat(web): asset upload, task run observer, and session lineage on tasks
Upload binary attachments as project assets, subscribe by run_id after refresh,
and pass session_id/project_id through long-task requests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 4258d88415 feat(authz): add AuthorizationService, capabilities API, and project members CRUD
Wire authz service into server, expose capabilities on /auth/me, and add project member management routes with owner/admin gates.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor e139b2b267 feat(api): observer task runs decoupled from SSE lifecycle
Add POST/GET/POST cancel task run APIs, background worker with event replay,
workspace reconcile, runner child cancel, and chat message metadata updates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen d8c445bfd5 feat(auth): persist sessions and accounts via PostgresAuthStore
Add PgStore with hashed token sessions, IAM bootstrap, and store factory wiring; remove in-memory token map and allow_dev_switch from login payload.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 908d4bdb2e feat(agent): project asset upload and squad materials assembly
Register uploads via CAS, resolve project asset pools into task materials
with server-side extraction, and propagate asset_id through the bizdev/squad chain.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 3b72503ec6 feat(db): add IAM core migration for users, sessions, and RBAC
Introduce goose migration 00015 to extend users with IAM columns and seed system roles/permissions for Phase 1 authorization.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 6f3a4d4c80 fix(api): pass materials through task/stage stream handlers
Stream SSE path now forwards Materials to ExecuteTask/ExecuteStage, and
TestTaskStream_MaterialsInjection targets the real /tasks/run/stream endpoint.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 25ec2a22d8 docs(plan): add Phase 1 IAM and authorization implementation plan 2026-09-13 02:50:22 +00:00
WeiCHENandCursor 70493a3ed5 feat(web): wire project list and create to server API
Login syncs projects from GET /api/v1/projects; create project uses POST with server-assigned id while preserving local sessions and templates.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen d4988d04e8 test(docs): extend Phase 0 security gates and archive test report
Add P0 negative tests, prod bundle forbidden-string scan, and the Phase 0
security止血 acceptance report with PASS results.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor 636eb0ccf1 fix(web): align workbench user ids with auth seed
Unify MOCK_USERS with backend auth (admin id=1), merge session identity on login, and migrate demo seeds/tests to id 2/3/4 for 张工/李/王.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen e96ade076a fix(auth): restrict demo seed users to dev/test environments
Main no longer creates fixed-password demo accounts and legacy anonymous
fallback is limited to explicit dev/test in-memory fixtures.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor a8c8cba447 fix(web): keep draft when send preflight fails
Return accepted/error from handleSendMessage, clear InputArea only on success, and surface thinking/streaming feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 171959710d fix(security): add CORS allowlist and enforce principal on chat handlers
Replace wildcard CORS with configured origins and bind chat/task user
identity to the authenticated principal instead of request body fields.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor f9c4f9b01b fix(web): add secure-context-safe clientTurnId helper
Provide RFC 4122 v4 fallback via getRandomValues for LAN HTTP pages where randomUUID is unavailable.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen d612c1193e fix(web): remove identity simulation and stop sending X-User-ID
Product UI no longer switches sessions locally; API clients attach Bearer
tokens only and LocalAuthClient stays test-only outside the prod bundle.
2026-09-13 02:50:22 +00:00
WeiCHEN eea28f0be4 feat(task): inject uploaded documents into task materials and enable LAN host access
- backend: add Materials field to TaskRunRequestDTO and forward to ExecuteTask
- backend: add TestTaskStream_MaterialsInjection test case in taskstream_test.go
- web: serialize materials in buildTaskRequest and add unit test
- web: improve isSameMessage identity comparison in messageIdentity.ts
- web: configure host: '0.0.0.0' in vite.config.ts for LAN collaboration access
2026-09-13 02:50:22 +00:00
weichen 886cbb7913 docs(plan): add production governance plan and Phase 0 authz matrix 2026-09-13 02:50:22 +00:00
WeiCHENandCursor cc2aa33b10 docs(test): chat turn idempotency automated test report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 36721f9c08 docs(test): archive P0 remediation test report 2026-09-13 02:50:22 +00:00
WeiCHENandCursor 7ab5041c59 refactor(web): stop persisting full message list to localStorage
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen 3145550a59 feat(security): complete P0 release blocking remediation
Unify auth middleware and remove X-User-ID trust, add project_members
authorization, sandbox workspaces via resolver, and admin-only reconcile
by run_id. Introduce goose migrations with startup schema gate, fail closed
when DB unavailable outside explicit ALLOW_IN_MEMORY, bundle web/dist in
app Dockerfile, and remove frontend pseudo-login fallback.
2026-09-13 02:50:22 +00:00
WeiCHENandCursor d17fae0a5d feat(web): isolate stream runtime by session and turn
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor ad2147445c chore(deploy): 三环境 Compose 构建真实 app 镜像并补齐法规库运维
将 dev/test/main 的 app 服务从占位容器改为 Dockerfile 多阶段构建,增加 healthcheck 与 .regulations 只读挂载;新增法规库备份/恢复脚本并同步 env-service 目录初始化与 gitignore。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor f5ead1dcd5 feat(web): send stable client_turn_id and resume turns after disconnect
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor f4e4357ddb fix(agent): Chat Agent 全链路 P0-P5 整改
封堵鉴权旁路与导出 IDOR,DocGov 改服务端身份;对话层 PendingAction 接真实 docgov/taskrun;修复流式租约假死与会话级任务流;加固配置/doc_id/NULL;补齐 slog 与测试;前端 ErrorBoundary 与受控文档重试。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
WeiCHENandCursor a1cb4aade0 feat(api): gate chat stream on chat_turns with session serial execution
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:22 +00:00
weichen eb350d4367 merge: feature/web-chat-ux — SSE chat longtask history workflow and seed data 2026-09-13 02:50:21 +00:00
WeiCHENandCursor c887bc0480 feat(db): add chat_turns idempotency table
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 93ae180159 chore(db): add ten-project chat seed migration and generator script
Provide SQL migration and Python helper to import review demo sessions
and seed messages from tenProjectsSeed.json into Postgres.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 62ab734021 fix(web): guard chat window fetch races on session switch
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor cda534a75d feat(web): improve chat attachments, unread marks, and session UX
Support richer attachment payloads in input area, local read-id cache for
unread badges, and expand private-shared and chronology test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 7c830146f5 test(web): cover real temp vs server message identity
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 6f4e8c0933 feat(web): align project templates with official reference skeletons
Replace ad-hoc markdown stubs with reference-system template baselines,
free-text device type input, and add template quality regression tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor e1a9b302ba fix(web): merge live and history by serverId and clientTurnId
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor a9fe69ac16 fix(workflow): reconcile version conflicts in review mode and UI retry
Auto-adopt current workflow selection version in review/demo backend
paths, and retry frontend workflow switch after refreshing project version.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor c4ef72506f feat(api): return user_message_id in SSE turn_ack and done
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 0d395f2bf2 fix(ctxmgr): normalize dismissed_unread_ids for Postgres array insert
Ensure nil dismissed ID slices serialize as empty bigint arrays and
preallocate compressDismissed output to avoid NULL write failures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 9f7500bb72 fix(web): disable chat stream auto-retry without idempotency
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHEN 222b0c2dd6 feat(doc-preview): 上传文档多格式在线预览 + IndexedDB 持久化恢复
## 新增功能
- 支持用户上传的 Word(.docx)、PDF、Excel(.xlsx/.csv)、PPT(.pptx)、
  图像(png/jpg/svg/webp等)、纯文本/代码文件的在线高保真预览
- 预览与受控工作流文档严格隔离:上传文档走 FilePreviewPanel,
  工作流/对话入库文档继续走 BlockRenderer,互不干扰

## 核心 Bug 修复
- 修复页面刷新后上传文件无法预览/下载的根本问题
  - 根因:File 对象无法 JSON 序列化,刷新后内存引用丢失
  - 方案:新增 fileStore.ts,使用 IndexedDB 持久化文件二进制内容
  - App 启动时自动 restoreFileRawToDeliverables() 从 IndexedDB 恢复 fileRaw
  - 上传时 saveFile() 同步写入 IndexedDB(fire-and-forget)

## 下载按钮修复
- 优先从内存 File 对象动态创建 blob URL,避免依赖已 revoke 的旧 URL
- 文件内容不可用时按钮禁用并显示 tooltip 说明

## 存储层改进
- saveDeliverables() 序列化前剔除 fileRaw(不可持久化)和 blob: URL
  避免 localStorage 保存损坏的空对象

## 新增文件
- web/src/data/fileStore.ts — IndexedDB 封装(saveFile/getFile/restore)
- web/src/components/doc/preview/FilePreviewPanel.tsx — 预览面板主组件
- web/src/components/doc/preview/renderers/DocxViewer.tsx — Word 预览
- web/src/components/doc/preview/renderers/PdfViewer.tsx  — PDF 预览
- web/src/components/doc/preview/renderers/ExcelViewer.tsx — Excel 预览
- web/src/components/doc/preview/renderers/PptViewer.tsx  — PPT 预览
- web/src/components/doc/preview/renderers/ImageViewer.tsx — 图像预览
- web/src/components/doc/preview/renderers/TextViewer.tsx  — 文本预览
- web/src/tests/file-preview.test.ts — 预览功能单元测试
2026-09-13 02:50:21 +00:00
WeiCHENandCursor b69cb617a0 docs(spec): chat turn idempotency and session isolation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 24478ec383 feat(intent): Phase 5 V2 shadow gray flags and IntentPlan execution
Add env-based feature flags (intent_v2_shadow/decision, multi_intent,
workflow_intents), V1/V2 shadow diff reporting, expectation_plus_new plan
building, ranked-frame L2 conflict gate, and coordinator sequential query
plan execution with confirm-step deferral.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 9cb129d3e8 feat(intent): Phase 4 run control, subtypes, and limited IntentPlan
Add RUN_STATUS_QUERY/RUN_RESUME/RUN_RESTART with matcher and coordinator
handlers; write QUERY_PROGRESS/SUPPLEMENT_INFO subtypes to V2 frame; support
safe query+query multi-intent plans via IntentPlan dual-write.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor dda6a06e4a feat(intent): Phase 3 workflow/help intents and coordinator handlers
Add SWITCH/TRIGGER/QUERY workflow, doc status, help and unsupported intents
with ActionSpec registry entries, NL matchers, L2 handlers with creator-only
switch gate, router routes, and capability-aware AvailableActions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 3db56b4166 feat(intent): add V2 frame, ActionSpec registry, and legacy dual-write
Introduce IntentFrameV2 with goal/object/relation/evidence, register all 21
legacy intents in ActionSpec registry, and dual-write intent_frame_v2 alongside
TopIntent without changing Router/Coordinator routing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHENandCursor 868238137c fix(intent): Phase 0+1 P0 safety gates for recognition and coordination
Add golden-v1 hard-negative suite, shadow observability fields, query/command
negation gates for high-risk writes, AllowAffirmative enforcement, candidate
conflict clarification, and coordinator clarify-before-ambiguous ordering.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00
WeiCHEN 60d4df4319 fix(chat): resolve intent recognition, workflow auth, and message ordering 2026-09-13 02:50:21 +00:00
WeiCHEN 917740f26d feat(project): implement modal-based project creation, creator-led member assignment, and exited-member read-only retention 2026-09-13 02:50:21 +00:00
WeiCHEN eda2a2b32b refactor(dialogue): implement task dispatch notifications and consecutive assistant messages with confirmation cards 2026-09-13 02:50:21 +00:00
WeiCHEN 0df8b065c2 refactor(dialogue): naturalize multi-role conversations, close chat sessions with assistant response, and set URS to project shared 2026-09-13 02:50:21 +00:00
WeiCHEN 76e538a47f fix(doc): resolve URS viewing and private-to-shared workflow in document pane for 10 review projects 2026-09-13 02:50:21 +00:00
WeiCHEN f48181ee0c feat(chat): add URS requirement document upload dialogues with attachments and phase events for all 10 projects 2026-09-13 02:50:21 +00:00
WeiCHEN 27fe03a3e3 feat(chat): mount interactive review, approval, and verification confirmation cards in multi-role dialogues 2026-09-13 02:50:21 +00:00
WeiCHEN 2e3e43be8f fix(frontend): align MockDocumentMeta markdown property and guard nullish input in markdownToBlockAST 2026-09-13 02:50:21 +00:00
WeiCHEN a8f74244f5 feat(review): seed 10 real medical device projects with dual workflows, multi-role dialogues and fix account-switch chat isolation 2026-09-13 02:50:21 +00:00
WeiCHEN 42e3ece2c6 fix(workflow): fix 405/404/403 errors on workflow switcher by updating CORS, 5201 demo permissions and server restart 2026-09-13 02:50:21 +00:00
WeiCHEN 408bef6b8a chore(release): Phase 7 全链路验收报告、测试修复与发布基线归档 2026-09-13 02:50:21 +00:00
WeiCHEN 716aa6f49a feat(workflow): Phase 6 前端项目多工作流切换器、前置依赖横幅与文档血缘失效提醒 2026-09-13 02:50:21 +00:00
WeiCHEN abeab90388 feat(workflow): Phase 5 智能测试经理工作流、前置强依赖校验与文档血缘级联失效 2026-09-13 02:50:21 +00:00
WeiCHEN f994c45d67 feat(workflow): Phase 4 智能产品经理工作流、系统需求规格书与质量门禁 2026-09-13 02:50:21 +00:00
WeiCHEN c0d6ef7d80 feat(workflow): Phase 3 Coordinator 上下文、动作路由与工作流运行 API 集成 2026-09-13 02:50:21 +00:00
WeiCHEN f87a6ee28d feat(workflow): Phase 1 & 2 数据库迁移、项目创建人权威化与多工作流控制面 2026-09-13 02:50:21 +00:00
WeiCHEN adfb45946f docs(workflow): Phase 0 基线确认、架构决策记录(ADR)与契约冻结 2026-09-13 02:50:21 +00:00
WeiCHEN 1fc7d0d01f feat(export): 实现单次智能体回复导出、私密文档保存与隐私防泄露全套闭环 (Phase 0 - Phase 2)
- Phase 0: 实现服务端回复导出策略矩阵引擎 (replyexport.EvaluatePolicy)、数据库迁移 (2026-09-11-message-export-policy.sql)、SSE done 事件挂载与能力探测 API
- Phase 1: 构建前端 ReplyDocumentIR 语法树解析与渲染管道,支持 Markdown / DOCX 文件下载及带格式富文本剪贴板复制
- Phase 2: 实现私密自由文档 (freeform_documents) 领域服务、PostgreSQL 乐观锁版本管理、ACL 隐私隔离、一键共享与右侧栏编辑联动
- 专项修复:
  1. 修复后台 API 路由注册并加入双向拉取同步,确保私密保存实时进入我的私密列表
  2. 实现轻量回复专属 DOCX 生成与静默下载逻辑 (downloadDocxReply)
  3. 将 LaTeX 公式转为标准 MathML 矢量标记,支持粘贴到 Microsoft Word / WPS 自动识别为原生公式
2026-09-13 02:50:21 +00:00
weichen eedf2d17e0 merge: feature/rbac-auth — dynamic RBAC and auth settings 2026-09-13 02:50:20 +00:00
WeiCHEN 3885ef5da2 test(chat): add session turn_intent metadata assertion and chip category navigation tests 2026-09-13 02:50:20 +00:00
weichen ade4723a3a merge: feature/web-features — intent funnel export and templates 2026-09-13 02:50:20 +00:00
WeiCHENandCursor aef1d79060 docs(test): archive auth and dual settings test report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN e8002b2243 feat(category): implement recategorize backfill engine and fallback mapping (Spec §3.4-3.5 A4-A5) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor cd4d0a19e5 test(engine): add integration tests and archive test report for project template cloning
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor b4e4a64cd0 feat(web): integrate auth guards, dual settings and dev switcher
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 7d293833bf feat(chat): 完成分类锚点坞(CategoryDock)与双轨制未读重构 (含方案A轮次归一化与起始位置居中) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor cd08e443eb feat(web): implement dedicated AdminSettingsModal for role-admin
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN aa19926819 fix(nav): 修复点击项目会话时因 URL hash 监听重放导致被强制回弹选中第一个项目的 bug 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 775bf73fb1 feat(web): implement dedicated UserSettingsModal
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 1cfe3f9f02 feat(history): 完成 Phase P3 虚拟滚动、聊天记录导出与协同未读提醒
- 虚拟滚动:接入 @tanstack/react-virtual,封装 useVirtualMessages 动态测高与 overscan 预渲染,迁移 anchorNavigator 锚点定位与 SSR 兼容降级
- 聊天记录导出:基于既有 docx 与 xlsx 依赖实现 chatExporter 与 ChatExportModal,新增服务端 /api/v1/chat/export/messages 支持按条件导出
- 协同未读标记:新增 useUnreadMarks 30s 轮询与服务端 /api/v1/chat/unread 接口,日历格与工具栏支持橙色未读徽标提示
- 测试与验证:新增 chat_unread_and_export_api_test.go,前端全量 126 项单元/组件测试及生产打包 100% 通过
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 793efd31d2 feat(web): add LoginView and FirstLoginPasswordModal components
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 487dc072f5 feat(history): 实现三模历史搜索、每日智能协同摘要与时间轴侧栏 (Phase P2) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 6f1579dde3 feat(web): add frontend auth types and api client
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 54f1c88791 feat(history): 实现多级历史导航、分类筛选、日历联动与消息双向引用 (Phase P1)
- 后端核心与 API:
  - 实现 ChatCategoryStat 结构体与 ListChatCategories 统计引擎 (Postgres + In-Memory 内存降级双轨)
  - 注册 GET /api/v1/chat/categories 聚合接口
  - 增强 GetChatDayMessages 支持自动根据 anchor_id 逆查 day_key,实现免猜测跨日检索
- 前端锚点导航引擎:
  - 实现 anchorNavigator 模块 (快路径 DOM scrollIntoView + 1.8s 发光脉冲、慢路径跨日拉取、深链 Hash 解析)
  - 编写 anchorNavigator.test.ts 单元测试并 100% 通过
- 分类过滤与轻量月历:
  - 实现 CategoryFilterBar 水平分类筛选栏 (8 类业务标签,暗淡/高亮模式)
  - 实现 HistoryCalendar 零依赖原生悬浮月历组件 (热度点与消息数,jumpToDate 快速定位)
- 消息引用与双向追溯:
  - 消息气泡悬浮“引用”入口,点击提取发言人与摘要至输入框
  - 实现 QuoteChip 待发引用标签与 QuoteCard 已发引用卡片
  - 引用卡片点击直连锚点定位,快慢路径自动回溯
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 2047c85ba5 feat(api): add auth and admin management endpoints
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN fb8f57398c feat(history): 实现超长对话历史按日归档与滑动窗口 (Phase P0) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 6c9ad6b61d feat(auth): add auth data models, config and store engine
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 645bd06519 feat(prompt+cache): implement 10-section prompt template, true KB regulation recall, behavior rules and multi-level caching (P4) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor e8ca4b02aa docs(plan): add auth and dual settings implementation plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 1635ad0007 feat(coordinator): implement determinism-first query rewrite with ellipsis completion and pronoun resolution (P3) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 72f54a2461 docs(spec): add auth and dual settings design specification
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 640b672e8b feat(ctxmgr): implement chat memory vectorization, privacy dual-gate retrieval and memory composer (P2) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 9c586f2baf test(rbac): archive dynamic roles and doc visibility rbac test report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN c58d33b853 feat(ctxmgr): implement sliding window, rolling summarizer and DST task state (P1) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor e1c1d03a85 feat(web): wire rbac permission enforcement into left rail and rights modal
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN be659cba11 feat(chat): wire multi-turn dialogue broken links (G1/G2/G3/G9) with session restore 2026-09-13 02:50:20 +00:00
WeiCHENandCursor d905c91338 feat(web): add doc visibility override modal and badges in deck drawer
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN e590dcfd7b docs(design): add multi-turn dialogue optimization system design (report 03) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor b13a03840c feat(web): upgrade settings modal with dynamic roles CRUD and permission matrix
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN e5e80a6fc6 feat(core): update backend coordinator, docgov lease, squad workflow and web governance integration 2026-09-13 02:50:20 +00:00
WeiCHENandCursor bd52108c8a feat(rbac): implement permission evaluation engine and unit test suite
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 658e9db65e fix(web): wire ALL_MOCK_DOCUMENTS and project deliverables to fix document switching 2026-09-13 02:50:20 +00:00
WeiCHENandCursor aa9636c10f feat(rbac): define rbac data contracts and extend deliverable and user types
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 04cdb8f371 feat(scripts): add launch.sh to detect-and-restart dev stack (compose, backend, web) 2026-09-13 02:50:20 +00:00
WeiCHENandCursor b52f72c6fc docs(plan): add dynamic roles and doc visibility rbac implementation plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN b83e3de401 fix(web): render step_failed phase as failed strip node with retry reset 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 16674d476c docs(spec): add dynamic roles and doc visibility rbac design spec
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHEN 7e243f4330 docs(test): archive long-task phase live/resume UX real-agent report 2026-09-13 02:50:20 +00:00
WeiCHEN 096dc8a5b4 fix(web): distinguish recovery action styles for long-task failures 2026-09-13 02:50:20 +00:00
WeiCHEN 8292f69790 feat(web): drive long tasks from SSE with live phases and continue/restart recovery 2026-09-13 02:50:20 +00:00
WeiCHEN 4dd799c785 feat(web): add task SSE client and live phase-event mapper 2026-09-13 02:50:20 +00:00
WeiCHEN 1df0a3f15f test(server): task stream transient injection, classification and resume integration tests 2026-09-13 02:50:20 +00:00
WeiCHEN 912eb61a02 feat(api): task stream request-id, resume mode and workspace-aware error classification 2026-09-13 02:50:20 +00:00
WeiCHEN c83f53a4fa docs(spec): add long-task phase live/resume UX P2 spec and plan 2026-09-13 02:50:20 +00:00
WeiCHEN a6864fe7b4 docs(spec): archive chat wait-error-retry UX spec and implementation plan 2026-09-13 02:50:20 +00:00
WeiCHENandCursor 545765c409 fix(web): escape HTML in chat markdown rendering
Prevent self-XSS when chat bubbles render user/LLM markdown via
dangerouslySetInnerHTML by escaping raw HTML after math/code
extraction and sanitizing link href schemes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor e344a10a0f docs(test): strengthen chat wait-error-retry report with web E2E evidence
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 4eaad5adb8 docs(test): archive chat wait-state error-retry UX real-agent report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor d03d9396e1 fix(web): scope Task 5 App.tsx to SSE wiring only
- Rebased App.tsx on the last clean Task-4 parent (5aa8129) and re-applied
  only Task-5's SSE plumbing: streamAbortRef, isStreamingActive,
  buildNetworkErrorInfo, runStreamAttempt, handleErrorAction,
  handleStopStreaming, and the InputArea/MessageStream wiring.
- Removed the unscoped WIP that had been folded into b2cf863 (NeuroPulse
  demo data/session-privacy/docgov-lease/cardActionPolicy imports that do
  not exist in git, causing b2cf863 to fail to build in isolation).
- Real-backend path now appends the pending placeholder and calls
  runStreamAttempt immediately; the artificial setTimeout(600) is only
  used for the mock keyword-shortcut demo branches (unchanged from 5aa8129),
  gated by precomputed predicates so it never wraps the SSE call.
- Preserved 5aa8129's mock keyword shortcuts (生成文档/驳回/修改/通过等) verbatim.
- No silent success-template fallback re-introduced.
- P1 error actions remain filtered to retry-only; auto-retry transient
  attempts stay capped at 2 with 1s/2s backoff via AbortController.
- Bloated WIP App.tsx backed up to .superpowers/sdd/App.tsx.wip-backup
  for later use by whichever task owns NeuroPulse/session-privacy/docgov
  lease work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 0cb664d540 feat(web): drive chat bubbles from SSE with auto-retry and stop
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 0d0ef5d5b6 feat(web): render chat wait-state and structured error actions in bubbles
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor fa6b979346 fix(web): drop out-of-scope ProjectSession.userId from Task 3
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 9d0a054307 feat(web): add chat SSE client and transient auto-retry helpers
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 7615beeaf9 fix(agent): scope Task 2 to SSE phases/errors without dialogue_llm leak
- untrack internal/coordinator/dialogue_llm.go (kept on disk untracked as local WIP for a future dialogue-LLM commit with its own tests; it depends on engine.go fields (dialogueBackend, ReplySource) not yet committed)
- slim internal/chat/session.go back to Task 2 scope relative to bfa6889: keep EmitErrorInfo(stream.ClassifyError(...)) for intent+coordination errors and the dialogue_generating EmitPhase before ProcessIntent; drop sync.Mutex/mu, ChatResponse.ReplySource, preference/RecentDialogue injection block, and collectRecentDialogue helper (unrelated WIP for the dialogue-LLM feature)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor 1889279b18 feat(agent): emit dialogue phases and classified SSE errors with request id
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor c32532bce9 fix(stream): avoid dial substring false-positive in ClassifyError
Remove "dial" from networkHints to stop "dialogue" misclassification;
extend workspace/resumable and EmitErrorInfo test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor f9b676ac93 feat(stream): add structured ErrorInfo and error classification
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
WeiCHENandCursor e8b9347d8d fix(web): redesign auth and settings UI using system design tokens and high-fidelity styles
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:20 +00:00
weichen 6ccf98e291 merge: feature/web-workbench — three-column workbench MVP 2026-09-13 02:50:19 +00:00
WeiCHENandCursor 4301c034f5 feat(web): wire project isolation and template cloning on project creation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
weichen a779d353b4 merge: feature/backend-platform — KB memory docgov API and chat history 2026-09-13 02:50:19 +00:00
WeiCHENandCursor f00bf14ab4 test(doc): 完善三分类隐私隔离与流转单元测试并归档全量测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 9ca74422c9 feat(web): add template status badges to deck drawer and tab bar
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
weichen cb8a615e0a merge: feature/squad-intent — squad engine intent and adaptive planning 2026-09-13 02:50:19 +00:00
WeiCHENandCursor 8708645f22 docs(test): 归档历史多轮会话持久化与标杆案例语义推荐标准化实测报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 4c2e93fece feat(ui): 实现三分类Tab分段切换、全景大盘分区与一键共享/取消共享闭环
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 3da2324e7c fix(engine): 修复 DOCX 公式因 undefined 虚根在 Word 中丢失的缺陷
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ab31e0e774 docs(report): 补充归档真实Agent全流程业务测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 46b955f30d feat(cli): 终端自推荐标杆案例渲染与全业务链 E2E 端到端回归实操
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 9eb155021b fix(chore): 修正.gitignore根目录data规则并纳入前端mockDocuments
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 258a8dacd2 feat(engine): add project template cloning factory and unit tests
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor a8f0cc9f01 docs(report): 归档智能体小队自适应规划真实后端集成测试报告与设计方案
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2a6dd442bb feat(server): 新增会话列表、多轮历史消息查询与标杆案例语义检索 RESTful API
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor c46f5422b9 feat(types): 升级交付物数据契约支持工作流/共享/私密三分类与创作者属性
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2faddab7ac refactor(types): extend deliverable item with projectId and isTemplateOnly
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor aa968d277b test(chat): 添加基于真实Agent工作区的多轮人机交互E2E测试用例
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor d0c9670ebc feat(coordinator): 在贴身业务参谋决策锦囊中注入相似标杆案例自推荐
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 9480e3fa29 fix(layout): 修复边栏拖拽位移累加并实现1:1光标捕获绝对跟随
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 1e8e7ed3ce docs(plan): add project init template cloning implementation plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor e2ca8ad55a feat(intent): 增强目标市场槽位意图匹配与上下文兼容推断
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor fb8232639b feat(ctxmgr): 增加已批准受控文档自动切片向量化与标杆案例语义检索
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 9c4a839932 feat(ui): 修复模态背景穿透、公式/富文本Markdown解析并集成右键快捷菜单
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 9cebf826ba docs(spec): add project init template cloning design spec
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2597a4555b feat(squad): 优化质量门禁章节规范化匹配与审核专员预置草稿流转
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor db3dc282ba feat(ctxmgr): 增加历史多轮会话列表查询、消息拉取与会话重构引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ff948377bd docs(spec): 归档三层交付物分类治理与多用户隐私/共享设计规范与实施计划
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 580a77d80a docs(test): 补充 Canvas Tainted 缺陷排查与修复验证记录
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 56bbb2f137 feat(squad): 打通成果物基准假设附录挂载、协调层自适应回显与CLI非标文档执行
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor edf2f759ae feat(ctxmgr): 增加离线确定性高维嵌入生成器与向量字面量工具
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 6885c48d48 chore(web): update package-lock.json with tsx
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor c5d53c28fa test(engine): 增加 cleanSvgForCanvas 净化与防污染单元测试
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 337d75f05b docs(rules): enforce real agent execution standard for delivery verification
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 0e49892075 docs(plan): 编制历史多轮对话持久化与标杆案例语义检索实施计划
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ffdb332547 docs(test): add three-column workbench and block document engine test report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 3c147ed7db fix(engine): 修复 Mermaid 导出时的 Canvas Tainted 污染与 toBlob 异常
- 配置 Mermaid flowchart.htmlLabels 为 false,禁用 foreignObject 嵌入式 HTML 标签
- 实现 cleanSvgForCanvas 深度净化 SVG,剥离 @import 与将 foreignObject 转为原生 SVG <text>
- 替换异步 toBlob/FileReader 为同步 toDataURL + atob,并在 img.onload 中增加安全沙箱 try/catch 兜底

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor f75e5094a2 feat(squad): 实现单步评估器StepEvaluator与工作流动态加步、跳步及基准假设推断
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 10e01a2481 docs(spec): 编写历史多轮对话持久化与已批准交付物标杆案例语义检索设计规范
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 996f4a79df feat(server): integrate web spa static assets hosting and route fallback
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 980d0f9a2d docs(test): 归档 DOCX 原生公式、Mermaid 与排版优化测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 62ebaf49d4 feat(squad): 实现自适应任务规划器AdaptivePlanner支持固定流微调与非标文档自治拆解
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 804c7bd128 docs(test): 归档全业务链成熟度端到端贯通与受控文档治理实操测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 47d4f7cf8b feat(web): complete in-place block editing, reviewer comments, and role governance loop
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 808d706180 test(engine): 增加 DOCX 行内 OMML 复合解析与公式转换单元测试
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor f1d602b089 feat(squad): 实现角色资产中心RoleRegistry支持8大标准角色与临时专员派生
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 4be8be277f test(bizdev): 新增全业务链成熟度螺旋推进(V0.1->V0.5->V1.0)端到端贯通测试
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2cb8d9b8d2 feat(web): implement 36px slim tabs, deck drawer, and block views with medical styling
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 80383269e9 feat(engine): 实现 DOCX 原生 OMML 数学公式、Mermaid 高清渲染与出版级公文排版
- 集成 mathml2omml 与 KaTeX,实现展示级公式 (<m:oMathPara>) 与行内公式 (<m:oMath>) 的微软原生矢量公式渲染
- 实现 svgToPngData 将 Mermaid 矢量图光栅化为 2.5x 视网膜清晰度的 PNG 图片嵌入 Word
- 重构公文抬头、4列受控签署栏、出版级三线表、keepNext 防孤行与带分割线的受控页眉页脚

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 912ae4f782 feat(squad): 增强领域核心模型支持角色来源、自适应步骤与黑板基准假设
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor c68c0026d9 feat(cli): 升级 bizdev-cli 阶段执行器支持流式进度与文档治理拦截
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ef6665288c feat(web): implement agent chat stream with thinking pulse indicator and case cards
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 26c94d1107 fix(cli): adapt default stage by role and add scanner error checking
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor f9dcd51831 docs(test): establish test report standards and generate three-branch intent framework report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 429179e472 feat(bizdev): 贯通跨阶段事实黑板自动传承与里程碑决策记录
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor deee4dcee1 feat(web): implement responsive three-column shell with resizable rails and theme switch
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor a02d4de7d2 docs(test): archive test report for dialogue-driven content and hierarchical intent system
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor eedda67aad feat(cli): add three-branch interaction feedback and comprehensive verification test cases
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor c290f3104b feat(ctxmgr): 支持跨阶段项目事实黑板与成熟度状态持久化
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2b9678a496 feat(web): implement markdown block ast converters and auto-numbering engine
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor d4ddd61443 feat(web): integrate interactive cards into chat stream and wire docgov actions
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ae9d2f1fea docs(test): archive 2026-09-08 HTTP API and SSE context integration test report
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 75b7c1c3d1 feat(web): define block ast, workbench session, and docgov types
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 656a19cbe2 fix(web): add 60s grace period undo, executing banner and ttl safeguards to interactive card
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 44ebafd946 test(api): add e2e integration tests for claimed document SSE and docgov RESTful APIs
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 36afce14e6 feat(web): initialize react 19 vite typescript scaffold and token design system
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 77d854e343 feat(web): build interactive card component with lifecycle and idempotency
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2815381613 feat(api): add RESTful endpoints and SSE streams for context and docgov lifecycle
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ff0262c182 docs(plan): add three-column modern workbench and block document engine implementation plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 6493ffd3ce fix(coordinator): chain expectation for card confirmation and add ttl lifecycle cleanup
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2c05c5d3cb feat(service): emit governance interception and progress summary on claimed documents
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor b407fe534b docs(spec): refine right rail with 36px slim tabs and deck panel drawer
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 1af5a9e909 docs(test): 归档 DOCX/XLSX 导出与会话隔离持久化测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 8b942d0460 feat(stream): add governance event and lightweight progress summary protocol
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor fa9eb31d2b docs(spec): add three-column modern workbench and block document engine specification
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ff1eaab820 test(workbench): 增加 DOCX/XLSX 导出与会话隔离单元测试
- 验证 DOCX 二进制 Buffer 生成、TextRun 解析与 Blob 输出
- 验证 XLSX 多表提取、自适应列宽与工作簿 Sheet 命名规范
- 验证 sess-001 与 sess-002 对话隔离及动态追加互不串线

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor dba93f8bc2 test(docgov): 增加编制审核批准全流程自动化测试与测试报告归档
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 2fcf02200e feat(ui): 顶栏综合导出下拉选择器与 App 消息隔离及存储打通
- SlimTabBar: 增加导出格式气泡下拉菜单,支持一键导出 Word DOCX、Excel XLSX、Markdown MD
- App: MessageStream 严格根据 activeSessionId 过滤消息流,杜绝多项目会话串线
- App: 新建项目自动注入独立引导语,全流程与 storage 自动双向同步

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor d883836075 feat(agent): 将文档治理生命周期与认领拦截挂钩至BizDev服务与CLI工具链
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor ece051d456 feat(storage): 实现多项目会话隔离与 localStorage 全局刷新持久化
- 预设 sess-001 (4K内窥镜) 与 sess-002 (掌上超声) 独立初始消息流
- safeGetItem/safeSetItem 包装器防御性存取 sessions, activeSessionId, messages, deliverables
- 确保页面刷新后用户发送的所有内容、回复及即时生成的私密文档零丢失

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 4b00a98d4f feat(service): 实现文档编制审核批准生命周期、权限控制与认领闭环引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor fefb53ef30 feat(engine): 实现 DOCX 与 XLSX 客户端原生渲染导出引擎
- 引入 docx 与 xlsx 依赖,纯前端无损编译 Block AST 交付物
- buildDocxModel: 自动生成两行四列受控签署栏、多级编号标题、Markdown富文本、医疗标准三线表、Cambria Math公式与动态页眉页脚
- buildXlsxWorkbook: 自动提取文档概览与全部数据表格,生成带自适应列宽的 Excel 工作簿并支持直接下载

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 6c875ffbeb feat(db): 增加受控文档编制审核批准生命周期与认领治理Schema
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 1a1875bc8c feat(coordinator): implement docgov gates, semantic anchoring and interactive card dispatch
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 6cd9bbe67e docs(test): 归档多级上下文管理与记忆衰减引擎真实Agent实测报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 12aad70a28 feat(ui): 升级顶栏为极简级联面包屑架构,自适应 320px 极窄视窗
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 224a2f8f9d feat(agent): 增强上下文沙箱指引、搜索过滤与CLI用户ID上下文透传
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 00e7d4db1e fix(intent): address review findings for hierarchical intent funnel and security guards
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 6ea93e5e82 feat(agent): 实现混合上下文装配引擎(Context Blender)与智能体小队沙箱对接
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 85e5c31034 feat(intent): implement 4-stage hierarchical intent funnel and slot extraction
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 96be8fdd94 feat(service): 实现单用户/项目多级上下文模型、时间衰减与用户习惯偏好管理
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 9e84ba71e3 fix(doc): 完善文档系统各层级标题、图表公式与有序列表自动编号引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 4de6c12721 feat(storage): 实现CAS物理文件寻址与向量切片防爆炸去重引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor f6e4edcb08 feat(intent): add interactive card payload and extended intent contracts
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor f769f8da4c feat(db): 部署专属记忆与多级上下文数据库容器与pgvector初始化Schema
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 3a3347e627 docs(plan): add implementation plan for dialogue-driven content synthesis and hierarchical intent funnel
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 07a5e999b8 docs(test): 归档流式传输服务与按需呈现交互规范测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 24e577f50c docs(spec): add specification for dialogue-driven content synthesis and hierarchical intent funnel
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 500884a19b test(api): 补充SSE流式长连接端到端自动化测试套件
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 75494cbd75 feat(cli): 终端支持动态阶段状态流式输出与低认知负荷摘要呈现
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 810eb26be3 feat(api): 实现HTTP服务骨架与Server-Sent Events流式交互接口
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 0f01f047d5 feat(agent): 在小队编排与任务生命周期中打通阶段性状态与摘要流式通知
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 1bdea54022 feat(service): 建立多层级流式事件发射模型与Context穿透引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 68d9c65317 docs(test): 归档多领域知识中枢与专属法规知识库解耦集成测试报告
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 3e341fbb1b feat(agent): 配置法规可行性评估报告专属三阶段智能体工作流
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 1b7ce098b6 feat(agent): 智能体小队工作区动态法规检索与上下文注入
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 7cbfb33150 feat(service): 实现嵌入式多领域知识中枢与Hybrid RRF检索引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
WeiCHENandCursor 7d123ae8c6 feat(db): 启动本项目专属知识库容器并完成法规数据无损迁移与解耦
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:19 +00:00
weichen 29e00db0d9 merge: feature/agent-infra — pi-agent Tavily and docker 2026-09-13 02:50:18 +00:00
WeiCHENandCursor 97c8a7629c feat(chat): integrate non-blocking pending expectation and topic preemption in session
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
weichen 6e4c8e319b merge: feature/bizdev-core — bizdev MVP stack 2026-09-13 02:50:18 +00:00
WeiCHENandCursor 4c35888a4e feat(agent): ensure clean container and isolate workspace artifacts strictly to host volume
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 6d44412719 feat(coordinator): refactor advisor persona and assemble next expectation drafts
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
weichen 085da29859 merge: feature/foundation — repo scaffold and env baseline 2026-09-13 02:50:18 +00:00
WeiCHENandCursor 713ff94ff8 feat(cli): add bizdev-cli runner tool and integration tests
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 3ffcab4502 docs(env): update environment configuration template with MiniMax and Tavily pool
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor db46ac7388 feat(intent): implement three-branch flexible intent resolution and expectation contracts
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
weichen 024af3e66b chore: history rewrite root anchor 2026-09-13 02:50:18 +00:00
WeiCHENandCursor 68d58df38f chore(config): initialize go module and configuration loader
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor c65f5e8a3d fix(service): populate Excel pricing cells and verify attachment readback parity
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 34fcbe6ff3 chore(docker): integrate pi-agent service in dev, test, and main compose files
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 105b3f4103 feat(coordinator): 增强工作区阶段元数据持久化与上下文自动关联
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 0832d7caa9 docs(plan): add bizdev squad and templates implementation plan
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 59cca0594e fix(service): backfill CDO quote markdown table from excel summary and align workspace
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor aad4a0daee test(agent): add Tavily pool rotation and PiAgent remote runner tests
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 52c36e6a87 feat(cli): CLI支持-chat交互式对话REPL与单次自然语言指令调度
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 7838ae804d chore(config): add .env.example with cursor, pi-agent, and kb variables
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 77c17b7bc0 feat(service): implement bizdev service with independent task drivers
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor b36a9ee108 feat(agent): support PI_AGENT_RUNNER_URL remote execution in PiAgentBackend
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 82bfe41d1f feat(chat): 封装L1会话管理器打通自然语言多轮人机交互闭环
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 6eebe2872a docs(spec): add business docking squad and templates design spec
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor d54ba6ea77 chore(tools): add package.json for cursor-bridge and pi-bridge
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 61f9b6edb4 feat(agent): add pi-agent container assets with dynamic MiniMax config and HTTP runner
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor b8439a89e9 feat(coordinator): 实现L2统一上下文组装器与意图校验调度引擎
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 57b8db2fcc chore(rules): 配置 Cursor 持久化规则以约束三分支模型与环境隔离规范
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 6ee1c5b6c7 feat(agent): implement cursor-cli, pi-agent, and stub backend adapters
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor b78c9f5071 feat(agent): add Tavily search extension with API key pool and auto-rotation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 2414bd4742 feat(intent): 定义核心意图契约并实现基于上下文约束的规则意图识别器
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor aeab5c3c40 feat(scripts): 增加多环境一键启停管理与分支工作流辅助脚本
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 9bcf458529 feat(quote): implement CDO quote Excel calculation and fill engine
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 1208c74030 fix(agent): pass absolute workDir and parse bridge JSON response
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 733fb8dae5 docs(system): 纳管系统架构设计与演进规划文档
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 5d2389b2c3 feat(env): 增加开发/测试/主分支三套独立服务与共享知识库编排及配置
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor a3b58f09ac feat(template): add self-describing templates and agent personas
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 260e1a6b8a fix(all): resolve whole-branch review findings on Excel labels, persona forwarding, and error handling
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 288dbeffdf feat(cli): CLI支持成熟度阶段执行与业务参谋锦囊可视化
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 203297056d feat(db): 增加共享知识库与隔离系统数据库初始化脚本
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 9f5bd762a8 feat(kb): add regulation knowledge base client with snapshot materialization
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 6ea0043b49 feat(bizdev): 实现成熟度三阶段编排与AdvisorBriefing双轨交付
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHEN ee18e5436e docs(ops): 建立仓库基础架构、三分支规范与环境运行文档 2026-09-13 02:50:18 +00:00
WeiCHENandCursor 32beee0b75 feat(squad): 修复stub字段覆盖并增强质量门禁闭环与锚点提取
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor f1227d9a8a test(squad): add comprehensive tests for workspace, context, workflow, quality gate, and cli
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 0f43102f84 feat(cli): upgrade bizdev-cli with dynamic inspection, step manipulation, and manifest display
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 3c2d0ca94e feat(service): integrate squad service and ports into bizdev domain service
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 434ce844f8 feat(quality): implement 3-tier quality gate, manifest auditing, and quote backfill
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 4474d575da feat(workflow): implement dynamic workflow driver with sub-workspace isolation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor f84a12acae feat(context): implement self-describing context system with authority guide
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
WeiCHENandCursor 6bbbb16a1c feat(squad): define workspace directory metadata models and engine
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:18 +00:00
539 changed files with 91931 additions and 1565 deletions
@@ -0,0 +1,25 @@
# ADR:文档 Version / Revision 边界与决策门
## 状态
已接受(2026-09-13,用户确认 DOCREV 整改实施计划)
## 背景
受控文档此前只有当前 `output.md` 与 SHA,无法表达「智能体基线 + 后续人工修改」的业务版本语义;自由文档每次保存 +1 的 `current_version_id` 与本需求冲突。
## 决策
1. **版本边界**:模板或一次成功提交的智能体/智能体小队产物开启 `Version`;人工每次服务端成功保存只增加该 Version 内的 `Revision`,不增加面向用户的版本号。
2. **high/critical 候选**:风险达到 `high` 或 `critical` 的 agent candidate,必须经编制负责人二次确认后才能 `CommitAgentVersion`。
3. **首发范围**:Wave 1–5 仅覆盖受控文档;自由文档统一读模型与 UI 语义切换放在 Wave 6。
4. **根表指针列**:统一 `ledger_*` / `head_*` 前缀;禁止与 `freeform_documents.current_version_id`(00008 每-save+1 legacy)同名承载新语义;旧列迁移时改名为 `legacy_version_id`。
5. **Goose**:从 **00028** 起递增;不得硬占用并行分支可能冲突的旧号。
6. **保留策略**:受控文档随项目/法规保留;自由文档默认 365 天可配置,禁止静默硬删。
7. **发布 blocker**:方案评审与 Wave 落地阶段不擅自写入 gap-matrix;纳入发布范围后再新增行。
## 后果
- 实施必须按 Wave 0→6 顺序;禁止先上前端颜色标记再补快照事实源。
- `document_records.version` / `content_sha256` 在兼容期由 ledger 同事务投影,稳定后退役。
- 详细表结构、API、状态机见 [../system-design/document-revision-management.md](../system-design/document-revision-management.md)。
@@ -0,0 +1,29 @@
# ADR:模块化单体解耦——契约通信、单一写者、编排下沉
## 状态
已接受(2026-09-14;Wave 0 契约骨架与 arch-check warn 基线已落地,未占集成槽)
## 背景
多轮审计与实测表明:一处修改波及多处的根因不是模块数量不足,而是——
`internal/server`(17k 行)同时是组合根、跨模块闭包事件总线、编排载体与文件系统/SSE 细节持有者;`internal/bizdev` 是第二组合根(依赖 16 个内部包);`UserProjectContext` 被 chat/coordinator 双向直改;`document_records` 有 5 个写者;工作区路径与 squad 文件 schema 是无版本化的隐性公共契约;`intent→bizdev` 反向依赖。
证据与完整诊断见 [../system-design/2026-09-14-module-decoupling-architecture.md](../system-design/2026-09-14-module-decoupling-architecture.md) §1。
## 决策
1. **架构形态**:维持模块化单体(不做微服务拆分),新增 `internal/contracts` 作为跨模块接口/DTO/事件/共享枚举的唯一 SSOT;模块间仅允许「调 contracts 接口」与「发布/订阅 contracts 事件」两种通信。
2. **单一写者**:每张表、每类文件唯一属主(docgov 独占 `document_records`;chatlog 独占 chat_* 表;workspace 独占工作区路径);跨模块写走属主端口方法。
3. **编排下沉**:跨模块流程收敛到应用编排层(chatflow/stageflow/docflow,拆自 bizdev/coordinator/chat);HTTP handler 只做参数→服务→DTO 三行式。
4. **组合根唯一**:wiring 迁 `internal/app`;`server.NewServer` 只剩 HTTP 装配;SSE 帧协议下沉 `internal/stream/transport`。
5. **squadrun 契约**:系统备好工作区与 `InputBundle`,小队按 `OutputContract` 交货并写 `RunManifest`(SchemaVer=1);外部禁止直读/覆写工作区内部文件。
6. **机器门禁**:`scripts/arch-check.sh` + `module-boundaries.yaml`(import allowlist / 表属主 / 路径字面量属主),warn 两周后 block 进 CI 与集成槽位冒烟。
7. **兼容承诺**:HTTP URL 与响应结构在 Wave 1–5 不变;**零表结构迁移**;旧路径设一版兼容期后删除。
8. **实施顺序**:Wave 0 立规矩 → 1 止血 → 2 读路径 API 化 → 3 小队契约化 → 4 单写者 → 5 编排事件化(可拆 5a/5b)→ 6 传输收口;每 Wave 独立分支、独立回滚,遵守 AGENTS.md §6 mutex/槽位纪律,避开在途认领。
## 后果
- 新增包:contracts / app / chatlog / contextasm / docquery / squadrun(squad 换壳);
- `internal/bizdev` 与 `internal/ctxmgr` 将被拆解退役(知识迁移到 use case 与两个子包);
- 所有后续新能力(含软件项目自举)必须基于新边界实现,禁止再挂 bizdev 门面;
- 任何契约(contracts 中已发布的 DTO/事件/文件 schema)变更须走 ADR。
@@ -0,0 +1,54 @@
---
title: "刷新后对话正文消失问题定位与整改方案"
status: done
created: 2026-09-13
updated: 2026-09-13
owner: codex
branch: dev
worktree: "-"
mutex: chat
---
# 刷新后对话正文消失问题定位与整改方案
## 目标
定位页面刷新后对话正文不显示、但锚点与过滤计数仍存在的根因,并形成可执行、可验证的整改方案。
## 范围
- 前端对话状态、会话恢复、消息窗口、锚点与类别过滤的数据来源
- 后端会话/消息持久化与历史读取 API
- 当前 dev 运行态的只读接口与数据一致性验证
- 审计记录、整改方案与验收标准
## 非目标
- 本轮不修改业务代码
- 不执行破坏性数据修复
- 不把 stub 或仅内存态结果作为最终验收
## 步骤
1. [x] 复核刷新前后前端状态初始化和会话选择链路
2. [x] 核对历史消息 API、存储字段及运行态返回
3. [x] 解释正文、锚点和过滤计数数据源为何分叉
4. [x] 输出 audit 与 remediation 文档并回链
## 验收标准
- [x] 根因有源码、接口或运行态证据支撑
- [x] 明确影响范围、触发条件与风险等级
- [x] 整改方案覆盖实现、回归测试、数据兼容和验收
## 相关链接
- Checklist: 待整改实施时建立
- Handoff: [chat-history-refresh-diagnosis](../../ops/handoffs/2026-09-13-chat-history-refresh-diagnosis.md)
- Test report: 待整改实施并验收后建立
## 证据 / 备注
- 用户实测:新对话能正常生成文档;刷新后历史对话正文消失,但右侧锚点与顶部过滤仍显示对应消息数量。
- Audit: [../../audit/2026-09-13-chat-history-refresh-disappears.md](../../audit/2026-09-13-chat-history-refresh-disappears.md)
- Remediation: [../../remediation/2026-09-13-chat-history-refresh-remediation.md](../../remediation/2026-09-13-chat-history-refresh-remediation.md)
@@ -0,0 +1,47 @@
---
title: "当前受控文档指示语优先于领域关键词路由"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-active-doc-routing
worktree: "-"
mutex: docgov
---
# 当前受控文档指示语优先于领域关键词路由
## 目标
用户说「当前受控文档/当前文档/本文件/这份文档」且已选中服务端注册的 `doc_proj*` 时,任务 payload 为该文档 `taskKey`+`docId`;UI-05 提示须为 `intake` + `doc_proj6109_intake`。
## 范围
- `web/src/engine/templateMatch.ts` + App 发送/重试链
- 单测与边界;服务端 mismatch 复核(不信任客户端 doc_id 改 task)
- 文档:audit / gap-matrix / CURRENT
## 非目标
- 不改弱 E2E UI-05 断言;不操作容器;不触碰/提交 test-report assets
- 生产 `templateMatch.ts` 不导出用例编号/E2E 专属提示词;测试提示词留在 test 文件
## 步骤
1. [x] 认领 CURRENT;写 audit/short-term
2. [x] 指示语钉住 active 受控文档;显式点名可切换;只读不启动;模板槽不钉
3. [x] App 传入 activeDoc;payload 用一致 taskKey/docId
4. [x] 单测 + 门禁 + 原子提交
## 验收标准
- [x] UI-05 原文 + active intake → `intake` / `doc_proj6109_intake`
- [x] 只读「查看当前受控文档」不启动任务
- [x] 显式点名另一交付物可切换;模板-only 不钉住
- [x] 服务端 task_key 与已注册 doc 不一致仍拒绝
- [x] `go vet` / `go test -short` / web 242+27 / build / `git diff --check`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-active-doc-routing.md](../../audit/2026-09-13-document-revision-active-doc-routing.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05-active-doc-routing-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05-active-doc-routing-failure)
@@ -0,0 +1,55 @@
---
title: "职责单元格精确断言"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-duty-cell-assertion
worktree: "-"
mutex: document-revision-duty-cell-assertion
---
# 职责单元格精确断言
## 目标
堵住第16轮 UI-13a:权限矩阵已打开,整行 `innerText` 含全部 select option,误命中「编制负责人」。改为读控件 value/badge,且 USER_B 必须精确 `reviewer`,不得接受 viewer 降级。
## 范围
- `web/src/lib/dutyCellAssertion.ts` 与单测
- `UserProjectRightsModal` 职责控件可访问语义
- `web/e2e/document-revision-runtime.spec.ts` UI-13a
- audit / remediation / CURRENT
## 非目标
- 不放宽 reviewer 只读;不删双击/无编辑提示检查
- 不碰证据;不合 dest;不启停容器;不 E2E;不 push
## 步骤
1. [x] 从 `dev@dd5671e` 开分支并登记 mutex
2. [x] 精确角色解析 + option 文案不得误判测试
3. [x] 产品控件 data-* + UI-13a 接线
4. [x] `npm test` + `npm run build` 并原子提交
5. [x] 独立审查收紧:只接受 reviewer;viewer 与 canAssignLead=true 拒绝
## 验收标准
- [x] select/badge 必须精确 `reviewer`;viewer/author/approver 拒绝
- [x] 整行 option 文案不得推断职责
- [x] select 必须不可配置且 disabled
- [ ] 现场 UI-13a(未跑)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-duty-cell-assertion.md](../../audit/2026-09-13-document-revision-duty-cell-assertion.md)
- Remediation: [../../remediation/2026-09-13-document-revision-duty-cell-assertion.md](../../remediation/2026-09-13-document-revision-duty-cell-assertion.md)
## 证据 / 备注
- mutex:`document-revision-duty-cell-assertion`(新 mutex)
- 基线:`dev@dd5671e`
- 验证(收紧后):`npx tsx --test src/lib/dutyCellAssertion.test.ts` PASS(6);`cd web && npm test` PASS;`npm run build` PASS
- **未跑真实 UI-13a,不得标 done**;**不得 merge / 启停容器 / E2E / push**
@@ -0,0 +1,51 @@
---
title: "E2E:给真实文档块加稳定寻址并修正 UI-06/13b"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-e2e-block-selector
worktree: "-"
mutex: document-revision-block-selector
---
# E2E:给真实文档块加稳定寻址并修正 UI-06/13b
## 目标
第六轮 UI-06 首错:`pure` 模式下块 wrapper 无 `data-overlay-kind`、正文也不是 `p`/`h1`。为每个真实 `DocumentBlock` wrapper 增加与 overlay 无关的稳定 DOM 标识;E2E 只在 `active-document-pane` 内定位该标识。不改视觉/权限/双击行为。不得将本任务标 `done`。
## 范围
- `web/src/lib/documentBlockDom.ts` + 契约单测
- `web/src/components/doc/BlockRenderer.tsx`
- `web/e2e/document-revision-runtime.spec.ts`(`openFirstPaneEditorAndFill`;UI-06/13b 复用,UI-13a 同步)
- 文档:audit / CURRENT
## 非目标
- 不改编辑/权限/overlay 视觉
- 不降低已有断言;不伪造、不直接打 API
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX
## 步骤
1. [x] 认领 CURRENT(mutex `document-revision-block-selector`);前序 reject-routing 保持 in_progress
2. [x] 真实块 wrapper 增加 `data-testid=document-block` + block id
3. [x] E2E 仅在 active pane 内按该标识双击
4. [x] 契约单测:pure 模式也有块标识,且不依赖 `data-overlay-kind`
5. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] 块标识与 overlay 无关;带 block id
- [x] `openFirstPaneEditorAndFill` 不使用 overlay/`p`/`h1`/`h2`
- [x] web tests + `tsc`/build + `git diff --check`
- [ ] 真实 UI-06/13b PASS 后才可将本任务标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-block-selector.md](../../audit/2026-09-13-document-revision-block-selector.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-block-selector-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-block-selector-failure)
- 前序: [2026-09-13-document-revision-e2e-reject-routing.md](./2026-09-13-document-revision-e2e-reject-routing.md)
@@ -0,0 +1,51 @@
---
title: "E2E:纯净阅读按 document-block 取样 overlay"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-e2e-overlay-selector
worktree: "-"
mutex: document-revision-overlay-selector
---
# E2E:纯净阅读按 document-block 取样 overlay
## 目标
第八轮 UI-07 首错:pure 模式用 `[data-overlay-kind],[class*=block]` 找不到真实块。在 `active-document-pane` 内对全部 `document-block` 取样真实样式/hunk;manual/all 不保证两两不同。不得将本任务标 `done`。
## 范围
- `web/e2e/document-revision-runtime.spec.ts`(UI-07 取样;UI-10 历史自动关闭;UI-16 text 选择器)
- `web/src/features/documentRevision/overlayMode.test.ts`(同一 human hunk 不保证 pairwise)
- 文档:audit / CURRENT
## 非目标
- 不新建 policy 抽象;不改 overlay 视觉/业务
- 不人为换块制造 manual≠all
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX
## 步骤
1. [x] 认领 CURRENT(mutex `document-revision-overlay-selector`)
2. [x] UI-07 在 pane `document-block` 上取样
3. [x] 按 checklist 校正三模式断言
4. [x] UI-10 按抽屉自动关闭比较
5. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] 禁止 `[class*=block]` / 全页 overlay 取样
- [x] 纯净阅读必须无装饰;人工/全部必须有真实 hunk 装饰
- [x] web tests + `tsc`/build + `git diff --check`
- [ ] 真实 UI-07/08/09 PASS 后才可将本任务标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-overlay-selector.md](../../audit/2026-09-13-document-revision-overlay-selector.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui07-pure-selector-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui07-pure-selector-failure)
- Checklist: [../checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](checklists/2026-09-13-document-revision-runtime-ui-acceptance.md)
- 前序: [2026-09-13-document-revision-e2e-save-selector.md](./2026-09-13-document-revision-e2e-save-selector.md)
@@ -0,0 +1,46 @@
---
title: "E2E:等 overlay CSS transition 结束后再取样"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-e2e-overlay-transition
worktree: "-"
mutex: document-revision-overlay-transition
---
# E2E:等 overlay CSS transition 结束后再取样
## 目标
第九轮 UI-07 首错:`data-overlay-kind` 已空,但采样落在 200ms transition 中间帧。用 Playwright 轮询 computed style 直到稳定且达到无装饰目标后再取样。不得将本任务标 `done`。
## 范围
- `web/e2e/document-revision-runtime.spec.ts`(pure/manual/all 均等样式 settle)
- 文档:audit / CURRENT
## 非目标
- 不禁用产品 `transition`;不固定极短 sleep;不放宽纯净无装饰断言
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX;不合 `dev`
## 步骤
1. [x] 认领 CURRENT(mutex `document-revision-overlay-transition`)
2. [x] `expect.poll` 连续两帧相同且达到 mode 目标后再采样
3. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] 纯净阅读仍要求透明底 + `box-shadow:none` + 无 overlay-kind
- [x] manual/all 也等 transition 完成
- [x] web tests + `tsc`/build + `git diff --check` + Go 门禁
- [ ] 真实 UI-07/08/09 PASS 后才可将本任务标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-overlay-transition.md](../../audit/2026-09-13-document-revision-overlay-transition.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui07-css-transition-sampling-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui07-css-transition-sampling-failure)
- 前序: [2026-09-13-document-revision-e2e-overlay-selector.md](./2026-09-13-document-revision-e2e-overlay-selector.md)
@@ -0,0 +1,49 @@
---
title: "E2E:待确认报告必须真实打开再确认/拒绝"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-e2e-pending-flow
worktree: "-"
mutex: pending-report-ui
---
# E2E:待确认报告必须真实打开再确认/拒绝
## 目标
第四轮 UI-05a 首错修复:验收脚本按真实用户路径关闭首轮报告、打开「待确认报告」,在面板内断言 high(critical 允许)与 pending 动作后再确认/拒绝。不改产品业务逻辑。
## 范围
- `web/e2e/document-revision-runtime.spec.ts` UI-04 / UI-05a / UI-05b
- 文档:audit / CURRENT 认领(mutex `pending-report-ui`;与 reject-routing 的 `document-revision-runtime-ui` 分开,避免虚报 done)
## 非目标
- 不改 `ChangeReportPanel` / Toolbar / decision API
- 不降低已有业务断言或超时;不伪造、不直接打 API
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX
## 步骤
1. [x] 认领 CURRENT;写 audit/short-term
2. [x] UI-04 用弹窗内「关闭」并断言 dialog 消失
3. [x] UI-05a 点击「待确认报告」,断言 risk/pending-actions/确认提交后确认
4. [x] UI-05b 新 pending 后同样打开面板,断言 pending-actions/拒绝后再拒绝
5. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] UI-04 不再使用无效 Escape
- [x] UI-05a/05b 不靠全局 count 代替打开待确认报告
- [x] web tests + `tsc`/build + `git diff --check`
- [ ] 真实 UI-05a/05b PASS 后才可将本任务标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-pending-report-selection.md](../../audit/2026-09-13-document-revision-pending-report-selection.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05a-pending-report-selection-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05a-pending-report-selection-failure)
- Checklist: [../checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](checklists/2026-09-13-document-revision-runtime-ui-acceptance.md)
@@ -0,0 +1,62 @@
---
title: "E2E:UI-05b 钉住 intake 并收紧 UI-10/12/13/14"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-e2e-reject-routing
worktree: "-"
mutex: document-revision-runtime-ui
---
# E2E:UI-05b 钉住 intake 并收紧 UI-10/12/13/14
## 目标
第五轮 UI-05b 首错修复:拒绝用例 prompt 必须带「当前受控文档《用户初始需求收集表》」,并在本轮 `POST /tasks/runs` 上严格断言 `task_key==='intake'` 且 `doc_id===controlledDocId`。同步收紧 UI-10/12/13/14 真实用户路径。本轮追加产品修复:权威文档职责 + 打开时基线 ETag。
## 范围
- `internal/docgov/project_docs.go`(summary 职责投影)
- `web/src` 职责字段、`resolveCurrentDocRole`、hydrate/PATCH ETag
- `web/e2e/document-revision-runtime.spec.ts`(UI-13b 真实竞争)
- 文档:audit / remediation / CURRENT(mutex `document-revision-runtime-ui`)
## 非目标
- 不降低已有业务断言或超时;不伪造、不直接打 API
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX
## 步骤
1. [x] 认领 CURRENT;前序 pending-flow 保持 in_progress,mutex 改为 `pending-report-ui`(仅 UI-05a 实战 PASS,UI-05b 尚未拒绝,不得虚报 done)
2. [x] UI-05b prompt + tasks/runs 契约断言 + 真实打开拒绝
3. [x] UI-10 历史 dialog 内选 A/B 比较并关闭;UI-12 项目不可见;UI-13 拆成审核人只读 + 双 A 冲突;UI-14 同时锁 v/r
4. [x] 仅修 05a/05b/10 遗留弹窗对 UI-06 的确切遮挡
5. [x] 产品修复:权威职责 + viewer fail-closed + hydrate 基线 ETag
6. [x] UI-13b:A1 保存前 A2 编辑器已打开并填入文本;两窗口同一 r/etag
7. [x] 审查补强:controlled 缺 ETag fail-closed;viewer 只读批注;服务端零 id 不按 name 提权
8. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] UI-05b 发送前等待 POST `/api/v1/tasks/runs`,`task_key`/`doc_id` 不符即 FAIL
- [x] UI-10 不点全局工具条「比较」
- [x] UI-12 不接受「项目可见但只查 marker」
- [x] UI-13a/13b 结果分别记录;B 不作正文编辑者
- [x] B/陌生人不会变 author;A 仍 author(Go + 前端单测)
- [x] stale hydrate ETag 用于 PATCH(不能用最新 ETag 掩盖冲突)
- [x] controlled 缺打开时 ETag 不得 PATCH 0:0;hydrate 5xx 进加载失败屏障
- [x] viewer 无新增批注入口
- [x] 服务端受控 duty id=0 不按 name 提权
- [x] web tests + `tsc`/build + `git diff --check`
- [ ] 真实 UI-05b+ 后段及 UI-13a/13b PASS 后才可将本任务标 `done`
## 相关链接
- Audit (05b 路由): [../../audit/2026-09-13-document-revision-e2e-reject-routing.md](../../audit/2026-09-13-document-revision-e2e-reject-routing.md)
- Audit (职责/ETag): [../../audit/2026-09-13-document-revision-duty-etag-overwrite.md](../../audit/2026-09-13-document-revision-duty-etag-overwrite.md)
- Remediation: [../../remediation/2026-09-13-document-revision-duty-etag-overwrite.md](../../remediation/2026-09-13-document-revision-duty-etag-overwrite.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05b-reject-routing-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05b-reject-routing-failure)
- 前序: [2026-09-13-document-revision-e2e-pending-flow.md](./2026-09-13-document-revision-e2e-pending-flow.md)
@@ -0,0 +1,51 @@
---
title: "E2E:块编辑 dialog 内精确保存"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-e2e-save-selector
worktree: "-"
mutex: document-revision-save-selector
---
# E2E:块编辑 dialog 内精确保存
## 目标
第七轮 UI-06 首错:双击已打开编辑器,但全页模糊「保存」点到聊天私密库按钮,未 PATCH。给 `BlockEditorModal` 可访问 dialog + 稳定 aria-label;保存只在该 dialog 内 `exact: true` 点「保存修改」。不得将本任务标 `done`。
## 范围
- `web/src/lib/blockEditorDialog.ts` + 契约单测
- `web/src/components/doc/BlockEditorModal.tsx`
- `web/e2e/document-revision-runtime.spec.ts`(UI-06/13b 复用;UI-13a dialog=0)
- 文档:audit / CURRENT
## 非目标
- 不改视觉/保存业务
- 不降低已有断言
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX
## 步骤
1. [x] 认领 CURRENT(mutex `document-revision-save-selector`)
2. [x] dialog `role` + `aria-label=编辑受控块`
3. [x] E2E 在 dialog 内精确点「保存修改」
4. [x] UI-13a 断言编辑 dialog 不出现
5. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] 契约单测钉住 dialog label 与 exact 保存文案
- [x] 禁止全页 `/保存/`
- [x] web tests + `tsc`/build + `git diff --check`
- [ ] 真实 UI-06/13b PASS 后才可将本任务标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-save-selector.md](../../audit/2026-09-13-document-revision-save-selector.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-save-selector-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-save-selector-failure)
- 前序: [2026-09-13-document-revision-e2e-block-selector.md](./2026-09-13-document-revision-e2e-block-selector.md)
@@ -0,0 +1,61 @@
---
title: "编辑弹窗 hydration 竞态修复"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-editor-hydration-race
worktree: "-"
mutex: document-revision-editor-hydration-race
---
# 编辑弹窗 hydration 竞态修复
## 目标
堵住第十二轮 UI-06:编辑弹窗打开期间后台 hydration 换块 ID,保存静默关窗且不发 PATCH。用户编辑期间与 PATCH 成功后,迟到 hydration 不得覆盖基线;找不到块 fail-closed。
## 范围
- `web/src/lib/controlledDocHydrate.ts`:`fetchRevisionState` 保留 `head_block_map`,hydrate 后 `applyHeadBlockMap`
- `web/src/lib/editorHydrationGate.ts` 与单测(迟到响应不得覆盖 PATCH 成功正文)
- `web/src/lib/blockSavePolicy.ts` 与单测(stale-id / doc 绑定 / 切文档 fail-closed)
- `web/src/lib/saveControlledBlockEdit.ts`:App 真实调用的 PATCH 编排(可注入 patch API)
- `web/src/App.tsx`:`editorSession`、关窗续跑、切文档 fail-closed
- audit / remediation / CURRENT 认领
## 非目标
- 不修改、移动、删除或提交 `.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/`
- 不合 `dev`、不 push、不启动/重建 Docker
- 不运行或伪造真实 UI/E2E;不得声称 UI-06 已通过
- 不改 FEATURE-MATRIX 完成度;不削弱 ETag/409
## 步骤
1. [x] 从 `dev@4c465d2` 开 `fix/document-revision-editor-hydration-race`,mutex 不与现有 in_progress 冲突
2. [x] 定位全部会在弹窗打开期间替换 AST 的路径(effect / 选文档 / 重试;lease 改 deliverables 触发 effect)
3. [x] hydrate 对齐 `head_block_map` + generation token / 编辑门闩 + stale-id fail-closed
4. [x] 单测:同 map ID 稳定、缺 map 仍随机、deferred hydrate、stale id、迟到 hydrate、PATCH ETag、409
5. [x] `web` npm test / build(首轮)
6. [x] 独立审查补强:真实 PATCH 编排测试、editorDocId 绑定、关窗续跑、切文档 fail-closed
7. [ ] 真实 UI-06 重跑(本轮不做)
## 验收标准
- [x] 编辑中不因后台 hydration 换 ID 而静默丢稿(逻辑门闩 + 单测)
- [x] 找不到目标块保留编辑器并提示
- [ ] 现场 r0→r1(未跑 E2E,保持未勾选)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-editor-hydration-race.md](../../audit/2026-09-13-document-revision-editor-hydration-race.md)
- Remediation: [../../remediation/2026-09-13-document-revision-editor-hydration-race.md](../../remediation/2026-09-13-document-revision-editor-hydration-race.md)
- 失败证据(勿提交): `.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-r-bump-noop-failure/`
## 证据 / 备注
- mutex:`document-revision-editor-hydration-race`(新 mutex,未占用 `document-revision-save-selector` 等 in_progress 行)
- 基线:`dev@4c465d2`
- 验证:补强后全量 `npm test` + `npm run build` 通过;`saveControlledBlockEdit` 断言一次 PATCH
- **未跑真实 UI-06,不得标 done**
@@ -0,0 +1,54 @@
---
title: "UI-11 快速完成观测契约"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-fast-completion-observation
worktree: "-"
mutex: document-revision-fast-completion-observation
---
# UI-11 快速完成观测契约
## 目标
堵住第14轮 UI-11:助手已 `completed`,验收脚本仍硬等处理中 60s,把成功终态误判为失败。只改测试契约,不降真实性。
## 范围
- `web/src/lib/squadCompletionObservation.ts` 与单测
- `web/e2e/document-revision-runtime.spec.ts` 的 `waitForSquadCompletion`
- audit / remediation / CURRENT
## 非目标
- 不改产品运行时、不放宽上传/对应关系/终态/无错误
- 不碰证据目录;不合 dest;不启动/重启容器;不 E2E;不 push
- 不把 stub 或伪造页面当验收
## 步骤
1. [x] 从 `dev@339e871` 开分支并登记 mutex
2. [x] 观测谓词 + 直接 completed / 经历 inflight 测试
3. [x] 接线 `waitForSquadCompletion`,保留 UI-11 上传断言
4. [x] 跑相关单测并原子提交
## 验收标准
- [x] 已 completed 直接接受,不要求 inflight
- [x] 经历 inflight 再到终态仍接受
- [x] 错误终态与错位消息拒绝
- [ ] 现场 UI-11(未跑)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-fast-completion-observation.md](../../audit/2026-09-13-document-revision-fast-completion-observation.md)
- Remediation: [../../remediation/2026-09-13-document-revision-fast-completion-observation.md](../../remediation/2026-09-13-document-revision-fast-completion-observation.md)
## 证据 / 备注
- mutex:`document-revision-fast-completion-observation`(新 mutex)
- 基线:`dev@339e871`
- 验证:`npx tsx --test src/lib/squadCompletionObservation.test.ts` PASS;`cd web && npm test` PASS(306 + 29)
- **未跑真实 UI-11,不得标 done**;**不得 merge / rebuild / E2E / push**
@@ -0,0 +1,61 @@
---
title: "文档修改、版本差异与智能体变更说明设计"
status: done
created: 2026-09-13
updated: 2026-09-13
owner: Codex
branch: feature/document-revision-management
worktree: "-"
mutex: docgov
---
# 文档修改、版本差异与智能体变更说明设计
## 目标
基于当前 DocGov、任务、块编辑器与通知实现,形成一套可直接评审和拆分实施的文档修改管理方案,覆盖人工修改标记、智能体/小队修改归属、版本边界、任意版本比较、AI 变更说明及负责人通知。
## 范围
- 交叉核对现有文档数据模型、保存链路、Agent 产物落盘、前端块编辑器、权限和通知机制。
- 明确定义“智能体基线 + 后续人工修改”的工作副本与正式版本语义。
- 设计数据模型、事务边界、API、前端交互、通知、权限、迁移兼容及验收矩阵。
- 产出 audit、system-design、remediation 文档并同步文档索引与 FEATURE-MATRIX。
## 非目标
- 本任务不修改业务代码、数据库迁移或运行环境。
- 本任务不执行共享容器重建、真实 PI E2E 或合入 `dev`。
- 本任务不替用户决定版本保留周期、强监管电子签名策略等产品决策;方案给出推荐默认值和决策点。
## 步骤
1. [x] 完成当前实现与既有设计的证据核对。
2. [x] 形成领域模型、版本状态机与一致性边界设计。
3. [x] 形成前端展示、API、权限、通知与验收设计。
4. [x] 形成分波次整改方案和实施任务拆分。
5. [x] 更新文档索引、FEATURE-MATRIX、CURRENT 并执行文档质量检查。
## 验收标准
- [ ] 方案能逐条映射用户提出的版本边界与显示规则。
- [ ] 能区分用户、单智能体、智能体小队及系统迁移等修改主体。
- [ ] 并发、失败恢复、权限、审计、通知去重和大文档性能均有确定性方案。
- [ ] API、表结构、UI 状态、迁移顺序与测试用例足以供开发直接拆单。
- [ ] 仅产生方案文档变更,无业务代码和环境变更。
## 相关链接
- Audit: `../../audit/2026-09-13-document-revision-management-gap-analysis.md`
- System design: `../../system-design/document-revision-management.md`
- Remediation: `../../remediation/2026-09-13-document-revision-management-implementation-plan.md`
- Test report: 实施阶段补充
## 证据 / 备注
- 用户评审通过前保持 `in_progress`;本轮交付的是可评审方案,不代表能力已实现。
- 2026-09-13:`git diff --check` PASS;新增文档及新增链接均可解析。
- 索引文件中另有 3 个与本任务无关的既有失效链接(两个历史 `.tmp` 目录、一个 `architecture-design.md` 相对路径),本任务未扩大范围修改。
- 2026-09-13:独立复审(Cline)通过,结论待用户最终拍板:①三项决策(智能体/模板开 Version、high/critical 强制编制负责人二次确认、首发只覆盖受控文档)均确认可行,理由与既有 `document_change_proposals` 认领授权机制一致;②抽查 DOCREV-01~09 全部 9 项源码证据属实(含 `bizdev/service.go:499-502` 通用提案文案、`:694-705` 忽略错误写哈希、`handlers.go:1027` 客户端 holder 直通、`BlockEditorModal.tsx:104` 硬编码“张工”、`saveDocumentContent` 无调用者、Goose 基线 00027);③补强 2 处设计缺口——根表指针列与既有 `freeform_documents.current_version_id` 同名冲突(改为 `ledger_*` 命名并明确旧列退役)、状态机把文档生命周期误并入版本状态(已拆为正交状态图);同步修订 system-design §4/§6.7、remediation §3/§5.2/§5.7。
- 2026-09-13:用户确认 DOCREV 实施计划选项 1;设计任务归档,进入 Wave 0。
@@ -0,0 +1,57 @@
---
title: "文档账本 PG ID 与计数器重映射"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-pg-id-remap
worktree: "-"
mutex: document-revision
---
# 文档账本 PG ID 与计数器重映射
## 目标
堵住 schema31-round19:首次生成 PG 已写入 snapshot/version/candidate,但 `CommitAgentVersion` 因内存 map 误删 baseline 而 `not found`。
## 范围
- `internal/docrevision` ID 分配、adopt、PG persist
- 确定性单测 + 隔离 PG 回归
- audit / remediation / CURRENT / FEATURE-MATRIX / gap-matrix
## 非目标
- 本任务编码阶段不 merge / 不启停容器 / 不 push;Round20 验收见运行时 UI 报告
- 不删不改证据目录
- 不忽略 `ErrNotFound`,不伪造基线/报告
## 步骤
1. [x] 从 `dev@fa6a033` 开分支并登记 mutex
2. [x] 独立验证 openTemplate 不推进 counter + 无条件 delete 误删
3. [x] 统一 helper + 全路径 adopt
4. [x] `gofmt` / `go vet` / `go test -short` / 相关包测试
5. [x] 原子提交
## 验收标准
- [x] 占用 ID 不覆盖;adopt 只删同一对象
- [x] 高序列首次生成:自动提交、V2、candidate committed、baseline 未丢、重启 hydration
- [x] 现场 UI-03:Round20 项目 6159 首次生成 V2/r0,任务 `run_1789343479579646533` 成功(相对 6158 candidate id=175 / output snapshot 250 的 not found)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-pg-id-remap.md](../../audit/2026-09-13-document-revision-pg-id-remap.md)
- Remediation: [../../remediation/2026-09-13-document-revision-pg-id-remap.md](../../remediation/2026-09-13-document-revision-pg-id-remap.md)
- Checklist: [../checklists/2026-09-13-document-revision-pg-id-remap.md](checklists/2026-09-13-document-revision-pg-id-remap.md)
- Handoff: [../handoffs/2026-09-13-document-revision-pg-id-remap.md](handoffs/2026-09-13-document-revision-pg-id-remap.md)
## 证据 / 备注
- 基线:`dev@fa6a033`
- 验证:`gofmt`/`go vet` PASS;`go test -short ./...` PASS;隔离临时库 `HighSequenceFirstGen` PASS(拒绝 `agent_system_dev`,测完 DROP)
- 失败归档(只读):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema31-round19-ui03-advisor-briefing-docrevision-not-found/`
- 验收:Round20 UI-03 PASS,见 [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
- 工程修复已合入 `dev@b258ab8`
@@ -0,0 +1,56 @@
---
title: "post-restart 期望正文须为最终持久 marker"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-post-restart-final-snippet
worktree: "-"
mutex: document-revision-post-restart-final-snippet
---
# post-restart 期望正文须为最终持久 marker
## 目标
第二次 post-restart 已恢复 login/项目/文档/`revision-state` 200/`V3`/`r2`/正文,但 `phase-state.bodySnippet` 仍是 UI-06 marker,断言旧文失败。UI-13b A1 成功保存后须把最终持久正文写入 phase-state;不得放宽 post body 断言。
## 范围
- `web/src/lib/durableBodySnippet.ts` 纯函数契约
- UI-06 / UI-13b / UI-15-pre 同步 `latestDurableBodySnippet` → `phase-state.bodySnippet`
- audit / checklist / handoff / CURRENT
## 非目标
- 不改生产业务代码、不重跑真实 UI、不动容器、不 merge、不 push
- 不改删 assets
- 不改删历史失败 assets;不声称全仓 `production_ready=yes`
## 步骤
1. [x] 从 `dev@eb85b8a` 认领分支并登记 mutex
2. [x] 成功修订覆盖旧 snippet;冲突失败稿不成为期望正文
3. [x] UI-13b 完成后与 UI-15-pre 写入最终 marker
4. [x] `npm test` / `npm run build`
5. [x] 原子提交
6. [x] Round20 `UI_PHASE=post-restart` PASS(V3/r2 / `A1-win-mu0gwiez`)
## 验收标准
- [x] 契约测试:A1 覆盖 UI06;A2 conflict 不覆盖 A1
- [x] post-restart 仍断言 `st.bodySnippet` 可见
- [x] 真实 UI-15 post-restart:Round20 1 passed / 18 skipped;页面恢复 V3/r2/正文
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-post-restart-final-snippet.md](../../audit/2026-09-13-document-revision-post-restart-final-snippet.md)
- Checklist: [../checklists/2026-09-13-document-revision-post-restart-final-snippet.md](checklists/2026-09-13-document-revision-post-restart-final-snippet.md)
- Handoff: [../handoffs/2026-09-13-document-revision-post-restart-final-snippet.md](handoffs/2026-09-13-document-revision-post-restart-final-snippet.md)
## 证据 / 备注
- 基线:`dev@eb85b8a`
- 失败归档(只读):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema31-postrestart-stale-body-snippet-failure/`(当时 `bodySnippet=UI06-mu0eq020`)
- Round20 `phase-state`:`versionText=V3` `revisionText=r2` `bodySnippet=A1-win-mu0gwiez`
- 报告:[../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
@@ -0,0 +1,59 @@
---
title: "post-restart 项目名 selector 与阶段产物隔离"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-post-restart-selector
worktree: "-"
mutex: document-revision-post-restart-selector
---
# post-restart 项目名 selector 与阶段产物隔离
## 目标
第18轮 main 18 PASS 后,post-restart 在页面已恢复项目时因项目名同时出现在顶栏与侧栏而 strict violation。改为 banner 内唯一 exact 断言,点击仍走可见项目入口;Playwright output/report 与结果 JSON 按 `UI_PHASE` 分离(main 仍用 `ui-acceptance-results.json`)。
## 范围
- `web/e2e/document-revision-runtime.spec.ts` post-restart 项目恢复断言
- `web/src/lib/currentProjectRestore.ts` 与契约测试
- `web/playwright.config.ts` + `playwrightPhaseArtifacts` 按阶段分目录
- audit / checklist / handoff / CURRENT
## 非目标
- 不改业务逻辑、不重跑真实 UI、不动容器、不 merge、不 push
- 不改删 `.doc/test-reports/assets/` 证据
- 不声称 post-restart / UI-15 通过
## 步骤
1. [x] 从 `dev@b824948` 认领分支并登记 mutex
2. [x] 项目入口 click + banner exact 断言;禁 `.first()` 弱化
3. [x] `UI_PHASE` 分离 `playwright-output-*` / `playwright-report-*`
4. [x] 结果 JSON:main 保持 `ui-acceptance-results.json`;post-restart 写 `ui-acceptance-results-post-restart.json`
5. [x] `npm test` / `npm run build`
6. [x] 原子提交
7. [ ] 占槽后重跑 post-restart(本轮不做)
## 验收标准
- [x] 页面级 `getByText(项目名)` 在 2 命中时契约判定失败
- [x] 入口为 complementary exact title;当前项目为 banner exact text
- [x] main / post-restart 产物目录不同
- [x] post-restart `recordPass` 不覆盖 main 的 `ui-acceptance-results.json`
- [ ] 真实 UI-15 post-restart(未跑)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-post-restart-selector.md](../../audit/2026-09-13-document-revision-post-restart-selector.md)
- Checklist: [../checklists/2026-09-13-document-revision-post-restart-selector.md](checklists/2026-09-13-document-revision-post-restart-selector.md)
- Handoff: [../handoffs/2026-09-13-document-revision-post-restart-selector.md](handoffs/2026-09-13-document-revision-post-restart-selector.md)
## 证据 / 备注
- 基线:`dev@b824948`
- 失败归档(只读):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema31-postrestart-project-title-selector-failure/`
- **未跑真实 post-restart,不得标 done**
@@ -0,0 +1,62 @@
---
title: "prelim_design 缺 output.md 产物契约修复"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-pi-runner-module
worktree: "-"
mutex: document-revision-prelim-output
---
# prelim_design 缺 output.md 产物契约修复
## 目标
第11轮 UI-11:202 + `prelim_design` 已正确,但 `step_01_draft` 缺真实 `output.md`。embed 官方模板、归一化 runner 路径、缺产物 fail-closed;对「进程 0 + settled failure / 缺产物」的**瞬时**失败做有界全新 step 重试。不得标 `done`。
## 范围
- `internal/template` embed + loader
- `internal/agent` 路径映射、目标强制、瞬时/永久分类、`Result.Retryable`
- `internal/squad` `runOneStep` 有界全新 invocation
- `deploy/pi-agent/runner.mjs` + `settle-policy.mjs`
- `deploy/pi-agent/Dockerfile` 必须 COPY runner 的全部相对 import 到 `/app`
- `deploy/app/Dockerfile` `COPY templates` / `COPY configs` 到 `/app`;`.dockerignore` 放行官方 markdown
- Docker build context / `/app/templates/docs` 读路径实测(不执行 env-service 重建)
- 文档:audit / remediation / CURRENT
## 非目标
- 不伪造 `output.md`;不执行截断 `write` 参数;不改 E2E prompt;不放宽缺失校验
- 不触碰/提交证据目录;不执行 env-service 重建/重启;本轮不重跑 E2E
- 不改 FEATURE-MATRIX;不合 `dev`;不 push
- 不对永久缺失(干净 settle 后无产物、`prompt_empty`、治理)无限重试
## 步骤
1. [x] 从 `dev@2a58674` 开 `fix/document-revision-prelim-output` 并认领 mutex
2. [x] 定位:stub 模板 + `agent_settled` 假成功 + 只认精确 `output.md` 键
3. [x] embed / 映射 / runner fail-closed + 单测 + 门禁
4. [x] 纳入现场时序:write 已流出但 `terminated`;SDK retry 1–3 Connection error;`auto_retry_end success=false`;仍 `agent_settled`;trace `success=true`
5. [x] settle-policy + Go 分类 + `runOneStep` 有界全新重试 + 单测
6. [x] `.dockerignore` 放行 `templates/**/*.md`;Docker context 实测 `/app/templates/docs/prelim_design.md`
7. [x] 本次写入的目标不覆盖、不再调用;backend 明确失败仍 FAIL(不把文件存在当成功);上一轮残留不当成功
8. [x] `dev@55a4f39` 重建后 runner `ERR_MODULE_NOT_FOUND settle-policy.mjs`:Dockerfile COPY 齐相对模块 + COPY 契约测试
9. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [ ] 无盘模板时 `prelim_design` 仍为官方「系统初步设计方案」
- [ ] 绝对/`./`/重复子目录 `rel_path` 能落到目标文件
- [ ] `ok:true` 但无非空目标 → 失败,不发明正文
- [x] 瞬时 settled failure → 最多一次全新 step;永久缺失不重试;耗尽 fail-closed
- [x] pi-agent 镜像 COPY 含 runner 全部相对 import(含 `settle-policy.mjs`)
- [ ] intake 工作流单测仍绿
- [ ] 真实 UI-11 PASS 后才可标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-prelim-output.md](../../audit/2026-09-13-document-revision-prelim-output.md)
- Remediation: [../../remediation/2026-09-13-document-revision-prelim-output.md](../../remediation/2026-09-13-document-revision-prelim-output.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-prelim-design-missing-output-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-prelim-design-missing-output-failure)
@@ -0,0 +1,46 @@
---
title: "质量门禁:行动计划表状态「待续」窄豁免"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-quality-context
worktree: "-"
mutex: docgov
---
# 质量门禁:行动计划表状态「待续」窄豁免
## 目标
结构化行动计划表中独立状态单元格「待续」不再误报;正文/标题/列表/普通表中的「待续」仍 FAIL。禁词表不得删除「待续」。
## 范围
- `internal/squad/quality_gate.go` 窄 Markdown 表结构识别
- 敌意单测 + 既有自检豁免 / 投影 / repair 隔离不回归
- 文档:audit / gap-matrix / CURRENT / FEATURE-MATRIX
## 非目标
- 不删除「待续」禁词;不放宽普通正文/任意同行表格
- 不触碰 assets / E2E;不操作容器
## 步骤
1. [x] 认领 CURRENT;写 audit/short-term
2. [x] 仅豁免行动计划表「阶段/状态/进度」列独立单元格(去粗体精确等于「待续」+ 表头列索引对齐 + 实质行动 + 负责/触发完整)
3. [x] 敌意用例:正文「后续章节待续」、`| 内容 | 待续 |`、待续说明、残行/空动作、负责方/触发=待续仍 FAIL;列重排仅状态列可 PASS
4. [x] 门禁 + 原子提交
## 验收标准
- [x] 现场同构行动表 PASS,且不触发 repair
- [x] 敌意上下文仍记录 `待续`
- [x] `ProhibitedPhrases` 仍含「待续」
- [x] targeted / `go vet` / `go test -short` / `go test -race ./internal/taskrun` / web test+build / `git diff --check`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-quality-status-false-positive.md](../../audit/2026-09-13-document-revision-quality-status-false-positive.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui03-quality-status-false-positive](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui03-quality-status-false-positive)
@@ -0,0 +1,57 @@
---
title: "质量修复子工作区契约"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-quality-repair-workspace-contract
worktree: "-"
mutex: document-revision-quality-repair-workspace-contract
---
# 质量修复子工作区契约
## 目标
堵住第13轮 UI-03:repair 步 TASK 引导 `../../output.md`,模型越界改根文件,本地目标缺失导致 `quality_failed` 停在 70。门禁判定保持,修复契约改为本地快照 + containment。
## 范围
- `internal/squad/repair_workspace.go` 与单测
- `EnsureQualityOrRepair` / `buildSubWorkspaces` snapshot 布局
- audit / remediation / CURRENT
## 非目标
- 不放宽必填章节;不把越界根文件当成功;不隐藏 `quality_failed`
- 不改默认步骤的 `../../` context 导航
- 不碰证据目录;不合 dev;不 rebuild Docker;不 E2E;不 push
## 步骤
1. [x] 从 `dev@8b1a531` 开分支并登记 mutex
2. [x] 快照契约 + containment + 测试
3. [x] 独立审查 fail-open:`runErr` / containment 不得提升;restore 失败硬返回;创建/删除计入 mutation
4. [x] gofmt / vet / `go test -short ./...` / `-race` squad+agent / settle-policy.test.mjs / `git diff --check`
5. [ ] 真实 UI-03(本轮不做)
## 验收标准
- [x] 仅 `runErr==nil` ∧ 无 containment ∧ `TrustedLocalDeliverable=true` 才覆盖根并重验
- [x] 越界(含创建/删除受保护父级)恢复后不提升,报告 FAIL
- [x] backend 失败/超时即使留下本地目标也不提升
- [x] restore 失败立即返回,可测策略能断言错误传播
- [ ] 现场 UI-03(未跑)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-quality-repair-workspace-contract.md](../../audit/2026-09-13-document-revision-quality-repair-workspace-contract.md)
- Remediation: [../../remediation/2026-09-13-document-revision-quality-repair-workspace-contract.md](../../remediation/2026-09-13-document-revision-quality-repair-workspace-contract.md)
## 证据 / 备注
- mutex:`document-revision-quality-repair-workspace-contract`(新 mutex,不与现有 in_progress 冲突)
- 基线:`dev@8b1a531`
- 验证(fail-closed 追加):`gofmt` / `go vet ./...` / `go test -short ./...` / `go test -short -race ./internal/squad/ ./internal/agent/` / `node --test deploy/pi-agent/settle-policy.test.mjs` / `git diff --check` PASS
- 保护范围仅 `output.md` / `template.md` / `blackboard.json`;其它父级文件是剩余风险
- **未跑真实 UI-03,不得标 done**;**不得 merge / rebuild / E2E / push**
@@ -0,0 +1,68 @@
---
title: "项目 reviewer 同步到受控文档职责"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-reviewer-duty-sync
worktree: "-"
mutex: document-revision-reviewer-duty-sync
---
# 项目 reviewer 同步到受控文档职责
## 目标
堵住第17轮 UI-13a:UI-01 已把 USER_B 设为 reviewer,但 `doc_proj6145_intake` 矩阵为 viewer。项目创建时的 reviewer 必须成为后续每份受控文档的权威 `reviewerId`。
## 范围
- `project_members.document_duty` 迁移与成员 upsert
- 任务生成/账本创建解析项目职责;禁止硬编码 2/3
- 已有文档缺失/非成员占位的服务端自愈
- 前端立项 persist `document_duty` + 职责互斥
- audit / remediation / CURRENT
## 非目标
- 不 merge、不启停/重建容器、不跑/声称真实 UI E2E、不 push
- 不删不改证据目录
- 不向用户索要 token;不提交账号密码
## 步骤
1. [x] 从 `dev@639969f` 开分支并登记 mutex
2. [x] RED/GREEN:解析、自愈、成员 duty、前端映射
3. [x] `gofmt` / `go vet` / `go test -short` / 相关 `-race` / `npm test` / `npm run build`
4. [x] 原子提交
5. [x] 独立审查收紧(暂不合入):Heal 以 assigned 为权威;成员变更带 duty 并同步文档;缺 role 不降 owner;写权精确断言;迁移多 owner 确定回填;并发 upsert PG 用例;自愈失败不假成功
6. [x] 最后一轮:移出成员 sync + 前端刷新;空 assigned 只清失效 holder;显式 revoke 再 heal;账本创建失败不成功
7. [x] 补充审查:lock + 读旧/冲突 holder + 成员写 + 精确清槽同事务;提交后 heal;失败仍 `ERR_DUTY_SYNC`
8. [x] Heal 与成员写共用 `pg_advisory_xact_lock(project_id)`;解析与文档读写同事务;确定性并发 PG 证明旧 reviewer 不复活
## 验收标准
- [x] A=author、B=reviewer、C=none;第二文档继承;重复执行幂等;旧文档缺失回填
- [x] 服务端写操作仍按权限拒绝
- [x] 前端不按名字提升
- [ ] 现场 UI-13a(未跑)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-reviewer-duty-sync.md](../../audit/2026-09-13-document-revision-reviewer-duty-sync.md)
- Remediation: [../../remediation/2026-09-13-document-revision-reviewer-duty-sync.md](../../remediation/2026-09-13-document-revision-reviewer-duty-sync.md)
- Checklist: [../checklists/2026-09-13-document-revision-reviewer-duty-sync.md](checklists/2026-09-13-document-revision-reviewer-duty-sync.md)
- Handoff: [../handoffs/2026-09-13-document-revision-reviewer-duty-sync.md](handoffs/2026-09-13-document-revision-reviewer-duty-sync.md)
## 证据 / 备注
- mutex:`document-revision-reviewer-duty-sync`(新 mutex,不占用已有 in_progress)
- 基线:`dev@639969f`
- 证据(只读):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui13a-reviewer-duty-sync-failure/`
- 验证(原子清槽轮):`gofmt`/`go vet` PASS;`go test -short ./...` PASS;相关 `-race` PASS;`npm test`/`build` PASS;隔离 PG PASS
- 原子性:成员写与 `HealProjectDocuments` 均先 `pg_advisory_xact_lock(project_id)`,再在同一事务内读成员/文档并更新;旧 heal 不能在转移提交后把 reviewer A 写回
- PG 集成已写 heal/空 assigned/多 owner 回填/并发 upsert;`-short` 或无 `TEST_DATABASE_URL` 时跳过
- 隔离跑法:`scripts/run-isolated-duty-sync-pg-tests.sh`(`TEST_DATABASE_URL` 或 `PG_ADMIN_URL` 建临时库)。拒绝 `agent_system_dev`
- 本轮已在已运行的 context Postgres 上 `CREATE DATABASE agent_duty_sync_itest_*`,串行跑通后 `DROP`;未 `env-service`、未动共享库数据
- **兼容**:旧二进制不读 `document_duty` 仍可运行;新代码在 assigned 为空时不臆造 reviewer。6145 的 B 仍是空 duty,须再走成员 API
- **未跑真实 UI-13a,不得标 done**;**不得 merge / 启停容器 / E2E / push**
@@ -0,0 +1,107 @@
---
title: "文档版本账本运行时整改"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-runtime-ui03
worktree: "-"
mutex: docgov
---
# 文档版本账本运行时整改
## 目标
消除 revision-state 404、重启丢账本、人工保存无效、overlay 无效;接通首轮/二轮可见确定性 change report;PATCH 权限→账本→投影顺序正确;停在 fix 分支待集成。
## 范围
- `internal/docrevision` PG hydrate/persist + bootstrap + `MaterializeAgentOutput`
- `internal/server` 授权、PATCH 顺序、orphan 不静默建账
- `internal/bizdev` 小队成功走 Materialize(禁止仅 OpenTemplate)
- `cmd/document-revision-backfill` gofmt
- `web` 保存链路与 overlay 三模式
- 工程测试 + 扩展 UI 验收计划(分栏)
## 非目标
- 不占 CURRENT 集成槽、不 `env-service rebuild`、不 push、不 merge `dev`
- 不伪造 PI 叙事 change report;不把 fallback 说成完整 PI 分析
- 不把 stub 输出写入最终用户验收报告
## 步骤
1. [x] 审计 / 整改 / 本任务 + CURRENT 认领
2. [x] 分支 `fix/document-revision-runtime`
3. [x] PG store + bootstrap + backfill
4. [x] Handler / agent / 前端
5. [x] 首轮报告 Materialize + PATCH 顺序 + 单测
6. [x] gofmt + UI checklist 扩展 + 文档证据
7. [x] 分层 commit,输出哈希与剩余 blocker(不 merge/push)
## 验收标准
- [x] 工程门禁与 UI 实战计划分栏
- [x] Round20 真实 UI **PASS**(见 [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md))
- [x] 剩余开放:PI 叙事仍为 fallback;orphan 禁止假 V1(UI-16 验证已注册路径);不可用假数据掩盖
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-runtime-404.md](../../audit/2026-09-13-document-revision-runtime-404.md)
- Remediation: [../../remediation/2026-09-13-document-revision-runtime-remediation.md](../../remediation/2026-09-13-document-revision-runtime-remediation.md)
- Checklist/UI: [../checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](checklists/2026-09-13-document-revision-runtime-ui-acceptance.md)
## 证据 / 备注
### 工程门禁(非 UI 验收)
```text
gofmt -l cmd/document-revision-backfill/main.go internal/docrevision/risk.go
go vet ./...
go test -short ./...
cd web && npm test && npm run build
```
本轮门禁(2026-09-13 10:11 UTC 独立复跑):`go vet ./...` PASS;`go test -short ./... -count=1` PASS(含 Materialize 首/二轮 change_report_id、PATCH 顺序、Materialize 失败透出、Assert 先职责后租约、SaveDocumentContent 审计、pending 事实源不越权、同步/异步待确认文案、完成活动仅 committed、pending 活动标明待确认、MarkProposalApplied 失败显式可重试);`web npm test` 199+27 PASS;`npm run build` PASS。使用 dev PostgreSQL(schema 28)执行 `TestPGPersistSurvivesNewServiceInstance` PASS,证明新 Service 实例可恢复账本。上述均为工程门禁,不能替代 UI 验收。
UI-01 目录同步补丁门禁(2026-09-13):`node --test adminUserDirectorySync.test.ts` 3 PASS;`web npm test` 219+27 PASS;`npm run build` PASS;`go vet ./...` + `go test -short ./...` PASS。未提交 `web/e2e/*` 与 `test-reports/assets/`。
UI-01/02 访问与成员落库门禁(2026-09-13):`go test ./internal/projectinstance -short` PASS;`TEST_DATABASE_URL=… go test ./internal/projectinstance -run TestPG_GoverningAccess` PASS;`TEST_DATABASE_URL=… go test ./internal/server -run TestChatProjectAccess` PASS;`go vet ./...` + `go test -short ./...`;`web npm test` + `npm run build`。未提交 e2e/assets。
复核补强(同日):
- A:`MaterializeAgentOutput` 错误写入 `TaskRunResult.Success=false` + `ErrorReason`,不再空白忽略
- B:cand 非空且 report invalid/unassessed 时禁止自动提交(候选标 needs_confirmation)
- C:`AssertHumanCanEdit` 先职责/生命周期再租约;受控投影改 `SaveDocumentContent` 保留 author_last_edited/审计;失败 `DOCUMENT_PROJECTION_FAILED` 可幂等重试
- D:ChangeReportPanel 完整展示风险条目/项目影响/文档影响建议/开放问题;加载失败显式错误
- E:revision-state 暴露 `pending_candidate_id` / `pending_change_report_id` / `pending_risk_level` + `can_decide_pending`;工具条「待确认报告」确认/拒绝调 decision API(不绕过确认)
- F:**高风险事实源门禁**:Materialize 后仅 committed 才 MarkDocumentContentUpdated / MarkProposalApplied;`needs_confirmation` 立即 `ProjectOutputMarkdown` 恢复 ledger head,候选仅留 immutable blob;decision=commit 投影后再 Mark;decision=reject 保持旧 head;投影失败显式错误
- G:**对话可见状态**:`TaskRunResult` 带 `pending_agent_candidate_id` / report / risk;`RequiresAuthorApproval` 可复用但用 `PendingProposal` vs `PendingAgentCandidateID` 区分 DocGov 提案;terminal=`pending_author_confirmation`;同步 coordinator 与异步 `CompletionSummary` 显示「文档候选已生成,待编制人确认」+ artifact 元数据;确认并投影后才「已完成」
- H:**活动与提案收口**:`RecordActivity(完成交付物)` 仅在 committed 投影成功后;pending 记「候选待编制人确认」;落盘/投影失败不记完成。`MarkProposalApplied` 失败返回显式错误(bizdev / `DOCUMENT_GOVERNANCE_FAILED`)可重试
- I:**阶段链防传播**:`ExecuteStage` 遇 `PendingAgentCandidateID` 立即停阶段(Success=false + 待确认文案),SubArtifacts 保留候选,**不**吸收 ExtractedData / PriorDoc;确认后由用户重新发起阶段
- J:**前端历史映射**:`pending_author_confirmation` 显式映射为气泡状态(不再默认 completed);刷新窗口显示「待编制人确认」标签
- K:**决策幂等收口**:`CommitAgentVersion` 已 committed 且 expected hashes 一致时返回当前 state(可继续投影/MarkProposalApplied);已 committed 禁止 reject。`MarkProposalApplied` 先写 DB 再改内存;已 applied 幂等(包内 Propose+Decide 验证)。decision 失败 hint 指向同决策重试;**不**暴露内存补种 helper(避免内存/DB 分叉)
- L:**Playwright 骨架**:`web` 增加 `@playwright/test` + `playwright.config.ts` + `e2e/document-revision-runtime.spec.ts`(`RUN_UI_ACCEPTANCE=1` 才跑;无 mock/route/API/DB fixture)
- M:**上传注册事实源**:发送前 `await registerUploadAttachments` → `POST /api/v1/freeform-documents`(`client_key` 幂等);失败 UI 显式错误且不发消息、不生成本地 `doc-upload` orphan;成功使用 `doc-free-*` 写入 deliverable/fileStore 并挂 toolbar
- N:**Auth 契约映射(UI-00 实战)**:Go `UserAccount` 为 snake_case;前端在 API 边界 `mapUserAccount`/`mapLoginResult`/`mapMeResult` 统一转 camelCase(login/me/admin users/create/role/status);`BootstrapAdminFromConfig` 的 `UpdateUserRole` 错误不再静默。详见 [../../audit/2026-09-13-auth-useraccount-snake-case-mapping.md](../../audit/2026-09-13-auth-useraccount-snake-case-mapping.md)
- O:**全局用户目录同步(UI-01 实战)**:管理员创建/角色/状态成功后必须经 `syncAdminUserDirectories` 调用父级 `onRefreshUsers`(禁止死 prop / 静默 catch);同浏览器立项候选可立即看到新账号。跨设备/清缓存缺口见 audit 残留风险,**不**下放 admin users API。详见 [../../audit/2026-09-13-admin-user-directory-sync-ui01.md](../../audit/2026-09-13-admin-user-directory-sync-ui01.md)
- P:**无 live 访问 + chat 项目门禁 + 立项成员落库(UI-01/02)**:`GetGoverningInstanceForAccess` 区分从未激活 vs completed/terminated;chat/chatStream 先 `RequireProjectAccess` 再 stage(SSE 拒绝不得先 200);`createProject` 后持久化非创建者成员。详见 [../../audit/2026-09-13-workflow-access-chat-members-ui01-02.md](../../audit/2026-09-13-workflow-access-chat-members-ui01-02.md)
- Q:**立项确认双击竞态**:`handleCreateProjectConfirm` 加同步 in-flight `useRef` 锁 + `createProjectBootstrapIdRef`(取代 state);`createProjectSubmitting`/`submitPhase` 驱动 Modal「立项中/同步成员中」、禁用确认与关闭;失败可串行幂等重试,成功清 bootstrap。证据:`createProjectSubmitGuard.test.ts`
- R:**UI-02 任务作用域契约**:`ResolveMessageScopeForTask` 三态(preactivation / live stage / closed→Err);handler 无 live 创建 202 非 409;E2E UI-02 以 `POST /api/v1/tasks/runs` 2xx 为硬门禁(409/连接异常 FAIL)。证据:`message_scope_test.go`、`TestCreateTaskRun_PreActivationAcceptedNot409`、`document-revision-runtime.spec.ts` UI-02
- S:**UI-03 客户端同步 + 任务幂等(本分支)**:`templateMatch` intake 标记优先;任务终态后 `postTaskDeliverableSync` merge `doc_proj*`;goose `00030` 放行 `pending_author_confirmation` + `idempotency_key` 部分唯一;`ClaimRun` 先占键再写 chat;FE reconnect 同 run 订阅。审计:[../../audit/2026-09-13-controlled-doc-client-sync-ui03.md](../../audit/2026-09-13-controlled-doc-client-sync-ui03.md)。门禁:`go test -short ./internal/taskrun ./internal/server`;`web npm test` 232+27;`npm run build`。**schema30 真实现卷迁移合入前独立验证**;真实 UI-03 待占槽重跑。
### 用户 UI 实战验收
Round20 **PASS**。见 [checklist](checklists/2026-09-13-document-revision-runtime-ui-acceptance.md) 与 [test-report](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)。项目 6159;UI-03 V2/r0;终态 V3/r2;post-restart 恢复最终正文 `A1-win-mu0gwiez`。
### Blockers
- **DOCREV-RT-PI-NARRATIVE**(仍开放):真实 PI 业务叙事摘要/风险解释未替代确定性 fallback;Round20 已可见 fallback 字段,不得宣称为完整 PI
- **DOCREV-RT-UPLOAD-ORPHAN**(约束仍在,UI-16 PASS):仅 IndexedDB、无服务端正文 → 禁止假 V1
- **DOCREV-RT-UI-E2E**:**PASS**(Round20)
- **DOCREV-RT-SCHEMA30-VOLUME**:goose 00030 对既有重复卷的迁移仍属合入前独立验证残留
- **DOCREV-RT-USER-DIR-CROSS-DEVICE**:跨设备/新浏览器可能仍缺成员候选(本轮同浏览器未暴露)
### Commits(历史)
- `7ea686e` … `ec8a45a`(见 git log);本轮追加见会话结束提交号
@@ -0,0 +1,55 @@
---
title: "UI-11 点名优先路由 + PATCH 请求级释租"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-second-doc-routing-lease
worktree: "-"
mutex: document-revision-second-doc-routing-lease
---
# UI-11 点名优先路由 + PATCH 请求级释租
## 目标
第十轮 UI-11 首错:否定句「需求」压过「系统设计输入」,且 PATCH 残留 human lease 使小队 DOC_BUSY。点名优先 + 请求级 defer 释租 + E2E 202 门闩。不得将本任务标 `done`。
## 范围
- `web/src/engine/templateMatch.ts` + 单测
- `internal/server/document_revision_handlers.go` + `document_revision_patch_order_test.go`
- `web/e2e/document-revision-runtime.spec.ts` UI-11 waiter
- 文档:audit / remediation / CURRENT
## 非目标
- 不改 E2E prompt;不改 `SaveDocumentContent` 内部释租
- 不触碰/提交 `.doc/test-reports/assets`;不操作容器;本轮不重跑 E2E
- 不改 FEATURE-MATRIX;不合 `dev`;不 push
## 步骤
1. [x] 认领 CURRENT(mutex `document-revision-second-doc-routing-lease`)
2. [x] 点名优先 +「系统设计输入」别名 + 单测
3. [x] PATCH 已授权后 defer 释租(成功 / 409 / 投影失败)+ 服务端测试
4. [x] UI-11 send 前 `tasks/runs` waiter,断言 202 后再 wait completion
5. [ ] 占槽后真实 UI 重跑(本轮不做)
## 验收标准
- [x] UI-11 原文 / 混合句 → `prelim_design`;当前文档钉住、UI-05 pin、首轮摸底仍 intake
- [x] PATCH 后无 human lease,squad 可获取
- [x] UI-11 非 202 即 fail;`requireInflight` 拒绝同步 busy
- [ ] 真实 UI-11 PASS 后才可将本任务标 `done`
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-second-doc-routing-lease.md](../../audit/2026-09-13-document-revision-second-doc-routing-lease.md)
- Remediation: [../../remediation/2026-09-13-document-revision-second-doc-routing-lease.md](../../remediation/2026-09-13-document-revision-second-doc-routing-lease.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-second-doc-routing-human-lease-failure](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-second-doc-routing-human-lease-failure)
## 证据 / 备注
- Prompt 别名「系统设计输入」≠ 卡片标题。真实 UI / 模板 / squad 标题均为「系统初步设计方案」。
- UI-11 打开第二份文档必须用已注册 `doc_proj{n}_prelim_design`(`data-doc-id`),禁止 `/设计输入|系统设计/`:既匹配不到真实标题,也容易误命中其他设计类文案或同标题模板槽。
@@ -0,0 +1,57 @@
---
title: "任务 SSE 幂等 + 质量门禁自污染与 auto_repair 产品契约"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-sse-idempotency
worktree: "-"
mutex: docgov
---
# 任务 SSE 幂等 + 质量门禁自污染与 auto_repair 产品契约
## 目标
1. 同 turn 在 SSE 断线重连时返回既有 run 202、不重复聊天、不误 409 DOC_BUSY;长任务 events SSE 不被 120s WriteTimeout 切断;前端 EOF 按 after_seq 重订阅同一 run。
2. 受控文档小队任务质量门禁:**服务端启用修复预算**;否定性自检引用不误报;`quality_failed` UI 保持失败且不激活未过门禁稿。
## 范围
- SSE/幂等:`task_run_handlers`、SSE write deadline、FE subscribe 重连
- 质量 A–D:`repairBudgetForSquadTask`、`quality_gate` 语境检测、prompt 去原词、Materialize/`TerminalStatus`、FE `quality_failed`、单测
- 证据:`data/dev/workspaces/bizdev/intake_1789308825666278807`(output.md:204;events seq10)
## 非目标
- 不改全局 HTTP 超时为「无超时」;不 rebuild Docker;不 push/merge;不删证据 assets
## 步骤
1. [x] 从 `dev` 开 `fix/document-revision-sse-idempotency`;CURRENT 认领
2. [x] 幂等先查 + 属主校验
3. [x] SSE write deadline + heartbeat
4. [x] FE subscribe 重连
5. [x] A 服务端修复预算产品契约
6. [x] B 门禁否定/元语境 + prompt 去原词
7. [x] C quality_failed UI/Materialize 契约
8. [x] D 真实问题单测 + 门禁回归
9. [x] E 质量失败在 SetDocumentWorkDir/Materialize 前短路(无正式投影副作用)
10. [x] 豁免收窄为同行 meta+否定紧邻/引号;handlers 阶段请求字段边界单测锁定
11. [x] ExecuteStage 质量失败停链:不吸收事实、不追加 PriorDoc
12. [x] 小队 AutoRepair/Success 语义恢复;受控修复仅在 bizdev docRec 与 HTTP 边界强制
13. [x] 补强:quality projection / 阶段停链 / 非受控不强制 repair 单测;全量 Go+Web 门禁 PASS
## 验收标准
- [x] 同 turn + 活跃租约 → 同 run 202、仅一对消息;不同 turn → 仍 409
- [x] SSE 心跳/写期限可测;FE EOF/after_seq 单测
- [x] TaskKey 任务 AutoRepair=false 仍有 DefaultMaxRepairRounds;L204 自检引用不误报;真敷衍仍 FAIL
- [x] quality_failed ≠ completed;Materialize 跳过未过门禁稿
- [x] `go test -short ./...`、`go vet`、`npm test`/`build`、`git diff --check`
## 相关链接
- Audit SSE: [../../audit/2026-09-13-document-revision-sse-idempotency.md](../../audit/2026-09-13-document-revision-sse-idempotency.md)
- Audit 质量: [../../audit/2026-09-13-document-revision-quality-gate-self-pollution.md](../../audit/2026-09-13-document-revision-quality-gate-self-pollution.md)
- Evidence: [../../test-reports/assets/2026-09-13-document-revision-runtime-ui/](../../test-reports/assets/2026-09-13-document-revision-runtime-ui/)
@@ -0,0 +1,49 @@
---
title: "DOCREV Wave 0:契约冻结"
status: done
created: 2026-09-13
updated: 2026-09-13
owner: Cursor
branch: feature/document-revision-management
worktree: "-"
mutex: docgov
---
# DOCREV Wave 0:契约冻结
## 目标
冻结 Version/Revision/Snapshot/Candidate/Report 契约、黄金 diff fixture、前后端类型与先红契约测试。
## 范围
- ADR 决策门落盘
- `internal/docrevision` 契约类型、schema、testdata、契约测试
- `web/src/features/documentRevision/types.ts`
## 非目标
- 不写生产写路径;不跑容器重建;不合入 `dev`
## 步骤
1. [ ] 写入 ADR 与决策门
2. [ ] 实现契约类型、change-report schema、黄金 fixture
3. [ ] 契约测试先红后绿(随 Wave 1 内核实现变绿)
4. [ ] 前端 types 对齐
## 验收标准
- [ ] ADR 已接受且与实施计划冻结表一致
- [ ] 黄金 diff 覆盖中文段落/表格/列表/Mermaid/移动块/no-op
- [ ] 契约测试可独立运行
## 相关链接
- ADR: `../../adr/2026-09-13-document-version-boundary.md`
- Design: `../../system-design/document-revision-management.md`
- Remediation: `../../remediation/2026-09-13-document-revision-management-implementation-plan.md`
## 证据 / 备注
实施中。
@@ -0,0 +1,45 @@
---
title: "DOCREV Wave 1–6:ledger 实施"
status: done
created: 2026-09-13
updated: 2026-09-13
owner: Cursor
branch: feature/document-revision-management
worktree: "-"
mutex: docgov
---
# DOCREV Wave 1–6:ledger 实施
## 目标
在 feature 分支交付快照内核、人工 PATCH、Agent candidate、比较 UI、通知与自由文档兼容。
## 范围
- Goose 00028、`internal/docrevision`、HTTP API、前端工具条、bizdev/freedoc/notification 接线
## 非目标
- 本任务不占集成槽位合入 `dev`;真实 PI 全链路补录另开集成窗口
## 步骤
1. [x] Wave 0 契约与 ADR
2. [x] Wave 1 迁移与内核
3. [x] Wave 2 人工编辑 API/UI
4. [x] Wave 3 Agent candidate/commit
5. [x] Wave 4 比较 UI
6. [x] Wave 5 通知
7. [x] Wave 6 自由文档兼容
## 验收标准
- [x] `go test -short ./internal/docrevision/...` PASS
- [x] 相关包回归 PASS
- [ ] 真实 PI + Playwright 双用户(集成槽位)
## 相关链接
- Test report: `../../test-reports/2026-09-13-document-revision-management-test-report.md`
- ADR: `../../adr/2026-09-13-document-version-boundary.md`
@@ -0,0 +1,52 @@
---
title: "受控文档分类导航契约"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-workflow-category-navigation
worktree: "-"
mutex: document-revision-workflow-category-navigation
---
# 受控文档分类导航契约
## 目标
堵住第15轮 UI-13a:UI-11 后停在「我的私密」,未切「流程受控」就展开文档菜单,找不到 `doc_proj*_intake`。只改验收导航,不降真实性。
## 范围
- `web/src/lib/workflowCategoryNavigation.ts` 与单测
- `web/e2e/document-revision-runtime.spec.ts` 三个 opener
- audit / remediation / CURRENT
## 非目标
- 不改产品分类状态机;不用 API/内存规避 UI
- 不碰证据;不合 dest;不启停容器;不 E2E;不 push
## 步骤
1. [x] 从 `dev@48a4dcb` 开分支并登记 mutex
2. [x] 导航谓词 + private→workflow / 缺失 fail-closed 测试
3. [x] 三个 opener 先真实切分类
4. [x] `npm test` + `npm run build` 并原子提交
## 验收标准
- [x] 从私密分类可恢复到精确受控文档
- [x] 目标缺失 fail-closed
- [ ] 现场 UI-13a(未跑)
## 相关链接
- Audit: [../../audit/2026-09-13-document-revision-workflow-category-navigation.md](../../audit/2026-09-13-document-revision-workflow-category-navigation.md)
- Remediation: [../../remediation/2026-09-13-document-revision-workflow-category-navigation.md](../../remediation/2026-09-13-document-revision-workflow-category-navigation.md)
## 证据 / 备注
- mutex:`document-revision-workflow-category-navigation`(新 mutex)
- 基线:`dev@48a4dcb`
- 验证:`npx tsx --test src/lib/workflowCategoryNavigation.test.ts` PASS;`cd web && npm test` PASS(309 + 29);`npm run build` PASS
- **未跑真实 UI-13a,不得标 done**;**不得 merge / 启停容器 / E2E / push**
@@ -0,0 +1,22 @@
# Git 历史史诗重组执行记录
**日期**: 2026-09-13
**status**: done
## 结果
- 358 线性 commit → 14 史诗 × (`feature/*`|`fix/*` + `merge --no-ff`) + 1 root anchor = **373 commit**
- `git diff backup/pre-rewrite-2026-09-13 dev` 为空
- `go test -short ./...` PASS
- 旧历史:`dev-old-linear`、`backup/pre-rewrite-2026-09-13`
## 产物
- [`scripts/history-epic-manifest.tsv`](../../../scripts/history-epic-manifest.tsv)
- [`scripts/rewrite-history-epics.sh`](../../../scripts/rewrite-history-epics.sh)
- [`scripts/generate-commit-rewrite-map.py`](../../../scripts/generate-commit-rewrite-map.py)
- [`reference/commit-rewrite-map-2026-09-13.md`](../reference/commit-rewrite-map-2026-09-13.md)
## 远端
- `origin/dev|test|main` force-with-lease 同步至重组后 HEAD
@@ -0,0 +1,65 @@
---
title: "Herdr Agent 角色、备援与自动审批治理"
status: done
created: 2026-09-13
updated: 2026-09-14
owner: Codex
branch: feature/herdr-agent-governance
worktree: .worktrees/feature-herdr-agent-governance
mutex: ops-governance
---
# Herdr Agent 角色、备援与自动审批治理
> **superseded 2026-09-14**:活文档与 `scripts/herdr-agent-*.sh` 已移除;本文件仅作历史证据。见 [2026-09-14-remove-herdr-agent-settings.md](./2026-09-14-remove-herdr-agent-settings.md)。
## 目标
建立可审计的 Herdr Agent 能力分工、额度保护、故障接管和免人工工具审批入口,并明确 Herdr PI 与产品容器 PI Agent Runner 不是同一执行体。
## 范围
- 持久化主责、备份顺序、任务泳道和接管条件。
- 为已安装的 Claude、Codex、Cursor、Antigravity、PI、Kimi、Cline CLI 提供统一启动入口。
- 自动审批仍受仓库、worktree、mutex、集成槽和破坏性操作红线约束。
- 提供保守的自动派发:只向同工作目录、空闲的规范命名实例投递;明确失败时降级,超时停止重复投递。
## 非目标
- 不重启或接管当前正在执行 DOCREV/CHAT/INTENT 的实例。
- 不修改容器内 PI Agent Runner 的模型、凭证、配置或运行状态。
- 不操作共享 Docker 或推送远端。
- 不将删库、强推、密钥读取/外传等不可逆动作纳入无条件许可。
## 步骤
1. [x] 盘点 Herdr 0.9.0、在线实例、集成状态、CLI 版本和审批参数。
2. [x] 写入项目级角色与备援 SSOT,并在 AGENTS/PROJECT 建立入口。
3. [x] 实现统一自动审批启动脚本和保守派发脚本。
4. [x] 完成静态检查、脚本 dry-run 与路由验收。
5. [x] 更新任务状态、提交 feature 分支并合入 `dev`。
## 验收标准
- [x] 每种当前可调用 CLI 都有明确角色、主备关系和自动审批启动参数。
- [x] Codex/Claude 的高成本推理与 Cursor/Flash 模型的实施负载分离。
- [x] 明确禁止因 timeout/unknown 状态盲目重复派发。
- [x] Herdr PI 与产品容器 PI 在名称、职责和动作上不会混淆。
- [x] 启动和派发脚本通过 `bash -n`,dry-run 不启动实例、不执行任务。
## 相关链接
- Agent roster: [2026-09-13-herdr-agent-roster.md](./2026-09-13-herdr-agent-roster.md)
- Handoff: [handoffs/2026-09-13-herdr-agent-governance.md](./handoffs/2026-09-13-herdr-agent-governance.md)
- Test report: 本任务文“证据 / 备注”
- 移除设定任务: [./2026-09-14-remove-herdr-agent-settings.md](./2026-09-14-remove-herdr-agent-settings.md)
## 证据 / 备注
- `herdr status`: client/server 0.9.0,protocol 22,兼容。
- `herdr integration status`: Claude/Codex/Cursor/Antigravity/PI/Kimi integration current;Cline CLI 3.0.61 可调用。
- CLI 版本:Claude 2.1.270、Codex 0.154.0、Cursor 2026.09.10、Antigravity 1.2.2、PI 0.85.1、Kimi 0.41.0、Cline 3.0.61。
- `bash -n scripts/herdr-agent-start.sh scripts/herdr-agent-dispatch.sh`: PASS。
- 七种启动 profile dry-run:PASS;未启动或重启实例。
- 七条 lane `--explain`:PASS。
- 非法标准名:exit 2;无在线标准实例:逐级跳过并 exit 69,未误投任务。
@@ -0,0 +1,96 @@
# Herdr Agent 角色、审批与备援 SSOT
> **archived / superseded 2026-09-14**:不再作为活协作规范;脚本已删除。历史证据保留本文件。移除任务见 [./2026-09-14-remove-herdr-agent-settings.md](./2026-09-14-remove-herdr-agent-settings.md)。
**更新**: 2026-09-13(归档标注 2026-09-14)
**owner**: `orchestrator_codex`
**status**: archived
本文只管理工程协作终端,不管理产品运行时智能体。通用分支、worktree、mutex、集成槽、密钥和破坏性操作规则仍以仓库根 [AGENTS.md](../../../AGENTS.md) 为准。
## 1. 身份边界
| 名称 | 唯一含义 | 禁止混称 |
|------|----------|----------|
| Herdr PI / `context_pi` | Herdr pane 内运行的 PI CLI,当前目标模型 MiniMax M3,负责工程调研与长上下文分析 | 不代表后端 runner,不作为产品 E2E 证据 |
| 产品 PI Agent Runner | Compose/服务端调用的产品执行器;模型与验收要求见 PROJECT | 不参与 Herdr 工程任务路由 |
文档、提示词和 handoff 中禁止只写“PI”;必须写 `context_pi` 或“产品 PI Agent Runner”。
## 2. 稳定角色
| 逻辑名 | 客户端 / 目标模型 | 主责 | 工作量策略 | 首选备援 |
|--------|-------------------|------|------------|----------|
| `orchestrator_codex` | Codex / GPT Sol 5.6 | 需求澄清、系统方案、任务拆解、调度、跨模块风险、代码终审、发布判断 | 保留推理容量,原则上不承担大批量机械实现 | `context_kimi`;关键争议才用 `reserve_claude` |
| `implementer_cursor` | Cursor / Auto | 前后端实施、测试补齐、重构、浏览器验证、按 checklist 收口 | 主力实施席,承担最大常规工作量 | `implementer_cline` → `verifier_antigravity` → `orchestrator_codex` |
| `verifier_antigravity` | Antigravity / Gemini 3.8 Flash | 快速只读排查、测试设计、文档核对、日志归纳、低风险小修 | 低成本高频;不得单独作安全或发布终审 | `implementer_cline` → `implementer_cursor` |
| `context_pi` | PI CLI / MiniMax M3 1M | 全仓长上下文扫描、文档/代码交叉研究、候选清单、handoff 压缩 | 长材料首选;结论由 Codex 或 reviewer 复核 | `context_kimi` → `orchestrator_codex` |
| `context_kimi` | Kimi Code / Kimi K3 1M | PI 备援、长文档审查、跨文件一致性检查、方案反证 | 额度有限,优先作长上下文备援而非日常实现 | `context_pi` → `orchestrator_codex` |
| `implementer_cline` | Cline / GLM 5.3 Flash | 机械实现、测试修复、格式化、重复性迁移、Cursor 备援 | CLI 已可调用;进入主路由前需完成一次隔离 worktree 写验收 | `implementer_cursor` → `verifier_antigravity` |
| `reserve_claude` | Claude Code / Sonnet 5 | P0/P1 架构争议、安全关键复核、Codex 失败后的第二强意见 | 额度极少,禁止日常调研、批量实现和首轮测试 | `orchestrator_codex` → `context_kimi` |
| `reserve_devin` | Devin / 尚未接入 | 预留长任务自治席 | `standby`,不得派发 | 无 |
模型名称来自当前工作区约定;启动脚本不猜测各 CLI 的模型别名。每次新会话由 orchestrator 在首条状态回报中确认实际模型,不一致则停止高风险任务并记录 handoff。
## 3. 任务泳道与自动备援顺序
| lane | 适用任务 | 路由顺序 |
|------|----------|----------|
| `governance` | 方案、拆解、跨模块决策、普通 review | Codex → Kimi → Cursor → Claude |
| `critical-review` | 鉴权、安全、迁移、发布 blocker 终审 | Codex → Claude → Kimi |
| `implementation` | Go/React/SQL 实施与测试 | Cursor → Cline → Antigravity → Codex |
| `ui` | React、交互、Playwright | Cursor → Antigravity → Cline |
| `test` | 单测、集成测试、失败定位 | Cursor → Cline → Antigravity |
| `fast-check` | 日志、静态核对、文档一致性、小修 | Antigravity → Cline → Cursor |
| `long-context` | 全仓/全量文档审读、证据汇总 | PI → Kimi → Codex |
Claude 只在 `critical-review` 中作为前排备援;其他 lane 放在最后或不进入路由,以保护额度。Codex 的实现兜底只用于阻塞交付的关键路径。
## 4. 自动派发和接管协议
1. Orchestrator 先创建 short-term、认领 mutex、建立独立 worktree;之后才启动或选择 agent。
2. 实例必须使用上表逻辑名,且 `cwd` 必须与任务 worktree 完全相同。派发器不会占用名称不规范或其他目录的实例。
3. 只向 `idle` / `done` 实例投递。同一 mutex 同时只允许一个执行者写入。
4. 以下情况可自动尝试下一个备援:实例不存在、启动前已 blocked、认证失败、明确额度耗尽、客户端在写入前失败。
5. Agent 只有在尚未写文件、未运行有副作用命令时,才可返回派发器给出的本次唯一 `HERDR_RETRY:<dispatch-id>:<reason>` 行触发降级。
6. `timeout`、`agent_prompt_stalled`、`unknown` 或无终态标记均不能证明任务未执行;派发器必须停止,不得盲目重投。先读取 pane,必要时写 handoff。
7. 接管前确认原实例不再 `working`;有部分改动时由原实例或 orchestrator 写 handoff,备援串行续作,不得并发覆盖。
8. Review 可由不同 worktree 的多个只读实例并行;写任务仍受 mutex 单写者约束。
## 5. 自动审批不是无限授权
统一入口为 [`scripts/herdr-agent-start.sh`](../../scripts/herdr-agent-start.sh)。当前安装版本验证过的参数如下:
| profile | 自动审批参数 | 保留的边界 |
|---------|--------------|------------|
| Claude | `--dangerously-skip-permissions` | 仍受本规范和任务提示约束 |
| Codex | `--ask-for-approval never --sandbox workspace-write` | 保留 workspace 沙箱;失败回传模型,不询问人工 |
| Cursor | `--force --sandbox enabled --approve-mcps --trust` | 保留 Cursor 沙箱和显式 deny |
| Antigravity | `--dangerously-skip-permissions --sandbox` | 保留其终端沙箱 |
| PI | `--approve` | 信任项目本地文件;该 CLI 没有独立的逐工具审批开关 |
| Kimi | `--auto` | Never Ask 模式 |
| Cline | `--tui --auto-approve true` | 所有工具自动批准 |
即使客户端不弹确认框,Agent 也不得自行执行:删库/清空数据、强推、删除主干或 worktree、停止 Herdr server、覆盖其他 Agent 未合并改动、泄露密钥、未获用户授权的外部写入。需要新权限时写 handoff/blocker,不把确认框转交给用户逐条点击。
## 6. 操作入口
在任务 worktree 的 Herdr pane 中启动标准实例:
```bash
./scripts/herdr-agent-start.sh codex orchestrator_codex <pane-id>
./scripts/herdr-agent-start.sh cursor implementer_cursor <pane-id>
```
预览某泳道路由,或自动投递:
```bash
./scripts/herdr-agent-dispatch.sh --explain implementation
./scripts/herdr-agent-dispatch.sh implementation "读取任务文并完成已认领范围,验证后写 handoff。"
```
派发器只处理规范命名且已在线的实例,不擅自创建 pane、不重启 agent、不抢集成槽。缺少实例时由 orchestrator 用启动脚本补齐。
## 7. 当前可用性基线
2026-09-13 现场基线:Herdr client/server 0.9.0、协议 22;Claude/Codex/Cursor/Antigravity/PI/Kimi 集成已安装且 current;Cline CLI 3.0.61 可调用,但尚无在线标准命名实例;Devin 尚未接入。在线状态是瞬时信息,派发前必须重新运行 `herdr agent list`。
@@ -0,0 +1,37 @@
---
title: "受控文档正文修复真实 UI 实战验收"
status: done
owner: verifier_antigravity
branch: fix/controlled-content-ui-acceptance
mutex: document-content-ui-acceptance
created: 2026-09-14
updated: 2026-09-14
---
# 目标
仅通过真实浏览器页面操作,验证项目 143 历史文档恢复,并以真实产品 PI Agent Runner / 智能体小队完成新项目文档全链路。API、数据库和 stub 不能替代 UI 验收结果。
# 范围
- 项目 143:登录、打开正文、30 秒空闲、双击编辑保存、三种变更视图、刷新与重新登录持久化。(clean-run3 已全部 PASS)
- 新项目:从 UI 创建,真实对话触发工作流/小队生成文档,再次对话触发修改;页面查看助手回复、文档正文、版本账本、影响、风险、开放问题。(full-chain-final UI-00..UI-16 全部 18 项 PASS)
- 冲突与权限:双页面并发编辑、审核人/无关用户访问边界均通过;宿主容器重启后 post-restart 复验通过。
- Ubuntu Server 浏览器:统一使用 Playwright 官方 `mcr.microsoft.com/playwright:v1.63.0-noble` 容器。
# 红线
- 不用 API 直建用户、项目、会话、文档或测试数据。
- 不注入/伪造 assistant 消息、文档、账本、change report 或通过结果。
- 所有通过项必须有页面可见证据;失败如实记录为 FAIL。
- 测试账号凭证只读本机既有 secrets/phase 文件,不输出、不提交。
# 阶段判据与进展
- [x] 项目 143 页面正文可见且无 content/revision 404(UI-143-01..06 全 PASS,产物在 `clean-run3/`)。
- [x] 人工编辑、视图切换、刷新/重登持久化通过(项目 143 回归)。
- [x] 新项目真实 PI/小队链路及文档影响风险报告页面可见(UI-00..05b 通过,首轮 toolbar V2/r0,UI-05 pending 保持 V2,UI-05a 确认后晋升 V3,UI-05b 拒绝后保持 V3)。
- [x] UI-06 硬刷新正文保留通过(合入 08bf615 修复后 1.1 秒内秒级通过)。
- [x] 并发、权限、重启前凭据生成有真实 UI 判定(UI-12/13a/13b/15/16 全 PASS)。
- [x] 容器重启后恢复核验通过(UI-15 post-restart 2.8 秒秒级通过,V3/r2 与标记完好呈现,目标 404=0)。
- [x] 测试报告落盘至 `.doc/test-reports/2026-09-14-controlled-content-ui-acceptance.md`。
@@ -0,0 +1,42 @@
---
title: "运行时 UI 证据计数与 race 秒数纠错"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/document-revision-evidence-count
worktree: "-"
mutex: document-revision-evidence-count
---
# 运行时 UI 证据计数与 race 秒数纠错
## 目标
把顶层截图写成 21(20 main/pre + 1 post),并把全包 race 写成 `FAIL 109.279s`,不与 21 条 results 混淆。
## 范围
- 最终报告、UI checklist、CURRENT
- 本短任务登记后即关闭
## 非目标
- 不改业务代码、assets、容器,不 push
- 不改 UI PASS 判定,不提交 secrets
## 步骤
1. [x] 从 `dev@5d79da6` 开 `fix/document-revision-evidence-count` 并登记
2. [x] 截图 21 = 20 main/pre + 1 post;race `FAIL 109.279s`
3. [x] `git diff --check`;只提交文档
## 验收标准
- [x] 报告/清单不再把 20 张截图与 21 条 JSON 混写
- [x] 全包 race 不再写成 `ok ... 110.723s`
- [x] assets 未 stage
## 相关链接
- Test report: [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
@@ -0,0 +1,45 @@
---
title: "文档账本运行时 UI 最终报告收口"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Cursor-Auto
branch: feature/document-revision-runtime-ui-final-report
worktree: "-"
mutex: document-revision-runtime-ui
---
# 文档账本运行时 UI 最终报告收口
## 目标
在 `dev@b258ab8` 上只写文档,把 Round20 真实 UI 验收收口为 test-report,并释放运行时集成槽。
## 范围
- `.doc/test-reports/2026-09-14-document-revision-runtime-ui-test-report.md`
- management report、UI checklist、runtime / PG-id 文档、FEATURE-MATRIX、gap-matrix、CURRENT
## 非目标
- 不改业务代码、不跑容器、不 push、不提交 assets
- 不引用 `phase-secrets.local.json` 内容
- 不把全仓标 `production_ready=yes`
## 步骤
1. [x] 从 `dev@b258ab8` 开 `feature/document-revision-runtime-ui-final-report`
2. [x] 按 results JSON 写 Input/Actual/Verdict/Duration
3. [x] 同步任务文档并释放集成槽
4. [x] 原子 docs commit
## 验收标准
- [x] 运行时范围 PASS/done
- [x] `production_ready` 仍为 no;`CHAT-INTENT` 保留
- [x] 历史失败资产未改删
## 相关链接
- Test report: [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
- Checklist: [../checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](checklists/2026-09-13-document-revision-runtime-ui-acceptance.md)
@@ -0,0 +1,47 @@
---
title: "文档账本运行时会话关闭归档"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Cursor-Auto
branch: feature/document-revision-session-close
worktree: "-"
mutex: document-revision-session-close
---
# 文档账本运行时会话关闭归档
## 目标
按 AGENTS 会话关闭清单:把已 done 的 document-revision short-term / checklist / handoff 迁入 archive,并修好相对链接。
## 范围
- `.doc/ops/short-term/*document-revision*`
- 4 个专项 checklist + runtime-ui-acceptance
- 4 个 document-revision handoff
- `.doc` 内因移动失效的相对链接
- 本任务完成后一并归档
## 非目标
- 不改业务代码、assets、容器,不 push
- 不改 `production_ready=no`、fallback / race 结论
- 不改非 document-revision 任务
## 步骤
1. [x] 从 `dev@4bf8b6d` 开 `feature/document-revision-session-close` 并登记
2. [x] short-term / checklist / handoff 标 done 后 `git mv` 入 archive
3. [x] 扫描并重写失效相对链接;`git diff --check`
## 验收标准
- [x] CURRENT 焦点仅非 DOCREV;槽位 idle
- [x] 本次移动文件的相对 Markdown 链接可解析
- [x] assets 未 stage
## 相关链接
- Test report: [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
- CURRENT: [CURRENT](../../ops/CURRENT.md)
@@ -0,0 +1,48 @@
---
title: "项目 143 受控文档正文 404 现场诊断"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Codex
branch: fix/project143-controlled-content-404-diagnosis
worktree: "-"
mutex: docgov-content-diagnosis
---
# 项目 143 受控文档正文 404 现场诊断
## 目标
定位已登录用户打开项目 143 时 `doc_proj143_intake` 正文接口返回 404 的当前根因,并形成可复核的整改边界。
## 范围
- 对照当前 dev 源码、数据库、工作区文件与既有真实 UI 证据。
- 分析服务端 404 条件、前端 hydration 与重复请求条件。
- 形成审计记录和整改建议;本轮不修改业务代码。
## 非目标
- 不恢复或覆盖用户文档数据。
- 不以 API 探针或伪造数据替代后续真实浏览器验收。
- 不继续纯软件项目自举方案实施。
## 步骤
1. [x] 核对项目 143 的项目、文档记录、账本与工作区事实源。
2. [x] 核对正文 handler 的 404 分支和前端 hydration 重试条件。
3. [x] 记录根因、影响范围、整改顺序和验收要求。
## 验收标准
- [x] 404 的直接原因与数据/代码证据相互印证。
- [x] 明确区分历史项目数据缺口、当前能力回归和前端错误放大。
- [x] 不宣称未执行的浏览器或真实 PI 结果。
## 相关链接
- Audit: [../../audit/2026-09-14-project143-controlled-content-404.md](../../audit/2026-09-14-project143-controlled-content-404.md)
## 证据 / 备注
结论:文件存在;raw/canonical 哈希因 5 处 Markdown 双空格硬换行产生 10-byte 差异。该空格具有渲染语义,须保全原文修复。详见 Audit 与 Remediation。
@@ -0,0 +1,51 @@
---
title: "移除 Herdr 工作与角色设定"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Cursor-Auto
branch: feature/remove-herdr-agent-settings
worktree: "-"
mutex: agent-collab-docs
---
# 移除 Herdr 工作与角色设定
## 目标
从仓库活文档与脚本中移除 Herdr Agent 角色、审批、备援与派发设定,协作规范回到通用 AGENTS / worktree / mutex 流程。
## 范围
- 删除 `scripts/herdr-agent-start.sh`、`scripts/herdr-agent-dispatch.sh`
- 归档 roster / 相关 handoff
- 从 `AGENTS.md`、`PROJECT.md`、`.doc/README.md` 去掉 Herdr 专章与索引
## 非目标
- 不改写历史 audit / remediation / 已归档任务中的执行者名(如 `implementer_cursor`)作为证据
- 不卸载本机 Herdr 客户端
## 步骤
1. [x] 从 `dev` 开 `feature/remove-herdr-agent-settings` 并认领
2. [x] 移除活文档与脚本中的 Herdr 设定
3. [x] 归档 roster / handoff 并更新 CURRENT
4. [x] 提交
## 验收标准
- [x] 活文档与 `scripts/` 无 Herdr 角色/派发入口
- [x] 历史证据在 `archive/` 可追溯
## 相关链接
- Roster(已归档): [./2026-09-13-herdr-agent-roster.md](./2026-09-13-herdr-agent-roster.md)
- 既有治理归档: [./2026-09-13-herdr-agent-governance.md](./2026-09-13-herdr-agent-governance.md)
- Handoff(已归档): [./handoffs/2026-09-13-herdr-agent-governance.md](./handoffs/2026-09-13-herdr-agent-governance.md)
## 证据 / 备注
- 删除:`scripts/herdr-agent-start.sh`、`scripts/herdr-agent-dispatch.sh`
- 文档:去掉 `AGENTS.md` §6.6、`PROJECT.md` §10 Herdr 章与索引行、`.doc/README.md` roster 入口
- 归档:roster + handoff → `.doc/archive/ops/`
@@ -0,0 +1,51 @@
---
title: "纯软件项目自举工作流方案"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Codex
branch: feature/software-project-bootstrap-plan
worktree: "-"
mutex: workflow-design
---
# 纯软件项目自举工作流方案
## 目标
基于当前 Agent-System 的真实能力,设计一套可创建、可配置、可冻结、可执行、可验收的纯软件项目自举工作流,并明确复用智能体小队、文档模板、权限与阶段门禁的实施路线。
## 范围
- 当前项目创建、工作流、阶段、文档、智能体小队和 UI 能力盘点
- 纯软件项目的创建选项、阶段模型、交付物、门禁、角色与小队设计
- 从最小可用版本到完整自举闭环的实施拆分、数据迁移、API/UI 与验收计划
## 非目标
- 本轮不修改 Go、React、数据库迁移、模板或智能体配置
- 不把医疗器械合规要求默认带入纯软件项目
- 不宣称尚未实现的方案已经可用
## 步骤
1. [x] 盘点当前实现与可复用能力
2. [x] 完成详细系统设计和创建向导设计
3. [x] 给出分阶段实施与真实验收计划
4. [x] 更新 FEATURE-MATRIX、CURRENT 并完成文档校验
## 验收标准
- [x] 方案覆盖工作流、文档、智能体小队、角色权限、项目创建选项、状态机、API/UI、迁移和验收
- [x] 清楚区分已实现、可复用、需新增和暂缓项
- [x] 自举机制有边界、有人工确认点且不会让智能体自行修改治理规则
## 相关链接
- Research: [../../ops/research/2026-09-14-software-project-bootstrap-current-state.md](../../ops/research/2026-09-14-software-project-bootstrap-current-state.md)
- Design: [../../system-design/2026-09-14-software-project-bootstrap-workflow.md](../../system-design/2026-09-14-software-project-bootstrap-workflow.md)
- Checklist: [../../ops/checklists/2026-09-14-software-project-bootstrap-acceptance.md](../../ops/checklists/2026-09-14-software-project-bootstrap-acceptance.md)
## 证据 / 备注
本轮为设计任务;所有当前态结论已回链源码、迁移或现有测试报告。主方案 599 行,验收计划 207 行;`git diff --check` 通过,相关文档 84 条相对链接校验无坏链。未运行产品功能测试,验收清单全部保持 `NOT RUN`。
@@ -0,0 +1,40 @@
---
title: "Vite 允许 FRP Host(frp-mix.com)"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Cursor-Auto
branch: fix/vite-frp-allowed-hosts
worktree: "-"
mutex: web-devserver
---
# Vite 允许 FRP Host(frp-mix.com)
## 目标
通过 FRP 映射访问 `:3100` 时,Vite 不再拦截 `Host: frp-mix.com`。
## 范围
- `web/vite.config.ts`:`server.allowedHosts` 增加 `.frp-mix.com`
## 非目标
- 不改生产 nginx / 反向代理配置
- 不放开全部任意 Host(保持显式白名单)
## 步骤
1. [x] 在 `fix/vite-frp-allowed-hosts` 上改 `allowedHosts`
2. [x] 重启本地 Vite `:3100`
## 验收标准
- [x] 通过 `frp-mix.com`(FRP→3100)可打开开发页,不再出现 `Blocked request. This host is not allowed`
## 相关链接
- Checklist: —
- Handoff: —
- Test report: —
@@ -10,20 +10,20 @@ related_task: short-term/2026-09-13-codex-audit-p0-remediation.md
## Wave 0 — Agent 文档
- [x] AGENTS.md / PROJECT.md / CLAUDE.md — commit 31fe607
- [x] AGENTS.md / PROJECT.md / CLAUDE.md — commit 0d10c9a(原 31fe607,见 [rewrite map](../../reference/commit-rewrite-map-2026-09-13.md))
- [x] .cursor/rules — agent-collaboration + git-secrets
- [x] .doc/ops templates + CURRENT
## Wave A — P0
- [x] AUTH tasks/run + stream — commit d82021e;`task_run_authz_pg_test.go`
- [x] DB 00025 — commit b13ced6;dev/test setval
- [x] AUTH tasks/run + stream — commit 3b7b49c(原 d82021e);`task_run_authz_pg_test.go`
- [x] DB 00025 — commit 8c5dd97(原 b13ced6);dev/test setval
- [x] DATA lifecycle — dev UPDATE 47 → 0
- [x] DATA test wf — UPDATE 5 retired
## Wave B — Go 门禁
- [x] go vet ./... PASS — commit 91985a2
- [x] go vet ./... PASS — commit 3d09bd6(原 91985a2)
- [x] go test -short ./... PASS
- [x] AdvisorBrief / V0.5 / chat / kb / health / asset
@@ -32,7 +32,7 @@ related_task: short-term/2026-09-13-codex-audit-p0-remediation.md
- [x] test rebuild schema 25 — health 8081
- [x] dev docker app schema 25 — health 8080
- [x] main 冒烟 — health/ready 8000 schema 25;restart 恢复
- [x] HTTP 超时 + env status 只读 — commit 505c419
- [x] HTTP 超时 + env status 只读 — commit 0547bd5(原 505c419)
- [x] .env.dev/.env.test chmod 600
## Wave D — 文档
@@ -0,0 +1,23 @@
---
title: "PG ID 重映射收紧"
status: done
created: 2026-09-13
updated: 2026-09-14
related_task: "2026-09-13-document-revision-pg-id-remap.md"
---
# PG ID 重映射收紧
## Wave 0
- [x] `adopt*ID` 推进 counter,仅删同一对象
- [x] 临时 ID 跳过已占用键(snapshot/version/event/report/candidate)
- [x] openTemplate / human / candidate / commit / noop event 全走 adopt
- [x] 纯函数 + 高序列首次生成 PG 回归
- [x] `gofmt` / `go vet` / `go test -short ./...`
- [x] 真实 UI-03:Round20 PASS(6159 / `doc_proj6159_intake` / V2/r0)
## 完成定义
- [x] 上述实现项有测试证据
- [x] 现场 UI-03 Round20 已通过;Round19 失败归档不删
@@ -0,0 +1,23 @@
---
title: "post-restart 最终持久正文 snippet"
status: done
created: 2026-09-13
updated: 2026-09-14
related_task: "2026-09-13-document-revision-post-restart-final-snippet.md"
---
# post-restart 最终持久正文 snippet
## 本轮
- [x] `nextDurableBodySnippet`:后续成功修订覆盖旧 snippet
- [x] 冲突失败稿不成为期望正文
- [x] UI-13b 冲突断言完成后回写 `markerA1`;UI-15-pre 写出最终值
- [x] 不放宽/删除 post-restart body 断言
- [x] `npm test` / `npm run build`
- [x] 真实 UI-15 post-restart:Round20 PASS
## 完成定义
- [x] 上述实现项有单测或脚本证据
- [x] 现场 post-restart Round20 已通过;stale-snippet 失败归档不删
@@ -0,0 +1,23 @@
---
title: "post-restart 项目名 selector 收紧"
status: done
created: 2026-09-13
updated: 2026-09-14
related_task: "2026-09-13-document-revision-post-restart-selector.md"
---
# post-restart 项目名 selector 收紧
## 本轮
- [x] 点击来自侧栏可见项目入口(complementary exact title),不用 `.first()` 弱化
- [x] 恢复断言为 banner 内 exact 项目名
- [x] `UI_PHASE` 分离 `playwright-output-main|post-restart` 与 `playwright-report-main|post-restart`
- [x] 结果 JSON 分文件:`ui-acceptance-results.json`(main)与 `ui-acceptance-results-post-restart.json`;phase-state/secrets 仍共享
- [x] helper 契约测试 + `npm test` / `npm run build`
- [ ] 真实 UI-15 post-restart(本轮不做)
## 完成定义
- [x] 上述实现项有单测或脚本证据
- [ ] 现场 post-restart 仍开放,不得标 done
@@ -0,0 +1,25 @@
---
title: "项目 reviewer 职责同步收紧"
status: done
created: 2026-09-13
updated: 2026-09-14
related_task: "2026-09-13-document-revision-reviewer-duty-sync.md"
---
# 项目 reviewer 职责同步收紧
## 最后一轮严格修复
- [x] 移出成员后端 reconcile + `ERR_DUTY_SYNC`;前端 `afterProjectMemberPersisted` 刷新文档
- [x] Heal 空 assigned 仅清退出/非成员;在任成员保留;author 不清空
- [x] 显式 revoke:reviewer→viewer、职责转移、退出、幂等;author 不进撤销集
- [x] `CreateOrGetDocument` 失败任务不成功;fault test
- [x] 成员 upsert/退出:advisory lock、读旧/冲突 holder、成员更新、`document_records` 精确清槽同一事务;提交后 heal;失败 `ERR_DUTY_SYNC`
- [x] `HealProjectDocuments` 与成员写同锁键/顺序;解析与文档更新同事务;转移后旧 holder 不复活;第二次 heal 幂等
- [x] `gofmt` / `go vet` / `go test -short` / 相关 `-race` / `npm test` / `build` / 隔离 PG
- [ ] 真实 UI-13a(本轮不做)
## 完成定义
- [x] 上述实现项有测试或隔离 PG 证据
- [ ] 现场 UI-13a 仍开放,不得标 done
@@ -0,0 +1,149 @@
---
title: "文档版本账本运行时 — Ubuntu Server 无头浏览器真实 UI 验收计划"
status: done
created: 2026-09-13
updated: 2026-09-14
---
# 文档版本账本运行时 — Ubuntu Server 无头浏览器真实 UI 验收计划
> **与工程门禁分离**:本文件仅描述**用户限定的最终实战验收**(浏览器页面操作)。
> **严禁**用 API 直灌、DB fixture、`page.route` mock、stub 模型、或伪造 SSE 冒充小队完成。
> 工程单测 / `go vet` / `npm test` / `npm run build` 属于「工程门禁」,见 short-term 证据区,**不能替代**本计划。
## 0. 环境前置(必须占 CURRENT 集成槽位后执行)
| 项 | 要求 |
|----|------|
| OS | Ubuntu Server 22.04+(无图形桌面亦可) |
| 服务 | `./scripts/env-service.sh dev rebuild` → `curl -sf http://127.0.0.1:8080/health`;schema ≥ 28 |
| Agent | 真实 `pi-agent` + 运行中的 `MiniMax-M2.7-highspeed` 容器(禁止 stub) |
| 账号 | ≥2 名项目成员(编制人 A、协作者 B);禁止共用 token 串号;**管理员凭据仅来自 `ADMIN_USERNAME`/`ADMIN_PASSWORD` 环境变量(禁止 spec 硬编码)** |
| 认证契约 | 真实 login/me 返回 snake_case `role_id` 等;前端须映射为 `roleId`,否则管理员入口隐藏(UI-00 已踩坑,见 audit) |
| 用户目录 | 管理员开通 A/B 后,同浏览器立项成员候选须含新账号(`onRefreshUsers` 不得死 prop);跨设备缺口见 [../../audit/2026-09-13-admin-user-directory-sync-ui01.md](../../../audit/2026-09-13-admin-user-directory-sync-ui01.md) |
| 证据根 | `.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/` |
| 报告 | `.doc/test-reports/YYYY-MM-DD-document-revision-runtime-ui-test-report.md` |
### 0.1 Ubuntu Server 无头 Playwright(Round20 实际路径)
**本轮采用官方容器,无需给 Ubuntu host 安装浏览器:**
```bash
# 测试前部署合入基线(Round20:b258ab8)
./scripts/env-service.sh dev rebuild
curl -sf http://127.0.0.1:8080/health
# 官方镜像跑页面验收(host 网络;BASE_URL 指向工作台 :3100)
docker run --rm --network host --ipc host \
-e RUN_UI_ACCEPTANCE=1 \
-e BASE_URL=http://127.0.0.1:3100 \
-v "$PWD":/work -w /work/web \
mcr.microsoft.com/playwright:v1.63.0-noble \
npx playwright test e2e/document-revision-runtime.spec.ts --project=chromium
```
**备选(本轮未走)**:宿主 `cd web && npx playwright install --with-deps chromium`。仅当不能跑官方容器时使用。
### 0.2 两阶段(验收轮)
1. `RUN_UI_ACCEPTANCE=1 UI_PHASE=main BASE_URL=http://127.0.0.1:3100` 跑主场景(写 `phase-state.json`,密码仅落本地 `phase-secrets.local.json`,不得提交)。产物:`playwright-output-main` / `playwright-report-main` / `ui-acceptance-results.json`
2. 宿主仅 `restart shuimu-agent-app-dev` 一次(PG/PI 未动;不是再次 rebuild)
3. `RUN_UI_ACCEPTANCE=1 UI_PHASE=post-restart` 仅页面登录校验 UI-15。产物:`playwright-output-post-restart` / `playwright-report-post-restart` / `ui-acceptance-results-post-restart.json`(不得覆盖 main 总账或 trace)
4. 文档收口阶段不再动容器。
证据:`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/`(trace/video/screenshot);结果 JSON 不得含凭证与 URL query。
---
## 1. 数据来源铁律(FAIL 即整轮作废)
| 允许 | 禁止(一票否决) |
|------|------------------|
| 页面登录后创建项目 | `INSERT`/`psql` 灌 document_records / snapshots |
| 页面上传附件 | 测试进程直连 Postgres 插 fixture |
| 对话输入框真实提问触发小队 | `page.route` 劫持 `/api/v1/chat` 或 SSE 返回假成功 |
| 等待真实 runner 完成 | `AgentBackend=stub` 或 mock MiniMax |
| 打开生成的文档 Tab 观察 UI | API-only 调用 PATCH/OpenTemplate 冒充「用户操作」 |
---
## 2. 用例矩阵(全部必须页面可见)
| ID | 步骤(仅 UI) | 期望页面现象 | 证据 | 判定 |
|----|---------------|--------------|------|------|
| UI-01 | 管理员开通 B 后,tech-lead A **页面创建**项目并勾选成员 | 立项成员候选含 B;项目工作台三栏可见 | 截图 `01-project.png` | PASS |
| UI-02 | 对话输入框发起真实任务(触发真实小队编排) | 助手流式回复;任务进度/文档 busy 可见;网络可见真实 agent 请求 | 截图 + trace | PASS |
| UI-03 | 等待小队**首轮**完成,打开生成的受控文档 Tab | 右侧出现文档;版本工具条 `Vn`/`r*`(非「账本未就绪」) | 截图 `03-first-doc.png` | PASS |
| UI-04 | 打开变更报告:工具条「变更报告」/「待确认报告」或版本历史「报告」 | **首轮**可见:摘要、**风险条目**、项目影响内容、各文档影响原因/建议、开放问题;加载失败显式错误非永久加载中;`fallback` 不得宣称为完整 PI | 截图 `04-first-report.png` | PASS |
| UI-05 | 同项目再触发**二轮**更新生成(真实对话) | 低/中风险:新版本+报告;**高风险**:工具条显示「待确认报告」与 pending 徽章,**版本历史尚无新 V**,打开报告可见完整字段 | 截图 `05-second-report.png` | PASS |
| UI-05a | 编制人对高风险候选点「确认提交」 | decision API `confirmed:true`;版本前进;pending 消失;历史出现带 `change_report_id` 的新版本 | 截图+网络 | PASS |
| UI-05b | 编制人对高风险候选点「拒绝」 | 候选拒绝;pending 消失;版本号不前进;无权用户无确认/拒绝按钮或 decision 403 | 截图+网络 | PASS |
| UI-06 | 双击块编辑 → 保存 → **硬刷新** | 无冲突时工具条 `r` **立即**递增(`revisionRefreshKey`);硬刷新后正文仍为保存内容 | 截图前后对比 | PASS |
| UI-07 | 切换「纯净阅读」 | 块无琥珀/蓝色装饰底 | 截图 | PASS |
| UI-08 | 切换「人工修改」 | 相对当前 Version 的人工修订块琥珀底+下划线暗示 | 截图 | PASS |
| UI-09 | 切换「全部变更」 | 智能体+人工差异;仅人工时允许与 UI-08 相同 | 三模式并排或连续截图 | PASS |
| UI-10 | 「版本历史」+「比较」 | 抽屉列出版本;比较视图展示 hunk | 截图 | PASS |
| UI-11 | **多文档**:同项目再生成/打开第二份受控文档 + **页面上传**附件 Tab | 多 Tab 可切换;各文档 revision-state 独立;附件可预览 | 截图 | PASS |
| UI-12 | 用户 C 打开无权限项目(非成员) | 项目不可见,**不泄漏正文** | 截图 + 网络 403/404 | PASS |
| UI-13 | 拆为 13a reviewer 只读 + 13b A/A 同 r 冲突 | B 无正文编辑;A2 `409 DOCUMENT_HEAD_CONFLICT` 保留草稿 | 双 context 截图 | PASS |
| UI-14 | A 退出 → **重登录** → 打开同一文档 | revision-state 200;正文与 `r` 与退出前一致 | 截图 | PASS |
| UI-15 | (集成槽内)**重启 app 容器**后再打开同一文档 | 账本与正文仍可恢复;非「未就绪」除非确无事实源 | 截图 + `docker restart` 日志摘录 | PASS |
| UI-16 | 页面上传经 freeform 注册后打开;禁止 `doc-upload` 假账本 | 已注册 `doc-free-*` 工具条 V 可见;无 orphan revision-state | 截图 | PASS |
---
## 3. 证据要求(归档规范)
| 类型 | 路径约定 | 最低要求 |
|------|----------|----------|
| 截图 | `assets/.../screenshots/UI-XX-*.png` | 每用例 ≥1;UI-07/08/09 必须能看出三模式差异 |
| Trace | `assets/.../traces/UI-XX.zip`(Playwright trace) | 失败用例必留;PASS 建议全留 |
| 录像 | `assets/.../videos/*.webm` | 首轮生成 + 二轮报告 + 双人冲突 必留 |
| 网络摘录 | 报告正文粘贴关键响应 | `revision-state` 200;`change-reports` 含 summary/risk/open_questions;禁止贴 token |
报告正文每个用例必须含:**Input(页面操作)** / **Actual(可见文本+状态码)** / **Verdict PASS|FAIL** / **Duration**。
---
## 4. 失败标准(任一即 FAIL)
1. 使用 stub / `page.route` mock / DB fixture / 纯 API 灌库冒充 UI 路径
2. 首轮成功生成后仍无变更报告入口,或报告摘要为固定假句「智能体交付物已生成」;或报告面板缺少风险条目/项目影响/文档影响原因建议/开放问题
2b. 高风险二轮仅有小队成功文案但工具条无「待确认报告」、或未确认就静默进版本历史、或 `confirmed:false` 仍提交成功
3. 把 `analysis_status=fallback` 文案写成「PI 完整分析」或隐瞒开放问题
4. 人工保存返回成功但刷新丢正文,或投影失败仍 200
5. 三 overlay 视觉无差异(截图无法区分)
6. 双上下文后写静默覆盖
7. 无权限用户可见正文片段
8. 容器重启后受控已落盘文档仍永久「账本未就绪」(在确有 output.md / 记录的前提下)
9. 证据目录缺失或无法打开 trace/截图复盘
---
## 5. 通过标准
- UI-01…UI-16 全部 PASS,证据归档完整
- 工程门禁另栏 PASS(不记入本计划勾选)
- 已知 blocker `DOCREV-RT-PI-NARRATIVE`:允许 fallback,但必须可见真实 diff 摘要 + 开放问题标明叙事待补
- `DOCREV-RT-UPLOAD-ORPHAN`:UI-16 按空状态 PASS,不得伪造成功账本
---
## 6. 与工程门禁对照
| 类型 | 命令/产物 | 可否代替 UI 验收 |
|------|-----------|------------------|
| 工程 | `go vet ./...`;`go test -short ./...`;`cd web && npm test && npm run build` | **否** |
| PG 可选 | `TEST_DATABASE_URL=... go test ./internal/docrevision -run TestPGPersist` | **否** |
| 本计划 | Playwright 无头真实页面 + 真实小队 | **是(唯一最终)** |
## 7. 本轮状态
- Round20(2026-09-14)真实页面验收 **PASS**:results JSON 21/21;Playwright main 18 passed / 1 post skipped;仅 `restart shuimu-agent-app-dev` 后 post 1 passed / 18 skipped。
- 测试前 `env-service.sh dev rebuild` 部署 `b258ab8`;文档收口不再动容器。
- 项目 `UI验收-超声微创系统-mu0gwiez`(6159);intake `doc_proj6159_intake`;终态 V3/r2 / `A1-win-mu0gwiez`。
- 报告:[../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
- Ubuntu 无头:`mcr.microsoft.com/playwright:v1.63.0-noble`(`--network host --ipc host`,`BASE_URL :3100`);本次无需给 host 装浏览器。宿主 `npx playwright install` 仅备选。
- 顶层截图 **21** 个文件:主阶段 20 张(含 UI-15-pre)+ post-restart 1 张;与 results JSON 21 条不是同一计数。
- 工程门禁另栏:`go test -short` / `go vet` / web 333+30 / build PASS;`-race` 全包并行 **NOT PASS**(`TestCreateTaskRun_PreActivationAcceptedNot409` TempDir cleanup)。
- 全仓仍 `production_ready=no`(`CHAT-INTENT` 等)。
@@ -0,0 +1,57 @@
---
title: "PG ID 重映射:Round20 后关闭"
created: 2026-09-13
updated: 2026-09-14
from: Cursor-Auto
to: next-agent
status: done
---
# 交接:PG ID 重映射(已合入并经 Round20 验证)
## 目标(下一位 Agent 应完成什么)
- 不要重开本缺陷,除非新现场再次出现 `CommitAgentVersion` not found
- 不要改删 Round19 失败归档
- 全仓焦点已离开文档运行时 UI;勿占用已释放的 DOCREV-RT 集成槽,除非新任务登记
## 已完成
- 统一 `advanceID` / `nextFreeID` / `adopt*ID`
- 隔离 PG 高序列首次生成:baseline 不丢、重启 hydration
- 合入 `dev@b258ab8`
- Round20 真实 UI-03:项目 6159 首次生成 V2/r0,不再 `docrevision: not found`
## 未完成
- 无(本缺陷)。PI 叙事 fallback 与 `CHAT-INTENT` 属其他条目
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | yes |
| 集成槽位 holder | idle(运行时 UI 收口后释放) |
| branch | 已合入 `dev`(`merge: fix/document-revision-pg-id-remap`) |
| worktree | - |
## 关键文件
| 路径 | 说明 |
|------|------|
| `internal/docrevision/ids.go` | counter / adopt |
| `internal/docrevision/pg_mutate.go` | PG 写入后 adopt |
| `internal/docrevision/pg_id_remap_test.go` | 隔离 PG 碰撞 |
## 如何验证
见 [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)。不要把 output snapshot 250 写成 candidate 250(6158 现场:candidate id=175、output snapshot id=250、report id=175)。
## 风险 / Blocker
- 不得把 `ErrNotFound` 改成忽略
## 相关链接
- CURRENT: [../CURRENT.md](../../../ops/CURRENT.md)
- Task: [../short-term/2026-09-13-document-revision-pg-id-remap.md](../2026-09-13-document-revision-pg-id-remap.md)
@@ -0,0 +1,40 @@
---
title: "post-restart 最终正文 snippet:Round20 后关闭"
created: 2026-09-13
updated: 2026-09-14
from: Cursor-Auto
to: next-agent
status: done
---
# 交接:post-restart 最终正文 snippet(已验证)
## 目标(下一位 Agent 应完成什么)
- 不要改删 `schema31-postrestart-stale-body-snippet-failure`
- 不要删除 post-restart `bodySnippet` 可见断言
- 新 UI 轮次必须继续把 UI-13b A1 成功正文写入 phase-state
## 已完成
- `durableBodySnippet`:成功修订覆盖;冲突稿不入账
- UI-13b / UI-15-pre 同步最终 marker
- Round20 post-restart:login / 项目 6159 / `revision-state` 200 / V3/r2 / `A1-win-mu0gwiez`
## 未完成
- 无(本缺陷)
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | yes |
| 集成槽位 holder | idle |
| branch | 已合入 `dev` |
| worktree | - |
## 相关链接
- Test report: [../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
- Task: [../short-term/2026-09-13-document-revision-post-restart-final-snippet.md](../2026-09-13-document-revision-post-restart-final-snippet.md)
@@ -0,0 +1,70 @@
---
title: "post-restart 项目名 selector:编码后交接"
created: 2026-09-13
from: Cursor-Auto
to: next-agent
status: done
updated: 2026-09-14
---
# 交接:post-restart 项目名 selector(暂不合入)
## 目标(下一位 Agent 应完成什么)
- 不要在本分支继续改职责/业务语义
- 合入前占 CURRENT 集成槽位;本轮禁止 merge / 重建容器 / 声称 post-restart 通过
- 占槽后重跑 `UI_PHASE=post-restart`,确认 UI-15 走到 revision-state
## 已完成
- post-restart:侧栏 exact title 点击 + banner exact 项目名断言
- Playwright 产物按 `UI_PHASE` 分目录,避免第二阶段覆盖主阶段
- 结果 JSON:main 仍写 `ui-acceptance-results.json`;post-restart 写 `ui-acceptance-results-post-restart.json`;`phase-state` / secrets 共享
- helper 契约测试;`npm test` / `npm run build`
## 未完成
- 真实 UI-15 post-restart
- 合入 `dev`
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | no(`document-revision-post-restart-selector` 仍 `in_progress`) |
| 集成槽位 holder | 他人 e2e;本任务未占槽 |
| branch | `fix/document-revision-post-restart-selector` |
| worktree | - |
> 若 mutex 未释放,下一位须先在 CURRENT 认领或写 blocker。
## 关键文件
| 路径 | 说明 |
|------|------|
| `web/src/lib/currentProjectRestore.ts` | 入口 / banner locator 契约 |
| `web/src/lib/playwrightPhaseArtifacts.ts` | 阶段目录名 |
| `web/e2e/document-revision-runtime.spec.ts` | post-restart UI-15 |
| `web/playwright.config.ts` | 分阶段 outputDir / HTML report |
## 如何验证
```bash
cd web && npm test && npm run build
# 真实 UI(本轮不做):
# RUN_UI_ACCEPTANCE=1 UI_PHASE=post-restart npx playwright test e2e/document-revision-runtime.spec.ts
```
产物:`playwright-output-main` / `playwright-report-main` / `ui-acceptance-results.json` 与 `playwright-output-post-restart` / `playwright-report-post-restart` / `ui-acceptance-results-post-restart.json`。`phase-state.json` 与 `phase-secrets.local.json` 跨阶段共享;`UI-15-post-restart.png` 可与主阶段截图同目录。
## 风险 / Blocker
- 侧栏折叠时 complementary 入口不可见,应 FAIL 而非 `.first()` 跳过
- 不得改删 schema31 失败归档
## 相关链接
- CURRENT: [../CURRENT.md](../../../ops/CURRENT.md)
- Task: [../short-term/2026-09-13-document-revision-post-restart-selector.md](../2026-09-13-document-revision-post-restart-selector.md)
- Checklist: [../checklists/2026-09-13-document-revision-post-restart-selector.md](../checklists/2026-09-13-document-revision-post-restart-selector.md)
@@ -0,0 +1,73 @@
---
title: "reviewer 职责同步:heal 同事务锁后交接"
created: 2026-09-13
from: Cursor-Auto
to: next-agent
status: done
updated: 2026-09-14
---
# 交接:reviewer 职责同步(暂不合入)
## 目标(下一位 Agent 应完成什么)
- 不要在本分支继续改职责语义,除非新审查点
- 合入前占 CURRENT 集成槽位,再 `--no-ff` 合 `dev`;本轮禁止 merge / 重建容器 / 声称 E2E
- 6145 的 B 仍是空 `document_duty`,须再走成员 API 写成 reviewer 后自愈才会对齐文档
## 已完成
- Heal 以 assigned 为权威;空 assigned 只清失效审核/批准 holder
- 成员增改/移出:同一事务内 advisory lock + 读旧/冲突 holder + 成员写 + 精确清 reviewer/approver 槽;提交后服务层 heal 新 holder
- `HealProjectDocuments` 与成员写共用 `pg_advisory_xact_lock(project_id)`;解析与文档读写同事务;错误回滚
- 确定性并发 PG:成员写持锁未提交时 heal 进入 `pg_locks` 等待;提交后旧 reviewer 不复活;第二次 heal 幂等
- 同步失败仍显式 `ERR_DUTY_SYNC`;author 不因普通成员变更清空
- 账本创建失败任务失败
## 未完成
- 真实 UI-13a
- 合入 `dev` 与共享容器 schema 31 晋升
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | no(`document-revision-reviewer-duty-sync` 仍 `in_progress`) |
| 集成槽位 holder | 他人 e2e;本任务未占槽 |
| branch | `fix/document-revision-reviewer-duty-sync` |
| worktree | - |
> 若 mutex 未释放,下一位须先在 CURRENT 认领或写 blocker。
## 关键文件
| 路径 | 说明 |
|------|------|
| `internal/docduty/revoke.go` | `AcquireProjectDutyLock`(与成员写同键) |
| `internal/docduty/store.go` | heal lock + 解析 + 回填同事务 |
| `internal/authz/authorizer.go` | upsert / setStatus 走同一 lock helper |
| `scripts/run-isolated-duty-sync-pg-tests.sh` | 隔离 PG 入口 |
## 如何验证
```bash
go test -short ./...
go test -short -race ./internal/docduty ./internal/authz ./internal/bizdev ./internal/server
cd web && npm test && npm run build
# 隔离库,禁止 agent_system_dev:
./scripts/run-isolated-duty-sync-pg-tests.sh
```
## 风险 / Blocker
- 旧项目未写 `document_duty` 时,在任成员仍留在文档槽位(有意兼容)
- 显式降级/退出才会撤 reviewer/approver;author 永不被 revoke
- 6145 B 不会被臆造为 reviewer
## 相关链接
- CURRENT: [../CURRENT.md](../../../ops/CURRENT.md)
- Task: [../short-term/2026-09-13-document-revision-reviewer-duty-sync.md](../2026-09-13-document-revision-reviewer-duty-sync.md)
- Checklist: [../checklists/2026-09-13-document-revision-reviewer-duty-sync.md](../checklists/2026-09-13-document-revision-reviewer-duty-sync.md)
@@ -0,0 +1,65 @@
---
title: "Herdr Agent 治理分支待集成交接"
created: 2026-09-13
from: Codex
to: next-integration-holder
status: closed
---
# 交接:Herdr Agent 治理分支待集成
> **superseded 2026-09-14**:Herdr 角色/脚本已从活文档移除;本交接仅作历史证据。见 [.././2026-09-14-remove-herdr-agent-settings.md](.././2026-09-14-remove-herdr-agent-settings.md)。
## 目标(下一位 Agent 应完成什么)
治理规范已完成并准备合入 `dev`;本文件保留为集成证据。
## 已完成
- 已建立角色、任务泳道、额度保护、自动审批和故障接管 SSOT。
- 已提供七种 profile 的统一启动脚本和保守派发脚本。
- 已验证脚本语法、全部 profile dry-run、全部 route、错误标准名和无实例安全退出。
## 未完成 / 后续
- 未推送远端(用户未要求)。
- Cline 已安装且可调用,但标准命名 Herdr 实例仍需一次只读和一次隔离 worktree 写验收后才能升为 active。
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | yes |
| 集成槽位 holder | 未操作共享容器 |
| branch | `feature/herdr-agent-governance` |
| worktree | `.worktrees/feature-herdr-agent-governance` |
## 关键文件
| 路径 | 说明 |
|------|------|
| `.doc/archive/ops/2026-09-13-herdr-agent-roster.md` | 角色与路由 SSOT(已归档) |
| `scripts/herdr-agent-start.sh` | 免人工审批启动入口(已删除) |
| `scripts/herdr-agent-dispatch.sh` | 主备派发与防重复策略(已删除) |
| `AGENTS.md` / `PROJECT.md` | 强制入口与 PI 身份边界 |
## 如何验证
```bash
bash -n scripts/herdr-agent-start.sh scripts/herdr-agent-dispatch.sh
./scripts/herdr-agent-start.sh --dry-run codex orchestrator_codex w1:p1
./scripts/herdr-agent-dispatch.sh --explain implementation
git diff --check
```
## 风险 / Blocker
- `CURRENT.md` 是活文档;合并时以最新 `dev` 的 holder、phase、scope 为准,仅保留本任务认领或完成记录。
- 不要因为 `timeout` / `agent_prompt_stalled` 自动重投任务。
- 不要为验证本分支重启现有 DOCREV 实例或操作共享 Docker。
## 相关链接
- CURRENT: [CURRENT.md](../CURRENT.md)
- Task: [2026-09-13-herdr-agent-governance.md](./2026-09-13-herdr-agent-governance.md)
- Checklist: 任务文中的验收标准
@@ -0,0 +1,43 @@
# Commit SHA 重写对照表(2026-09-13)
> **背景**:2026-09-13 将 358 个线性 `dev` commit 按 14 个功能史诗重放为 `feature/*` / `fix/*` + `merge --no-ff` 拓扑(策略 A)。
> **代码树**:`git diff backup/pre-rewrite-2026-09-13 dev` 为空——HEAD 实现与重写前一致。
> **旧线性历史**:本地保留于分支 `dev-old-linear` 与 tag `backup/pre-rewrite-2026-09-13`。
## 对照规则
- 匹配键:`subject | author | email | committer date`(重写前后一致)
- 下列「旧 SHA」来自 `dev-old-linear`;「新 SHA」来自重组后 `dev`
- 6 条缺 scope 的 message 已在重写中修正(如 `fix:` → `fix(quality):`)
## 关键引用(checklist / test-report)
| 旧 SHA | 新 SHA | 说明 |
|--------|--------|------|
| `d27b0ad` | `ee18e54` | 首 commit → `docs(ops):` 建立仓库基础架构 |
| `31fe607` | `0d10c9a` | AGENTS / PROJECT / CLAUDE 入口 |
| `d82021e` | `3b7b49c` | AUTH tasks/run + stream |
| `b13ced6` | `8c5dd97` | DB 00025 种子序列 |
| `91985a2` | `3d09bd6` | Go 质量门禁(message 修正为 `fix(quality):`) |
| `505c419` | `0547bd5` | HTTP 超时 + env status 只读 |
| `8f3aa0f` | `c605993` | pi-agent MiniMax 模型对齐 |
| `abd0893e` | `f75e509` | StepEvaluator 实现 |
| `bb3f3a1` | `73bf082` | pi-agent E2E v5 PASS |
| `99e0d4a` | `096dc8a` | long-task recovery UX |
| `56fb318` | `d03d939` | chat SSE wiring scope |
| `33b1b8b` | `511864b` | doc taxonomy scaffold |
| `5e5bc1f` | `f30886e` | 策略 A 分支规范 |
## 新历史拓扑
- 1 个 root anchor + 358 原子 commit + 14 个 `merge --no-ff` = **373 commit**
- 史诗清单:[`scripts/history-epic-manifest.tsv`](../../../scripts/history-epic-manifest.tsv)
- 重放脚本:[`scripts/rewrite-history-epics.sh`](../../../scripts/rewrite-history-epics.sh)
## 全量映射生成
```bash
python3 scripts/generate-commit-rewrite-map.py > /tmp/full-map.tsv
```
(脚本随 `feature/chore-history-rewrite` 一并入库)
@@ -0,0 +1,55 @@
---
title: "管理员开通账号后立项成员候选缺失(UI-01)"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# 管理员开通账号后立项成员候选缺失(UI-01)
## 现象
Antigravity 真实 UI:UI-00 管理员入口已 PASS。UI-01 产品失败——管理员经 UI 成功创建账号 B,但 tech-lead A 打开「新建项目」时成员候选列表中无 B。
## 根因分析
1. `AdminSettingsModalProps` 已声明 `onRefreshUsers`;`App` 已传入 `getAdminUsers → setAllUsers`。
2. 组件 **destructuring 漏掉** `onRefreshUsers`,成为死 prop。
3. 模态内 `refreshUsers()` 仅 `setAdminUsers`,创建/角色/状态成功后从未同步父级 `allUsers`。
4. `CreateProjectModal` / `ProjectMembersModal` 的 `availableUsers` 来自 App `allUsers`(并经 `saveUsers` 写入 localStorage),故同会话内立项候选仍是旧目录。
5. 附带:App 原 `onRefreshUsers` 用 `.catch(() => {})` 静默吞错,即使接线也会掩盖同步失败。
## 严重度
`high`(同浏览器管理员开通后立项立刻缺人;阻断 UI-01)
## 本轮修复(本任务范围内)
- 抽出可测 helper:`web/src/lib/adminUserDirectorySync.ts`(缺 `onRefreshUsers` / 父级抛错均 fail-closed)
- `AdminSettingsModal` 正确 destructure;创建/角色/状态/审批/重置后 `await refreshUsers()`;同步失败对用户可见
- `App` `onRefreshUsers` 改为 async 上抛,禁止静默
## 残留审计风险(本任务不越权补齐)
| 风险 ID | 说明 | 为何本轮不修 |
|---------|------|--------------|
| **DOCREV-RT-USER-DIR-CROSS-DEVICE** | 立项成员目录仍以浏览器 `allUsers`/localStorage 为事实源。tech-lead 在**新设备 / 清缓存 / 从未在本机跑过管理员同步**的会话中,即使服务端已有 B,本地候选仍可能只有 MOCK/`loadUsers` 缓存。非管理员无 `GET /api/v1/admin/users` 权限。 | 安全补齐需**非 admin 的成员目录/搜索 API**(最小权限、按项目或组织范围),属授权面扩展;禁止把 admin users API 下放给 tech-lead。 |
相关代码锚点:`App.tsx` `availableUsers={allUsers}`;`storage.loadUsers`/`saveUsers`;服务端仅 `GET /api/v1/admin/users`。
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-runtime.md](../archive/ops/2026-09-13-document-revision-runtime.md)
- Checklist: [../ops/checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](../archive/ops/checklists/2026-09-13-document-revision-runtime-ui-acceptance.md)
- 前序 auth 映射: [2026-09-13-auth-useraccount-snake-case-mapping.md](./2026-09-13-auth-useraccount-snake-case-mapping.md)
## 证据
- 实战:UI-00 PASS;UI-01 创建 B 后 A 立项候选无 B
- 代码:`AdminSettingsModal` 原未解构 `onRefreshUsers`;App 静默 catch
- 单测:`web/src/lib/adminUserDirectorySync.test.ts`(死 prop / 父级错误上浮)
## 开放问题
- 跨设备成员目录 API(见上表)→ 记入 short-term blocker,勿用 admin API workaround
@@ -0,0 +1,39 @@
---
title: "Auth UserAccount snake_case 契约漏映射导致管理员入口隐藏"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# Auth UserAccount snake_case 契约漏映射导致管理员入口隐藏
## 现象
真实浏览器 UI-00(Antigravity):管理员登录后左侧「系统管理」入口不可见,无法开通 A/B 账号。控制台侧 `currentUser.roleId` 为 `undefined`(服务端实际返回 `role_id: "role-admin"`)。
## 根因分析
- Go `auth.UserAccount` JSON 标签为 snake_case:`role_id` / `employee_id` / `must_change_password` / `created_at` / `updated_at`。
- 前端 `AuthClient` 将 login / me / admin users 响应直接当作 camelCase `UserAccount` 使用,未在 API 边界映射。
- 既有单测使用内存 `auth.local` 或驼峰假响应,未覆盖真实 wire 契约,故漏检。
- `BootstrapAdminFromConfig` 对已存在非 admin 账号调用 `UpdateUserRole` 时静默忽略错误(`_, _ =`),可能留下非 `role-admin` 管理员配置账号。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-runtime.md](../archive/ops/2026-09-13-document-revision-runtime.md)
- Checklist: [../ops/checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](../archive/ops/checklists/2026-09-13-document-revision-runtime-ui-acceptance.md)
## 证据
- UI-00 实战:管理员登录后无系统管理入口(roleId undefined)
- `internal/auth/models.go` UserAccount json tags
- `web/src/api/auth.ts` 原直接 `resp.json()` 赋给 UserAccount
## 开放问题
- 无(映射层 + bootstrap 错误上浮已落地;占槽后需重跑 UI-00 验证管理员入口)
@@ -0,0 +1,99 @@
---
title: "刷新后对话正文消失但统计仍存在"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# 刷新后对话正文消失但统计仍存在
## 现象
用户在项目会话中可以正常与助手对话并生成文档;页面刷新后,消息正文区域显示为空,但顶部分类过滤和右侧分类锚点仍显示消息数量及首尾消息 ID。
结论:**消息没有从数据库删除,而是在刷新后的服务端历史恢复链路中被阶段权限过滤器全部剔除。统计接口没有应用同一权限范围,因此仍返回未过滤的数量和锚点。**
## 根因分析
### 1. 刷新前与刷新后使用不同消息来源
- 刷新前,`web/src/App.tsx:1634-1656` 中的组件内 `messages` 保存本轮实时消息,`useChatWindow` 将它们合并到画面。
- 刷新后,组件内 `messages` 从空数组重新开始,正文依赖 `GET /api/v1/chat/messages/window` 恢复。
- `web/src/hooks/useChatWindow.ts:112-120` 只要服务端返回非空 `days`,就用返回桶覆盖窗口和本地缓存;即使桶中的 `messages` 已被过滤为空也照常覆盖。
因此,实时画面正常不代表历史恢复链路正常。
### 2. 文档任务消息没有绑定工作流阶段
- 普通聊天路径会在 `internal/chat/session.go:267-274,425-438` 把 `ActiveStageKey` 写入用户与助手消息的 `metadata.stage_key`。
- 文档生成使用的异步任务路径在 `internal/server/task_run_handlers.go:81-96` 只写入 `project_id`、`client_turn_id`、`task_key`、`task_status`,没有写 `stage_key`、`workflow_instance_id` 或 `stage_instance_id`。
- 任务完成投影 `internal/server/task_finalize.go:58-85` 仍未补这些作用域字段。
这使得文档任务在当前页面可见,但重载后无法通过阶段可见性判定。
### 3. 工作流激活前的历史也会被追溯性隐藏
- `internal/server/stage_access_helpers.go:135-163` 在项目进入受限工作流后,明确丢弃所有 `metadata.stage_key` 为空的历史消息。
- `internal/projectinstance/stage_access.go:15-77` 根据当前 live 实例计算可见阶段;策略一旦进入 `Restricted=true`,激活前产生、天然没有阶段键的消息也无法恢复。
- `StageKeyAllowed("")` 本身在 `internal/projectinstance/stage_access.go:103-108` 返回允许,但外层过滤器在调用它之前已经对空阶段执行 `continue`;现有单测只验证前者,没有覆盖组合行为。
这不是合理的“拒绝越权”,而是缺少对 `pre_activation/legacy` 对话作用域的正式建模。
### 4. 统计与正文的授权口径分裂
- 窗口和按日正文在 `internal/server/chat_window_api.go:48-50,104-106` 应用阶段过滤。
- 分类与日期统计在同文件 `111-155` 直接查询并返回原始统计,没有会话所有权校验,也没有阶段过滤。
- `internal/ctxmgr/chat_window.go:622-749` 的 SQL 对会话内全部未删除消息聚合,返回数量及 `MIN/MAX(id)`。
- 前端 `CategoryFilterBar` 使用这些服务端统计显示数量;`CategoryDock` 还以统计中的首尾 ID 作为锚点兜底。因此正文为空时,数量与锚点仍存在。
此外,所有这些端点虽由全局中间件要求登录,但窗口、日期、分类等端点没有统一调用 `assertSessionOwnedByUser`。这会造成私聊会话对象级授权不一致,并可能泄露其他会话的消息存在性、分类数量和消息 ID。
## 运行态证据(dev,2026-09-13)
只读查询 `shuimu-context-pg-dev/agent_system_dev`:
| 项目/会话 | 结果 |
|---|---|
| project `143` | 创建者 user `9`,live instance `89`,active stage `V0.1_triage` |
| session `sess-p143-u9` | 共 4 条未删除消息,4 条正文长度均大于 0 |
| 激活前消息 `431-432` | 创建于 instance `89` 之前,无 `stage_key` |
| 文档任务消息 `433-434` | 创建于激活之后,`task_key=intake`,仍无 `stage_key` |
| 过滤结果 | 4 条均命中“空 stage_key → 丢弃”,窗口日桶保留但消息数组为空 |
| 分类统计 | 仍按全量 4 条聚合,可返回数量及首尾 ID |
全库当前有 live 工作流实例的会话消息统计也显示:所有命中的消息均缺少 `stage_key`。这说明不是单条偶发数据,而是写入链路缺字段与历史兼容策略共同造成的系统性问题。
## 严重度
`high`,并应作为发布 blocker:
- 核心对话记录在刷新/重新登录后不可用,用户会误认为数据丢失;
- 文档任务的对话留痕无法恢复,破坏可审计性;
- 正文、搜索、日期、统计、锚点的授权集合不一致;
- 分类数量和消息 ID 可在对象级授权不完整时形成侧信道泄露。
## 关联整改
- Remediation: [../remediation/2026-09-13-chat-history-refresh-remediation.md](../remediation/2026-09-13-chat-history-refresh-remediation.md)
- Short-term: [../ops/short-term/2026-09-13-chat-history-refresh-remediation.md](../ops/short-term/2026-09-13-chat-history-refresh-remediation.md)
- Gap matrix: [../remediation/gap-matrix.md](../remediation/gap-matrix.md)
## 证据
- `web/src/App.tsx:1634-1656,3393-3506`
- `web/src/hooks/useChatWindow.ts:81-170,446-578`
- `web/src/api/chatWindow.ts:73-164`
- `internal/chat/session.go:267-280,425-468`
- `internal/server/task_run_handlers.go:76-108`
- `internal/server/task_finalize.go:58-96`
- `internal/server/stage_access_helpers.go:135-212`
- `internal/server/chat_window_api.go:12-155`
- `internal/ctxmgr/chat_window.go:39-174,622-749`
- dev PostgreSQL 只读查询(未读取或落盘消息正文)
- 相关测试通过但缺场景:`go test -short ./internal/server -run 'TestServer_ChatWindow' -count=1 -v`、`go test -short ./internal/ctxmgr -run 'TestChatWindow' -count=1 -v`、`cd web && npm test`
## 开放问题
- 激活前项目私聊应默认仅对会话所有者可见,还是按项目成员和退出留痕策略共享,需要在实现前固化为策略测试;本方案建议保持现有“每人独立私聊”语义,优先按会话所有者授权。
- 历史上若同一 `task_key` 在多个工作流实例/阶段重复出现,不能仅按当前模板名称盲目回填,必须结合运行实例、创建时间和不可变实例 ID;无法唯一归属的数据应标记为 `legacy_unscoped` 并走显式兼容策略。
@@ -0,0 +1,106 @@
---
title: "小队完成未同步受控文档状态 + UI-03 选择器非 Tab + Retry 暴露 DB 约束(UI-03)"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: critical
---
# 小队完成未同步受控文档状态 + UI-03 选择器非 Tab + Retry 暴露 DB 约束(UI-03)
## 1. 现场实战概况与判定
在真实 UI 验收(`UI_PHASE=main`,dev 环境 `schema 29`,真实 `pi-agent` + `MiniMax-M2.7-highspeed`):
- **UI-00 PASS**(4.9s):管理员真实创建 A/B/C,准确按 DOM 作用域关闭模态,三用户完成首次登录改密。
- **UI-01 PASS**(774ms):A 页面立项并分配 B 为 reviewer,项目工作台就绪,零 404,模板预览正确。
- **UI-02 PASS**(191ms):真实发任务,`POST /api/v1/tasks/runs` 返回 202 Accepted,小队编排启动;真实模型耗时约 157 秒完成编排,后端成功生成受控文档 `doc_proj6089_user_requirements`(质量评分 100/100)。
- **UI-03 FAIL**:`await expect(page.locator('[data-testid="doc-rev-version"]')).toBeVisible({ timeout: 60_000 });` 超时失败。
- **页面真实状态**:页面已明确显示小队任务完成,正文标出 `📄 受控文档:doc_proj6089_user_requirements`。
- **右栏面板状态**:右栏仍保持为 `doc-p intake` 初始模板(`用户初始需求收集表 模板`,`模板预览:首轮编制后启用版本账本`),版本工具条 `[data-testid="doc-rev-version"]` 根本未挂载。
- **UI-04 ~ UI-16**:**NOT RUN**(因 UI-03 失败立即停机保全现场,未执行后续用例)。
---
## 2. 根因与现场异常分析
### A. 产品缺陷:前端在小队完成后未同步工作流文档列表
1. **服务端已落库受控文档**:
后端 `document_records` 表已落库 `doc_id="doc_proj6089_user_requirements"`,`is_template_only=false`,`current_state="drafting"`。且前端每 5 秒发起的轮询 `GET /api/v1/projects/6089/documents?category=workflow` 已正确返回该受控文档记录。
2. **`syncLeases` 轮询丢弃新文档**:
在 `web/src/App.tsx` 第 1664–1697 行,每 5 秒执行的 `syncLeases` 仅提取 `doc.lease_holder_type` 并更新既有 `doc.docId` 的租约。由于本地 React 状态 `deliverables` 初始仅有 `doc-p6089-*` 模板,`leases.has(doc.docId)` 匹配不上 `doc_proj*`,新文档从未被合并进 `deliverables`。
3. **`syncWorkflowDocs` 依赖项未触发**:
在 `App.tsx` 第 1618–1661 行,`syncWorkflowDocs`(调用 `mergeWorkflowDocumentsFromServer`)仅在 `currentProjectId` 或 `session` 变动时执行;同一会话内小队完成不会触发该 effect。
4. **流式结束 `case 'done'` 遗漏文档同步**:
在 `App.tsx` 第 2571–2593 行,任务流完成时仅调用了 `await chatWindow.refresh().catch(() => undefined)`(仅刷新聊天消息),未同步工作流文档列表。
5. **连锁阻断工具条挂载**:
前端 `deliverables` 中的 `user_requirements` 一直是 `isTemplateOnly: true`。根据 `revisionToolbarMountMode` 契约,`isTemplateOnly === true` 时返回 `'template_hint'`,阻断 `DocumentRevisionToolbar`(`[data-testid="doc-rev-version"]`)挂载。
### B. 测试脚本缺陷:定位器假设水平 Tab 且命中页头 Banner 徽章
1. 在 `web/e2e/document-revision-runtime.spec.ts` 第 538 行:
`const tab = page.locator('[role="tab"], button, div').filter({ hasText: /需求|摸底|URS|用户/ }).first();`
2. **穿透到页头徽章**:
`[role="tab"], button, div` 包含全局所有 `div`。页面顶部 Header Banner 含有 `当前项目: ... V0.1 需求摸底`(`div` 元素)。`.first()` 命中了该非交互的 Banner 徽章 `div`,根本没有点击文档切换器。
3. **真实 UI 为下拉/抽屉交互**:
`SlimTabBar.tsx` 为面包屑下拉(`button.dropdown-trigger` -> `.dropdown-menu`)或大盘抽屉(`DeckDrawer`),页面不存在水平文档 Tab。
### C. 前端断线自动重试与 DB 约束异常暴露
1. **前端断线自动重试导致同 turn 二次触发(非 Playwright retries)**:
`web/playwright.config.ts` 中 **`retries: 0`**。现场 13:02 完成首轮后,13:05 再次出现同 prompt 处理中,根因是前端 `runTaskAttempt` 在连接异常路径上自动重试,且重试开头 `setRunId(null)` / 未显式传递 `reconnectRunId`,导致重复 `POST /tasks/runs` 而非订阅既有 run:
- 13:02:`TRIGGER_TASK 请基于本项目编制首轮...` → `《用户需求表》已生成。当前状态:已完成`
- 13:05:同 turn 自动重试路径再次进入处理中(工程修复:`reconnectRunId` 跨 attempt + Claim 幂等)
2. **暴露 `task_runs` 状态约束缺陷**:
在二次运行与高风险候选流转路径中,后台服务尝试将 `task_runs.status` 更新为 `pending_author_confirmation` 时,暴露了数据库底层约束拦截:
goose **`00019`** 原始 `chk_task_run_status` 仅允许:
```sql
CHECK (status IN ('pending', 'running', 'completed', 'failed', 'cancelled', 'finalizing_failed', 'quality_failed', 'interrupted'))
```
该枚举**未包含** `pending_author_confirmation`,导致写入状态时触发 PostgreSQL check constraint 违规(由 goose `00030` 补齐)。
---
## 3. 严重度与阻断
- **严重度**:`critical`
- **阻断项**:
1. 产品前端:`App.tsx` 在小队完成(`case 'done'`)以及定期轮询中必须调用 `mergeWorkflowDocumentsFromServer` 动态更新受控文档。
2. 数据库约束:`task_runs` 表的 `chk_task_run_status` 约束必须补齐 `pending_author_confirmation`。
3. 测试脚本:修正 UI-03 文档切换定位器,禁止使用全局 `div` 通配,走真实 `SlimTabBar` 下拉或 `DeckDrawer` 动作;关闭非幂等的单用例重试。
---
## 4. 证据保全清单
- **归档路径**:`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/ui03-controlled-doc-sync-failure/`
- `playwright-output/`(含完整 `trace.zip`、`test-failed-1.png`、`error-context.md`)
- `playwright-report/`(HTML 完整执行报告)
- `screenshots/`(UI-00~UI-02 真实过程截图)
- `traces/`、`videos/`
- `ui-acceptance-results.json`(UI-00~UI-02 逐项 PASS 记录)
- `phase-secrets.local.json`、`phase-state.json`
- 历史归档目录全部原位保全:
- `post-auth-ui00-backdrop-click-failure/`
- `post-auth-ui00-close-selector-failure/`
- `post-auth-ui00-wrong-close-locator-failure/`
- `pre-auth-fix-ui00-failure/`
- `ui01-parent-directory-sync-failure/`
- `ui01-strict-mode-title-selector-failure/`
- `ui02-task-scope-409-failure/`
- `ui02-workflow-access-failure/`
---
## 5. 工程修复落盘(`fix/document-revision-runtime-ui03`,合入前)
| 根因 | 修复 | 门禁 |
|---|---|---|
| A 任务完成后未 merge 受控文档 | `pollUntilPostTaskServerDoc` + `deliverablesRef` 显式快照(禁止 setState updater 取 mergedSnap)+ 有限重试至 `doc_proj*` | focused + `npm test` / `build` |
| A′ intake vs URS 误匹配 | `templateMatch`:**intake 标记优先**于裸「用户需求」 | 单测 PASS |
| B UI-03 选择器命中 Banner | SlimTabBar/DeckDrawer;`data-chat-role/status` + 本轮 assistant sibling 等待;UI-11 禁止全局 div | 待真实 UI 重跑 |
| C `pending_author_confirmation` 约束 | goose `00030` 扩展 `chk_task_run_status`(相对 **00019** 枚举) | 真实现卷迁移合入前独立验证 |
| C′ 断线自动重试重复 POST | `reconnectRunId` 显式跨 retry;`ClaimRun`;`GetRun` 读回 `idempotency_key`;`StartClaimedRun` UpdateRun 失败不启 worker | `go test -short ./internal/taskrun` |
**未做**:占槽 rebuild、真实 UI UI-03 重验、schema30 对现有重复 `(session_id,client_turn_id)` 卷的迁移实测。
@@ -0,0 +1,71 @@
---
title: "真实会话被调试探针污染、查询误触发写任务与刷新状态退化"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: critical
---
# 真实会话被调试探针污染、查询误触发写任务与刷新状态退化
## 现象
- 用户在“对话协同会话”中看到 `test` 等非本人业务输入,多次任务失败。
- “总结一下用户初始需求表”没有读取/总结已有文档,而是启动 `intake` 写任务。
- 实时失败卡片带恢复动作;刷新后只剩错误正文,重试/继续/重新开始能力消失。
- 文档被智能体小队编辑期间,页面没有持续、醒目的占用状态,用户继续工作后才从失败中得知冲突。
## 根因分析
### 1. 诊断请求写入了真实用户会话
dev PostgreSQL 的 `sess-p143-u9` 在 03:17–03:32 记录了 `debug ping`、`test task`、`test`、`验证租约修复`。这些请求带有 `debug-turn-*` 等诊断标识,并与真实用户消息混排。结论不是“意图模型把输入改成 test”,而是调试过程直接复用了真实会话和项目 143,污染了审计记录与 UI。
### 2. 前端用名词命中代替动作意图识别
`web/src/engine/templateMatch.ts` 的 `resolveTaskKeyFromMessage` 只要文本包含“需求/用户”等名词就返回 `intake` 或 `user_requirements`。`App.tsx` 在聊天请求进入后端意图识别前先执行该匹配,并直接调用 `/api/v1/tasks/runs`。因此查询句“总结一下用户初始需求表”被确定性误判为写任务。
这不是模型偶发误判,而是客户端关键词捷径绕过了服务端意图合同;现有测试只覆盖“开始编写”,没有任何“总结/查看/当前状态/谁在编辑”等只读负例。
### 3. 结构化失败状态只存在于实时 SSE
实时路径把 `error_info`、`taskRequest`、`phaseEvents` 保存在 React 内存消息中;失败投影到 `chat_messages` 时只持久化 `run_id/workspace_id/task_status` 和错误正文。`mapRecordToMessage` 刷新恢复时也只依据 `task_status` 还原 `failed`,没有恢复 `errorInfo.actions`、原始任务请求或事件进度,导致 `MessageBubble` 无法渲染重试/继续/重新开始按钮。
### 4. 编辑租约存在,但不是可恢复的页面状态
`task_run_events` 已保存 `lease_acquired/lease_released`,`document_records` 也保存 `lease_holder_type/id/expires_at/heartbeat_at`。但 `App.tsx` 的任务事件处理只消费 `phase/status/delta/deliverable/error/done`,忽略 `governance`;刷新历史也不回放运行中任务事件。租约提示只可能短暂出现在内部数据,不能驱动会话、文档列表和编辑器的统一 busy 状态。
### 5. 文档忙被错误分型为系统内部错误
并发请求因有效租约拒绝时,事件被分类为 `INTERNAL_ERROR/fatal/actions=[restart]`,用户看到“系统内部错误,请重新开始会话”。实际是可预期的 `DOC_BUSY` 状态;除正确分型外,还必须在创建 `task_runs` 之前做服务端 busy 预检,持久化“未创建新任务”的只读状态卡,且不提供重试动作。
### 6. dev restart 不会加载新代码,健康检查可对旧镜像误报通过
`env-service.sh dev restart` 调用的是 `docker compose restart`;应用代码未挂载进容器,因此该命令只重启旧镜像。第一次修复后真实验证仍返回旧的 `CASUAL_CHAT`,但 `/health` 与 `/ready` 都为绿色。重建 app 镜像后,同一句话才返回 `QUERY_DOC_STATUS/doc_summary`。已新增显式 `rebuild` 动作,并将集成冒烟命令改为 `dev rebuild`。
## 严重度
`critical`:真实会话污染破坏可审计性;只读请求触发写入违反用户意图;刷新丢失恢复能力;后台编辑不可见导致重复劳动和冲突。
## 关联整改
- Remediation: [../remediation/2026-09-13-conversation-intent-runtime-state-remediation.md](../remediation/2026-09-13-conversation-intent-runtime-state-remediation.md)
- Short-term: [../ops/short-term/2026-09-13-conversation-intent-runtime-state.md](../ops/short-term/2026-09-13-conversation-intent-runtime-state.md)
## 证据
- dev PostgreSQL:`chat_sessions.id=138/session_id=sess-p143-u9/project_id=143/user_id=9`
- `chat_messages.id=554..567`:诊断探针、误路由与失败投影
- `task_runs.run_id=run_1789269755258510844`:03:22–03:32 持有租约;并发请求均因 busy 失败
- `task_runs.run_id=run_1789270446838831656`:由“总结一下用户初始需求表”启动的新写任务
- `task_run_events`:租约获取/释放与 `INTERNAL_ERROR` 分型
- `web/src/engine/templateMatch.ts`
- `web/src/App.tsx`
- `web/src/api/chatWindow.ts`
- `internal/taskrun/manager.go`
- `scripts/env-service.sh`(`restart` 与 `rebuild` 语义)
## 开放问题
- 已污染的四条诊断消息是否由项目创建者确认后做可审计软删除;本任务不擅自修改用户数据。
- 误启动的最新任务是否保留其产物;本任务不擅自取消或删除。
@@ -0,0 +1,48 @@
---
title: "当前受控文档改写被领域关键词改路由到另一交付物"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# 当前受控文档改写被领域关键词改路由到另一交付物
## 现象
第二轮真实 UI(schema 30)**UI-05 首个失败**:
- 页面打开 `doc_proj6109_intake`(用户初始需求收集表,V2/r0)
- 用户输入含「当前受控文档」的高风险改写提示(YY/T、GB 9706.1、NMPA 注册法规)
- 前端按法规关键词路由为 `feasibility_reg`
- `POST` 启动 `run_1789313290400899325`,生成 `doc_proj6109_feasibility_reg` 并 `completed`
- 当前 intake **无 pending badge**;E2E 等待 60s 失败
## 根因分析
| 层 | 问题 |
|---|---|
| `resolveTaskKeyFromMessage` | 写动词「改写」通过后,正文「注册」命中 `feasibility_reg`,无视当前打开文档 |
| `handleSendMessage` | 只把文案+模板池交给 `resolveTaskTemplateForMessage`,未传入 active `doc_proj` |
| 产品 | 「当前受控文档/本文件/这份文档」是指示语,领域词是改写内容,不是切换交付物 |
服务端 `ResolveAndValidateDocID` 已校验 project + task_key 与已注册文档一致,**不得**用客户端 `doc_id` 覆盖 `task_key`。本轮补了 `feasibility_reg` + `doc_proj6109_intake` mismatch 拒绝用例:攻击或误路由不得借 intake 文档改写另一任务键。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-active-doc-routing.md](../archive/ops/2026-09-13-document-revision-active-doc-routing.md)
- 分支: `fix/document-revision-active-doc-routing`
## 证据
- Evidence root(勿删、勿提交本轮):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05-active-doc-routing-failure`
- E2E:`web/e2e/document-revision-runtime.spec.ts` UI-05(断言不改弱)
- 审查约束:E2E/用例提示词只留在 test 文件,生产 `templateMatch.ts` 不导出用例编号常量
## 开放问题
- 占槽后真实 UI-05 重跑;本轮不操作容器
@@ -0,0 +1,45 @@
---
title: "UI-06 用 overlay/p/h 选择器找不到真实文档块"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-06 用 overlay/p/h 选择器找不到真实文档块
## 现象
第六轮真实 UI(schema 30):
- UI-00~05b **PASS**
- UI-06 在 `editFirstPaneBlockAndSave` 里对 `[data-overlay-kind], p, h1, h2` **双击前超时**
- 失败页正文真实存在;工具条版本徽章可见
## 根因分析
| 层 | 问题 |
|---|---|
| DOM | `BlockRenderer` 块 wrapper 是 generic `div`;`HeadingBlockView` / `ParagraphBlockView` 也不是 `h1`/`p` |
| overlay | `data-overlay-kind` 仅在非 `pure` 且命中 hunk 时出现;默认 `pure` 模式该属性不存在 |
| 脚本 | `openFirstPaneEditorAndFill` 依赖 overlay 装饰或原生标题/段落标签,与产品 DOM 契约不符 |
这是 **UI 自动化可寻址缺口**,不是正文未加载。继续用 overlay 选择器会误点标题栏/骨架/报告,或在 pure 模式直接超时。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-block-selector.md](../archive/ops/2026-09-13-document-revision-e2e-block-selector.md)
- 分支: `fix/document-revision-e2e-block-selector`
## 证据
- Evidence root(已归档、本轮勿提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-block-selector-failure/`
- `ui-acceptance-results.json`:UI-00~05b PASS;UI-06 未写入 PASS
## 开放问题
- 占槽后真实 UI-06/13b 重跑;本任务保持 `in_progress`,不得标 `done`
@@ -0,0 +1,48 @@
---
title: "UI-13a 用整行 option 文案误判编制负责人"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-13a 用整行 option 文案误判编制负责人
## 现象
第16轮真实 UI(schema 30,`dev@dd5671e`):UI-00 至 UI-12 PASS;分类导航修复已实证,UI-13a 已能从「我的私密」切回「流程受控」并打开 reviewer B 权限矩阵。
失败在职责断言:`intakeRow.innerText` 被整行匹配,报 `reviewer B must not be 编制负责人`。实际 `innerText` 为:
`V0.5 用户初始需求收集表当前打开 状态: drafting ✍️ 编制负责人 🔍 审核负责人 👑 批准负责人 👁️ 查阅者 (只读) 前往`
## 根因分析
| 层 | 问题 | 后果 |
|---|---|---|
| 职责单元格 | `onRoleChangeForDoc` 存在时渲染 `<select>`,四个 option 文案都在 DOM | `element.innerText` 含全部 option |
| 验收 | `/编制负责人/.test(整行文本)` | 审核人行也被判成编制负责人 |
| 控件语义 | select/badge 无稳定 `data-testid` / `data-doc-role` | 脚本只能刮行文案 |
select 的 `value` 才是当前职责。USER_B 在 UI-01 被明确分配 reviewer:验收必须证明 `role=reviewer`,不得把职责同步丢失降级成的 `viewer` 判通过。select 还须 `data-can-assign=false` 且 `disabled`;`canAssignLead=true` 一律拒绝。
## 严重度
`high`
权限矩阵已打开,真实只读检查未跑到就被假阳性打断。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-duty-cell-assertion.md](../remediation/2026-09-13-document-revision-duty-cell-assertion.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-duty-cell-assertion.md](../archive/ops/2026-09-13-document-revision-duty-cell-assertion.md)
- 分支: `fix/document-revision-duty-cell-assertion`
## 证据
- 失败证据(只读):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui13a-duty-cell-assertion-failure/`
## 开放问题
- 本轮不重跑真实 UI-13a;不得标 E2E 通过或任务 `done`
- 独立审查:不得用 `reviewer|viewer` 宽判;`evaluateReviewerDuty` 只接受精确 reviewer
@@ -0,0 +1,58 @@
---
title: "文档职责伪造与保存时重取 ETag 可覆盖并发正文"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: critical
---
# 文档职责伪造与保存时重取 ETag 可覆盖并发正文
## 现象
静态审查与 E2E UI-13 路径暴露两类产品缺陷:
1. **职责提升**:审核人 B 或项目外陌生人打开受控文档后,工作台把其当成编制人,出现正文编辑 / 送审动作。
2. **并发覆盖**:两窗口同开同一修订时,后保存方在点击保存瞬间重新 GET 最新 ETag,If-Match 对准已更新账本,409 不会出现,先保存方的正文被静默覆盖。
## 根因分析
| 层 | 问题 | 风险 |
|---|---|---|
| API | `ListWorkflowDocumentsByProject` / `GET projects/{id}/documents` 的 summary 不投影 `document_records` 的 author/reviewer/approver id+name | 前端无权威职责,只能猜 |
| 前端 merge | `mergeWorkflowDocumentsFromServer` 用当前登录用户名伪造 `author`,审核/批准写死「李主管」「王总监」 | B 登录后 `author===自己`,权限矩阵显示编制人 |
| 角色解析 | `currentDocRole` 比 name,失败默认 `'author'` | 未知身份 fail-open,陌生人获得编辑/送审 |
| 保存 | `handleSaveBlockEdit` 在 PATCH 前 `getRevisionState` 取最新 ETag | 打开时基线被丢弃;后写覆盖先写 |
| E2E | UI-13b 在 A1 完整保存后才打开 A2 编辑器 | 不是真实竞争,无法钉住上述 ETag 缺陷 |
独立审查补强(同一分支):
| 层 | 问题 | 风险 |
|---|---|---|
| PATCH | `resolvePatchEtag` 在 controlled 缺基线时仍返回 `0:0` | 服务异常被当成合法 bootstrap,可能覆盖已有账本 |
| hydrate | revision-state 5xx/网络失败只写 undefined 仍返回可编辑 AST | 用户能改正文,保存再 PATCH `0:0` |
| 批注 | viewer 被 cast 为 reviewer/approver,`canAnnotate` 对 viewer 开放 | 查阅者可新增评审批注 |
| 职责 | `isLegacyLocalDoc = !ids`:服务端 duty id 为 0 仍走 name fallback | 同名用户被提权为编制人 |
安全含义:职责伪造是**越权写**(viewer/reviewer 可改受控正文并送审)。ETag 刷新或 `0:0` 误用是**完整性破坏**。viewer 批注是**越权写元数据**。
## 严重度
`critical`
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-duty-etag-overwrite.md](../remediation/2026-09-13-document-revision-duty-etag-overwrite.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-reject-routing.md](../archive/ops/2026-09-13-document-revision-e2e-reject-routing.md)
- 分支: `fix/document-revision-e2e-reject-routing`
## 证据
- 代码(修复前):`internal/docgov/project_docs.go` summary 无职责列;`web/src/lib/deliverableSync.ts` `author: fallbackUser.name`;`web/src/App.tsx` 默认 `'author'` 与保存前 `getRevisionState`
- 单测钉住:B/陌生人不成 author;stale hydrate ETag 用于 PATCH
- 补强单测:controlled 缺 ETag/5xx 不可保存或不可打开;freeform 可 `0:0`;viewer 不能批注;服务端 duty id=0 不按 name 提权
- 本轮不跑真实 E2E、不提交 evidence assets
## 开放问题
- 占槽后真实 UI-13a/13b 重跑;CURRENT 仍 `in_progress`,不得标 `done`
@@ -0,0 +1,51 @@
---
title: "UI-05b 缺当前受控文档指示语被路由到 feasibility_reg"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-05b 缺当前受控文档指示语被路由到 feasibility_reg
## 现象
第五轮真实 UI(schema 30)**UI-05b 首个失败**:
- UI-00~05a PASS(含第四轮「待确认报告」真实打开)
- UI-05b 等待 `doc-rev-pending-badge` 60s 超时
- Prompt 为「请再次按医疗器械临床试验与注册检验法规,重写电磁兼容与软件生存周期章节…」,**没有**「当前受控文档《用户初始需求收集表》」
- 助手实际生成《注册路径可行性评估报告》`doc_proj6120_feasibility_reg`,状态 `completed`
- 原 intake `doc_proj6120_intake` 工具条为 V3/r0、「变更报告」,**无 pending**
项目 `UI验收-超声微创系统-mu01100b`。
## 根因分析
| 层 | 问题 |
|---|---|
| Prompt | 缺「当前受控文档」指示语;「注册检验法规」命中 `feasibility_reg` 关键词 |
| 产品路由 | 无 deixis 时按领域词选任务,这是既有契约;本轮**不改产品** |
| 脚本 | 未在 `sendChat` 前等待并校验本轮 `POST /api/v1/tasks/runs` 的 `task_key`/`doc_id`,失败时才在 pending 徽章上暴露 |
同轮审查:UI-10 点全局工具条「比较」冒充历史比较;UI-12 接受「项目可见但只查一个 marker」;UI-13 把立项审核人 B 当正文第二编辑者。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-reject-routing.md](../archive/ops/2026-09-13-document-revision-e2e-reject-routing.md)
- 分支: `fix/document-revision-e2e-reject-routing`
## 证据
- Evidence root(勿删、勿提交本轮):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05b-reject-routing-failure`
- Playwright:`playwright-output/document-revision-runtime--bc8cd-date-→-reject-version-stays-chromium/error-context.md`
- 结果:`ui-acceptance-results.json`(UI-05a PASS;UI-05b 未写入 PASS)
## 开放问题
- 占槽后真实 UI-05b 起重跑;本轮不操作容器、不重跑 E2E
- 脚本收紧后状态仍为 `in_progress`,真实重跑前不得 `done`
@@ -0,0 +1,60 @@
---
title: "UI-06 编辑弹窗打开期间 hydration 换块 ID 导致保存静默丢稿"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-06 编辑弹窗打开期间 hydration 换块 ID 导致保存静默丢稿
## 现象
第十二轮真实 UI(schema 30,dev@4c465d2 基线):
- 双击正文块、fill 标记、点击「保存修改」动作均成功,编辑器随后关闭
- 30 秒内修订仍为 **r0**
- 网络 trace 中 `PATCH /api/v1/documents/.../content` **数量为 0**
- 动作 monotonic:dblclick 611755–611807;fill 611860–611910;save 611917–611979
- 恰在 fill 开始时,后台 `GET /api/v1/docgov/documents/doc_proj6140_intake/content` 于 **611862.379** 发起并完成 hydration
本轮不是选择器点错按钮(第七轮 save-selector),而是保存路径在客户端被静默短路。
## 根因分析
| 层 | 问题 | 后果 |
|---|---|---|
| AST 身份 | `markdownToBlockAST` / `generateId()` 明确 `Math.random()`,每次 parse 新建 `blk_*` | 弹窗持有打开时的块 ID,当前 `docAST` 已是新 ID |
| hydrate 丢账本 | `fetchRevisionState` 依赖被窄化为 `Promise<{etag:string}>`;`buildControlledDocumentAST` 之后**没有** `applyHeadBlockMap(rev.st.head_block_map)` | 服务端已有稳定块身份,前端每次 hydration 仍随机换 ID |
| 保存 | `handleSaveBlockEdit` 按 `updated.id` 在 `docAST.rootBlock.children` 查找;`idx === -1` 时 `setEditingBlock(null)` 后 return | 关窗、不发 PATCH、无提示 |
| hydration 触发 | `useEffect([session, sessionValidated, activeDocId, deliverables])` 在 lease/工作流同步改 `deliverables` 时重跑 | fill 窗口打出新 GET |
| 迟到响应 | hydrate `.then` 无 generation / 编辑门闩 | 弹窗打开后或 PATCH 成功后仍可覆盖编辑基线(即使 ID 已对齐,也会回滚新正文) |
| 会话绑定 | 只按块 ID 保存;`activeDocId` 可被 canonical/session/任务流改写,不经 `handleSelectDoc` | 可能对另一份文档发 PATCH,或块 ID 碰巧对上 |
| 关窗续跑 | 编辑中拒绝/跳过的首次 hydrate,effect 依赖不再变化 | 关窗后可能永久停在 loading skeleton |
| 切文档 | `handleSelectDoc` 在编辑中静默 `closeBlockEditor` | 草稿被丢;modal 虽 `fixed inset:0 zIndex 100` 挡住 SlimTabBar,但 chat/drawer 等仍会调 `handleSelectDoc` |
`deliverables` 被 5s lease 同步、任务完成后 `syncControlledDocsAfterTask`、工作流列表合并(清 cache)以及 governance 事件改写。任一变化都会在编辑期间再拉正文并换块身份。
## 严重度
`high`
用户可见「已保存」(弹窗关闭),账本仍 r0。属于静默丢稿,不是提示后的失败。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-editor-hydration-race.md](../remediation/2026-09-13-document-revision-editor-hydration-race.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-editor-hydration-race.md](../archive/ops/2026-09-13-document-revision-editor-hydration-race.md)
- 分支: `fix/document-revision-editor-hydration-race`
## 证据
- 失败证据目录(根代理保留、本轮不得改/移/删/提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-r-bump-noop-failure/`
- Playwright 断言:`[data-testid="doc-rev-revision"]` 30s 内仍为 `r0`
## 开放问题
- 本轮只做前端门闩与单测/构建验证;**未跑真实 UI-06**,不得标 E2E 通过或任务 `done`
- 关窗后的下一次 deliverables 驱动 hydrate 仍会重建块 ID(编辑会话已结束;缺 map 时仍随机,门闩已消费)
- **首次 hydrate 在 `editor_open` 被拒后会卡 skeleton**:可达(骨架块可双击,或清 cache 后编辑中跳过 GET)。关窗时 `takeHydrationResume()` 递增 `hydrateResumeKey` 重跑 effect。
- modal 不能硬保证挡死所有 `handleSelectDoc`;编辑中切文档 fail-closed,不静默关窗。
@@ -0,0 +1,47 @@
---
title: "UI-11 快速 completed 被验收脚本误判为失败"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-11 快速 completed 被验收脚本误判为失败
## 现象
第14轮真实 UI(schema 30,`dev@339e871`)在 **UI-11** 失败:页面上传附件并发送「请将此附件归档」后,相邻助手卡片已快速处于 `completed`(文案:已收录补充材料并关联黑板)。
`waitForSquadCompletion` 默认 `requireInflight=true`,用 Playwright `toHaveAttribute` 硬等 `pending|streaming_status|auto_retrying` 60 秒。收到的属性已是 `completed`,被当成 unexpected value,60s 后 FAIL。产品终态成功,验收误判。
## 根因分析
| 层 | 问题 | 后果 |
|---|---|---|
| 验收契约 | `requireInflight !== false` 默认为必须先看到处理中 | 快路径成功被 60s 超时打死 |
| Playwright 匹配 | `toHaveAttribute` 对已是 `completed` 的节点持续重试同一错误匹配 | 日志里 123 次 resolved 到 completed 仍等 inflight |
| UI-03 先例 | 已用 `{ requireInflight: false }` 避开同类竞态 | UI-11 未沿用,默认仍硬等 |
| 真实性 | 现场助手无错误、用户句与相邻卡片对应、上传已走 freeform | 不得放宽上传/对应关系/终态/无错误,只改观测顺序 |
证据 `error-context.md`:Locator 命中 `data-chat-status="completed"`,Expected `/pending|streaming_status|auto_retrying/`。
## 严重度
`high`
真实成功轮次被脚本误杀,阻断后续 UI-12+。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-fast-completion-observation.md](../remediation/2026-09-13-document-revision-fast-completion-observation.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-fast-completion-observation.md](../archive/ops/2026-09-13-document-revision-fast-completion-observation.md)
- 分支: `fix/document-revision-fast-completion-observation`
## 证据
- 失败证据(只读,不得改/移/删/提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-fast-completion-observation-failure/`
## 开放问题
- 本轮不重跑真实 UI-11;不得标 E2E 通过或任务 `done`
- 处理中状态仅作可选观测,不作为成功必要条件
@@ -0,0 +1,105 @@
---
title: "文档修改、版本差异与智能体变更说明能力缺口分析"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# 文档修改、版本差异与智能体变更说明能力缺口分析
## 1. 结论
系统已有受控文档生命周期、编辑租约、正文 SHA-256、审计日志、智能体变更提案、自由文档版本表和阶段通知 Outbox,可作为本能力的基础;但当前尚不存在可信的“受控文档版本库”。受控正文仍以工作区单个 `output.md` 为事实源,人工或智能体更新会覆盖现状,无法复原任一历史正文,也无法可靠回答“谁在何时基于哪个智能体版本改了什么”。
本需求不能通过前端缓存一份旧正文后做颜色标记来完成。必须把不可变正文快照、以智能体生成为边界的版本周期、每次已提交人工修改、精确 diff、智能体变更报告和负责人通知放入同一个服务端一致性模型。
## 2. 用户规则的确定性解释
用户描述中的“版本以智能体修改为准”按以下语义实现:
1. 模板或一次成功提交的智能体/智能体小队产物,是一个版本周期的 `baseline`。
2. 此后所有人工保存都形成该版本下的 `revision`,改变当前 `head`,但不增加面向用户的版本号。
3. 下次智能体基于当时的 `head` 生成成功后,旧版本以该 `head` 封存;智能体输出成为新版本的 `baseline`。
4. “人工修改标记”永远计算为当前版本 `baseline → head`。智能体新版本生效后该标记归零,后续只显示相对新 baseline 的人工修改。
5. 两个版本的默认比较使用各版本的最终内容:已封存版本取 `sealed_head`,当前开放版本取实时 `head`;智能体自身的改动单独用“上一版本最终内容 → 新版本 baseline”表达。
该解释既满足“模板/上一次智能体生成 + 下一次智能体生成前人工修改为一个版本”,也不会把每次自动保存误展示成一个正式版本。
## 3. 已确认的现有基础
| 能力 | 当前证据 | 可复用部分 |
|---|---|---|
| 受控文档元数据 | `deploy/postgres/goose/00001_baseline.sql:230-280` | `document_records`、三权、状态、当前 SHA、版本号 |
| 编辑互斥 | `internal/docgov/lease.go:41-180` | human/squad 租约、心跳和忙状态 |
| 人工保存入口 | `internal/docgov/lease.go:290-360` | 编制人/状态校验与 `expected_sha256` 乐观锁 |
| 智能体修改授权 | `internal/docgov/engine.go:448-577`、`internal/bizdev/service.go:451-538` | 已认领文档先提案、编制人裁决 |
| 智能体执行归属 | `internal/squad/models.go:35-95,216-226` | 小队角色、步骤、manifest 与工作区信息 |
| 自由文档版本 | `internal/freedoc/service.go:416-535` | 事务、`FOR UPDATE`、每次保存快照与 If-Match |
| 文档血缘 | `deploy/postgres/goose/00010_2026-09-11-project-workflows-and-lineage.sql:66-84` | 上下游文档版本、哈希和 stale 传播 |
| 可靠通知基础 | `deploy/postgres/goose/00018_2026-09-12-outbox-notifications-stage-advance.sql`、`internal/notification/service.go` | Outbox、用户通知、去重键 |
| 右侧块编辑器 | `web/src/components/doc/BlockRenderer.tsx`、`BlockEditorModal.tsx` | 块级阅读、编辑、批注和右侧栏布局 |
## 4. 已确认缺口
| ID | 缺口 | 当前证据 | 后果 |
|---|---|---|---|
| DOCREV-01 | 受控正文没有不可变历史快照 | `ReadDocumentContent` 只读取当前工作区 `output.md`;`document_records.version` 没有对应的受控版本表 | 不能查看旧版本、恢复证据或验证历史哈希 |
| DOCREV-02 | 人工保存只覆盖文件和当前哈希 | `SaveDocumentContent` 写 `output.md` 后更新 `document_records`,不增加版本/修订记录;数据库错误还被忽略 | 无法记录具体修改人和前后正文;文件与 DB 可分裂 |
| DOCREV-03 | 前端块编辑尚未持久化 | `handleSaveBlockEdit` 只修改 React `docCache`;`saveDocumentContent` 没有调用者;编辑弹窗把修改人硬编码为“张工” | 刷新丢失、归属不可信、展示与服务端不一致 |
| DOCREV-04 | 智能体完成只更新当前哈希 | `internal/bizdev/service.go:694-705` 只调用 `SetDocumentWorkDir` 和 `MarkDocumentContentUpdated` | 不能把 run、输入快照、输出快照和版本关联 |
| DOCREV-05 | 现有提案不是实际 diff | `service.go:499-502` 在智能体执行前写入通用文案,未绑定真实 before/after | 不能作为生成完成后的改动摘要、风险或影响证据 |
| DOCREV-06 | 块锚点不稳定 | `markdownToBlockAST` 每次解析使用随机 `blk_*` ID | 刷新或换版本后不能稳定定位修改块、批注和 diff |
| DOCREV-07 | 自由文档“每次保存一个版本”与本需求语义不同 | `freedoc.UpdateDocument` 每次正文变化都 `current_version_id + 1` | 同一右侧栏内“版本”概念不一致,自动保存会制造版本噪声 |
| DOCREV-08 | 通知只覆盖阶段推进 | `notification/types.go` 只有 stage-ready 类型;前端仅 `StageAdvanceBanner` 消费 | 文档负责人不会收到智能体版本摘要、风险和影响 |
| DOCREV-09 | 内容修改链路的一致性和授权边界不足以支撑审计 | 租约 API 接受客户端 holder type/id;部分 DocGov 入口只认证后直接调用领域引擎;当前锁主要是进程内 mutex | 多实例、伪造 holder、并发提交时可能发生越权或静默覆盖 |
## 5. 根因分析
### 5.1 “当前文档”同时承担事实源、工作副本和历史版本
`document_records` 的 `version` 和 `content_sha256` 只是当前指针;`output.md` 同时被智能体工作区、人工编辑和读取 API 使用。缺少 immutable snapshot 后,审计日志只能证明发生过一个动作,不能证明动作前后内容。
### 5.2 版本、修订、生命周期三种概念没有拆开
- 智能体生成版本:本需求要求的业务版本边界;
- 人工保存修订:高频、可聚合展示,但必须逐次留痕;
- 送审/批准快照:生命周期冻结点。
当前单个 `version` 整数无法同时表达三者,继续叠加字段会导致比较对象含糊。
### 5.3 UI 的 Block AST 是临时视图,不是稳定编辑协议
Markdown 每次解析都会重新生成随机块 ID;编辑 metadata 由浏览器填写,既不能作为服务端身份,也无法跨快照追踪。需要由服务端产生稳定 block map,并由 immutable snapshot 保存。
### 5.4 智能体说明与确定性事实没有分层
智能体适合解释“为什么改、有哪些风险”,但真实增删内容必须由服务端 diff 得出,上下游影响必须由工作流/血缘图计算,风险等级也不能允许模型自行降级。当前变更提案把三者都存为自由文本,且没有版本关联。
## 6. 严重度
`high`
该能力尚未对外承诺为已实现,因此不是现有数据破坏事件;但若仅增加 UI 高亮便宣称完成,会形成错误审计证据,并在多人/多智能体协作下引入静默覆盖、错误归属和不完整通知。
## 7. 设计边界
- 受控工作流文档与自由文档继续使用各自权限/生命周期策略;只共享底层快照、修订和 diff 能力。
- Markdown 正文为规范化内容真源,Block AST 是带稳定映射的编辑/展示投影,避免双真源。
- 未保存的浏览器按键不属于审计记录;每次服务端成功提交才是 revision。
- 批注、审核意见与正文修改是不同事件,不混入人工正文高亮。
- 已批准内容不可原地修改;后续修改必须经受控变更/驳回回编制流程创建新工作周期。
## 8. 关联整改
- System design: [../system-design/document-revision-management.md](../system-design/document-revision-management.md)
- Remediation: [../remediation/2026-09-13-document-revision-management-implementation-plan.md](../remediation/2026-09-13-document-revision-management-implementation-plan.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-management-design.md](../archive/ops/2026-09-13-document-revision-management-design.md)
## 9. 开放问题
方案给出推荐默认值,等待评审时确认:
1. 高/严重风险的智能体候选是否一律要求编制负责人再次确认后才成为新版本(推荐:是)。
2. 首期是否同时迁移自由文档到“智能体版本 + 人工修订”语义(推荐:底层统一,UI 第二波启用)。
3. 历史快照默认保留期限(推荐:受控文档随项目/法规保留策略;自由文档默认 365 天且可配置,不做静默硬删除)。
@@ -0,0 +1,45 @@
---
title: "UI-07 纯净阅读用 overlay/class*block 找不到真实块"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-07 纯净阅读用 overlay/class*block 找不到真实块
## 现象
第八轮真实 UI(schema 30):
- UI-00~UI-06 **PASS**(UI-06 `r0→r1` 且硬刷新持久)
- UI-07 `captureOverlayFingerprint(mode=pure)` 抛 `no block to sample computed style`
## 根因分析
| 层 | 问题 |
|---|---|
| DOM | `BlockRenderer` 真实块是 `data-testid=document-block` 的 generic wrapper;无 `class` 含 `block` |
| overlay | `data-overlay-kind` 仅在 `overlayMode !== 'pure'` 且 hunk 命中时出现;纯净阅读该属性不存在 |
| 脚本 | pure 取样 `[data-overlay-kind], [class*="block"]`;manual/all 全页 `[data-overlay-kind]`,未限定活动文档 |
`ManualChangeOverlay` 只是工具条 hint,不是块装饰。块装饰是同一 wrapper 上的 inline style。
同一 human hunk 在 manual/all 都是琥珀底,产品不保证两两不同。Checklist:UI-07 无装饰、UI-08 琥珀标记、失败标准是「三 overlay 视觉无差异」,不是强制 manual≠all。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-overlay-selector.md](../archive/ops/2026-09-13-document-revision-e2e-overlay-selector.md)
- 分支: `fix/document-revision-e2e-overlay-selector`
## 证据
- Evidence root(已归档、本轮勿提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui07-pure-selector-failure/`
## 开放问题
- 占槽后真实 UI-07/08/09 重跑;本任务保持 `in_progress`,不得标 `done`
@@ -0,0 +1,45 @@
---
title: "UI-07 在 CSS transition 中间帧采样纯净阅读"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-07 在 CSS transition 中间帧采样纯净阅读
## 现象
第九轮真实 UI(schema 30):
- UI-00~UI-06 **PASS**
- 切到纯净阅读后,全部 `data-overlay-kind` 已空
- 取样到 `background rgba(51,41,15,0.294)`、`boxShadow` alpha `.294` / 位移 `.589549px`
- 断言「纯净阅读必须无装饰」FAIL
## 根因分析
| 层 | 问题 |
|---|---|
| 产品 | `BlockRenderer` 块 wrapper 有 `transition: background/box-shadow 0.2s ease` |
| 脚本 | 上一轮去掉 `waitForTimeout(400)` 后,overlay 响应与 `data-overlay-kind` 清空即采样 |
| 时序 | 属性已达终态,computed style 仍是琥珀→透明的中间帧 |
这是 **采样过早**,不是纯净模式仍保留装饰。禁止禁用产品 transition,也禁止放宽无装饰断言。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-overlay-transition.md](../archive/ops/2026-09-13-document-revision-e2e-overlay-transition.md)
- 分支: `fix/document-revision-e2e-overlay-transition`
## 证据
- Evidence root(已归档、本轮勿提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui07-css-transition-sampling-failure/`
## 开放问题
- 占槽后真实 UI-07/08/09 重跑;本任务保持 `in_progress`,不得标 `done`
@@ -0,0 +1,51 @@
---
title: "UI-05a 未打开待确认报告导致确认按钮缺失"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-05a 未打开待确认报告导致确认按钮缺失
## 现象
第四轮真实 UI(schema 30)**UI-05a 首个失败**:
- UI-00~05 PASS;**UI-05a** 抛 `confirm button missing for pending high-risk candidate`
- 工具条已显示「待确认 high」与「待确认报告」
- 助手气泡写明候选 #91、变更报告 91、风险 high、状态 `pending_author_confirmation`
- 页面仍挂着 **首轮** `dialog「变更报告」`:风险 **low** / `fallback`,无 `change-report-pending-actions`,无「确认提交」
- 脚本用全局 `getByRole('button', { name: /确认提交/ }).count()` 判定,未先点「待确认报告」
项目 `UI验收-超声微创系统-mu00igjt`,文档 `doc_proj6119_intake`,首轮报告 `change-reports/90`,pending 候选/报告 `#91`。
## 根因分析
| 层 | 问题 |
|---|---|
| UI-04 关闭 | `ChangeReportPanel` 只有弹窗内「关闭」;**没有 Escape 处理**。`page.keyboard.press('Escape')` 被 `.catch` 吞掉,首轮 low 报告 `reportId` 仍打开 |
| 产品条件 | `pendingDecision`(确认/拒绝)仅当 `reportId === pending_change_report_id` 才注入。首轮报告 90 ≠ pending 91,弹窗里不会出现「确认提交」 |
| UI-05a | 未模拟真实用户点击「待确认报告」并等待 `change-report-panel`;只用全局 count,错过必须打开 pending 报告的路径 |
产品确认/拒绝逻辑本身未坏;失败来自验收脚本未走真实面板路径。本轮**禁止改产品业务逻辑**。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-pending-flow.md](../archive/ops/2026-09-13-document-revision-e2e-pending-flow.md)
- 分支: `fix/document-revision-e2e-pending-flow`
## 证据
- Evidence root(勿删、勿提交本轮):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui05a-pending-report-selection-failure`
- Playwright:`playwright-output/document-revision-runtime--91599-andidate-→-version-advances-chromium/error-context.md`
- 结果:`ui-acceptance-results.json`(UI-04 PASS 131ms,打开 `/change-reports/90`;UI-05 PASS;UI-05a 未写入 PASS)
## 开放问题
- 占槽后真实 UI-05a/05b 重跑;本轮不操作容器、不重跑 E2E
- 脚本收紧后状态仍为 `in_progress`,真实重跑前不得 `done`
@@ -0,0 +1,47 @@
---
title: "首次生成 PG ID 未同步计数器导致 baseline 被误删"
status: done
created: 2026-09-13
updated: 2026-09-14
severity: critical
---
# 首次生成 PG ID 未同步计数器导致 baseline 被误删
## 现象
第19轮真实 UI(schema 31,项目 `6158` / `doc_proj6158_intake`):小队输出、baseline snapshot=249、version=217、**candidate id=175**、**output snapshot id=250**、**report id=175** 均已落库,candidate 保持 `ready`,任务失败 `docrevision: not found`(`CommitAgentVersion` 找不到 input snapshot)。不要把 output snapshot 250 误写成 candidate 250。
## 根因分析
`openTemplatePGLocked` 把 PostgreSQL `RETURNING id` 写入 `s.snapshots[249]` / `s.versions[217]`,但**不推进** `nextSnapID` / `nextVerID` / `nextEvtID`。
当进程内计数器已因其它文档 hydration 停在 248 时:
1. `putSnapshotLocked` 执行 `nextSnapID++` 得到临时 ID **249**,覆盖真实 baseline;
2. `persistAgentCandidateLocked` 把输出重映射到 250 后 `delete(s.snapshots, 249)`,误删 baseline;
3. `CommitAgentVersion` 按 `InputSnapshotID=249` 查找 → `ErrNotFound`;
4. 任务失败,candidate 仍 `ready`(不得伪装成功)。
同类无条件 `delete(map, oldID)` 也存在于 version / event / report / candidate 持久化路径。
## 严重度
`critical`
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-pg-id-remap.md](../remediation/2026-09-13-document-revision-pg-id-remap.md)
## 证据
- 失败归档(只读,不改不删):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema31-round19-ui03-advisor-briefing-docrevision-not-found/`
- Playwright:`squad observation rejected: error_terminal:failed`
## 开放问题
- 无(本缺陷)。Round20 已在项目 6159 重跑 UI-03 PASS。Round19 归档不删。
## 关闭记录
工程修复合入 `dev@b258ab8`。验收:[../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)。
@@ -0,0 +1,52 @@
---
title: "post-restart 断言了已过期的 UI-06 正文 marker"
status: done
created: 2026-09-13
updated: 2026-09-14
severity: high
---
# post-restart 断言了已过期的 UI-06 正文 marker
## 现象
第二次真实 post-restart(schema 31):login、项目、受控文档、`revision-state` 200、`V3`/`r2`、正文均已恢复。失败只因:
```
getByText('UI06-mu0eq020') → element(s) not found
```
`phase-state.json` 仍写 `bodySnippet=UI06-mu0eq020`,而 UI-13b A1 成功保存后最终持久正文是 `A1-win-*`。
## 根因分析
| 层 | 问题 |
|---|---|
| UI-06 | 硬刷新后把当时 marker 写入 `phase-state.bodySnippet` |
| UI-13b | A1 2xx 保存并断言 `markerA1` 可见;A2 409 冲突稿留在编辑器。未回写最终持久正文 |
| UI-15-pre | 更新了 `versionText`/`revisionText`,但 `...st` 原样带上过期 snippet |
| post-restart | 正确坚持断言 `st.bodySnippet` 可见,于是用旧 marker 对照新正文 FAIL |
产品恢复链已成立;这是 **测试状态链过期**,不是账本丢失。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-post-restart-final-snippet.md](../archive/ops/2026-09-13-document-revision-post-restart-final-snippet.md)
- 分支: `fix/document-revision-post-restart-final-snippet`
## 证据
- 失败归档(只读):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema31-postrestart-stale-body-snippet-failure/`
- `phase-state.json`:`controlledDocId=doc_proj6157_intake`,`V3`/`r2`,`bodySnippet=UI06-mu0eq020`
## 开放问题
- 无(本缺陷)。Round20 `bodySnippet=A1-win-mu0gwiez`,post-restart PASS。失败归档不删。
## 关闭记录
[../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
@@ -0,0 +1,50 @@
---
title: "post-restart 项目名同时命中顶栏与侧栏"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# post-restart 项目名同时命中顶栏与侧栏
## 现象
第18轮真实 UI(schema 31):main **18 PASS / 0 FAIL**。宿主重启 app 后 `UI_PHASE=post-restart` 在页面**已经恢复项目**时失败,尚未走到 `revision-state`。
```
strict mode violation: getByText('UI验收-超声微创系统-mu0eq020') resolved to 2 elements:
1) getByRole('banner').getByText(...)
2) getByTitle(...)
```
失败行:`web/e2e/document-revision-runtime.spec.ts` 原第 626 行。
## 根因分析
| 层 | 问题 |
|---|---|
| DOM | 顶栏 `header`(banner)写「当前项目:」+ 项目名;侧栏 `aside` 会话行 `title`/`span` 再写同一项目名 |
| 脚本 | 点击用 `getByText(..., { exact: false }).first()`;恢复断言用页面级 `getByText(项目名)`,strict 下双命中 |
| 产物 | `playwright.config.ts` 的 `outputDir` / HTML report 不按 `UI_PHASE` 分目录,第二阶段会覆盖主阶段 trace |
| 总账 | `RESULTS_FILE` 固定 `ui-acceptance-results.json`;post-restart `recordPass` 会覆盖 main 的 18 项 |
这是 **UI 自动化可寻址缺口**,不是项目未恢复。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-post-restart-selector.md](../archive/ops/2026-09-13-document-revision-post-restart-selector.md)
- 分支: `fix/document-revision-post-restart-selector`
## 证据
- 失败归档(只读,不改不删):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema31-postrestart-project-title-selector-failure/`
- `error-context.md`:项目名同时出现在 banner 与 complementary title
## 开放问题
- 本轮不重跑真实 post-restart;不得标 UI-15 通过或任务 `done`
@@ -0,0 +1,78 @@
---
title: "UI-11 prelim_design 缺 output.md 导致 TASK_INTERRUPTED"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-11 prelim_design 缺 output.md 导致 TASK_INTERRUPTED
## 现象
第11轮真实 UI(schema 30,`dev@2a58674`):
- Prompt 正确 POST **202**,`task_key=prelim_design`
- 旧 intake 未再 DOC_BUSY
- 小队终态 `TASK_INTERRUPTED` / `task_failed`
- 页面:`step step_01_draft missing target deliverable output.md` · `run_1789325979820025769`
## 现场时序(只读 workspace / execution.log / trace)
工作区:`data/dev/workspaces/bizdev/prelim_design_1789325982486234431/tasks/01_draft/execution.log`
1. MiniMax **第一次已流出** `write(/app/data/workspaces/.../tasks/01_draft/output.md, content=...)` 的 `toolCall`
2. **同一条** assistant message:`stopReason=error`,`errorMessage=terminated` → 工具未执行,磁盘无 `output.md`
3. SDK `auto_retry_start` attempt 1–3 均为 `Connection error.`
4. `auto_retry_end success=false`,`finalError=Connection error.`
5. 随后仍有 `agent_settled`
6. 同文件头却写 `Outcome: SUCCESS` / `Error: None`
7. 工作区 `trace.jsonl`:`step_01_draft success=true`,`output_digest=e3b0c442...`(空 SHA)
8. PI 子进程退出 0,runner 对上层呈成功;服务端最后因 `output.md` 不存在才失败
**禁止**从该 `write` 参数(可能截断)拼正文或补写 `output.md`。
## 根因分层
必须区分外部瞬时故障与产品韧性缺口,二者同时成立:
| 层 | 性质 | 证据 | 问题 |
|---|---|---|---|
| MiniMax / PI SDK | **外部 provider 瞬时故障** | 同 message `terminated`;SDK 三次 `Connection error`;`auto_retry_end success=false` | 流式 `write` 未落地;in-process 重试耗尽 |
| 模板 | 产品前置条件 | `.dockerignore` 的 `*.md` 把 `templates/docs/*.md` 排除出 build context;即使 `COPY templates /app/templates`,镜像内仍无官方稿,`GetDocTemplate` 失败后 `workspace.go` 回落两段 stub「待确认」 | writer 被迫一次性超长 `write`,拉长流式窗口 |
| `runner.mjs` | **产品韧性缺口** | `agent_settled` 后文件头 `Outcome: SUCCESS` | 把 settle 当成成功;进程 0 ≠ 产物存在 |
| Go `runOneStep` / `AppendTrace` | **产品韧性缺口** | `trace.jsonl` `success=true` + 空 digest | 以 backend `Success` / 进程 0 入账,未按目标文件 fail-closed,也未对瞬时失败做**全新 step invocation** |
| 映射 | 产品契约 | 绝对路径 / `./` / 重复 `tasks/01_draft/output.md` | 即使 write 落地,旧映射也可能认不到 |
app 日志:`taskrun_status_transition run_id=run_1789325979820025769 error="step step_01_draft missing target deliverable output.md"`。
## 成功判定契约(本轮补齐)
- `agent_settled` 在 `auto_retry_end success=false` / `terminated` / `Connection error` 之后 **不是** 成功
- 进程退出 0 **不是** 成功
- 目标文件缺失或空 **不是** 成功
- 不得执行/回放可能截断的 `write` 参数
- **瞬时**(provider 信号或 runner `retryable`):有界 **全新** `backend.Execute`(默认 1+1),最终仍 fail-closed
- **永久**(干净 settle 后缺产物、`prompt_empty`、`unauthorized`、治理拦截):不得重试
## 严重度
`high`
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-prelim-output.md](../remediation/2026-09-13-document-revision-prelim-output.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-prelim-output.md](../archive/ops/2026-09-13-document-revision-prelim-output.md)
- 分支: `fix/document-revision-pi-runner-module`(由 `dev@55a4f39` 检出;前序 `fix/document-revision-prelim-output` 已合入)
## 证据
- Evidence root(已归档、本轮勿改勿提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-prelim-design-missing-output-failure/`
- Workspace(只读):`data/dev/workspaces/bizdev/prelim_design_1789325982486234431/`
## 开放问题
- 占槽后真实 UI-11 重跑;本任务保持 `in_progress`,不得标 `done`
- 本轮不执行 `env-service` 重建;Dockerfile / `.dockerignore` 已按 `/app/templates/docs` 读路径修好并做 context 实测。占槽后的镜像重建才带进运行中的 dev 容器
- Go 侧必须能在**旧 runner 假成功**时靠 `execution.log` 识别瞬时失败并全新重试;仅修 runner 假成功只会更早 FAIL,不会单独提高成功率
- **热修(dev@55a4f39 重建后)**:`deploy/pi-agent/Dockerfile` 只 COPY 了 `runner.mjs`,未 COPY `settle-policy.mjs`;`shuimu-pi-agent-dev` 因 `ERR_MODULE_NOT_FOUND file:///app/settle-policy.mjs` 重启循环。app 侧 `/app/templates/docs` 与 configs 已正常。
@@ -0,0 +1,48 @@
---
title: "质量门禁自污染与 auto_repair 未启用导致 quality_failed"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# 质量门禁自污染与 auto_repair 未启用导致 quality_failed
## 现象
同一整改范围真实 run(与 SSE/幂等现场同源):
- workspace=`data/dev/workspaces/bizdev/intake_1789308825666278807`
- run 于 **14:17:51** 结束为 **`quality_failed`**(仅 1 个 `task_runs`)
- 质量门禁事件:**score=40**,命中 `不做展开` / `篇幅有限` / `从略`
- `output.md` **第204行**终稿自检表:`无"不做展开""从略""篇幅有限"等敷衍套话` → 门禁 `strings.Contains` **自污染误报**
- 请求体未带 `auto_repair`;虽存在 `EnsureQualityOrRepair`,实际 **maxRetries=0**
- chat_messages 同 `client_turn` 两对(1131/1132 正常;1133/1134 重连误写)——与 SSE 幂等缺陷同源,另案处理
## 根因
| 项 | 说明 |
|---|---|
| A | 修复预算依赖客户端 `auto_repair`(浏览器可省略,默认 false) |
| B | 生成指令与自检表原样引用禁词;检测无否定/元语境豁免 |
| C | FE 将 `quality_failed` 映射为 `completed`,并在断线 catch 路径同步受控文档 |
| D | 缺真实失败形态单测 |
## 整改(同分支 `fix/document-revision-sse-idempotency`)
- A:小队 `repairBudget` 只认 `AutoRepair`;bizdev 在解析出 `docID`+`docRec` 后强制开启;受控 HTTP `task_run_handlers` 仍设 `true`。小队 `Success` 仅表示执行完成,投影/阶段停链看 `QualityReport`
- B:prompt 去原词;豁免仅限同一自检/规则行且同时具备 meta marker + 否定紧邻或引号引用(禁止 48 字窗口遇「无」即放过)
- C:`TerminalStatus` 优先 quality;Materialize 仅 `Passed`;FE `quality_failed` 独立失败态且不同步激活
- D:现场 L204 / repair budget / TerminalStatus / FE 映射单测
- **E(投影边界)**:`finalizeSquadDeliverable` 在任何 `SetDocumentWorkDir` / `Materialize` / `MarkDocumentContentUpdated` / 完成活动之前按 `QualityReport.Passed=false` 短路;保留隔离工作区与失败摘要;正式 `work_dir`/head/hash/候选不变。单测:`TestFinalizeSquadDeliverable_QualityFailed_NoDocProjectionSideEffects`(敌意 `Success=true`)
- **F(阶段链)**:`ExecuteStage` 在 `err=nil` 后经 `classifyStageTaskHalt` 检查质量/`Success`;失败立即停链,保留失败 artifact,不吸收 ExtractedData、不追加 PriorDoc、不写 completed workspace / 阶段跃迁。单测:`TestExecuteStage_QualityFailed_StopsChainWithoutAbsorbingFactsOrPriorDoc`
## 证据
- workspace path 如上;events seq10;output.md:204
- assets:[../test-reports/assets/2026-09-13-document-revision-runtime-ui/](../test-reports/assets/2026-09-13-document-revision-runtime-ui/)(勿删)
## 关联
- Short-term 扩写:[../ops/short-term/2026-09-13-document-revision-sse-idempotency.md](../archive/ops/2026-09-13-document-revision-sse-idempotency.md)
- SSE 幂等审计:[./2026-09-13-document-revision-sse-idempotency.md](./2026-09-13-document-revision-sse-idempotency.md)
@@ -0,0 +1,56 @@
---
title: "UI-03 质量修复子工作区越界改写根 output.md"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-03 质量修复子工作区越界改写根 output.md
## 现象
第13轮 Antigravity 完整 UI(schema 30,dev@8b1a531 基线):UI00–02 PASS,UI-03 真实 PI 终态 `quality_failed`,页面 70 分、缺少必填章节「阻塞信息 / 非阻塞信息」。
真实工作区 `/app/data/workspaces/bizdev/intake_1789329815528283509`:
- `tasks/03_review/output.md` 于 20:07:02 **确实没有**两个章节;质量门禁判定正确,不得放宽必填章节。
- `EnsureQualityOrRepair` 创建 `tasks/repair_1`,TASK.md 同时写「参考 `../../template.md`、基于 `../../output.md`、输出到 `output.md`」。
- 真实模型读取父级文件后,`edit` 写了 `tasks/repair_1/../../output.md`(根 `output.md`);根文件 20:07:24 已补齐两章节。
- `tasks/repair_1/output.md` **从未生成**;runner 目标仍是本地 `output.md` → `missing target` → `runOneStep` 失败 → `EnsureQualityOrRepair` break → manifest 保留原 70 分。
- runner `execution.log` 的 `Outcome: SUCCESS` 只是模型 settle,不代表目标契约成功。
## 根因分析
| 层 | 问题 | 后果 |
|---|---|---|
| TASK 契约 | 修复步骤把输入写成 `../../output.md` / `../../template.md` | 模型按字面去 edit 父级 |
| 沙箱 | `buildSubWorkspaces` 对 template/blackboard 建 **symlink** | 子目录写同名文件会打穿父级 |
| Needs | 只在 TASK 里列 `../../need`,不把原稿快照成非目标文件名 | 若复制成本地 `output.md` 会假成功;当前则诱导越界 |
| 成功判定 | 只认本地 `output.md`(正确),但失败后不恢复被改的根文件 | 根文件「看起来更好」却不覆盖/不重验,页面仍 70 |
| 提升谓词(独立审查) | 曾在 `runErr != nil` 或 containment 后仍因 `localOK` 提升 | 截断产物或越界轮次会被当成修复成功 |
| settle | 内部 Outcome SUCCESS ≠ 本地目标存在 | 不得把 settle 当交付 |
`MatchDeliverableRel` 已拒绝 `../`,因此 missing-target fail-closed 正确,**不能**因此把越界根文件当成功。
## 严重度
`high`
自动修复轮空转:模型可能已经写好章节,契约失败导致任务 `quality_failed`。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-quality-repair-workspace-contract.md](../remediation/2026-09-13-document-revision-quality-repair-workspace-contract.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-quality-repair-workspace-contract.md](../archive/ops/2026-09-13-document-revision-quality-repair-workspace-contract.md)
- 分支: `fix/document-revision-quality-repair-workspace-contract`
## 证据
- 失败证据(根代理保留、本轮不得改/移/删/提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui03-required-sections-quality-failure/`
## 开放问题
- 本轮不跑真实 UI-03;不得标 E2E 通过或任务 `done`
- 默认子步骤仍可用 `../../` + symlink(未改正常步骤读本地 context 的路径)
- **剩余风险(保护范围)**:containment 只快照/恢复 `output.md` / `template.md` / `blackboard.json`。模型改写其它父级文件(如 `PLAN.md`、其它 `tasks/*`)检测不到、不会回滚。创建/删除这三份受保护输入已计入 mutation。
@@ -0,0 +1,50 @@
---
title: "行动计划表状态列「待续」被质量门禁误判为敷衍"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# 行动计划表状态列「待续」被质量门禁误判为敷衍
## 现象
第三轮真实 UI(新用户 `mtzzliz5`,新项目,真实 MiniMax):
- UI-00~02 PASS;**UI-03** 两轮 auto-repair 后 **`quality_failed` 80/100**
- workspace=`intake_1789314411395330821`
- `manifest.prohibited_phrases` 仅 **「待续」**
- `output.md` 第163–164 行与 `repair_1` / `repair_2` 对应行均为行动计划表状态单元格,而非省略正文:
```text
| **待续** | 合规专员基于用户补充材料... | 合规专员 | D-01至D-07全部确认后 |
| **待续** | 组织专员编制里程碑规划与检测排期方案... | 组织专员 | 合规评估完成后 |
```
表头为 `| 阶段 | 行动项 | 负责方 | 触发条件 |`,节标题为「下一步行动建议」。泛化修复提示未能让模型改掉结构化状态词,造成真实假阳性。
## 根因分析
`containsProhibitedUsage` 对禁词「待续」做全文命中;既有豁免只覆盖自检/规则行的否定或引号引用。行动计划表把「待续」用作**独立阶段状态**(与「立即」并列),不是「后续章节待续」式正文省略。门禁无法区分结构,扣 20 分后触发无效 auto-repair。
审查补强:豁免必须按表头把命中列对齐到「阶段/状态/进度」;动作/负责方/触发条件按表头索引取值。负责方或触发条件单元格为「待续」不得豁免。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-quality-context.md](../archive/ops/2026-09-13-document-revision-quality-context.md)
- 分支: `fix/document-revision-quality-context`
- 前序自污染豁免不得回退:[./2026-09-13-document-revision-quality-gate-self-pollution.md](./2026-09-13-document-revision-quality-gate-self-pollution.md)
## 证据
- Evidence root(勿删、勿提交本轮):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui03-quality-status-false-positive`
- 只读 workspace:`data/dev/workspaces/bizdev/intake_1789314411395330821`
## 开放问题
- 占槽后真实 UI-03 重跑;本轮不操作容器、不改 E2E
@@ -0,0 +1,82 @@
---
title: "项目 reviewer 未同步到受控文档职责"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: critical
---
# 项目 reviewer 未同步到受控文档职责
## 现象
第17轮真实 UI(schema 30,`dev@639969f`):UI-00 至 UI-12 PASS。UI-13a 精确职责断言首次暴露产品缺陷:
- UI-01 页面建项目把 USER_B 的职责下拉设为 `reviewer`
- B 登录打开 `doc_proj6145_intake` 权限矩阵时,select `value` / badge `data-doc-role` 实际为 `viewer`
- 失败:`reviewer B intake duty select must be reviewer: expected_duty:reviewer;got:viewer`
现场文档头仍写「编制人: 编制工程师 / 审核人: 审核负责人 / 批准人: 批准负责人」。
## 根因分析
只读查本轮 `project 6145`(不暴露账号密码/token):
| 层 | 证据 | 后果 |
|---|---|---|
| 立项 UI | `CreateProjectModal` 把 B 标成 `reviewer`;默认还勾选 seed `id=3` 李主管 / `id=4` 王总监 | 用户意图是 B=审核人 |
| 成员持久化 | `toApiProjectRole` **禁止** author/reviewer/approver,一律映射 `member`;payload 无 document duty | B=`171` 落成 `project_role=member` |
| `project_members` | `170` owner(A)、`171` member(B)、`3`/`4` member | 库表无法区分 B 是 reviewer |
| 任务生成 | `bizdev.service`:`ReviewerID==0` → **写死 2** +「审核负责人」;`ApproverID==0` → **写死 3** | 与真实成员无关 |
| `document_records` | intake / prelim_design 均为 `author_id=170`(恰为创建者 UserID)、`reviewer_id=2`、`approver_id=3` | 第二份文档继承了同一套假职责 |
| 列表 API | 原样投影 `reviewer_id=2` | 前端拿到权威但错误的 id |
| `resolveCurrentDocRole` | 受控文档按 id 匹配,fail-closed 为 viewer | B=`171` ≠ `2` → viewer;**不是前端提权,是服务端职责丢失** |
`document_duty_assignments` 只挂官方工作流实例任务,聊天 `TRIGGER_TASK` 生成账本不走该表。
## 严重度
`critical`
项目创建时明确指定的审核人在后续每份受控文档上变成查阅者;写路径虽因 fail-closed 未把 B 提成编制人,但审核职责与权限矩阵验收全部失真。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-reviewer-duty-sync.md](../remediation/2026-09-13-document-revision-reviewer-duty-sync.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-reviewer-duty-sync.md](../archive/ops/2026-09-13-document-revision-reviewer-duty-sync.md)
- 分支: `fix/document-revision-reviewer-duty-sync`
## 证据
- 失败归档(只读,不改不删):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui13a-reviewer-duty-sync-failure/`
- `phase-state.json`:`controlledDocId=doc_proj6145_intake`,项目 `UI验收-超声微创系统-mu0bvnp8`
- Playwright:`expected_duty:reviewer;got:viewer`
## 独立审查收紧(同一分支,暂不合入)
独立审查指出首轮 Heal「已是任意在任成员则保留」会让批准人串位:6145 类场景 `approver=3`(李主管也是成员)而 assigned=`4` 时不应保留 3。项目 `document_duty` 才是权威。
立项后成员增改/恢复若只发 `project_role`,`document_duty` 会静默失效。更新成员时若省略 `project_role` 且带 `document_duty`,默认 `member` 会把 owner 降级。
生成/列表路径若吞掉自愈错误,会带着 `reviewer_id=2` 假成功。
## 最后一轮缺口(已在同分支修复)
- 移出成员只改 `exited` 不同步文档;前端移出不刷新矩阵
- 空 assigned 若保留非成员占位,退出审核人会留在文档上
- reviewer→viewer 时人仍 active,generic heal 会把槽位留下,必须按更新前 duty 显式撤销
- `CreateOrGetDocument` 错误被 `_` 吞掉会假成功
## 原子清槽约束(已在同分支修复)
职责撤销/转移不得在成员 upsert 已提交后再用服务层前后快照做非原子清理。权威路径是同一 DB 事务:`pg_advisory_xact_lock` → 读旧 duty / 冲突 holder → 成员更新 → 精确清 `reviewer_*` / `approver_*`。随后 heal 填新 holder。
## Heal 与成员写竞态(已在同分支修复)
`HealProjectDocuments` 若无项目锁、用 pool 先读后写,会出现:heal 读到 reviewer A → 成员事务持锁把 A 清槽并提交为 B → 旧 heal 把 A 写回。现已与成员写共用 `pg_advisory_xact_lock(project_id)`,解析与 `document_records` 更新在同一事务。
## 开放问题
- 本轮不重跑真实 UI-13a;不得标 E2E 通过或任务 `done`
- **6145 剩余风险**:迁移后 owner 会补 `author`;B(171)当时只落成 `member` 且 `document_duty=''`。服务端不能臆造 reviewer。须再次经成员 API 写入 `document_duty=reviewer` 后,自愈才会把文档从占位 `2` 对齐到 B。
- 隔离 PG 集成须用临时库 + `TEST_DATABASE_URL`,见 `scripts/run-isolated-duty-sync-pg-tests.sh`;禁止默认连 `agent_system_dev`
@@ -0,0 +1,117 @@
---
title: "文档版本账本运行时 404 与修订链路失效现场审计"
status: done
created: 2026-09-13
updated: 2026-09-14
severity: critical
# note: Round20 真实 UI PASS 后运行时 404 链路关闭;剩余开放仅为 PI 叙事 fallback 与无关系统 blocker
---
# 文档版本账本运行时 404 与修订链路失效现场审计
## 现象
登录项目对话后:
1. `GET /api/v1/documents/doc-upload-1789263145197-0/revision-state` → **404**,body 含 `docrevision: not found`
2. `GET /api/v1/documents/doc_proj143_srs/revision-state` → **404**(同错误)
3. UI 工具条显示「版本账本未就绪:docrevision: not found」
4. 块双击编辑保存无效(或仅改本地 AST)
5. 纯净阅读 / 人工修改 / 全部变更切换无可视效果
6. 未重跑智能体小队时看不到变更摘要、风险、项目/文档影响(预期);但即便重跑,当前接线也会写入**静态假 JSON** 而非真实 diff/报告
## 根因分析(证据)
### R1 — 账本仅进程内 map,PostgreSQL schema 未真正读写(主因)
`internal/docrevision/service.go` 中 `Service` 虽接收 `*pgxpool.Pool`,但全部状态存在:
- `blobs` / `snapshots` / `versions` / `events` / `candidates` / `reports` / `roots` / `idemp`
`GetRevisionState` 仅查内存 `s.roots[docID]`;无 hydrate、无 INSERT/SELECT。
Goose `00028` 已建表且 CURRENT 记录 schema 28 healthy,但**运行态账本与 PG 脱节**。
**后果**:服务重启 / 多副本 / 冷启动后一律 404;backfill CLI 亦 `NewService(nil)`,apply 不落库。
### R2 — GET revision-state 无确定性 bootstrap
账本仅在以下路径创建:
- `OpenTemplateVersion`(PATCH 时 DocGov 命中且先前 404;或 bizdev 首次 agent 成功)
- `CommitHumanRevision` + `AllowCreateBaseline`
- freeform `syncLedgerLocked`(仅走 freeform 保存 API 时)
首次打开文档只读 GET **不会**从 `document_records` / `freeform_documents` / `output.md` 回填 → 老文档与上传文档稳定 404。
### R3 — 上传文档与受控文档解析/权限边界未统一
- `doc-upload-*`:前端本地 `deliverables` + IndexedDB,**未**强制经 freeform API 落库;`governanceMode: freeform`
- `doc_proj143_srs`:受控 DocGov 记录存在,但无 ledger 指针/内存根
- Handler `handleDocRevisionState` 仅 `requirePrincipal`,未走 DocumentAccess / 项目成员校验,也未按 kind 解析事实源
### R4 — 人工块保存未更新用户所见事实源
`web/src/App.tsx` `handleSaveBlockEdit`:
```ts
if (!target || target.governanceMode === 'freeform') {
return; // 上传/自由文档直接跳过 PATCH
}
```
受控路径虽调 PATCH,但:
- `ProjectOutputMarkdown(docID, ".")` 工作目录相对路径易错;
- 成功后仅 `MarkDocumentContentUpdated` 哈希,重启后内存账本仍丢;
- GET 404 时工具条已坏,overlay 无数据。
### R5 — Overlay 三模式未接到块渲染
- `DocumentRevisionToolbar` 在 state=null 时仍可切换 select,但 `onOverlay(null)`
- `ManualChangeOverlay` 仅为提示文案,不装饰块
- `BlockRenderer` 无 `overlayHunks` / 模式 props;App 仅在工具条下显示「人工差异 N 处」统计条
### R6 — Agent/Squad → change report 使用静态假数据(工程已修;叙事仍 blocker)
**原状**:`bizdev` 硬编码 `summary:["智能体交付物已生成"]`,且首次成功仅 `OpenTemplateVersion`、无 candidate/report。
**修复(fix 分支)**:`MaterializeAgentOutput` — 无账本时用显式空基线 `EmptyGenerationBaseline` 开版,再 `CreateAgentCandidate` + `BuildDeterministicChangeReportJSON`(`analysis_status=fallback`);二轮对 head 再出候选与报告。禁止把 fallback 宣称为 PI 完整分析。
**仍开放**:`DOCREV-RT-PI-NARRATIVE`(业务叙事摘要需真实 PI 链路)。
### R7 — PATCH 先写事实源再写 ledger(工程已修)
**原状**:`handleDocRevisionPatchContent` 先 `SaveDocumentContent` 再 ledger;ledger 失败时 output.md 已变。
**修复**:`AssertHumanCanEdit`(租约+编制人)→ ledger commit → `ProjectOutputMarkdown` / freeform `UpdateDocument`;投影失败返回 `DOCUMENT_PROJECTION_FAILED`(非假 200),账本 head 仍为权威、可重试投影。
## 严重度
`critical` — 版本账本对用户表现为全面不可用;保存与差异认知失效;假报告有审计污染风险。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-runtime-remediation.md](../remediation/2026-09-13-document-revision-runtime-remediation.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-runtime.md](../archive/ops/2026-09-13-document-revision-runtime.md)
- 前置设计: [../system-design/document-revision-management.md](../system-design/document-revision-management.md)
- 前置 ADR: [../adr/2026-09-13-document-version-boundary.md](../adr/2026-09-13-document-version-boundary.md)
## 证据
| 项 | 路径 |
|----|------|
| 内存账本 | `internal/docrevision/service.go` `NewService` / `GetRevisionState` |
| PG schema 未接线 | `deploy/postgres/goose/00028_2026-09-13-document-revisions.sql` |
| GET 无 bootstrap | `internal/server/document_revision_handlers.go` `handleDocRevisionState` |
| freeform 跳过保存 | `web/src/App.tsx` `handleSaveBlockEdit` |
| 静态 report | `internal/bizdev/service.go` CreateAgentCandidate `ReportJSON` |
| Overlay 空壳 | `web/src/components/doc/ManualChangeOverlay.tsx` |
## 开放问题
1. 纯客户端上传且从未调用 freeform create 的文档:服务端无正文事实源 → bootstrap 需 PATCH/显式注册,或返回可操作的 empty/register 状态(禁止静默假账本)。Round20 UI-16 验证的是已注册 `doc-free-*` 路径。
2. PI Agent 叙事变更报告(业务含义、开放问题文案)需独立调用链;Round20 仍为确定性 fallback,**不得**宣称为完整 PI。
## 关闭记录(Round20)
现场 404 / 未就绪 / 保存与 overlay 失效已在真实页面闭环。证据:[../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)。项目 6159 / `doc_proj6159_intake` / V3/r2。历史失败资产不删。
@@ -0,0 +1,45 @@
---
title: "UI-06 全页模糊保存按钮未发出 PATCH"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-06 全页模糊保存按钮未发出 PATCH
## 现象
第七轮真实 UI(schema 30):
- 稳定 `document-block` 已成功双击,编辑弹窗出现
- `saveOpenEditor` 使用全页 `getByRole(button, { name: /保存修改|保存/ })`
- 严格模式同时命中 7 个「一键保存到我的私密文档库」与真正的「保存修改」
- **未发送 PATCH**,UI-06 失败
## 根因分析
| 层 | 问题 |
|---|---|
| 聊天栏 | `ReplyActionBar` 保存按钮的可访问名称是 `aria-label="一键保存到我的私密文档库"`,含「保存」 |
| 弹窗 | `BlockEditorModal` 无 `role=dialog` / 稳定 `aria-label`,无法按 dialog 收窄 |
| 脚本 | 全页模糊 `/保存修改\|保存/` 在 Playwright 严格模式命中多个控件 |
块寻址已修好;本轮是 **保存选择器过宽**,不是正文或双击失败。
## 严重度
`high`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-e2e-save-selector.md](../archive/ops/2026-09-13-document-revision-e2e-save-selector.md)
- 分支: `fix/document-revision-e2e-save-selector`
## 证据
- Evidence root(已归档、本轮勿提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui06-save-selector-failure/`
## 开放问题
- 占槽后真实 UI-06/13b 重跑;本任务保持 `in_progress`,不得标 `done`
@@ -0,0 +1,46 @@
---
title: "UI-11 第二份文档路由到 intake 且 human lease 残留"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-11 第二份文档路由到 intake 且 human lease 残留
## 现象
第十轮真实 UI(schema 30):
- UI-00~UI-10 **PASS**
- UI-11 页面输入:请另行生成一份《系统设计输入》受控文档(第二份),不要覆盖上一份需求文档,并给出可打开的交付物。
- 页面回复《用户初始需求收集表》正由其他用户编辑/生成中,**未启动任务**
## 根因分析
| 层 | 问题 |
|---|---|
| 路由 | `resolveTaskKeyFromMessage` 写意图后先扫「需求\|摸底\|用户\|首轮」,否定句「不要覆盖上一份**需求**文档」压过正向点名「系统设计输入」 |
| 别名 | `NAMED_DELIVERABLE_ALIASES.prelim_design` 只有「初步设计说明书 / 系统设计规格」,缺「系统设计输入」(模板正式标题是「系统初步设计方案」) |
| 租约 | PATCH 在 `AssertHumanCanEdit` 后持 15min human lease;本 UI 无 heartbeat/token。成功 / 409 / 投影失败都不释放,intake 被锁,小队再跑 intake 得 DOC_BUSY |
| E2E | UI-11 `sendChat` 后直接 `waitForSquadCompletion`,没有 `tasks/runs` 202 门闩;同步 busy completed 可能被当成成功 |
## 严重度
`high`
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-second-doc-routing-lease.md](../remediation/2026-09-13-document-revision-second-doc-routing-lease.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-second-doc-routing-lease.md](../archive/ops/2026-09-13-document-revision-second-doc-routing-lease.md)
- 分支: `fix/document-revision-second-doc-routing-lease`
## 证据
- Evidence root(已归档、本轮勿提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui11-second-doc-routing-human-lease-failure/`
## 开放问题
- 占槽后真实 UI-11 重跑;本任务保持 `in_progress`,不得标 `done`
- 请求级租约:同用户双窗 ETag 冲突靠 If-Match,不靠租约互斥(同 `holderID` 会续租)
- 卡片展示标题是「系统初步设计方案」(非 prompt 别名「系统设计输入」);E2E 必须按 `doc_proj{n}_prelim_design` 打开
@@ -0,0 +1,46 @@
---
title: "任务 run SSE 超时断线后同 turn 误击 DOC_BUSY"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: critical
---
# 任务 run SSE 超时断线后同 turn 误击 DOC_BUSY
## 现象
真实 Antigravity UI-03(dev schema 30):
1. 初始 `POST /api/v1/tasks/runs` → **202** `run_1789308825655387640`
2. `GET .../events` 约 **157s** 后以 `ERR_INCOMPLETE_CHUNKED_ENCODING` 断开(对齐服务端默认 `WriteTimeout=120s`)
3. 浏览器用**完全相同** `session=sess-p6098-u107`、`client_turn_id=turn_1789308825646`、`doc_id=doc_proj6098_intake` 再 POST
4. `handleCreateTaskRun` 在幂等 `ClaimRun` **之前**执行 `preflightTaskDocumentBusy` → **409 DOC_BUSY**,并 `recordBusyPreflightMessages` 写入**重复**用户/失败助手消息
## 根因分析
| 层 | 问题 |
|---|---|
| HTTP | 全局 `WriteTimeout: 120s` 切断长任务 SSE 响应体,客户端见 incomplete chunked encoding |
| Handler | 同 turn 重试仍走 scope/preflight;活跃小队租约被当成「别人在编」 |
| FE | `subscribeTaskRunEvents` 遇意外 EOF 直接结束,上层可能再次 `createTaskRun` |
## 严重度
`critical`
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-sse-idempotency.md](../archive/ops/2026-09-13-document-revision-sse-idempotency.md)
- 分支: `fix/document-revision-sse-idempotency`
## 证据
- 运行产物目录(勿删):[../test-reports/assets/2026-09-13-document-revision-runtime-ui/](../test-reports/assets/2026-09-13-document-revision-runtime-ui/)
- 前序 UI-03 客户端同步审计:[./2026-09-13-controlled-doc-client-sync-ui03.md](./2026-09-13-controlled-doc-client-sync-ui03.md)
- 现场键:`run_1789308825655387640` / `sess-p6098-u107` / `turn_1789308825646` / `doc_proj6098_intake`
## 开放问题
- 合入前占槽真实 UI 重跑 UI-03(本轮不 rebuild Docker)
- chat `/stream` 与 `tasks/run/stream` 是否需同样 SSE write-deadline 扩展(本轮优先 `/tasks/runs/{id}/events`)
@@ -0,0 +1,48 @@
---
title: "UI-13a 在私密分类下打不开受控工作流文档"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
severity: high
---
# UI-13a 在私密分类下打不开受控工作流文档
## 现象
第15轮真实 UI(schema 30,`dev@48a4dcb`):UI-00 至 UI-12 全部 PASS,UI-11 快速完成修复已实证 PASS。**UI-13a 在真正权限断言前失败**。
`openWorkflowDocById(page, doc_proj6143_intake)` 报:`doc-selector menu missing data-doc-id=doc_proj6143_intake`。
现场快照:分类触发器为「我的私密 1」,文档下拉只有私密清单。intake 仍存在于对话引用中,只是当前分类菜单不可见。
## 根因分析
| 层 | 问题 | 后果 |
|---|---|---|
| UI-11 后状态 | 上传归档把 active category 留在 `private` | 后续步骤默认停在「我的私密」 |
| 验收导航 | `openWorkflowDocById` / `ByLabel` / `ByControlledTaskKey` 直接展开当前分类的文档菜单 | 私密菜单里没有 `doc_proj*` |
| 分类控件 | 真实页面必须先点 `doc-category-trigger` 再选 `data-category=workflow`(文案「流程受控」) | 脚本跳过该步即 fail-open 于错误清单 |
不是权限矩阵错,也不是 intake 丢失。
## 严重度
`high`
阻断 UI-13a 及之后所有「从任意分类回到受控文档」的步骤。
## 关联整改
- Remediation: [../remediation/2026-09-13-document-revision-workflow-category-navigation.md](../remediation/2026-09-13-document-revision-workflow-category-navigation.md)
- Short-term: [../ops/short-term/2026-09-13-document-revision-workflow-category-navigation.md](../archive/ops/2026-09-13-document-revision-workflow-category-navigation.md)
- 分支: `fix/document-revision-workflow-category-navigation`
## 证据
- 失败证据(只读,不得改/移/删/提交):`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/schema30-ui13a-category-navigation-failure/`
## 开放问题
- 本轮不重跑真实 UI-13a;不得标 E2E 通过或任务 `done`
- 不得用直接 API / 改内存 `activeCategory` 规避页面分类控件
@@ -0,0 +1,88 @@
---
title: "无 live 误拒 + chat 缺项目授权 + 立项成员未落库(UI-01/02)"
status: done
created: 2026-09-13
updated: 2026-09-13
severity: critical
---
# 无 live 误拒 + chat 缺项目授权 + 立项成员未落库(UI-01/02)
## 现象
1. **UI-02**:项目 6071 `creator_user_id`/`project_members` owner 正确,但 `project_workflow_instances` 零记录;页面首轮 intake 返回 `WORKFLOW_ACCESS_DENIED`。
2. **安全连锁**:若仅把「无 live」改为 unrestricted,而不在 `handleChat`/`handleChatStream` 做项目成员校验,任意登录用户只要猜到 `project_id` 即可进入项目对话。
3. **UI-01/UI-13**:页面勾选 B 为 reviewer,但 `project_members` 仅有 creator A;B 新浏览器看不到项目。
## 根因分析
### A. ResolveStageAccess 与 GetLiveInstance 语义错位
- 注释写明「无 live 不限制(legacy)」,但 `err != nil || live == nil` 分支设 `Restricted=true`,空允许名单 → 新建未激活项目被全拒。
- `GetLiveInstance` / `HasLiveInstance`(PG)仅返回 active 系;**completed/terminated 在 PG 上表现为 live=nil**。若把 live=nil 一律 unrestricted,会把已结束实例误判为从未激活,使 `CheckDocTaskAccess` 的 `WORKFLOW_INSTANCE_CLOSED` 在生产 PG 成死代码。
### B. Chat 入口缺项目成员门禁
- `handleChat` / `handleChatStream` 仅有 stage ABAC(`allowActiveStageChatAccess`),**无** `RequireProjectAccess`。
- `handleChatStream` 在鉴权前即 `Content-Type: text/event-stream` + `Flush()`,拒绝时已是 200 SSE。
### C. 立项成员只写本地
- `App.handleCreateProjectConfirm` 在 `createProject` 成功后构造本地 members/sessions,**从未**调用 `addProjectMember`;服务端仅有 creator owner。
## 严重度
`critical`(错误拒绝阻断 UI-02;修复 A 而不修 B 会开放跨项目对话;C 阻断跨设备协同与 UI-13)
## 本轮修复
1. **Store**:新增 `GetGoverningInstanceForAccess`(优先 live,否则最新 completed/terminated;无则 nil)。`HasLiveInstance`/`GetLiveInstance` 保持 active-only。mem 与 PG 对齐。
2. **ABAC**:`ResolveStageAccess` / `CheckDocTaskAccess` 改用 governing 实例;无实例 unrestricted;closed 全拒;存储错误 fail-closed/上抛。
3. **Chat**:`enforceChatProjectAccess`(成员/创建者;系统管理员按既有策略);同步与流式均在 stage 之前;SSE **headers/Flush 之前**结构化 JSON 403。
4. **立项**:`ensureCreatedProjectWithMembers` + `persistInitialProjectMembers`;失败显式报错并保留 bootstrap project id 幂等重试;成功后才关弹窗。
5. **立项双击竞态**:同步 in-flight ref 锁 + `createProjectBootstrapIdRef`(取代 state);Modal `submitting`/`submitPhase` 禁用确认与关闭,文案「立项中/同步成员中」。
6. **任务作用域三态**:`ResolveMessageScopeForTask` 用 `GetGoverningInstanceForAccess`——从未激活→`ScopePreActivation`;live→阶段作用域;closed→拒绝;存储错误上抛。
## 证据
- 实战:项目 6071 零实例 + `WORKFLOW_ACCESS_DENIED`;成员表无 B
- PG:`TestPG_GoverningAccess_*`(never / active outsider / completed|terminated / query error)
- PG:`TestChatProjectAccess_*`(nonmember 403 无 event-stream;creator/member 200 SSE)
- FE:`createProjectMembersPersist.test.ts`
- FE:`createProjectSubmitGuard.test.ts`(in-flight 锁 + 文案/关闭门禁)
## 关联整改
- Short-term: [../ops/short-term/2026-09-13-document-revision-runtime.md](../archive/ops/2026-09-13-document-revision-runtime.md)
- 前序: [2026-09-13-admin-user-directory-sync-ui01.md](./2026-09-13-admin-user-directory-sync-ui01.md)
## 开放问题
- 跨设备用户目录(非 admin 成员目录 API)仍见前序 audit residual
- 立项 UI 角色 reviewer→API `member` 为既有契约;文档三权仍在工作流 plan duties,非 `project_members.project_role`
## 后续竞态(已确认并修复)
### D. `createProjectBootstrapId` 为 React state 导致双击重复建项
**现象**:快速双击「确认立项」时,两个 async 调用可同时读到 `bootstrapId=null`,各自 `createProject` → 重复项目。
**根因**:`useState` 更新非同步;仅靠 bootstrap state 无法在入口互斥。`disabled` 若依赖尚未提交的 submitting state,首帧仍可连点。
**修复**:
1. 同步 `useRef` in-flight 锁(`beginCreateProjectSubmit` 入口立即锁 / `finally` 解锁)
2. `createProjectBootstrapIdRef` 取代 React state 保存 bootstrap;`create` 成功即写入,成员失败后串行幂等重试
3. `createProjectSubmitting` + `submitPhase` 传给 `CreateProjectModal`:确认按钮禁用并显示「立项中 / 同步成员中」,阻止关闭与重复 submit
4. 失败解锁后允许再次确认;成功清 bootstrap
**证据**:`web/src/lib/createProjectSubmitGuard.test.ts`;`createProjectMembersPersist` onPhase 断言
### E. 无 live 新项目 POST `/api/v1/tasks/runs` → 409 TASK_SCOPE_UNRESOLVED(UI-02)
**现象**:UI-00/01 PASS;UI-02 截图「连接异常,1s后自动重试…」;网络唯一 POST `tasks/runs`=409;E2E 因短暂「生成中」误记 PASS。
**根因**:stage/doc access 已允许无 governing 新项目兼容运行,但 `ResolveMessageScopeForTask` 对 no-live 一律 `ErrTaskScopeNotResolved` → handler 409。若仅凭 `GetLiveInstance=nil` 放行,会把 completed/terminated 误当预激活。
**修复**:`ResolveMessageScopeForTask` 经 `GetGoverningInstanceForAccess` 三态——nil→`ScopePreActivation`;live 系→阶段作用域;completed/terminated→`ErrTaskScopeNotResolved`;存储错误原样上抛。E2E UI-02 等待 `tasks/runs` 真实响应并要求 2xx,409/连接异常立即 FAIL。
**证据**:`message_scope_test.go`(preactivation / live / closed 组合 / storage error);`TestCreateTaskRun_PreActivationAcceptedNot409`;`web/e2e` UI-02
@@ -0,0 +1,52 @@
---
title: "arch-check Wave 0 基线"
status: done
created: 2026-09-14
updated: 2026-09-14
severity: medium
---
# arch-check Wave 0 基线
## 现象
模块边界此前只能靠人工约定。Wave 0 用当前 `go list` 生成 import allowlist,并用目标属主扫描表名与路径字面量,得到可重复的 warn 基线。
## 根因分析
`document_records`、`output.md`、`data/dev` 被多个包直接提及,与「单一写者 / 路径属主」目标不一致。这些不是本轮回归,而是 Wave 1+ 的收口对象。
## 严重度
`medium`
## 关联整改
- ADR: [../adr/2026-09-14-modular-monolith-decoupling.md](../adr/2026-09-14-modular-monolith-decoupling.md)
- 设计: [../system-design/2026-09-14-module-decoupling-architecture.md](../system-design/2026-09-14-module-decoupling-architecture.md)
- 任务: [../ops/short-term/2026-09-14-module-decoupling-wave0.md](../ops/short-term/2026-09-14-module-decoupling-wave0.md)
## 证据
命令:`./scripts/arch-check.sh --mode warn`(2026-09-14,本工作区)
- import 相对基线 allowlist:**0** 条新边
- 目标属主扫描:**21** 条 warn(按包去重)
```
WARN R5 table document_records mentioned in authz, workspace, docduty, server, bizdev, docrevision
WARN R5 table freeform_documents mentioned in docrevision
WARN R5 table task_runs mentioned in server, projectinstance, docgov
WARN R6 path output.md mentioned in coordinator, server, bizdev, docgov, docrevision, agent
WARN R6 path data/dev mentioned in coordinator, server, bizdev, storage
WARN R6 path workspaces/ mentioned in server
violations=21
arch-check warn: recorded 21 baseline findings
```
`--mode block` 会因这 21 条失败,故 **不得**在 warn 期满前把脚本挂进集成冒烟。
## 后续
- Wave 1 起按属主清零上表,再把对应规则转 block
- 本轮不占集成槽、不 `env-service` rebuild
@@ -0,0 +1,81 @@
---
title: "UI-06 页面刷新后受控正文停留加载骨架竞争态审计"
status: done
created: 2026-09-14
updated: 2026-09-14
severity: high
---
# UI-06 页面刷新后受控正文停留加载骨架竞争态审计
## 现象
在真实 UI 验收主阶段 `e2e/document-revision-runtime.spec.ts` 的 `UI-06` 用例中:
1. 用户 A 双击段落完成人工修改并保存,PATCH 200 成功,修订版本从 `r0` 递增至 `r1`;
2. 执行 `await page.reload()` 硬刷新页面;
3. 页面重新挂载后,顶栏与修订徽章显示 `r1`,但正文区域长时间停留在骨架占位文案:
`用户初始需求收集表 提示说明 正在从服务端加载文档正文… 受控状态: 编制中 • 已被编制人认领`
4. 导致 `getByText(marker)` 超过 30 秒未能在 DOM 中找到,测试套件判定 **FAIL**。
## 根因分析
从 Playwright Trace (`1-trace.network` / `1-trace.trace`) 的毫秒级时序分析:
1. **后端数据与接口均正常**:
- `03:22:19.374Z (+6.1ms) GET 200 /api/v1/docgov/documents/doc_proj6172_intake/content`
- 返回数据快照 `resources/039f1e925ea0bf047bca866dba4e35cff8c72a2b.json` 第一行即包含本次修改标记 `# 人工修订段落 UI06-mu0o5hbq 用于硬刷新验收。`;
- 修订接口 `GET 200 /api/v1/documents/doc_proj6172_intake/revision-state` 正确返回 `r1`;
- 浏览器 Console 无任何报错。
2. **前端内部状态清理竞争(App.tsx)**:
- 页面重新挂载时,`useEffect` 触发受控正文拉取,在 `03:22:19.380Z` 将解析好的 AST 存入 `docCache[docId]` 并置 `controlledContentReady[docId] = true`;
- 页面重新挂载同时触发的 `syncWorkflowDocs`(`GET /api/v1/projects/6172/documents?category=workflow`)在 `03:22:19.384Z`(仅晚 4ms)返回;
- 在 [`web/src/App.tsx#L1746-L1765`](file:///home/weichen/projects/Agent-System/.worktrees/fix-controlled-content-ui-acceptance/web/src/App.tsx#L1746-L1765):
```typescript
const serverBackedIds = merged
.filter((d) => d.projectId === currentProjectId && shouldLoadControlledContent(d))
.map((d) => d.docId);
if (serverBackedIds.length > 0) {
setDocCache((cache) => {
const next = { ...cache };
serverBackedIds.forEach((docId) => {
delete next[docId]; // 无条件删除缓存
});
return next;
});
setControlledContentReady((ready) => {
const next = { ...ready };
serverBackedIds.forEach((docId) => {
delete next[docId]; // 无条件清空 ready
});
return next;
});
}
```
`syncWorkflowDocs` 无条件删除了 `docCache[activeDocId]` 与 `controlledContentReady[activeDocId]`。
3. **死锁成因**:
- 此时 `docAST` 判定 `docCache` 缺失且 `controlledContentReady` 为 false,回退至 `buildControlledLoadingSkeleton`;
- 在 [`web/src/App.tsx#L1258`](file:///home/weichen/projects/Agent-System/.worktrees/fix-controlled-content-ui-acceptance/web/src/App.tsx#L1258),拉取正文的 `useEffect` 依赖为 `[session, sessionValidated, activeDocId, activeHydrateFingerprint, applyHydratedDocument, hydrateResumeKey]`;
- `activeHydrateFingerprint` 仅包含 `docId`、`stage`、`updatedAt` 等,在缓存被清空后并未发生变化,导致不会再次唤醒网络拉取;
- 页面永久锁死在加载骨架屏。
## 严重度
`high`(阻断主阶段硬刷新、登出重登持久化及后续多文档验收)。
## 建议整改方案(供 Cursor 参考)
1. `syncWorkflowDocs` 不应对所有 `serverBackedIds` 进行盲目的全量缓存与 ready 标志清空;应比对服务端返回的 `updatedAt` / `sha256` / `stage`,仅在真正发生更新时定向失效;
2. 或者,若主动清空了已加载文档的缓存,必须同步唤醒重新拉取(如递增 `hydrateResumeKey`),避免状态丢失后无重入机制。
## 整改与复验结果
- Cursor 在 `08bf615` 引入统一的 `controlledContentInvalidation` 规划:`list_sync` 保留已水合缓存;`post_task` 定向失效并唤醒重水合;编辑期间保护活动正文并在关闭编辑器后恢复拉取。
- 修复通过 349 项前端脚本测试、30 项 Vitest 与生产构建,并随 `36e4bc3` 合入 dev 后 rebuild。
- Antigravity 在完全新建的真实 UI 项目中重跑 `UI-06`:人工编辑 `r0→r1` 后硬刷新,正文和唯一标记在 1.1 秒内恢复;完整主链与容器重启后恢复均 PASS。
- 有效证据与历史 FAIL/INVALID 运行严格分开,详见[真实 UI 验收报告](../test-reports/2026-09-14-controlled-content-ui-acceptance.md)。
## 证据路径
- 报告:`.doc/test-reports/2026-09-14-controlled-content-ui-acceptance.md`
- Trace:`.doc/test-reports/assets/2026-09-14-controlled-content-ui-acceptance/full-chain-valid/playwright-output-main/document-revision-runtime--d72a3-ard-refresh-persists-r-bump-chromium/trace.zip`
- 截图:`.doc/test-reports/assets/2026-09-14-controlled-content-ui-acceptance/full-chain-valid/playwright-output-main/document-revision-runtime--d72a3-ard-refresh-persists-r-bump-chromium/test-failed-1.png`
@@ -0,0 +1,107 @@
---
title: "项目 143 受控文档正文因规范化哈希漂移返回 404"
status: done
created: 2026-09-14
updated: 2026-09-14
severity: critical
---
# 项目 143 受控文档正文因规范化哈希漂移返回 404
## 现象
已登录用户打开项目 143 后,页面无法加载 `doc_proj143_intake` 正文,并周期性出现:
```text
GET /api/v1/docgov/documents/doc_proj143_intake/content 404
自动拉取受控文档正文失败: fetch controlled document content failed: 404
```
本轮未操作用户浏览器,也未执行真实 PI 或页面验收;上述 UI 现象来自用户现场。诊断仅对当前 dev 源码、PostgreSQL、容器挂载文件和既有真实 UI 证据做只读核对。
## 根因分析
### R1 — 文件存在,404 实际是哈希完整性冲突(直接原因)
当前 dev 数据链如下:
| 项 | 值 |
|---|---|
| project | `143`,active,workflow=`main` |
| document | `doc_proj143_intake`,非模板、drafting |
| work_dir | `/app/data/workspaces/bizdev/intake_1789270446856290128` |
| output.md | 存在,38,581 bytes |
| 文件原始 SHA-256 | `c97d749728bf5607a9117c29e45c0a165353f5bb8ba65532f21bda87232a988b` |
| `document_records.content_sha256` | `7e3c4954de0bd225ccde0c8494784d4275e7f29a517510f6a286ec004c35d490` |
| ledger head snapshot SHA-256 | 同上 `7e3c...d490`,38,571 bytes |
`output.md` 有 5 行各保留 2 个 Markdown 尾随空格,共多 10 bytes。逐行去掉行尾空白后,文件 SHA-256 **精确等于**数据库记录和账本 head 的 `7e3c...d490`。这证明漂移由当前 canonicalizer 的行尾裁剪造成,而不是文件缺失;但 Markdown 的两个尾随空格表示硬换行,具有渲染语义,不能把两侧判为语义等价,也不能直接用账本 blob 覆盖原文件。
`internal/docgov/project_docs.go::ReadDocumentContent` 对文件原始字节计算 SHA,并与 `document_records.content_sha256` 比较;不等即报 `content sha256 mismatch`。`internal/server/project_doc_handlers.go::handleDocGovGetDocumentContent` 又把 `ReadDocumentContent` 的所有错误统一写成 HTTP 404,所以页面看到的是错误的 Not Found。
### R2 — revision bootstrap 改了数据库哈希,没有同步规范化文件(制造漂移)
项目 143 的 `output.md` 于 2026-09-13 03:42 UTC 由真实小队落盘;账本 snapshot 66 于 10:32 UTC 才由旧文档首次 revision bootstrap 建立。
bootstrap 调用链:
1. `bootstrapRevisionIfNeeded` 从 DocGov 文件读出 Markdown;
2. `EnsureBootstrap` / `OpenTemplateVersion` 调用 `CanonicalizeMarkdown`;
3. canonicalizer 会去掉每行尾随空格,包括 Markdown 有语义的双空格硬换行;
4. `openTemplatePGLocked` 将 canonical SHA 写入 snapshot、blob 和 `document_records.content_sha256`;
5. 该路径没有把 canonical blob 重新投影到 `output.md`。
结果是数据库与账本指向 38,571-byte canonical 内容,兼容文件仍为 38,581-byte raw 内容。旧项目一旦被 bootstrap,后续正文读取稳定失败。
### R3 — content 与 revision 并发 hydration 使首次行为存在竞态
`hydrateControlledDocumentContent` 用 `Promise.all` 同时请求 content 与 revision-state。对尚未建账本的旧文档:
- content 若先读到旧 raw 哈希,可能首次成功;
- revision-state 随后 bootstrap 并把记录改成 canonical 哈希;
- 后续 content 立即或下一轮稳定 404。
既有真实 UI 资产已经记录过项目 143 的 `revision-state=200`、`content=404`;Round20 的 PASS 使用新项目 6159,不能覆盖项目 143 的旧数据迁移场景。
### R4 — 5 秒 lease 同步无变化也制造新数组,放大为重复 404
正文 hydration effect 依赖整个 `deliverables`。lease 轮询每 5 秒执行 `prev.map(...)` 并始终返回新数组,即使每个文档的 lease 均未变化。React 因引用变化重跑 hydration effect,持续请求同一已知失败正文。
因此控制台中的多次 404 不是多份正文丢失,而是一个后端一致性错误被前端无效状态更新周期性放大。
### R5 — 错误协议丢失可诊断信息
- 后端将记录不存在、文件不存在、文件为空、哈希冲突全部映射为 404。
- `fetchControlledDocumentContent` 只抛出 HTTP status,不解析结构化错误码、message 或 correlation id。
- 用户只能看到 `failed: 404`,无法区分可重试网络问题与必须修复的数据冲突。
## 影响范围
- **已确认受影响**:dev 项目 143 / `doc_proj143_intake`。
- 对当前 dev 中可定位到现存 `output.md` 的 27 个非模板受控记录做只读比对:26 个 raw SHA 一致,只有项目 143 为 mismatch。
- 数据库另有大量测试记录使用临时路径或空 `work_dir`;属于测试数据隔离/清理问题,不据此扩大本缺陷的用户数据范围。
- 任何“旧文件含会被 canonicalizer 改写的内容、首次 bootstrap 只改数据库不投影文件”的文档都具有同类风险;不能仅手工修项目 143 后关闭代码缺陷。
## 严重度
`critical` — 用户正文实际存在却无法在 UI 查看;编辑、overlay、版本比较等后续能力均被正文 hydration 阻断,且错误码误导为不存在。
## 关联整改
- Remediation: [../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md](../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md)
- 既有账本审计: [2026-09-13-document-revision-runtime-404.md](./2026-09-13-document-revision-runtime-404.md)
- 既有真实 UI 报告: [../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
## 证据
- 源码:`internal/docrevision/canonicalize.go`、`internal/docrevision/pg_mutate.go`、`internal/docgov/project_docs.go`、`internal/server/project_doc_handlers.go`
- 前端:`web/src/lib/controlledDocHydrate.ts`、`web/src/App.tsx`
- 数据库:`document_records.id=87`、`document_versions.id=59`、`document_snapshots.id=66`
- 历史 UI 资产:`.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/ui01-parent-directory-sync-failure/ui-acceptance-results.json`
## 关闭结果
- Cursor 已完成语义保持的 canonicalization、结构化错误、原子投影、定向 reconciler、legacy/mock 水合隔离和刷新缓存竞态修复;产品代码已合入并部署至 dev。
- 项目 143 已在保全原文件与旧 head 后以显式 `migration_repair` 校正账本,没有把裁剪硬换行的旧 head 静默覆盖回原文件。
- Antigravity 的 `clean-run3` 仅通过真实页面完成登录、正文打开、30 秒静置、人工编辑、三模式切换、硬刷新和退出重登;`doc_proj143_intake` 的 content/revision 目标 404 全程为 0。
- 新项目 `full-chain-final` 又覆盖真实小队生成、影响/风险报告、高风险确认与拒绝、多文档、上传账本、权限、并发冲突及容器重启后恢复。最终验收见[报告](../test-reports/2026-09-14-controlled-content-ui-acceptance.md)。
@@ -0,0 +1,104 @@
---
title: "workflow-plan 409 冻结冲突(项目 143)与三权设置粒度调整需求"
status: done
created: 2026-09-14
updated: 2026-09-14
severity: medium
---
# workflow-plan 409 冻结冲突(项目 143)与三权设置粒度调整需求
## 现象
用户在项目设置(`ProjectSettingsModal`)中把项目内所有文档任务的编制/审核/批准指派为「系统管理员 / 李审核 / 王总监」,点击「校验并预览」无反应。控制台报错:
```text
projectSettings.ts:51 PUT https://frp-mix.com:58880/api/v1/projects/143/workflow-plan 409 (Conflict)
```
同时用户提出新需求:**三权设置粒度按文档控制**——对某个允许省略人工审批的文档,一旦设置职责,必须三个职责(编制/审核/批准)都指派负责人;三个职责都未设置时,该文档仍可生成和进入版本账本,但不进入人工审批及阶段批准门禁。它不是“非受控文档”;若不需要生成该文档,应关闭文档任务。
## 根因分析
### 409 的直接原因:项目 143 已激活工作流,规划已冻结(PLAN_FROZEN)
dev 库(`shuimu-context-pg-dev` / `agent_system_dev`)实测:
```text
id | name | lifecycle_status | active_workflow_key | workflow_selection_version | workflow_plan_revision
-----+------+------------------+---------------------+----------------------------+------------------------
143 | 测试 | active | main | 2 | 1
id | project_id | status | config_revision | has_hash | created_at
----+------------+--------+-----------------+----------+-------------------------------
89 | 143 | active | 1 | t | 2026-09-13 01:31:33.212283+00
```
项目 143 于 2026-09-13 已激活 `main` 工作流(实例 89,status=active)。后端保存链路:
- `internal/projectinstance/service.go:131-133`(`SaveWorkflowPlan`):`if lifecycle != LifecyclePlanning { return nil, ErrPlanFrozen }`,冲突检查发生在最前;
- `internal/server/project_settings_handlers.go:164-165`:`ErrPlanFrozen` → HTTP 409 `{"error":"PLAN_FROZEN","message":"工作流已激活,规划已冻结"}`。
前端未能把该语义展示出来,构成「点击无反应」的体验:
- `web/src/api/projectSettings.ts:60-63`:非 2xx 直接抛出普通 `Error`。`parseError`(`projectSettings.ts:200-213`)其实已经能取到后端 `message`,所以“工作流已激活,规划已冻结”并未丢失;真正缺口是错误对象不保留 HTTP status/code/issues,UI 无法按 `PLAN_FROZEN`、版本冲突等类型切换冻结态或执行定向恢复;
- `web/src/components/project/ProjectSettingsModal.tsx:161-162`:catch 后写入 `error` state。弹窗在 `configure` 步骤的「校验并预览」按钮(538-557 行)点击后仅更新顶部 error 区(276-293 行),视口停留在长表单底部时用户看不到顶部横幅,感知即「无反应」。
### 前端缺少冻结态守卫
`ProjectSettingsModal.tsx` 的 `loadSettings`(53-81 行)只要 `s.plan` 存在就 `setStep('configure')`,`handleSelectWorkflow` / `handleSavePlan`(91-166 行)均未检查 `settings.lifecycle_status !== 'planning'` 或 `can_edit_plan === false`。后端 `GetSettings` 已正确返回 `can_edit_plan=false`(`internal/projectinstance/service.go:59-60,78-79`),前端没用它。因此已激活项目仍可一路走到保存,必然撞 409。
### 现行三权校验为「逐文档三职全必填」
- 后端 `internal/projectinstance/validator.go:93-95`:`dt.Enabled` 即调用 `validateDuties`;`validateDuties`(143-179 行)对启用的文档强制 `DUTY_AUTHOR/REVIEWER/APPROVER_REQUIRED` + 互斥校验;
- 前端 `ProjectSettingsModal.tsx:130-145`:成员数 <3 直接拦截;每个启用文档三职任一未指派即报错。
即当前不存在「整文档留空」的合法表达,与用户新需求冲突。门禁侧 `internal/projectinstance/gate.go:23-51` 对 `enabled` 的文档按工作流定义的 `BlocksWhenEnabled()` 计入阶段就绪——若允许留空却不改门禁,阻断型文档会产生永久死锁。因此**留空语义必须同步改门禁,但不能反过来让项目配置绕过工作流定义中不可省略的必需/阻断文档**。
## 方案复核发现的补充风险
1. **必需文档可被绕过**:若简单采用“全空即 `required=false`”,创建者可把定义中 `required/blocking` 且不可关闭的文档职责清空,从而绕过正式工作流门禁。全空只应允许用于工作流定义允许创建者裁剪的非必需文档;必需/阻断文档仍必须三职全满。
2. **零治理工作流**:原方案允许“全部启用文档全空后激活”。这超出“部分文档不设置”的需求,并会产生没有任何审核责任人的 active 工作流。保存草稿可以暂时全空,但激活时必须至少有一份三职完整的受治理文档。
3. **成员有效性未由后端保证**:现有 `validateDuties` 只检查 ID 为正且互异;`document_duty_assignments.user_id` 也只外键到 `users`,没有保证用户属于该项目且仍在任。保存和激活前都必须按服务端成员快照复核。
4. **权限语义缺失**:当前 active 实例中,创建者可操作无职责文档;其他成员的阶段范围会因没有职责而排除该文档。最终方案必须明确:无人工审批文档对有项目访问权的成员可只读可见,创建者可触发生成/编辑,review/approve 始终不可用。
5. **冻结快照可能残留旧 ID**:关闭文档任务或切换为“无需人工审批”时,如果不清空旧职责 ID,冻结 JSON、plan hash 和预览统计仍会携带过期职责。保存前必须服务端规范化,前端也应原子清空三职。
## 严重度
`medium`(既有冻结规则正确,但页面误导用户继续编辑;职责可选属于治理能力扩展,涉及门禁、权限与激活完整性)
## 关联整改
- Remediation: [2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md](../remediation/2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md)
- Short-term: [../ops/short-term/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md](../ops/short-term/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md)
## 证据
```bash
# dev DB 实测(2026-09-14)
docker exec shuimu-context-pg-dev psql -U app -d agent_system_dev \
-c "SELECT id,name,lifecycle_status,active_workflow_key,workflow_selection_version,workflow_plan_revision FROM projects WHERE id=143;"
docker exec shuimu-context-pg-dev psql -U app -d agent_system_dev \
-c "SELECT id,project_id,status,config_revision FROM project_workflow_instances WHERE project_id=143 ORDER BY id;"
# → lifecycle_status=active / active_workflow_key=main / 实例 89 status=active
# test/main 环境项目 143 不存在(0 rows),现场仅 dev
```
代码引用:
- `internal/projectinstance/service.go:123-180`(SaveWorkflowPlan:冻结/live/选版/乐观锁顺序)
- `internal/projectinstance/store.go:123-134`(BumpPlanRevision 乐观锁)
- `internal/server/project_settings_handlers.go:160-204`(错误码 → HTTP 状态映射)
- `internal/projectinstance/validator.go:9-126,143-179`(validatePlan / validateActivationPlan / validateDuties)
- `internal/projectinstance/gate.go:5-54`(阶段门禁)
- `web/src/components/project/ProjectSettingsModal.tsx:53-81,120-166`(loadSettings / handleSavePlan)
- `web/src/api/projectSettings.ts:45-65,200-213`(saveWorkflowPlan / parseError)
## 审核结论
- 409 根因成立;项目 143 的职责内容合法与否不会改变冻结判定。
- “部分指派”继续明确拒绝;顶层响应为 HTTP 400 `VALIDATION_FAILED`,具体 issue code 为 `DUTY_PARTIAL_ASSIGNMENT`。
- 无职责文档定义为“启用但不纳入人工三权审批”,仍保留生成、正文、版本账本和项目内只读可见性;禁止使用“非受控文档”描述。
- 全空只允许在非必需且允许项目侧裁剪的文档任务上使用;必需/阻断任务仍须三职完整。激活时至少存在一份三职完整文档。
- 项目 143 仅做冻结态只读回归;不得在验收中终止其工作流。若业务上确需改职责,必须先查看终止影响、确认取消运行任务及关闭实例的访问影响,再受控终止并重新规划、激活。
+158 -38
View File
@@ -1,31 +1,151 @@
# 项目全面审计 - 文档索引
> **HISTORICAL(2026-09-12 初审快照)**
> **当前发布/缺口 SSOT** → [../remediation/gap-matrix.md](../remediation/gap-matrix.md)
> **协作焦点** → [../ops/CURRENT.md](../ops/CURRENT.md)
> **HISTORICAL(2026-09-12 初审快照)**
> **当前发布/缺口 SSOT** → [../remediation/gap-matrix.md](../remediation/gap-matrix.md)
> **协作焦点** → [../ops/CURRENT.md](../ops/CURRENT.md)
> **Agent 工作方式** → [AGENTS.md](../../AGENTS.md) · [PROJECT.md](../../PROJECT.md)
**审计日期**: 2026-09-12
**项目**: Chat-Agent-System
**审计日期**: 2026-09-12
**项目**: Chat-Agent-System
**审计状态**: 历史索引(下方 5.7/10 为初审结论,勿作 live status)
---
## 核心文档(按阅读顺序推荐)
### 模块边界 arch-check Wave 0 基线(2026-09-14)
**文件**: [2026-09-14-arch-check-baseline.md](./2026-09-14-arch-check-baseline.md)
**结论**: import 相对现状 allowlist 无新边;表/路径目标属主扫描 21 条 warn,作为 Wave 1+ 收口清单,不在本轮转 block。
### 项目 143 workflow-plan 409 与三权全有或全无(2026-09-14)
**文件**: [2026-09-14-workflow-plan-409-frozen-and-optional-duties.md](./2026-09-14-workflow-plan-409-frozen-and-optional-duties.md)
**结论**: 项目 143 已于 2026-09-13 激活 main 工作流(实例 89),`SaveWorkflowPlan` 因 `lifecycle=active` 返回 409 `PLAN_FROZEN`;前端无冻结守卫、错误提示在视口外,表现为「校验并预览无反应」。按文档支持三权全有或全无,但全空仅用于定义允许裁剪的非必需文档,表示“不纳入人工审批”而非“非受控”;必需文档和零治理激活不得被绕过。
**整改**: [workflow-plan 409 + 三权全有或全无整改](../remediation/2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md)
### 项目 143 受控正文 canonical hash 漂移(2026-09-14)
**文件**: [2026-09-14-project143-controlled-content-404.md](./2026-09-14-project143-controlled-content-404.md)
**结论**: 正文文件存在;revision bootstrap 去掉 5 行具有 Markdown 硬换行语义的双空格并把 canonical SHA 写入账本/DocGov,却未同步文件,正文读取将哈希冲突误报为 404;5 秒 lease no-op 更新又周期性重复 hydration。原文件必须保全,不能用旧 canonical blob 覆盖。
**整改**: [canonical hash 漂移整改计划](../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md)
### 文档版本账本运行时失效(2026-09-13)
**文件**: [2026-09-13-document-revision-runtime-404.md](./2026-09-13-document-revision-runtime-404.md)
**结论**: 原现场 404(账本仅内存、GET 无 bootstrap、freeform 跳过 PATCH、overlay 空壳、静态假 JSON)已在工程侧修复;**Round20 真实 UI PASS**(项目 6159,V3/r2)。change report 仍为 fallback,不冒充 PI 叙事。
**整改**: [运行时整改方案](../remediation/2026-09-13-document-revision-runtime-remediation.md) · [short-term](../archive/ops/2026-09-13-document-revision-runtime.md) · [Round20 报告](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
### 文档修改与智能体版本专项分析(2026-09-13)
**文件**: [2026-09-13-document-revision-management-gap-analysis.md](./2026-09-13-document-revision-management-gap-analysis.md)
**结论**: 现有受控文档只有当前工作区正文和哈希,缺少不可变快照、智能体版本边界、人工修订差异、实际变更报告和负责人通知;前端块编辑尚未持久化。
**设计/整改**: [系统设计](../system-design/document-revision-management.md) · [实施方案](../remediation/2026-09-13-document-revision-management-implementation-plan.md)
### 最新专项审计(2026-09-13)
**文件**: [2026-09-13-document-revision-pg-id-remap.md](./2026-09-13-document-revision-pg-id-remap.md)
**结论**: 项目 6158 首次生成 PG 已写入 baseline snapshot=249、candidate id=175、output snapshot id=250、report id=175,但内存计数器未同步,临时 ID 覆盖并删除 baseline,commit `not found`。工程修复已合入;Round20 项目 6159 首次生成 UI-03 PASS。
**整改**: [short-term](../archive/ops/2026-09-13-document-revision-pg-id-remap.md) · [Round20 报告](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
**文件**: [2026-09-13-document-revision-post-restart-final-snippet.md](./2026-09-13-document-revision-post-restart-final-snippet.md)
**结论**: 第二次 post-restart 已恢复 V3/r2 与正文;当时失败只因 phase-state 仍断言 UI-06 marker。Round20 `bodySnippet=A1-win-mu0gwiez`,post-restart PASS。
**整改**: [short-term](../archive/ops/2026-09-13-document-revision-post-restart-final-snippet.md) · [Round20 报告](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md)
**文件**: [2026-09-13-document-revision-post-restart-selector.md](./2026-09-13-document-revision-post-restart-selector.md)
**结论**: 第18轮 main 18 PASS;post-restart 在项目已恢复时,页面级项目名同时命中顶栏与侧栏,strict violation,未到 revision-state。
**整改**: [short-term](../archive/ops/2026-09-13-document-revision-post-restart-selector.md)
**文件**: [2026-09-13-document-revision-reviewer-duty-sync.md](./2026-09-13-document-revision-reviewer-duty-sync.md)
**结论**: 第17轮 UI-00–12 PASS;精确职责断言暴露真实缺陷——UI-01 已把 B 设为 reviewer,`doc_proj6145_*` 的 `reviewer_id` 却是硬编码 `2`,矩阵为 viewer。
**整改**: [项目 reviewer 同步整改](../remediation/2026-09-13-document-revision-reviewer-duty-sync.md)
### UI-13a 职责单元格误判(2026-09-13)
**文件**: [2026-09-13-document-revision-duty-cell-assertion.md](./2026-09-13-document-revision-duty-cell-assertion.md)
**结论**: 第16轮 UI-13a 已打开 reviewer B 权限矩阵;整行 `innerText` 含全部 select option,误命中「编制负责人」。须读 select value / badge role。
**整改**: [职责单元格精确断言整改](../remediation/2026-09-13-document-revision-duty-cell-assertion.md)
### 受控文档分类导航(2026-09-13)
**文件**: [2026-09-13-document-revision-workflow-category-navigation.md](./2026-09-13-document-revision-workflow-category-navigation.md)
**结论**: 第15轮 UI-00–12 PASS;UI-13a 在私密分类下直接展开文档菜单,找不到 `doc_proj*_intake`。须先用页面控件切到流程受控。
**整改**: [受控文档分类导航整改](../remediation/2026-09-13-document-revision-workflow-category-navigation.md)
### UI-11 快速完成观测(2026-09-13)
**文件**: [2026-09-13-document-revision-fast-completion-observation.md](./2026-09-13-document-revision-fast-completion-observation.md)
**结论**: 第14轮 UI-11 上传归档后助手已 `completed`;验收默认硬等 inflight 60s,把成功终态误判为失败。
**整改**: [快速完成观测契约整改](../remediation/2026-09-13-document-revision-fast-completion-observation.md)
### 质量修复子工作区契约(2026-09-13)
**文件**: [2026-09-13-document-revision-quality-repair-workspace-contract.md](./2026-09-13-document-revision-quality-repair-workspace-contract.md)
**结论**: 第13轮 UI-03 质量门禁正确判缺「阻塞信息/非阻塞信息」;repair TASK 引导 `../../output.md`,模型越界改根文件,本地目标缺失,manifest 停在 70。
**整改**: [质量修复子工作区契约整改](../remediation/2026-09-13-document-revision-quality-repair-workspace-contract.md)
### 编辑弹窗 hydration 竞态(2026-09-13)
**文件**: [2026-09-13-document-revision-editor-hydration-race.md](./2026-09-13-document-revision-editor-hydration-race.md)
**结论**: 第十二轮 UI-06 在 fill 窗口完成后台 hydration,块 ID 被重建;保存按旧 ID 找不到目标后静默关窗,未发 PATCH,修订停在 r0。
**整改**: [编辑弹窗 hydration 竞态整改](../remediation/2026-09-13-document-revision-editor-hydration-race.md)
### 对话意图运行时审计(2026-09-13)
**文件**: [2026-09-13-conversation-intent-runtime-state.md](./2026-09-13-conversation-intent-runtime-state.md)
**结论**: 真实会话被诊断探针污染;客户端名词匹配令只读总结请求误启动写任务;错误动作与文档租约状态刷新后无法恢复。
**整改**: [对话意图、可恢复任务状态与文档占用可见性整改](../remediation/2026-09-13-conversation-intent-runtime-state-remediation.md)
### 刷新历史专项审计(2026-09-13)
**文件**: [2026-09-13-chat-history-refresh-disappears.md](./2026-09-13-chat-history-refresh-disappears.md)
**结论**: 消息仍在数据库;文档任务与激活前消息缺阶段作用域,被刷新后的窗口过滤器剔除,而统计仍返回未过滤数量。
**整改**: [对话刷新恢复与阶段授权一致性整改方案](../remediation/2026-09-13-chat-history-refresh-remediation.md)
### 0️⃣ 当前状态(Live SSOT)
**文件**: [gap-matrix.md](../remediation/gap-matrix.md)
**协作**: [CURRENT.md](../ops/CURRENT.md) · [AGENTS.md](../../AGENTS.md) · [PROJECT.md](../../PROJECT.md)
**用途**: 发布缺口、Codex 再审计闭环证据、发布门禁勾选
**文件**: [gap-matrix.md](../remediation/gap-matrix.md)
**协作**: [CURRENT.md](../ops/CURRENT.md) · [AGENTS.md](../../AGENTS.md) · [PROJECT.md](../../PROJECT.md)
**用途**: 发布缺口、Codex 再审计闭环证据、发布门禁勾选
---
### 1️⃣ 从这里开始:审计总结报告(历史)
**文件**: `2026-09-12-audit-summary-report.md`
**用途**: 项目整体现状、关键数字、风险评估
**适合**: 项目经理、技术负责人、快速概览
**阅读时间**: 15-20 分钟
**文件**: `2026-09-12-audit-summary-report.md`
**用途**: 项目整体现状、关键数字、风险评估
**适合**: 项目经理、技术负责人、快速概览
**阅读时间**: 15-20 分钟
**关键内容**:
- 项目评分及各维度打分
@@ -38,10 +158,10 @@
---
### 2️⃣ 详细缺陷与整改:综合整改方案
**文件**: `2026-09-12-comprehensive-audit-and-remediation-plan.md`
**用途**: 12 个缺陷的详细分析 + 3 个新功能的整改方案
**适合**: 架构师、资深开发工程师
**阅读时间**: 45-60 分钟
**文件**: `2026-09-12-comprehensive-audit-and-remediation-plan.md`
**用途**: 12 个缺陷的详细分析 + 3 个新功能的整改方案
**适合**: 架构师、资深开发工程师
**阅读时间**: 45-60 分钟
**关键内容**:
- BUG-01 到 BUG-12 的代码现场与后果分析
@@ -53,10 +173,10 @@
---
### 3️⃣ 可执行的任务拆分:任务清单与验收
**文件**: `2026-09-12-remediation-tasks-and-acceptance-checklist.md`
**用途**: 具体的代码修改指引、单元测试框架、验收标准
**适合**: 开发工程师、QA、代码审查人
**阅读时间**: 60-90 分钟
**文件**: `2026-09-12-remediation-tasks-and-acceptance-checklist.md`
**用途**: 具体的代码修改指引、单元测试框架、验收标准
**适合**: 开发工程师、QA、代码审查人
**阅读时间**: 60-90 分钟
**关键内容**:
- Task A1-A6:关键缺陷修复(15h)
@@ -72,10 +192,10 @@
---
### 4️⃣ 快速参考与速查:快速指南
**文件**: `2026-09-12-quick-reference-guide.md`
**用途**: 问题症状→原因→解决方案的快速诊断
**适合**: 所有开发人员、值班人员
**阅读时间**: 5-10 分钟(按需查阅)
**文件**: `2026-09-12-quick-reference-guide.md`
**用途**: 问题症状→原因→解决方案的快速诊断
**适合**: 所有开发人员、值班人员
**阅读时间**: 5-10 分钟(按需查阅)
**关键内容**:
- 10 个常见症状的诊断矩阵
@@ -92,9 +212,9 @@
## 配套参考文档
### 业务需求原文
**文件**: `2026-09-12-three-workflows-strict-governance-remediation.md`
**用途**: 业务决策、验收标准的原始出处
**适合**: 产品、架构、QA(需要理解业务背景)
**文件**: `2026-09-12-three-workflows-strict-governance-remediation.md`
**用途**: 业务决策、验收标准的原始出处
**适合**: 产品、架构、QA(需要理解业务背景)
**关键章节**:
- 第 3 章:不可违反的业务规则
@@ -231,32 +351,32 @@ Day 4-5: Phase C 完善与发布准备(20h)
## 常见路径快查
**"完成工作流后项目仍然是 active"**
→ quick-reference-guide.md 第二部分 症状 1
→ comprehensive-audit 第二部分 BUG-01
→ quick-reference-guide.md 第二部分 症状 1
→ comprehensive-audit 第二部分 BUG-01
→ remediation-tasks 的 Task A1
**"对话推进不起作用"**
→ quick-reference-guide.md 第二部分 症状 3
→ comprehensive-audit 第二部分 BUG-04
→ quick-reference-guide.md 第二部分 症状 3
→ comprehensive-audit 第二部分 BUG-04
→ remediation-tasks 的 Task A4
**"禁用文档仍能被打开"**
→ quick-reference-guide.md 第二部分 症状 2
→ comprehensive-audit 第二部分 BUG-05
→ quick-reference-guide.md 第二部分 症状 2
→ comprehensive-audit 第二部分 BUG-05
→ remediation-tasks 的 Task A5
**"激活 token 可能被重复使用"**
→ quick-reference-guide.md 第二部分 症状 6
→ comprehensive-audit 第二部分 BUG-06
→ quick-reference-guide.md 第二部分 症状 6
→ comprehensive-audit 第二部分 BUG-06
→ remediation-tasks 的 Task A6
**"无法运行测试流程"**
→ quick-reference-guide.md 第二部分 症状 7
→ comprehensive-audit 第三部分 MISSING-06
→ quick-reference-guide.md 第二部分 症状 7
→ comprehensive-audit 第三部分 MISSING-06
→ remediation-tasks 的 Phase B 开始
**"需要完整 E2E 验证"**
→ comprehensive-audit 第三部分 MISSING-04
→ comprehensive-audit 第三部分 MISSING-04
→ remediation-tasks 的 Task B2
---
+76 -10
View File
@@ -1,27 +1,66 @@
# 当前焦点
**更新**: 2026-09-13
**production_ready**: no(对话刷新恢复、CI 真实 PI E2E、前端人工抽检待完成)
**更新**: 2026-09-14
**production_ready**: no(`CHAT-INTENT-STATE` 等无关 blocker 仍开放。文档账本运行时 UI Round20 **PASS**,不把 fallback change report 写成完整 PI,也不把本轮写成全仓可发布)
## 焦点
1. **CHAT**: [刷新恢复整改待实施](short-term/2026-09-13-chat-history-refresh-remediation.md)(发布 blocker)
2. **CI**: `TEST_DATABASE_URL` + 真实 PI E2E 实录
3. **前端**: 版本冲突刷新、终止 preview 人工抽检
1. **WORKFLOW-PLAN**: [冻结 409 与文档职责可选治理](../audit/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md)(Wave 1–4 已在 `fix/workflow-plan-409-frozen-and-optional-duties` 落地;Wave 5 占槽 e2e 进行中;后续治理原则见 [MVP 治理规则评审](../ops/research/2026-09-14-mvp-governance-rules-review.md))
2. **CHAT-INTENT**: [对话意图运行时状态](../audit/2026-09-13-conversation-intent-runtime-state.md)(`fix/conversation-intent-state`;与文档账本运行时无关)
3. **CHAT**: [对话历史刷新](../audit/2026-09-13-chat-history-refresh-disappears.md)(认领仍 `in_progress`;gap 行已 PASS,以代码/handoff 为准收敛)
## 并行认领
| owner | task | branch | worktree | mutex | status |
|-------|------|--------|----------|-------|--------|
| — | — | — | — | — | — |
| verifier_antigravity | controlled-content-ui-acceptance | fix/controlled-content-ui-acceptance | .worktrees/fix-controlled-content-ui-acceptance | document-content-ui-acceptance | done |
| implementer_cursor | controlled-content-canonical-hash | fix/controlled-content-canonical-hash | .worktrees/fix-controlled-content-canonical-hash | docgov | done |
| Codex | project143-controlled-content-404-diagnosis | fix/project143-controlled-content-404-diagnosis | - | docgov-content-diagnosis | done |
| Codex | software-project-bootstrap-plan | feature/software-project-bootstrap-plan | - | workflow-design | done |
| Cursor | chat-history-refresh-remediation | fix/chat-history-refresh | - | chat | in_progress |
| Codex | conversation-intent-runtime-state | fix/conversation-intent-state | .worktrees/fix-conversation-intent-state | intent | in_progress |
| Cursor | document-revision-wave1-6-implementation | feature/document-revision-management | - | docgov | done |
| Cursor-Auto | document-revision-runtime-ui03 | fix/document-revision-runtime-ui03 | - | docgov | done |
| Cursor-Auto | document-revision-sse-idempotency | fix/document-revision-sse-idempotency | - | docgov | done |
| Cursor-Auto | document-revision-active-doc-routing | fix/document-revision-active-doc-routing | - | docgov | done |
| Cursor-Auto | document-revision-quality-context | fix/document-revision-quality-context | - | docgov | done |
| Cursor-Auto | document-revision-e2e-pending-flow | fix/document-revision-e2e-pending-flow | - | pending-report-ui | done |
| Cursor-Auto | document-revision-e2e-reject-routing | fix/document-revision-e2e-reject-routing | - | document-revision-runtime-ui | done |
| Cursor-Auto | document-revision-e2e-block-selector | fix/document-revision-e2e-block-selector | - | document-revision-block-selector | done |
| Cursor-Auto | document-revision-e2e-save-selector | fix/document-revision-e2e-save-selector | - | document-revision-save-selector | done |
| Cursor-Auto | document-revision-e2e-overlay-selector | fix/document-revision-e2e-overlay-selector | - | document-revision-overlay-selector | done |
| Cursor-Auto | document-revision-e2e-overlay-transition | fix/document-revision-e2e-overlay-transition | - | document-revision-overlay-transition | done |
| Cursor-Auto | document-revision-second-doc-routing-lease | fix/document-revision-second-doc-routing-lease | - | document-revision-second-doc-routing-lease | done |
| Cursor-Auto | document-revision-prelim-output | fix/document-revision-pi-runner-module | - | document-revision-prelim-output | done |
| Cursor-Auto | document-revision-editor-hydration-race | fix/document-revision-editor-hydration-race | - | document-revision-editor-hydration-race | done |
| Cursor-Auto | document-revision-quality-repair-workspace-contract | fix/document-revision-quality-repair-workspace-contract | - | document-revision-quality-repair-workspace-contract | done |
| Cursor-Auto | document-revision-fast-completion-observation | fix/document-revision-fast-completion-observation | - | document-revision-fast-completion-observation | done |
| Cursor-Auto | document-revision-workflow-category-navigation | fix/document-revision-workflow-category-navigation | - | document-revision-workflow-category-navigation | done |
| Cursor-Auto | document-revision-duty-cell-assertion | fix/document-revision-duty-cell-assertion | - | document-revision-duty-cell-assertion | done |
| Cursor-Auto | document-revision-reviewer-duty-sync | fix/document-revision-reviewer-duty-sync | - | document-revision-reviewer-duty-sync | done |
| Cursor-Auto | document-revision-post-restart-selector | fix/document-revision-post-restart-selector | - | document-revision-post-restart-selector | done |
| Cursor-Auto | document-revision-post-restart-final-snippet | fix/document-revision-post-restart-final-snippet | - | document-revision-post-restart-final-snippet | done |
| Cursor-Auto | document-revision-pg-id-remap | fix/document-revision-pg-id-remap | - | document-revision | done |
| Cursor-Auto | document-revision-runtime | fix/document-revision-runtime-ui03 | - | docgov | done |
| Cursor-Auto | document-revision-runtime-ui-final-report | feature/document-revision-runtime-ui-final-report | - | document-revision-runtime-ui | done |
| Cursor-Auto | document-revision-evidence-count | fix/document-revision-evidence-count | - | document-revision-evidence-count | done |
| Cursor-Auto | document-revision-session-close | feature/document-revision-session-close | - | document-revision-session-close | done |
| Cursor-Auto | vite-frp-allowed-hosts | fix/vite-frp-allowed-hosts | - | web-devserver | done |
| Cursor-Auto | remove-herdr-agent-settings | feature/remove-herdr-agent-settings | - | agent-collab-docs | done |
| implementer_cursor | workflow-plan-409-frozen-and-optional-duties | fix/workflow-plan-409-frozen-and-optional-duties | .worktrees/fix-workflow-plan-409-frozen-and-optional-duties | workflow | in_progress |
| Cline | governance-action-level-authz | fix/governance-action-level-authz | - | workflow | blocked |
| Cursor | module-decoupling-wave0 | feature/remove-herdr-agent-settings | - | arch | done |
> 新任务开始前登记。`branch` 必须为 `feature/<slug>` 或 `fix/<slug>`,**禁止** `dev` / `test` / `main`。同一 `mutex` 同时仅一个 `in_progress`。
> `workflow-plan-409-frozen-and-optional-duties` 已由 implementer_cursor 接管:worktree 已创建,Wave 1–4 提交落地,Wave 5 占集成槽位(e2e)进行中。
> `governance-action-level-authz` blocked 仅为等待同 mutex `workflow` 的 Wave 5 收敛;收敛后从最新 `dev` 创建 `fix/governance-action-level-authz` 并改 `in_progress`,不得在当前 `feature/remove-herdr-agent-settings` 工作区编码。
## 集成槽位
| holder | phase | since | scope | queue |
|--------|-------|-------|-------|-------|
| idle | - | - | - | - |
| implementer_cursor | e2e | 2026-09-14 | workflow-plan 409 frozen + optional duties | governance-action-level-authz |
**phase**: `idle` | `merging` | `smoke` | `e2e`
@@ -31,9 +70,9 @@
| 环境 | 端口 | schema | 状态 |
|------|------|--------|------|
| dev | 8080 | 25 | healthy |
| test | 8081 | 25 | healthy |
| main | 8000 | 25 | healthy(app + runner + DB) |
| dev | 8080 | **32** | healthy(产品代码部署为 `36e4bc3`;真实 UI 主链+restart PASS) |
| test | 8081 | 25→27* | healthy |
| main | 8000 | 25→27* | healthy(app + runner + DB) |
## SSOT
@@ -44,3 +83,30 @@
| 发布缺口 | [gap-matrix](../remediation/gap-matrix.md) |
| 测试报告 | [test-reports/](../test-reports/) |
| Agent 手册 | [AGENTS.md](../../AGENTS.md) |
| 受控正文 hash 漂移 W1–W6 | [../ops/handoffs/2026-09-14-controlled-content-canonical-hash.md](../ops/handoffs/2026-09-14-controlled-content-canonical-hash.md) |
| DOCREV ADR | [../adr/2026-09-13-document-version-boundary.md](../adr/2026-09-13-document-version-boundary.md) |
| DOCREV 管理测试 | [../test-reports/2026-09-13-document-revision-management-test-report.md](../test-reports/2026-09-13-document-revision-management-test-report.md) |
| DOCREV 运行时 UI Round20 | [../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md) |
| 纯软件项目自举设计 | [../system-design/2026-09-14-software-project-bootstrap-workflow.md](../system-design/2026-09-14-software-project-bootstrap-workflow.md) |
| SSE/幂等审计 | [../audit/2026-09-13-document-revision-sse-idempotency.md](../audit/2026-09-13-document-revision-sse-idempotency.md) |
| 质量门禁自污染审计 | [../audit/2026-09-13-document-revision-quality-gate-self-pollution.md](../audit/2026-09-13-document-revision-quality-gate-self-pollution.md) |
| 当前文档路由审计 | [../audit/2026-09-13-document-revision-active-doc-routing.md](../audit/2026-09-13-document-revision-active-doc-routing.md) |
| 行动表状态假阳性审计 | [../audit/2026-09-13-document-revision-quality-status-false-positive.md](../audit/2026-09-13-document-revision-quality-status-false-positive.md) |
| 待确认报告选择失败审计 | [../audit/2026-09-13-document-revision-pending-report-selection.md](../audit/2026-09-13-document-revision-pending-report-selection.md) |
| UI-05b 拒绝路由失败审计 | [../audit/2026-09-13-document-revision-e2e-reject-routing.md](../audit/2026-09-13-document-revision-e2e-reject-routing.md) |
| 职责伪造与 ETag 覆盖审计 | [../audit/2026-09-13-document-revision-duty-etag-overwrite.md](../audit/2026-09-13-document-revision-duty-etag-overwrite.md) |
| UI-06 块选择器失败审计 | [../audit/2026-09-13-document-revision-block-selector.md](../audit/2026-09-13-document-revision-block-selector.md) |
| UI-06 保存选择器失败审计 | [../audit/2026-09-13-document-revision-save-selector.md](../audit/2026-09-13-document-revision-save-selector.md) |
| UI-07 纯净阅读取样失败审计 | [../audit/2026-09-13-document-revision-overlay-selector.md](../audit/2026-09-13-document-revision-overlay-selector.md) |
| UI-07 transition 中间帧取样审计 | [../audit/2026-09-13-document-revision-overlay-transition.md](../audit/2026-09-13-document-revision-overlay-transition.md) |
| UI-11 第二份文档路由与 lease 审计 | [../audit/2026-09-13-document-revision-second-doc-routing-lease.md](../audit/2026-09-13-document-revision-second-doc-routing-lease.md) |
| UI-11 prelim_design 缺 output.md 审计 | [../audit/2026-09-13-document-revision-prelim-output.md](../audit/2026-09-13-document-revision-prelim-output.md) |
| UI-06 编辑弹窗 hydration 竞态审计 | [../audit/2026-09-13-document-revision-editor-hydration-race.md](../audit/2026-09-13-document-revision-editor-hydration-race.md) |
| UI-03 质量修复子工作区契约审计 | [../audit/2026-09-13-document-revision-quality-repair-workspace-contract.md](../audit/2026-09-13-document-revision-quality-repair-workspace-contract.md) |
| UI-11 快速完成观测误判审计 | [../audit/2026-09-13-document-revision-fast-completion-observation.md](../audit/2026-09-13-document-revision-fast-completion-observation.md) |
| UI-13a 私密分类导航失败审计 | [../audit/2026-09-13-document-revision-workflow-category-navigation.md](../audit/2026-09-13-document-revision-workflow-category-navigation.md) |
| UI-13a 职责单元格误判审计 | [../audit/2026-09-13-document-revision-duty-cell-assertion.md](../audit/2026-09-13-document-revision-duty-cell-assertion.md) |
| UI-13a reviewer 职责未同步审计 | [../audit/2026-09-13-document-revision-reviewer-duty-sync.md](../audit/2026-09-13-document-revision-reviewer-duty-sync.md) |
| UI-03 首次生成 PG ID 误删 baseline | [../audit/2026-09-13-document-revision-pg-id-remap.md](../audit/2026-09-13-document-revision-pg-id-remap.md) |
| UI-06 刷新后缓存竞争死锁审计 | [../audit/2026-09-14-document-revision-refresh-cache-race.md](../audit/2026-09-14-document-revision-refresh-cache-race.md) |
| 受控正文真实 UI 验收报告 | [../test-reports/2026-09-14-controlled-content-ui-acceptance.md](../test-reports/2026-09-14-controlled-content-ui-acceptance.md) |
@@ -0,0 +1,45 @@
---
title: "对话刷新恢复整改 Checklist"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
related_task: "../short-term/2026-09-13-chat-history-refresh-remediation.md"
---
# 对话刷新恢复整改 Checklist
## Wave 0 — 锁定回归
- [x] `MessageVisible` / `ScopeFromMetadata` 单测 — 证据:`internal/projectinstance/message_scope_test.go`
- [x] PG 集成:激活前 + 任务 scope + 刷新窗口 — 证据:`internal/server/chat_history_refresh_pg_test.go`
- [x] 前端:空 messages 日桶不覆盖缓存 — 证据:`web/src/hooks/useChatWindow.ts`
## Wave 1 — 写入作用域
- [x] Goose `00026` 列迁移 — 证据:`deploy/postgres/goose/00026_2026-09-13-chat-message-scope.sql`
- [x] `ResolveMessageScopeForChat/Task` — 证据:`internal/projectinstance/message_scope.go`
- [x] 任务/聊天写入接线 — 证据:`task_run_handlers.go`, `session.go`, `ctxmgr/manager.go`
## Wave 2 — 授权同集
- [x] `authorizeSessionRead` + 可见性谓词 — 证据:`internal/server/chat_history_auth.go`
- [x] window/day/search/dates/categories/unread/digest 授权 — 证据:各 `*_api.go`
## Wave 3 — 历史回填
- [x] Goose `00027` backfill SQL — 证据:`deploy/postgres/goose/00027_2026-09-13-chat-message-scope-backfill.sql`
## Wave 4 — 前端恢复态
- [x] `useChatWindow` 阶段态 + 用户隔离缓存 — 证据:`web/src/hooks/useChatWindow.ts`, `web/src/data/storage.ts`
## Wave 5 — 验收
- [x] `go test -short ./...` — 证据:本机执行输出
- [ ] 真实 PI 刷新 E2E(需 dev 容器 + pi-agent)— 证据:待 test-report 补录
- [x] 测试报告归档 — 证据:`.doc/test-reports/2026-09-13-chat-history-refresh-test-report.md`
## 完成定义
- [ ] 全部勾选且有证据链接
- [ ] gap-matrix `CHAT-HISTORY-REFRESH` → PASS
@@ -0,0 +1,45 @@
# 受控文档正文修复真实 UI 验收 Checklist
## 执行身份与环境
- [x] 报告 Antigravity CLI / 实际模型。
- [x] 阅读 `AGENTS.md`、`PROJECT.md`、`.doc/README.md`、`.doc/ops/CURRENT.md`、任务文、审计与整改方案。
- [x] 使用 `mcr.microsoft.com/playwright:v1.63.0-noble`、`--network host`、`BASE_URL=http://127.0.0.1:3100`。
- [x] acceptance worktree 挂载 `/work`,主仓 `web/node_modules` 只读挂载到 `/work/web/node_modules`。
- [x] 管理员凭证只从 `shuimu-agent-app-dev` 容器环境安全传入,不输出、不截图、不提交。
## 强制边界
- [x] 用户、项目、成员、对话、文档、小队、编辑等数据只由 Playwright `page` 的真实 UI 操作产生。
- [x] 不用 `page.request`、`context.request`、curl、API 直调、DB 写、route/mock/stub、localStorage 注入。
- [x] 网络响应只用于监听和断言;PASS 必须同时有页面可见证据。
- [x] 不复用主仓旧 phase state/旧 PASS;失败原样记录。
- [x] 不从 worktree 重启共享 Docker;主阶段后输出 `NEEDS_HOST_RESTART`(若主阶段遇到 FAIL 阻塞,则先定位并等待修复,不提前重启)。
## A. 项目 143 回归(clean-run3 全部 PASS)
- [x] admin 从登录页登录,经 UI 打开项目标题“对话协同会话”(原项目143对应UI会话)。
- [x] 经 UI 打开 `doc_proj143_intake`(用户初始需求收集表),正文非空、账本就绪。
- [x] console/pageerror 无相关错误,content 与 revision-state 均无 404;初始 legacy doc-001 请求严格为 0。
- [x] 初次稳定后空闲 30 秒,无新增重复正文请求、无闪烁。
- [x] 双击真实块,追加唯一中文标记,保存后页面可见且修订号增加(r1 -> r2)。
- [x] 纯净阅读 / 人工修改 / 全部变更均验证 active 状态与真实装饰差异。
- [x] 刷新、退出、重新登录,再打开同一项目/文档,标记与修订号持久化。
- [x] 截图、trace、结果写 `.doc/test-reports/assets/2026-09-14-controlled-content-ui-acceptance/clean-run3/`。
## B. 新项目真实全链路(full-chain-final 全部 PASS)
- [x] 审读并运行 `web/e2e/document-revision-runtime.spec.ts` main phase;该测试只能通过 UI 建 A/B/C、新项目和全部数据。
- [x] 真实产品 PI/小队完成初次文档生成和二次修改;页面显示本轮用户输入与 assistant 终态回复。
- [x] 页面显示文档正文、版本账本、人工编辑、三模式(UI-06 刷新后通过,UI-07/08/09 三模式计算样式互斥通过)。
- [x] 页面打开真实 change report,并显示项目影响、文档影响、风险、开放问题。
- [x] 并发编辑、审核人、无关用户权限边界有 UI 证据(UI-12/13a/13b 均通过)。
- [x] 产生本轮非敏感 phase state、截图、results 并提交 Git;本地运行产生的 trace/video/HTML 报告未提交仓库;本地 secrets 继续 ignored 且绝不披露。
- [x] 主阶段写报告草稿并输出 `NEEDS_HOST_RESTART`,等待 orchestrator 重启。
## C. 重启后(由 orchestrator 重启并执行 post-restart 全部 PASS)
- [x] 仅用 UI 重新登录、打开本轮新项目与文档(UI-15 post-restart 2.8s 通过)。
- [x] 正文唯一标记(A1-win-mu0oymfg)、版本/修订(V3/r2)页面可见。
- [x] 目标受控文档 404 严格为 0。
- [x] 完成报告;如实记录全部结果,主阶段与重启后产物完好归档。
@@ -0,0 +1,207 @@
---
title: "纯软件项目自举工作流验收清单"
status: planned
created: 2026-09-14
updated: 2026-09-14
related_task: "ops/long-term/2026-09-14-software-project-bootstrap-implementation.md"
---
# 纯软件项目自举工作流验收清单
> 本文件是未来实施验收计划,当前全部用例均为 `NOT RUN`。不得把设计评审、stub、接口注入或静态 JSON 写成真实功能 PASS。
## 0. 验收分层
| 层 | 范围 | 可否代替真实 UI |
|----|------|-----------------|
| L1 | manifest、profile、模板、quality gate 单元测试 | 否 |
| L2 | PostgreSQL 迁移、领域服务、API、鉴权、并发 | 否 |
| L3 | 前端组件、类型、build | 否 |
| L4 | stub 小队和固定输出工程测试 | 否 |
| L5 | 真实 PI Agent Runner | 否,仍需页面验证 |
| L6 | Ubuntu Server 无头浏览器真实页面操作 | 是,最终验收 |
## 1. 工程门禁
### Manifest 与目录
- [ ] `software_bootstrap` 和 `software_delivery` 均可校验、发布和退役 — 证据:NOT RUN
- [ ] 非 published / 非 selectable / 不兼容 domain 的工作流不出现在项目目录 — 证据:NOT RUN
- [ ] 新版本不会改变已激活实例的 manifest/template/profile hash — 证据:NOT RUN
- [ ] 医疗现有三工作流及黄金用例无回归 — 证据:NOT RUN
- [ ] 不再依赖“三正式 key”或固定文档数量硬编码 — 证据:NOT RUN
### 数据与迁移
- [ ] 空数据库从 schema 1 升级并创建项目类型、profile、source binding — 证据:NOT RUN
- [ ] 旧数据库升级不误分类既有项目 — 证据:NOT RUN
- [ ] secret 只存引用,数据库、文档、日志和 prompt 无明文 — 证据:NOT RUN
- [ ] 项目、成员、planning instance、模板账本创建具备幂等事务语义 — 证据:NOT RUN
- [ ] 应用重启后项目、来源、plan、阶段和文档版本可恢复 — 证据:NOT RUN
### 授权与治理
- [ ] 非成员无法列出项目、对话、来源、文档、SSE、RAG 或 Agent 结果 — 证据:NOT RUN
- [ ] 非创建者无法激活、推进、选择下一流程或终止 — 证据:NOT RUN
- [ ] 客户端伪造 task/stage/duty/repo path 被服务端拒绝 — 证据:NOT RUN
- [ ] collaborative 模式三权必须不同人 — 证据:NOT RUN
- [ ] solo 只允许 creator acknowledgement 且页面显示“未独立评审” — 证据:NOT RUN
- [ ] controlled profile 禁止 solo — 证据:NOT RUN
- [ ] 激活后 workflow/template/profile/duty 不能直接修改 — 证据:NOT RUN
### 小队与文档
- [ ] 每个 executor/template/quality gate/profile 均注册且可解析 — 证据:NOT RUN
- [ ] 正式任务只能从冻结 doc_task_instance 启动 — 证据:NOT RUN
- [ ] 步骤预算、timeout、工作区边界和 manifest 生效 — 证据:NOT RUN
- [ ] 失败、跳过、fallback、未验证项不会被改写成 PASS — 证据:NOT RUN
- [ ] 非医疗默认小队不包含 regulatory — 证据:NOT RUN
- [ ] 纯软件模板和回复无医疗默认术语污染 — 证据:NOT RUN
## 2. Ubuntu Server 真实 UI 前置
- [ ] 占用 CURRENT 集成槽位 — 证据:NOT RUN
- [ ] `go vet ./...`、`go test -short ./...`、前端测试/build 通过 — 证据:NOT RUN
- [ ] PostgreSQL、app、真实 PI Runner、MiniMax 均 ready — 证据:NOT RUN
- [ ] 明确记录 commit、schema、镜像、模型、BASE_URL 和开始时间 — 证据:NOT RUN
- [ ] 使用官方 Playwright Chromium 容器;宿主无需安装浏览器 — 证据:NOT RUN
- [ ] 若容器不可用,才执行 `npx playwright install --with-deps chromium` — 证据:NOT RUN
- [ ] 禁止 `page.route`、mock/stub、直接写数据库或伪造 API 输出 — 证据:NOT RUN
推荐运行形态:
```bash
docker run --rm --network host --ipc host \
-e BASE_URL=http://127.0.0.1:3100 \
-v "$PWD:/work" -w /work \
mcr.microsoft.com/playwright:v1.63.0-noble \
npx playwright test <software-bootstrap-ui-spec>
```
## 3. 真实 UI 用例
### UI-SW-00 项目类型与向导
- **Input**:管理员登录;打开创建项目;选择 non-medical software。
- **Expected**:展示七步软件字段;不出现医疗器械固定标题、临床用途或 NMPA 默认值。
- **Evidence**:截图、trace、console/network 日志。
- **Status**:NOT RUN。
### UI-SW-01 既有项目单人创建
- **Input**:`existing_self_bootstrap + standard + solo + docs_only`;页面上传允许的仓库说明和文档。
- **Expected**:确认页显示 creator acknowledgement 和“未独立评审”;一次提交后项目、成员、plan 和模板可见;重复提交不创建第二项目。
- **Evidence**:截图、项目 ID、页面列表、trace。
- **Status**:NOT RUN。
### UI-SW-02 协作项目职责
- **Input**:创建 collaborative 项目并选择至少三名成员。
- **Expected**:逐文档分配 author/reviewer/approver;重复人员不能激活;修正后预览成功。
- **Evidence**:职责矩阵截图、错误提示、激活预览。
- **Status**:NOT RUN。
### UI-SW-03 激活冻结
- **Input**:保存 plan、查看预览、确认激活;随后尝试修改模板、profile 或职责。
- **Expected**:实例引用固定版本/hash;直接修改被拒绝;409 时展示差异且不自动重试。
- **Evidence**:预览、实例详情、拒绝提示。
- **Status**:NOT RUN。
### UI-SW-04 真实基线小队
- **Input**:在对话框输入“请基于我上传的项目资料,正式启动现状梳理并生成现状审计”。
- **Expected**:页面可见真实小队、角色、步骤、进度、真实助手回复;生成 `current_state_audit`,不是聊天长回答。
- **Evidence**:对话、步骤条、文档截图、trace/video。
- **Status**:NOT RUN。
### UI-SW-05 事实等级与证据
- **Input**:打开现状审计和架构基线。
- **Expected**:confirmed/inferred/unverified 可区分;high 问题有来源;找不到的信息明确写未验证。
- **Evidence**:文档截图、来源清单、版本账本。
- **Status**:NOT RUN。
### UI-SW-06 软件语义隔离
- **Input**:使用不含医疗内容的软件项目材料跑完整 bootstrap。
- **Expected**:项目、回复、模板和文档中不出现临床、注册、NMPA、GB 9706、CDMO 等默认语义。
- **Evidence**:页面全文搜索和截图;任何命中逐条说明来源。
- **Status**:NOT RUN。
### UI-SW-07 文档变更链
- **Input**:人工编辑一个块并保存;再通过真实对话要求小队更新同一文档。
- **Expected**:revision 增长、刷新保留;agent candidate 有 diff、风险、项目/文档影响和开放问题;确认/拒绝行为正确。
- **Evidence**:版本、revision、overlay、报告截图。
- **Status**:NOT RUN。
### UI-SW-08 阶段门禁与创建者确认
- **Input**:文档未批准时尝试推进;完成审核批准后等待通知;创建者确认推进。
- **Expected**:未批准时列出 blocker;就绪只通知一次;不自动推进;非创建者不可推进。
- **Evidence**:readiness 面板、通知、阶段前后截图。
- **Status**:NOT RUN。
### UI-SW-09 Bootstrap 就绪
- **Input**:完成所有启用阶段并打开 readiness。
- **Expected**:汇总风险、依赖和未验证项;存在 high blocker 时不可批准;通过后 workflow completed。
- **Evidence**:readiness 文档、阶段树、审计事件。
- **Status**:NOT RUN。
### UI-SW-10 下一工作流建议
- **Input**:bootstrap 完成。
- **Expected**:页面建议 `software_delivery`,但不自动创建或激活;仅创建者确认后生成新的 planning instance。
- **Evidence**:建议卡、确认前后实例列表。
- **Status**:NOT RUN。
### UI-SW-11 Delivery 迭代
- **Input**:建立 change brief 和 implementation plan,上传外部实现的 change manifest 与真实测试报告。
- **Expected**:trace 到 bootstrap requirements;失败/跳过测试阻断发布;用户确认后完成迭代。
- **Evidence**:文档血缘、测试报告、门禁、release notes。
- **Status**:NOT RUN。
### UI-SW-12 权限负例
- **Input**:非成员和 viewer 登录;篡改 URL 中 project/doc/run/source ID。
- **Expected**:服务端 403/404;页面无数据泄露;SSE 不先 flush 200。
- **Evidence**:页面错误、network、服务端审计。
- **Status**:NOT RUN。
### UI-SW-13 刷新与重启恢复
- **Input**:记录项目/实例/阶段/文档版本和正文;硬刷新、退出重登;仅 restart app 后再次登录。
- **Expected**:对话、任务、阶段、文档、职责、风险、V/r 和正文一致恢复。
- **Evidence**:pre/post state 文件和截图。
- **Status**:NOT RUN。
### UI-SW-14 Agent-System 自举黄金项目
- **Input**:用 Agent-System 当前仓库作为只读来源,真实执行 software_bootstrap。
- **Expected**:页面生成当前态审计、架构、需求/backlog、风险、路线图和测试策略;当前结论重新核验,不照抄历史审计;不修改仓库。
- **Evidence**:完整对话、全部文档、版本、trace/video、来源 hash。
- **Status**:NOT RUN。
## 4. 未来 controlled patch 负例
- [ ] repo 未绑定不能执行 — 证据:NOT RUN
- [ ] 非 allowlist 路径被拒绝 — 证据:NOT RUN
- [ ] `.env`、secret、生产 dump 排除有效 — 证据:NOT RUN
- [ ] 只在 feature worktree 写入 — 证据:NOT RUN
- [ ] 超出批准文件范围立即停止 — 证据:NOT RUN
- [ ] 测试失败不自动 merge — 证据:NOT RUN
- [ ] 批准执行不等于批准 merge/push/deploy — 证据:NOT RUN
- [ ] 保护分支直接 commit、force push、破坏性命令均被拒绝 — 证据:NOT RUN
## 5. 完成定义
- [ ] L1–L5 工程门禁分别记录真实结果
- [ ] UI-SW-00–14 全部由真实页面操作执行并留证
- [ ] 真实 PI 回复、小队进度和所有交付文档均可在 UI 看到
- [ ] 医疗与软件两套黄金项目均无回归
- [ ] 刷新、重登、重启、并发和权限负例通过
- [ ] test-report 逐项包含 Input/Expected/Actual/Verdict/Duration
- [ ] 任何 NOT RUN、fallback、失败和开放风险均如实保留
@@ -0,0 +1,70 @@
---
title: "对话刷新后正文消失整改实施交接"
created: 2026-09-13
from: codex
to: next-agent
status: open
---
# 交接:对话刷新后正文消失整改实施
## 目标(下一位 Agent 应完成什么)
按整改方案修复消息作用域、历史读取授权和统计同集问题,并完成历史回填与真实刷新 E2E。
## 已完成
- 源码链路与 dev PostgreSQL 只读定位完成,确认消息未删除。
- 确认 project 143/session `sess-p143-u9` 的 4 条消息均缺 `stage_key`,工作流激活后被窗口过滤器全部移除。
- 确认异步文档任务写入路径缺阶段/实例作用域;分类与日期统计未应用同一过滤。
- 审计、整改方案、发布 blocker 与 planned short-term 已建立。
- 现有相关 Go 测试和前端 192 项测试通过,但均未覆盖真实缺陷场景。
## 未完成
- 未修改业务代码、迁移或运行态数据。
- 未建立实施 checklist/test-report。
- 未运行真实 PI 刷新回归和双用户对象级授权负例。
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | yes |
| 集成槽位 holder | idle |
| branch | dev(诊断);建议实施用 `fix/chat-history-refresh` |
| worktree | 建议 `.worktrees/fix-chat-history-refresh` |
## 关键文件
| 路径 | 说明 |
|------|------|
| `.doc/audit/2026-09-13-chat-history-refresh-disappears.md` | 根因与运行态证据 |
| `.doc/remediation/2026-09-13-chat-history-refresh-remediation.md` | 分波次整改与验收 |
| `internal/server/task_run_handlers.go` | 文档任务消息缺阶段作用域 |
| `internal/server/stage_access_helpers.go` | 空阶段消息被丢弃 |
| `internal/server/chat_window_api.go` | 正文与统计授权口径分裂 |
| `web/src/hooks/useChatWindow.ts` | 刷新后服务端空桶覆盖本地窗口 |
## 如何验证
```bash
go test -short ./internal/server -run 'TestServer_ChatWindow' -count=1 -v
go test -short ./internal/ctxmgr -run 'TestChatWindow' -count=1 -v
cd web && npm test
```
实施时必须另加真实 PG 场景:激活前对话 → 激活 → `intake` 文档任务 → 刷新窗口,以及非 owner/无阶段职责负例。
## 风险 / Blocker
- 当前为发布 blocker;刷新会造成对话“数据丢失”假象。
- 不能用“空 `stage_key` 全部放行”或保留旧 localStorage 缓存作修复,否则会扩大阶段/跨用户泄露。
- 历史回填存在重复 `task_key` 歧义,必须先 dry-run 并按实例与时间唯一匹配。
## 相关链接
- CURRENT: [CURRENT.md](../CURRENT.md)
- Task: [chat-history-refresh-remediation](../short-term/2026-09-13-chat-history-refresh-remediation.md)
- Audit: [chat-history-refresh-disappears](../../audit/2026-09-13-chat-history-refresh-disappears.md)
- Remediation: [chat-history-refresh-remediation](../../remediation/2026-09-13-chat-history-refresh-remediation.md)
@@ -0,0 +1,142 @@
---
title: "受控正文 canonical hash 漂移 W1–W6 + 审查修补交接"
created: 2026-09-14
from: implementer_cursor
to: orchestrator_codex / W7 holder
status: done
---
# 交接:受控正文 canonical hash 漂移
## 目标(下一位 Agent 应完成什么)
占 CURRENT 集成槽后将 `fix/controlled-content-canonical-hash` `--no-ff` 合入 `dev`,`env-service.sh dev rebuild`,**先对项目 143 完成 live dry-run + apply**,再做 W8 真实 UI。合入后若未 repair 就打开页面,content API 会返回 `DOCUMENT_CONTENT_PROJECTION_DRIFT`,而不会静默展示裁掉硬换行的旧 head。
## 已完成
- W1–W6 工程实现与门禁
- 合入前审查修补:
- goose `00032` 允许 `migration_repair` source/change kind
- `migration_repair` 不递增 `head_revision_no` / `human_revision_count`;ETag 随新 snapshot ID 变化
- CLI 显式 live 模式 + `/app/data` → host data root 映射
- `MarkDocumentContentUpdated` 未预加载时从 DB 装入;aligned/retry 仍同步记录哈希
- 读路径对 legacy/fork 返回结构化冲突
- follow-up:apply 同时备份原文件与**旧 head 正文**(`head.md`)及 metadata;唯一目录 + O_EXCL;原子写 rename 后打开父目录 Sync(EINVAL/ENOTSUP/ENOSYS 忽略)
- 终审:`--live --environment dev` 必须同时识别 DSN `:5433` 与库名 `agent_system_dev`,且 `--host-data-root` 为 `data/dev`;空 dsnEnv/pathEnv 不放行;stored work_dir 必须在 `--stored-data-root` 下并映射,禁止沿用其他绝对路径
- 工程门禁(worktree):`go vet`、`go test -short`、`web npm test`、`web npm run build` PASS
- UI follow-up:`shouldLoadControlledContent` / `hydrateControlledDocumentContent` 与 `revisionToolbarMountMode` 的 server-backed 资格对齐;`doc-001` 等本地 legacy/mock 不再请求 content 与 revision-state。`doc_proj*` 仍 hydrate;已注册 `doc-free`/freeform 与 template preview 不走受控 content 请求
- UI 竞态 follow-up:`planControlledContentInvalidation` 统一失效。`list_sync` 不再清空 cache/ready(硬刷新后晚到列表不能把刚成功的 hydrate 打回 loading);`post_task` 清空活动文档时必须 bump `hydrateResumeKey`;编辑中保护草稿并 `requestHydrationResume`。`setDeliverables` updater 不再嵌套 setCache/setReady
## 未完成
- W7 合 `dev` + 容器 rebuild(本 worktree **禁止**)
- **隔离 `TEST_DATABASE_URL` 上实际跑 `TestReconcile_LegacyRepair_PG`**:本机未配置隔离库;5432/5433/5434/5435 为共享环境,已拒绝使用。这是 apply 可落地的工程 blocker,不是业务库可替代项
- 未在真实 `data/dev` / 共享库执行 apply
- W8 真实 UI(须在 143 repair 之后)
## 认领 / 槽位状态
| 项 | 值 |
|----|-----|
| mutex 已释放 | yes(`docgov` **done**;合入前再占) |
| 集成槽位 holder | idle |
| branch | `fix/controlled-content-canonical-hash` |
| worktree | `.worktrees/fix-controlled-content-canonical-hash` |
> 合 dev 必须另占集成槽位。W7 前请重新登记 `docgov`。
## 关键文件
| 路径 | 说明 |
|------|------|
| `deploy/postgres/goose/00032_2026-09-14-document-revision-migration-repair.sql` | 约束允许 `migration_repair` |
| `internal/fsutil/atomic.go` | rename 后打开父目录 Sync;O_EXCL;不支持的 dir sync 忽略 |
| `internal/docrevision/reconcile.go` | 唯一备份目录;回报 output/head/meta 三条路径 |
| `cmd/document-content-reconcile/safety.go` | live 正向确认 dev DSN 与 `data/dev` |
| `web/src/lib/controlledDocHydrate.ts` | 本地 legacy/mock 不 hydrate;与 toolbar 资格一致 |
| `web/src/lib/controlledContentInvalidation.ts` | 受控正文失效/重水合规划;list_sync 保 hydrate,post_task 必重拉 |
| `internal/docgov/engine.go` | Mark 预加载/幂等补偿 |
| `cmd/document-content-reconcile/` | 默认拒绝共享;live 硬门闩 + 路径映射 |
| `internal/server/project_doc_handlers.go` | drift 返回 `DOCUMENT_CONTENT_PROJECTION_DRIFT` |
## 如何验证
```bash
go vet ./...
go test -short ./...
go test ./internal/docrevision/ ./internal/docgov/ ./internal/server/ ./internal/db/ ./cmd/document-content-reconcile/ \
-run 'TestCanonicalize|TestClassify|TestReconcile|TestCommitMigrationRepair|TestMapStored|TestInspectProjection|TestMigration032|TestReadDocumentContent_Typed|TestWriteControlledContentError|TestServeLedgerHead|TestValidateCLI'
cd web && npm test && npm run build
# 重点:controlledDocHydrate 拒绝 doc-001 / template / registered freeform 发 content+revision
# 重点:controlledContentInvalidation 覆盖 hydrate→晚到sync、post_task 重水合、编辑/PATCH 防旧 GET
```
隔离 PG(禁止 5433/5434/5435 与 `agent_system_dev|test|main`):
```bash
TEST_DATABASE_URL='postgres://app:pass@127.0.0.1:55432/agent_itest?sslmode=disable' \
go test ./internal/docrevision/ -count=1 -run TestReconcile_LegacyRepair_PG
```
## 数据迁移命令的 dry-run / apply 安全边界
**默认拒绝** `:5433|:5434|:5435` 与 `data/dev|test|main`。
**隔离库**(无 `--live`)可 dry-run / apply,仍须 `--backup-dir`。
**真实 dev 单文档**必须同时具备:
- `--live`
- `--environment dev`
- 精确 `--doc-id`(禁止批量)
- apply 时 `--confirm REPAIR_SINGLE_DEV_DOC` 与 `--backup-dir`
宿主路径映射(DB 中 `work_dir=/app/data/...`):
```text
# dry-run(live,无 confirm)
go run ./cmd/document-content-reconcile \
--dsn "$DEV_DSN" \
--live --environment dev \
--doc-id doc_proj143_intake \
--stored-data-root /app/data \
--host-data-root "$REPO/data/dev" \
--report /tmp/proj143-reconcile-dry-run.json
# DSN 必须是 :5433 / agent_system_dev;host-data-root 必须就是 data/dev
# apply
go run ./cmd/document-content-reconcile \
--dsn "$DEV_DSN" \
--live --environment dev \
--doc-id doc_proj143_intake \
--confirm REPAIR_SINGLE_DEV_DOC \
--stored-data-root /app/data \
--host-data-root "$REPO/data/dev" \
--apply --backup-dir /safe/backup/proj143 \
--report /tmp/proj143-reconcile-apply.json
```
容器内可执行:在已 rebuild 的 `shuimu-agent-app-dev` 中运行同一 CLI。`/app/data` 已挂载时可不做 host 映射,但仍须 live 门闩与单 `--doc-id`。
Apply 只处理 `LEGACY_CANONICALIZATION_DRIFT`:备份 + `migration_repair`,不覆盖原文件,不只改 DB hash。
## 集成顺序(红线)
1. 合 `dev` + rebuild(schema 含 00032)
2. live dry-run 确认 class=`LEGACY_CANONICALIZATION_DRIFT`
3. live apply `doc_proj143_intake`
4. 然后才做 W8 页面验收
未 repair 前打开文档应看到结构化 drift 冲突,而不是裁掉双空格的旧 head。
## 风险 / Blocker
- **隔离 PG 未跑**:不能宣称真实 PG apply 已验证。W7 前用隔离库补跑 `TestReconcile_LegacyRepair_PG`
- 代码合入前,项目 143 现场仍失败(旧镜像 + 未 apply)
- apply 后仍须 W8 页面验收才能把 gap 标 PASS
## 相关链接
- CURRENT: [../CURRENT.md](../CURRENT.md)
- Task: [../short-term/2026-09-14-controlled-content-canonical-hash.md](../short-term/2026-09-14-controlled-content-canonical-hash.md)
- Remediation: [../../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md](../../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md)
@@ -0,0 +1,58 @@
---
title: "纯软件项目自举工作流实施"
status: planned
created: 2026-09-14
updated: 2026-09-14
---
# 纯软件项目自举工作流实施
## 动机
当前工作流引擎已经声明支持 `non_medical_software`,但创建入口、正式目录、阶段、模板、执行器和小队提示词仍以医疗器械为主。需要新增领域原生的软件项目工作流,使既有软件项目可以在系统中完成可信梳理、路线规划和后续迭代,并为安全的系统自举建立边界。
## 成功标准
- 用户可以在页面创建 greenfield/existing/legacy/self-bootstrap 软件项目;
- 项目创建、成员、planning instance 和模板账本由服务端幂等落库;
- `software_bootstrap` 可真实生成并批准项目基线、审计、需求、架构、风险、路线和验证策略;
- 完成后只建议、不会自动启动 `software_delivery`;
- delivery 可重复创建实例并承接每个迭代的计划、证据、测试和发布资料;
- 纯软件项目无医疗语义污染,医疗既有工作流无回归;
- 真实 PI 和 Ubuntu 无头浏览器黄金项目验收通过;
- 未实现受控代码执行前,系统不会直接修改项目仓库。
## 实施拆分
| Epic | 范围 | 依赖 | 验收 |
|------|------|------|------|
| SWBOOT-00 契约与 ADR | keys、profiles、领域边界、solo、错误码 | 无 | 设计评审 |
| SWBOOT-01 项目域模型 | project type/compliance/governance/source schema 与迁移 | 00 | 空库/旧库 PG |
| SWBOOT-02 工作流目录 | 适用性过滤、去三 key/固定 doc count 硬编码 | 01 | catalog/validator |
| SWBOOT-03 Bootstrap 定义 | manifest、模板、executor、quality gate | 02 | unit + stub |
| SWBOOT-04 Delivery 定义 | 可重复交付实例、血缘和交接 | 03 | instance lifecycle |
| SWBOOT-05 软件角色 profile | product/architecture/quality/security/operations | 03 | prompt golden |
| SWBOOT-06 创建向导 | preview、幂等事务、成员、七步 UI | 01/02 | API + UI |
| SWBOOT-07 对话路由 | 软件 task aliases、正式/自由任务边界、domain context | 03/05 | hard-negative |
| SWBOOT-08 阶段门禁 | 软件风险、来源 freshness、readiness、下一流程建议 | 03/04 | PG + notification |
| SWBOOT-09 真实验收 | 医疗/软件双黄金、真实 PI、重启、权限 | 03–08 | 完整 test-report |
| SWBOOT-10 受控工程执行 | repo allowlist、worktree、patch/test/merge 分段批准 | 09 后单独启动 | 安全 E2E |
## 依赖
- 当前 `CHAT-INTENT-STATE` 整改需先完成或至少冻结稳定基线,否则只读梳理可能误启动写任务;
- CI PostgreSQL 隔离库和真实 PI 凭证链;
- 工作流设计器/模板发布能力保持可用;
- 文档版本运行时 Round20 能力作为文档链基线;
- 用户确认首期执行模式及 solo/collaborative 策略。
## 暂不启动原因
本轮用户要求先梳理和制定详细方案;业务代码、迁移、模板和智能体配置尚未授权进入实施。本任务保持 `planned`,启动时须从 `dev` 新建独立 feature 分支,并在 CURRENT 认领 `workflow-design`/相应拆分 mutex。
## 相关链接
- [详细设计](../../system-design/2026-09-14-software-project-bootstrap-workflow.md)
- [现状调研](../research/2026-09-14-software-project-bootstrap-current-state.md)
- [验收清单](../checklists/2026-09-14-software-project-bootstrap-acceptance.md)
- [运行时权威 ADR](../../adr/2026-09-12-workflow-runtime-authority.md)
@@ -0,0 +1,86 @@
---
title: "MVP 治理规则方案评审(零治理创建 / 禁止零治理激活与执行 / 职责-动作对应)"
status: done
created: 2026-09-14
updated: 2026-09-14
author: Cline
---
# MVP 治理规则方案评审(零治理创建 / 禁止零治理激活与执行 / 职责-动作对应)
## 评审对象
用户转来的治理原则提案(外部评审稿,自称「仅完成审核判断,尚未修改此前落盘方案或业务代码」),核心主张:
> 允许零治理创建项目和普通对话;禁止零治理激活和执行文档任务。文档任务按动作进行职责鉴权,编制、审核、批准只能由对应文档负责人执行,项目创建者不具有隐式越权能力。
## 结论(先说判断)
**方向合理、证据属实、与已实施的 DutyMode 架构(Wave 1–4)高度兼容,建议采纳为治理总原则;但存在 4 个必须先决策/修正的分歧点,其中 A(none 文档可否生成)与 B(pre-activation 202 契约)若按提案字面实施,会直接推翻刚落地的已验收语义与测试。**
## 证据核实矩阵(提案引用的代码全部属实)
| # | 提案主张 | 核实结果 | 证据位置 |
|---|----------|----------|----------|
| 1 | 无治理实例时文档任务访问直接放行 | ✅ 属实 | `internal/projectinstance/document_access.go:49-51`(`gov == nil → return allow`);`stage_access_test.go:163` 断言该行为 |
| 2 | 创建者可绕过文档职责检查 | ✅ 属实 | `document_access.go:115-117`(`isCreator → allow`);`stage_access.go:65,67,79`(`allow = isCreator \|\| hasDuty`) |
| 3 | 只判断是否三职之一,不区分动作 | ✅ 属实 | `stage_access.go:96-100`(`docTaskDutyForUser` 任意一职即通过;`DocAccessAction*` 常量已存在于 `document_access.go:8-13` 但未与职责绑定) |
| 4 | `initial_workflow_key` 直通 active | ✅ 属实 | `internal/projectworkflow/service.go:57-83`(非空即 `LifecycleStatus="active"`);E2E `project_workflow_api_test.go:101-105` 依赖该旁路 |
| 5 | 创建弹窗默认勾选创建者+推荐审核/批准(成员角色≠文档职责) | ✅ 属实 | `web/src/components/project/CreateProjectModal.tsx:50-69`(creator/reviewer/approver 为项目成员角色) |
| 6 | 启用文档须完整三职(现行 validator) | ✅ 属实(主树) | `internal/projectinstance/validator.go:93-95`;已实施 worktree 已改为 DutyMode none/partial/full |
## 与已实施代码的交叉分析(提案未覆盖的现场)
上一轮整改(409 冻结 + 全有或全无)**已在 `fix/workflow-plan-409-frozen-and-optional-duties` worktree 实施**:Wave 1–4 已提交(`classifyDocDuty`/`DutyMode` 统一校验、门禁/readiness/访问一致语义、前端逐文档「纳入人工审批」开关),Wave 5(dev 真实浏览器验收)进行中(e2e spec 与 test-reports assets 未提交,集成槽位已占用)。dev 库实测:`133 active / 204 planning`,其中 **81 个 planning 项目带非空 `active_workflow_key`**(`initial_workflow_key` 旁路/历史迁移遗留的异态存量)——提案第 4 差距点在 dev 有真实影响面。
### 分歧点 A(最关键):none 模式文档可否生成 —— **已决策(2026-09-14,用户拍板)**
- 提案:「编制、审核、批准全部为空:该文档**不启用,不可发起任务**,也不阻塞阶段」。
- 已实施 D4(remediation 76-78 行):`DutyModeNone` = 文档**启用**、不要求 approved、不阻塞阶段,**项目创建者可触发生成和人工编辑**,其他成员只读。
- **用户决策:保持现实现(none = 不走人工审批但可生成)**。提案的「不可发起任务」正式收窄为「不可发起**审批流**动作(提交审核/审核/批准)」,不推翻 Wave 4/5。后续实施以本决策为准。
### 分歧点 B:pre-activation 202 契约
- 提案:「未激活:不创建任务、不启动小队、不获取文档租约」。
- 已验收契约:`ResolveMessageScopeForTask` 从未激活 → `ScopePreActivation`;`POST /api/v1/tasks/runs` 必须 **202**(`TestCreateTaskRun_PreActivationAcceptedNot409`,`internal/server/task_run_busy_preflight_test.go:75`);E2E UI-02 以 2xx 为硬门禁(409 即 FAIL)。
- 按字面「不创建任务」会推翻该契约并破坏 E2E。**建议**修正表述为:保留 202 创建 run(进入 `blocked_pending_governance` 之类状态、不启动小队、不取租约),chat 流内返回自然语言提示(提案的示例文案即为此设计)。提案意图(不执行)与现状兼容,仅「不创建」三个字必须改。
### 分歧点 C:creator 越权移除的影响面与 view 范围
- 移除 `isCreator` 例外(`document_access.go:115`、`stage_access.go:65,67,79`)方向正确,但大量已验收测试断言 creator allow(如 `access_governing_pg_test.go:140`),需同步重写测试语义,工作量可控但必须列入计划。
- 提案职责表「查看文档 = 具有项目访问权的成员」与 `document_access.go:102-104`(view 全放行)一致;但 `ResolveStageAccess` 的 UI 导航收窄会把无职责成员/创建者限制在职责阶段。需明确:view 豁免 stage 收窄(按提案表格),`AllowedStageKeys` 仅约束非 view 动作与任务发起入口。
### 分歧点 D:initial_workflow_key 旁路的存量处理
- 关闭入口正确(`projectworkflow/service.go:80-83` 改为仅挂载目录、不置 active),但需同步:`CreateProjectInput.InitialWorkflowKey` 字段废弃(`types.go:96`、前端 `web/src/types/projectWorkflow.ts:66`)、E2E legacy 用例(`project_workflow_api_test.go:101-105`)语义更新、以及 dev 库 81 个 planning+with_wf 异态项目的分类处置(至少审计:真 legacy / 测试数据,不得静默改库)。
## 提案其余要点的核实意见
- 三概念分离(创建/激活/执行)优于「创建即治理」:成立。创建者自动入成员已有实现(`CreateProjectModal` 默认勾选 + `ensureCreatedProjectWithMembers` 持久化),无死锁。
- 「至少一个 full 文档才能激活;全部未启用可存草稿禁激活」:与已实施 Wave 2 校验(至少一份 `DutyModeFull` + active member 复核)**完全一致**,无需重复实施。
- 「审核人退回 → 待编制人修订,审核人不得直接启动重编」:与职责-动作对应表一致,合理;现状 `docTaskDutyForUser` 不区分动作是真实缺口。
- 「激活冻结提示留空文档不可补配」:与现有冻结语义一致,属 Wave 1 frozen 视图文案的自然扩展。
- 「项目管理员」概念:现有成员角色枚举(creator/reviewer/approver/viewer)无 admin;提案未定义 role 模型如何演进(谁可配成员/职责目前是创建者,`IsProjectCreator` 权威)。建议 MVP 维持「创建者=项目管理员」,role 枚举演进留 backlog。
## 建议实施时序
1. 等 `fix/workflow-plan-409-frozen-and-optional-duties` Wave 5 验收收敛(验收中途改语义会导致返工与报告失真)。
2. 用户先决策分歧点 A(其次 C 的 view 范围)。
3. 采纳后新开 short-term(建议 `fix/governance-action-level-authz`,mutex=`workflow`),分波次:后端动作-职责映射(`CheckDocTaskAccess` 按动作判 author/reviewer/approver + 移除 creator 例外 + gov==nil 由「放行」改为「未激活拦截」但保留 202 契约)→ 关闭 `initial_workflow_key` 直通 → 前端交互与提示 → 存量异态审计 → E2E 更新。
## 采纳与派生记录(2026-09-14)
- 分歧点 A:用户拍板「保持现实现(none 可生成)」——见上文。
- 分歧点 B/C/D:按本评审建议采纳(B:保留 202 契约 + blocked 状态;C:view 豁免阶段收窄、creator 仅保留配置权与 none 生成触发;D:关闭直通 + 字段废弃 + 存量只审计不改库)。
- 已派生实施任务:[2026-09-14-governance-action-level-authz.md](../short-term/2026-09-14-governance-action-level-authz.md)(status=blocked,等待 Wave 5 收敛;含采纳版职责-动作矩阵与 G1–G5 波次)。
- Wave 5 现状(2026-09-14 实测):`implementer_cursor` 占集成槽位 phase=e2e,worktree 存在未提交 e2e 产物;新任务已排入槽位 queue。
## 相关链接
- Audit: [2026-09-14-workflow-plan-409-frozen-and-optional-duties.md](../../audit/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md)
- Remediation(已实施版): [2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md](../../remediation/2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md)
- 先例: [2026-09-13-workflow-access-chat-members-ui01-02.md](../../audit/2026-09-13-workflow-access-chat-members-ui01-02.md)(202 契约与三态作用域来源)
## 备注
主树 `.doc/ops/CURRENT.md`(`feature/remove-herdr-agent-settings` 分支)焦点 1 仍写「worktree 尚未创建、blocked」,已过时:worktree 已存在且 Wave 1–4 落地、Wave 5 进行中。该更新属实施分支职责,本评审不跨分支代改,仅在此记录提醒收敛时同步。
@@ -0,0 +1,72 @@
---
title: "纯软件项目自举能力现状"
created: 2026-09-14
status: done
confidence: high
---
# 调研:纯软件项目自举能力现状
## 结论
当前系统已经具备版本化工作流、冻结实例、阶段门禁、文档三权、文档版本账本、真实 PI 小队、自由任务、上下文快照、通知和审计等可复用基础,但项目创建、正式工作流目录、模板、角色提示词和任务路由仍以医疗器械语义为主。现状不能通过把 `device_type` 改成“软件”来安全复用;应新增纯软件工作流与领域配置,同时复用治理引擎和大部分通用小队能力。
本结论来自当前源码和现有验收报告核对,未在本轮启动真实 PI 或修改业务代码。
## 证据
| 项 | 路径/命令 | 结果 |
|----|-----------|------|
| 项目创建 UI | `web/src/components/project/CreateProjectModal.tsx` | 标题固定“医疗器械新项目”,`deviceType` 固定“通用医疗器械”,字段与提示词均是临床/法规语义 |
| 项目创建后模板 | `web/src/App.tsx` `handleCreateProjectConfirm` | 前端本地克隆固定 7 份医疗模板,并写死 V0.1 阶段提示;不是工作流版本驱动的服务端事务 |
| 项目模型 | `internal/projectworkflow/types.go`、`00001_baseline.sql` | 仍使用 `device_type/intended_use/target_market`;没有权威 `project_type/product_domain/compliance_profile/repository_binding` |
| 工作流定义 | `internal/workflowdef/manifests/*.v2.json` | manifest 宣称支持 `non_medical_software`,但阶段、文档与执行器仍是商务、注册、CDO、医疗验证语义 |
| 正式目录限制 | `internal/workflowdef/catalog_policy.go`、`projectinstance/validator.go` | 项目只能选择 `main/product_manager/test_manager`,还存在“三正式工作流”和固定文档数硬编码 |
| 工作流治理 | `internal/projectinstance/service.go`、`stage_service.go` | planning、激活预览、冻结快照、单活动实例、文档批准门禁、创建者确认推进均已实现,可直接复用 |
| 运行时权威 | `.doc/adr/2026-09-12-workflow-runtime-authority.md` | 运行任务必须从冻结实例解析 executor、模板和三权,禁止客户端覆盖 task/stage/duty |
| 小队角色 | `internal/squad/roles.go` | organizer/searcher/engineer/market/finance/writer 具有较强通用性;regulatory 是医疗专属;leader 仍绑定水木东方医疗器械 CDMO |
| 小队治理 | `internal/squad/workflow.go`、`gov.go`、`workspace.go` | 已有工作区隔离、步骤冻结、预算、轨迹、黑板、质量门禁、断点续跑,可复用 |
| 自由任务 | `internal/coordinator/router.go`、`internal/squad/planner.go` | 已有复杂任务升级与 ad-hoc 四步小队,但自动模板和专家派生仍含医疗措辞,不能当正式软件工作流 |
| 模板 | `templates/docs/*.md` | `system_reqs`、部分 `user_requirements` 可抽取通用骨架;research/test/prelim/quote 含法规、临床、电气安全或 CDMO 语义 |
| 文档版本 | `.doc/test-reports/2026-09-14-document-revision-runtime-ui-test-report.md` | 真实 UI 已验证版本、修订、确认/拒绝、并发、权限和重启恢复,可作为软件文档链路基础 |
| 发布状态 | `.doc/status/FEATURE-MATRIX.md`、`remediation/gap-matrix.md` | 全系统仍 `production_ready=no`;新方案不得绕过现有 CHAT-INTENT、CI 和真实 PI 门禁 |
## 可复用与需新增边界
| 能力 | 判定 | 处理方式 |
|------|------|----------|
| 工作流版本、冻结、阶段推进 | 直接复用 | 不新造运行时引擎 |
| 文档三权与版本账本 | 直接复用 | 按纯软件文档类型挂载 |
| organizer/searcher/writer | 复用为主 | 去除组织和医疗专属措辞 |
| engineer/leader | 复用内核 | 增加软件领域 profile;leader 改为领域中立交付负责人 |
| regulatory | 条件复用 | 仅合规配置需要时启用,不作为非医疗默认角色 |
| market/finance | 可选复用 | 商业产品启用,内部工具默认关闭 |
| 自由任务与动态角色 | 辅助复用 | 用于非标准文档;不得替代已发布工作流和冻结任务契约 |
| 项目创建向导 | 需重构 | 由服务端项目类型与工作流目录驱动,停止前端固定克隆 7 份模板 |
| 软件模板和质量门禁 | 需新增 | 新 task key、模板、executor、quality gate |
| 仓库绑定与代码执行 | 需新增 | 分成只读盘点和受控变更两级;首期不直接改仓库 |
| 独立评审例外 | 需新增 | 单人项目明确标记“无独立评审”,不可伪造 reviewer/approver |
## 关键差距
1. `product_domains` 只存在于 manifest 声明,项目本身没有权威产品域,工作流目录也未按项目域过滤。
2. `workflow_definitions.product_domain` 是单字符串,而 manifest 是多域数组,适用性模型存在双重表达。
3. 创建项目与创建成员不是同一后端事务,模板又由浏览器本地克隆;跨设备和失败恢复的事实源不完整。
4. 当前三权校验强制三个不同用户,无法诚实支持个人自举项目。
5. 当前阶段 readiness 主要检查“必需文档已批准”,尚不能表达测试证据、开放高风险、变更请求和构建结果等软件门禁。
6. 当前 `SupportedTasks`、意图关键词、知识检索和模板都绑定既有 task key,新增软件工作流必须成套扩展。
7. PI 小队只能在受控工作区生成文件;没有经授权的仓库 worktree、测试、补丁审查和合并控制面。
## 开放问题
- 首个使用者是单人还是至少三人协作,这将决定是否启用独立三权或“创建者确认、未独立评审”策略。
- 目标项目仓库如何接入:浏览器上传快照、只读 Git URL,还是服务器受控本地路径。
- 首期目标是“梳理与计划”还是要同时支持生成代码补丁;建议先交付前者。
- 是否需要默认启用隐私、安全或外部合规 profile;不能从“纯软件”自动推断为 `none`。
## 建议动作
- 首期新增 `software_bootstrap`,并以项目类型、治理强度和项目形态生成默认规划。
- 第二期新增可重复实例化的 `software_delivery`,承接每个里程碑或发布。
- 先实现 `docs_only/read_only_repo`,代码变更执行器单独立项并受 feature worktree、测试、审批和审计约束。
- 保留现有医疗三工作流,不在原 manifest 上直接替换语义,避免回归。
@@ -0,0 +1,57 @@
---
title: "修复对话刷新恢复与授权统计不一致"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
owner: Cursor
branch: fix/chat-history-refresh
worktree: ".worktrees/fix-chat-history-refresh"
mutex: chat
---
# 修复对话刷新恢复与授权统计不一致
## 目标
按整改方案修复消息作用域写入、历史兼容、读取授权和前端恢复态,并完成真实 PostgreSQL 与 PI 文档生成后的刷新验收。
## 范围
- 消息和 task run 的不可变工作流实例/阶段作用域
- 会话 owner 与阶段可见性的统一服务端策略
- 窗口、日期、分类、搜索、摘要、未读、导出、锚点的同集查询
- 现有消息 dry-run/backfill
- 前端窗口错误态和用户隔离缓存
- 自动化与真实 PI E2E 证据
## 非目标
- 不放宽现有阶段可见性规则
- 不用前端缓存替代服务端持久化
- 不对无法唯一归属的历史消息盲目回填当前阶段
## 步骤
1. [x] 先补可稳定复现本缺陷的 PG 集成与前端恢复测试
2. [x] 实现统一消息作用域解析与写入
3. [x] 实现统一会话/消息授权查询及统计同集
4. [x] 实现历史 dry-run/backfill 与对账
5. [x] 完善前端恢复状态及用户隔离缓存
6. [ ] 执行全量门禁、真实 PI 刷新 E2E 和双用户负例(PG/单测已完成;PI 待 dev 容器)
## 验收标准
- [x] [整改方案](../../remediation/2026-09-13-chat-history-refresh-remediation.md) 的验收项(除真实 PI E2E)有证据
- [x] `CHAT-HISTORY-REFRESH` 在 gap-matrix 中由 FAIL 更新为 PASS
- [x] 测试报告归档并回链
## 相关链接
- Checklist: 实施开始时复制模板建立
- Handoff: [../handoffs/2026-09-13-chat-history-refresh-diagnosis.md](../handoffs/2026-09-13-chat-history-refresh-diagnosis.md)
- Test report: [../../test-reports/2026-09-13-chat-history-refresh-test-report.md](../../test-reports/2026-09-13-chat-history-refresh-test-report.md)
## 证据 / 备注
- Audit: [../../audit/2026-09-13-chat-history-refresh-disappears.md](../../audit/2026-09-13-chat-history-refresh-disappears.md)
- Remediation: [../../remediation/2026-09-13-chat-history-refresh-remediation.md](../../remediation/2026-09-13-chat-history-refresh-remediation.md)
@@ -0,0 +1,57 @@
---
title: "修复查询误触发写任务与任务状态刷新退化"
status: in_progress
created: 2026-09-13
updated: 2026-09-13
owner: Codex
branch: fix/conversation-intent-state
worktree: ".worktrees/fix-conversation-intent-state"
mutex: intent
---
# 修复查询误触发写任务与任务状态刷新退化
## 目标
修复只读查询误启动文档、刷新丢失任务卡片能力及文档编辑状态不可见,并建立诊断数据隔离门禁。
## 范围
- 模板任务动作识别及负例测试
- 任务错误/进度/恢复上下文持久化与历史重建
- 文档租约/运行态的 UI 展示和重复启动前置拦截
- 隔离 fixture 验收与真实 PI 刷新 E2E
## 非目标
- 未经项目创建者确认,不软删除已污染消息或删除误启动产物
- 不放宽文档租约与工作流权限规则
## 步骤
1. [x] 核对真实会话、任务运行、事件和文档租约证据
2. [x] 补只读意图与刷新恢复失败测试
3. [x] 收紧写任务动作识别并修复 busy 错误分型
4. [x] 实现任务/租约状态刷新恢复与统一提示
5. [x] 实现命名文档的服务端鉴权只读总结(“总结”不止是不写入)
6. [ ] 执行前端、Go、PG 与真实 PI 双标签页验收
- [x] Go、前端、构建、dev 重建与真实 PI 只读总结
- [x] 服务端 busy 预检不创建 run,并持久化无重试状态卡
- [ ] 浏览器刷新恢复与双标签页 busy 可见性
## 验收标准
- [ ] [整改方案](../../remediation/2026-09-13-conversation-intent-runtime-state-remediation.md) 全部验收项有证据
- [ ] `CHAT-INTENT-STATE` 由 FAIL 更新为 PASS
- [ ] test-report 归档并回链
## 相关链接
- Checklist: 本任务验收标准
- Handoff: 与 `fix/chat-history-refresh` 合并前复核 `App.tsx/chatWindow.ts`
- Test report: [../../test-reports/2026-09-13-conversation-intent-runtime-state-test-report.md](../../test-reports/2026-09-13-conversation-intent-runtime-state-test-report.md)
## 证据 / 备注
- Audit: [../../audit/2026-09-13-conversation-intent-runtime-state.md](../../audit/2026-09-13-conversation-intent-runtime-state.md)
- Remediation: [../../remediation/2026-09-13-conversation-intent-runtime-state-remediation.md](../../remediation/2026-09-13-conversation-intent-runtime-state-remediation.md)
@@ -0,0 +1,80 @@
---
title: "受控正文 canonical hash 漂移与重复 hydration 实施"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: implementer_cursor
branch: fix/controlled-content-canonical-hash
worktree: ".worktrees/fix-controlled-content-canonical-hash"
mutex: docgov
---
# 受控正文 canonical hash 漂移与重复 hydration 实施
## 目标
按整改计划 W1–W6 修复受控文档 canonical/raw 哈希漂移、错误语义与重复 hydration;工程门禁在 worktree 内通过。不操作 `data/dev`、共享 Docker,不合 `dev`。
## 范围
- W1 语义保持的 Markdown canonicalization + golden test
- W2 统一 bootstrap / PATCH / agent commit / backfill 的 hash、snapshot、DocGov、output.md bytes
- W3 已建账本以 head 为 SSOT;投影不一致不静默覆盖;结构化 error code
- W4 dry-run 默认 reconciler/CLI(项目 143 分类为 `LEGACY_CANONICALIZATION_DRIFT`);不在本 worktree 对真实数据 apply
- W5 前端 lease no-op 保引用、hydrate fingerprint + 最小在途去重、解析结构化错误
- W6 Go 单测、PG 相关能力、前端 test/build
## 非目标
- W7 占集成槽合 `dev` / `env-service.sh` / 共享容器
- W8 真实浏览器 / 真实 PI UI 验收
- 在 worktree 读写 `data/dev` 或共享数据库
## 步骤
1. [x] cherry-pick `81288bd` 诊断文档
2. [x] 创建本任务并认领 `docgov`
3. [x] W1–W6 实现与 focused/门禁测试
4. [x] 更新 audit/remediation/FEATURE-MATRIX/CURRENT
5. [x] 原子提交 + handoff
6. [x] 合入前审查 blockers:00032 / 修订号 / live CLI / HashUpdater 预加载 / 读路径 drift 冲突 / 隔离 PG 状态
7. [x] follow-up:旧 head 正文备份、备份不可覆盖、原子写目录 fsync;单提交后 done
8. [x] 终审 3 项:live 正向确认 :5433+agent_system_dev+data/dev;备份三件套+唯一目录/O_EXCL+全路径;rename 后目录 Sync 兼容处理
9. [x] UI clean run:doc-001 等本地 legacy 不发 content/revision;hydrate 资格对齐 toolbar server-backed
10. [x] UI 竞态:晚到 list sync 不得擦掉成功 hydrate;清空 ready/cache 必须重水合;编辑/PATCH 基线受保护
## 验收标准
- [x] `CanonicalizeMarkdown` 保留双空格硬换行;golden test 覆盖
- [x] 写路径 `file_sha == record_sha == head_sha`(同一 canonical bytes)
- [x] 记录不存在才 404;missing/empty/mismatch 为结构化 error code
- [x] reconciler 默认 dry-run;legacy drift 不把旧 head 覆盖回文件、不只改 DB hash
- [x] lease 无变化返回原 `deliverables` 引用;同文档 hydrate 去重
- [x] `go vet ./...`、`go test -short ./...`、`web npm test`、`web npm run build` 真实通过后才勾选
- [x] 不宣称未执行的 UI / 容器 / 数据修复
- [x] goose 00032 允许 `migration_repair`;repair 不递增 `head_revision_no` / `human_revision_count`
- [x] CLI 默认仍拒绝共享库/路径;`--live --environment dev --doc-id --confirm REPAIR_SINGLE_DEV_DOC` 才允许单文档 apply
- [x] `MarkDocumentContentUpdated` 未预加载时从 DB 补偿;retry 仍同步
- [x] 投影 drift 返回 `DOCUMENT_CONTENT_PROJECTION_DRIFT`,不静默展示破坏性旧 head
- [x] 隔离 `TEST_DATABASE_URL` 未配置:`TestReconcile_LegacyRepair_PG` skip,记为 blocker,未用 5433 业务库代替
## 相关链接
- Audit: [../../audit/2026-09-14-project143-controlled-content-404.md](../../audit/2026-09-14-project143-controlled-content-404.md)
- Remediation: [../../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md](../../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md)
- Handoff: [../handoffs/2026-09-14-controlled-content-canonical-hash.md](../handoffs/2026-09-14-controlled-content-canonical-hash.md)
- Test report: 本轮仅工程门禁;真实 UI 属 W8
## 证据 / 备注
- cherry-pick: `f80e7a1` (`81288bd`)
- `go vet ./...` PASS
- `go test -short ./...` PASS
- focused: `TestCanonicalize*` / `TestClassify*` / `TestReconcile*` / `TestReadDocumentContent_Typed*` / `TestWriteControlledContentError` PASS
- 审查修补后再次 `go vet ./...` PASS、`go test -short ./...` PASS
- focused:canonical/classify/reconcile/CLI live 门闩/path map/typed content/drift 冲突 PASS
- PG: 本机 `TEST_DATABASE_URL` 未设置;`TestReconcile_LegacyRepair_PG` skip。已去掉 `-short` 无条件跳过,隔离库就绪后即使 `-short` 也会跑。禁止 5433/5434/5435
- `web npm test` PASS(tsx 349 + vitest 30;含 controlledContentInvalidation 时序)
- `web npm run build` PASS
- follow-up:`*.head.md` 保存旧 head 正文;已有备份拒绝覆盖;`WriteFileAtomic` rename/link 后 `SyncDir`
- 未执行:`env-service.sh`、共享 Docker、`data/dev` apply、真实 UI、隔离 PG apply 验证
@@ -0,0 +1,80 @@
---
title: "治理鉴权升级:职责-动作严格对应 + 未激活拦截 + 关闭创建直通"
status: blocked
created: 2026-09-14
updated: 2026-09-14
owner: Cline
branch: fix/governance-action-level-authz
worktree: "-"
mutex: workflow
---
# 治理鉴权升级:职责-动作严格对应 + 未激活拦截 + 关闭创建直通
## 目标
采纳 [MVP 治理规则评审](../../ops/research/2026-09-14-mvp-governance-rules-review.md) 修正版原则:**允许零治理创建与普通对话;禁止零治理激活与执行文档任务(审批流动作)**。文档动作按职责鉴权,创建者不隐式越权,`initial_workflow_key` 不再直通 active。
## 决策记录(已定,不再开放)
- **A(用户拍板 2026-09-14)**:`DutyModeNone` 文档 = 不走人工审批但**可生成**(创建者触发,维持已实施 D4);「不可发起任务」收窄为不可发起**审批流动作**(submit/review/approve)。
- **B(按评审建议采纳)**:pre-activation 保留 202 契约——`POST /tasks/runs` 仍 202 创建 run,但置 blocked 状态、不启动小队、不取文档租约,chat 流内返回自然语言治理提示。
- **C(按评审建议采纳)**:移除 `isCreator` 对 full 文档的隐式全通行;`view` 豁免阶段收窄(项目访问成员可查看);创建者保留:配置成员/职责 + none 文档生成触发。
- **D(按评审建议采纳)**:关闭 `initial_workflow_key` 直通 active(仅挂载目录);后端/前端 types 字段废弃标注;E2E legacy 用例语义更新;dev 库 81 个 planning+with_wf 异态项目**只审计分类,不改库**。
## 采纳版职责-动作矩阵
| 动作 | full 文档 | none 文档 | 未激活(gov==nil) |
|------|-----------|-----------|--------------------|
| view | 项目访问成员 | 项目访问成员 | 项目访问成员 |
| run(首次生成/重生成) | 编制负责人 | **创建者**(无审批链) | 202 + blocked 状态,chat 内提示,不启小队/不取租约 |
| edit/submit(编辑/提交审核) | 编制负责人 | 拒绝(无审批链) | 拒绝 |
| review(审核/退回) | 审核负责人 | 拒绝 | 拒绝 |
| approve(批准/拒绝批准) | 批准负责人 | 拒绝 | 拒绝 |
| 配置成员/文档职责 | 创建者 | 创建者 | 创建者(planning 期配置正是本阶段语义) |
退回后形成「待编制人修订」;审核人不得直接启动重编(由编制负责人发起修订)。
## 范围
- `internal/projectinstance/document_access.go`(动作-职责映射、creator 例外移除、gov==nil 未激活拦截)
- `internal/projectinstance/stage_access.go`(view 豁免语义;`docTaskDutyForUser` 拆分为按职责判定)
- `internal/projectinstance/message_scope.go` + taskrun/chat handler(blocked 状态 + 自然语言提示)
- `internal/projectworkflow/service.go`(关闭 `initial_workflow_key` 直通)+ `types.go` 前后端字段废弃
- 受影响单测重写(`access_governing_pg_test.go` creator 断言、`TestCreateTaskRun_PreActivationAcceptedNot409` 语义细化)与 E2E legacy 用例
## 非目标
- 不改三权互斥与 DutyMode 校验(Wave 2 已完成)
- 不做运行中动态补配职责 / 按文档单独激活(冻结语义维持,激活页提示「留空文档不参与、不可补配」)
- 不做成员 role 枚举演进(MVP 维持创建者=项目管理员;role 演进留 backlog)
- 不改 dev 库存量数据(仅审计)
## 步骤
1. [x] 评审落盘 + 决策 A–D 收敛 + 本任务登记(blocked 等待 Wave 5 收敛、mutex `workflow` 空闲)
2. [ ] G1 后端:`CheckDocTaskAccess` 动作-职责映射 + creator 例外移除(保留 none 生成触发)+ gov==nil 未激活拦截(202 契约保留);重写受影响单测
3. [ ] G2 关闭 `initial_workflow_key` 直通 + 前后端字段废弃 + E2E legacy 用例更新
4. [ ] G3 前端:chat 治理拦截自然语言提示、按钮级职责禁用、激活确认页冻结提示补强
5. [ ] G4 dev 库 81 个 planning+with_wf 异态审计分类(只读报告)
6. [ ] G5 集成验证 + 测试报告归档(新项目全链路:零治理创建→对话→配置→激活→职责动作负例)
## 验收标准
- [ ] full 文档 API 负例:author 不可 review/approve;reviewer 不可 run/edit/submit;approver 不可 run/edit/review;creator 不可任一审批动作(view 除外)
- [ ] none 文档:创建者可触发生成;submit/review/approve 全拒
- [ ] 未激活项目 chat 输入「帮我生成立项文档」:消息正常显示、run 202 且 blocked、无小队/租约、chat 内明确治理提示文案
- [ ] `POST /projects` 带 `initial_workflow_key`:不再置 active,工作流目录仍自动挂载
- [ ] `go vet ./...`、`go test -short ./...`、`cd web && npm test && npm run build` 全绿
- [ ] 异态审计报告与测试报告归档并回链
## 相关链接
- Research(评审与决策记录): [2026-09-14-mvp-governance-rules-review.md](../research/2026-09-14-mvp-governance-rules-review.md)
- 前序 Remediation(已实施 Wave 1–4): [2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md](../../remediation/2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md)
- 202 契约来源: [2026-09-13-workflow-access-chat-members-ui01-02.md](../../audit/2026-09-13-workflow-access-chat-members-ui01-02.md)
## 证据 / 备注
- Wave 5 占槽现状(2026-09-14 实测):`implementer_cursor` phase=e2e,worktree 存在未提交 e2e 产物;本任务排在集成槽位 queue。
- dev 库:133 active / 204 planning;81 个 planning 项目带非空 `active_workflow_key`(待 G4 审计分类)。
@@ -0,0 +1,54 @@
---
title: "模块解耦 Wave 0:契约包骨架 + 架构门禁基线"
status: done
created: 2026-09-14
updated: 2026-09-14
owner: Cursor
branch: feature/remove-herdr-agent-settings
worktree: "-"
mutex: arch
---
# 模块解耦 Wave 0:契约包骨架 + 架构门禁基线
> 总方案:[../../system-design/2026-09-14-module-decoupling-architecture.md](../../system-design/2026-09-14-module-decoupling-architecture.md)
> ADR:[../../adr/2026-09-14-modular-monolith-decoupling.md](../../adr/2026-09-14-modular-monolith-decoupling.md)
## 目标
建立 `internal/contracts` 骨架与 `scripts/arch-check.sh` 依赖门禁(warn 基线),使模块边界从此可度量、可执行,为 Wave 1–6 提供验收对照。
## 范围
- `internal/contracts/`:vocabulary.go(MaturityStage 等共享枚举占位)、errors.go(错误码表)、events.go(首批事件类型定义,纯定义零实现)
- `scripts/arch-check.sh` + `.doc/system-design/module-boundaries.yaml`(以现状生成 allowlist,不收紧)
- 基线违规报告存 `.doc/audit/2026-09-14-arch-check-baseline.md`
## 非目标
- 不改任何业务行为、不迁移任何包(属 Wave 1+)
- 不收紧任何依赖规则(block 转换在两周 warn 期后)
## 步骤
1. [x] 用户确认 ADR → 状态转「已接受」
2. [x] 建 contracts 骨架(纯定义,`go test ./internal/contracts` 绿)
3. [x] 写 arch-check.sh(import allowlist / 表属主 / 路径字面量三类检查,支持 --mode warn|block)
4. [x] 运行 warn 模式,基线报告落 `.doc/audit/`
5. [ ] 合 `dev` 占槽冒烟(本轮不占槽;集成槽仍由 workflow-plan Wave 5 持有)
## 验收标准
- [x] `./scripts/arch-check.sh --mode warn` 可运行并产出基线报告
- [x] `go vet ./... && go test -short ./...` 全绿(2026-09-14 本工作区;`internal/server` 9.823s)
- [x] ADR 状态「已接受」;本文件 status → done
## 相关链接
- Checklist: -
- Handoff: -
- Test report: -
## 证据 / 备注
- 依赖图实测(2026-09-14):server 25 内部包 / 17,007 行;bizdev 16 包;详见总方案 §1.1
@@ -0,0 +1,70 @@
---
title: "workflow-plan 409 冻结态守卫 + 文档职责可选治理"
status: in_progress
created: 2026-09-14
updated: 2026-09-14
owner: implementer_cursor
branch: fix/workflow-plan-409-frozen-and-optional-duties
worktree: ".worktrees/fix-workflow-plan-409-frozen-and-optional-duties"
mutex: workflow
---
# workflow-plan 409 冻结态守卫 + 文档职责可选治理
## 目标
已激活项目的设置页进入明确的冻结只读态;非必需且允许裁剪的文档可选择“不纳入人工审批”,部分职责、必需文档空职责、非成员职责和零治理激活由服务端拒绝;门禁、权限、快照与页面语义保持一致。
## 范围
- `web/src/components/project/ProjectSettingsModal.tsx`:frozen 视图、逐文档审批开关、内联/sticky 错误、并发恢复。
- `web/src/api/projectSettings.ts`:保留 status/code/message/issues 的 typed error。
- `internal/projectinstance/validator.go`:统一 DutyMode、工作流定义约束、结构与成员校验。
- `internal/projectinstance/service.go`:保存/预览/激活重复复核 active members。
- `internal/projectinstance/gate.go`、`stage_access.go`、`document_access.go`:none/full/disabled 一致语义。
- `internal/projectinstance/store.go`、`internal/workflow/runtime/orchestrator.go`:快照清理、零 assignment rows、零职责运行时契约。
- 激活预览统计与相应前后端测试。
## 非目标
- 不修改项目 143 的现有工作流配置,不在验收中终止项目 143。
- 不支持部分指派或自动补齐职责。
- 不允许项目配置降低工作流定义中必需/阻断文档的治理要求。
- 不把“无需人工审批”文档改成无版本、无审计的非受控文档。
- 不迁移历史 active 实例;冻结快照继续作为历史 SSOT。
## 步骤
1. [x] 定位项目 143 的 409 `PLAN_FROZEN` 根因并落盘 audit。
2. [x] 完成方案审核:补齐定义优先、零治理拦截、成员有效性、权限、快照清理和真实 UI 边界。
3. [ ] Wave 1:typed API error + frozen 独立只读视图 + sticky/可访问错误 + 两标签竞态恢复。
4. [ ] Wave 2:DutyMode、强制/可选任务策略、partial/成员/零治理校验、服务端规范化。
5. [ ] Wave 3:门禁、readiness、阶段/文档访问、运行时和预览统计统一。
6. [ ] Wave 4:前端逐文档“纳入人工审批”开关及 full/none/partial 交互测试。
7. [ ] Wave 5:合 dev、rebuild、真实浏览器新项目全链路;项目 143 只读回归;归档 test report。
## 验收标准
- [ ] active 项目设置无编辑控件,页面显示冻结原因、工作流/阶段/职责快照和受控终止影响入口。
- [ ] 允许裁剪的非必需文档 full/none 均合法;partial 精确拒绝。
- [ ] 必需/阻断/不可裁剪文档全空被服务端拒绝。
- [ ] 保存和激活均拒绝非 active project member;预览后成员退出也 fail closed。
- [ ] 所有文档 none 时可保存草稿但不能激活。
- [ ] none 文档仍生成和入账本、项目成员只读可见、创建者可生成/编辑,但无 review/approve 且不阻塞阶段。
- [ ] disabled/none 的冻结快照、plan hash 和 assignment rows 不残留旧职责。
- [ ] 两标签陈旧保存的 409 在当前视口可见、草稿保留并转 frozen。
- [ ] 工程门禁与整改方案中的真实 UI 用例全部有证据;报告回链。
## 相关链接
- Audit: [2026-09-14-workflow-plan-409-frozen-and-optional-duties.md](../../audit/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md)
- Remediation: [2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md](../../remediation/2026-09-14-workflow-plan-409-frozen-and-optional-duties-remediation.md)
- Test report: (Wave 5 归档至 `.doc/test-reports/`)
## 证据 / 备注
- dev 项目 143:`lifecycle_status=active`、`active_workflow_key=main`、实例 89 active;409 与三名职责人选择内容无关。
- 当前 `parseError` 已读取后端 message;前端改造重点是 typed error、冻结态切换和视口内呈现。
- 当前职责校验只检查正数/互异,数据库只外键到 users;项目成员有效性必须补服务端校验。
- 当前终止实现会取消运行任务、关闭实例并退回 planning;关闭实例访问 fail closed,因此项目 143 不能作为终止测试对象。
- 开始编码前必须先把本任务从当前误置的 `feature/remove-herdr-agent-settings` 工作区迁移至声明的 `fix/workflow-plan-409-frozen-and-optional-duties` 分支/worktree,禁止污染无关分支。

Some files were not shown because too many files have changed in this diff Show More